From 2b37a0610e32fddf50a532e25935e9aede25210d Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Wed, 23 Apr 2014 20:55:28 +0200 Subject: [PATCH] SAT>IP: Add --satip_xml option to reach tuners behind routers or local blocked UPnP ports --- src/input/mpegts.c | 5 +- src/input/mpegts.h | 3 +- src/input/mpegts/satip/satip.c | 85 +++++++++++++++++++++++++++++----- src/input/mpegts/satip/satip.h | 2 +- src/main.c | 8 +++- 5 files changed, 87 insertions(+), 16 deletions(-) diff --git a/src/input/mpegts.c b/src/input/mpegts.c index 51117107..87d341a4 100644 --- a/src/input/mpegts.c +++ b/src/input/mpegts.c @@ -19,7 +19,8 @@ #include "input.h" void -mpegts_init ( int linuxdvb_mask, str_list_t *tsfiles, int tstuners ) +mpegts_init ( int linuxdvb_mask, str_list_t *satip_client, + str_list_t *tsfiles, int tstuners ) { /* Register classes (avoid API 400 errors due to not yet defined) */ idclass_register(&mpegts_network_class); @@ -53,7 +54,7 @@ mpegts_init ( int linuxdvb_mask, str_list_t *tsfiles, int tstuners ) /* SAT>IP DVB client */ #if ENABLE_SATIP_CLIENT - satip_init(); + satip_init(satip_client); #endif /* Mux schedulers */ diff --git a/src/input/mpegts.h b/src/input/mpegts.h index 85493faa..ffc0fe1c 100644 --- a/src/input/mpegts.h +++ b/src/input/mpegts.h @@ -68,7 +68,8 @@ extern const idclass_t mpegts_input_class; * Setup / Tear down * *************************************************************************/ -void mpegts_init ( int linuxdvb_mask, str_list_t *tsfiles, int tstuners ); +void mpegts_init ( int linuxdvb_mask, str_list_t *satip_client, + str_list_t *tsfiles, int tstuners ); void mpegts_done ( void ); /* ************************************************************************** diff --git a/src/input/mpegts/satip/satip.c b/src/input/mpegts/satip/satip.c index 9a238543..313ed747 100644 --- a/src/input/mpegts/satip/satip.c +++ b/src/input/mpegts/satip/satip.c @@ -390,6 +390,19 @@ satip_device_find( const char *satip_uuid ) return NULL; } +static satip_device_t * +satip_device_find_by_descurl( const char *descurl ) +{ + tvh_hardware_t *th; + + TVH_HARDWARE_FOREACH(th) { + if (idnode_is_instance(&th->th_id, &satip_device_class) && + strcmp(((satip_device_t *)th)->sd_info.location, descurl) == 0) + return (satip_device_t *)th; + } + return NULL; +} + void satip_device_save( satip_device_t *sd ) { @@ -483,6 +496,7 @@ static struct satip_discovery_queue satip_discoveries; static upnp_service_t *satip_discovery_service; static gtimer_t satip_discovery_timer; static gtimer_t satip_discovery_timerq; +static str_list_t *satip_static_clients; static void satip_discovery_destroy(satip_discovery_t *d, int unlink) @@ -525,10 +539,12 @@ satip_discovery_http_closed(http_client_t *hc, int errn) htsmsg_t *xml = NULL, *tags, *root, *device; const char *friendlyname, *manufacturer, *manufacturerURL, *modeldesc; const char *modelname, *modelnum, *serialnum; - const char *presentation, *tunercfg; + const char *presentation, *tunercfg, *udn, *uuid; const char *cs; satip_device_info_t info; char errbuf[100]; + char *argv[10]; + int i, n; s = http_arg_get(&hc->hc_args, "Content-Type"); if (s && strcasecmp(s, "text/xml")) { @@ -590,11 +606,24 @@ satip_discovery_http_closed(http_client_t *hc, int errn) goto finish; if ((presentation = htsmsg_xml_get_cdata_str(device, "presentationURL")) == NULL) goto finish; + if ((udn = htsmsg_xml_get_cdata_str(device, "UDN")) == NULL) + goto finish; if ((tunercfg = htsmsg_xml_get_cdata_str(device, "urn:ses-com:satipX_SATIPCAP")) == NULL) goto finish; + + uuid = NULL; + n = http_tokenize((char *)udn, argv, ARRAY_SIZE(argv), ':'); + for (i = 0; i < n+1; i++) + if (argv[i] && strcmp(argv[i], "uuid") == 0) { + uuid = argv[++i]; + break; + } + if (uuid == NULL || (d->uuid[0] && strcmp(uuid, d->uuid))) + goto finish; + info.myaddr = strdup(d->myaddr); info.addr = strdup(d->url.host); - info.uuid = strdup(d->uuid); + info.uuid = strdup(uuid); info.bootid = strdup(d->bootid); info.configid = strdup(d->configid); info.deviceid = strdup(d->deviceid); @@ -732,7 +761,7 @@ satip_discovery_service_received else if (strcmp(argv[0], "DEVICEID.SES.COM:") == 0) deviceid = argv[1]; else if (strcmp(argv[0], "USN:") == 0) { - n = http_tokenize(argv[1], argv, 10, ':'); + n = http_tokenize(argv[1], argv, ARRAY_SIZE(argv), ':'); for (i = 0; i < n+1; i++) if (argv[i] && strcmp(argv[i], "uuid") == 0) { uuid = argv[++i]; @@ -785,6 +814,32 @@ satip_discovery_service_received satip_discovery_destroy(d, 0); } +static void +satip_discovery_static(const char *descurl) +{ + satip_discovery_t *d; + + lock_assert(&global_lock); + + if (satip_device_find_by_descurl(descurl)) + return; + d = calloc(1, sizeof(satip_discovery_t)); + if (urlparse(descurl, &d->url)) { + satip_discovery_destroy(d, 0); + return; + } + d->myaddr = strdup(d->url.host); + d->location = strdup(descurl); + d->server = strdup(""); + d->uuid = strdup(""); + d->bootid = strdup(""); + d->configid = strdup(""); + d->deviceid = strdup(""); + TAILQ_INSERT_TAIL(&satip_discoveries, d, disc_link); + satip_discoveries_count++; + satip_discovery_timerq_cb(NULL); +} + static void satip_discovery_service_destroy(upnp_service_t *us) { @@ -801,7 +856,7 @@ MAN: \"ssdp:discover\"\r\n\ MX: 2\r\n\ ST: urn:ses-com:device:SatIPServer:1\r\n\ \r\n" - htsbuf_queue_t q; + int i; if (!tvheadend_running) return; @@ -811,13 +866,20 @@ ST: urn:ses-com:device:SatIPServer:1\r\n\ } if (satip_discovery_service == NULL) { satip_discovery_service = upnp_service_create(upnp_service); - satip_discovery_service->us_received = satip_discovery_service_received; - satip_discovery_service->us_destroy = satip_discovery_service_destroy; + if (satip_discovery_service) { + satip_discovery_service->us_received = satip_discovery_service_received; + satip_discovery_service->us_destroy = satip_discovery_service_destroy; + } } - htsbuf_queue_init(&q, 0); - htsbuf_append(&q, MSG, sizeof(MSG)-1); - upnp_send(&q, NULL); - htsbuf_queue_flush(&q); + if (satip_discovery_service) { + htsbuf_queue_t q; + htsbuf_queue_init(&q, 0); + htsbuf_append(&q, MSG, sizeof(MSG)-1); + upnp_send(&q, NULL); + htsbuf_queue_flush(&q); + } + for (i = 0; i < satip_static_clients->num; i++) + satip_discovery_static(satip_static_clients->str[i]); gtimer_arm(&satip_discovery_timer, satip_discovery_timer_cb, NULL, 3600); #undef MSG } @@ -832,9 +894,10 @@ satip_device_discovery_start( void ) * Initialization */ -void satip_init ( void ) +void satip_init ( str_list_t *clients ) { TAILQ_INIT(&satip_discoveries); + satip_static_clients = clients; satip_device_discovery_start(); } diff --git a/src/input/mpegts/satip/satip.h b/src/input/mpegts/satip/satip.h index 6e994c82..59d035eb 100644 --- a/src/input/mpegts/satip/satip.h +++ b/src/input/mpegts/satip/satip.h @@ -20,7 +20,7 @@ #ifndef __TVH_SATIP_H__ #define __TVH_SATIP_H__ -void satip_init( void ); +void satip_init( str_list_t *clients ); void satip_done( void ); #endif /* __TVH_SATIP_H__ */ diff --git a/src/main.c b/src/main.c index fba0b10c..8d4add02 100644 --- a/src/main.c +++ b/src/main.c @@ -476,6 +476,7 @@ main(int argc, char **argv) #endif *opt_bindaddr = NULL, *opt_subscribe = NULL; + str_list_t opt_satip_xml = { .max = 10, .num = 0, .str = calloc(10, sizeof(char*)) }; str_list_t opt_tsfile = { .max = 10, .num = 0, .str = calloc(10, sizeof(char*)) }; cmdline_opt_t cmdline_opts[] = { { 0, NULL, "Generic Options", OPT_BOOL, NULL }, @@ -497,6 +498,10 @@ main(int argc, char **argv) #if ENABLE_LINUXDVB { 'a', "adapters", "Only use specified DVB adapters (comma separated)", OPT_STR, &opt_dvb_adapters }, +#endif +#if ENABLE_SATIP_CLIENT + { 0, "satip_xml", "URL with the SAT>IP server XML location", + OPT_STR_LIST, &opt_satip_xml }, #endif { 0, NULL, "Server Connectivity", OPT_BOOL, NULL }, { '6', "ipv6", "Listen on IPv6", OPT_BOOL, &opt_ipv6 }, @@ -766,7 +771,7 @@ main(int argc, char **argv) service_init(); #if ENABLE_MPEGTS - mpegts_init(adapter_mask, &opt_tsfile, opt_tsfile_tuner); + mpegts_init(adapter_mask, &opt_satip_xml, &opt_tsfile, opt_tsfile_tuner); #endif channel_init(); @@ -881,6 +886,7 @@ main(int argc, char **argv) unlink(opt_pidpath); free(opt_tsfile.str); + free(opt_satip_xml.str); /* OpenSSL - welcome to the "cleanup" hell */ ENGINE_cleanup();