[Mt-daapd-cvs] SF.net SVN: mt-daapd: [1581] trunk
Status: Beta
Brought to you by:
andrew40
From: <rp...@us...> - 2007-05-04 21:31:13
|
Revision: 1581 http://svn.sourceforge.net/mt-daapd/?rev=1581&view=rev Author: rpedde Date: 2007-05-04 14:31:05 -0700 (Fri, 04 May 2007) Log Message: ----------- Finish (mostly) upnp discovery Modified Paths: -------------- trunk/admin-root/upnp-basic.xml trunk/src/conf.c trunk/src/configfile.c trunk/src/main.c trunk/src/upnp.c trunk/src/upnp.h Added Paths: ----------- trunk/admin-root/upnp/ trunk/admin-root/upnp/ff_logo_16.png trunk/admin-root/upnp/ff_logo_32.png trunk/admin-root/upnp/ff_logo_48.png trunk/admin-root/upnp-cd.xml trunk/admin-root/upnp-cm.xml Added: trunk/admin-root/upnp/ff_logo_16.png =================================================================== (Binary files differ) Property changes on: trunk/admin-root/upnp/ff_logo_16.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/admin-root/upnp/ff_logo_32.png =================================================================== (Binary files differ) Property changes on: trunk/admin-root/upnp/ff_logo_32.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/admin-root/upnp/ff_logo_48.png =================================================================== (Binary files differ) Property changes on: trunk/admin-root/upnp/ff_logo_48.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Modified: trunk/admin-root/upnp-basic.xml =================================================================== --- trunk/admin-root/upnp-basic.xml 2007-05-04 04:59:06 UTC (rev 1580) +++ trunk/admin-root/upnp-basic.xml 2007-05-04 21:31:05 UTC (rev 1581) @@ -15,18 +15,27 @@ <modelURL>http://www.fireflymediaserver.org/</modelURL> <serialNumber>SERIAL-001</serialNumber> <UDN>uuid:@upnp@</UDN> + <iconList> + <icon> + <mimetype>image/png</mimetype> + <width>32</width> + <height>32</height> + <depth>32</depth> + <url>/upnp/ff_logo_32.png</url> + </icon> + </iconList> <serviceList> <service> <serviceType>urn:schemas-upnp-org:service:ConnectionManager:1</serviceType> <serviceId>urn:upnp-org:serviceId:ConnectionManager</serviceId> - <SCPDURL>/upnp/cm/scpdurl</SCPDURL> + <SCPDURL>/upnp-cm.xml</SCPDURL> <controlURL>/upnp/cm/control</controlURL> <eventSubURL>/upnp/cm/event</eventSubURL> </service> <service> <serviceType>urn:schemas-upnp-org:service:ContentDirectory:1</serviceType> <serviceId>urn:upnp-org:serviceId:ContentDirectory</serviceId> - <SCPDURL>/upnp/cd/scpdurl</SCPDURL> + <SCPDURL>/upnp-cd.xml</SCPDURL> <controlURL>/upnp/cd/control</controlURL> <eventSubURL>/upnp/cd/event</eventSubURL> </service> Added: trunk/admin-root/upnp-cd.xml =================================================================== --- trunk/admin-root/upnp-cd.xml (rev 0) +++ trunk/admin-root/upnp-cd.xml 2007-05-04 21:31:05 UTC (rev 1581) @@ -0,0 +1,178 @@ +<?xml version="1.0" encoding="utf-8"?> +<scpd xmlns="urn:schemas-upnp-org:service-1-0"> + <specVersion> + <major>1</major> + <minor>0</minor> + </specVersion> + <actionList> + <action> + <name>Browse</name> + <argumentList> + <argument> + <name>ObjectID</name> + <direction>in</direction> + <relatedStateVariable>A_ARG_TYPE_ObjectID</relatedStateVariable> + </argument> + <argument> + <name>BrowseFlag</name> + <direction>in</direction> + <relatedStateVariable>A_ARG_TYPE_BrowseFlag</relatedStateVariable> + </argument> + <argument> + <name>Filter</name> + <direction>in</direction> + <relatedStateVariable>A_ARG_TYPE_Filter</relatedStateVariable> + </argument> + <argument> + <name>StartingIndex</name> + <direction>in</direction> + <relatedStateVariable>A_ARG_TYPE_Index</relatedStateVariable> + </argument> + <argument> + <name>RequestedCount</name> + <direction>in</direction> + <relatedStateVariable>A_ARG_TYPE_Count</relatedStateVariable> + </argument> + <argument> + <name>SortCriteria</name> + <direction>in</direction> + <relatedStateVariable>A_ARG_TYPE_SortCriteria</relatedStateVariable> + </argument> + <argument> + <name>Result</name> + <direction>out</direction> + <relatedStateVariable>A_ARG_TYPE_Result</relatedStateVariable> + </argument> + <argument> + <name>NumberReturned</name> + <direction>out</direction> + <relatedStateVariable>A_ARG_TYPE_Count</relatedStateVariable> + </argument> + <argument> + <name>TotalMatches</name> + <direction>out</direction> + <relatedStateVariable>A_ARG_TYPE_Count</relatedStateVariable> + </argument> + <argument> + <name>UpdateID</name> + <direction>out</direction> + <relatedStateVariable>A_ARG_TYPE_UpdateID</relatedStateVariable> + </argument> + </argumentList> + </action> + <action> + <name>DestroyObject</name> + <argumentList> + <argument> + <name>ObjectID</name> + <direction>in</direction> + <relatedStateVariable>A_ARG_TYPE_ObjectID</relatedStateVariable> + </argument> + </argumentList> + </action> + <action> + <name>GetSystemUpdateID</name> + <argumentList> + <argument> + <name>Id</name> + <direction>out</direction> + <relatedStateVariable>SystemUpdateID</relatedStateVariable> + </argument> + </argumentList> + </action> + <action> + <name>GetSearchCapabilities</name> + <argumentList> + <argument> + <name>SearchCaps</name> + <direction>out</direction> + <relatedStateVariable>SearchCapabilities</relatedStateVariable> + </argument> + </argumentList> + </action> + <action> + <name>GetSortCapabilities</name> + <argumentList> + <argument> + <name>SortCaps</name> + <direction>out</direction> + <relatedStateVariable>SortCapabilities</relatedStateVariable> + </argument> + </argumentList> + </action> + <action> + <name>UpdateObject</name> + <argumentList> + <argument> + <name>ObjectID</name> + <direction>in</direction> + <relatedStateVariable>A_ARG_TYPE_ObjectID</relatedStateVariable> + </argument> + <argument> + <name>CurrentTagValue</name> + <direction>in</direction> + <relatedStateVariable>A_ARG_TYPE_TagValueList</relatedStateVariable> + </argument> + <argument> + <name>NewTagValue</name> + <direction>in</direction> + <relatedStateVariable>A_ARG_TYPE_TagValueList</relatedStateVariable> + </argument> + </argumentList> + </action> + </actionList> + <serviceStateTable> + <stateVariable sendEvents="no"> + <name>A_ARG_TYPE_BrowseFlag</name> + <dataType>string</dataType> + <allowedValueList> + <allowedValue>BrowseMetadata</allowedValue> + <allowedValue>BrowseDirectChildren</allowedValue> + </allowedValueList> + </stateVariable> + <stateVariable sendEvents="yes"> + <name>SystemUpdateID</name> + <dataType>ui4</dataType> + </stateVariable> + <stateVariable sendEvents="no"> + <name>A_ARG_TYPE_Count</name> + <dataType>ui4</dataType> + </stateVariable> + <stateVariable sendEvents="no"> + <name>A_ARG_TYPE_SortCriteria</name> + <dataType>string</dataType> + </stateVariable> + <stateVariable sendEvents="no"> + <name>SortCapabilities</name> + <dataType>string</dataType> + </stateVariable> + <stateVariable sendEvents="no"> + <name>A_ARG_TYPE_Index</name> + <dataType>ui4</dataType> + </stateVariable> + <stateVariable sendEvents="no"> + <name>A_ARG_TYPE_ObjectID</name> + <dataType>string</dataType> + </stateVariable> + <stateVariable sendEvents="no"> + <name>A_ARG_TYPE_UpdateID</name> + <dataType>ui4</dataType> + </stateVariable> + <stateVariable sendEvents="no"> + <name>A_ARG_TYPE_TagValueList</name> + <dataType>string</dataType> + </stateVariable> + <stateVariable sendEvents="no"> + <name>A_ARG_TYPE_Result</name> + <dataType>string</dataType> + </stateVariable> + <stateVariable sendEvents="no"> + <name>SearchCapabilities</name> + <dataType>string</dataType> + </stateVariable> + <stateVariable sendEvents="no"> + <name>A_ARG_TYPE_Filter</name> + <dataType>string</dataType> + </stateVariable> + </serviceStateTable> +</scpd> \ No newline at end of file Added: trunk/admin-root/upnp-cm.xml =================================================================== --- trunk/admin-root/upnp-cm.xml (rev 0) +++ trunk/admin-root/upnp-cm.xml 2007-05-04 21:31:05 UTC (rev 1581) @@ -0,0 +1,132 @@ +<?xml version="1.0" encoding="utf-8"?> +<scpd xmlns="urn:schemas-upnp-org:service-1-0"> + <specVersion> + <major>1</major> + <minor>0</minor> + </specVersion> + <actionList> + <action> + <name>GetCurrentConnectionInfo</name> + <argumentList> + <argument> + <name>ConnectionID</name> + <direction>in</direction> + <relatedStateVariable>A_ARG_TYPE_ConnectionID</relatedStateVariable> + </argument> + <argument> + <name>RcsID</name> + <direction>out</direction> + <relatedStateVariable>A_ARG_TYPE_RcsID</relatedStateVariable> + </argument> + <argument> + <name>AVTransportID</name> + <direction>out</direction> + <relatedStateVariable>A_ARG_TYPE_AVTransportID</relatedStateVariable> + </argument> + <argument> + <name>ProtocolInfo</name> + <direction>out</direction> + <relatedStateVariable>A_ARG_TYPE_ProtocolInfo</relatedStateVariable> + </argument> + <argument> + <name>PeerConnectionManager</name> + <direction>out</direction> + <relatedStateVariable>A_ARG_TYPE_ConnectionManager</relatedStateVariable> + </argument> + <argument> + <name>PeerConnectionID</name> + <direction>out</direction> + <relatedStateVariable>A_ARG_TYPE_ConnectionID</relatedStateVariable> + </argument> + <argument> + <name>Direction</name> + <direction>out</direction> + <relatedStateVariable>A_ARG_TYPE_Direction</relatedStateVariable> + </argument> + <argument> + <name>Status</name> + <direction>out</direction> + <relatedStateVariable>A_ARG_TYPE_ConnectionStatus</relatedStateVariable> + </argument> + </argumentList> + </action> + <action> + <name>GetProtocolInfo</name> + <argumentList> + <argument> + <name>Source</name> + <direction>out</direction> + <relatedStateVariable>SourceProtocolInfo</relatedStateVariable> + </argument> + <argument> + <name>Sink</name> + <direction>out</direction> + <relatedStateVariable>SinkProtocolInfo</relatedStateVariable> + </argument> + </argumentList> + </action> + <action> + <name>GetCurrentConnectionIDs</name> + <argumentList> + <argument> + <name>ConnectionIDs</name> + <direction>out</direction> + <relatedStateVariable>CurrentConnectionIDs</relatedStateVariable> + </argument> + </argumentList> + </action> + </actionList> + <serviceStateTable> + <stateVariable sendEvents="no"> + <name>A_ARG_TYPE_ProtocolInfo</name> + <dataType>string</dataType> + </stateVariable> + <stateVariable sendEvents="no"> + <name>A_ARG_TYPE_ConnectionStatus</name> + <dataType>string</dataType> + <allowedValueList> + <allowedValue>OK</allowedValue> + <allowedValue>ContentFormatMismatch</allowedValue> + <allowedValue>InsufficientBandwidth</allowedValue> + <allowedValue>UnreliableChannel</allowedValue> + <allowedValue>Unknown</allowedValue> + </allowedValueList> + </stateVariable> + <stateVariable sendEvents="no"> + <name>A_ARG_TYPE_AVTransportID</name> + <dataType>i4</dataType> + </stateVariable> + <stateVariable sendEvents="no"> + <name>A_ARG_TYPE_RcsID</name> + <dataType>i4</dataType> + </stateVariable> + <stateVariable sendEvents="no"> + <name>A_ARG_TYPE_ConnectionID</name> + <dataType>i4</dataType> + </stateVariable> + <stateVariable sendEvents="no"> + <name>A_ARG_TYPE_ConnectionManager</name> + <dataType>string</dataType> + </stateVariable> + <stateVariable sendEvents="yes"> + <name>SourceProtocolInfo</name> + <dataType>string</dataType> + </stateVariable> + <stateVariable sendEvents="yes"> + <name>SinkProtocolInfo</name> + <dataType>string</dataType> + </stateVariable> + <stateVariable sendEvents="no"> + <name>A_ARG_TYPE_Direction</name> + <dataType>string</dataType> + <allowedValueList> + <allowedValue>Input</allowedValue> + <allowedValue>Output</allowedValue> + </allowedValueList> + </stateVariable> + <stateVariable sendEvents="yes"> + <name>CurrentConnectionIDs</name> + <dataType>string</dataType> + </stateVariable> + </serviceStateTable> +</scpd> \ No newline at end of file Modified: trunk/src/conf.c =================================================================== --- trunk/src/conf.c 2007-05-04 04:59:06 UTC (rev 1580) +++ trunk/src/conf.c 2007-05-04 21:31:05 UTC (rev 1581) @@ -1226,6 +1226,7 @@ FILE *fp; if(!conf_main_file) { + DPRINTF(E_DBG,L_CONF,"Config file apparently not loaded\n"); return CONF_E_NOCONF; } @@ -1233,10 +1234,13 @@ if((fp = fopen(conf_main_file,"w+")) != NULL) { retval = _conf_write(fp,conf_main,0,NULL); fclose(fp); + } else { + DPRINTF(E_LOG,L_CONF,"Error opening config file for write: %s\n", + strerror(errno)); } util_mutex_unlock(l_conf); - return retval ? CONF_E_SUCCESS : CONF_E_NOTWRITABLE; + return retval; } /** @@ -1299,8 +1303,10 @@ } fprintf(fp,"\n"); - if(!_conf_write(fp, pli->value.as_ll, 1, pli->key)) - return FALSE; + if(!_conf_write(fp, pli->value.as_ll, 1, pli->key)) { + DPRINTF(E_DBG,L_CONF,"Error writing key %s:%s\n",pli->key); + return FALSE; + } } break; Modified: trunk/src/configfile.c =================================================================== --- trunk/src/configfile.c 2007-05-04 04:59:06 UTC (rev 1580) +++ trunk/src/configfile.c 2007-05-04 21:31:05 UTC (rev 1581) @@ -531,7 +531,7 @@ } void config_emit_upnp(WS_CONNINFO *pwsc, void *value, char *arg) { - ws_writefd(pwsc,"%s",UPNP_UUID); + ws_writefd(pwsc,"%s",upnp_uuid()); } Modified: trunk/src/main.c =================================================================== --- trunk/src/main.c 2007-05-04 04:59:06 UTC (rev 1580) +++ trunk/src/main.c 2007-05-04 21:31:05 UTC (rev 1581) @@ -589,10 +589,6 @@ config.reload = 1; /* force a reload on start */ while(!config.stop) { -#ifdef UPNP - upnp_tick(); /* run the upnp loop */ -#endif - if((conf_get_int("general","rescan_interval",0) && (rescan_counter > conf_get_int("general","rescan_interval",0)))) { if((conf_get_int("general","always_scan",0)) || Modified: trunk/src/upnp.c =================================================================== --- trunk/src/upnp.c 2007-05-04 04:59:06 UTC (rev 1580) +++ trunk/src/upnp.c 2007-05-04 21:31:05 UTC (rev 1581) @@ -40,6 +40,7 @@ #include "upnp.h" #define UPNP_MAX_PACKET 1500 +#define UPNP_CACHE_DURATION 1800 #define UPNP_ADDR "239.255.255.250" #define UPNP_PORT 1900 @@ -47,8 +48,10 @@ #define UPNP_TYPE_BYEBYE 2 #define UPNP_TYPE_RESPONSE 3 -#define UPNP_SELECT_TIMEOUT 1 /* update loop for discover replies */ +#define UPNP_UUID "12345678-1234-1234-1234-123456789013" +#define UPNP_SELECT_TIMEOUT 1 + typedef struct upnp_adinfo_t { int type; /** one of the UPNP_AD_ values */ int version; /** numeric version. 0 if unversioned */ @@ -67,16 +70,24 @@ typedef struct upnp_disco_t { int seconds_remaining; char *query; - struct sockaddr to; + struct sockaddr_in to; struct upnp_disco_t *next; } UPNP_DISCO; /* Globals */ UPNP_PACKETINFO upnp_packetlist; OS_SOCKETTYPE upnp_socket; +UPNP_DISCO upnp_disco; + pthread_t upnp_listener_tid; int upnp_quitflag = 0; int upnp_thread_started = 0; +char *upnp_broadcast_types[] = { + "none", + "SSDP Alive", + "SSDP Byebye", + "SSDP Discovery Response" +}; /* Forwards */ int upnp_strcat(char *what, char *where, int bytes_left); @@ -85,8 +96,17 @@ void upnp_broadcast(int type, UPNP_DISCO *pdisco); void *upnp_listener(void *arg); void upnp_process_packet(void); +void upnp_process_queries(void); /** + * return the current upnp uuid + */ +char *upnp_uuid(void) { + return UPNP_UUID; +} + + +/** * add a upnp packet too the root list. */ void upnp_add_packet(char *group_id, int type, char *location, @@ -178,11 +198,11 @@ /* USN & NT */ switch(pi->padinfo->type) { - case UPNP_AD_BARE: - snprintf(buffer,sizeof(buffer),"USN: uuid:%s\r\n",UPNP_UUID); + case UPNP_AD_UUID: + snprintf(buffer,sizeof(buffer),"USN: uuid:%s\r\n",upnp_uuid()); len=upnp_strcat(buffer,packet,len); if(type != UPNP_TYPE_RESPONSE) { /* no NT for responses */ - snprintf(buffer,sizeof(buffer),"NT: uuid:%s\r\n",UPNP_UUID); + snprintf(buffer,sizeof(buffer),"NT: uuid:%s\r\n",upnp_uuid()); len=upnp_strcat(buffer,packet,len); } break; @@ -190,7 +210,7 @@ case UPNP_AD_DEVICE: case UPNP_AD_SERVICE: case UPNP_AD_ROOT: - snprintf(buffer,sizeof(buffer),"USN: uuid:%s::%s:%s",UPNP_UUID, + snprintf(buffer,sizeof(buffer),"USN: uuid:%s::%s:%s",upnp_uuid(), pi->padinfo->namespace, pi->padinfo->name); len=upnp_strcat(buffer,packet,len); if(pi->padinfo->version) { @@ -214,7 +234,9 @@ break; } - len=upnp_strcat("CACHE-CONTROL: max-age=1800\r\n",packet,len); + snprintf(buffer,sizeof(buffer),"CACHE-CONTROL: max-age=%d\r\n", + UPNP_CACHE_DURATION); + len=upnp_strcat(buffer,packet,len); if((pi->padinfo->body) && (type != UPNP_TYPE_RESPONSE)) { snprintf(buffer,sizeof(buffer),"Content-Length: %d\r\n\r\n", @@ -234,42 +256,80 @@ struct sockaddr_in sin; char packet[UPNP_MAX_PACKET]; int pass; + char passes; + int send_packet; + int elements=0; + int recognized=0; + char **argv = NULL; memset(&sin, 0, sizeof(sin)); - sin.sin_family = AF_INET; - sin.sin_port = htons(UPNP_PORT); - sin.sin_addr.s_addr = inet_addr(UPNP_ADDR); + if(type == UPNP_TYPE_RESPONSE) { + memcpy((void*)&sin,(void*)&pdisco->to,sizeof(struct sockaddr_in)); + } else { + sin.sin_addr.s_addr = inet_addr(UPNP_ADDR); + sin.sin_family = AF_INET; + sin.sin_port = htons(UPNP_PORT); + } util_mutex_lock(l_upnp); - DPRINTF(E_DBG,L_MISC,"Sending upnp broadcast of type: %d\n",type); + DPRINTF(E_DBG,L_MISC,"Sending upnp broadcast of type: %d (%s)\n",type, + upnp_broadcast_types[type]); - for(pass=0; pass < 2; pass++) { + passes = 2; + if(type == UPNP_TYPE_RESPONSE) { + passes = 1; + if(strcasecmp(pdisco->query,"ssdp:all")==0) + passes = 3; + + elements = util_split(pdisco->query,":",&argv); + } + + for(pass=0; pass < passes; pass++) { pi=upnp_packetlist.next; while(pi) { - upnp_build_packet(packet, UPNP_MAX_PACKET, type, pi, pdisco); - sendto(upnp_socket,packet,strlen(packet),0, - (struct sockaddr *)&sin, sizeof(sin)); + send_packet = 1; + if(type == UPNP_TYPE_RESPONSE) { + send_packet = 0; + /* if it's a request for rootdevice, only respond + with root device. */ + if(strcasecmp(pdisco->query,"ssdp:all")==0) { + send_packet = 1; + } else if((strcasecmp(pdisco->query,"upnp:rootdevice")==0) && + (pi->padinfo->type == UPNP_AD_ROOT)) { + send_packet = 1; + } + else if((strncasecmp(pdisco->query,"uuid:",5) == 0) && + (!strcasecmp((char*)&pdisco->query[5],upnp_uuid())) && + (pi->padinfo->type == UPNP_AD_UUID)) { + send_packet = 1; + } + } + + if(send_packet) { + usleep(100); + recognized = 1; + upnp_build_packet(packet, UPNP_MAX_PACKET, type, pi, pdisco); + sendto(upnp_socket,packet,strlen(packet),0, + (struct sockaddr *)&sin, sizeof(sin)); + } + pi = pi->next; } } - util_mutex_unlock(l_upnp); -} + if(type == UPNP_TYPE_RESPONSE) { + printf("%s respond to query %s\n", recognized ? "Did" : "Did not", + pdisco->query); + } - -int upnp_tick(void) { - static time_t last_broadcast = 0; - - if((time(NULL) - last_broadcast) > 60) { - upnp_broadcast(UPNP_TYPE_ALIVE,NULL); - last_broadcast = time(NULL); + if(argv) { + util_dispose_split(argv); } - return TRUE; + util_mutex_unlock(l_upnp); } - /** * start UPnP broadcaster. We'll want to send at least a rootdevice * announcement with a location pointer to the admin page @@ -285,7 +345,9 @@ srand((unsigned)time(NULL)); memset(&upnp_packetlist,0,sizeof(upnp_packetlist)); - upnp_add_packet("base,", UPNP_AD_BARE, "/upnp-basic.xml", + memset(&upnp_disco,0,sizeof(upnp_disco)); + + upnp_add_packet("base,", UPNP_AD_UUID, "/upnp-basic.xml", NULL, NULL, 0, NULL); upnp_add_packet("base,", UPNP_AD_DEVICE, "/upnp-basic.xml", "urn:schemas-upnp-org","MediaServer", 1, NULL); @@ -346,10 +408,41 @@ } /** + * walk the query chain and see if there are any queries we need + * to respond to. + */ +void upnp_process_queries(void) { + UPNP_DISCO *plast, *pcurrent; + + plast=&upnp_disco; + pcurrent = upnp_disco.next; + + /* don't need locks here since this ist he same thread as the listening + * thread */ + + while(pcurrent) { + if(pcurrent->seconds_remaining - UPNP_SELECT_TIMEOUT < 1) { + /* do the broadcast, and cull it */ + upnp_broadcast(UPNP_TYPE_RESPONSE,pcurrent); + pcurrent = pcurrent->next; + free(plast->next->query); + free(plast->next); + plast->next = pcurrent; + } else { + pcurrent->seconds_remaining -= UPNP_SELECT_TIMEOUT; + plast = pcurrent; + pcurrent = pcurrent->next; + } + } +} + + +/** * listener thread for upnp query requests */ void *upnp_listener(void *arg) { int result; + static time_t last_broadcast=0; fd_set readset; struct timeval timeout; @@ -379,7 +472,18 @@ upnp_thread_started=0; pthread_exit(NULL); } - upnp_process_packet(); + + if(FD_ISSET(upnp_socket,&readset)) { + upnp_process_packet(); + } + + if((time(NULL) - last_broadcast) > (UPNP_CACHE_DURATION/3)) { + DPRINTF(E_DBG,L_MISC,"Time for alive message!\n"); + upnp_broadcast(UPNP_TYPE_ALIVE,NULL); + last_broadcast = time(NULL); + } + + upnp_process_queries(); } upnp_thread_started=0; @@ -464,19 +568,22 @@ /* do we care? Let's check the query and see if it is interesting */ discovery = 0; - pdisco = (UPNP_DISCO *)malloc(sizeof(UPNP_DISCO)); if(!pdisco) DPRINTF(E_FATAL,L_MISC,"malloc error"); memset(pdisco,0,sizeof(UPNP_DISCO)); if(mx) { - pdisco->seconds_remaining = 2; + pdisco->seconds_remaining = (rand() / (RAND_MAX/mx)) + 1; + DPRINTF(E_DBG,L_MISC,"Responding in %d (of %d) seconds\n", + pdisco->seconds_remaining, mx); } pdisco->query = query; query = NULL; - memcpy((void*)&pdisco->to, (void*)&from, sizeof(struct sockaddr)); + memcpy((void*)&pdisco->to, (void*)&from,sizeof(struct sockaddr_in)); + pdisco->next = upnp_disco.next; + upnp_disco.next = pdisco; } if(query) { @@ -510,6 +617,3 @@ return TRUE; } - - - Modified: trunk/src/upnp.h =================================================================== --- trunk/src/upnp.h 2007-05-04 04:59:06 UTC (rev 1580) +++ trunk/src/upnp.h 2007-05-04 21:31:05 UTC (rev 1581) @@ -31,18 +31,16 @@ #ifndef _UPNP_H_ #define _UPNP_H_ -#define UPNP_UUID "12345678-1234-1234-1234-123456789013" - #define UPNP_AD_DEVICE 1 #define UPNP_AD_SERVICE 2 #define UPNP_AD_ROOT 3 -#define UPNP_AD_BARE 4 +#define UPNP_AD_UUID 4 extern int upnp_init(void); -extern int upnp_tick(void); extern int upnp_deinit(void); extern void upnp_add_packet(char *group_id, int type, char *location, char *namespace, char *name, int version, char *body); +extern char *upnp_uuid(); #endif /* _UPNP_H_ */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |