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; } }
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); } }