1 /*****************************************************************************
2 * upnp.hpp : UPnP discovery module (libupnp) header
3 *****************************************************************************
4 * Copyright (C) 2004-2016 VLC authors and VideoLAN
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>
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU Lesser General Public License as published by
14 * the Free Software Foundation; either version 2.1 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public License
23 * along with this program; if not, write to the Free Software Foundation,
24 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
25 *****************************************************************************/
38 #include <upnp/upnp.h>
39 #include <upnp/upnptools.h>
41 #include <vlc_common.h>
44 #if UPNP_VERSION < 10800
45 typedef void* UpnpEventPtr
;
47 typedef const void* UpnpEventPtr
;
52 class MediaServerList
;
56 * libUpnp allows only one instance per process, so we have to share one for
57 * both SD & Access module
58 * Since the callback is bound to the UpnpClient_Handle, we have to register
59 * a wrapper callback, in order for the access module to be able to initialize
61 * When a SD wishes to use libUpnp, it will provide its own callback, that the
62 * wrapper will forward.
63 * This way, we always have a register callback & a client handle.
65 class UpnpInstanceWrapper
68 // This increases the refcount before returning the instance
69 static UpnpInstanceWrapper
* get(vlc_object_t
* p_obj
, services_discovery_t
*p_sd
);
70 void release(bool isSd
);
71 UpnpClient_Handle
handle() const;
72 static SD::MediaServerList
*lockMediaServerList();
73 static void unlockMediaServerList();
76 static int Callback( Upnp_EventType event_type
, UpnpEventPtr p_event
, void* p_user_data
);
78 UpnpInstanceWrapper();
79 ~UpnpInstanceWrapper();
82 static UpnpInstanceWrapper
* s_instance
;
83 static vlc_mutex_t s_lock
;
84 UpnpClient_Handle m_handle
;
85 static SD::MediaServerList
* p_server_list
;
92 struct MediaServerDesc
94 MediaServerDesc( const std::string
& udn
, const std::string
& fName
,
95 const std::string
& loc
, const std::string
& iconUrl
);
98 std::string friendlyName
;
101 input_item_t
* inputItem
;
103 std::string satIpHost
;
107 class MediaServerList
111 MediaServerList( services_discovery_t
* p_sd
);
114 bool addServer(MediaServerDesc
*desc
);
115 void removeServer(const std::string
&udn
);
116 MediaServerDesc
* getServer( const std::string
& udn
);
117 static int Callback( Upnp_EventType event_type
, UpnpEventPtr p_event
);
120 void parseNewServer( IXML_Document
* doc
, const std::string
& location
);
121 std::string
getIconURL( IXML_Element
* p_device_elem
, const char* psz_base_url
);
124 services_discovery_t
* const m_sd
;
125 std::vector
<MediaServerDesc
*> m_list
;
136 Upnp_i11e_cb( Upnp_FunPtr callback
, void *cookie
);
138 void waitAndRelease( void );
139 static int run( Upnp_EventType
, UpnpEventPtr
, void *);
145 Upnp_FunPtr m_callback
;
152 MediaServer( stream_t
* p_access
, input_item_node_t
* node
);
154 bool fetchContents();
157 MediaServer(const MediaServer
&);
158 MediaServer
& operator=(const MediaServer
&);
160 bool addContainer( IXML_Element
* containerElement
);
161 bool addItem( IXML_Element
* itemElement
);
163 IXML_Document
* _browseAction(const char*, const char*,
164 const char*, const char*, const char* );
165 static int sendActionCb( Upnp_EventType
, UpnpEventPtr
, void *);
169 char* m_psz_objectId
;
171 input_item_node_t
* m_node
;