* 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);
|
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)) )
|
||||||
|
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",
|
"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
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user