示例#1
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(LS_EN50221, "%s CAPMT enqueued (%s)", ca_pmt_cmd_id2str(lcc->cmd_id),
             ca_pmt_list_mgmt2str(lcc->list_mgmt));
  }

  mtimer_arm_rel(&lca->lca_capmt_queue_timer,
                 linuxdvb_ca_process_capmt_queue, lca, ms2mono(50));
}
示例#2
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);
  }
}