Beispiel #1
0
static void
linuxdvb_ca_class_enabled_notify ( void *p, const char *lang )
{
  linuxdvb_ca_t *lca = (linuxdvb_ca_t *) p;

  if (lca->lca_enabled) {
    if (lca->lca_ca_fd < 0) {
      lca->lca_ca_fd = tvh_open(lca->lca_ca_path, O_RDWR | O_NONBLOCK, 0);
      tvhtrace("linuxdvb", "opening ca%u %s (fd %d)",
               lca->lca_number, lca->lca_ca_path, lca->lca_ca_fd);
    }
  } else {
    tvhtrace("linuxdvb", "closing ca%u %s (fd %d)",
             lca->lca_number, lca->lca_ca_path, lca->lca_ca_fd);

    if (lca->lca_en50221_thread_running) {
      lca->lca_en50221_thread_running = 0;
      pthread_join(lca->lca_en50221_thread, NULL);
    }

    ioctl(lca->lca_ca_fd, CA_RESET, NULL);

    close(lca->lca_ca_fd);
    lca->lca_ca_fd = -1;

    idnode_notify_title_changed(&lca->lca_id, lang);
  }
}
/*
 * Output packet
 */
static int _timeshift_read
  ( timeshift_t *ts, timeshift_file_t **cur_file, off_t *cur_off, int *fd,
    streaming_message_t **sm, int *wait )
{
  if (*cur_file) {

    /* Open file */
    if (*fd == -1) {
      tvhtrace("timeshift", "ts %d open file %s",
               ts->id, (*cur_file)->path);
      *fd = open((*cur_file)->path, O_RDONLY);
    }
    tvhtrace("timeshift", "ts %d seek to %"PRIoff_t, ts->id, *cur_off);
    lseek(*fd, *cur_off, SEEK_SET);

    /* Read msg */
    ssize_t r = _read_msg(*fd, sm);
    if (r < 0) {
      streaming_message_t *e = streaming_msg_create_code(SMT_STOP, SM_CODE_UNDEFINED_ERROR);
      streaming_target_deliver2(ts->output, e);
      tvhlog(LOG_ERR, "timeshift", "ts %d could not read buffer", ts->id);
      return -1;
    }
    tvhtrace("timeshift", "ts %d read msg %p (%"PRIssize_t")",
             ts->id, *sm, r);

    /* Incomplete */
    if (r == 0) {
      lseek(*fd, *cur_off, SEEK_SET);
      return 0;
    }

    /* Update */
    *cur_off += r;

    /* Special case - EOF */
    if (r == sizeof(size_t) || *cur_off > (*cur_file)->size) {
      close(*fd);
      *fd       = -1;
      pthread_mutex_lock(&ts->rdwr_mutex);
      *cur_file = timeshift_filemgr_next(*cur_file, NULL, 0);
      pthread_mutex_unlock(&ts->rdwr_mutex);
      *cur_off  = 0; // reset
      *wait     = 0;

    /* Check SMT_START index */
    } else {
      streaming_message_t *ssm = _timeshift_find_sstart(*cur_file, (*sm)->sm_time);
      if (ssm && ssm->sm_data != ts->smt_start) {
        streaming_target_deliver2(ts->output, streaming_msg_clone(ssm));
        if (ts->smt_start)
          streaming_start_unref(ts->smt_start);
        ts->smt_start = ssm->sm_data;
        atomic_add(&ts->smt_start->ss_refcount, 1);
      }
    }
  }
  return 0;
}
Beispiel #3
0
static void* timeshift_reaper_callback ( void *p )
{
  char *dpath;
  timeshift_file_t *tsf;
  timeshift_index_iframe_t *ti;
  timeshift_index_data_t *tid;
  streaming_message_t *sm;
  pthread_mutex_lock(&timeshift_reaper_lock);
  while (timeshift_reaper_run) {

    /* Get next */
    tsf = TAILQ_FIRST(&timeshift_reaper_list);
    if (!tsf) {
      pthread_cond_wait(&timeshift_reaper_cond, &timeshift_reaper_lock);
      continue;
    }
    TAILQ_REMOVE(&timeshift_reaper_list, tsf, link);
    pthread_mutex_unlock(&timeshift_reaper_lock);

    if (tsf->path) {
      tvhtrace("timeshift", "remove file %s", tsf->path);

      /* Remove */
      unlink(tsf->path);
      dpath = dirname(tsf->path);
      if (rmdir(dpath) == -1)
        if (errno != ENOTEMPTY)
          tvhlog(LOG_ERR, "timeshift", "failed to remove %s [e=%s]",
                 dpath, strerror(errno));
    } else {
      tvhtrace("timeshift", "remove RAM segment (time %li)", (long)tsf->time);
    }

    /* Free memory */
    while ((ti = TAILQ_FIRST(&tsf->iframes))) {
      TAILQ_REMOVE(&tsf->iframes, ti, link);
      free(ti);
    }
    while ((tid = TAILQ_FIRST(&tsf->sstart))) {
      TAILQ_REMOVE(&tsf->sstart, tid, link);
      sm = tid->data;
      streaming_msg_free(sm);
      free(tid);
    }
    free(tsf->path);
    free(tsf->ram);
    free(tsf);

    pthread_mutex_lock(&timeshift_reaper_lock);
  }
  pthread_mutex_unlock(&timeshift_reaper_lock);
  tvhtrace("timeshift", "reaper thread exit");
  return NULL;
}
Beispiel #4
0
static void timeshift_reaper_remove ( timeshift_file_t *tsf )
{
  if (tvhtrace_enabled()) {
    if (tsf->path)
      tvhtrace("timeshift", "queue file for removal %s", tsf->path);
    else
      tvhtrace("timeshift", "queue file for removal - RAM segment time %li", (long)tsf->time);
  }
  pthread_mutex_lock(&timeshift_reaper_lock);
  TAILQ_INSERT_TAIL(&timeshift_reaper_list, tsf, link);
  pthread_cond_signal(&timeshift_reaper_cond);
  pthread_mutex_unlock(&timeshift_reaper_lock);
}
/*
 * Output packet
 */
