merged: Platinum from linuxport branches
[xbmc:xbmc-antiquated.git] / xbmc / lib / libUPnP / Platinum / Source / Core / PltUPnP.cpp
1 /*****************************************************************\r
2 |\r
3 |   Platinum - UPnP Engine\r
4 |\r
5 |   Copyright (c) 2004-2008 Sylvain Rebaud\r
6 |   Author: Sylvain Rebaud (sylvain@rebaud.com)\r
7 |\r
8  ****************************************************************/\r
9 \r
10 /*----------------------------------------------------------------------\r
11 |   includes\r
12 +---------------------------------------------------------------------*/\r
13 #include "Neptune.h"\r
14 #include "PltUPnP.h"\r
15 #include "PltDeviceHost.h"\r
16 #include "PltCtrlPoint.h"\r
17 #include "PltSsdp.h"\r
18 \r
19 NPT_SET_LOCAL_LOGGER("platinum.core.upnp")\r
20 \r
21 /*----------------------------------------------------------------------\r
22 |   PLT_UPnP_CtrlPointStartIterator class\r
23 +---------------------------------------------------------------------*/\r
24 class PLT_UPnP_CtrlPointStartIterator\r
25 {\r
26 public:\r
27     PLT_UPnP_CtrlPointStartIterator(PLT_SsdpListenTask* listen_task) :\r
28         m_ListenTask(listen_task)  {}\r
29     virtual ~PLT_UPnP_CtrlPointStartIterator() {}\r
30 \r
31     NPT_Result operator()(PLT_CtrlPointReference& ctrl_point) const {\r
32         NPT_CHECK_SEVERE(ctrl_point->Start(m_ListenTask));\r
33         return NPT_SUCCESS;\r
34     }\r
35 \r
36 private:\r
37     PLT_SsdpListenTask* m_ListenTask;\r
38 };\r
39 \r
40 /*----------------------------------------------------------------------\r
41 |   PLT_UPnP_CtrlPointStopIterator class\r
42 +---------------------------------------------------------------------*/\r
43 class PLT_UPnP_CtrlPointStopIterator\r
44 {\r
45 public:\r
46     PLT_UPnP_CtrlPointStopIterator(PLT_SsdpListenTask* listen_task) :\r
47         m_ListenTask(listen_task)  {}\r
48     virtual ~PLT_UPnP_CtrlPointStopIterator() {}\r
49 \r
50     NPT_Result operator()(PLT_CtrlPointReference& ctrl_point) const {\r
51         return ctrl_point->Stop(m_ListenTask);\r
52     }\r
53 \r
54 \r
55 private:\r
56     PLT_SsdpListenTask* m_ListenTask;\r
57 };\r
58 \r
59 /*----------------------------------------------------------------------\r
60 |   PLT_UPnP_DeviceStartIterator class\r
61 +---------------------------------------------------------------------*/\r
62 class PLT_UPnP_DeviceStartIterator\r
63 {\r
64 public:\r
65     PLT_UPnP_DeviceStartIterator(PLT_SsdpListenTask* listen_task) :\r
66         m_ListenTask(listen_task)  {}\r
67     virtual ~PLT_UPnP_DeviceStartIterator() {}\r
68 \r
69     NPT_Result operator()(PLT_DeviceHostReference& device_host) const {\r
70         NPT_CHECK_SEVERE(device_host->Start(m_ListenTask));\r
71         return NPT_SUCCESS;\r
72     }\r
73 \r
74 private:\r
75     PLT_SsdpListenTask* m_ListenTask;\r
76 };\r
77 \r
78 /*----------------------------------------------------------------------\r
79 |   PLT_UPnP_DeviceStopIterator class\r
80 +---------------------------------------------------------------------*/\r
81 class PLT_UPnP_DeviceStopIterator\r
82 {\r
83 public:\r
84     PLT_UPnP_DeviceStopIterator(PLT_SsdpListenTask* listen_task) :\r
85         m_ListenTask(listen_task)  {}\r
86     virtual ~PLT_UPnP_DeviceStopIterator() {}\r
87 \r
88     NPT_Result operator()(PLT_DeviceHostReference& device_host) const {\r
89         return device_host->Stop(m_ListenTask);\r
90     }\r
91 \r
92 \r
93 private:\r
94     PLT_SsdpListenTask* m_ListenTask;\r
95 };\r
96 \r
97 /*----------------------------------------------------------------------\r
98 |   PLT_UPnP::PLT_UPnP\r
99 +---------------------------------------------------------------------*/\r
100 PLT_UPnP::PLT_UPnP(NPT_UInt32 port, bool multicast /* = true */) :\r
101     m_Started(false),\r
102     m_Port(port),\r
103     m_Multicast(multicast),\r
104     m_SsdpListenTask(NULL)\r
105 {\r
106 }\r
107     \r
108 /*----------------------------------------------------------------------\r
109 |   PLT_UPnP::~PLT_UPnP\r
110 +---------------------------------------------------------------------*/\r
111 PLT_UPnP::~PLT_UPnP()\r
112 {\r
113     Stop();\r
114 \r
115     m_CtrlPoints.Clear();\r
116     m_Devices.Clear();\r
117 }\r
118 \r
119 /*----------------------------------------------------------------------\r
120 |   PLT_UPnP::Start()\r
121 +---------------------------------------------------------------------*/\r
122 NPT_Result\r
123 PLT_UPnP::Start()\r
124 {\r
125     NPT_LOG_INFO("Starting UPnP...");\r
126 \r
127     NPT_AutoLock lock(m_Lock);\r
128 \r
129     if (m_Started == true) return NPT_FAILURE;\r
130 \r
131     NPT_Socket* socket = m_Multicast?new NPT_UdpMulticastSocket(): new NPT_UdpSocket();\r
132     NPT_CHECK_SEVERE(socket->Bind(NPT_SocketAddress(NPT_IpAddress::Any, m_Port)));\r
133 \r
134     /* create the ssdp listener */\r
135     m_SsdpListenTask = new PLT_SsdpListenTask(socket, m_Multicast);\r
136     NPT_CHECK_SEVERE(m_TaskManager.StartTask(m_SsdpListenTask));\r
137 \r
138     /* start devices & ctrlpoints */\r
139     m_CtrlPoints.Apply(PLT_UPnP_CtrlPointStartIterator(m_SsdpListenTask));\r
140     m_Devices.Apply(PLT_UPnP_DeviceStartIterator(m_SsdpListenTask));\r
141 \r
142     m_Started = true;\r
143     return NPT_SUCCESS;\r
144 }\r
145 \r
146 /*----------------------------------------------------------------------\r
147 |   PLT_UPnP::Stop\r
148 +---------------------------------------------------------------------*/\r
149 NPT_Result\r
150 PLT_UPnP::Stop()\r
151 {\r
152     NPT_AutoLock lock(m_Lock);\r
153 \r
154     if (m_Started == false) return NPT_FAILURE;\r
155 \r
156     NPT_LOG_INFO("Stopping UPnP...");\r
157 \r
158     // Stop ctrlpoints and devices first\r
159     m_CtrlPoints.Apply(PLT_UPnP_CtrlPointStopIterator(m_SsdpListenTask));\r
160     m_Devices.Apply(PLT_UPnP_DeviceStopIterator(m_SsdpListenTask));\r
161 \r
162     m_TaskManager.StopAllTasks();\r
163     m_SsdpListenTask = NULL;\r
164 \r
165     m_Started = false;\r
166     return NPT_SUCCESS;\r
167 }\r
168 \r
169 /*----------------------------------------------------------------------\r
170 |   PLT_UPnP::AddDevice\r
171 +---------------------------------------------------------------------*/\r
172 NPT_Result\r
173 PLT_UPnP::AddDevice(PLT_DeviceHostReference& device)\r
174 {\r
175     NPT_AutoLock lock(m_Lock);\r
176 \r
177     if (m_Started) {\r
178         NPT_LOG_INFO("Starting Device...");\r
179         NPT_CHECK_SEVERE(device->Start(m_SsdpListenTask));\r
180     }\r
181 \r
182     m_Devices.Add(device);\r
183     return NPT_SUCCESS;\r
184 }\r
185 \r
186 /*----------------------------------------------------------------------\r
187 |   PLT_UPnP::RemoveDevice\r
188 +---------------------------------------------------------------------*/\r
189 NPT_Result\r
190 PLT_UPnP::RemoveDevice(PLT_DeviceHostReference& device)\r
191 {\r
192     NPT_AutoLock lock(m_Lock);\r
193 \r
194     if (m_Started) {\r
195         device->Stop(m_SsdpListenTask);\r
196     }\r
197 \r
198     return m_Devices.Remove(device);\r
199 }\r
200 \r
201 /*----------------------------------------------------------------------\r
202 |   PLT_UPnP::AddCtrlPoint\r
203 +---------------------------------------------------------------------*/\r
204 NPT_Result\r
205 PLT_UPnP::AddCtrlPoint(PLT_CtrlPointReference& ctrl_point)\r
206 {\r
207     NPT_AutoLock lock(m_Lock);\r
208 \r
209     if (m_Started) {\r
210         NPT_LOG_INFO("Starting Ctrlpoint...");\r
211         NPT_CHECK_SEVERE(ctrl_point->Start(m_SsdpListenTask));\r
212     }\r
213 \r
214     m_CtrlPoints.Add(ctrl_point);\r
215     return NPT_SUCCESS;\r
216 }\r
217 \r
218 /*----------------------------------------------------------------------\r
219 |   PLT_UPnP::RemoveCtrlPoint\r
220 +---------------------------------------------------------------------*/\r
221 NPT_Result\r
222 PLT_UPnP::RemoveCtrlPoint(PLT_CtrlPointReference& ctrl_point)\r
223 {\r
224     NPT_AutoLock lock(m_Lock);\r
225 \r
226     if (m_Started) {\r
227         ctrl_point->Stop(m_SsdpListenTask);\r
228     }\r
229 \r
230     return m_CtrlPoints.Remove(ctrl_point);\r
231 }\r
232 \r