1 /*****************************************************************
5 | Copyright (c) 2004-2010, Plutinosoft, LLC.
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 ****************************************************************/
42 /*----------------------------------------------------------------------
44 +---------------------------------------------------------------------*/
46 #include "PltThreadTask.h"
47 #include "PltHttpServerTask.h"
49 /*----------------------------------------------------------------------
50 | forward declarations
51 +---------------------------------------------------------------------*/
54 /*----------------------------------------------------------------------
55 | PLT_SsdpAnnounceType
56 +---------------------------------------------------------------------*/
58 PLT_ANNOUNCETYPE_BYEBYE
,
59 PLT_ANNOUNCETYPE_ALIVE
,
60 PLT_ANNOUNCETYPE_UPDATE
61 } PLT_SsdpAnnounceType
;
63 /*----------------------------------------------------------------------
64 | PLT_SsdpPacketListener class
65 +---------------------------------------------------------------------*/
67 The PLT_SsdpPacketListener class is an interface for handling SSDP packets
68 (M-SEARCH and NOTIFY).
70 class PLT_SsdpPacketListener
73 virtual ~PLT_SsdpPacketListener() {}
74 virtual NPT_Result
OnSsdpPacket(const NPT_HttpRequest
& request
,
75 const NPT_HttpRequestContext
& context
) = 0;
78 /*----------------------------------------------------------------------
79 | PLT_SsdpSearchResponseListener class
80 +---------------------------------------------------------------------*/
82 The PLT_SsdpSearchResponseListener class is an interface for handling SSDP M-SEARCH
85 class PLT_SsdpSearchResponseListener
88 virtual ~PLT_SsdpSearchResponseListener() {}
89 virtual NPT_Result
ProcessSsdpSearchResponse(NPT_Result res
,
90 const NPT_HttpRequestContext
& context
,
91 NPT_HttpResponse
* response
) = 0;
94 /*----------------------------------------------------------------------
95 | PLT_SsdpSender class
96 +---------------------------------------------------------------------*/
98 The PLT_SsdpSender class provides a mechanism to format and send SSDP packets.
103 static NPT_Result
SendSsdp(NPT_HttpRequest
& request
,
106 NPT_UdpSocket
& socket
,
108 const NPT_SocketAddress
* addr
= NULL
);
110 static NPT_Result
SendSsdp(NPT_HttpResponse
& response
,
113 NPT_UdpSocket
& socket
,
115 const NPT_SocketAddress
* addr
= NULL
);
118 static NPT_Result
FormatPacket(NPT_HttpMessage
& message
,
121 NPT_UdpSocket
& socket
,
125 /*----------------------------------------------------------------------
126 | PLT_SsdpDeviceSearchResponseInterfaceIterator class
127 +---------------------------------------------------------------------*/
129 The PLT_SsdpDeviceSearchResponseInterfaceIterator class looks for the best network
130 interface to use then sends a SSDP M-SEARCH response.
132 class PLT_SsdpDeviceSearchResponseInterfaceIterator
135 PLT_SsdpDeviceSearchResponseInterfaceIterator(PLT_DeviceHost
* device
,
136 NPT_SocketAddress remote_addr
,
138 m_Device(device
), m_RemoteAddr(remote_addr
), m_ST(st
) {}
139 virtual ~PLT_SsdpDeviceSearchResponseInterfaceIterator() {}
141 NPT_Result
operator()(NPT_NetworkInterface
*& if_addr
) const;
144 PLT_DeviceHost
* m_Device
;
145 NPT_SocketAddress m_RemoteAddr
;
149 /*----------------------------------------------------------------------
150 | PLT_SsdpDeviceSearchResponseTask class
151 +---------------------------------------------------------------------*/
153 The PLT_SsdpDeviceSearchResponseTask class is used by a PLT_DeviceHost to respond
154 to SSDP M-SEARCH requests from UPnP ControlPoints.
156 class PLT_SsdpDeviceSearchResponseTask
: public PLT_ThreadTask
159 PLT_SsdpDeviceSearchResponseTask(PLT_DeviceHost
* device
,
160 NPT_SocketAddress remote_addr
,
162 m_Device(device
), m_RemoteAddr(remote_addr
), m_ST(st
) {}
165 ~PLT_SsdpDeviceSearchResponseTask() override
{}
167 // PLT_ThreadTask methods
168 void DoRun() override
;
171 PLT_DeviceHost
* m_Device
;
172 NPT_SocketAddress m_RemoteAddr
;
176 /*----------------------------------------------------------------------
177 | PLT_SsdpAnnounceInterfaceIterator class
178 +---------------------------------------------------------------------*/
180 The PLT_SsdpAnnounceInterfaceIterator class is used to send SSDP announcements
181 given a list of network interaces.
183 class PLT_SsdpAnnounceInterfaceIterator
186 PLT_SsdpAnnounceInterfaceIterator(PLT_DeviceHost
* device
, PLT_SsdpAnnounceType type
, bool broadcast
= false) :
187 m_Device(device
), m_Type(type
), m_Broadcast(broadcast
) {}
189 NPT_Result
operator()(NPT_NetworkInterface
*& if_addr
) const;
192 PLT_DeviceHost
* m_Device
;
193 PLT_SsdpAnnounceType m_Type
;
197 /*----------------------------------------------------------------------
198 | PLT_SsdpInitMulticastIterator class
199 +---------------------------------------------------------------------*/
201 The PLT_SsdpInitMulticastIterator class is used to join a multicast group
202 given a list of IP addresses.
204 class PLT_SsdpInitMulticastIterator
207 PLT_SsdpInitMulticastIterator(NPT_UdpMulticastSocket
* socket
) :
210 NPT_Result
operator()(NPT_IpAddress
& if_addr
) const {
212 addr
.ResolveName("239.255.255.250");
213 // OSX bug, since we're reusing the socket, we need to leave group first
215 m_Socket
->LeaveGroup(addr
, if_addr
);
216 return m_Socket
->JoinGroup(addr
, if_addr
);
220 NPT_UdpMulticastSocket
* m_Socket
;
223 /*----------------------------------------------------------------------
224 | PLT_SsdpDeviceAnnounceTask class
225 +---------------------------------------------------------------------*/
227 The PLT_SsdpDeviceAnnounceTask class is a task to send UPnP Device SSDP announcements
228 (alive or byebye). It can be setup to automatically repeat after an interval.
230 class PLT_SsdpDeviceAnnounceTask
: public PLT_ThreadTask
233 PLT_SsdpDeviceAnnounceTask(PLT_DeviceHost
* device
,
234 NPT_TimeInterval repeat
,
235 bool is_byebye_first
= false,
236 bool extra_broadcast
= false) :
239 m_IsByeByeFirst(is_byebye_first
),
240 m_ExtraBroadcast(extra_broadcast
) {}
243 ~PLT_SsdpDeviceAnnounceTask() override
{}
245 // PLT_ThreadTask methods
246 void DoRun() override
;
249 PLT_DeviceHost
* m_Device
;
250 NPT_TimeInterval m_Repeat
;
251 bool m_IsByeByeFirst
;
252 bool m_ExtraBroadcast
;
255 /*----------------------------------------------------------------------
256 | PLT_NetworkInterfaceAddressSearchIterator class
257 +---------------------------------------------------------------------*/
259 The PLT_NetworkInterfaceAddressSearchIterator class returns the network interface
262 class PLT_NetworkInterfaceAddressSearchIterator
265 PLT_NetworkInterfaceAddressSearchIterator(NPT_String ip
) : m_Ip(ip
) {}
266 virtual ~PLT_NetworkInterfaceAddressSearchIterator() {}
268 NPT_Result
operator()(NPT_NetworkInterface
*& addr
) const {
269 NPT_List
<NPT_NetworkInterfaceAddress
>::Iterator niaddr
= addr
->GetAddresses().GetFirstItem();
270 if (!niaddr
) return NPT_FAILURE
;
272 return (m_Ip
.Compare((*niaddr
).GetPrimaryAddress().ToString(), true) == 0) ? NPT_SUCCESS
: NPT_FAILURE
;
279 /*----------------------------------------------------------------------
280 | PLT_SsdpPacketListenerIterator class
281 +---------------------------------------------------------------------*/
283 The PLT_SsdpPacketListenerIterator class iterates through a list of
284 PLT_SsdpPacketListener instances to notify of a new SSDP incoming packet.
286 class PLT_SsdpPacketListenerIterator
289 PLT_SsdpPacketListenerIterator(NPT_HttpRequest
& request
,
290 const NPT_HttpRequestContext
& context
) :
291 m_Request(request
), m_Context(context
) {}
293 NPT_Result
operator()(PLT_SsdpPacketListener
*& listener
) const {
294 return listener
->OnSsdpPacket(m_Request
, m_Context
);
298 NPT_HttpRequest
& m_Request
;
299 const NPT_HttpRequestContext
& m_Context
;
302 /*----------------------------------------------------------------------
303 | PLT_SsdpListenTask class
304 +---------------------------------------------------------------------*/
306 The PLT_SsdpListenTask class is used to listen for incoming SSDP packets and
307 keep track of a list of PLT_SsdpPacketListener listeners to notify when a new
308 SSDP packet has arrived.
310 class PLT_SsdpListenTask
: public PLT_HttpServerSocketTask
313 PLT_SsdpListenTask(NPT_Socket
* socket
) :
314 PLT_HttpServerSocketTask(socket
, true) {
315 // Change read time out for UDP because iPhone 3.0 seems to hang
316 // after reading everything from the socket even though
317 // more stuff arrived
318 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
319 m_Socket
->SetReadTimeout(10000);
323 NPT_Result
AddListener(PLT_SsdpPacketListener
* listener
) {
324 NPT_AutoLock
lock(m_Mutex
);
325 m_Listeners
.Add(listener
);
329 NPT_Result
RemoveListener(PLT_SsdpPacketListener
* listener
) {
330 NPT_AutoLock
lock(m_Mutex
);
331 m_Listeners
.Remove(listener
);
336 void DoAbort() override
;
339 ~PLT_SsdpListenTask() override
{}
341 // PLT_HttpServerSocketTask methods
342 NPT_Result
GetInputStream(NPT_InputStreamReference
& stream
) override
;
343 NPT_Result
GetInfo(NPT_SocketInfo
& info
) override
;
344 NPT_Result
SetupResponse(NPT_HttpRequest
& request
,
345 const NPT_HttpRequestContext
& context
,
346 NPT_HttpResponse
& response
) override
;
349 PLT_InputDatagramStreamReference m_Datagram
;
350 NPT_List
<PLT_SsdpPacketListener
*> m_Listeners
;
354 /*----------------------------------------------------------------------
355 | PLT_SsdpSearchTask class
356 +---------------------------------------------------------------------*/
358 The PLT_SsdpSearchTask class is a task used by a PLT_CtrlPoint to issue a SSDP
359 M-SEARCH request. It can be set to repeat at a certain frequencey.
361 class PLT_SsdpSearchTask
: public PLT_ThreadTask
364 PLT_SsdpSearchTask(NPT_UdpSocket
* socket
,
365 PLT_SsdpSearchResponseListener
* listener
,
366 NPT_HttpRequest
* request
,
367 NPT_TimeInterval frequency
= NPT_TimeInterval(0.)); // pass 0 for one time
370 ~PLT_SsdpSearchTask() override
;
372 // PLT_ThreadTask methods
373 void DoAbort() override
;
374 void DoRun() override
;
376 virtual NPT_Result
ProcessResponse(NPT_Result res
,
377 const NPT_HttpRequest
& request
,
378 const NPT_HttpRequestContext
& context
,
379 NPT_HttpResponse
* response
);
382 PLT_SsdpSearchResponseListener
* m_Listener
;
383 NPT_HttpRequest
* m_Request
;
384 NPT_TimeInterval m_Frequency
;
386 NPT_UdpSocket
* m_Socket
;
389 #endif /* _PLT_SSDP_H_ */