]> git.sesse.net Git - vlc/blob - modules/services_discovery/upnp.hpp
478cc08c85f2fbf336b2238185138d9a21b21a8b
[vlc] / 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 #include <vector>
30 #include <string>
31
32 #include <upnp/upnp.h>
33 #include <upnp/upnptools.h>
34
35 #include <vlc_common.h>
36
37 namespace SD
38 {
39     class MediaServerList;
40 }
41
42 /*
43  * libUpnp allows only one instance per process, so we have to share one for
44  * both SD & Access module
45  * Since the callback is bound to the UpnpClient_Handle, we have to register
46  * a wrapper callback, in order for the access module to be able to initialize
47  * libUpnp first.
48  * When a SD wishes to use libUpnp, it will provide its own callback, that the
49  * wrapper will forward.
50  * This way, we always have a register callback & a client handle.
51  */
52 class UpnpInstanceWrapper
53 {
54 public:    
55     // This increases the refcount before returning the instance
56     static UpnpInstanceWrapper* get(vlc_object_t* p_obj, Upnp_FunPtr callback, SD::MediaServerList *opaque);
57     void release(bool isSd);
58     UpnpClient_Handle handle() const;
59
60 private:
61     static int Callback( Upnp_EventType event_type, void* p_event, void* p_user_data );
62
63     UpnpInstanceWrapper();
64     ~UpnpInstanceWrapper();
65
66 private:
67     static UpnpInstanceWrapper* s_instance;
68     static vlc_mutex_t s_lock;
69     UpnpClient_Handle handle_;
70     SD::MediaServerList* opaque_;
71     Upnp_FunPtr callback_;
72     int refcount_;
73 };
74
75 namespace SD
76 {
77
78 struct MediaServerDesc
79 {
80     MediaServerDesc(const std::string& udn, const std::string& fName, const std::string& loc);
81     ~MediaServerDesc();
82     std::string UDN;
83     std::string friendlyName;
84     std::string location;
85     input_item_t* inputItem;
86 };
87
88
89 class MediaServerList
90 {
91 public:
92
93     MediaServerList( services_discovery_t* p_sd );
94     ~MediaServerList();
95
96     bool addServer(MediaServerDesc *desc );
97     void removeServer(const std::string &udn );
98     MediaServerDesc* getServer( const std::string& udn );
99     static int Callback( Upnp_EventType event_type, void* p_event, void* p_user_data );
100
101 private:
102     void parseNewServer( IXML_Document* doc, const std::string& location );
103
104 private:
105     services_discovery_t* p_sd_;
106     std::vector<MediaServerDesc*> list_;
107     vlc_mutex_t lock_;
108 };
109
110 }
111
112 namespace Access
113 {
114
115 class MediaServer
116 {
117 public:
118     MediaServer( const char* psz_url, access_t* p_access, input_item_node_t* node );
119     bool fetchContents();
120
121 private:
122     MediaServer(const MediaServer&);
123     MediaServer& operator=(const MediaServer&);
124
125     void addItem(const char* objectID, const char* title);
126     void addItem(const char* title, const char* psz_objectID, const char* psz_subtitles, mtime_t duration, const char* psz_url );
127
128     IXML_Document* _browseAction(const char*, const char*,
129             const char*, const char*, const char* );
130
131 private:
132     const std::string url_;
133     access_t* access_;
134     input_item_node_t* node_;
135 };
136
137 }