static int _timeshift_read
  ( timeshift_t *ts, timeshift_seek_t *seek,
    streaming_message_t **sm, int *wait )
{
  timeshift_file_t *tsf = seek->file;
  ssize_t r;
  off_t off = 0;

  *sm = NULL;

  if (tsf) {

    /* Open file */
    if (tsf->rfd < 0 && !tsf->ram) {
      tsf->rfd = tvh_open(tsf->path, O_RDONLY, 0);
      tvhtrace(LS_TIMESHIFT, "ts %d open file %s (fd %i)", ts->id, tsf->path, tsf->rfd);
      if (tsf->rfd < 0)
        return -1;
    }
    if (tsf->rfd >= 0)
      if ((off = lseek(tsf->rfd, tsf->roff, SEEK_SET)) != tsf->roff)
        tvherror(LS_TIMESHIFT, "ts %d seek to %s failed (off %"PRId64" != %"PRId64"): %s",
                 ts->id, tsf->path, (int64_t)tsf->roff, (int64_t)off, strerror(errno));

    /* Read msg */
    r = _read_msg(tsf, -1, sm);
    if (r < 0) {
      streaming_message_t *e = streaming_msg_create_code(SMT_STOP, SM_CODE_UNDEFINED_ERROR);
      streaming_target_deliver2(ts->output, e);
      tvhtrace(LS_TIMESHIFT, "ts %d seek to %jd (woff %jd) (fd %i)", ts->id, (intmax_t)off, (intmax_t)tsf->woff, tsf->rfd);
      tvherror(LS_TIMESHIFT, "ts %d could not read buffer", ts->id);
      return -1;
    }
    tvhtrace(LS_TIMESHIFT, "ts %d seek to %jd (fd %i) read msg %p/%"PRId64" (%"PRId64")",
             ts->id, (intmax_t)off, tsf->rfd, *sm, *sm ? (*sm)->sm_time : -1, (int64_t)r);

    /* Special case - EOF */
    if (r <= sizeof(size_t) || tsf->roff > tsf->size || *sm == NULL) {
      timeshift_file_get(seek->file); /* _read_close decreases file reference */
      _read_close(seek);
      _seek_set_file(seek, timeshift_filemgr_next(tsf, NULL, 0), 0);
      *wait     = 0;
      tvhtrace(LS_TIMESHIFT, "ts %d eof, seek->file %p (prev %p)", ts->id, seek->file, tsf);
      timeshift_filemgr_dump(ts);
    }
  }
  return 0;
}
Beispiel #6
0
void
linuxdvb_ca_enqueue_capmt(linuxdvb_ca_t *lca, uint8_t slot, const uint8_t *ptr,
                          int len, uint8_t list_mgmt, uint8_t cmd_id)
{
  linuxdvb_ca_capmt_t *lcc;
  int c = 1;

  if (!lca)
    return;

  if (lca->lca_capmt_query && cmd_id == CA_PMT_CMD_ID_OK_DESCRAMBLING)
    c = 2;

  while (c--) {
    lcc = calloc(1, sizeof(*lcc));

    if (!lcc)
      return;

    lcc->data = malloc(len);
    lcc->len = len;
    lcc->slot = slot;
    lcc->list_mgmt = list_mgmt;
    lcc->cmd_id = (c ? CA_PMT_CMD_ID_QUERY : cmd_id);
    memcpy(lcc->data, ptr, len);

    TAILQ_INSERT_TAIL(&lca->lca_capmt_queue, lcc, lcc_link);

    tvhtrace("en50221", "%s CAPMT enqueued (%s)", ca_pmt_cmd_id2str(lcc->cmd_id),
             ca_pmt_list_mgmt2str(lcc->list_mgmt));
  }

  gtimer_arm_ms(&lca->lca_capmt_queue_timer,
                linuxdvb_ca_process_capmt_queue, lca, 50);
}
/*
 * Send the status message
 */
