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 *****************************************************************************/
34 #include <upnp/upnp.h>
35 #include <upnp/upnptools.h>
37 #include <vlc_common.h>
40 #if UPNP_VERSION < 10800
41 typedef void* UpnpEventPtr
;
43 typedef const void* UpnpEventPtr
;
48 class MediaServerList
;
52 * libUpnp allows only one instance per process, so we have to share one for
53 * both SD & Access module
54 * Since the callback is bound to the UpnpClient_Handle, we have to register
55 * a wrapper callback, in order for the access module to be able to initialize
57 * When a SD wishes to use libUpnp, it will provide its own callback, that the
58 * wrapper will forward.
59 * This way, we always have a register callback & a client handle.
61 class UpnpInstanceWrapper
64 // This increases the refcount before returning the instance
65 static UpnpInstanceWrapper
* get(vlc_object_t
* p_obj
, services_discovery_t
*p_sd
);
66 void release(bool isSd
);
67 UpnpClient_Handle
handle() const;
68 static SD::MediaServerList
*lockMediaServerList();
69 static void unlockMediaServerList();
72 static int Callback( Upnp_EventType event_type
, UpnpEventPtr p_event
, void* p_user_data
);
74 UpnpInstanceWrapper();
75 ~UpnpInstanceWrapper();
78 static UpnpInstanceWrapper
* s_instance
;
79 static vlc_mutex_t s_lock
;
80 UpnpClient_Handle m_handle
;
81 static SD::MediaServerList
* p_server_list
;
88 struct MediaServerDesc
90 MediaServerDesc( const std::string
& udn
, const std::string
& fName
,
91 const std::string
& loc
, const std::string
& iconUrl
);
94 std::string friendlyName
;
97 input_item_t
* inputItem
;
99 std::string satIpHost
;
103 class MediaServerList
107 MediaServerList( services_discovery_t
* p_sd
);
110 bool addServer(MediaServerDesc
*desc
);
111 void removeServer(const std::string
&udn
);
112 MediaServerDesc
* getServer( const std::string
& udn
);
113 static int Callback( Upnp_EventType event_type
, UpnpEventPtr p_event
);
116 void parseNewServer( IXML_Document
* doc
, const std::string
& location
);
117 std::string
getIconURL( IXML_Element
* p_device_elem
, const char* psz_base_url
);
120 services_discovery_t
* const m_sd
;
121 std::vector
<MediaServerDesc
*> m_list
;
132 Upnp_i11e_cb( Upnp_FunPtr callback
, void *cookie
);
134 void waitAndRelease( void );
135 static int run( Upnp_EventType
, UpnpEventPtr
, void *);
141 Upnp_FunPtr m_callback
;
148 MediaServer( stream_t
* p_access
, input_item_node_t
* node
);
150 bool fetchContents();
153 MediaServer(const MediaServer
&);
154 MediaServer
& operator=(const MediaServer
&);
156 bool addContainer( IXML_Element
* containerElement
);
157 bool addItem( IXML_Element
* itemElement
);
159 IXML_Document
* _browseAction(const char*, const char*,
160 const char*, const char*, const char* );
161 static int sendActionCb( Upnp_EventType
, UpnpEventPtr
, void *);
165 char* m_psz_objectId
;
167 input_item_node_t
* m_node
;