Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/azatoth/minidlna.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Maggard <jmaggard@users.sourceforge.net>2011-02-17 11:54:02 +0300
committerJustin Maggard <jmaggard@users.sourceforge.net>2011-02-17 11:54:02 +0300
commit7bb86c947fca709ccd271746918444032b7d39e0 (patch)
tree68f2a0d1ec4b0fbc331413b39b543e879f3dd707
parent65e53a04506676451529d469cb9f00fdf7c95dcf (diff)
* Fix TiVo beacon support so that we respond to beacons, and drain the socket in the process.
-rw-r--r--minidlna.c18
-rw-r--r--tivo_beacon.c133
-rw-r--r--tivo_beacon.h17
3 files changed, 90 insertions, 78 deletions
diff --git a/minidlna.c b/minidlna.c
index c1b6fa2..19f0ca5 100644
--- a/minidlna.c
+++ b/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)) )
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