static void timeshift_fill_status
  ( timeshift_t *ts, timeshift_status_t *status, int64_t current_time )
{
  int active = 0;
  int64_t start, end;

  start = _timeshift_first_time(ts, &active);
  end   = ts->buf_time;
  if (ts->state <= TS_LIVE) {
    current_time = end;
  } else {
    if (current_time < 0)
      current_time = 0;
    if (current_time > end)
      current_time = end;
  }
  status->full = ts->full;
  tvhtrace(LS_TIMESHIFT, "ts %d status start %"PRId64" end %"PRId64
                        " current %"PRId64" state %d",
           ts->id, start, end, current_time, ts->state);
  status->shift = ts_rescale_inv(end - current_time, 1000000);
  if (active) {
    status->pts_start = ts_rescale_inv(start, 1000000);
    status->pts_end   = ts_rescale_inv(end,   1000000);
  } else {
    status->pts_start = PTS_UNSET;
    status->pts_end   = PTS_UNSET;
  }
}
Beispiel #8
0
static void *
thread_wrapper ( void *p )
{
  struct thread_state *ts = p;
  sigset_t set;

#if defined(PLATFORM_LINUX)
  /* Set name */
  prctl(PR_SET_NAME, ts->name);
#elif defined(PLATFORM_FREEBSD)
  /* Set name of thread */
  pthread_set_name_np(pthread_self(), ts->name);
#elif defined(PLATFORM_DARWIN)
  pthread_setname_np(ts->name);
#endif

  sigemptyset(&set);
  sigaddset(&set, SIGTERM);
  pthread_sigmask(SIG_UNBLOCK, &set, NULL);

  signal(SIGTERM, doexit);

  /* Run */
  tvhtrace("thread", "created thread %ld [%s / %p(%p)]",
           (long)pthread_self(), ts->name, ts->run, ts->arg);
  void *r = ts->run(ts->arg);
  free(ts);

  return r;
}
Beispiel #9
0
/*
 * Process directory
 *
 * Note: should we follow symlinks?
 */
