* Fix TiVo beacon support so that we respond to beacons, and drain the socket in the process.

This commit is contained in:
Justin Maggard 2011-02-17 08:54:02 +00:00
parent df2b72ada5
commit b6d764ea13
3 changed files with 90 additions and 78 deletions

View File

@ -983,7 +983,13 @@ main(int argc, char * * argv)
FD_SET(shttpl, &readset); FD_SET(shttpl, &readset);
max_fd = MAX( max_fd, shttpl); 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 */ i = 0; /* active HTTP connections count */
for(e = upnphttphead.lh_first; e != NULL; e = e->entries.le_next) for(e = upnphttphead.lh_first; e != NULL; e = e->entries.le_next)
{ {
@ -994,14 +1000,13 @@ main(int argc, char * * argv)
i++; i++;
} }
} }
/* for debug */
#ifdef DEBUG #ifdef DEBUG
/* for debug */
if(i > 1) if(i > 1)
{ {
DPRINTF(E_DEBUG, L_GENERAL, "%d active incoming HTTP connections\n", i); DPRINTF(E_DEBUG, L_GENERAL, "%d active incoming HTTP connections\n", i);
} }
#endif #endif
FD_ZERO(&writeset); FD_ZERO(&writeset);
upnpevents_selectfds(&readset, &writeset, &max_fd); upnpevents_selectfds(&readset, &writeset, &max_fd);
@ -1018,6 +1023,13 @@ main(int argc, char * * argv)
/*DPRINTF(E_DEBUG, L_GENERAL, "Received UDP Packet\n");*/ /*DPRINTF(E_DEBUG, L_GENERAL, "Received UDP Packet\n");*/
ProcessSSDPRequest(sudp, (unsigned short)runtime_vars.port); 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, /* increment SystemUpdateID if the content database has changed,
* and if there is an active HTTP connection, at most once every 2 seconds */ * and if there is an active HTTP connection, at most once every 2 seconds */
if( i && (time(NULL) >= (lastupdatetime.tv_sec + 2)) ) if( i && (time(NULL) >= (lastupdatetime.tv_sec + 2)) )

View File

