Beispiel #1
0
void
tvhdhomerun_device_destroy( tvhdhomerun_device_t *hd )
{
  tvhdhomerun_frontend_t *lfe;

  lock_assert(&global_lock);

  gtimer_disarm(&hd->hd_destroy_timer);

  tvhlog(LOG_INFO, "tvhdhomerun", "Releasing locks for devices");
  while ((lfe = TAILQ_FIRST(&hd->hd_frontends)) != NULL) {
    tvhdhomerun_frontend_delete(lfe);
  }

#define FREEM(x) free(hd->hd_info.x)
  FREEM(ip_address);
  FREEM(friendlyname);
  FREEM(uuid);
  FREEM(deviceModel);
#undef FREEM

  tvh_hardware_delete((tvh_hardware_t*)hd);

#define FREEM(x) free(hd->x)
  FREEM(hd_override_type);
#undef FREEM

  free(hd);
}
Beispiel #2
0
static void
tvhdhomerun_device_class_override_notify( void * obj, const char *lang )
{
  tvhdhomerun_device_t *hd = obj;
  tvhdhomerun_frontend_t *hfe;
  dvb_fe_type_t type = dvb_str2type(hd->hd_override_type);
  struct hdhomerun_discover_device_t discover_info;
  unsigned int tuner;
  htsmsg_t *conf;

  conf = hts_settings_load("input/tvhdhomerun/adapters/%s", hd->hd_info.uuid);
  if (conf)
    conf = htsmsg_get_map(conf, "frontends");

  lock_assert(&global_lock);

  while ((hfe = TAILQ_FIRST(&hd->hd_frontends)) != NULL)
  {
    if (hfe->hf_type == type)
      break;

    discover_info.device_id = hdhomerun_device_get_device_id(hfe->hf_hdhomerun_tuner);
    discover_info.ip_addr =  hdhomerun_device_get_device_ip(hfe->hf_hdhomerun_tuner);
    tuner = hfe->hf_tunerNumber;

    tvhdhomerun_frontend_delete(hfe);

    tvhdhomerun_frontend_create(hd, &discover_info, conf, type, tuner);
  }
}
Beispiel #3
0
static void
satip_discovery_timerq_cb(void *aux)
{
  satip_discovery_t *d, *next;
  int r;

  lock_assert(&global_lock);

  next = TAILQ_FIRST(&satip_discoveries);
  while (next) {
    d = next;
    next = TAILQ_NEXT(d, disc_link);
    if (d->http_client) {
      if (dispatch_clock - d->http_start > 4)
        satip_discovery_destroy(d, 1);
      continue;
    }

    d->http_client = http_client_connect(d, HTTP_VERSION_1_1, d->url.scheme,
                                         d->url.host, d->url.port, NULL);
    if (d->http_client == NULL)
      satip_discovery_destroy(d, 1);
    else {
      d->http_start = dispatch_clock;
      d->http_client->hc_conn_closed = satip_discovery_http_closed;
      http_client_register(d->http_client);
      r = http_client_simple(d->http_client, &d->url);
      if (r < 0)
        satip_discovery_destroy(d, 1);
    }
  }
  if (TAILQ_FIRST(&satip_discoveries))
    gtimer_arm(&satip_discovery_timerq, satip_discovery_timerq_cb, NULL, 5);
}
Beispiel #4
0
void
tvhdhomerun_device_destroy( tvhdhomerun_device_t *hd )
{
  tvhdhomerun_frontend_t *lfe;

  lock_assert(&global_lock);

  mtimer_disarm(&hd->hd_destroy_timer);

  idnode_save_check(&hd->th_id, 0);

  tvhinfo(LS_TVHDHOMERUN, "Releasing locks for devices");
  while ((lfe = TAILQ_FIRST(&hd->hd_frontends)) != NULL) {
    tvhdhomerun_frontend_delete(lfe);
  }

#define FREEM(x) free(hd->hd_info.x)
  FREEM(friendlyname);
  FREEM(uuid);
  FREEM(deviceModel);
#undef FREEM

  tvh_hardware_delete((tvh_hardware_t*)hd);

#define FREEM(x) free(hd->x)
  FREEM(hd_override_type);
#undef FREEM

  free(hd);
}
Beispiel #5
0
/*
 * Stop connection
 */