static void
scanfile_load_dir
  ( const char *path, const char *type, int lvl )
{
  char p[256];
  fb_dir *dir;
  fb_dirent *de;
  tvhtrace("scanfile", "load dir %s", path);

  if (lvl >= 3) return;
  if (!(dir = fb_opendir(path))) return;
  lvl++;
  
  while ((de = fb_readdir(dir))) {
    if (*de->name == '.') continue;
    if (de->type == FB_DIR) {
      snprintf(p, sizeof(p), "%s/%s", path, de->name);
      scanfile_load_dir(p, de->name, lvl+1);
    } else if (type) {
      scanfile_load_file(type, dir, de->name);
    }
  }

  fb_closedir(dir);
}
Beispiel #10
0
/*
 * Process mux entry
 */
static void
scanfile_load_one ( scanfile_network_t *net, const char *line )
{
  int r = 1;
  dvb_mux_conf_t *mux = calloc(1, sizeof(dvb_mux_conf_t));
  
  switch (line[0]) {
    case 'A':
      r = scanfile_load_atsc(mux, line+1);
      break;
    case 'T':
      r = scanfile_load_dvbt(mux, line+1);
      break;
    case 'S':
      r = scanfile_load_dvbs(mux, line+1);
      break;
    case 'C':
      r = scanfile_load_dvbc(mux, line+1);
      break;
  }

  tvhtrace("scanfile", "[%s] %s", line, r ? "FAIL" : "OK");
  if (r) {
    free(mux);
  } else {
    LIST_INSERT_HEAD(&net->sfn_muxes, mux, dmc_link);
  }
}
Beispiel #11
0
/*
 * Create/Find region entry
 *
 * TODO: not sure why I didn't use RB here!
 */
static scanfile_region_t *
scanfile_region_create 
  ( const char *type, const char *id, const char *desc )
{
  scanfile_region_t *reg;
  scanfile_region_list_t *list = NULL;
  if      (!strcmp(type, "dvb-s")) list = &scanfile_regions_DVBS;
  else if (!strcmp(type, "dvb-t")) list = &scanfile_regions_DVBT;
  else if (!strcmp(type, "dvb-c")) list = &scanfile_regions_DVBC;
  else if (!strcmp(type, "atsc"))  list = &scanfile_regions_ATSC;
  if (!list) return NULL;

  LIST_FOREACH(reg, list, sfr_link) {
    if (!strcmp(reg->sfr_id, id)) break;
  }

  if (!reg) {
    tvhtrace("scanfile", "%s region %s created", type, id);
    reg = calloc(1, sizeof(scanfile_region_t));
    reg->sfr_id   = strdup(id);
    reg->sfr_name = strdup(desc);
    LIST_INSERT_SORTED(list, reg, sfr_link, scanfile_region_cmp);
  }
  
  return reg;
}
Beispiel #12
0
static void
tvhcsa_csa_cbc_flush
  ( tvhcsa_t *csa, struct mpegts_service *s )
{
#if ENABLE_DVBCSA
  tvhtrace(LS_CSA, "%p: CSA flush - descramble packets for service \"%s\" MAX=%d even=%d odd=%d fill=%d",
           csa,((mpegts_service_t *)s)->s_dvb_svcname, csa->csa_cluster_size,csa->csa_fill_even,csa->csa_fill_odd,csa->csa_fill);

  if(csa->csa_fill_even) {
    csa->csa_tsbbatch_even[csa->csa_fill_even].data = NULL;
    dvbcsa_bs_decrypt(csa->csa_key_even, csa->csa_tsbbatch_even, 184);
    csa->csa_fill_even = 0;
  }
  if(csa->csa_fill_odd) {
    csa->csa_tsbbatch_odd[csa->csa_fill_odd].data = NULL;
    dvbcsa_bs_decrypt(csa->csa_key_odd, csa->csa_tsbbatch_odd, 184);
    csa->csa_fill_odd = 0;
  }

  ts_recv_packet2(s, csa->csa_tsbcluster, csa->csa_fill * 188);

  csa->csa_fill = 0;

#else
#error "Unknown CSA descrambler"
#endif
}
Beispiel #13
0
/*
 * Process mux entry
 */
