/*****************************************************************
|
| Platinum - Device Host
|
| 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 Device
*/
#ifndef _PLT_DEVICE_HOST_H_
#define _PLT_DEVICE_HOST_H_
/*----------------------------------------------------------------------
| includes
+---------------------------------------------------------------------*/
#include "Neptune.h"
#include "PltDeviceData.h"
#include "PltSsdp.h"
#include "PltTaskManager.h"
#include "PltAction.h"
#include "PltHttp.h"
/*----------------------------------------------------------------------
| forward declarations
+---------------------------------------------------------------------*/
class PLT_HttpServer;
class PLT_HttpServerHandler;
class PLT_SsdpDeviceAnnounceTask;
class PLT_SsdpListenTask;
/*----------------------------------------------------------------------
| PLT_DeviceHost class
+---------------------------------------------------------------------*/
/**
UPnP Device Host.
The PLT_DeviceHost class is a base class for implementing a UPnP Device. It handles
network announcements and responses to searches from ControlPoints. ControlPoint
action invocations are also received and delegated to derived classes. A
PLT_DeviceHost also takes care of eventing when services state variables change.
*/
class PLT_DeviceHost : public PLT_DeviceData,
public PLT_SsdpPacketListener,
public NPT_HttpRequestHandler
{
public:
/**
Creates a new instance of UPnP Device Host.
@param description_path Relative path for description url
@param uuid UPnP device unique id
@param device_type UPnP device type
@param friendly_name Name advertised for UPnP device
@param show_ip Flag to indicate if device IP should be appended to friendly name
@param port local port for the device host internal HTTP server, 0 for randomly
selected.
@param port_rebind Flag to indicate if device host should automatically try to look
for another port if failing to choose the one passed.
*/
PLT_DeviceHost(const char* description_path = "/",
const char* uuid = "",
const char* device_type = "",
const char* friendly_name = "",
bool show_ip = false,
NPT_UInt16 port = 0,
bool port_rebind = false);
virtual ~PLT_DeviceHost();
virtual void SetBroadcast(bool broadcast) { m_Broadcast = broadcast; }
/**
When a UPnP device comes up, the specifications require that a SSDP bye-bye
sequence is sent to force the removal of the device in case it wasn't sent
properly during the last shutdown.
@param bye_bye_first Boolean to indicate that SSDP bye-bye sequence should
be sent first or not.
*/
virtual void SetByeByeFirst(bool bye_bye_first) { m_ByeByeFirst = bye_bye_first; }
/**
Returns the port used by the internal HTTP server for all incoming requests.
@return port
*/
virtual NPT_UInt16 GetPort() { return m_Port; };
/**
Sets the lease time.
@param lease_time Lease Time
*/
NPT_Result SetLeaseTime(NPT_TimeInterval lease_time) { return PLT_DeviceData::SetLeaseTime(lease_time); }
protected:
/**
NPT_HttpRequestHandler method for setting up the response of an incoming
HTTP request.
@param request the request received
@param context the context of the request
@param response the response to set up
*/
virtual NPT_Result SetupResponse(NPT_HttpRequest& request,
const NPT_HttpRequestContext& context,
NPT_HttpResponse& response);
/**
Static method similar to Announce.
@param device the device to announce
@param request the SSDP pre formatted request
@param socket the network socket to use to send the request
@param byebye boolean indicating if the announce is a SSDP bye-bye or alive.
*/
static NPT_Result Announce(PLT_DeviceData* device,
NPT_HttpRequest& request,
NPT_UdpSocket& socket,
bool byebye);
/**
Called during SSDP announce. The HTTP request is already configured with
the right method and host.
@param request the SSDP pre formatted request
@param socket the network socket to use to send the request
@param byebye boolean indicating if the announce is a SSDP bye-bye or alive.
*/
NPT_Result Announce(NPT_HttpRequest& request,
NPT_UdpSocket& socket,
bool byebye) {
return Announce(this, request, socket, byebye);
}
/**
PLT_SsdpPacketListener method called when a M-SEARCH SSDP packet is received.
@param request SSDP packet
@param context the context of the request
*/
virtual NPT_Result OnSsdpPacket(const NPT_HttpRequest& request,
const NPT_HttpRequestContext& context);
/**
Static method similar to SendSsdpSearchResponse.
@param device the device to announce
@param response the SSDP pre formatted response
@param socket the network socket to use to send the request
@param st the original request search target
@param addr the remote address to send the response back to in case the socket
is not already connected.
*/
static NPT_Result SendSsdpSearchResponse(PLT_DeviceData* device,
NPT_HttpResponse& response,
NPT_UdpSocket& socket,
const char* st,
const NPT_SocketAddress* addr = NULL);
/**
Called by PLT_SsdpDeviceSearchResponseTask when responding to a M-SEARCH
SSDP request.
@param response the SSDP pre formatted response
@param socket the network socket to use to send the request
@param st the original request search target
@param addr the remote address to send the response back to in case the socket
is not already connected.
*/
virtual NPT_Result SendSsdpSearchResponse(NPT_HttpResponse& response,
NPT_UdpSocket& socket,
const char* st,
const NPT_SocketAddress* addr = NULL) {
return SendSsdpSearchResponse(this, response, socket, st, addr);
}
public:
/**
Add UPnP icon information to serve from file system.
@param icon the icon information including url path
@param fileroot the file system root path
@param urlroot the url root path of the icon url to match to fileroot
Note: As an exemple, if the icon url path is "/images/icon1.jpg", the fileroot
is "/Users/joe/www" and the urlroot is "/", when a request is made for
"/images/icon1.jpg", the file is expected to be found at
"/Users/joe/www/images/icon1.jpg". If the urlroot were "/images", the file
would be expected to be found at "/Users/joe/www/icon1.jpg".
*/
virtual NPT_Result AddIcon(const PLT_DeviceIcon& icon,
const char* fileroot,
const char* urlroot = "/");
/**
Add UPnP icon information to serve using static image.
@param icon the icon information including url path
@param data the image data
@param size the image data size
@param copy boolean to indicate the data should be copied internally
*/
virtual NPT_Result AddIcon(const PLT_DeviceIcon& icon,
const void* data,
NPT_Size size,
bool copy = true);
protected:
/**
Required method for setting up UPnP services of device host
(and any embedded). Called when device starts.
*/
virtual NPT_Result SetupServices() = 0;
/**
Default implementation for registering device icon resources. Override to
use different ones. Called when device starts.
*/
virtual NPT_Result SetupIcons();
/**
Default implementation for setting up device host. This calls SetupServices
and SetupIcons when device starts.
*/
virtual NPT_Result SetupDevice();
/**
Called by PLT_TaskManager when the device is started.
@param task the SSDP listening task to attach to for receiving
SSDP M-SEARCH messages.
*/
virtual NPT_Result Start(PLT_SsdpListenTask* task);
/**
Called by PLT_TaskManager when the device is stoped.
@param task the SSDP listening task to detach from to stop receiving
SSDP M-SEARCH messages.
*/
virtual NPT_Result Stop(PLT_SsdpListenTask* task);
/**
This mehod is called when an action performed by a control point has been
received and needs to be answered.
@param action the action information to answer
@param context the context information including the HTTP request and
local and remote socket information (IP & port).
*/
virtual NPT_Result OnAction(PLT_ActionReference& action,
const PLT_HttpRequestContext& context);
/**
This method is called when a control point is requesting the device
description.
@param request the HTTP request
@param context the context information including local and remote socket information.
@param response the response to setup.
*/
virtual NPT_Result ProcessGetDescription(NPT_HttpRequest& request,
const NPT_HttpRequestContext& context,
NPT_HttpResponse& response);
/**
This method is called when a control point is requesting a service SCPD.
@param service the service
@param request the HTTP request
@param context the context information including local and remote socket information.
@param response the response to setup.
*/
virtual NPT_Result ProcessGetSCPD(PLT_Service* service,
NPT_HttpRequest& request,
const NPT_HttpRequestContext& context,
NPT_HttpResponse& response);
/**
This method is called when a "GET" request for a resource other than the device
description, SCPD, or icons has been received.
@param request the HTTP request
@param context the context information including local and remote socket information.
@param response the response to setup.
*/
virtual NPT_Result ProcessHttpGetRequest(NPT_HttpRequest& request,
const NPT_HttpRequestContext& context,
NPT_HttpResponse& response);
/**
This method is called when a "POST" request has been received. This is usually
an UPnP service action invocation. This will deserialize the request and call
the OnAction method.
@param request the HTTP request
@param context the context information including local and remote socket information.
@param response the response to setup.
*/
virtual NPT_Result ProcessHttpPostRequest(NPT_HttpRequest& request,
const NPT_HttpRequestContext& context,
NPT_HttpResponse& response);
/**
This method is called when a request from a subscriber has been received. This is
for any new subscritions, existing subscrition renewal or cancellation.
@param request the HTTP request
@param context the context information including local and remote socket information.
@param response the response to setup.
*/
virtual NPT_Result ProcessHttpSubscriberRequest(NPT_HttpRequest& request,
const NPT_HttpRequestContext& context,
NPT_HttpResponse& response);
protected:
friend class PLT_UPnP;
friend class PLT_UPnP_DeviceStartIterator;
friend class PLT_UPnP_DeviceStopIterator;
friend class PLT_Service;
friend class NPT_Reference<PLT_DeviceHost>;
friend class PLT_SsdpDeviceSearchResponseInterfaceIterator;
friend class PLT_SsdpDeviceSearchResponseTask;
friend class PLT_SsdpAnnounceInterfaceIterator;
PLT_TaskManager m_TaskManager;
PLT_HttpServer* m_HttpServer;
bool m_Broadcast;
NPT_UInt16 m_Port;
bool m_PortRebind;
bool m_ByeByeFirst;
};
typedef NPT_Reference<PLT_DeviceHost> PLT_DeviceHostReference;
#endif /* _PLT_DEVICE_HOST_H_ */