Platinum UPnP SDK
PltSsdp.h
Go to the documentation of this file.
1 /*****************************************************************
2 |
3 | Platinum - SSDP
4 |
5 | Copyright (c) 2004-2010, Plutinosoft, LLC.
6 | All rights reserved.
7 | http://www.plutinosoft.com
8 |
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.
13 |
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
21 |
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.
26 |
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
32 |
33 ****************************************************************/
34 
39 #ifndef _PLT_SSDP_H_
40 #define _PLT_SSDP_H_
41 
42 /*----------------------------------------------------------------------
43 | includes
44 +---------------------------------------------------------------------*/
45 #include "Neptune.h"
46 #include "PltThreadTask.h"
47 #include "PltHttpServerTask.h"
48 
49 /*----------------------------------------------------------------------
50 | forward declarations
51 +---------------------------------------------------------------------*/
52 class PLT_DeviceHost;
53 
54 /*----------------------------------------------------------------------
55 | PLT_SsdpPacketListener class
56 +---------------------------------------------------------------------*/
62 {
63 public:
64  virtual ~PLT_SsdpPacketListener() {}
65  virtual NPT_Result OnSsdpPacket(const NPT_HttpRequest& request,
66  const NPT_HttpRequestContext& context) = 0;
67 };
68 
69 /*----------------------------------------------------------------------
70 | PLT_SsdpSearchResponseListener class
71 +---------------------------------------------------------------------*/
77 {
78 public:
79  virtual ~PLT_SsdpSearchResponseListener() {}
80  virtual NPT_Result ProcessSsdpSearchResponse(NPT_Result res,
81  const NPT_HttpRequestContext& context,
82  NPT_HttpResponse* response) = 0;
83 };
84 
85 /*----------------------------------------------------------------------
86 | PLT_SsdpSender class
87 +---------------------------------------------------------------------*/
92 {
93 public:
94  static NPT_Result SendSsdp(NPT_HttpRequest& request,
95  const char* usn,
96  const char* nt,
97  NPT_UdpSocket& socket,
98  bool notify,
99  const NPT_SocketAddress* addr = NULL);
100 
101  static NPT_Result SendSsdp(NPT_HttpResponse& response,
102  const char* usn,
103  const char* nt,
104  NPT_UdpSocket& socket,
105  bool notify,
106  const NPT_SocketAddress* addr = NULL);
107 
108 private:
109  static NPT_Result FormatPacket(NPT_HttpMessage& message,
110  const char* usn,
111  const char* nt,
112  NPT_UdpSocket& socket,
113  bool notify);
114 };
115 
116 /*----------------------------------------------------------------------
117 | PLT_SsdpDeviceSearchResponseInterfaceIterator class
118 +---------------------------------------------------------------------*/
124 {
125 public:
127  NPT_SocketAddress remote_addr,
128  const char* st) :
129  m_Device(device), m_RemoteAddr(remote_addr), m_ST(st) {}
131 
132  NPT_Result operator()(NPT_NetworkInterface*& if_addr) const;
133 
134 private:
135  PLT_DeviceHost* m_Device;
136  NPT_SocketAddress m_RemoteAddr;
137  NPT_String m_ST;
138 };
139 
140 /*----------------------------------------------------------------------
141 | PLT_SsdpDeviceSearchResponseTask class
142 +---------------------------------------------------------------------*/
148 {
149 public:
151  NPT_SocketAddress remote_addr,
152  const char* st) :
153  m_Device(device), m_RemoteAddr(remote_addr), m_ST(st) {}
154 
155 protected:
157 
158  // PLT_ThreadTask methods
159  virtual void DoRun();
160 
161 protected:
162  PLT_DeviceHost* m_Device;
163  NPT_SocketAddress m_RemoteAddr;
164  NPT_String m_ST;
165 };
166 
167 /*----------------------------------------------------------------------
168 | PLT_SsdpAnnounceInterfaceIterator class
169 +---------------------------------------------------------------------*/
175 {
176 public:
177  PLT_SsdpAnnounceInterfaceIterator(PLT_DeviceHost* device, bool is_byebye = false, bool broadcast = false) :
178  m_Device(device), m_IsByeBye(is_byebye), m_Broadcast(broadcast) {}
179 
180  NPT_Result operator()(NPT_NetworkInterface*& if_addr) const;
181 
182 private:
183  PLT_DeviceHost* m_Device;
184  bool m_IsByeBye;
185  bool m_Broadcast;
186 };
187 
188 /*----------------------------------------------------------------------
189 | PLT_SsdpInitMulticastIterator class
190 +---------------------------------------------------------------------*/
196 {
197 public:
198  PLT_SsdpInitMulticastIterator(NPT_UdpMulticastSocket* socket) :
199  m_Socket(socket) {}
200 
201  NPT_Result operator()(NPT_IpAddress& if_addr) const {
202  NPT_IpAddress addr;
203  addr.ResolveName("239.255.255.250");
204  // OSX bug, since we're reusing the socket, we need to leave group first
205  // before joining it
206  m_Socket->LeaveGroup(addr, if_addr);
207  return m_Socket->JoinGroup(addr, if_addr);
208  }
209 
210 private:
211  NPT_UdpMulticastSocket* m_Socket;
212 };
213 
214 /*----------------------------------------------------------------------
215 | PLT_SsdpDeviceAnnounceTask class
216 +---------------------------------------------------------------------*/
222 {
223 public:
225  NPT_TimeInterval repeat,
226  bool is_byebye_first = false,
227  bool extra_broadcast = false) :
228  m_Device(device),
229  m_Repeat(repeat), m_IsByeByeFirst(is_byebye_first),
230  m_ExtraBroadcast(extra_broadcast) {}
231 
232 protected:
233  virtual ~PLT_SsdpDeviceAnnounceTask() {}
234 
235  // PLT_ThreadTask methods
236  virtual void DoRun();
237 
238 protected:
239  PLT_DeviceHost* m_Device;
240  NPT_TimeInterval m_Repeat;
241  bool m_IsByeByeFirst;
242  bool m_ExtraBroadcast;
243 };
244 
245 /*----------------------------------------------------------------------
246 | PLT_NetworkInterfaceAddressSearchIterator class
247 +---------------------------------------------------------------------*/
253 {
254 public:
255  PLT_NetworkInterfaceAddressSearchIterator(NPT_String ip) : m_Ip(ip) {}
257 
258  NPT_Result operator()(NPT_NetworkInterface*& addr) const {
259  NPT_List<NPT_NetworkInterfaceAddress>::Iterator niaddr = addr->GetAddresses().GetFirstItem();
260  if (!niaddr) return NPT_FAILURE;
261 
262  return (m_Ip.Compare((*niaddr).GetPrimaryAddress().ToString(), true) == 0) ? NPT_SUCCESS : NPT_FAILURE;
263  }
264 
265 private:
266  NPT_String m_Ip;
267 };
268 
269 /*----------------------------------------------------------------------
270 | PLT_SsdpPacketListenerIterator class
271 +---------------------------------------------------------------------*/
277 {
278 public:
279  PLT_SsdpPacketListenerIterator(NPT_HttpRequest& request,
280  const NPT_HttpRequestContext& context) :
281  m_Request(request), m_Context(context) {}
282 
283  NPT_Result operator()(PLT_SsdpPacketListener*& listener) const {
284  return listener->OnSsdpPacket(m_Request, m_Context);
285  }
286 
287 private:
288  NPT_HttpRequest& m_Request;
289  const NPT_HttpRequestContext& m_Context;
290 };
291 
292 /*----------------------------------------------------------------------
293 | PLT_SsdpListenTask class
294 +---------------------------------------------------------------------*/
301 {
302 public:
303  PLT_SsdpListenTask(NPT_Socket* socket) :
304  PLT_HttpServerSocketTask(socket, true) {
305  // Change read time out for UDP because iPhone 3.0 seems to hang
306  // after reading everything from the socket even though
307  // more stuff arrived
308 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
309  m_Socket->SetReadTimeout(10000);
310 #endif
311  }
312 
313  NPT_Result AddListener(PLT_SsdpPacketListener* listener) {
314  NPT_AutoLock lock(m_Mutex);
315  m_Listeners.Add(listener);
316  return NPT_SUCCESS;
317  }
318 
319  NPT_Result RemoveListener(PLT_SsdpPacketListener* listener) {
320  NPT_AutoLock lock(m_Mutex);
321  m_Listeners.Remove(listener);
322  return NPT_SUCCESS;
323  }
324 
325  // PLT_Task methods
326  void DoAbort();
327 
328 protected:
329  virtual ~PLT_SsdpListenTask() {}
330 
331  // PLT_HttpServerSocketTask methods
332  NPT_Result GetInputStream(NPT_InputStreamReference& stream);
333  NPT_Result GetInfo(NPT_SocketInfo& info);
334  NPT_Result SetupResponse(NPT_HttpRequest& request,
335  const NPT_HttpRequestContext& context,
336  NPT_HttpResponse& response);
337 
338 protected:
339  PLT_InputDatagramStreamReference m_Datagram;
340  NPT_List<PLT_SsdpPacketListener*> m_Listeners;
341  NPT_Mutex m_Mutex;
342 };
343 
344 /*----------------------------------------------------------------------
345 | PLT_SsdpSearchTask class
346 +---------------------------------------------------------------------*/
352 {
353 public:
354  PLT_SsdpSearchTask(NPT_UdpSocket* socket,
356  NPT_HttpRequest* request,
357  NPT_TimeInterval frequency = NPT_TimeInterval(0.)); // pass 0 for one time
358 
359 protected:
360  virtual ~PLT_SsdpSearchTask();
361 
362  // PLT_ThreadTask methods
363  virtual void DoAbort();
364  virtual void DoRun();
365 
366  virtual NPT_Result ProcessResponse(NPT_Result res,
367  const NPT_HttpRequest& request,
368  const NPT_HttpRequestContext& context,
369  NPT_HttpResponse* response);
370 
371 private:
372  PLT_SsdpSearchResponseListener* m_Listener;
373  NPT_HttpRequest* m_Request;
374  NPT_TimeInterval m_Frequency;
375  bool m_Repeat;
376  NPT_UdpSocket* m_Socket;
377 };
378 
379 #endif /* _PLT_SSDP_H_ */