* Add PnP-X support.

This commit is contained in:
Justin Maggard 2011-02-17 23:17:24 +00:00
parent 41136ae17c
commit 309499d378
10 changed files with 141 additions and 42 deletions

View File

@ -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

View File

@ -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}

View File

@ -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! "

View File

@ -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"},

View File

@ -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 */

View File

@ -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)
{

View File

@ -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},

View File

@ -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);

View File

@ -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 */

View File

@ -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 */