static int
scanfile_load_one
  ( scanfile_network_t **net, const char *type, const char *name, const char *line )
{
  int r = 1;
  dvb_mux_conf_t *mux = malloc(sizeof(dvb_mux_conf_t));
  
  switch (line[0]) {
    case 'A':
      r = scanfile_load_atsc(mux, line+1);
      break;
    case 'T':
      r = scanfile_load_dvbt(mux, line+1);
      break;
    case 'S':
      r = scanfile_load_dvbs(mux, line+1);
      break;
    case 'C':
      r = scanfile_load_dvbc(mux, line+1);
      break;
  }

  tvhtrace("scanfile", "[%s] %s", line, r ? "FAIL" : "OK");
  if (r) {
    free(mux);
  } else {
    if (*net == NULL && scanfile_create_network(net, type, name, mux->dmc_fe_delsys)) {
      free(mux);
      return -1;
    }
    LIST_INSERT_HEAD(&(*net)->sfn_muxes, mux, dmc_link);
  }
  return 1;
}
Beispiel #14
0
static int
linuxdvb_ca_mmi_enq_cb(void *arg, uint8_t slot_id, uint16_t session_num,
                       uint8_t blind_answ, uint8_t exp_answ_len,
                       uint8_t *text, uint32_t text_size)
{
    linuxdvb_ca_t * lca = arg;
    char buffer[256];

    snprintf(buffer, sizeof(buffer), "%.*s", text_size, text);

    tvhlog(LOG_NOTICE, "en50221", "MMI enquiry from CAM in slot %u:  %s (%s%u digits)",
           slot_id, buffer, blind_answ ? "blind " : "" , exp_answ_len);

    if (lca->lca_pin_reply &&
        (strlen((char *) lca->lca_pin_str) == exp_answ_len) &&
        strstr((char *) buffer, lca->lca_pin_match_str))
    {
      tvhtrace("en50221", "answering to PIN enquiry");
      en50221_app_mmi_answ(lca->lca_mmi_resource, session_num,
                           MMI_ANSW_ID_ANSWER, (uint8_t *) lca->lca_pin_str,
                           exp_answ_len);
    }

    en50221_app_mmi_close(lca->lca_mmi_resource, session_num,
                          MMI_CLOSE_MMI_CMD_ID_IMMEDIATE, 0);

    return 0;
}
Beispiel #15
0
static void timeshift_reaper_remove ( timeshift_file_t *tsf )
{
  tvhtrace("timeshift", "queue file for removal %s", tsf->path);
  pthread_mutex_lock(&timeshift_reaper_lock);
  TAILQ_INSERT_TAIL(&timeshift_reaper_list, tsf, link);
  pthread_cond_signal(&timeshift_reaper_cond);
  pthread_mutex_unlock(&timeshift_reaper_lock);
}
Beispiel #16
0
/*
 * Connected
 */
