Home | Downloads | Compatibility list | libnatpmp | MiniSSDPd | xchat upnp patch | Forum
Every UPnP device and UPnP client (or control point in UPnP terminology) needs to listen to SSDP packets broadcasted to the multicast group 239.255.255.250 (or FF02::C / FF05::C in IPv6) port 1900. So when several UPnP devices are running on the same computer, or several UPnP control points are trying a discovery process on the same computer, there is concurence to open a socket for listening on the UDP port 1900. Also from the point of view of a control point software, it is usefull to get history of the SSDP NOTIFY packets sent on the network during a few past minutes.
I first coded MiniSSDPd as a small daemon used by MiniUPnPc (a UPnP
control point for IGD devices) to speed up device discoveries.
MiniSSDPd keep memory of all UPnP devices that announced themselves on the
network through SSDP NOTIFY packets.
More recently, some MiniUPnPd (an implementation of a UPnP IDG)
users complained about the non-possibility to run MiniUPnPd and
MediaTomb (an implementation of a
UPnP Media Server) on the same computer because these two piece of software
needed to open UDP port 1900. I then added to MiniSSDPd the ability
to handle all SSDP traffic recieved on a computer via the multicast
group 239.255.255.250:1900.
You may be interested in reading
this forum thread
about all this.
MiniSSDPd receive NOTIFY packets and store information contained
for later use by UPnP Control Points on the machine.
MiniSSDPd receive M-SEARCH packets and answer on behalf of the
UPnP devices running on the machine.
Recent versions of MiniUPnPd and MiniUPnPc are designed to take
automaticaly advantage of MiniSSDPd running on the same computer.
Juste make sure that MiniSSDPd is started before any
other UPnP program on the computer.
Other software must be patched in order to take advantage of MiniSSDPd.
I made a pach for MediaTomb
which add the Device in MiniSSDPd : mediatomb_minissdp-20081006.patch.
More recently I made a patch for MiniDLNA :
minidlna_1.0.18_minissdp1.patch.
Communication with a running MiniSSDPd process is done through a
Unix socket. The path of this socket is usually
/var/run/minissdpd.sock. Here is some sample code to open
a unix socket :
struct sockaddr_un addr;
int s;
const char * minissdpdsocketpath = "/var/run/minissdpd.sock";
s = socket(AF_UNIX, SOCK_STREAM, 0);
if(s < 0) {
// ERROR
}
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, minissdpdsocketpath, sizeof(addr.sun_path));
if(connect(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0) {
// ERROR
}
[...]
close(s);
Request are sent to the Unix socket. The first byte of the request
is the request type.
Strings sent or recieved are not zero-terminated but prefixed by their
length in a variable length format. Use following macros to encode
and decode to this format :
/* Encode length by using 7bit per Byte : * Most significant bit of each byte specifies that the * following byte is part of the code */ #define DECODELENGTH(n, p) n = 0; \ do { n = (n << 7) | (*p & 0x7f); } \ while(*(p++)&0x80); #define CODELENGTH(n, p) if(n>=268435456) *(p++) = (n >> 28) | 0x80; \ if(n>=2097152) *(p++) = (n >> 21) | 0x80; \ if(n>=16384) *(p++) = (n >> 14) | 0x80; \ if(n>=128) *(p++) = (n >> 7) | 0x80; \ *(p++) = n & 0x7f;
A control point sends one of these requests to MiniSSDPd in order to receive a list of UPnP devices and services meeting the requirements. The request type byte is followed by a string (an empty string for type 3). Request types :
unsigned char buffer[2048]; unsigned char * p; const char * device = "urn:schemas-upnp-org:device:InternetGatewayDevice:1"; int device_len = (int)strlen(device); buffer[0] = 1; /* request type 1 : request devices/services by type */ p = buffer + 1; CODELENGTH(device_len, p); memcpy(p, device, device_len); p += device_len; write(socket, buffer, p - buffer);
For these three request types, the responses is as following :
These "request" type is used by UPnP devices that declare themselves and their services that way. The first byte is 4 and is followed by four Strings :
There is no response.
Thomas Bernard