Merge pull request #25959 from neo1973/TagLib_deprecation_warnings
[xbmc.git] / lib / libUPnP / Platinum / Source / Core / PltUPnP.cpp
blobe0b1e8b7340d4286748c239b5af01cf95967057b
1 /*****************************************************************
3 | Platinum - UPnP Engine
5 | Copyright (c) 2004-2010, Plutinosoft, LLC.
6 | All rights reserved.
7 | http://www.plutinosoft.com
9 | This program is free software; you can redistribute it and/or
10 | modify it under the terms of the GNU General Public License
11 | as published by the Free Software Foundation; either version 2
12 | of the License, or (at your option) any later version.
14 | OEMs, ISVs, VARs and other distributors that combine and
15 | distribute commercially licensed software with Platinum software
16 | and do not wish to distribute the source code for the commercially
17 | licensed software under version 2, or (at your option) any later
18 | version, of the GNU General Public License (the "GPL") must enter
19 | into a commercial license agreement with Plutinosoft, LLC.
20 | licensing@plutinosoft.com
22 | This program is distributed in the hope that it will be useful,
23 | but WITHOUT ANY WARRANTY; without even the implied warranty of
24 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 | GNU General Public License for more details.
27 | You should have received a copy of the GNU General Public License
28 | along with this program; see the file LICENSE.txt. If not, write to
29 | the Free Software Foundation, Inc.,
30 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
31 | http://www.gnu.org/licenses/gpl-2.0.html
33 ****************************************************************/
35 /*----------------------------------------------------------------------
36 | includes
37 +---------------------------------------------------------------------*/
38 #include "Neptune.h"
39 #include "PltVersion.h"
40 #include "PltUPnP.h"
41 #include "PltDeviceHost.h"
42 #include "PltCtrlPoint.h"
43 #include "PltSsdp.h"
45 NPT_SET_LOCAL_LOGGER("platinum.core.upnp")
47 /*----------------------------------------------------------------------
48 | PLT_UPnP_CtrlPointStartIterator class
49 +---------------------------------------------------------------------*/
50 class PLT_UPnP_CtrlPointStartIterator
52 public:
53 PLT_UPnP_CtrlPointStartIterator(PLT_SsdpListenTask* listen_task) :
54 m_ListenTask(listen_task) {}
55 virtual ~PLT_UPnP_CtrlPointStartIterator() {}
57 NPT_Result operator()(PLT_CtrlPointReference& ctrl_point) const {
58 NPT_CHECK_SEVERE(ctrl_point->Start(m_ListenTask));
59 return NPT_SUCCESS;
62 private:
63 PLT_SsdpListenTask* m_ListenTask;
66 /*----------------------------------------------------------------------
67 | PLT_UPnP_CtrlPointStopIterator class
68 +---------------------------------------------------------------------*/
69 class PLT_UPnP_CtrlPointStopIterator
71 public:
72 PLT_UPnP_CtrlPointStopIterator(PLT_SsdpListenTask* listen_task) :
73 m_ListenTask(listen_task) {}
74 virtual ~PLT_UPnP_CtrlPointStopIterator() {}
76 NPT_Result operator()(PLT_CtrlPointReference& ctrl_point) const {
77 return ctrl_point->Stop(m_ListenTask);
81 private:
82 PLT_SsdpListenTask* m_ListenTask;
85 /*----------------------------------------------------------------------
86 | PLT_UPnP_DeviceStartIterator class
87 +---------------------------------------------------------------------*/
88 class PLT_UPnP_DeviceStartIterator
90 public:
91 PLT_UPnP_DeviceStartIterator(PLT_SsdpListenTask* listen_task) :
92 m_ListenTask(listen_task) {}
93 virtual ~PLT_UPnP_DeviceStartIterator() {}
95 NPT_Result operator()(PLT_DeviceHostReference& device_host) const {
97 // We should always increment the boot id on restart
98 // so it is used in place of boot id during initial announcement
99 device_host->SetBootId(device_host->GenerateNextBootId());
100 device_host->SetNextBootId(0);
102 NPT_CHECK_SEVERE(device_host->Start(m_ListenTask));
103 return NPT_SUCCESS;
106 private:
107 PLT_SsdpListenTask* m_ListenTask;
110 /*----------------------------------------------------------------------
111 | PLT_UPnP_DeviceStopIterator class
112 +---------------------------------------------------------------------*/
113 class PLT_UPnP_DeviceStopIterator
115 public:
116 PLT_UPnP_DeviceStopIterator(PLT_SsdpListenTask* listen_task) :
117 m_ListenTask(listen_task) {}
118 virtual ~PLT_UPnP_DeviceStopIterator() {}
120 NPT_Result operator()(PLT_DeviceHostReference& device_host) const {
121 return device_host->Stop(m_ListenTask);
125 private:
126 PLT_SsdpListenTask* m_ListenTask;
129 /*----------------------------------------------------------------------
130 | PLT_UPnP::PLT_UPnP
131 +---------------------------------------------------------------------*/
132 PLT_UPnP::PLT_UPnP() :
133 m_TaskManager(NULL),
134 m_Started(false),
135 m_SsdpListenTask(NULL),
136 m_IgnoreLocalUUIDs(true)
140 /*----------------------------------------------------------------------
141 | PLT_UPnP::~PLT_UPnP
142 +---------------------------------------------------------------------*/
143 PLT_UPnP::~PLT_UPnP()
145 Stop();
147 m_CtrlPoints.Clear();
148 m_Devices.Clear();
151 /*----------------------------------------------------------------------
152 | PLT_UPnP::Start()
153 +---------------------------------------------------------------------*/
154 NPT_Result
155 PLT_UPnP::Start()
157 NPT_LOG_INFO("Starting UPnP...");
159 NPT_AutoLock lock(m_Lock);
161 if (m_Started) NPT_CHECK_WARNING(NPT_ERROR_INVALID_STATE);
163 NPT_List<NPT_IpAddress> ips;
164 PLT_UPnPMessageHelper::GetIPAddresses(ips);
166 /* Create multicast socket and bind on 1900. If other apps didn't
167 play nicely by setting the REUSE_ADDR flag, this could fail */
168 NPT_Reference<NPT_UdpMulticastSocket> socket(new NPT_UdpMulticastSocket(NPT_SOCKET_FLAG_CANCELLABLE));
169 NPT_CHECK_SEVERE(socket->Bind(NPT_SocketAddress(NPT_IpAddress::Any, 1900), true));
171 /* Join multicast group for every ip we found */
172 NPT_CHECK_SEVERE(ips.ApplyUntil(PLT_SsdpInitMulticastIterator(socket.AsPointer()),
173 NPT_UntilResultNotEquals(NPT_SUCCESS)));
175 /* create the ssdp listener */
176 m_SsdpListenTask = new PLT_SsdpListenTask(socket.AsPointer());
177 socket.Detach();
178 NPT_Reference<PLT_TaskManager> taskManager(new PLT_TaskManager());
179 NPT_CHECK_SEVERE(taskManager->StartTask(m_SsdpListenTask));
181 /* start devices & ctrlpoints */
182 m_CtrlPoints.Apply(PLT_UPnP_CtrlPointStartIterator(m_SsdpListenTask));
183 m_Devices.Apply(PLT_UPnP_DeviceStartIterator(m_SsdpListenTask));
185 m_TaskManager = taskManager;
186 m_Started = true;
187 return NPT_SUCCESS;
190 /*----------------------------------------------------------------------
191 | PLT_UPnP::Stop
192 +---------------------------------------------------------------------*/
193 NPT_Result
194 PLT_UPnP::Stop()
196 NPT_AutoLock lock(m_Lock);
198 if (!m_Started) NPT_CHECK_WARNING(NPT_ERROR_INVALID_STATE);
200 NPT_LOG_INFO("Stopping UPnP...");
202 // Stop ctrlpoints and devices first
203 m_CtrlPoints.Apply(PLT_UPnP_CtrlPointStopIterator(m_SsdpListenTask));
204 m_Devices.Apply(PLT_UPnP_DeviceStopIterator(m_SsdpListenTask));
206 // stop remaining tasks
207 m_TaskManager->Abort();
208 m_SsdpListenTask = NULL;
209 m_TaskManager = NULL;
211 m_Started = false;
212 return NPT_SUCCESS;
215 /*----------------------------------------------------------------------
216 | PLT_UPnP::AddDevice
217 +---------------------------------------------------------------------*/
218 NPT_Result
219 PLT_UPnP::AddDevice(PLT_DeviceHostReference& device)
221 NPT_AutoLock lock(m_Lock);
223 // tell all our controllers to ignore this device
224 if (m_IgnoreLocalUUIDs) {
225 for (NPT_List<PLT_CtrlPointReference>::Iterator iter =
226 m_CtrlPoints.GetFirstItem();
227 iter;
228 iter++) {
229 (*iter)->IgnoreUUID(device->GetUUID());
233 if (m_Started) {
234 NPT_LOG_INFO("Starting Device...");
235 NPT_CHECK_SEVERE(device->Start(m_SsdpListenTask));
238 m_Devices.Add(device);
239 return NPT_SUCCESS;
242 /*----------------------------------------------------------------------
243 | PLT_UPnP::RemoveDevice
244 +---------------------------------------------------------------------*/
245 NPT_Result
246 PLT_UPnP::RemoveDevice(PLT_DeviceHostReference& device)
248 NPT_AutoLock lock(m_Lock);
250 if (m_Started) {
251 device->Stop(m_SsdpListenTask);
254 return m_Devices.Remove(device);
257 /*----------------------------------------------------------------------
258 | PLT_UPnP::AddCtrlPoint
259 +---------------------------------------------------------------------*/
260 NPT_Result
261 PLT_UPnP::AddCtrlPoint(PLT_CtrlPointReference& ctrl_point)
263 NPT_AutoLock lock(m_Lock);
265 // tell the control point to ignore our own running devices
266 if (m_IgnoreLocalUUIDs) {
267 for (NPT_List<PLT_DeviceHostReference>::Iterator iter =
268 m_Devices.GetFirstItem();
269 iter;
270 iter++) {
271 ctrl_point->IgnoreUUID((*iter)->GetUUID());
275 if (m_Started) {
276 NPT_LOG_INFO("Starting Ctrlpoint...");
277 NPT_CHECK_SEVERE(ctrl_point->Start(m_SsdpListenTask));
280 m_CtrlPoints.Add(ctrl_point);
281 return NPT_SUCCESS;
284 /*----------------------------------------------------------------------
285 | PLT_UPnP::RemoveCtrlPoint
286 +---------------------------------------------------------------------*/
287 NPT_Result
288 PLT_UPnP::RemoveCtrlPoint(PLT_CtrlPointReference& ctrl_point)
290 NPT_AutoLock lock(m_Lock);
292 if (m_Started) {
293 ctrl_point->Stop(m_SsdpListenTask);
296 return m_CtrlPoints.Remove(ctrl_point);