diff -N -u -r minidlna-1.0.21/codelength.h minidlna_minissdpd/codelength.h --- minidlna-1.0.21/codelength.h 1970-01-01 01:00:00.000000000 +0100 +++ minidlna_minissdpd/codelength.h 2011-07-25 16:49:25.000000000 +0200 @@ -0,0 +1,24 @@ +/* $Id: codelength.h,v 1.1 2008/10/06 22:04:06 nanard Exp $ */ +/* Project : miniupnp + * Author : Thomas BERNARD + * copyright (c) 2005-2008 Thomas Bernard + * This software is subjet to the conditions detailed in the + * provided LICENCE file. */ +#ifndef __CODELENGTH_H__ +#define __CODELENGTH_H__ + +/* 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; + +#endif + diff -N -u -r minidlna-1.0.21/minidlna.c minidlna_minissdpd/minidlna.c --- minidlna-1.0.21/minidlna.c 2011-07-19 00:18:11.000000000 +0200 +++ minidlna_minissdpd/minidlna.c 2011-07-25 16:49:25.000000000 +0200 @@ -588,6 +588,9 @@ break; } break; + case UPNPMINISSDPDSOCKET: + minissdpdsocketpath = ary_options[i].value; + break; default: fprintf(stderr, "Unknown option in file %s\n", optionsfile); @@ -974,7 +977,11 @@ sudp = OpenAndConfSSDPReceiveSocket(n_lan_addr, lan_addr); if(sudp < 0) { - DPRINTF(E_FATAL, L_GENERAL, "Failed to open socket for receiving SSDP. EXITING\n"); + DPRINTF(E_INFO, L_GENERAL, "Failed to open socket for receiving SSDP. Trying to use MiniSSDPd\n"); + if(SubmitServicesToMiniSSDPD(lan_addr[0].str, runtime_vars.port) < 0) { + DPRINTF(E_FATAL, L_GENERAL, "Failed to connect to MiniSSDPd. EXITING"); + return 1; + } } /* open socket for HTTP connections. Listen on the 1st LAN address */ shttpl = OpenAndConfHTTPSocket(runtime_vars.port); diff -N -u -r minidlna-1.0.21/minissdp.c minidlna_minissdpd/minissdp.c --- minidlna-1.0.21/minissdp.c 2011-07-19 00:18:11.000000000 +0200 +++ minidlna_minissdpd/minissdp.c 2011-07-25 16:50:23.000000000 +0200 @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -45,6 +46,7 @@ #include "getifaddr.h" #include "minissdp.h" #include "utils.h" +#include "codelength.h" #include "log.h" /* SSDP ip/port */ @@ -52,7 +54,7 @@ #define SSDP_MCAST_ADDR ("239.255.255.250") static int -AddMulticastMembership(int s, in_addr_t ifaddr/*const char * ifaddr*/) +AddMulticastMembership(int s, in_addr_t ifaddr) { struct ip_mreq imr; /* Ip multicast membership */ @@ -70,6 +72,8 @@ return 0; } +/* Open and configure the socket listening for + * SSDP udp packets sent on 239.255.255.250 port 1900 */ int OpenAndConfSSDPReceiveSocket() { @@ -242,9 +246,9 @@ { int l, n; char buf[512]; - /* TODO : + /* * follow guideline from document "UPnP Device Architecture 1.0" - * put in uppercase. + * uppercase is recommended. * DATE: is recommended * SERVER: OS/ver UPnP/1.0 minidlna/1.0 * - check what to put in the 'Cache-Control' header @@ -742,3 +746,62 @@ } return 0; } + +/* SubmitServicesToMiniSSDPD() : + * register services offered by MiniUPnPd to a running instance of + * MiniSSDPd */ +int +SubmitServicesToMiniSSDPD(const char * host, unsigned short port) { + struct sockaddr_un addr; + int s; + unsigned char buffer[2048]; + char strbuf[256]; + unsigned char * p; + int i, l; + + s = socket(AF_UNIX, SOCK_STREAM, 0); + if(s < 0) { + DPRINTF(E_ERROR, L_SSDP, "socket(unix): %s", strerror(errno)); + return -1; + } + 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) { + DPRINTF(E_ERROR, L_SSDP, "connect(\"%s\"): %s", + minissdpdsocketpath, strerror(errno)); + return -1; + } + for(i = 0; known_service_types[i]; i++) { + buffer[0] = 4; + p = buffer + 1; + l = (int)strlen(known_service_types[i]); + if(i > 0) + l++; + CODELENGTH(l, p); + memcpy(p, known_service_types[i], l); + if(i > 0) + p[l-1] = '1'; + p += l; + l = snprintf(strbuf, sizeof(strbuf), "%s::%s%s", + uuidvalue, known_service_types[i], (i==0)?"":"1"); + CODELENGTH(l, p); + memcpy(p, strbuf, l); + p += l; + l = (int)strlen(MINIDLNA_SERVER_STRING); + CODELENGTH(l, p); + memcpy(p, MINIDLNA_SERVER_STRING, l); + p += l; + l = snprintf(strbuf, sizeof(strbuf), "http://%s:%u" ROOTDESC_PATH, + host, (unsigned int)port); + CODELENGTH(l, p); + memcpy(p, strbuf, l); + p += l; + if(write(s, buffer, p - buffer) < 0) { + DPRINTF(E_ERROR, L_SSDP, "write(): %s", strerror(errno)); + return -1; + } + } + close(s); + return 0; +} + diff -N -u -r minidlna-1.0.21/minissdp.h minidlna_minissdpd/minissdp.h --- minidlna-1.0.21/minissdp.h 2010-11-12 00:48:13.000000000 +0100 +++ minidlna_minissdpd/minissdp.h 2011-07-25 16:49:25.000000000 +0200 @@ -62,5 +62,8 @@ int SendSSDPGoodbye(int * sockets, int n); +int +SubmitServicesToMiniSSDPD(const char * host, unsigned short port); + #endif diff -N -u -r minidlna-1.0.21/options.c minidlna_minissdpd/options.c --- minidlna-1.0.21/options.c 2011-07-19 00:18:11.000000000 +0200 +++ minidlna_minissdpd/options.c 2011-07-25 16:51:25.000000000 +0200 @@ -58,6 +58,7 @@ { UPNPINOTIFY, "inotify" }, { UPNPDBDIR, "db_dir" }, { UPNPLOGDIR, "log_dir" }, + { UPNPMINISSDPDSOCKET, "minissdpdsocket"}, { ENABLE_TIVO, "enable_tivo" }, { ENABLE_DLNA_STRICT, "strict_dlna" }, { ROOT_CONTAINER, "root_container" } diff -N -u -r minidlna-1.0.21/options.h minidlna_minissdpd/options.h --- minidlna-1.0.21/options.h 2011-07-19 00:18:11.000000000 +0200 +++ minidlna_minissdpd/options.h 2011-07-25 16:55:10.000000000 +0200 @@ -51,6 +51,7 @@ UPNPINOTIFY, /* enable inotify on the media directories */ UPNPDBDIR, /* base directory to store the database and album art cache */ UPNPLOGDIR, /* base directory to store the log file */ + UPNPMINISSDPDSOCKET, /* minissdpdsocket */ ENABLE_TIVO, /* enable support for streaming images and music to TiVo */ ENABLE_DLNA_STRICT, /* strictly adhere to DLNA specs */ ROOT_CONTAINER /* root ObjectID (instead of "0") */ diff -N -u -r minidlna-1.0.21/upnpglobalvars.c minidlna_minissdpd/upnpglobalvars.c --- minidlna-1.0.21/upnpglobalvars.c 2011-05-27 01:10:54.000000000 +0200 +++ minidlna_minissdpd/upnpglobalvars.c 2011-07-25 16:49:25.000000000 +0200 @@ -80,6 +80,9 @@ int n_lan_addr = 0; struct lan_addr_s lan_addr[MAX_LAN_ADDR]; +/* Path of the Unix socket used to communicate with MiniSSDPd */ +const char * minissdpdsocketpath = "/var/run/minissdpd.sock"; + /* UPnP-A/V [DLNA] */ sqlite3 * db; char dlna_no_conv[] = "DLNA.ORG_OP=01;DLNA.ORG_CI=0"; diff -N -u -r minidlna-1.0.21/upnpglobalvars.h minidlna_minissdpd/upnpglobalvars.h --- minidlna-1.0.21/upnpglobalvars.h 2011-07-19 00:18:12.000000000 +0200 +++ minidlna_minissdpd/upnpglobalvars.h 2011-07-25 16:49:25.000000000 +0200 @@ -211,6 +211,8 @@ extern int n_lan_addr; extern struct lan_addr_s lan_addr[]; +extern const char * minissdpdsocketpath; + /* UPnP-A/V [DLNA] */ extern sqlite3 *db; extern char dlna_no_conv[];