static void
iptv_rtsp_stop
  ( iptv_mux_t *im )
{
  rtsp_priv_t *rp = im->im_data;
  int play;

  lock_assert(&global_lock);

  if (rp == NULL)
    return;

  play = rp->play;
  im->im_data = NULL;
  rp->hc->hc_aux = NULL;
  if (play)
    rtsp_teardown(rp->hc, rp->path, "");
  pthread_mutex_unlock(&iptv_lock);
  gtimer_disarm(&rp->alive_timer);
  udp_multirecv_free(&rp->um);
  if (!play)
    http_client_close(rp->hc);
  free(rp->path);
  free(rp->query);
  rtcp_destroy(rp->rtcp_info);
  free(rp->rtcp_info);
  free(rp);
  pthread_mutex_lock(&iptv_lock);
}
Beispiel #6
0
void
timeshift_destroy(streaming_target_t *pad)
{
  timeshift_t *ts = (timeshift_t*)pad;
  streaming_message_t *sm;

  /* Must hold global lock */
  lock_assert(&global_lock);

  /* Ensure the threads exits */
  // Note: this is a workaround for the fact the Q might have been flushed
  //       in reader thread (VERY unlikely)
  pthread_mutex_lock(&ts->state_mutex);
  sm = streaming_msg_create(SMT_EXIT);
  streaming_target_deliver2(&ts->wr_queue.sq_st, sm);
  timeshift_write_exit(ts->rd_pipe.wr);
  pthread_mutex_unlock(&ts->state_mutex);

  /* Wait for all threads */
  pthread_join(ts->rd_thread, NULL);
  pthread_join(ts->wr_thread, NULL);

  /* Shut stuff down */
  streaming_queue_deinit(&ts->wr_queue);

  close(ts->rd_pipe.rd);
  close(ts->rd_pipe.wr);

  /* Flush files */
  timeshift_filemgr_flush(ts, NULL);

  free(ts->path);
  free(ts);
}
Beispiel #7
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->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);
}
Beispiel #8
0
void
bouquet_destroy_by_channel_tag(channel_tag_t *ct)
{
  bouquet_t *bq;

  lock_assert(&global_lock);

  RB_FOREACH(bq, &bouquets, bq_link)
    if (bq->bq_chtag_ptr == ct)
      bq->bq_chtag_ptr = NULL;
}
Beispiel #9
0
void
gtimer_arm_abs(gtimer_t *gti, gti_callback_t *callback, void *opaque,
	       time_t when)
{
  lock_assert(&global_lock);

  if(gti->gti_callback != NULL)
    LIST_REMOVE(gti, gti_link);
    
  gti->gti_callback = callback;
  gti->gti_opaque = opaque;
  gti->gti_expire = when;

  LIST_INSERT_SORTED(&gtimers, gti, gti_link, gtimercmp);
}
Beispiel #10
0
void
bouquet_destroy_by_service(service_t *t)
{
  bouquet_t *bq;
  service_lcn_t *sl;

  lock_assert(&global_lock);

  RB_FOREACH(bq, &bouquets, bq_link)
    if (idnode_set_exists(bq->bq_services, &t->s_id))
      idnode_set_remove(bq->bq_services, &t->s_id);
  while ((sl = LIST_FIRST(&t->s_lcns)) != NULL) {
    LIST_REMOVE(sl, sl_link);
    free(sl);
  }
}
Beispiel #11
0
/**
 * Create timeshift buffer
 *
 * max_period of buffer in seconds (0 = unlimited)
 * max_size   of buffer in bytes   (0 = unlimited)
 */
