From 0d3505656de8bfbe960843fcdfca9057d5e34dd3 Mon Sep 17 00:00:00 2001 From: Justin Maggard Date: Tue, 10 Feb 2009 07:41:50 +0000 Subject: [PATCH] * Fix accidental double-scan from last checkin. * Add XBox360 compatibility. --- getifaddr.c | 6 +----- minidlna.c | 1 - scanner.c | 16 ++++++++-------- scanner.h | 6 +++--- upnphttp.c | 10 ++++++++++ upnphttp.h | 5 +++++ upnpsoap.c | 47 ++++++++++++++++++++++++++++++++++++++++++++--- upnpsoap.h | 10 ++++++++++ 8 files changed, 81 insertions(+), 20 deletions(-) diff --git a/getifaddr.c b/getifaddr.c index 00679b5..2f5e452 100644 --- a/getifaddr.c +++ b/getifaddr.c @@ -71,11 +71,7 @@ getsysaddr(char * buf, int len) if( ioctl(s, SIOCGIFNAME, &ifr) < 0 ) break; if(ioctl(s, SIOCGIFADDR, &ifr, sizeof(struct ifreq)) < 0) - { - syslog(LOG_ERR, "ioctl(s, SIOCGIFADDR, ...): %m"); - close(s); - return -1; - } + continue; if(strncmp(inet_ntoa(addr->sin_addr), "127.", 4) == 0) continue; if(!inet_ntop(AF_INET, &addr->sin_addr, buf, len)) diff --git a/minidlna.c b/minidlna.c index 2b34e12..264f65b 100644 --- a/minidlna.c +++ b/minidlna.c @@ -640,7 +640,6 @@ main(int argc, char * * argv) ScanDirectory(media_path->path, NULL, media_path->type); media_path = media_path->next; } - ScanDirectory(media_dirs->path, NULL, media_dirs->type); freopen("/proc/self/fd/2", "a", stderr); #if USE_FORK _exit(0); diff --git a/scanner.c b/scanner.c index 9f280b3..eac6f0b 100644 --- a/scanner.c +++ b/scanner.c @@ -207,7 +207,7 @@ insert_containers(const char * name, const char *path, const char * refID, const /* All Images */ if( !last_all_objectID ) { - last_all_objectID = get_next_available_id("OBJECTS", "1$4"); + last_all_objectID = get_next_available_id("OBJECTS", "3$11"); } sql = sqlite3_mprintf( "INSERT into OBJECTS" " (OBJECT_ID, PARENT_ID, REF_ID, CLASS, DETAIL_ID, NAME) " @@ -323,7 +323,7 @@ insert_containers(const char * name, const char *path, const char * refID, const /* All Videos */ if( !last_all_objectID ) { - last_all_objectID = get_next_available_id("OBJECTS", "1$4"); + last_all_objectID = get_next_available_id("OBJECTS", "2$8"); } sql = sqlite3_mprintf( "INSERT into OBJECTS" " (OBJECT_ID, PARENT_ID, REF_ID, CLASS, DETAIL_ID, NAME) " @@ -436,7 +436,7 @@ insert_file(char * name, const char * path, const char * parentID, int object) if( is_image(name) ) { strcpy(base, IMAGE_DIR_ID); - strcpy(class, "item.imageItem"); + strcpy(class, "item.imageItem.photo"); detailID = GetImageMetadata(path, name); } else if( is_audio(name) ) @@ -504,15 +504,15 @@ CreateDatabase(void) "1$5", "1", "Genre", "1$6", "1", "Artist", "1$7", "1", "Album", - "1$20", "1", "Folders", + "1$14", "1", "Folders", "2", "0", "Video", "2$8", "2", "All Video", - "2$21", "2", "Folders", + "3$15", "2", "Folders", "3", "0", "Pictures", "3$11", "3", "All Pictures", - "3$12", "3", "Date Taken", - "3$13", "3", "Camera", - "3$22", "3", "Folders", + "3$C", "3", "Date Taken", + "3$D", "3", "Camera", + "3$16", "3", "Folders", "64", "0", "Browse Folders", 0 }; diff --git a/scanner.h b/scanner.h index c4ca4e4..f6f3dba 100644 --- a/scanner.h +++ b/scanner.h @@ -11,9 +11,9 @@ #define __SCANNER_H__ #define BROWSEDIR_ID "64" -#define MUSIC_DIR_ID "1$20" -#define VIDEO_DIR_ID "2$21" -#define IMAGE_DIR_ID "3$22" +#define MUSIC_DIR_ID "1$14" +#define VIDEO_DIR_ID "2$15" +#define IMAGE_DIR_ID "3$16" sqlite_int64 get_next_available_id(const char * table, const char * parentID); diff --git a/upnphttp.c b/upnphttp.c index 58b9dd8..dc27ef0 100644 --- a/upnphttp.c +++ b/upnphttp.c @@ -184,6 +184,16 @@ intervening space) by either an integer or the keyword "infinite". */ { h->reqflags |= FLAG_HOST; } + else if(strncasecmp(line, "User-Agent", 10)==0) + { + p = colon + 1; + while(isspace(*p)) + p++; + if(strncasecmp(p, "Xbox/", 5)==0) + { + h->req_client = EXbox; + } + } else if(strncasecmp(line, "Transfer-Encoding", 17)==0) { p = colon + 1; diff --git a/upnphttp.h b/upnphttp.h index 52c6c93..76b4144 100644 --- a/upnphttp.h +++ b/upnphttp.h @@ -31,6 +31,10 @@ enum httpCommands { EUnSubscribe }; +enum clientType { + EXbox = 1 +}; + struct upnphttp { int socket; struct in_addr clientaddr; /* client address */ @@ -42,6 +46,7 @@ struct upnphttp { int req_contentlen; int req_contentoff; /* header length */ enum httpCommands req_command; + enum clientType req_client; const char * req_soapAction; int req_soapActionLen; #ifdef ENABLE_EVENTS diff --git a/upnpsoap.c b/upnpsoap.c index 4dea89b..997bffb 100644 --- a/upnpsoap.c +++ b/upnpsoap.c @@ -206,7 +206,7 @@ GetCurrentConnectionInfo(struct upnphttp * h, const char * action) static int callback(void *args, int argc, char **argv, char **azColName) { - struct Response { char *resp; int returned; int requested; int total; char *filter; } *passed_args = (struct Response *)args; + struct Response *passed_args = (struct Response *)args; char *id = argv[1], *parent = argv[2], *refID = argv[3], *class = argv[4], *detailID = argv[5], *size = argv[9], *title = argv[10], *duration = argv[11], *bitrate = argv[12], *sampleFrequency = argv[13], *artist = argv[14], *album = argv[15], *genre = argv[16], *comment = argv[17], *nrAudioChannels = argv[18], *track = argv[19], *date = argv[20], *resolution = argv[21], @@ -229,6 +229,16 @@ static int callback(void *args, int argc, char **argv, char **azColName) if( strncmp(class, "item", 4) == 0 ) { + if( passed_args->client == EXbox ) + { + if( strcmp(mime, "video/divx") == 0 ) + { + mime[6] = 'a'; + mime[7] = 'v'; + mime[8] = 'i'; + mime[9] = '\0'; + } + } sprintf(str_buf, "<item id=\"%s\" parentID=\"%s\" restricted=\"1\"", id, parent); strcat(passed_args->resp, str_buf); if( refID && (!passed_args->filter || strstr(passed_args->filter, "@refID")) ) { @@ -404,7 +414,7 @@ BrowseContentDirectory(struct upnphttp * h, const char * action) char *zErrMsg = 0; char *sql; int ret; - struct Response { char *resp; int returned; int requested; int total; char *filter; } args; + struct Response args; struct NameValueParserData data; ParseNameValue(h->req_buf + h->req_contentoff, h->req_contentlen, &data); @@ -430,6 +440,16 @@ BrowseContentDirectory(struct upnphttp * h, const char * action) args.requested = RequestedCount; args.resp = NULL; args.filter = NULL; + args.client = h->req_client; + if( h->req_client == EXbox ) + { + if( strcmp(ObjectId, "16") == 0 ) + ObjectId = strdup("3$16"); + else if( strcmp(ObjectId, "15") == 0 ) + ObjectId = strdup("2$15"); + else + ObjectId = strdup(ObjectId); + } printf("Asked for ObjectID: %s\n", ObjectId); printf("Asked for Count: %d\n", RequestedCount); printf("Asked for StartingIndex: %d\n", StartingIndex); @@ -475,6 +495,10 @@ BrowseContentDirectory(struct upnphttp * h, const char * action) BuildSendAndCloseSoapResp(h, resp, strlen(resp)); ClearNameValueList(&data); free(resp); + if( h->req_client == EXbox ) + { + free(ObjectId); + } } static void @@ -494,7 +518,7 @@ SearchContentDirectory(struct upnphttp * h, const char * action) char *sql; char str_buf[4096]; int ret; - struct Response { char *resp; int returned; int requested; int total; char *filter; } args; + struct Response args; struct NameValueParserData data; ParseNameValue(h->req_buf + h->req_contentoff, h->req_contentlen, &data); @@ -513,6 +537,19 @@ SearchContentDirectory(struct upnphttp * h, const char * action) args.requested = RequestedCount; args.resp = NULL; args.filter = NULL; + if( h->req_client == EXbox ) + { + if( strcmp(ContainerID, "4") == 0 ) + ContainerID = strdup("1$4"); + else if( strcmp(ContainerID, "5") == 0 ) + ContainerID = strdup("1$5"); + else if( strcmp(ContainerID, "6") == 0 ) + ContainerID = strdup("1$6"); + else if( strcmp(ContainerID, "7") == 0 ) + ContainerID = strdup("1$7"); + else + ContainerID = strdup(ContainerID); + } printf("Asked for ContainerID: %s\n", ContainerID); printf("Asked for Count: %d\n", RequestedCount); printf("Asked for StartingIndex: %d\n", StartingIndex); @@ -595,6 +632,10 @@ SearchContentDirectory(struct upnphttp * h, const char * action) if( newSearchCriteria ) free(newSearchCriteria); free(resp); + if( h->req_client == EXbox ) + { + free(ContainerID); + } } /* diff --git a/upnpsoap.h b/upnpsoap.h index 258478c..ceb8324 100644 --- a/upnpsoap.h +++ b/upnpsoap.h @@ -14,6 +14,16 @@ #define DLNA_NAMESPACE \ " xmlns:dlna=\"urn:schemas-dlna-org:metadata-1-0/\"" +struct Response +{ + char *resp; + int returned; + int requested; + int total; + char *filter; + enum clientType client; +}; + /* ExecuteSoapAction(): * this method executes the requested Soap Action */ void