diff -u -r -N minidlna_1.0.18/codelength.h minidlna_minissdpd/codelength.h --- minidlna_1.0.18/codelength.h 1970-01-01 01:00:00.000000000 +0100 +++ minidlna_minissdpd/codelength.h 2011-02-02 15:35:05.000000000 +0100 @@ -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 -u -r -N minidlna_1.0.18/minidlna.c minidlna_minissdpd/minidlna.c --- minidlna_1.0.18/minidlna.c 2010-07-21 01:26:36.000000000 +0200 +++ minidlna_minissdpd/minidlna.c 2011-02-02 15:59:07.000000000 +0100 @@ -422,6 +422,9 @@ if( (strcmp(ary_options[i].value, "yes") == 0) || atoi(ary_options[i].value) ) SETFLAG(DLNA_STRICT_MASK); break; + case UPNPMINISSDPDSOCKET: + minissdpdsocketpath = ary_options[i].value; + break; default: fprintf(stderr, "Unknown option in file %s\n", optionsfile); @@ -797,7 +800,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 -u -r -N minidlna_1.0.18/minissdp.c minidlna_minissdpd/minissdp.c --- minidlna_1.0.18/minissdp.c 2010-07-16 23:27:11.000000000 +0200 +++ minidlna_minissdpd/minissdp.c 2011-02-02 15:57:12.000000000 +0100 @@ -1,7 +1,7 @@ /* $Id: minissdp.c,v 1.12 2010/01/13 21:15:11 jmaggard Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * (c) 2006 Thomas Bernard + * (c) 2006-2011 Thomas Bernard * This software is subject to the conditions detailed * in the LICENCE file provided within the distribution */ @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -20,14 +21,18 @@ #include "upnphttp.h" #include "upnpglobalvars.h" #include "minissdp.h" +#include "codelength.h" #include "log.h" /* SSDP ip/port */ #define SSDP_PORT (1900) #define SSDP_MCAST_ADDR ("239.255.255.250") +/* Prototypes */ +void ProcessSSDPData(int s, char *bufr, struct sockaddr_in sendername, int n, unsigned short port) ; + 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 */ @@ -45,6 +50,8 @@ return 0; } +/* Open and configure the socket listening for + * SSDP udp packets sent on 239.255.255.250 port 1900 */ int OpenAndConfSSDPReceiveSocket() { @@ -207,9 +214,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 @@ -314,17 +321,12 @@ * process SSDP M-SEARCH requests and responds to them */ void ProcessSSDPRequest(int s, unsigned short port) -/*ProcessSSDPRequest(int s, struct lan_addr_s * lan_addr, int n_lan_addr, - unsigned short port)*/ { int n; char bufr[1500]; socklen_t len_r; struct sockaddr_in sendername; - int i, l; - int lan_addr_index = 0; - char * st = NULL, * mx = NULL, * man = NULL, * mx_end = NULL; - int st_len = 0, mx_len = 0, man_len = 0, mx_val = 0; + len_r = sizeof(struct sockaddr_in); n = recvfrom(s, bufr, sizeof(bufr), 0, @@ -334,6 +336,15 @@ DPRINTF(E_ERROR, L_SSDP, "recvfrom(udp): %s\n", strerror(errno)); return; } + ProcessSSDPData(s, bufr, sendername, n, port); + +} + +void ProcessSSDPData(int s, char *bufr, struct sockaddr_in sendername, int n, unsigned short port) { + int i, l; + int lan_addr_index = 0; + char * st = NULL, * mx = NULL, * man = NULL, * mx_end = NULL; + int st_len = 0, mx_len = 0, man_len = 0, mx_val = 0; if(memcmp(bufr, "NOTIFY", 6) == 0) { @@ -433,6 +444,7 @@ /* strlen("ssdp:all") == 8 */ if(st_len==8 && (0 == memcmp(st, "ssdp:all", 8))) { + DPRINTF(E_INFO, L_SSDP, "ssdp:all found"); for(i=0; known_service_types[i]; i++) { l = (int)strlen(known_service_types[i]); @@ -496,3 +508,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 -u -r -N minidlna_1.0.18/minissdp.h minidlna_minissdpd/minissdp.h --- minidlna_1.0.18/minissdp.h 2010-07-16 23:25:55.000000000 +0200 +++ minidlna_minissdpd/minissdp.h 2011-02-02 15:22:14.000000000 +0100 @@ -1,6 +1,6 @@ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * (c) 2006-2007 Thomas Bernard + * (c) 2006-2011 Thomas Bernard * This software is subject to the conditions detailed * in the LICENCE file provided within the distribution */ #ifndef __MINISSDP_H__ @@ -39,5 +39,8 @@ int SendSSDPGoodbye(int * sockets, int n); +int +SubmitServicesToMiniSSDPD(const char * host, unsigned short port); + #endif diff -u -r -N minidlna_1.0.18/options.c minidlna_minissdpd/options.c --- minidlna_1.0.18/options.c 2010-07-16 23:25:55.000000000 +0200 +++ minidlna_minissdpd/options.c 2011-02-02 15:59:52.000000000 +0100 @@ -35,7 +35,8 @@ { UPNPINOTIFY, "inotify" }, { UPNPDBDIR, "db_dir" }, { ENABLE_TIVO, "enable_tivo" }, - { ENABLE_DLNA_STRICT, "strict_dlna" } + { ENABLE_DLNA_STRICT, "strict_dlna" }, + { UPNPMINISSDPDSOCKET, "minissdpdsocket"} }; int diff -u -r -N minidlna_1.0.18/options.h minidlna_minissdpd/options.h --- minidlna_1.0.18/options.h 2010-07-16 23:25:55.000000000 +0200 +++ minidlna_minissdpd/options.h 2011-02-02 16:09:06.000000000 +0100 @@ -28,7 +28,8 @@ UPNPINOTIFY, /* enable inotify on the media directories */ UPNPDBDIR, /* base directory to store the database, log files, and album art cache */ ENABLE_TIVO, /* enable support for streaming images and music to TiVo */ - ENABLE_DLNA_STRICT /* strictly adhere to DLNA specs */ + ENABLE_DLNA_STRICT, /* strictly adhere to DLNA specs */ + UPNPMINISSDPDSOCKET /* minissdpdsocket */ }; /* readoptionsfile() diff -u -r -N minidlna_1.0.18/upnpglobalvars.c minidlna_minissdpd/upnpglobalvars.c --- minidlna_1.0.18/upnpglobalvars.c 2010-07-16 23:25:56.000000000 +0200 +++ minidlna_minissdpd/upnpglobalvars.c 2011-02-02 15:55:11.000000000 +0100 @@ -40,6 +40,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 -u -r -N minidlna_1.0.18/upnpglobalvars.h minidlna_minissdpd/upnpglobalvars.h --- minidlna_1.0.18/upnpglobalvars.h 2010-07-21 01:26:36.000000000 +0200 +++ minidlna_minissdpd/upnpglobalvars.h 2011-02-02 15:54:41.000000000 +0100 @@ -117,6 +117,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[];