static int en50221_app_unknown_message(void *arg, uint8_t slot_id, uint16_t session_num, uint32_t resource_id, uint8_t *data, uint32_t data_length) { tvhtrace("en50221", "unknown message slot_id %u, session_num %u, resource_id %x", slot_id, session_num, resource_id); tvhlog_hexdump("en50221", data, data_length); return 0; }
static void spawn_pipe_read( th_pipe_t *p, char **_buf, int level ) { char *buf = *_buf, *s; size_t len; int r; if (buf == NULL) { buf = malloc(SPAWN_PIPE_READ_SIZE); buf[0] = '\0'; buf[SPAWN_PIPE_READ_SIZE - 1] = 0; *_buf = buf; } while (1) { len = strlen(buf); r = read(p->rd, buf + len, SPAWN_PIPE_READ_SIZE - 1 - len); if (r < 1) { if (errno == EAGAIN) break; if (ERRNO_AGAIN(errno)) continue; break; } buf[len + r] = '\0'; tvhlog_hexdump("spawn", buf + len, r); while (1) { s = buf; while (*s && *s != '\n' && *s != '\r') s++; if (*s == '\0') break; *s++ = '\0'; if (buf[0]) tvhlog(level, "spawn", "%s", buf); memmove(buf, s, strlen(s) + 1); } if (strlen(buf) == SPAWN_PIPE_READ_SIZE - 1) { tvherror("spawn", "pipe buffer full"); buf[0] = '\0'; } } }
static void satip_discovery_http_closed(http_client_t *hc, int errn) { satip_discovery_t *d = hc->hc_aux; char *s; htsmsg_t *xml = NULL, *tags, *root, *device; const char *friendlyname, *manufacturer, *manufacturerURL, *modeldesc; const char *modelname, *modelnum, *serialnum; const char *presentation, *tunercfg, *udn, *uuid; const char *cs, *arg; 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) { n = http_tokenize(s, argv, ARRAY_SIZE(argv), ';'); if (n <= 0 || strcasecmp(s, "text/xml")) { errn = ENOENT; s = NULL; } } if (errn != 0 || s == NULL || hc->hc_code != 200 || hc->hc_data_size == 0 || hc->hc_data == NULL) { tvhlog(LOG_ERR, "satip", "Cannot get %s: %s", d->location, strerror(errn)); return; } if (tvhtrace_enabled()) { tvhtrace("satip", "received XML description from %s", hc->hc_host); tvhlog_hexdump("satip", hc->hc_data, hc->hc_data_size); } if (d->myaddr == NULL || d->myaddr[0] == '\0') { struct sockaddr_storage ip; socklen_t addrlen = sizeof(ip); errbuf[0] = '\0'; getsockname(hc->hc_fd, (struct sockaddr *)&ip, &addrlen); inet_ntop(ip.ss_family, IP_IN_ADDR(ip), errbuf, sizeof(errbuf)); free(d->myaddr); d->myaddr = strdup(errbuf); } s = hc->hc_data + hc->hc_data_size - 1; while (s != hc->hc_data && *s != '/') s--; if (s != hc->hc_data) s--; if (strncmp(s, "</root>", 7)) return; /* Parse */ xml = htsmsg_xml_deserialize(hc->hc_data, errbuf, sizeof(errbuf)); hc->hc_data = NULL; if (!xml) { tvhlog(LOG_ERR, "satip_discovery_desc", "htsmsg_xml_deserialize error %s", errbuf); goto finish; } if ((tags = htsmsg_get_map(xml, "tags")) == NULL) goto finish; if ((root = htsmsg_get_map(tags, "root")) == NULL) goto finish; if ((device = htsmsg_get_map(root, "tags")) == NULL) goto finish; if ((device = htsmsg_get_map(device, "device")) == NULL) goto finish; if ((device = htsmsg_get_map(device, "tags")) == NULL) goto finish; if ((cs = htsmsg_xml_get_cdata_str(device, "deviceType")) == NULL) goto finish; if (strcmp(cs, "urn:ses-com:device:SatIPServer:1")) goto finish; if ((friendlyname = htsmsg_xml_get_cdata_str(device, "friendlyName")) == NULL) goto finish; if ((manufacturer = htsmsg_xml_get_cdata_str(device, "manufacturer")) == NULL) goto finish; if ((manufacturerURL = htsmsg_xml_get_cdata_str(device, "manufacturerURL")) == NULL) manufacturerURL = ""; if ((modeldesc = htsmsg_xml_get_cdata_str(device, "modelDescription")) == NULL) modeldesc = ""; if ((modelname = htsmsg_xml_get_cdata_str(device, "modelName")) == NULL) goto finish; if ((modelnum = htsmsg_xml_get_cdata_str(device, "modelNumber")) == NULL) modelnum = ""; if ((serialnum = htsmsg_xml_get_cdata_str(device, "serialNumber")) == NULL) serialnum = ""; if ((presentation = htsmsg_xml_get_cdata_str(device, "presentationURL")) == NULL) presentation = ""; 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) tunercfg = ""; 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.rtsp_port = 554; info.srcs = 4; arg = http_arg_get(&hc->hc_args, "X-SATIP-RTSP-Port"); if (arg) { i = atoi(arg); if (i > 0 && i < 65535) info.rtsp_port = i; } arg = http_arg_get(&hc->hc_args, "X-SATIP-Sources"); if (arg) { i = atoi(arg); if (i > 0 && i < 128) info.srcs = i; } info.myaddr = strdup(d->myaddr); info.addr = strdup(d->url.host); info.uuid = strdup(uuid); info.bootid = strdup(d->bootid); info.configid = strdup(d->configid); info.deviceid = strdup(d->deviceid); info.location = strdup(d->location); info.server = strdup(d->server); info.friendlyname = strdup(friendlyname); info.manufacturer = strdup(manufacturer); info.manufacturerURL = strdup(manufacturerURL); info.modeldesc = strdup(modeldesc); info.modelname = strdup(modelname); info.modelnum = strdup(modelnum); info.serialnum = strdup(serialnum); info.presentation = strdup(presentation); info.tunercfg = strdup(tunercfg); htsmsg_destroy(xml); xml = NULL; pthread_mutex_lock(&global_lock); if (!satip_device_find(info.uuid)) satip_device_create(&info); pthread_mutex_unlock(&global_lock); free(info.myaddr); free(info.location); free(info.server); free(info.addr); free(info.uuid); free(info.bootid); free(info.configid); free(info.deviceid); free(info.friendlyname); free(info.manufacturer); free(info.manufacturerURL); free(info.modeldesc); free(info.modelname); free(info.modelnum); free(info.serialnum); free(info.presentation); free(info.tunercfg); finish: htsmsg_destroy(xml); }
/* * Discovery thread */ static void * upnp_thread( void *aux ) { char *bindaddr = aux; tvhpoll_t *poll = tvhpoll_create(2); tvhpoll_event_t ev[2]; upnp_data_t *data; udp_connection_t *multicast = NULL, *unicast = NULL; udp_connection_t *conn; unsigned char buf[16384]; upnp_service_t *us; struct sockaddr_storage ip; socklen_t iplen; size_t size; int r, delay_ms; multicast = udp_bind(LS_UPNP, "upnp_thread_multicast", "239.255.255.250", 1900, NULL, NULL, 32*1024, 32*1024); if (multicast == NULL || multicast == UDP_FATAL_ERROR) goto error; unicast = udp_bind(LS_UPNP, "upnp_thread_unicast", bindaddr, 0, NULL, NULL, 32*1024, 32*1024); if (unicast == NULL || unicast == UDP_FATAL_ERROR) goto error; memset(&ev, 0, sizeof(ev)); ev[0].fd = multicast->fd; ev[0].events = TVHPOLL_IN; ev[0].ptr = multicast; ev[1].fd = unicast->fd; ev[1].events = TVHPOLL_IN; ev[1].ptr = unicast; tvhpoll_add(poll, ev, 2); delay_ms = 0; while (atomic_get(&upnp_running) && multicast->fd >= 0) { r = tvhpoll_wait(poll, ev, 2, delay_ms ?: 1000); if (r == 0) /* timeout */ delay_ms = 0; while (r-- > 0) { if ((ev[r].events & TVHPOLL_IN) != 0) { conn = ev[r].ptr; iplen = sizeof(ip); size = recvfrom(conn->fd, buf, sizeof(buf), 0, (struct sockaddr *)&ip, &iplen); if (size > 0 && tvhtrace_enabled()) { char tbuf[256]; inet_ntop(ip.ss_family, IP_IN_ADDR(ip), tbuf, sizeof(tbuf)); tvhtrace(LS_UPNP, "%s - received data from %s:%hu [size=%zi]", conn == multicast ? "multicast" : "unicast", tbuf, (unsigned short) ntohs(IP_PORT(ip)), size); tvhlog_hexdump(LS_UPNP, buf, size); } /* TODO: a filter */ TAILQ_FOREACH(us, &upnp_services, us_link) us->us_received(buf, size, conn, &ip); } } while (delay_ms == 0) { tvh_mutex_lock(&upnp_lock); data = TAILQ_FIRST(&upnp_data_write); if (data) { delay_ms = data->delay_ms; data->delay_ms = 0; if (!delay_ms) { TAILQ_REMOVE(&upnp_data_write, data, data_link); } else { data = NULL; } } tvh_mutex_unlock(&upnp_lock); if (data == NULL) break; upnp_dump_data(data); udp_write_queue(data->from_multicast ? multicast : unicast, &data->queue, &data->storage); htsbuf_queue_flush(&data->queue); free(data); delay_ms = 0; } } /* flush the write queue (byebye messages) */ while (1) { tvh_mutex_lock(&upnp_lock); data = TAILQ_FIRST(&upnp_data_write); if (data) TAILQ_REMOVE(&upnp_data_write, data, data_link); tvh_mutex_unlock(&upnp_lock); if (data == NULL) break; tvh_safe_usleep((long)data->delay_ms * 1000); upnp_dump_data(data); udp_write_queue(unicast, &data->queue, &data->storage); htsbuf_queue_flush(&data->queue); free(data); } error: atomic_set(&upnp_running, 0); tvhpoll_destroy(poll); udp_close(unicast); udp_close(multicast); return NULL; }
/* * Discovery thread */ static void * upnp_thread( void *aux ) { char *bindaddr = aux; tvhpoll_t *poll = tvhpoll_create(2); tvhpoll_event_t ev[2]; upnp_data_t *data; udp_connection_t *multicast = NULL, *unicast = NULL; udp_connection_t *conn; unsigned char buf[16384]; upnp_service_t *us; struct sockaddr_storage ip; socklen_t iplen; size_t size; int r; multicast = udp_bind("upnp", "upnp_thread_multicast", "239.255.255.250", 1900, NULL, 32*1024); if (multicast == NULL || multicast == UDP_FATAL_ERROR) goto error; unicast = udp_bind("upnp", "upnp_thread_unicast", bindaddr, 0, NULL, 32*1024); if (unicast == NULL || unicast == UDP_FATAL_ERROR) goto error; memset(&ev, 0, sizeof(ev)); ev[0].fd = multicast->fd; ev[0].events = TVHPOLL_IN; ev[0].data.ptr = multicast; ev[1].fd = unicast->fd; ev[1].events = TVHPOLL_IN; ev[1].data.ptr = unicast; tvhpoll_add(poll, ev, 2); while (upnp_running && multicast->fd >= 0) { r = tvhpoll_wait(poll, ev, 2, 1000); while (r-- > 0) { if ((ev[r].events & TVHPOLL_IN) != 0) { conn = ev[r].data.ptr; iplen = sizeof(ip); size = recvfrom(conn->fd, buf, sizeof(buf), 0, (struct sockaddr *)&ip, &iplen); #if ENABLE_TRACE if (size > 0) { char tbuf[256]; inet_ntop(ip.ss_family, IP_IN_ADDR(ip), tbuf, sizeof(tbuf)); tvhtrace("upnp", "%s - received data from %s:%hu [size=%zi]", conn == multicast ? "multicast" : "unicast", tbuf, (unsigned short) IP_PORT(ip), size); tvhlog_hexdump("upnp", buf, size); } #endif /* TODO: a filter */ TAILQ_FOREACH(us, &upnp_services, us_link) us->us_received(buf, size, conn, &ip); } } while (1) { pthread_mutex_lock(&upnp_lock); data = TAILQ_FIRST(&upnp_data_write); if (data) TAILQ_REMOVE(&upnp_data_write, data, data_link); pthread_mutex_unlock(&upnp_lock); if (data == NULL) break; udp_write_queue(unicast, &data->queue, &data->storage); htsbuf_queue_flush(&data->queue); free(data); } } error: upnp_running = 0; tvhpoll_destroy(poll); udp_close(unicast); udp_close(multicast); return NULL; }
static void linuxdvb_ca_process_capmt_queue ( void *aux ) { linuxdvb_ca_t *lca = aux; linuxdvb_ca_capmt_t *lcc; struct section *section; struct section_ext *result; struct mpeg_pmt_section *pmt; uint8_t capmt[4096]; int size, i; lcc = TAILQ_FIRST(&lca->lca_capmt_queue); if (!lcc) return; if (!(section = section_codec(lcc->data, lcc->len))){ tvherror("en50221", "failed to decode PMT section"); goto done; } if (!(result = section_ext_decode(section, 0))){ tvherror("en50221", "failed to decode PMT ext_section"); goto done; } if (!(pmt = mpeg_pmt_section_codec(result))){ tvherror("en50221", "failed to decode PMT"); goto done; } size = en50221_ca_format_pmt(pmt, capmt, sizeof(capmt), 0, lcc->list_mgmt, lcc->cmd_id); if (size < 0) { tvherror("en50221", "Failed to format CAPMT"); } if (en50221_app_ca_pmt(lca->lca_ca_resource, lca->lca_ca_session_number, capmt, size)) { tvherror("en50221", "Failed to send CAPMT"); } tvhtrace("en50221", "%s CAPMT sent (%s)", ca_pmt_cmd_id2str(lcc->cmd_id), ca_pmt_list_mgmt2str(lcc->list_mgmt)); tvhlog_hexdump("en50221", capmt, size); done: i = (lcc->cmd_id == CA_PMT_CMD_ID_QUERY) ? lca->lca_capmt_query_interval : lca->lca_capmt_interval; TAILQ_REMOVE(&lca->lca_capmt_queue, lcc, lcc_link); free(lcc->data); free(lcc); if (!TAILQ_EMPTY(&lca->lca_capmt_queue)) { gtimer_arm_ms(&lca->lca_capmt_queue_timer, linuxdvb_ca_process_capmt_queue, lca, i); } }