* Add PnP-X support.
This commit is contained in:
parent
41136ae17c
commit
309499d378
1
Makefile
1
Makefile
@ -16,6 +16,7 @@ CFLAGS = -Wall -g -O3 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 \
|
||||
-I/usr/include/ffmpeg \
|
||||
-I/usr/include/libavutil -I/usr/include/libavcodec -I/usr/include/libavformat \
|
||||
-I/usr/include/ffmpeg/libavutil -I/usr/include/ffmpeg/libavcodec -I/usr/include/ffmpeg/libavformat
|
||||
#STATIC_LINKING: CFLAGS += -DSTATIC
|
||||
#STATIC_LINKING: LDFLAGS = -static
|
||||
CC = gcc
|
||||
RM = rm -f
|
||||
|
13
genconfig.sh
13
genconfig.sh
@ -35,6 +35,7 @@ OS_VERSION=`uname -r`
|
||||
TIVO="/*#define TIVO_SUPPORT*/"
|
||||
NETGEAR="/*#define NETGEAR*/"
|
||||
READYNAS="/*#define READYNAS*/"
|
||||
PNPX="#define PNPX 0"
|
||||
|
||||
${RM} ${CONFIGFILE}
|
||||
|
||||
@ -123,10 +124,12 @@ case $OS_NAME in
|
||||
OS_NAME=$(awk -F'!!|=' '{ print $1 }' /etc/raidiator_version)
|
||||
OS_VERSION=$(awk -F'!!|[=,.]' '{ print $3"."$4 }' /etc/raidiator_version)
|
||||
OS_URL="http://www.readynas.com/"
|
||||
LOG_PATH="/var/log"
|
||||
DB_PATH="/var/cache/minidlna"
|
||||
TIVO="#define TIVO_SUPPORT"
|
||||
NETGEAR="#define NETGEAR"
|
||||
READYNAS="#define READYNAS"
|
||||
PNPX="#define PNPX 5"
|
||||
# Debian GNU/Linux special case
|
||||
elif [ -f /etc/debian_version ]; then
|
||||
OS_NAME=Debian
|
||||
@ -154,13 +157,13 @@ case $OS_NAME in
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "#define OS_NAME \"$OS_NAME\"" >> ${CONFIGFILE}
|
||||
echo "#define OS_VERSION \"$OS_NAME/$OS_VERSION\"" >> ${CONFIGFILE}
|
||||
echo "#define OS_URL \"${OS_URL}\"" >> ${CONFIGFILE}
|
||||
echo "#define OS_NAME \"$OS_NAME\"" >> ${CONFIGFILE}
|
||||
echo "#define OS_VERSION \"$OS_NAME/$OS_VERSION\"" >> ${CONFIGFILE}
|
||||
echo "#define OS_URL \"${OS_URL}\"" >> ${CONFIGFILE}
|
||||
echo "" >> ${CONFIGFILE}
|
||||
|
||||
echo "/* full path of the file database */" >> ${CONFIGFILE}
|
||||
echo "#define DEFAULT_DB_PATH \"${DB_PATH}\"" >> ${CONFIGFILE}
|
||||
echo "#define DEFAULT_DB_PATH \"${DB_PATH}\"" >> ${CONFIGFILE}
|
||||
echo "" >> ${CONFIGFILE}
|
||||
|
||||
echo "/* full path of the log directory */" >> ${CONFIGFILE}
|
||||
@ -203,6 +206,8 @@ echo "/* Enable ReadyNAS-specific tweaks. */" >> ${CONFIGFILE}
|
||||
echo "${READYNAS}" >> ${CONFIGFILE}
|
||||
echo "/* Compile in TiVo support. */" >> ${CONFIGFILE}
|
||||
echo "${TIVO}" >> ${CONFIGFILE}
|
||||
echo "/* Enable PnPX support. */" >> ${CONFIGFILE}
|
||||
echo "${PNPX}" >> ${CONFIGFILE}
|
||||
echo "" >> ${CONFIGFILE}
|
||||
|
||||
echo "#endif" >> ${CONFIGFILE}
|
||||
|
83
minidlna.c
83
minidlna.c
@ -206,11 +206,13 @@ getfriendlyname(char * buf, int len)
|
||||
{
|
||||
char * dot = NULL;
|
||||
char * hn = calloc(1, 256);
|
||||
int off;
|
||||
|
||||
if( gethostname(hn, 256) == 0 )
|
||||
{
|
||||
strncpy(buf, hn, len-1);
|
||||
buf[len] = '\0';
|
||||
dot = index(buf, '.');
|
||||
dot = strchr(buf, '.');
|
||||
if( dot )
|
||||
*dot = '\0';
|
||||
}
|
||||
@ -219,13 +221,70 @@ getfriendlyname(char * buf, int len)
|
||||
strcpy(buf, "Unknown");
|
||||
}
|
||||
free(hn);
|
||||
strcat(buf, ": ");
|
||||
#ifdef READYNAS
|
||||
strncat(buf, "ReadyNAS", len-strlen(buf)-1);
|
||||
#else
|
||||
|
||||
off = strlen(buf);
|
||||
off += snprintf(buf+off, len-off, ": ");
|
||||
#ifdef READYNAS
|
||||
FILE * info;
|
||||
char ibuf[64], *key, *val;
|
||||
info = fopen("/proc/sys/dev/boot/info", "r");
|
||||
if( !info )
|
||||
{
|
||||
snprintf(buf+off, len-off, "ReadyNAS");
|
||||
return;
|
||||
}
|
||||
while( (val = fgets(ibuf, 64, info)) != NULL )
|
||||
{
|
||||
key = strsep(&val, ": \t");
|
||||
val = trim(val);
|
||||
if( strcmp(key, "model") == 0 )
|
||||
{
|
||||
key = strchr(val, ' ');
|
||||
if( key )
|
||||
{
|
||||
strncpy(modelnumber, key+1, MODELNUMBER_MAX_LEN);
|
||||
modelnumber[MODELNUMBER_MAX_LEN-1] = '\0';
|
||||
*key = '\0';
|
||||
}
|
||||
snprintf(modelname, MODELNAME_MAX_LEN,
|
||||
"Windows Media Connect compatible (%s)", val);
|
||||
}
|
||||
else if( strcmp(key, "serial") == 0 )
|
||||
{
|
||||
strncpy(serialnumber, val, SERIALNUMBER_MAX_LEN);
|
||||
serialnumber[SERIALNUMBER_MAX_LEN-1] = '\0';
|
||||
if( serialnumber[0] == '\0' )
|
||||
{
|
||||
char mac_str[13];
|
||||
if( getsyshwaddr(mac_str, sizeof(mac_str)) == 0 )
|
||||
strcpy(serialnumber, mac_str);
|
||||
else
|
||||
strcpy(serialnumber, "0");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose(info);
|
||||
if( strcmp(modelnumber, "NVX") == 0 )
|
||||
memcpy(pnpx_hwid+4, "01F2&DEV_0101", 17);
|
||||
else if( strcmp(modelnumber, "Pro") == 0 ||
|
||||
strcmp(modelnumber, "Pro 6") == 0 ||
|
||||
strncmp(modelnumber, "Ultra 6", 7) == 0 )
|
||||
memcpy(pnpx_hwid+4, "01F2&DEV_0102", 17);
|
||||
else if( strcmp(modelnumber, "Pro 2") == 0 ||
|
||||
strncmp(modelnumber, "Ultra 2", 7) == 0 )
|
||||
memcpy(pnpx_hwid+4, "01F2&DEV_0103", 17);
|
||||
else if( strcmp(modelnumber, "Pro 4") == 0 ||
|
||||
strncmp(modelnumber, "Ultra 4", 7) == 0 )
|
||||
memcpy(pnpx_hwid+4, "01F2&DEV_0104", 17);
|
||||
else if( strcmp(modelnumber+1, "100") == 0 )
|
||||
memcpy(pnpx_hwid+4, "01F2&DEV_0105", 17);
|
||||
else if( strcmp(modelnumber+1, "200") == 0 )
|
||||
memcpy(pnpx_hwid+4, "01F2&DEV_0106", 17);
|
||||
#else
|
||||
char * logname;
|
||||
logname = getenv("LOGNAME");
|
||||
#if 1 // Disable for static linking
|
||||
#ifndef STATIC // Disable for static linking
|
||||
if( !logname )
|
||||
{
|
||||
struct passwd * pwent;
|
||||
@ -234,8 +293,8 @@ getfriendlyname(char * buf, int len)
|
||||
logname = pwent->pw_name;
|
||||
}
|
||||
#endif
|
||||
strncat(buf, logname?logname:"Unknown", len-strlen(buf)-1);
|
||||
#endif
|
||||
snprintf(buf+off, len-off, "%s", logname?logname:"Unknown");
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
@ -362,6 +421,10 @@ init(int argc, char * * argv)
|
||||
strncpy(serialnumber, ary_options[i].value, SERIALNUMBER_MAX_LEN);
|
||||
serialnumber[SERIALNUMBER_MAX_LEN-1] = '\0';
|
||||
break;
|
||||
case UPNPMODEL_NAME:
|
||||
strncpy(modelname, ary_options[i].value, MODELNAME_MAX_LEN);
|
||||
modelname[MODELNAME_MAX_LEN-1] = '\0';
|
||||
break;
|
||||
case UPNPMODEL_NUMBER:
|
||||
strncpy(modelnumber, ary_options[i].value, MODELNUMBER_MAX_LEN);
|
||||
modelnumber[MODELNUMBER_MAX_LEN-1] = '\0';
|
||||
@ -770,10 +833,10 @@ main(int argc, char * * argv)
|
||||
return 1;
|
||||
|
||||
#ifdef READYNAS
|
||||
DPRINTF(E_WARN, L_GENERAL, "Starting ReadyDLNA version " MINIDLNA_VERSION ".\n");
|
||||
DPRINTF(E_WARN, L_GENERAL, "Starting " SERVER_NAME " version " MINIDLNA_VERSION ".\n");
|
||||
unlink("/ramfs/.upnp-av_scan");
|
||||
#else
|
||||
DPRINTF(E_WARN, L_GENERAL, "Starting MiniDLNA version " MINIDLNA_VERSION " [SQLite %s].\n", sqlite3_libversion());
|
||||
DPRINTF(E_WARN, L_GENERAL, "Starting " SERVER_NAME " version " MINIDLNA_VERSION " [SQLite %s].\n", sqlite3_libversion());
|
||||
if( !sqlite3_threadsafe() )
|
||||
{
|
||||
DPRINTF(E_ERROR, L_GENERAL, "SQLite library is not threadsafe! "
|
||||
|
@ -50,6 +50,7 @@ static const struct {
|
||||
{ UPNPSYSTEM_UPTIME, "system_uptime" },
|
||||
{ UPNPUUID, "uuid"},
|
||||
{ UPNPSERIAL, "serial"},
|
||||
{ UPNPMODEL_NAME, "model_name"},
|
||||
{ UPNPMODEL_NUMBER, "model_number"},
|
||||
{ UPNPFRIENDLYNAME, "friendly_name"},
|
||||
{ UPNPMEDIADIR, "media_dir"},
|
||||
|
@ -43,6 +43,7 @@ enum upnpconfigoptions {
|
||||
UPNPSYSTEM_UPTIME, /* system_uptime */
|
||||
UPNPUUID, /* uuid */
|
||||
UPNPSERIAL, /* serial */
|
||||
UPNPMODEL_NAME, /* model_name */
|
||||
UPNPMODEL_NUMBER, /* model_number */
|
||||
UPNPFRIENDLYNAME, /* how the system should show up to DLNA clients */
|
||||
UPNPMEDIADIR, /* directory to search for UPnP-A/V content */
|
||||
|
@ -37,9 +37,13 @@
|
||||
char uuidvalue[] = "uuid:12345678-0000-0000-0000-00000000abcd";
|
||||
char friendly_name[] = "localhost: system_type";
|
||||
char serialnumber[] = "12345678";
|
||||
char modelname[] = "MiniDLNA";
|
||||
char modelnumber[] = "1";
|
||||
char presentationurl[] = "http://192.168.0.1:8080/";
|
||||
unsigned int updateID = 0;
|
||||
#if PNPX
|
||||
char pnpx_hwid[] = "VEN_01F2&DEV_0101&REV_01 VEN_0033&DEV_0001&REV_01";
|
||||
#endif
|
||||
|
||||
int getifaddr(const char * ifname, char * buf, int len)
|
||||
{
|
||||
|
@ -117,37 +117,46 @@ static const char xmlver[] =
|
||||
static const char root_service[] =
|
||||
"scpd xmlns=\"urn:schemas-upnp-org:service-1-0\"";
|
||||
static const char root_device[] =
|
||||
"root xmlns=\"urn:schemas-upnp-org:device-1-0\"";
|
||||
"root xmlns=\"urn:schemas-upnp-org:device-1-0\""
|
||||
#if PNPX
|
||||
" xmlns:pnpx=\"http://schemas.microsoft.com/windows/pnpx/2005/11\""
|
||||
" xmlns:df=\"http://schemas.microsoft.com/windows/2008/09/devicefoundation\""
|
||||
#endif
|
||||
;
|
||||
|
||||
/* root Description of the UPnP Device
|
||||
* fixed to match UPnP_IGD_InternetGatewayDevice 1.0.pdf
|
||||
* presentationURL is only "recommended" but the router doesn't appears
|
||||
* in "Network connections" in Windows XP if it is not present. */
|
||||
/* root Description of the UPnP Device */
|
||||
static const struct XMLElt rootDesc[] =
|
||||
{
|
||||
{root_device, INITHELPER(1,2)},
|
||||
{"specVersion", INITHELPER(3,2)},
|
||||
{"device", INITHELPER(5,14)},
|
||||
{"device", INITHELPER(5,(14+PNPX))},
|
||||
{"/major", "1"},
|
||||
{"/minor", "0"},
|
||||
{"/deviceType", "urn:schemas-upnp-org:device:MediaServer:1"},
|
||||
#if PNPX == 5
|
||||
{"/pnpx:X_hardwareId", pnpx_hwid},
|
||||
{"/pnpx:X_compatibleId", "MS_DigitalMediaDeviceClass_DMS_V001"},
|
||||
{"/pnpx:X_deviceCategory", "MediaDevices"},
|
||||
{"/df:X_deviceCategory", "Multimedia.DMS"},
|
||||
{"/microsoft:magicPacketWakeSupported xmlns:microsoft=\"urn:schemas-microsoft-com:WMPNSS-1-0\"", "0"},
|
||||
#endif
|
||||
{"/friendlyName", friendly_name}, /* required */
|
||||
{"/manufacturer", ROOTDEV_MANUFACTURER}, /* required */
|
||||
{"/manufacturerURL", ROOTDEV_MANUFACTURERURL}, /* optional */
|
||||
{"/modelDescription", ROOTDEV_MODELDESCRIPTION}, /* recommended */
|
||||
{"/modelName", ROOTDEV_MODELNAME}, /* required */
|
||||
{"/modelName", modelname}, /* required */
|
||||
{"/modelNumber", modelnumber},
|
||||
{"/modelURL", ROOTDEV_MODELURL},
|
||||
{"/serialNumber", serialnumber},
|
||||
{"/UDN", uuidvalue}, /* required */
|
||||
{"/dlna:X_DLNADOC xmlns:dlna=\"urn:schemas-dlna-org:device-1-0\"", "DMS-1.50"},
|
||||
{"/presentationURL", presentationurl}, /* recommended */
|
||||
{"iconList", INITHELPER(19,4)},
|
||||
{"serviceList", INITHELPER(43,3)},
|
||||
{"icon", INITHELPER(23,5)},
|
||||
{"icon", INITHELPER(28,5)},
|
||||
{"icon", INITHELPER(33,5)},
|
||||
{"icon", INITHELPER(38,5)},
|
||||
{"iconList", INITHELPER((19+PNPX),4)},
|
||||
{"serviceList", INITHELPER((43+PNPX),3)},
|
||||
{"icon", INITHELPER((23+PNPX),5)},
|
||||
{"icon", INITHELPER((28+PNPX),5)},
|
||||
{"icon", INITHELPER((33+PNPX),5)},
|
||||
{"icon", INITHELPER((38+PNPX),5)},
|
||||
{"/mimetype", "image/png"},
|
||||
{"/width", "48"},
|
||||
{"/height", "48"},
|
||||
@ -168,9 +177,9 @@ static const struct XMLElt rootDesc[] =
|
||||
{"/height", "120"},
|
||||
{"/depth", "24"},
|
||||
{"/url", "/icons/lrg.jpg"},
|
||||
{"service", INITHELPER(46,5)},
|
||||
{"service", INITHELPER(51,5)},
|
||||
{"service", INITHELPER(56,5)},
|
||||
{"service", INITHELPER((46+PNPX),5)},
|
||||
{"service", INITHELPER((51+PNPX),5)},
|
||||
{"service", INITHELPER((56+PNPX),5)},
|
||||
{"/serviceType", "urn:schemas-upnp-org:service:ContentDirectory:1"},
|
||||
{"/serviceId", "urn:upnp-org:serviceId:ContentDirectory"},
|
||||
{"/controlURL", CONTENTDIRECTORY_CONTROLURL},
|
||||
|
@ -84,12 +84,6 @@ genConnectionManager(int * len);
|
||||
char *
|
||||
genX_MS_MediaReceiverRegistrar(int * len);
|
||||
|
||||
char *
|
||||
genWANIPCn(int * len);
|
||||
|
||||
char *
|
||||
genWANCfg(int * len);
|
||||
|
||||
char *
|
||||
getVarsContentDirectory(int * len);
|
||||
|
||||
|
@ -52,6 +52,7 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "upnpglobalvars.h"
|
||||
#include "upnpdescstrings.h"
|
||||
|
||||
/* LAN address */
|
||||
/*const char * listen_addr = 0;*/
|
||||
@ -65,9 +66,12 @@ int runtime_flags = INOTIFY_MASK;
|
||||
const char * pidfilename = "/var/run/minidlna.pid";
|
||||
|
||||
char uuidvalue[] = "uuid:00000000-0000-0000-0000-000000000000";
|
||||
char modelname[MODELNAME_MAX_LEN] = ROOTDEV_MODELNAME;
|
||||
char modelnumber[MODELNUMBER_MAX_LEN] = MINIDLNA_VERSION;
|
||||
char serialnumber[SERIALNUMBER_MAX_LEN] = "00000000";
|
||||
|
||||
char modelnumber[MODELNUMBER_MAX_LEN] = "1";
|
||||
#if PNPX
|
||||
char pnpx_hwid[] = "VEN_0000&DEV_0000&REV_01 VEN_0033&DEV_0001&REV_01";
|
||||
#endif
|
||||
|
||||
/* presentation url :
|
||||
* http://nnn.nnn.nnn.nnn:ppppp/ => max 30 bytes including terminating 0 */
|
||||
|
@ -57,7 +57,13 @@
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
#define MINIDLNA_VERSION "1.0.18.2"
|
||||
#define MINIDLNA_VERSION "1.0.19"
|
||||
|
||||
#ifdef NETGEAR
|
||||
# define SERVER_NAME "ReadyDLNA"
|
||||
#else
|
||||
# define SERVER_NAME "MiniDLNA"
|
||||
#endif
|
||||
|
||||
#define CLIENT_CACHE_SLOTS 20
|
||||
#define USE_FORK 1
|
||||
@ -69,6 +75,10 @@
|
||||
#define _(string) (string)
|
||||
#endif
|
||||
|
||||
#ifndef PNPX
|
||||
#define PNPX 0
|
||||
#endif
|
||||
|
||||
#if 0 // Add these once the newer ffmpeg libs that can detect WMAPRO are more widely used
|
||||
"http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVHIGH_PRO;DLNA.ORG_OP=01;DLNA.ORG_CI=0,"
|
||||
"http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_PRO;DLNA.ORG_OP=01;DLNA.ORG_CI=0,"
|
||||
@ -137,15 +147,22 @@ extern const char * pidfilename;
|
||||
|
||||
extern char uuidvalue[];
|
||||
|
||||
#define SERIALNUMBER_MAX_LEN (10)
|
||||
extern char serialnumber[];
|
||||
#define MODELNAME_MAX_LEN (64)
|
||||
extern char modelname[];
|
||||
|
||||
#define MODELNUMBER_MAX_LEN (48)
|
||||
#define MODELNUMBER_MAX_LEN (16)
|
||||
extern char modelnumber[];
|
||||
|
||||
#define SERIALNUMBER_MAX_LEN (16)
|
||||
extern char serialnumber[];
|
||||
|
||||
#define PRESENTATIONURL_MAX_LEN (64)
|
||||
extern char presentationurl[];
|
||||
|
||||
#if PNPX
|
||||
extern char pnpx_hwid[];
|
||||
#endif
|
||||
|
||||
/* lan addresses */
|
||||
/* MAX_LAN_ADDR : maximum number of interfaces
|
||||
* to listen to SSDP traffic */
|
||||
|
Loading…
x
Reference in New Issue
Block a user