@ -153,7 +153,7 @@ sendBeaconMessage(int fd, struct sockaddr_in * client, int len, int broadcast)
"1.0", "1.0",
broadcast ? "broadcast" : "connected", broadcast ? "broadcast" : "connected",
uuidvalue, friendly_name, runtime_vars.port); 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); sendto(fd, mesg, mesg_len, 0, (struct sockaddr*)client, len);
free(mesg); free(mesg);
} }
@ -168,7 +168,6 @@ int
rcvBeaconMessage(char * beacon) rcvBeaconMessage(char * beacon)
{ {
char * tivoConnect = NULL; char * tivoConnect = NULL;
char * swVersion = NULL;
char * method = NULL; char * method = NULL;
char * identity = NULL; char * identity = NULL;
char * machine = NULL; char * machine = NULL;
@ -178,118 +177,118 @@ rcvBeaconMessage(char * beacon)
char * scp; char * scp;
char * tokptr; char * tokptr;
struct aBeacon * b; struct aBeacon * b;
int len;
time_t current; 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 ) while( cp != NULL )
{ {
scp = cp; scp = cp;
cp = strtok_r( NULL, "=\r\n", &tokptr ); cp = strtok_r( NULL, "=\r\n", &tokptr );
if( strcasecmp( scp, "tivoconnect" ) == 0 ) if( strcasecmp(scp, "tivoconnect") == 0 )
tivoConnect = cp; tivoConnect = cp;
else if( strcasecmp( scp, "swversion" ) == 0 ) else if( strcasecmp(scp, "method") == 0 )
swVersion = cp;
else if( strcasecmp( scp, "method" ) == 0 )
method = cp; method = cp;
else if( strcasecmp( scp, "identity" ) == 0 ) else if( strcasecmp(scp, "identity") == 0 )
identity = cp; identity = cp;
else if( strcasecmp( scp, "machine" ) == 0 ) else if( strcasecmp(scp, "machine") == 0 )
machine = cp; machine = cp;
else if( strcasecmp( scp, "platform" ) == 0 ) else if( strcasecmp(scp, "platform") == 0 )
platform = cp; platform = cp;
else if( strcasecmp( scp, "services" ) == 0 ) else if( strcasecmp(scp, "services") == 0 )
services = cp; services = cp;
cp = strtok_r( NULL, "=\r\n", &tokptr ); cp = strtok_r(NULL, "=\r\n", &tokptr);
} }
if( tivoConnect == NULL ) if( tivoConnect == NULL )
return 0; 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 ) for( b = topBeacon; b != NULL; b = b->next )
{ {
if( strcasecmp( machine, b->machine ) == 0 || if( strcasecmp(machine, b->machine) == 0 ||
strcasecmp( identity, b->identity ) == 0 ) strcasecmp(identity, b->identity) == 0 )
{
break; break;
}
} }
if( b == NULL ) if( b == NULL )
{ {
b = ( struct aBeacon* ) calloc( 1, sizeof( *b ) ); b = calloc(1, sizeof(*b));
b->next = NULL;
if ( machine ) if( machine )
{ b->machine = strdup(machine);
b->machine = ( char* ) malloc( strlen( machine ) + 1 ); if( identity )
strcpy( b->machine, machine ); b->identity = strdup(identity);
}
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 );
}
b->next = topBeacon; b->next = topBeacon;
topBeacon = b; topBeacon = b;
printf( "Received new beacon: machine(%s) platform(%s) services(%s)\n", DPRINTF(E_DEBUG, L_TIVO, "Received new beacon: machine(%s) platform(%s) services(%s)\n",
b->machine ? b->machine : "-", machine ? machine : "-",
b->platform ? b->platform : "-", platform ? platform : "-",
b->services ? b->services : "-" ); 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; lastSummary = current;
if( lastSummary + 1800 < current ) if( lastSummary + 1800 < current )
{ /* Give a summary of received server beacons every half hour or so */ { /* Give a summary of received server beacons every half hour or so */
len = 0; len = 0;
for( b = topBeacon; b != NULL; b = b->next ) 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: " ); strcpy( scp, "Known servers: " );
for( b = topBeacon; b != NULL; b = b->next ) for( b = topBeacon; b != NULL; b = b->next )
{ {
strcat( scp, b->machine ); strcat(scp, b->machine);
sprintf( buf, "(%ld)", current - b->lastSeen ); sprintf(buf, "(%ld)", current - b->lastSeen);
strcat( scp, buf ); strcat(scp, buf);
if( b->next != NULL ) if( b->next != NULL )
strcat( scp, "," ); strcat(scp, ",");
} }
strcat(scp, "\n"); strcat(scp, "\n");
printf("%s\n", scp); DPRINTF(E_DEBUG, L_TIVO, "%s\n", scp);
free(scp); free(scp);
lastSummary = current; lastSummary = current;
} }
#endif
if( strcasecmp( method, "broadcast" ) == 0 ) if( strcasecmp(method, "broadcast") == 0 )
return 1; return 1;
return 0; 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 #endif // TIVO_SUPPORT

View File

@ -28,14 +28,12 @@
* */ * */
struct aBeacon struct aBeacon
{ {
time_t lastSeen; #ifdef DEBUG
char* machine; time_t lastSeen;
char* identity; #endif
char* platform; char * machine;
char* swversion; char * identity;
char* method; struct aBeacon *next;
char* services;
struct aBeacon* next;
}; };
uint32_t uint32_t
@ -46,4 +44,7 @@ OpenAndConfTivoBeaconSocket();
void void
sendBeaconMessage(int fd, struct sockaddr_in * client, int len, int broadcast); sendBeaconMessage(int fd, struct sockaddr_in * client, int len, int broadcast);
void
ProcessTiVoBeacon(int fd);
#endif #endif