Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/azatoth/minidlna.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Bernard <bernard@users.sourceforge.net>2011-02-02 17:57:12 +0300
committerCarl Fürstenberg <azatoth@gmail.com>2011-03-29 03:00:08 +0400
commite3e794e6053436a58810f19f8f3cd9350f28277c (patch)
tree3155a71fa809f98de968ce5ed330a70716f873e0
parenteb024683b54aef0fd711a8edda80262ef01dc6b6 (diff)
patch to use MiniSSDPd if availablepatch-bernard_minissdpd
with this patch, MiniDLNA uses MiniSSDPd to handle SSDP notify/discover/advertise processes. It enable MiniDLNA and MiniUPnPd (and any other UPnP software supporting MiniSSDPd) to run on the same box.
-rw-r--r--codelength.h23
-rw-r--r--minidlna.c9
-rw-r--r--minissdp.c90
-rw-r--r--minissdp.h5
-rw-r--r--options.c3
-rw-r--r--options.h3
-rw-r--r--upnpglobalvars.c3
-rw-r--r--upnpglobalvars.h2
8 files changed, 124 insertions, 14 deletions
diff --git a/codelength.h b/codelength.h
new file mode 100644
index 0000000..8a5f495
--- /dev/null
+++ b/codelength.h
@@ -0,0 +1,23 @@
+/* $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 --git a/minidlna.c b/minidlna.c
index 8fe7885..fd24814 100644
--- a/minidlna.c
+++ b/minidlna.c
@@ -547,6 +547,9 @@ init(int argc, char * * argv)
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);
@@ -932,7 +935,11 @@ main(int argc, char * * argv)
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 --git a/minissdp.c b/minissdp.c
index bc16964..d139405 100644
--- a/minissdp.c
+++ b/minissdp.c
@@ -2,7 +2,7 @@
/* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
*
- * Copyright (c) 2006, Thomas Bernard
+ * Copyright (c) 2006-2011, Thomas Bernard
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -32,6 +32,7 @@
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
+#include <sys/un.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
@@ -44,14 +45,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 */
@@ -69,6 +74,8 @@ AddMulticastMembership(int s, in_addr_t ifaddr/*const char * ifaddr*/)
return 0;
}
+/* Open and configure the socket listening for
+ * SSDP udp packets sent on 239.255.255.250 port 1900 */
int
OpenAndConfSSDPReceiveSocket()
{
@@ -231,9 +238,9 @@ SendSSDPAnnounce2(int s, struct sockaddr_in sockname, int st_no,
{
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
@@ -338,17 +345,12 @@ SendSSDPNotifies2(int * sockets,
* 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,
@@ -358,6 +360,15 @@ ProcessSSDPRequest(int s, unsigned short port)
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)
{
@@ -463,6 +474,7 @@ ProcessSSDPRequest(int s, unsigned short port)
/* 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]);
@@ -526,3 +538,61 @@ SendSSDPGoodbye(int * sockets, int n_sockets)
}
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 --git a/minissdp.h b/minissdp.h
index 7f79130..986f2e6 100644
--- a/minissdp.h
+++ b/minissdp.h
@@ -1,7 +1,7 @@
/* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
*
- * Copyright (c) 2006-2007, Thomas Bernard
+ * Copyright (c) 2006-2011, Thomas Bernard
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -62,5 +62,8 @@ ProcessSSDPRequest(int s, unsigned short port);
int
SendSSDPGoodbye(int * sockets, int n);
+int
+SubmitServicesToMiniSSDPD(const char * host, unsigned short port);
+
#endif
diff --git a/options.c b/options.c
index cfca9ee..6fcde05 100644
--- a/options.c
+++ b/options.c
@@ -59,7 +59,8 @@ static const struct {
{ UPNPDBDIR, "db_dir" },
{ UPNPLOGDIR, "log_dir" },
{ ENABLE_TIVO, "enable_tivo" },
- { ENABLE_DLNA_STRICT, "strict_dlna" }
+ { ENABLE_DLNA_STRICT, "strict_dlna" },
+ { UPNPMINISSDPDSOCKET, "minissdpdsocket"}
};
int
diff --git a/options.h b/options.h
index a02d7d4..146dcf8 100644
--- a/options.h
+++ b/options.h
@@ -54,7 +54,8 @@ enum upnpconfigoptions {
UPNPDBDIR, /* base directory to store the database and album art cache */
UPNPLOGDIR, /* base directory to store the log file */
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 --git a/upnpglobalvars.c b/upnpglobalvars.c
index 0c71f42..b40e5f3 100644
--- a/upnpglobalvars.c
+++ b/upnpglobalvars.c
@@ -82,6 +82,9 @@ char presentationurl[PRESENTATIONURL_MAX_LEN];
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 --git a/upnpglobalvars.h b/upnpglobalvars.h
index fbb9dc3..4aa4cbf 100644
--- a/upnpglobalvars.h
+++ b/upnpglobalvars.h
@@ -192,6 +192,8 @@ extern char pnpx_hwid[];
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[];