* Move SSDP and TiVo beacon notifications to a separate thread.
This commit is contained in:
parent
bce6da53ea
commit
27696edf6f
106
minidlna.c
106
minidlna.c
@ -266,7 +266,7 @@ init(int argc, char * * argv)
|
|||||||
if( parselanaddr(&lan_addr[n_lan_addr], ext_ip_addr) == 0 )
|
if( parselanaddr(&lan_addr[n_lan_addr], ext_ip_addr) == 0 )
|
||||||
n_lan_addr++;
|
n_lan_addr++;
|
||||||
runtime_vars.port = -1;
|
runtime_vars.port = -1;
|
||||||
runtime_vars.notify_interval = 30; /* seconds between SSDP announces */
|
runtime_vars.notify_interval = 895; /* seconds between SSDP announces */
|
||||||
|
|
||||||
/* read options file first since
|
/* read options file first since
|
||||||
* command line arguments have final say */
|
* command line arguments have final say */
|
||||||
@ -597,23 +597,17 @@ main(int argc, char * * argv)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int sudp = -1, shttpl = -1;
|
int sudp = -1, shttpl = -1;
|
||||||
int snotify[MAX_LAN_ADDR];
|
|
||||||
LIST_HEAD(httplisthead, upnphttp) upnphttphead;
|
LIST_HEAD(httplisthead, upnphttp) upnphttphead;
|
||||||
struct upnphttp * e = 0;
|
struct upnphttp * e = 0;
|
||||||
struct upnphttp * next;
|
struct upnphttp * next;
|
||||||
fd_set readset; /* for select() */
|
fd_set readset; /* for select() */
|
||||||
fd_set writeset;
|
fd_set writeset;
|
||||||
struct timeval timeout, timeofday, lasttimeofday = {0, 0}, lastupdatetime = {0, 0};
|
struct timeval timeout;
|
||||||
int max_fd = -1;
|
int max_fd = -1;
|
||||||
int last_changecnt = 0;
|
|
||||||
char * sql;
|
char * sql;
|
||||||
short int new_db = 0;
|
short int new_db = 0;
|
||||||
pthread_t thread[2];
|
pthread_t thread[3];
|
||||||
#ifdef TIVO_SUPPORT
|
struct sockets notify;
|
||||||
unsigned short int loop_cnt = 0;
|
|
||||||
int sbeacon = -1;
|
|
||||||
struct sockaddr_in tivo_bcast;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(init(argc, argv) != 0)
|
if(init(argc, argv) != 0)
|
||||||
return 1;
|
return 1;
|
||||||
@ -702,7 +696,7 @@ main(int argc, char * * argv)
|
|||||||
DPRINTF(E_WARN, L_GENERAL, "HTTP listening on port %d\n", runtime_vars.port);
|
DPRINTF(E_WARN, L_GENERAL, "HTTP listening on port %d\n", runtime_vars.port);
|
||||||
|
|
||||||
/* open socket for sending notifications */
|
/* open socket for sending notifications */
|
||||||
if(OpenAndConfSSDPNotifySockets(snotify) < 0)
|
if(OpenAndConfSSDPNotifySockets(notify.snotify) < 0)
|
||||||
{
|
{
|
||||||
DPRINTF(E_FATAL, L_GENERAL, "Failed to open sockets for sending SSDP notify "
|
DPRINTF(E_FATAL, L_GENERAL, "Failed to open sockets for sending SSDP notify "
|
||||||
"messages. EXITING\n");
|
"messages. EXITING\n");
|
||||||
@ -718,91 +712,27 @@ main(int argc, char * * argv)
|
|||||||
DPRINTF(E_ERROR, L_TIVO, "ERROR: Failed to add sqlite randomize function for TiVo!\n");
|
DPRINTF(E_ERROR, L_TIVO, "ERROR: Failed to add sqlite randomize function for TiVo!\n");
|
||||||
}
|
}
|
||||||
/* open socket for sending Tivo notifications */
|
/* open socket for sending Tivo notifications */
|
||||||
sbeacon = OpenAndConfTivoBeaconSocket();
|
notify.sbeacon = OpenAndConfTivoBeaconSocket();
|
||||||
if(sbeacon < 0)
|
if(notify.sbeacon < 0)
|
||||||
{
|
{
|
||||||
DPRINTF(E_FATAL, L_GENERAL, "Failed to open sockets for sending Tivo beacon notify "
|
DPRINTF(E_FATAL, L_GENERAL, "Failed to open sockets for sending Tivo beacon notify "
|
||||||
"messages. EXITING\n");
|
"messages. EXITING\n");
|
||||||
}
|
}
|
||||||
tivo_bcast.sin_family = AF_INET;
|
memset(¬ify.tivo_bcast.sin_zero, '\0', sizeof(notify.tivo_bcast.sin_zero));
|
||||||
tivo_bcast.sin_addr.s_addr = htonl(getBcastAddress());
|
notify.tivo_bcast.sin_family = AF_INET;
|
||||||
tivo_bcast.sin_port = htons( 2190 );
|
notify.tivo_bcast.sin_addr.s_addr = htonl(getBcastAddress());
|
||||||
|
notify.tivo_bcast.sin_port = htons( 2190 );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SendSSDPGoodbye(snotify, n_lan_addr);
|
SendSSDPGoodbye(notify.snotify, n_lan_addr);
|
||||||
|
|
||||||
|
notify.timeout = &timeout;
|
||||||
|
pthread_create(&thread[2], NULL, start_notify, ¬ify);
|
||||||
|
sleep(1);
|
||||||
/* main loop */
|
/* main loop */
|
||||||
while(!quitting)
|
while(!quitting)
|
||||||
{
|
{
|
||||||
/* Check if we need to send SSDP NOTIFY messages and do it if
|
|
||||||
* needed */
|
|
||||||
/* Also check if we need to increment our SystemUpdateID
|
|
||||||
* at most once every 2 seconds */
|
|
||||||
if(gettimeofday(&timeofday, 0) < 0)
|
|
||||||
{
|
|
||||||
DPRINTF(E_ERROR, L_GENERAL, "gettimeofday(): %s\n", strerror(errno));
|
|
||||||
timeout.tv_sec = runtime_vars.notify_interval;
|
|
||||||
timeout.tv_usec = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* the comparaison is not very precise but who cares ? */
|
|
||||||
if(timeofday.tv_sec >= (lasttimeofday.tv_sec + runtime_vars.notify_interval))
|
|
||||||
{
|
|
||||||
SendSSDPNotifies2(snotify,
|
|
||||||
(unsigned short)runtime_vars.port,
|
|
||||||
(runtime_vars.notify_interval << 1)+10);
|
|
||||||
memcpy(&lasttimeofday, &timeofday, sizeof(struct timeval));
|
|
||||||
timeout.tv_sec = runtime_vars.notify_interval;
|
|
||||||
timeout.tv_usec = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
timeout.tv_sec = lasttimeofday.tv_sec + runtime_vars.notify_interval
|
|
||||||
- timeofday.tv_sec;
|
|
||||||
if(timeofday.tv_usec > lasttimeofday.tv_usec)
|
|
||||||
{
|
|
||||||
timeout.tv_usec = 1000000 + lasttimeofday.tv_usec
|
|
||||||
- timeofday.tv_usec;
|
|
||||||
timeout.tv_sec--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
timeout.tv_usec = lasttimeofday.tv_usec - timeofday.tv_usec;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(timeofday.tv_sec >= (lastupdatetime.tv_sec + 2))
|
|
||||||
{
|
|
||||||
if( sqlite3_total_changes(db) != last_changecnt )
|
|
||||||
{
|
|
||||||
updateID++;
|
|
||||||
last_changecnt = sqlite3_total_changes(db);
|
|
||||||
upnp_event_var_change_notify(EContentDirectory);
|
|
||||||
}
|
|
||||||
#ifdef TIVO_SUPPORT
|
|
||||||
if( GETFLAG(TIVOMASK) )
|
|
||||||
{
|
|
||||||
if( loop_cnt < 10 )
|
|
||||||
{
|
|
||||||
sendBeaconMessage(sbeacon, &tivo_bcast, sizeof(struct sockaddr_in), 1);
|
|
||||||
loop_cnt++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( loop_cnt == 30 )
|
|
||||||
{
|
|
||||||
sendBeaconMessage(sbeacon, &tivo_bcast, sizeof(struct sockaddr_in), 1);
|
|
||||||
loop_cnt = 10;
|
|
||||||
}
|
|
||||||
loop_cnt++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
memcpy(&lastupdatetime, &timeofday, sizeof(struct timeval));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* select open sockets (SSDP, HTTP listen, and all HTTP soap sockets) */
|
/* select open sockets (SSDP, HTTP listen, and all HTTP soap sockets) */
|
||||||
FD_ZERO(&readset);
|
FD_ZERO(&readset);
|
||||||
|
|
||||||
@ -923,15 +853,15 @@ shutdown:
|
|||||||
if (sudp >= 0) close(sudp);
|
if (sudp >= 0) close(sudp);
|
||||||
if (shttpl >= 0) close(shttpl);
|
if (shttpl >= 0) close(shttpl);
|
||||||
#ifdef TIVO_SUPPORT
|
#ifdef TIVO_SUPPORT
|
||||||
if (sbeacon >= 0) close(sbeacon);
|
if (notify.sbeacon >= 0) close(notify.sbeacon);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(SendSSDPGoodbye(snotify, n_lan_addr) < 0)
|
if(SendSSDPGoodbye(notify.snotify, n_lan_addr) < 0)
|
||||||
{
|
{
|
||||||
DPRINTF(E_ERROR, L_GENERAL, "Failed to broadcast good-bye notifications\n");
|
DPRINTF(E_ERROR, L_GENERAL, "Failed to broadcast good-bye notifications\n");
|
||||||
}
|
}
|
||||||
for(i=0; i<n_lan_addr; i++)
|
for(i=0; i<n_lan_addr; i++)
|
||||||
close(snotify[i]);
|
close(notify.snotify[i]);
|
||||||
|
|
||||||
asprintf(&sql, "UPDATE SETTINGS set UPDATE_ID = %u", updateID);
|
asprintf(&sql, "UPDATE SETTINGS set UPDATE_ID = %u", updateID);
|
||||||
sql_exec(db, sql);
|
sql_exec(db, sql);
|
||||||
|
91
minissdp.c
91
minissdp.c
@ -12,6 +12,7 @@
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#include <sys/time.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@ -19,6 +20,8 @@
|
|||||||
#include "minidlnapath.h"
|
#include "minidlnapath.h"
|
||||||
#include "upnphttp.h"
|
#include "upnphttp.h"
|
||||||
#include "upnpglobalvars.h"
|
#include "upnpglobalvars.h"
|
||||||
|
#include "upnpevents.h"
|
||||||
|
#include "tivo_beacon.h"
|
||||||
#include "minissdp.h"
|
#include "minissdp.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
@ -211,7 +214,7 @@ SendSSDPAnnounce2(int s, struct sockaddr_in sockname, int st_no,
|
|||||||
* follow guideline from document "UPnP Device Architecture 1.0"
|
* follow guideline from document "UPnP Device Architecture 1.0"
|
||||||
* put in uppercase.
|
* put in uppercase.
|
||||||
* DATE: is recommended
|
* DATE: is recommended
|
||||||
* SERVER: OS/ver UPnP/1.0 miniupnpd/1.0
|
* SERVER: OS/ver UPnP/1.0 minidlna/1.0
|
||||||
* - check what to put in the 'Cache-Control' header
|
* - check what to put in the 'Cache-Control' header
|
||||||
* */
|
* */
|
||||||
char szTime[30];
|
char szTime[30];
|
||||||
@ -219,7 +222,7 @@ SendSSDPAnnounce2(int s, struct sockaddr_in sockname, int st_no,
|
|||||||
strftime(szTime, 30,"%a, %d %b %Y %H:%M:%S GMT" , gmtime(&tTime));
|
strftime(szTime, 30,"%a, %d %b %Y %H:%M:%S GMT" , gmtime(&tTime));
|
||||||
|
|
||||||
l = snprintf(buf, sizeof(buf), "HTTP/1.1 200 OK\r\n"
|
l = snprintf(buf, sizeof(buf), "HTTP/1.1 200 OK\r\n"
|
||||||
"CACHE-CONTROL: max-age=1810\r\n"
|
"CACHE-CONTROL: max-age=%u\r\n"
|
||||||
"DATE: %s\r\n"
|
"DATE: %s\r\n"
|
||||||
"ST: %s%s\r\n"
|
"ST: %s%s\r\n"
|
||||||
"USN: %s%s%s%s\r\n"
|
"USN: %s%s%s%s\r\n"
|
||||||
@ -228,6 +231,7 @@ SendSSDPAnnounce2(int s, struct sockaddr_in sockname, int st_no,
|
|||||||
"LOCATION: http://%s:%u" ROOTDESC_PATH "\r\n"
|
"LOCATION: http://%s:%u" ROOTDESC_PATH "\r\n"
|
||||||
"Content-Length: 0\r\n"
|
"Content-Length: 0\r\n"
|
||||||
"\r\n",
|
"\r\n",
|
||||||
|
(runtime_vars.notify_interval<<1)+10,
|
||||||
szTime,
|
szTime,
|
||||||
known_service_types[st_no], (st_no>1?"1":""),
|
known_service_types[st_no], (st_no>1?"1":""),
|
||||||
uuidvalue, (st_no>0?"::":""), (st_no>0?known_service_types[st_no]:""), (st_no>1?"1":""),
|
uuidvalue, (st_no>0?"::":""), (st_no>0?known_service_types[st_no]:""), (st_no>1?"1":""),
|
||||||
@ -495,3 +499,86 @@ SendSSDPGoodbye(int * sockets, int n_sockets)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
start_notify(void * arg)
|
||||||
|
{
|
||||||
|
struct sockets *s = (struct sockets *)arg;
|
||||||
|
struct timeval timeofday, lasttimeofday = {0, 0}, lastupdatetime = {0, 0};
|
||||||
|
int last_changecnt = 0;
|
||||||
|
#ifdef TIVO_SUPPORT
|
||||||
|
short int loop_cnt = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
/* Check if we need to send SSDP NOTIFY messages and do it if needed */
|
||||||
|
/* Also check if we need to increment our SystemUpdateID
|
||||||
|
* at most once every 2 seconds */
|
||||||
|
if(gettimeofday(&timeofday, 0) < 0)
|
||||||
|
{
|
||||||
|
DPRINTF(E_ERROR, L_GENERAL, "gettimeofday(): %s\n", strerror(errno));
|
||||||
|
s->timeout->tv_sec = runtime_vars.notify_interval;
|
||||||
|
s->timeout->tv_usec = 0;
|
||||||
|
sleep(2);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* the comparaison is not very precise but who cares ? */
|
||||||
|
if(timeofday.tv_sec >= (lasttimeofday.tv_sec + runtime_vars.notify_interval))
|
||||||
|
{
|
||||||
|
SendSSDPNotifies2(s->snotify,
|
||||||
|
runtime_vars.port,
|
||||||
|
(runtime_vars.notify_interval << 1)+10);
|
||||||
|
memcpy(&lasttimeofday, &timeofday, sizeof(struct timeval));
|
||||||
|
s->timeout->tv_sec = runtime_vars.notify_interval;
|
||||||
|
s->timeout->tv_usec = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s->timeout->tv_sec = lasttimeofday.tv_sec + runtime_vars.notify_interval
|
||||||
|
- timeofday.tv_sec;
|
||||||
|
if(timeofday.tv_usec > lasttimeofday.tv_usec)
|
||||||
|
{
|
||||||
|
s->timeout->tv_usec = 1000000 + lasttimeofday.tv_usec
|
||||||
|
- timeofday.tv_usec;
|
||||||
|
s->timeout->tv_sec--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s->timeout->tv_usec = lasttimeofday.tv_usec - timeofday.tv_usec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(timeofday.tv_sec >= (lastupdatetime.tv_sec + 2))
|
||||||
|
{
|
||||||
|
if( sqlite3_total_changes(db) != last_changecnt )
|
||||||
|
{
|
||||||
|
updateID++;
|
||||||
|
last_changecnt = sqlite3_total_changes(db);
|
||||||
|
upnp_event_var_change_notify(EContentDirectory);
|
||||||
|
}
|
||||||
|
#ifdef TIVO_SUPPORT
|
||||||
|
if( GETFLAG(TIVOMASK) )
|
||||||
|
{
|
||||||
|
if( loop_cnt < 20 )
|
||||||
|
{
|
||||||
|
if(loop_cnt % 3 == 0)
|
||||||
|
sendBeaconMessage(s->sbeacon, &(s->tivo_bcast), sizeof(struct sockaddr_in), 1);
|
||||||
|
loop_cnt++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( loop_cnt == 50 )
|
||||||
|
{
|
||||||
|
sendBeaconMessage(s->sbeacon, &(s->tivo_bcast), sizeof(struct sockaddr_in), 1);
|
||||||
|
loop_cnt = 20;
|
||||||
|
}
|
||||||
|
loop_cnt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
memcpy(&lastupdatetime, &timeofday, sizeof(struct timeval));
|
||||||
|
}
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
13
minissdp.h
13
minissdp.h
@ -8,6 +8,16 @@
|
|||||||
|
|
||||||
/*#include "minidlnatypes.h"*/
|
/*#include "minidlnatypes.h"*/
|
||||||
|
|
||||||
|
struct sockets
|
||||||
|
{
|
||||||
|
int snotify[MAX_LAN_ADDR];
|
||||||
|
#ifdef TIVO_SUPPORT
|
||||||
|
int sbeacon;
|
||||||
|
struct sockaddr_in tivo_bcast;
|
||||||
|
#endif
|
||||||
|
struct timeval *timeout;
|
||||||
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
OpenAndConfSSDPReceiveSocket();
|
OpenAndConfSSDPReceiveSocket();
|
||||||
/* OpenAndConfSSDPReceiveSocket(int n_lan_addr, struct lan_addr_s * lan_addr);*/
|
/* OpenAndConfSSDPReceiveSocket(int n_lan_addr, struct lan_addr_s * lan_addr);*/
|
||||||
@ -39,5 +49,8 @@ ProcessSSDPRequest(int s, unsigned short port);
|
|||||||
int
|
int
|
||||||
SendSSDPGoodbye(int * sockets, int n);
|
SendSSDPGoodbye(int * sockets, int n);
|
||||||
|
|
||||||
|
void *
|
||||||
|
start_notify(void * arg);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user