File Information
Library: UPnP/SSDP
Package: SSDP
Header: Poco/UPnP/SSDP/SSDPResponder.h
Description
SSDPResponder implements the Simple Service Discovery Protocol for UPnP.
The SSDPResponder maintains a list of local Advertisements and periodically sends out discovery messages, using a multicast socket. It also processes discovery and search messages received from other UPnP devices on the network. Search messages are replied to, if possible, while discovery messages (ssdp:alive and ssdp:byebye) from other UPnP devices are made available via events.
The steps for setting up a SSDPResponder are as follows:
// 1. Set up a multicast socket (we use a wildcard address here) Poco::Net::SocketAddress sa(Poco::Net::IPAddress(), Poco::UPnP::SSDPResponder::MULTICAST_PORT); Poco::Net::MulticastSocket socket(sa); socket.setLoopback(true); // optional socket.setTimeToLive(4); // recommended by SSDP specification // 2. Set up SSDPResponder Poco::UPnP::SSDPResponder responder(socket); // 3. Join multicast group for advertisements socket.joinGroup(responder.groupAddress().host()); // 4. Publish local devices and services. responder.publish(pRootDeviceAdvertisement); ... // 5. Start responder responder.start();
To shutdown a SSDPResponder, stop it and leave the multicast group:
responder.stop(); socket.leaveGroup(responder.groupAddress().host());
According to the UPnP SSDP specification, when a device is added to the network, it multicasts discovery messages to advertise its root device, any embedded devices, and any services. Each discovery message contains four major components:
- a potential search target (e.g., device type), sent in an NT (Notification Type) header,
- a composite identifier for the advertisement, sent in a USN (Unique Service Name) header,
- a URL for more information about the device (or enclosing device in the case of a service), sent in a LOCATION header, and
- a duration for which the advertisement is valid, sent in a CACHE-CONTROL header.
To advertise its capabilities, a device multicasts a number of discovery messages. Specifically, a root device must multicast:
- Three discovery messages (root device, device UUID and device type) for the root device.
- Two discovery messages (device UUID and device type) for each embedded device.
- One discovery message (service type) for each service type in each device.
For more information, please refer to the UPnP Device Architecture specification.
Note: In order to comply with DLNA requirements, two sockets are used for sending and receiving messages. For "security reasons", DLNA requirement 7.2.3.4 disallows sending out M-SEARCH and NOTIFY messages with source port 1900. Therefore, the same socket that is used to receive notifications from other devices cannot be used to send messages, and a separate socket is needed for that purpose. The second (outgoing) socket can be created automatically (in this case, bound address, TTL and loopback options are copied from the given socket), or it can be explicitly passed to the constructor, along with the incoming socket. Loopback option and TTL must be set for the outgoing socket in this case. However, the outgoing socket does not need to join the multicast group.
Member Summary
Member Functions: createServerString, getMaxResponseTime, getServer, groupAddress, handleRequest, handleResponse, publish, revoke, search, searchLocal, sendAliveMessage, sendByeByeMessage, sendSearchRequest, sendSearchResponse, setMaxResponseTime, setServer, start, stop
Nested Classes
struct AdvertisementInfo
Types
Advertisements
typedef std::map < std::string, AdvertisementInfo > Advertisements;
Enumerations
Anonymous
INITIAL_AD_MIN_REPEAT_INTERVAL = 100
INITIAL_AD_MAX_REPEAT_INTERVAL = 300
StopMode
Do not send ssdp:byebye messages when stopping.
Send ssdp:byebye messages when stopping.
Constructors
SSDPResponder
SSDPResponder(
const Poco::Net::MulticastSocket & socket
);
Creates a SSDPResponder, using the given multicast socket, which must have been properly setup.
For sending M-SEARCH and NOTIFY messages, a separate multicast socket is created and bound to the same IP address as the given socket. Loopback and TTL options are also copied from the given socket.
SSDPResponder
SSDPResponder(
const Poco::Net::MulticastSocket & incomingSocket,
const Poco::Net::MulticastSocket & outgoingSocket
);
Creates a SSDPResponder, using the given multicast sockets, which must have been properly setup.
SSDPResponder
SSDPResponder(
const Poco::Net::MulticastSocket & socket,
const Poco::Net::SocketAddress & groupAddress
);
Creates a SSDPResponder, using the given multicast socket, which must have been properly setup. Multicast messages are sent to the given address. Use of a non-standard multicast address (239.255.255.250:1900) is not recommended.
For sending M-SEARCH and NOTIFY messages, a separate multicast socket is created and bound to the same IP address as the given socket. Loopback and TTL options are also copied from the given socket.
SSDPResponder
SSDPResponder(
Poco::Util::Timer & timer,
const Poco::Net::MulticastSocket & socket
);
Creates a SSDPResponder, using the given timer and multicast socket, which must have been properly setup.
For sending M-SEARCH and NOTIFY messages, a separate multicast socket is created and bound to the same IP address as the given socket. Loopback and TTL options are also copied from the given socket.
SSDPResponder
SSDPResponder(
const Poco::Net::MulticastSocket & incomingSocket,
const Poco::Net::MulticastSocket & outgoingSocket,
const Poco::Net::SocketAddress & groupAddress
);
Creates a SSDPResponder, using the given multicast sockets, which must have been properly setup. Multicast messages are sent to the given address. Use of a non-standard multicast address (239.255.255.250:1900) is not recommended.
SSDPResponder
SSDPResponder(
Poco::Util::Timer & timer,
const Poco::Net::MulticastSocket & incomingSocket,
const Poco::Net::MulticastSocket & outgoingSocket
);
Creates a SSDPResponder, using the given timer and multicast socket, which must have been properly setup.
SSDPResponder
SSDPResponder(
Poco::Util::Timer & timer,
const Poco::Net::MulticastSocket & socket,
const Poco::Net::SocketAddress & groupAddress
);
Creates a SSDPResponder, using the given timer and multicast socket, which must have been properly setup. Multicast messages are sent to the given address. Use of a non-standard multicast address (239.255.255.250:1900) is not recommended.
For sending M-SEARCH and NOTIFY messages, a separate multicast socket is created and bound to the same IP address as the given socket. Loopback and TTL options are also copied from the given socket.
SSDPResponder
SSDPResponder(
Poco::Util::Timer & timer,
const Poco::Net::MulticastSocket & incomingSocket,
const Poco::Net::MulticastSocket & outgoingSocket,
const Poco::Net::SocketAddress & groupAddress
);
Creates a SSDPResponder, using the given timer and multicast socket, which must have been properly setup. Multicast messages are sent to the given address. Use of a non-standard multicast address (239.255.255.250:1900) is not recommended.
Destructor
~SSDPResponder
~SSDPResponder();
Destroys the SSDPResponder.
Stops the responder if it is still running.
Member Functions
getMaxResponseTime
int getMaxResponseTime() const;
Returns the maximum response time (in seconds) sent with search requests. The default is 2 seconds.
getServer
const std::string & getServer() const;
Returns the Server identification string sent with alive messages.
groupAddress
const Poco::Net::SocketAddress & groupAddress() const;
Returns the socket address of the multicast group used by this SSDPResponder.
Unless an address has been given in the constructor, the default SSDP multicast address (239.255.255.250:1900) is returned.
publish
void publish(
Advertisement::Ptr pAdvertisement
);
Adds a new Advertisement to the SSDPResponder's list of local advertisements.
An Advertisement can be for a root device, a device UUID, a device type or a service type.
If the SSDPResponder is already running, will also send an initial ssdp:alive message. While the SSDPResponder is running, it will send periodic discovery messages (ssdp:alive) for the Advertisement.
Throws a Poco::ExistsException if an Advertisement with the same USN has already been advertized.
revoke
void revoke(
const std::string & usn
);
Removes the Advertisement with the given Unique Service Name.
If the SSDPResponder is running, will send a ssdp:byebye message for the given USN.
Throws a Poco::NotFoundException if an Advertisement with the given USN is unknown.
search
void search(
const std::string & searchTarget
);
Multicasts a search request for the given search target.
According to the SSDP specification, the search target can be one of:
- ssdp:all: Search for all devices and services.
- upnp:rootdevice: Search for all root devices.
- a Unique Service Name: Search for a specific device or service type.
setMaxResponseTime
void setMaxResponseTime(
int seconds
);
Sets the maximum response time (in seconds) sent with search requests.
The maximum response time must be greater than 0.
setServer
void setServer(
const std::string & server
);
Sets the Server identification string sent with alive message.
The format must be <os>/<version> UPnP/1.0 <product>/<version>.
start
void start();
Starts the SSDPResponder.
The responder will start receiving advertisements. It will also send ssdp:alive messages for all registered advertisements.
While the SSDPResponder is running, it will send periodic discovery messages (ssdp:alive) for all registered advertisements. Messages will be send at a random interval. The interval will be larger than 1/3 of the Advertisement's life time and smaller than 2/3 of the Advertisement's life time.
The SSDPResponder will also reply to any matching search requests it receives.
stop
void stop();
Stops the SSDPResponder.
The responder will send ssdp:byebye messages for all registered advertisements.
Please note that the byebye messages will be sent using the timer, after stop() returns. When using an external timer, make sure that the SSDPResponder remains alive until all byebye messages have been sent and/or cancel all timer tasks before destroying the SSDPResponder.
stop
void stop(
StopMode mode
);
Stops the SSDPResponder.
If mode is SSDP_STOP_SEND_BYEBYE, the responder will send ssdp:byebye messages for all registered advertisements.
Please note that the byebye messages will be sent using the timer, after stop() returns. When using an external timer, make sure that the SSDPResponder remains alive until all byebye messages have been sent and/or cancel all timer tasks before destroying the SSDPResponder.
createServerString
static std::string createServerString();
handleRequest
void handleRequest(
const Poco::Net::HTTPRequest & request,
const Poco::Net::SocketAddress & senderAddress
);
handleResponse
void handleResponse(
const Poco::Net::HTTPResponse & response,
const Poco::Net::SocketAddress & senderAddress
);
searchLocal
void searchLocal(
const std::string & searchTarget,
int maxResponseTime,
const Poco::Net::SocketAddress & requesterAddress
);
sendAliveMessage
void sendAliveMessage(
Advertisement::Ptr pAdvertisement
);
sendByeByeMessage
void sendByeByeMessage(
Advertisement::Ptr pAdvertisement
);
sendSearchRequest
void sendSearchRequest(
const std::string & searchTarget
);
sendSearchResponse
void sendSearchResponse(
Advertisement::Ptr pAdvertisement,
const std::string & searchTarget,
const Poco::Net::SocketAddress & requesterAddress
);
Variables
MULTICAST_HOST
static const std::string MULTICAST_HOST;
MULTICAST_PORT
static const Poco::UInt16 MULTICAST_PORT;
PRODUCT_VERSION
static const std::string PRODUCT_VERSION;
UPNP_VERSION
static const std::string UPNP_VERSION;
advertisementGone
Poco::BasicEvent < std::string > advertisementGone;
A ssdp:byebye message has been received for the given Unique Service Name (USN).
The event handler should return as soon as possible to avoid disruptions in SSDP message processing.
advertisementSeen
Poco::BasicEvent < Advertisement::Ptr > advertisementSeen;
A ssdp:alive message has been received for the given Advertisement.
The Advertisement will contain the following attributes:
- Host: the host address and port number (<host>:<port>) of the device sending the message.
- Server: the server name (the value of the Server header sent with the ssdp:alive message). Will not be included in advertisements from search responses.
- ST: the search target. Only included in advertisements from search responses.
The event handler should return as soon as possible to avoid disruptions in SSDP message processing.
CACHE_CONTROL
static const std::string CACHE_CONTROL;
EMPTY
static const std::string EMPTY;
EXT
static const std::string EXT;
HOST
static const std::string HOST;
LOCATION
static const std::string LOCATION;
MAN
static const std::string MAN;
MAX_AGE_FORMAT
static const std::string MAX_AGE_FORMAT;
MX
static const std::string MX;
M_SEARCH
static const std::string M_SEARCH;
NOTIFY
static const std::string NOTIFY;
NT
static const std::string NT;
NTS
static const std::string NTS;
SERVER
static const std::string SERVER;
SSDP_ALIVE
static const std::string SSDP_ALIVE;
SSDP_ALL
static const std::string SSDP_ALL;
SSDP_BYEBYE
static const std::string SSDP_BYEBYE;
SSDP_DISCOVER
static const std::string SSDP_DISCOVER;
ST
static const std::string ST;
UPNP_ROOTDEVICE
static const std::string UPNP_ROOTDEVICE;
USN
static const std::string USN;
WILDCARD_URI
static const std::string WILDCARD_URI;