diff options
author | Justin Maggard <jmaggard@users.sourceforge.net> | 2011-02-17 11:54:02 +0300 |
---|---|---|
committer | Justin Maggard <jmaggard@users.sourceforge.net> | 2011-02-17 11:54:02 +0300 |
commit | 7bb86c947fca709ccd271746918444032b7d39e0 (patch) | |
tree | 68f2a0d1ec4b0fbc331413b39b543e879f3dd707 | |
parent | 65e53a04506676451529d469cb9f00fdf7c95dcf (diff) |
* Fix TiVo beacon support so that we respond to beacons, and drain the socket in the process.
-rw-r--r-- | minidlna.c | 18 | ||||
-rw-r--r-- | tivo_beacon.c | 133 | ||||
-rw-r--r-- | tivo_beacon.h | 17 |
3 files changed, 90 insertions, 78 deletions
@@ -983,7 +983,13 @@ main(int argc, char * * argv) FD_SET(shttpl, &readset); max_fd = MAX( max_fd, shttpl); } - +#ifdef TIVO_SUPPORT + if (sbeacon >= 0) + { + FD_SET(sbeacon, &readset); + max_fd = MAX(max_fd, sbeacon); + } +#endif i = 0; /* active HTTP connections count */ for(e = upnphttphead.lh_first; e != NULL; e = e->entries.le_next) { @@ -994,14 +1000,13 @@ main(int argc, char * * argv) i++; } } - /* for debug */ #ifdef DEBUG + /* for debug */ if(i > 1) { DPRINTF(E_DEBUG, L_GENERAL, "%d active incoming HTTP connections\n", i); } #endif - FD_ZERO(&writeset); upnpevents_selectfds(&readset, &writeset, &max_fd); @@ -1018,6 +1023,13 @@ main(int argc, char * * argv) /*DPRINTF(E_DEBUG, L_GENERAL, "Received UDP Packet\n");*/ ProcessSSDPRequest(sudp, (unsigned short)runtime_vars.port); } +#ifdef TIVO_SUPPORT + if(sbeacon >= 0 && FD_ISSET(sbeacon, &readset)) + { + /*DPRINTF(E_DEBUG, L_GENERAL, "Received UDP Packet\n");*/ + ProcessTiVoBeacon(sbeacon); + } +#endif /* increment SystemUpdateID if the content database has changed, * and if there is an active HTTP connection, at most once every 2 seconds */ if( i && (time(NULL) >= (lastupdatetime.tv_sec + 2)) ) diff --git a/tivo_beacon.c b/tivo_beacon.c index 6c5273e..2ed2bf9 100644 --- a/tivo_beacon.c +++ b/tivo_beacon.c @@ -153,7 +153,7 @@ sendBeaconMessage(int fd, struct sockaddr_in * client, int len, int broadcast) "1.0", broadcast ? "broadcast" : "connected", uuidvalue, friendly_name, runtime_vars.port); - DPRINTF(E_DEBUG, L_TIVO, "Sending TiVo beacon\n"); + DPRINTF(E_DEBUG, L_TIVO, "Sending TiVo beacon to %s\n", inet_ntoa(client->sin_addr)); sendto(fd, mesg, mesg_len, 0, (struct sockaddr*)client, len); free(mesg); } @@ -168,7 +168,6 @@ int rcvBeaconMessage(char * beacon) { char * tivoConnect = NULL; - char * swVersion = NULL; char * method = NULL; char * identity = NULL; char * machine = NULL; @@ -178,118 +177,118 @@ rcvBeaconMessage(char * beacon) char * scp; char * tokptr; struct aBeacon * b; - int len; time_t current; - char buf[32]; - static time_t lastSummary = 0; - cp = strtok_r( beacon, "=\r\n", &tokptr ); + cp = strtok_r(beacon, "=\r\n", &tokptr); while( cp != NULL ) { scp = cp; cp = strtok_r( NULL, "=\r\n", &tokptr ); - if( strcasecmp( scp, "tivoconnect" ) == 0 ) + if( strcasecmp(scp, "tivoconnect") == 0 ) tivoConnect = cp; - else if( strcasecmp( scp, "swversion" ) == 0 ) - swVersion = cp; - else if( strcasecmp( scp, "method" ) == 0 ) + else if( strcasecmp(scp, "method") == 0 ) method = cp; - else if( strcasecmp( scp, "identity" ) == 0 ) + else if( strcasecmp(scp, "identity") == 0 ) identity = cp; - else if( strcasecmp( scp, "machine" ) == 0 ) + else if( strcasecmp(scp, "machine") == 0 ) machine = cp; - else if( strcasecmp( scp, "platform" ) == 0 ) + else if( strcasecmp(scp, "platform") == 0 ) platform = cp; - else if( strcasecmp( scp, "services" ) == 0 ) + else if( strcasecmp(scp, "services") == 0 ) services = cp; - cp = strtok_r( NULL, "=\r\n", &tokptr ); + cp = strtok_r(NULL, "=\r\n", &tokptr); } if( tivoConnect == NULL ) return 0; - current = time( NULL ); + /* It's pointless to respond to our own beacon */ + if( strcmp(identity, uuidvalue) == 0) + return 0; + + current = time(NULL); for( b = topBeacon; b != NULL; b = b->next ) { - if( strcasecmp( machine, b->machine ) == 0 || - strcasecmp( identity, b->identity ) == 0 ) - { + if( strcasecmp(machine, b->machine) == 0 || + strcasecmp(identity, b->identity) == 0 ) break; - } } if( b == NULL ) { - b = ( struct aBeacon* ) calloc( 1, sizeof( *b ) ); - b->next = NULL; + b = calloc(1, sizeof(*b)); - if ( machine ) - { - b->machine = ( char* ) malloc( strlen( machine ) + 1 ); - strcpy( b->machine, machine ); - } - if ( identity ) - { - b->identity = ( char* ) malloc( strlen( identity ) + 1 ); - strcpy( b->identity, identity ); - } - if ( swVersion ) - { - b->swversion = ( char* ) malloc( strlen( swVersion ) + 1 ); - strcpy( b->swversion, swVersion ); - } - if ( method ) - { - b->method = ( char* ) malloc( strlen( method ) + 1 ); - strcpy( b->method, method ); - } - if ( platform ) - { - b->platform = ( char* ) malloc( strlen( platform ) + 1 ); - strcpy( b->platform, platform ); - } - if ( services ) - { - b->services = ( char* ) malloc( strlen( services ) + 1 ); - strcpy( b->services, services ); - } + if( machine ) + b->machine = strdup(machine); + if( identity ) + b->identity = strdup(identity); b->next = topBeacon; topBeacon = b; - printf( "Received new beacon: machine(%s) platform(%s) services(%s)\n", - b->machine ? b->machine : "-", - b->platform ? b->platform : "-", - b->services ? b->services : "-" ); + DPRINTF(E_DEBUG, L_TIVO, "Received new beacon: machine(%s) platform(%s) services(%s)\n", + machine ? machine : "-", + platform ? platform : "-", + services ? services : "-" ); } - b->lastSeen = current; +#ifdef DEBUG + int len; + char buf[32]; + static time_t lastSummary = 0; - if( lastSummary == 0 ) + b->lastSeen = current; + if( !lastSummary ) lastSummary = current; + if( lastSummary + 1800 < current ) { /* Give a summary of received server beacons every half hour or so */ len = 0; for( b = topBeacon; b != NULL; b = b->next ) { - len += strlen( b->machine ) + 32; + len += strlen(b->machine) + 32; } - scp = ( char* ) malloc( len + 128 ); + scp = malloc(len + 128); strcpy( scp, "Known servers: " ); for( b = topBeacon; b != NULL; b = b->next ) { - strcat( scp, b->machine ); - sprintf( buf, "(%ld)", current - b->lastSeen ); - strcat( scp, buf ); + strcat(scp, b->machine); + sprintf(buf, "(%ld)", current - b->lastSeen); + strcat(scp, buf); if( b->next != NULL ) - strcat( scp, "," ); + strcat(scp, ","); } strcat(scp, "\n"); - printf("%s\n", scp); + DPRINTF(E_DEBUG, L_TIVO, "%s\n", scp); free(scp); lastSummary = current; } - - if( strcasecmp( method, "broadcast" ) == 0 ) +#endif + if( strcasecmp(method, "broadcast") == 0 ) return 1; return 0; } + +void ProcessTiVoBeacon(int s) +{ + int n; + char *cp; + struct sockaddr_in sendername; + socklen_t len_r; + char bufr[1500]; + len_r = sizeof(struct sockaddr_in); + + /* We only expect to see beacon msgs from TiVo's and possibly other tivo servers */ + n = recvfrom(s, bufr, sizeof(bufr), 0, + (struct sockaddr *)&sendername, &len_r); + if( n > 0 ) + bufr[n] = '\0'; + for( cp = bufr; *cp; cp++ ) + /* do nothing */; + if( cp[-1] == '\r' || cp[-1] == '\n' ) + *--cp = '\0'; + if( cp[-1] == '\r' || cp[-1] == '\n' ) + *--cp = '\0'; + + if( rcvBeaconMessage(bufr) ) + sendBeaconMessage(s, &sendername, len_r, 0); +} #endif // TIVO_SUPPORT diff --git a/tivo_beacon.h b/tivo_beacon.h index 3c2c95e..738042c 100644 --- a/tivo_beacon.h +++ b/tivo_beacon.h @@ -28,14 +28,12 @@ * */ struct aBeacon { - time_t lastSeen; - char* machine; - char* identity; - char* platform; - char* swversion; - char* method; - char* services; - struct aBeacon* next; +#ifdef DEBUG + time_t lastSeen; +#endif + char * machine; + char * identity; + struct aBeacon *next; }; uint32_t @@ -46,4 +44,7 @@ OpenAndConfTivoBeaconSocket(); void sendBeaconMessage(int fd, struct sockaddr_in * client, int len, int broadcast); + +void +ProcessTiVoBeacon(int fd); #endif |