Example #1
0
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;
}
Example #2
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';
    }
  }
}
Example #3
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);
}
Example #4
0
/*
 *  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;
}
Example #5
0
/*
 *  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;
}
Example #6
0
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);
  }
}