streaming_target_t *timeshift_create
  (streaming_target_t *out, time_t max_time)
{
  timeshift_t *ts = calloc(1, sizeof(timeshift_t));

  memoryinfo_alloc(&timeshift_memoryinfo, sizeof(timeshift_t));

  /* Must hold global lock */
  lock_assert(&global_lock);

  /* Setup structure */
  TAILQ_INIT(&ts->files);
  ts->output     = out;
  ts->path       = NULL;
  ts->max_time   = max_time;
  ts->state      = TS_LIVE;
  ts->exit       = 0;
  ts->full       = 0;
  ts->vididx     = -1;
  ts->id         = timeshift_index;
  ts->ondemand   = timeshift_conf.ondemand;
  ts->dobuf      = ts->ondemand ? 0 : 1;
  ts->packet_mode= 1;
  ts->last_wr_time = 0;
  ts->buf_time   = 0;
  ts->start_pts  = 0;
  ts->ref_time   = 0;
  ts->seek.file  = NULL;
  ts->seek.frame = NULL;
  ts->ram_segments = 0;
  ts->file_segments = 0;
  pthread_mutex_init(&ts->state_mutex, NULL);

  /* Initialise output */
  tvh_pipe(O_NONBLOCK, &ts->rd_pipe);

  /* Initialise input */
  streaming_queue_init(&ts->wr_queue, 0, 0);
  streaming_target_init(&ts->input, &timeshift_input_ops, ts, 0);
  tvhthread_create(&ts->wr_thread, NULL, timeshift_writer, ts, "tshift-wr");
  tvhthread_create(&ts->rd_thread, NULL, timeshift_reader, ts, "tshift-rd");

  /* Update index */
  timeshift_index++;

  return &ts->input;
}
Beispiel #12
0
bouquet_t *
bouquet_create(const char *uuid, htsmsg_t *conf,
               const char *name, const char *src)
{
  bouquet_t *bq, *bq2;
  int i;

  lock_assert(&global_lock);

  bq = calloc(1, sizeof(bouquet_t));
  bq->bq_services = idnode_set_create(1);
  bq->bq_active_services = idnode_set_create(1);

  if (idnode_insert(&bq->bq_id, uuid, &bouquet_class, 0)) {
    if (uuid)
      tvherror("bouquet", "invalid uuid '%s'", uuid);
    free(bq);
    return NULL;
  }

  if (conf) {
    bq->bq_in_load = 1;
    idnode_load(&bq->bq_id, conf);
    bq->bq_in_load = 0;
    if (!htsmsg_get_bool(conf, "shield", &i) && i)
      bq->bq_shield = 1;
  }

  if (name) {
    free(bq->bq_name);
    bq->bq_name = strdup(name);
  }

  if (src) {
    free(bq->bq_src);
    bq->bq_src = strdup(src);
  }

  bq2 = RB_INSERT_SORTED(&bouquets, bq, bq_link, _bq_cmp);
  assert(bq2 == NULL);

  bq->bq_saveflag = 1;

  return bq;
}
Beispiel #13
0
void
epggrab_ota_queue_mux( mpegts_mux_t *mm )
{
  epggrab_ota_mux_t *om;
  int epg_flag;

  if (!mm)
    return;

  lock_assert(&global_lock);

  epg_flag = mm->mm_is_epg(mm);
  if (epg_flag < 0 || epg_flag == MM_EPG_DISABLE)
    return;
  om = epggrab_ota_find_mux(mm);
  if (om && epggrab_ota_queue_one(om))
    epggrab_ota_kick(4);
}
Beispiel #14
0
/**
 * Create timeshift buffer
 *
 * max_period of buffer in seconds (0 = unlimited)
 * max_size   of buffer in bytes   (0 = unlimited)
 */
