}
static void descrambler_cat_entry
- ( mpegts_mux_t *mux, uint16_t caid, uint32_t prov, uint16_t pid )
+ ( void *_mux, uint16_t caid, uint32_t prov, uint16_t pid )
{
+ mpegts_mux_t *mux = _mux;
descrambler_emm_t *emm;
caclient_caid_update(mux, caid, prov, pid, 1);
pthread_mutex_lock(&mux->mm_descrambler_lock);
descrambler_cat_data( mpegts_mux_t *mux, const uint8_t *data, int len )
{
descrambler_emm_t *emm;
- uint8_t dtag, dlen, dlen2;
- uint16_t caid = 0, pid = 0;
- uint32_t prov;
- const uint8_t *data2;
- int len2;
- card_type_t ctype;
tvhtrace(LS_DESCRAMBLER, "CAT data (len %d)", len);
tvhlog_hexdump(LS_DESCRAMBLER, data, len);
TAILQ_FOREACH(emm, &mux->mm_descrambler_emms, link)
emm->to_be_removed = 1;
pthread_mutex_unlock(&mux->mm_descrambler_lock);
- while (len > 2) {
- dtag = *data++;
- dlen = *data++;
- len -= 2;
- if (dtag != DVB_DESC_CA || len < 4 || dlen < 4)
- goto next;
- caid = (data[0] << 8) | data[1];
- pid = ((data[2] << 8) | data[3]) & 0x1fff;
- if (pid > 0) {
- ctype = detect_card_type(caid);
- descrambler_cat_entry(mux, caid, 0, pid);
- if (ctype == CARD_SECA) {
- dlen2 = dlen - 5;
- data2 = data + 5;
- len2 = len - 5;
- while (dlen2 >= 4 && len2 >= 4) {
- pid = ((data2[0] << 8) | data2[1]) & 0xfff;
- prov = (data2[2] << 8) | data2[3];
- descrambler_cat_entry(mux, caid, prov, pid);
- data2 += 4;
- len2 -= 4;
- dlen2 -= 4;
- }
- }
- }
-next:
- data += dlen;
- len -= dlen;
- }
+ dvb_cat_decode(data, len, descrambler_cat_entry, mux);
descrambler_cat_clean(mux);
}
mpegts_apids_t to_close;
} __cat_update_t;
+typedef struct __cat_entry {
+ mpegts_apids_t *pids;
+ mpegts_service_t *service;
+} __cat_entry_t;
+
+/*
+ *
+ */
+#if ENABLE_DDCI
+static void dvbcam_cat_entry
+ ( void *_aux, uint16_t caid, uint32_t prov, uint16_t pid )
+{
+ __cat_entry_t *aux = _aux;
+ if (!mpegts_pid_rexists(aux->pids, pid)) {
+ mpegts_pid_add(aux->pids, pid, 0);
+ tvhtrace(LS_DVBCAM, "%p: add EMM PID %d (%04X) for CAID %04X",
+ aux->service, pid, pid, caid);
+ }
+}
+#endif
+
/*
*
*/
int i, services_count;
dvbcam_active_service_t *as;
mpegts_apids_t pids;
- const uint8_t *data1;
- int len1;
- uint8_t dtag;
- uint8_t dlen;
- uint16_t caid;
- uint16_t pid;
mpegts_input_t *mi;
+ __cat_entry_t cat_aux;
if (len <= 0)
return;
mpegts_pid_init(&sp->to_open);
mpegts_pid_init(&sp->to_close);
mpegts_pid_init(&pids);
- data1 = data;
- len1 = len;
- while (len1 > 2) {
- dtag = *data1++;
- dlen = *data1++;
- len1 -= 2;
- if (dtag == DVB_DESC_CA && len1 >= 4 && dlen >= 4) {
- caid = (data1[0] << 8) | data1[1];
- pid = ((data1[2] << 8) | data1[3]) & 0x1fff;
- if (dvbcam_service_check_caid(as, caid) && pid != 0) {
- tvhtrace(LS_DVBCAM, "%p: add EMM PID %d (%04X) for CAID %04X",
- sp->service, pid, pid, caid);
- mpegts_pid_add(&pids, pid, 0);
- }
- }
- data1 += dlen;
- len1 -= dlen;
- }
+ cat_aux.pids = &pids;
+ cat_aux.service = sp->service;
+ dvb_cat_decode(data, len, dvbcam_cat_entry, &cat_aux);
mpegts_pid_compare(&pids, &as->cat_pids, &sp->to_open, &sp->to_close);
mpegts_pid_copy(&as->cat_pids, &pids);
mpegts_pid_done(&pids);
void dvb_bat_destroy(struct mpegts_table *mt);
+void dvb_cat_decode( const uint8_t *data, int len,
+ void (*add_emm)(void *aux, uint16_t caid, uint32_t prov, uint16_t pid),
+ void *aux );
+
int dvb_pat_callback
(struct mpegts_table *mt, const uint8_t *ptr, int len, int tableid);
int dvb_cat_callback
/*
* CAT processing
*/
+void
+dvb_cat_decode( const uint8_t *data, int len,
+ void (*add_emm)(void *aux, uint16_t caid, uint32_t prov, uint16_t pid),
+ void *aux )
+{
+ uint8_t dtag, dlen, dlen2;
+ uint16_t caid = 0, pid = 0;
+ uint32_t prov;
+ const uint8_t *data2;
+ int len2;
+ card_type_t ctype;
+
+ while (len > 2) {
+ dtag = *data++;
+ dlen = *data++;
+ len -= 2;
+ if (dtag != DVB_DESC_CA || len < 4 || dlen < 4)
+ goto next;
+ caid = (data[0] << 8) | data[1];
+ pid = ((data[2] << 8) | data[3]) & 0x1fff;
+ if (pid > 0) {
+ ctype = detect_card_type(caid);
+ add_emm(aux, caid, 0, pid);
+ if (ctype == CARD_SECA) {
+ dlen2 = dlen - 5;
+ data2 = data + 5;
+ len2 = len - 5;
+ while (dlen2 >= 4 && len2 >= 4) {
+ pid = ((data2[0] << 8) | data2[1]) & 0xfff;
+ prov = (data2[2] << 8) | data2[3];
+ add_emm(aux, caid, prov, pid);
+ data2 += 4;
+ len2 -= 4;
+ dlen2 -= 4;
+ }
+ }
+ }
+next:
+ data += dlen;
+ len -= dlen;
+ }
+}
+
+static void
+dvb_cat_entry(void *_mt, uint16_t caid, uint32_t prov, uint16_t pid)
+{
+ mpegts_table_t *mt = _mt;
+ tvhdebug(mt->mt_subsys, "%s: caid %04X (%d) pid %04X (%d)",
+ mt->mt_name, (uint16_t)caid, (uint16_t)caid, pid, pid);
+}
+
int
dvb_cat_callback
(mpegts_table_t *mt, const uint8_t *ptr, int len, int tableid)
{
int r, sect, last, ver;
- uint8_t dtag, dlen;
- uint16_t pid;
- uintptr_t caid;
mpegts_mux_t *mm = mt->mt_mux;
mpegts_psi_table_state_t *st = NULL;
/* Send CAT data for descramblers */
descrambler_cat_data(mm, ptr, len);
- while(len > 2) {
- dtag = *ptr++;
- dlen = *ptr++;
- len -= 2;
-
- switch(dtag) {
- case DVB_DESC_CA:
- if (len >= 4 && dlen >= 4) {
- caid = extract_2byte(ptr);
- pid = extract_pid(ptr + 2);
- tvhdebug(mt->mt_subsys, "%s: caid %04X (%d) pid %04X (%d)",
- mt->mt_name, (uint16_t)caid, (uint16_t)caid, pid, pid);
- }
- break;
- default:
- break;
- }
-
- ptr += dlen;
- len -= dlen;
- }
+ /* show CAT data */
+ dvb_cat_decode(ptr, len, dvb_cat_entry, mt);
/* Finish */
return dvb_table_end((mpegts_psi_table_t *)mt, st, sect);
return MPS_WEIGHT_ESOTHER + MIN(st->es_index, 49);
}
+typedef struct __cat_pass_aux {
+ mpegts_input_t *mi;
+ mpegts_mux_t *mm;
+ service_t *service;
+} __cat_pass_aux_t;
+
+static void
+mpegts_input_cat_pass_entry
+ (void *_aux, uint16_t caid, uint32_t prov, uint16_t pid)
+{
+ __cat_pass_aux_t *aux = _aux;
+ elementary_stream_t *es;
+ caid_t *c;
+
+ tvhdebug(LS_TBL_BASE, "cat: pass: caid %04X (%d) pid %04X (%d)",
+ (uint16_t)caid, (uint16_t)caid, pid, pid);
+ es = mpegts_input_open_service_pid(aux->mi, aux->mm, aux->service,
+ SCT_CAT, pid, MPS_WEIGHT_CAT, 1);
+ if (es) {
+ LIST_FOREACH(c, &es->es_caids, link) {
+ if (c->pid == pid) {
+ c->caid = caid;
+ c->delete_me = 0;
+ es->es_delete_me = 0;
+ break;
+ }
+ }
+ if (c == NULL) {
+ c = malloc(sizeof(caid_t));
+ c->caid = caid;
+ c->providerid = 0;
+ c->use = 1;
+ c->pid = pid;
+ c->delete_me = 0;
+ c->filter = 0;
+ LIST_INSERT_HEAD(&es->es_caids, c, link);
+ es->es_delete_me = 0;
+ }
+ }
+}
+
static int
mpegts_input_cat_pass_callback
(mpegts_table_t *mt, const uint8_t *ptr, int len, int tableid)
{
int r, sect, last, ver;
- uint8_t dtag, dlen;
- uint16_t pid;
- uintptr_t caid;
mpegts_mux_t *mm = mt->mt_mux;
mpegts_psi_table_state_t *st = NULL;
service_t *s = mt->mt_opaque;
mpegts_input_t *mi;
elementary_stream_t *es, *next;
caid_t *c, *cn;
+ __cat_pass_aux_t aux;
/* Start */
r = dvb_table_begin((mpegts_psi_table_t *)mt, ptr, len,
c->delete_me = 1;
}
- while(len > 2) {
- dtag = *ptr++;
- dlen = *ptr++;
- len -= 2;
-
- switch(dtag) {
- case DVB_DESC_CA:
- if (len >= 4 && dlen >= 4 && mm->mm_active) {
- caid = ( ptr[0] << 8) | ptr[1];
- pid = ((ptr[2] & 0x1f) << 8) | ptr[3];
- tvhdebug(LS_TBL_BASE, "cat: pass: caid %04X (%d) pid %04X (%d)",
- (uint16_t)caid, (uint16_t)caid, pid, pid);
- es = mpegts_input_open_service_pid(mi, mm, s, SCT_CAT, pid,
- MPS_WEIGHT_CAT, 1);
- if (es) {
- LIST_FOREACH(c, &es->es_caids, link) {
- if (c->pid == pid) {
- c->caid = caid;
- c->delete_me = 0;
- es->es_delete_me = 0;
- break;
- }
- }
- if (c == NULL) {
- c = malloc(sizeof(caid_t));
- c->caid = caid;
- c->providerid = 0;
- c->use = 1;
- c->pid = pid;
- c->delete_me = 0;
- c->filter = 0;
- LIST_INSERT_HEAD(&es->es_caids, c, link);
- es->es_delete_me = 0;
- }
- }
- }
- break;
- default:
- break;
- }
-
- ptr += dlen;
- len -= dlen;
- }
+ aux.mi = mi;
+ aux.mm = mm;
+ aux.service = s;
+ dvb_cat_decode(ptr, len, mpegts_input_cat_pass_entry, &aux);
for (es = TAILQ_FIRST(&s->s_components.set_all); es != NULL; es = next) {
next = TAILQ_NEXT(es, es_link);