diff options
Diffstat (limited to 'lib/libUPnP/Platinum/Source/Core/PltSsdp.h')
-rw-r--r-- | lib/libUPnP/Platinum/Source/Core/PltSsdp.h | 389 |
1 files changed, 389 insertions, 0 deletions
diff --git a/lib/libUPnP/Platinum/Source/Core/PltSsdp.h b/lib/libUPnP/Platinum/Source/Core/PltSsdp.h new file mode 100644 index 0000000..0bbbd75 --- /dev/null +++ b/lib/libUPnP/Platinum/Source/Core/PltSsdp.h @@ -0,0 +1,389 @@ +/***************************************************************** +| +| Platinum - SSDP +| +| Copyright (c) 2004-2010, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| licensing@plutinosoft.com +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +/** @file + UPnP SSDP + */ + +#ifndef _PLT_SSDP_H_ +#define _PLT_SSDP_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Neptune.h" +#include "PltThreadTask.h" +#include "PltHttpServerTask.h" + +/*---------------------------------------------------------------------- +| forward declarations ++---------------------------------------------------------------------*/ +class PLT_DeviceHost; + +/*---------------------------------------------------------------------- +| PLT_SsdpAnnounceType ++---------------------------------------------------------------------*/ +typedef enum { + PLT_ANNOUNCETYPE_BYEBYE, + PLT_ANNOUNCETYPE_ALIVE, + PLT_ANNOUNCETYPE_UPDATE +} PLT_SsdpAnnounceType; + +/*---------------------------------------------------------------------- +| PLT_SsdpPacketListener class ++---------------------------------------------------------------------*/ +/** + The PLT_SsdpPacketListener class is an interface for handling SSDP packets + (M-SEARCH and NOTIFY). + */ +class PLT_SsdpPacketListener +{ +public: + virtual ~PLT_SsdpPacketListener() {} + virtual NPT_Result OnSsdpPacket(const NPT_HttpRequest& request, + const NPT_HttpRequestContext& context) = 0; +}; + +/*---------------------------------------------------------------------- +| PLT_SsdpSearchResponseListener class ++---------------------------------------------------------------------*/ +/** + The PLT_SsdpSearchResponseListener class is an interface for handling SSDP M-SEARCH + responses. + */ +class PLT_SsdpSearchResponseListener +{ +public: + virtual ~PLT_SsdpSearchResponseListener() {} + virtual NPT_Result ProcessSsdpSearchResponse(NPT_Result res, + const NPT_HttpRequestContext& context, + NPT_HttpResponse* response) = 0; +}; + +/*---------------------------------------------------------------------- +| PLT_SsdpSender class ++---------------------------------------------------------------------*/ +/** + The PLT_SsdpSender class provides a mechanism to format and send SSDP packets. + */ +class PLT_SsdpSender +{ +public: + static NPT_Result SendSsdp(NPT_HttpRequest& request, + const char* usn, + const char* nt, + NPT_UdpSocket& socket, + bool notify, + const NPT_SocketAddress* addr = NULL); + + static NPT_Result SendSsdp(NPT_HttpResponse& response, + const char* usn, + const char* nt, + NPT_UdpSocket& socket, + bool notify, + const NPT_SocketAddress* addr = NULL); + +private: + static NPT_Result FormatPacket(NPT_HttpMessage& message, + const char* usn, + const char* nt, + NPT_UdpSocket& socket, + bool notify); +}; + +/*---------------------------------------------------------------------- +| PLT_SsdpDeviceSearchResponseInterfaceIterator class ++---------------------------------------------------------------------*/ +/** + The PLT_SsdpDeviceSearchResponseInterfaceIterator class looks for the best network + interface to use then sends a SSDP M-SEARCH response. + */ +class PLT_SsdpDeviceSearchResponseInterfaceIterator +{ +public: + PLT_SsdpDeviceSearchResponseInterfaceIterator(PLT_DeviceHost* device, + NPT_SocketAddress remote_addr, + const char* st) : + m_Device(device), m_RemoteAddr(remote_addr), m_ST(st) {} + virtual ~PLT_SsdpDeviceSearchResponseInterfaceIterator() {} + + NPT_Result operator()(NPT_NetworkInterface*& if_addr) const; + +private: + PLT_DeviceHost* m_Device; + NPT_SocketAddress m_RemoteAddr; + NPT_String m_ST; +}; + +/*---------------------------------------------------------------------- +| PLT_SsdpDeviceSearchResponseTask class ++---------------------------------------------------------------------*/ +/** + The PLT_SsdpDeviceSearchResponseTask class is used by a PLT_DeviceHost to respond + to SSDP M-SEARCH requests from UPnP ControlPoints. + */ +class PLT_SsdpDeviceSearchResponseTask : public PLT_ThreadTask +{ +public: + PLT_SsdpDeviceSearchResponseTask(PLT_DeviceHost* device, + NPT_SocketAddress remote_addr, + const char* st) : + m_Device(device), m_RemoteAddr(remote_addr), m_ST(st) {} + +protected: + ~PLT_SsdpDeviceSearchResponseTask() override {} + + // PLT_ThreadTask methods + void DoRun() override; + +protected: + PLT_DeviceHost* m_Device; + NPT_SocketAddress m_RemoteAddr; + NPT_String m_ST; +}; + +/*---------------------------------------------------------------------- +| PLT_SsdpAnnounceInterfaceIterator class ++---------------------------------------------------------------------*/ +/** + The PLT_SsdpAnnounceInterfaceIterator class is used to send SSDP announcements + given a list of network interaces. + */ +class PLT_SsdpAnnounceInterfaceIterator +{ +public: + PLT_SsdpAnnounceInterfaceIterator(PLT_DeviceHost* device, PLT_SsdpAnnounceType type, bool broadcast = false) : + m_Device(device), m_Type(type), m_Broadcast(broadcast) {} + + NPT_Result operator()(NPT_NetworkInterface*& if_addr) const; + +private: + PLT_DeviceHost* m_Device; + PLT_SsdpAnnounceType m_Type; + bool m_Broadcast; +}; + +/*---------------------------------------------------------------------- +| PLT_SsdpInitMulticastIterator class ++---------------------------------------------------------------------*/ +/** + The PLT_SsdpInitMulticastIterator class is used to join a multicast group + given a list of IP addresses. + */ +class PLT_SsdpInitMulticastIterator +{ +public: + PLT_SsdpInitMulticastIterator(NPT_UdpMulticastSocket* socket) : + m_Socket(socket) {} + + NPT_Result operator()(NPT_IpAddress& if_addr) const { + NPT_IpAddress addr; + addr.ResolveName("239.255.255.250"); + // OSX bug, since we're reusing the socket, we need to leave group first + // before joining it + m_Socket->LeaveGroup(addr, if_addr); + return m_Socket->JoinGroup(addr, if_addr); + } + +private: + NPT_UdpMulticastSocket* m_Socket; +}; + +/*---------------------------------------------------------------------- +| PLT_SsdpDeviceAnnounceTask class ++---------------------------------------------------------------------*/ +/** + The PLT_SsdpDeviceAnnounceTask class is a task to send UPnP Device SSDP announcements + (alive or byebye). It can be setup to automatically repeat after an interval. + */ +class PLT_SsdpDeviceAnnounceTask : public PLT_ThreadTask +{ +public: + PLT_SsdpDeviceAnnounceTask(PLT_DeviceHost* device, + NPT_TimeInterval repeat, + bool is_byebye_first = false, + bool extra_broadcast = false) : + m_Device(device), + m_Repeat(repeat), + m_IsByeByeFirst(is_byebye_first), + m_ExtraBroadcast(extra_broadcast) {} + +protected: + ~PLT_SsdpDeviceAnnounceTask() override {} + + // PLT_ThreadTask methods + void DoRun() override; + +protected: + PLT_DeviceHost* m_Device; + NPT_TimeInterval m_Repeat; + bool m_IsByeByeFirst; + bool m_ExtraBroadcast; +}; + +/*---------------------------------------------------------------------- +| PLT_NetworkInterfaceAddressSearchIterator class ++---------------------------------------------------------------------*/ +/** + The PLT_NetworkInterfaceAddressSearchIterator class returns the network interface + given an IP address. + */ +class PLT_NetworkInterfaceAddressSearchIterator +{ +public: + PLT_NetworkInterfaceAddressSearchIterator(NPT_String ip) : m_Ip(ip) {} + virtual ~PLT_NetworkInterfaceAddressSearchIterator() {} + + NPT_Result operator()(NPT_NetworkInterface*& addr) const { + NPT_List<NPT_NetworkInterfaceAddress>::Iterator niaddr = addr->GetAddresses().GetFirstItem(); + if (!niaddr) return NPT_FAILURE; + + return (m_Ip.Compare((*niaddr).GetPrimaryAddress().ToString(), true) == 0) ? NPT_SUCCESS : NPT_FAILURE; + } + +private: + NPT_String m_Ip; +}; + +/*---------------------------------------------------------------------- +| PLT_SsdpPacketListenerIterator class ++---------------------------------------------------------------------*/ +/** + The PLT_SsdpPacketListenerIterator class iterates through a list of + PLT_SsdpPacketListener instances to notify of a new SSDP incoming packet. + */ +class PLT_SsdpPacketListenerIterator +{ +public: + PLT_SsdpPacketListenerIterator(NPT_HttpRequest& request, + const NPT_HttpRequestContext& context) : + m_Request(request), m_Context(context) {} + + NPT_Result operator()(PLT_SsdpPacketListener*& listener) const { + return listener->OnSsdpPacket(m_Request, m_Context); + } + +private: + NPT_HttpRequest& m_Request; + const NPT_HttpRequestContext& m_Context; +}; + +/*---------------------------------------------------------------------- +| PLT_SsdpListenTask class ++---------------------------------------------------------------------*/ +/** + The PLT_SsdpListenTask class is used to listen for incoming SSDP packets and + keep track of a list of PLT_SsdpPacketListener listeners to notify when a new + SSDP packet has arrived. + */ +class PLT_SsdpListenTask : public PLT_HttpServerSocketTask +{ +public: + PLT_SsdpListenTask(NPT_Socket* socket) : + PLT_HttpServerSocketTask(socket, true) { + // Change read time out for UDP because iPhone 3.0 seems to hang + // after reading everything from the socket even though + // more stuff arrived +#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE + m_Socket->SetReadTimeout(10000); +#endif + } + + NPT_Result AddListener(PLT_SsdpPacketListener* listener) { + NPT_AutoLock lock(m_Mutex); + m_Listeners.Add(listener); + return NPT_SUCCESS; + } + + NPT_Result RemoveListener(PLT_SsdpPacketListener* listener) { + NPT_AutoLock lock(m_Mutex); + m_Listeners.Remove(listener); + return NPT_SUCCESS; + } + + // PLT_Task methods + void DoAbort() override; + +protected: + ~PLT_SsdpListenTask() override {} + + // PLT_HttpServerSocketTask methods + NPT_Result GetInputStream(NPT_InputStreamReference& stream) override; + NPT_Result GetInfo(NPT_SocketInfo& info) override; + NPT_Result SetupResponse(NPT_HttpRequest& request, + const NPT_HttpRequestContext& context, + NPT_HttpResponse& response) override; + +protected: + PLT_InputDatagramStreamReference m_Datagram; + NPT_List<PLT_SsdpPacketListener*> m_Listeners; + NPT_Mutex m_Mutex; +}; + +/*---------------------------------------------------------------------- +| PLT_SsdpSearchTask class ++---------------------------------------------------------------------*/ +/** + The PLT_SsdpSearchTask class is a task used by a PLT_CtrlPoint to issue a SSDP + M-SEARCH request. It can be set to repeat at a certain frequencey. + */ +class PLT_SsdpSearchTask : public PLT_ThreadTask +{ +public: + PLT_SsdpSearchTask(NPT_UdpSocket* socket, + PLT_SsdpSearchResponseListener* listener, + NPT_HttpRequest* request, + NPT_TimeInterval frequency = NPT_TimeInterval(0.)); // pass 0 for one time + +protected: + ~PLT_SsdpSearchTask() override; + + // PLT_ThreadTask methods + void DoAbort() override; + void DoRun() override; + + virtual NPT_Result ProcessResponse(NPT_Result res, + const NPT_HttpRequest& request, + const NPT_HttpRequestContext& context, + NPT_HttpResponse* response); + +private: + PLT_SsdpSearchResponseListener* m_Listener; + NPT_HttpRequest* m_Request; + NPT_TimeInterval m_Frequency; + bool m_Repeat; + NPT_UdpSocket* m_Socket; +}; + +#endif /* _PLT_SSDP_H_ */ |