From 39708112cc9d8bed21715f518d89a2f48d1cc271 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Mon, 19 Nov 2018 14:39:14 +0100 Subject: [PATCH] dvbpsi: move the cat decoder from descrambler to a common place and use it everywhere --- src/descrambler/descrambler.c | 39 ++------------ src/descrambler/dvbcam.c | 49 ++++++++--------- src/input/mpegts.h | 4 ++ src/input/mpegts/dvb_psi.c | 77 ++++++++++++++++++--------- src/input/mpegts/mpegts_input.c | 93 ++++++++++++++++----------------- 5 files changed, 131 insertions(+), 131 deletions(-) diff --git a/src/descrambler/descrambler.c b/src/descrambler/descrambler.c index 506e464b0..cc2bc94fe 100644 --- a/src/descrambler/descrambler.c +++ b/src/descrambler/descrambler.c @@ -1532,8 +1532,9 @@ descrambler_flush_tables( mpegts_mux_t *mux ) } 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); @@ -1586,12 +1587,6 @@ void 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); @@ -1600,35 +1595,7 @@ descrambler_cat_data( mpegts_mux_t *mux, const uint8_t *data, int 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); } diff --git a/src/descrambler/dvbcam.c b/src/descrambler/dvbcam.c index 8fd1a5ab5..461a0146f 100644 --- a/src/descrambler/dvbcam.c +++ b/src/descrambler/dvbcam.c @@ -666,6 +666,27 @@ typedef struct __cat_update { 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 + /* * */ @@ -677,13 +698,8 @@ dvbcam_cat_update(caclient_t *cac, mpegts_mux_t *mux, const uint8_t *data, int l 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; @@ -708,24 +724,9 @@ dvbcam_cat_update(caclient_t *cac, mpegts_mux_t *mux, const uint8_t *data, int l 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); diff --git a/src/input/mpegts.h b/src/input/mpegts.h index 696e842f6..e95b15511 100644 --- a/src/input/mpegts.h +++ b/src/input/mpegts.h @@ -1065,6 +1065,10 @@ void mpegts_table_consistency_check(mpegts_mux_t *mm); 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 diff --git a/src/input/mpegts/dvb_psi.c b/src/input/mpegts/dvb_psi.c index e04d2df6c..0475384f2 100644 --- a/src/input/mpegts/dvb_psi.c +++ b/src/input/mpegts/dvb_psi.c @@ -1041,14 +1041,62 @@ end: /* * 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; @@ -1062,27 +1110,8 @@ dvb_cat_callback /* 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); diff --git a/src/input/mpegts/mpegts_input.c b/src/input/mpegts/mpegts_input.c index 0bcc603db..7fb5f4695 100644 --- a/src/input/mpegts/mpegts_input.c +++ b/src/input/mpegts/mpegts_input.c @@ -704,20 +704,59 @@ int mpegts_mps_weight(elementary_stream_t *st) 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, @@ -742,50 +781,10 @@ mpegts_input_cat_pass_callback 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); -- 2.47.2