From 401da95831171737dfe71bea51403f398834f846 Mon Sep 17 00:00:00 2001 From: Justin Maggard Date: Fri, 1 May 2009 19:36:43 +0000 Subject: [PATCH] * Add generic DLNA client type detection and caching, and don't use DLNA-specific MIME types if the client doesn't support DLNA. --- minidlnatypes.h | 4 +++- upnphttp.c | 9 +++++++++ upnphttp.h | 30 ++++++++++++++++-------------- upnpsoap.c | 37 +++++++++++++++++++++++++------------ upnpsoap.h | 1 + 5 files changed, 54 insertions(+), 27 deletions(-) diff --git a/minidlnatypes.h b/minidlnatypes.h index 9f8434a..ef5c638 100644 --- a/minidlnatypes.h +++ b/minidlnatypes.h @@ -31,7 +31,8 @@ enum media_types { enum client_types { EXbox = 1, EPS3, - ESamsungTV + ESamsungTV, + EUnknownClient }; struct media_dir_s { @@ -48,6 +49,7 @@ struct album_art_name_s { struct client_cache_s { struct in_addr addr; enum client_types type; + u_int32_t flags; time_t age; }; diff --git a/upnphttp.c b/upnphttp.c index eeb56f4..deaa4cf 100644 --- a/upnphttp.c +++ b/upnphttp.c @@ -215,10 +215,17 @@ intervening space) by either an integer or the keyword "infinite". */ else if(strncmp(p, "PLAYSTATION", 11)==0) { h->req_client = EPS3; + h->reqflags |= FLAG_DLNA; } else if(strncmp(p, "SamsungWiselinkPro", 18)==0) { h->req_client = ESamsungTV; + h->reqflags |= FLAG_DLNA; + } + else if(strcasestr(p, "DLNADOC/")) + { + h->req_client = EUnknownClient; + h->reqflags |= FLAG_DLNA; } } else if(strncasecmp(line, "Transfer-Encoding", 17)==0) @@ -311,10 +318,12 @@ intervening space) by either an integer or the keyword "infinite". */ } } clients[n].type = h->req_client; + clients[n].flags = h->reqflags & 0xFFF00000; clients[n].age = time(NULL); } else if( n >= 0 ) { + h->reqflags |= clients[n].flags; h->req_client = clients[n].type; } } diff --git a/upnphttp.h b/upnphttp.h index efbc9fd..0aa9f98 100644 --- a/upnphttp.h +++ b/upnphttp.h @@ -54,7 +54,7 @@ struct upnphttp { long long int req_RangeStart; long long int req_RangeEnd; long int req_chunklen; - int reqflags; + u_int32_t reqflags; int respflags; /* response */ char * res_buf; @@ -65,21 +65,23 @@ struct upnphttp { LIST_ENTRY(upnphttp) entries; }; -#define FLAG_TIMEOUT 0x01 -#define FLAG_SID 0x02 -#define FLAG_RANGE 0x04 -#define FLAG_HOST 0x08 +#define FLAG_TIMEOUT 0x00000001 +#define FLAG_SID 0x00000002 +#define FLAG_RANGE 0x00000004 +#define FLAG_HOST 0x00000008 -#define FLAG_HTML 0x80 -#define FLAG_INVALID_REQ 0x10 +#define FLAG_HTML 0x00000080 +#define FLAG_INVALID_REQ 0x00000010 -#define FLAG_CHUNKED 0x0100 -#define FLAG_TIMESEEK 0x0200 -#define FLAG_REALTIMEINFO 0x0400 -#define FLAG_PLAYSPEED 0x0800 -#define FLAG_XFERSTREAMING 0x1000 -#define FLAG_XFERINTERACTIVE 0x2000 -#define FLAG_XFERBACKGROUND 0x4000 +#define FLAG_CHUNKED 0x00000100 +#define FLAG_TIMESEEK 0x00000200 +#define FLAG_REALTIMEINFO 0x00000400 +#define FLAG_PLAYSPEED 0x00000800 +#define FLAG_XFERSTREAMING 0x00001000 +#define FLAG_XFERINTERACTIVE 0x00002000 +#define FLAG_XFERBACKGROUND 0x00004000 + +#define FLAG_DLNA 0x00100000 /* New_upnphttp() */ struct upnphttp * diff --git a/upnpsoap.c b/upnpsoap.c index 7038da5..e0b2799 100644 --- a/upnpsoap.c +++ b/upnpsoap.c @@ -446,22 +446,33 @@ callback(void *args, int argc, char **argv, char **azColName) if( strncmp(class, "item", 4) == 0 ) { - switch( passed_args->client ) + /* We may need special handling for MIME types */ + if( strncmp(mime, "video", 5) == 0 ) { - case EPS3: - if( creator && (strcmp(mime, "video/x-msvideo") == 0) ) - { - strcpy(mime+6, "divx"); + switch( passed_args->client ) + { + case EPS3: + if( creator && (strcmp(mime, "video/x-msvideo") == 0) ) + { + strcpy(mime+6, "divx"); + break; + } + case EXbox: + if( strcmp(mime, "video/x-msvideo") == 0 ) + { + strcpy(mime+6, "avi"); + } break; - } - case EXbox: - if( strcmp(mime, "video/x-msvideo") == 0 ) + default: + break; + } + if( !(passed_args->flags & FLAG_DLNA) ) + { + if( strcmp(mime+6, "vnd.dlna.mpeg-tts") == 0 ) { - strcpy(mime+6, "avi"); + strcpy(mime+6, "mpeg"); } - break; - default: - break; + } } ret = sprintf(str_buf, "<item id=\"%s\" parentID=\"%s\" restricted=\"1\"", id, parent); memcpy(passed_args->resp+passed_args->size, &str_buf, ret+1); @@ -720,6 +731,7 @@ BrowseContentDirectory(struct upnphttp * h, const char * action) args.returned = 0; args.requested = RequestedCount; args.client = h->req_client; + args.flags = h->reqflags; if( h->req_client == EXbox ) { if( strcmp(ObjectId, "16") == 0 ) @@ -848,6 +860,7 @@ SearchContentDirectory(struct upnphttp * h, const char * action) args.returned = 0; args.requested = RequestedCount; args.client = h->req_client; + args.flags = h->reqflags; if( h->req_client == EXbox ) { if( strcmp(ContainerID, "4") == 0 ) diff --git a/upnpsoap.h b/upnpsoap.h index af33ccd..cb69770 100644 --- a/upnpsoap.h +++ b/upnpsoap.h @@ -22,6 +22,7 @@ struct Response int requested; int size; u_int32_t filter; + u_int32_t flags; enum client_types client; };