DCP: fixed include-guards
[vlc.git] / modules / services_discovery / upnp.hpp
1 /*****************************************************************************
2  * upnp.hpp :  UPnP discovery module (libupnp) header
3  *****************************************************************************
4  * Copyright (C) 2004-2010 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Rémi Denis-Courmont <rem # videolan.org> (original plugin)
8  *          Christian Henz <henz # c-lab.de>
9  *          Mirsal Ennaime <mirsal dot ennaime at gmail dot com>
10  *          Hugo Beauzée-Luyssen <hugo@beauzee.fr>
11  *
12  * UPnP Plugin using the Intel SDK (libupnp) instead of CyberLink
13  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2 of the License, or
17  * (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
27  *****************************************************************************/
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #include <vector>
34 #include <string>
35
36 #include <upnp/upnp.h>
37 #include <upnp/upnptools.h>
38
39 #include <vlc_common.h>
40 #include <vlc_url.h>
41
42 namespace SD
43 {
44     class MediaServerList;
45 }
46
47 /*
48  * libUpnp allows only one instance per process, so we have to share one for
49  * both SD & Access module
50  * Since the callback is bound to the UpnpClient_Handle, we have to register
51  * a wrapper callback, in order for the access module to be able to initialize
52  * libUpnp first.
53  * When a SD wishes to use libUpnp, it will provide its own callback, that the
54  * wrapper will forward.
55  * This way, we always have a register callback & a client handle.
56  */
57 class UpnpInstanceWrapper
58 {
59 public:
60     // This increases the refcount before returning the instance
61     static UpnpInstanceWrapper* get(vlc_object_t* p_obj, Upnp_FunPtr callback, SD::MediaServerList *opaque);
62     void release(bool isSd);
63     UpnpClient_Handle handle() const;
64
65 private:
66     static int Callback( Upnp_EventType event_type, void* p_event, void* p_user_data );
67
68     UpnpInstanceWrapper();
69     ~UpnpInstanceWrapper();
70
71 private:
72     static UpnpInstanceWrapper* s_instance;
73     static vlc_mutex_t s_lock;
74     UpnpClient_Handle handle_;
75     vlc_mutex_t callback_lock_; // protect opaque_ and callback_
76     SD::MediaServerList* opaque_;
77     Upnp_FunPtr callback_;
78     int refcount_;
79 };
80
81 namespace SD
82 {
83
84 struct MediaServerDesc
85 {
86     MediaServerDesc( const std::string& udn, const std::string& fName,
87                     const std::string& loc, const std::string& iconUrl );
88     ~MediaServerDesc();
89     std::string UDN;
90     std::string friendlyName;
91     std::string location;
92     std::string iconUrl;
93     input_item_t* inputItem;
94     bool isSatIp;
95 };
96
97
98 class MediaServerList
99 {
100 public:
101
102     MediaServerList( services_discovery_t* p_sd );
103     ~MediaServerList();
104
105     bool addServer(MediaServerDesc *desc );
106     void removeServer(const std::string &udn );
107     MediaServerDesc* getServer( const std::string& udn );
108     static int Callback( Upnp_EventType event_type, void* p_event, void* p_user_data );
109
110 private:
111     void parseNewServer( IXML_Document* doc, const std::string& location );
112     std::string getIconURL( IXML_Element* p_device_elem , const char* psz_base_url );
113
114 private:
115     services_discovery_t* p_sd_;
116     std::vector<MediaServerDesc*> list_;
117     vlc_mutex_t lock_;
118 };
119
120 }
121
122 namespace Access
123 {
124
125 class Upnp_i11e_cb
126 {
127 public:
128     Upnp_i11e_cb( Upnp_FunPtr callback, void *cookie );
129     ~Upnp_i11e_cb();
130     void waitAndRelease( void );
131     static int run( Upnp_EventType, void *, void *);
132
133 private:
134     vlc_sem_t       sem_;
135     vlc_mutex_t     lock_;
136     int             refCount_;
137     Upnp_FunPtr     callback_;
138     void*           cookie_;
139 };
140
141 class MediaServer
142 {
143 public:
144     MediaServer( access_t* p_access );
145     ~MediaServer();
146     input_item_t* getNextItem();
147
148 private:
149     MediaServer(const MediaServer&);
150     MediaServer& operator=(const MediaServer&);
151
152     void fetchContents();
153     input_item_t* newItem(const char* objectID, const char* title);
154     input_item_t* newItem(const char* title, const char* psz_objectID, mtime_t duration, const char* psz_url );
155
156     IXML_Document* _browseAction(const char*, const char*,
157             const char*, const char*, const char* );
158     static int sendActionCb( Upnp_EventType, void *, void *);
159
160 private:
161     char* psz_root_;
162     char* psz_objectId_;
163     access_t* access_;
164     IXML_Document* xmlDocument_;
165     IXML_NodeList* containerNodeList_;
166     unsigned int   containerNodeIndex_;
167     IXML_NodeList* itemNodeList_;
168     unsigned int   itemNodeIndex_;
169 };
170
171 }