static int
iptv_rtsp_header ( http_client_t *hc )
{
  iptv_mux_t *im = hc->hc_aux;
  rtsp_priv_t *rp;
  int r;

  if (im == NULL) {
    /* teardown (or teardown timeout) */
    if (hc->hc_cmd == RTSP_CMD_TEARDOWN) {
      pthread_mutex_lock(&global_lock);
      mtimer_arm_rel(&hc->hc_close_timer, iptv_rtsp_close_cb, hc, 0);
      pthread_mutex_unlock(&global_lock);
    }
    return 0;
  }

  if (hc->hc_cmd == RTSP_CMD_GET_PARAMETER && hc->hc_code != HTTP_STATUS_OK) {
    tvhtrace("iptv", "GET_PARAMETER command returned invalid error code %d for '%s', "
        "fall back to OPTIONS in keep alive loop.", hc->hc_code, im->mm_iptv_url_raw);
    hc->hc_rtsp_keep_alive_cmd = RTSP_CMD_OPTIONS;
    return 0;
  }

  if (hc->hc_code != HTTP_STATUS_OK) {
    tvherror("iptv", "invalid error code %d for '%s'", hc->hc_code, im->mm_iptv_url_raw);
    return 0;
  }

  rp = im->im_data;

  switch (hc->hc_cmd) {
  case RTSP_CMD_SETUP:
    r = rtsp_setup_decode(hc, 0);
    if (r >= 0) {
      rtsp_play(hc, rp->path, rp->query);
      rp->play = 1;
    }
    break;
  case RTSP_CMD_PLAY:
    // Now let's set peer port for RTCP
    // Use the HTTP host for sending RTCP reports, NOT the hc_rtp_dest (which is where the stream is sent)
    if (udp_connect(rp->rtcp_info->connection, "rtcp", hc->hc_host, hc->hc_rtcp_server_port)) {
        tvhlog(LOG_WARNING, "rtsp", "Can't connect to remote, RTCP receiver reports won't be sent");
    }
    hc->hc_cmd = HTTP_CMD_NONE;
    pthread_mutex_lock(&global_lock);
    iptv_input_mux_started(hc->hc_aux);
    mtimer_arm_rel(&rp->alive_timer, iptv_rtsp_alive_cb, im,
                   sec2mono(MAX(1, (hc->hc_rtp_timeout / 2) - 1)));
    pthread_mutex_unlock(&global_lock);
    break;
  default:
    break;
  }

  return 0;
}
Beispiel #17
0
static void *
mtimer_thread(void *aux)
{
  mtimer_t *mti;
  mti_callback_t *cb;
  int64_t now, next;
#if ENABLE_GTIMER_CHECK
  int64_t mtm;
  const char *id;
  const char *fcn;
#endif

  while (tvheadend_is_running()) {
    now = mdispatch_clock_update();

    /* Global monoclock timers */
    pthread_mutex_lock(&global_lock);

    next = now + sec2mono(3600);

    while((mti = LIST_FIRST(&mtimers)) != NULL) {
      
      if (mti->mti_expire > now) {
        next = mti->mti_expire;
        break;
      }

#if ENABLE_GTIMER_CHECK
      mtm = getmonoclock();
      id = mti->mti_id;
      fcn = mti->mti_fcn;
#endif
      cb = mti->mti_callback;

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

      cb(mti->mti_opaque);

#if ENABLE_GTIMER_CHECK
      mtm = getmonoclock() - mtm;
      if (mtm > 10000)
        tvhtrace("mtimer", "%s:%s duration %"PRId64"us", id, fcn, mtm);
#endif
    }

    /* Periodic updates */
    if (next > mtimer_periodic)
      next = mtimer_periodic;

    /* Wait */
    tvh_cond_timedwait(&mtimer_cond, &global_lock, next);
    pthread_mutex_unlock(&global_lock);
  }
  
  return NULL;
}
mpegts_mux_t *
tsfile_mux_create ( mpegts_network_t *mn )
{
  mpegts_mux_t *mm 
    = mpegts_mux_create1(NULL, mn, MPEGTS_ONID_NONE, MPEGTS_TSID_NONE, NULL);
  mm->mm_config_save = iptv_mux_config_save;
  tvhtrace("tsfile", "mm created %p", mm);
  return mm;
}
Beispiel #19
0
static int
linuxdvb_ca_mmi_close_cb(void *arg, uint8_t slot_id, uint16_t session_num,
                         uint8_t cmd_id, uint8_t delay)
{
    tvhtrace("en50221", "mmi close cb received for slot %u session_num %u "
             "cmd_id 0x%02x delay %u" , slot_id, session_num, cmd_id, delay);

    return 0;
}
Beispiel #20
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;
}
Beispiel #21
0
mpegts_mux_t *
tsfile_mux_create ( const char *uuid, mpegts_network_t *mn )
{
  mpegts_mux_t *mm 
    = mpegts_mux_create1(uuid, mn, MPEGTS_ONID_NONE, MPEGTS_TSID_NONE, NULL);
  mm->mm_config_save = iptv_mux_config_save;
  mm->mm_epg = MM_EPG_DISABLE;
  tvhtrace("tsfile", "mm created %p", mm);
  return mm;
}
Beispiel #22
0
int
tvhcsa_set_type( tvhcsa_t *csa, struct mpegts_service *s, int type )
{
  if (csa->csa_type == type)
    return 0;
  if (csa->csa_descramble)
    return -1;
  switch (type) {
  case DESCRAMBLER_CSA_CBC:
    csa->csa_descramble    = tvhcsa_csa_cbc_descramble;
    csa->csa_flush         = tvhcsa_csa_cbc_flush;
    csa->csa_keylen        = 8;
#if ENABLE_DVBCSA
    csa->csa_cluster_size  = dvbcsa_bs_batch_size();
#else
    csa->csa_cluster_size  = 0;
#endif
    csa->csa_fill_size  = 3 * csa->csa_cluster_size;
    tvhtrace(LS_CSA, "%p: service \"%s\" using CSA batch size = %d for decryption",
             csa, ((mpegts_service_t *)s)->s_dvb_svcname, csa->csa_cluster_size );

    csa->csa_tsbcluster    = malloc(csa->csa_fill_size * 188);
#if ENABLE_DVBCSA
    csa->csa_tsbbatch_even = malloc((csa->csa_cluster_size + 1) *
                                    sizeof(struct dvbcsa_bs_batch_s));
    csa->csa_tsbbatch_odd  = malloc((csa->csa_cluster_size + 1) *
                                    sizeof(struct dvbcsa_bs_batch_s));
    csa->csa_key_even      = dvbcsa_bs_key_alloc();
    csa->csa_key_odd       = dvbcsa_bs_key_alloc();
#endif
    break;
  case DESCRAMBLER_DES_NCB:
    csa->csa_priv          = des_get_priv_struct();
    csa->csa_descramble    = tvhcsa_des_ncb_descramble;
    csa->csa_flush         = tvhcsa_empty_flush;
    csa->csa_keylen        = 8;
    break;
  case DESCRAMBLER_AES_ECB:
    csa->csa_priv          = aes_get_priv_struct();
    csa->csa_descramble    = tvhcsa_aes_ecb_descramble;
    csa->csa_flush         = tvhcsa_empty_flush;
    csa->csa_keylen        = 8;
    break;
  case DESCRAMBLER_AES128_ECB:
    csa->csa_priv          = aes128_get_priv_struct();
    csa->csa_descramble    = tvhcsa_aes128_ecb_descramble;
    csa->csa_flush         = tvhcsa_empty_flush;
    csa->csa_keylen        = 16;
    break;
  default:
    assert(0);
  }
  csa->csa_type = type;
  return 0;
}
Beispiel #23
0
static int
linuxdvb_ca_rm_reply_cb(void *arg, uint8_t slot_id, uint16_t session_num,
                        uint32_t resource_id_count, uint32_t *_resource_ids)
{
    linuxdvb_ca_t * lca = arg;

    tvhtrace("en50221", "rm reply cb received for slot %d, count %u", slot_id,
             resource_id_count);

    uint32_t i;
    for(i=0; i< resource_id_count; i++) {
        tvhtrace("en50221", "CAM provided resource id: %08x", _resource_ids[i]);
    }

    if (en50221_app_rm_changed(lca->lca_rm_resource, session_num)) {
        tvherror("en50221", "failed to send RM reply on slot %u", slot_id);
    }

    return 0;
}
Beispiel #24
0
int
diseqc_voltage_off(int fe_fd)
{
  int err;
  
  tvhtrace("diseqc", "sending diseqc voltage off command");
  if ((err = ioctl(fe_fd, FE_SET_VOLTAGE, SEC_VOLTAGE_OFF))) {
    tvhlog(LOG_ERR, "diseqc", "error sending diseqc voltage off command");
    return err;
  }
  return 0;
}
Beispiel #25
0
static const char *
satip_rtsp_setup_find(const char *prefix, tvh2satip_t *tbl,
                      int src, const char *defval)
{
  while (tbl->t >= 0) {
    if (tbl->t == src)
     return tbl->s;
    tbl++;
  }
  tvhtrace("satip", "%s - cannot translate %d", prefix, src);
  return defval;
}
Beispiel #26
0
static int
linuxdvb_ca_session_cb (void *arg, int reason, uint8_t slot_id,
                        uint16_t session_num, uint32_t rid)
{
  linuxdvb_ca_t * lca = arg;

  if (reason == S_SCALLBACK_REASON_CAMCONNECTING) {
    tvhtrace("en50221", "0x%08x session %u connecting", rid, session_num);
    return 0;
  }

  if (reason == S_SCALLBACK_REASON_CAMCONNECTED) {
    tvhtrace("en50221", "0x%08x session %u connected", rid, session_num);
    switch(rid) {
      case EN50221_APP_RM_RESOURCEID:
        en50221_app_rm_enq(lca->lca_rm_resource, session_num);
        break;
      case EN50221_APP_AI_RESOURCEID:
      case TS101699_APP_AI_RESOURCEID:
      case CIPLUS13_APP_AI_RESOURCEID:
        lca->lca_ai_version = rid & 0x3f;
        lca->lca_ai_session_number = session_num;
        en50221_app_ai_enquiry(lca->lca_ai_resource, session_num);
        ciplus13_app_ai_data_rate_info(lca, lca->lca_high_bitrate_mode ?
                                       CIPLUS13_DATA_RATE_96_MBPS :
                                       CIPLUS13_DATA_RATE_72_MBPS );
        break;
      case EN50221_APP_CA_RESOURCEID:
        en50221_app_ca_info_enq(lca->lca_ca_resource, session_num);
        lca->lca_ca_session_number = session_num;
        break;
      case EN50221_APP_MMI_RESOURCEID:
      case EN50221_APP_DATETIME_RESOURCEID:
        break;
      default:
        tvhtrace("en50221", "session %u with unknown rid 0x%08x is connected",
                 session_num, rid);
    }
    return 0;
  }

  if (reason == S_SCALLBACK_REASON_CLOSE) {
    tvhtrace("en50221", "0x%08x session %u close", rid, session_num);
    switch(rid) {
      case EN50221_APP_CA_RESOURCEID:
        dvbcam_unregister_cam(lca, 0);
        lca->lca_cam_menu_string[0] = 0;
    }
    return 0;
  }

  if (reason == S_SCALLBACK_REASON_TC_CONNECT) {
    tvhtrace("en50221", "0x%08x session %u tc connect", rid, session_num);
    return 0;
  }

  tvhtrace("en50221", "unhandled session callback - reason %d slot_id %u "
           "session_num %u resource_id %x", reason, slot_id, session_num, rid);
  return 0;
}
Beispiel #27
0
static int
linuxdvb_ca_rm_changed_cb(void *arg, uint8_t slot_id,
                          uint16_t session_num)
{
    linuxdvb_ca_t * lca = arg;
    tvhtrace("en50221", "rm changed cb received for slot %d", slot_id);

    if (en50221_app_rm_enq(lca->lca_rm_resource, session_num)) {
        tvherror("en50221", "failed to send ENQ to slot %d", slot_id);
    }

    return 0;
}
Beispiel #28
0
/*
 * Add multiplex
 */
