static void process_pmt(int pmt_fd, struct gnutv_dvb_params *params)
{
	int size;
	uint8_t sibuf[4096];

	// read the section
	if ((size = read(pmt_fd, sibuf, sizeof(sibuf))) < 0) {
		return;
	}

	// parse section
	struct section *section = section_codec(sibuf, size);
	if (section == NULL) {
		return;
	}

	// parse section_ext
	struct section_ext *section_ext = section_ext_decode(section, 0);
	if (section_ext == NULL) {
		return;
	}
	if ((section_ext->table_id_ext != params->channel.service_id) ||
	    ((section_ext->version_number == data_pmt_version) &&
	     (section_ext->version_number == ca_pmt_version))) {
		return;
	}

	// parse PMT
	struct mpeg_pmt_section *pmt = mpeg_pmt_section_codec(section_ext);
	if (pmt == NULL) {
		return;
	}

	// do data handling
	if (section_ext->version_number != data_pmt_version) {
		if (gnutv_data_new_pmt(pmt) == 1)
			data_pmt_version = pmt->head.version_number;
	}

	// do ca handling
	if (section_ext->version_number != ca_pmt_version) {
		if (gnutv_ca_new_pmt(pmt) == 1)
			ca_pmt_version = pmt->head.version_number;
	}
}
示例#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);
  }
}