* 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);
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)) )

View File

@ -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

View File

@ -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