* Fix TiVo beacon support so that we respond to beacons, and drain the socket in the process.
This commit is contained in:
parent
df2b72ada5
commit
b6d764ea13
18
minidlna.c
18
minidlna.c
@ -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)) )
|
||||
|
133
tivo_beacon.c
133
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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user