void tsfile_add_file ( const char *path )
{
  mpegts_input_t        *mi;
  mpegts_mux_t          *mm;
  tvhtrace("tsfile", "add file %s", path);

  /* Create logical instance */
  mm = tsfile_mux_create(&tsfile_network);
  
  /* Create physical instance (for each tuner) */
  LIST_FOREACH(mi, &tsfile_inputs, mi_global_link)
    tsfile_mux_instance_create(path, mi, mm);
}
Beispiel #29
0
static int
linuxdvb_ca_dt_enquiry_cb(void *arg, uint8_t slot_id, uint16_t session_num,
                          uint8_t response_int)
{
    linuxdvb_ca_t * lca = arg;
    tvhtrace("en50221", "datetime enquiry cb received for slot %d", slot_id);

    if (en50221_app_datetime_send(lca->lca_dt_resource, session_num, time(NULL), -1)) {
        tvherror("en50221", "Failed to send datetime to slot %d", slot_id);
    }

    return 0;
}
tsfile_mux_instance_t *
tsfile_mux_instance_create
  ( const char *path, mpegts_input_t *mi, mpegts_mux_t *mm )
{
#define tsfile_mux_instance_class mpegts_mux_instance_class
  tsfile_mux_instance_t *mmi =
    mpegts_mux_instance_create(tsfile_mux_instance, NULL, mi, mm);
#undef tsfile_mux_instance_class
  mmi->mmi_tsfile_path    = strdup(path);
  mmi->mmi_tsfile_pcr_pid = MPEGTS_PID_NONE;
  tvhtrace("tsfile", "mmi created %p path %s", mmi, mmi->mmi_tsfile_path);
  return mmi;
}