streaming_target_t *timeshift_create
  (streaming_target_t *out, time_t max_time)
{
  timeshift_t *ts = calloc(1, sizeof(timeshift_t));
  int i;

  /* Must hold global lock */
  lock_assert(&global_lock);

  /* Setup structure */
  TAILQ_INIT(&ts->files);
  ts->output     = out;
  ts->path       = NULL;
  ts->max_time   = max_time;
  ts->state      = TS_INIT;
  ts->full       = 0;
  ts->vididx     = -1;
  ts->id         = timeshift_index;
  ts->ondemand   = timeshift_conf.ondemand;
  ts->dobuf      = ts->ondemand ? 0 : 1;
  ts->packet_mode= 1;
  ts->last_time  = 0;
  ts->start_pts  = 0;
  ts->ref_time   = 0;
  for (i = 0; i < TIMESHIFT_BACKLOG_MAX; i++)
    TAILQ_INIT(&ts->backlog[i]);
  pthread_mutex_init(&ts->rdwr_mutex, NULL);
  pthread_mutex_init(&ts->state_mutex, NULL);

  /* Initialise output */
  tvh_pipe(O_NONBLOCK, &ts->rd_pipe);

  /* Initialise input */
  streaming_queue_init(&ts->wr_queue, 0, 0);
  streaming_target_init(&ts->input, timeshift_input, ts, 0);
  tvhthread_create(&ts->wr_thread, NULL, timeshift_writer, ts, "tshift-wr");
  tvhthread_create(&ts->rd_thread, NULL, timeshift_reader, ts, "tshift-rd");

  /* Update index */
  timeshift_index++;

  return &ts->input;
}
Beispiel #15
0
void
timeshift_packets_clone
  ( timeshift_t *ts, struct streaming_message_queue *dst, int delivered )
{
  streaming_message_t *lowest, *sm, *sm2;
  struct streaming_message_queue *sq, *sq2, *backlogs;
  th_pkt_t *pkt;
  int i;

  lock_assert(&ts->state_mutex);

  /* init temporary queues and copy the backlog data */
  backlogs = alloca(ts->backlog_max * sizeof(*backlogs));
  for (i = 0; i < ts->backlog_max; i++) {
    sq = &backlogs[i];
    sq2 = &ts->backlog[i];
    TAILQ_INIT(sq);
    TAILQ_FOREACH(sm, sq2, sm_link) {
      if (!delivered) {
        pkt = sm->sm_data;
        if (pkt->pkt_delivered)
          continue;
      }
      sm2 = streaming_msg_clone(sm);
      TAILQ_INSERT_TAIL(sq, sm2, sm_link);
    }
  }
  /* push to destination (pts sorted) */
  while (1) {
    lowest = NULL;
    for (i = 0; i < ts->backlog_max; i++) {
      sq = &backlogs[i];
      sm = TAILQ_FIRST(sq);
      if (sm && (lowest == NULL || lowest->sm_time > sm->sm_time))
        lowest = sm;
    }
    if (!lowest)
      break;
    TAILQ_REMOVE(sq, lowest, sm_link);
    TAILQ_INSERT_TAIL(dst, lowest, sm_link);
  }
}
Beispiel #16
0
void
timeshift_destroy(streaming_target_t *pad)
{
  timeshift_t *ts = (timeshift_t*)pad;
  streaming_message_t *sm;
  int i;

  /* Must hold global lock */
  lock_assert(&global_lock);

  /* Ensure the threads exits */
  // Note: this is a workaround for the fact the Q might have been flushed
  //       in reader thread (VERY unlikely)
  pthread_mutex_lock(&ts->state_mutex);
  sm = streaming_msg_create(SMT_EXIT);
  streaming_target_deliver2(&ts->wr_queue.sq_st, sm);
  timeshift_write_exit(ts->rd_pipe.wr);
  pthread_mutex_unlock(&ts->state_mutex);

  /* Wait for all threads */
  pthread_join(ts->rd_thread, NULL);
  pthread_join(ts->wr_thread, NULL);

  /* Shut stuff down */
  streaming_queue_deinit(&ts->wr_queue);
  for (i = 0; i < TIMESHIFT_BACKLOG_MAX; i++)
    streaming_queue_clear(&ts->backlog[i]);

  close(ts->rd_pipe.rd);
  close(ts->rd_pipe.wr);

  /* Flush files */
  timeshift_filemgr_flush(ts, NULL);

  /* Release SMT_START index */
  if (ts->smt_start)
    streaming_start_unref(ts->smt_start);

  if (ts->path)
    free(ts->path);
  free(ts);
}
Beispiel #17
0
void
gtimer_arm_abs2
  (gtimer_t *gti, gti_callback_t *callback, void *opaque, struct timespec *when)
{
  lock_assert(&global_lock);

  if (gti->gti_callback != NULL)
    LIST_REMOVE(gti, gti_link);

  gti->gti_callback = callback;
  gti->gti_opaque   = opaque;
  gti->gti_expire   = *when;

  LIST_INSERT_SORTED(&gtimers, gti, gti_link, gtimercmp);

  //tvhdebug("gtimer", "%p @ %ld.%09ld", gti, when->tv_sec, when->tv_nsec);

  if (LIST_FIRST(&gtimers) == gti)
    pthread_cond_signal(&gtimer_cond); // force timer re-check
}
Beispiel #18
0
bouquet_t *
bouquet_find_by_source(const char *name, const char *src, int create)
{
  bouquet_t *bq;
  bouquet_t bqs;

  assert(src);

  lock_assert(&global_lock);

  bqs.bq_src = (char *)src;
  bq = RB_FIND(&bouquets, &bqs, bq_link, _bq_cmp);
  if (bq) {
    if (name && *name && strcmp(name, bq->bq_name)) {
      tvhwarn("bouquet", "bouquet name '%s' changed to '%s'", bq->bq_name ?: "", name);
      free(bq->bq_name);
      bq->bq_name = strdup(name);
    }
    return bq;
  }
Beispiel #19
0
void
GTIMER_FCN(gtimer_arm_absn)
  (GTIMER_TRACEID_ gtimer_t *gti, gti_callback_t *callback, void *opaque, time_t when)
{
  lock_assert(&global_lock);

  if (gti->gti_callback != NULL)
    LIST_REMOVE(gti, gti_link);

  gti->gti_callback = callback;
  gti->gti_opaque   = opaque;
  gti->gti_expire   = when;
#if ENABLE_GTIMER_CHECK
  gti->gti_id       = id;
#endif

  LIST_INSERT_SORTED(&gtimers, gti, gti_link, gtimercmp);

  if (LIST_FIRST(&gtimers) == gti)
    pthread_cond_signal(&gtimer_cond); // force timer re-check
}
Beispiel #20
0
void
GTIMER_FCN(mtimer_arm_abs)
  (GTIMER_TRACEID_ mtimer_t *mti, mti_callback_t *callback, void *opaque, int64_t when)
{
  lock_assert(&global_lock);

  if (mti->mti_callback != NULL)
    LIST_REMOVE(mti, mti_link);

  mti->mti_callback = callback;
  mti->mti_opaque   = opaque;
  mti->mti_expire   = when;
#if ENABLE_GTIMER_CHECK
  mti->mti_id       = id;
#endif

  LIST_INSERT_SORTED(&mtimers, mti, mti_link, mtimercmp);

  if (LIST_FIRST(&mtimers) == mti)
    tvh_cond_signal(&mtimer_cond, 0); // force timer re-check
}
Beispiel #21
0
/**
 * Create timeshift buffer
 *
 * max_period of buffer in seconds (0 = unlimited)
 * max_size   of buffer in bytes   (0 = unlimited)
 */
streaming_target_t *timeshift_create
  (streaming_target_t *out, time_t max_time)
{
  char buf[512];
  timeshift_t *ts = calloc(1, sizeof(timeshift_t));

  /* Must hold global lock */
  lock_assert(&global_lock);

  /* Create directories */
  if (timeshift_filemgr_makedirs(timeshift_index, buf, sizeof(buf)))
    return NULL;

  /* Setup structure */
  TAILQ_INIT(&ts->files);
  ts->output     = out;
  ts->path       = strdup(buf);
  ts->max_time   = max_time;
  ts->state      = TS_INIT;
  ts->full       = 0;
  ts->vididx     = -1;
  ts->id         = timeshift_index;
  ts->ondemand   = timeshift_ondemand;
  pthread_mutex_init(&ts->rdwr_mutex, NULL);
  pthread_mutex_init(&ts->state_mutex, NULL);

  /* Initialise output */
  tvh_pipe(O_NONBLOCK, &ts->rd_pipe);

  /* Initialise input */
  streaming_queue_init(&ts->wr_queue, 0);
  streaming_target_init(&ts->input, timeshift_input, ts, 0);
  pthread_create(&ts->wr_thread, NULL, timeshift_writer, ts);
  pthread_create(&ts->rd_thread, NULL, timeshift_reader, ts);

  /* Update index */
  timeshift_index++;

  return &ts->input;
}
Beispiel #22
0
void
satip_device_destroy( satip_device_t *sd )
{
  satip_frontend_t *lfe;

  lock_assert(&global_lock);

  gtimer_disarm(&sd->sd_destroy_timer);

  while ((lfe = TAILQ_FIRST(&sd->sd_frontends)) != NULL)
    satip_frontend_delete(lfe);

  satip_device_dbus_notify(sd, "stop");

#define FREEM(x) free(sd->sd_info.x)
  FREEM(myaddr);
  FREEM(addr);
  FREEM(uuid);
  FREEM(bootid);
  FREEM(configid);
  FREEM(deviceid);
  FREEM(location);
  FREEM(server);
  FREEM(friendlyname);
  FREEM(manufacturer);
  FREEM(manufacturerURL);
  FREEM(modeldesc);
  FREEM(modelname);
  FREEM(modelnum);
  FREEM(serialnum);
  FREEM(presentation);
  FREEM(tunercfg);
#undef FREEM
  free(sd->sd_bindaddr);
  free(sd->sd_tunercfg);

  tvh_hardware_delete((tvh_hardware_t*)sd);
  free(sd);
}
Beispiel #23
0
/**
 * Create timeshift buffer
 *
 * max_period of buffer in seconds (0 = unlimited)
 * max_size   of buffer in bytes   (0 = unlimited)
 */
streaming_target_t *timeshift_create
  (streaming_target_t *out, time_t max_time)
{
  timeshift_t *ts = calloc(1, sizeof(timeshift_t));
  int i;

  /* Must hold global lock */
  lock_assert(&global_lock);

  /* Setup structure */
  TAILQ_INIT(&ts->files);
  ts->output     = out;
  ts->path       = NULL;
  ts->max_time   = max_time;
  ts->state      = TS_INIT;
  ts->full       = 0;
  ts->vididx     = -1;
  ts->id         = timeshift_index;
  ts->ondemand   = timeshift_ondemand;
  ts->pts_delta  = PTS_UNSET;
  for (i = 0; i < ARRAY_SIZE(ts->pts_val); i++)
    ts->pts_val[i] = PTS_UNSET;
  pthread_mutex_init(&ts->rdwr_mutex, NULL);
  pthread_mutex_init(&ts->state_mutex, NULL);

  /* Initialise output */
  tvh_pipe(O_NONBLOCK, &ts->rd_pipe);

  /* Initialise input */
  streaming_queue_init(&ts->wr_queue, 0, 0);
  streaming_target_init(&ts->input, timeshift_input, ts, 0);
  tvhthread_create(&ts->wr_thread, NULL, timeshift_writer, ts);
  tvhthread_create(&ts->rd_thread, NULL, timeshift_reader, ts);

  /* Update index */
  timeshift_index++;

  return &ts->input;
}
Beispiel #24
0
void
epggrab_ota_queue_mux( mpegts_mux_t *mm )
{
  const char *id = idnode_uuid_as_str(&mm->mm_id);
  epggrab_ota_mux_t *om;
  int epg_flag;

  if (!mm)
    return;

  lock_assert(&global_lock);

  epg_flag = mm->mm_is_epg(mm);
  if (epg_flag < 0 || epg_flag == MM_EPG_DISABLE)
    return;
  RB_FOREACH(om, &epggrab_ota_all, om_global_link)
    if (!strcmp(om->om_mux_uuid, id)) {
      if (epggrab_ota_queue_one(om))
        epggrab_ota_kick(4);
      break;
    }
}