From: Jaroslav Kysela Date: Wed, 18 Nov 2015 08:31:22 +0000 (+0100) Subject: descrambler: unify, fix and improve the constcw handling, fixes #3313 X-Git-Tag: v4.2.1~1531 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=07d7af6f5799d2443212c5af99078a9075eace52;p=thirdparty%2Ftvheadend.git descrambler: unify, fix and improve the constcw handling, fixes #3313 --- diff --git a/data/conf/descrambler b/data/conf/descrambler index f9acf06b8..8caabfbc0 100644 --- a/data/conf/descrambler +++ b/data/conf/descrambler @@ -1,4 +1,10 @@ { + "const_cw" : [ + { + "name" : "BISS", + "caid" : "2600" + } + ], "quick_ecm" : [ { "name" : "Sky UK", diff --git a/src/descrambler.h b/src/descrambler.h index d5cabf56d..1886e13d0 100644 --- a/src/descrambler.h +++ b/src/descrambler.h @@ -68,6 +68,7 @@ typedef struct th_descrambler_runtime { uint32_t dr_quick_ecm:1; uint32_t dr_key:1; uint32_t dr_key_first:1; + uint32_t dr_key_const:1; uint8_t dr_key_index; uint8_t dr_key_valid; uint8_t dr_key_changed; diff --git a/src/descrambler/capmt.c b/src/descrambler/capmt.c index af6be2a17..67aab3cbe 100644 --- a/src/descrambler/capmt.c +++ b/src/descrambler/capmt.c @@ -195,7 +195,6 @@ typedef struct capmt_service { /* list of used ca-systems with ids and last ecm */ struct capmt_caid_ecm_list ct_caid_ecm; - int ct_constcw; /* fast flag */ /* current sequence number */ uint16_t ct_seq; @@ -1046,8 +1045,6 @@ capmt_ecm_reset(th_descrambler_t *th) { capmt_service_t *ct = (capmt_service_t *)th; - if (ct->ct_constcw) - return 1; /* keys will not change */ ct->td_keystate = DS_UNKNOWN; return 0; } @@ -1836,7 +1833,6 @@ capmt_caid_change(th_descrambler_t *td) cce->cce_providerid = c->providerid; cce->cce_service = t; LIST_INSERT_HEAD(&ct->ct_caid_ecm, cce, cce_link); - ct->ct_constcw |= c->caid == 0x2600 ? 1 : 0; change = 1; } } @@ -2126,7 +2122,6 @@ capmt_service_start(caclient_t *cac, service_t *s) cce->cce_providerid = c->providerid; cce->cce_service = t; LIST_INSERT_HEAD(&ct->ct_caid_ecm, cce, cce_link); - ct->ct_constcw |= c->caid == 0x2600 ? 1 : 0; change = 1; } } diff --git a/src/descrambler/cwc.c b/src/descrambler/cwc.c index f4b200f52..42ebc9b6d 100644 --- a/src/descrambler/cwc.c +++ b/src/descrambler/cwc.c @@ -151,7 +151,6 @@ typedef struct cwc_service { } ecm_state; LIST_HEAD(, ecm_pid) cs_pids; - int cs_constcw; } cwc_service_t; @@ -619,9 +618,6 @@ cwc_ecm_reset(th_descrambler_t *th) ecm_pid_t *ep; ecm_section_t *es; - if (ct->cs_constcw) - return 1; /* keys will not change */ - pthread_mutex_lock(&cwc->cwc_mutex); ct->td_keystate = DS_UNKNOWN; LIST_FOREACH(ep, &ct->cs_pids, ep_link) @@ -1515,7 +1511,6 @@ cwc_service_start(caclient_t *cac, service_t *t) ct->cs_channel = -1; ct->cs_mux = ((mpegts_service_t *)t)->s_dvb_mux; ct->ecm_state = ECM_INIT; - ct->cs_constcw = pcard->cs_ra.caid == 0x2600; td = (th_descrambler_t *)ct; snprintf(buf, sizeof(buf), "cwc-%s-%i-%04X", cwc->cwc_hostname, cwc->cwc_port, pcard->cs_ra.caid); diff --git a/src/descrambler/descrambler.c b/src/descrambler/descrambler.c index b63f82c3a..aebb0654d 100644 --- a/src/descrambler/descrambler.c +++ b/src/descrambler/descrambler.c @@ -31,6 +31,7 @@ #include "streaming.h" #define MAX_QUICK_ECM_ENTRIES 100 +#define MAX_CONSTCW_ENTRIES 100 typedef struct th_descrambler_data { TAILQ_ENTRY(th_descrambler_data) dd_link; @@ -41,6 +42,7 @@ typedef struct th_descrambler_data { TAILQ_HEAD(th_descrambler_queue, th_descrambler_data); uint16_t *quick_ecm_table = NULL; +uint16_t *constcw_table = NULL; /* * @@ -173,6 +175,20 @@ descrambler_init ( void ) if (quick_ecm_table) quick_ecm_table[idx] = 0; } + if ((q = htsmsg_get_list(c, "const_cw")) != NULL) { + HTSMSG_FOREACH(f, q) { + if (!(e = htsmsg_field_get_map(f))) continue; + if (idx + 1 >= MAX_CONSTCW_ENTRIES) continue; + if ((s = htsmsg_get_str(e, "caid")) == NULL) continue; + caid = strtol(s, NULL, 16); + tvhinfo("descrambler", "adding CAID %04X as constant crypto-word (%s)", caid, htsmsg_get_str(e, "name") ?: "unknown"); + if (!constcw_table) + constcw_table = malloc(sizeof(uint16_t) * MAX_CONSTCW_ENTRIES); + constcw_table[idx++] = caid; + } + if (constcw_table) + constcw_table[idx] = 0; + } htsmsg_destroy(c); } } @@ -183,6 +199,8 @@ descrambler_done ( void ) caclient_done(); free(quick_ecm_table); quick_ecm_table = NULL; + free(constcw_table); + constcw_table = NULL; } /* @@ -217,18 +235,28 @@ descrambler_service_start ( service_t *t ) { th_descrambler_runtime_t *dr; elementary_stream_t *st; + caid_t *ca; + int count, constcw = 0; + uint16_t *p; if (t->s_scrambled_pass) return; if (!((mpegts_service_t *)t)->s_dvb_forcecaid) { - TAILQ_FOREACH(st, &t->s_filt_components, es_filt_link) - if (LIST_FIRST(&st->es_caids) != NULL) - break; + count = 0; + TAILQ_FOREACH(st, &t->s_filt_components, es_filt_link) { + LIST_FOREACH(ca, &st->es_caids, link) + for (p = quick_ecm_table; *p; p++) + if (ca->caid == *p) { + constcw = 1; + break; + } + count++; + } /* Do not run descrambler on FTA channels */ - if (!st) + if (count == 0) return; } @@ -240,6 +268,9 @@ descrambler_service_start ( service_t *t ) TAILQ_INIT(&dr->dr_queue); dr->dr_key_index = 0xff; dr->dr_key_interval = 10; + dr->dr_key_const = constcw; + if (constcw) + tvhtrace("descrambler", "using constcw for \"%s\"", t->s_nicename); dr->dr_skip = 0; tvhcsa_init(&dr->dr_csa); } @@ -366,10 +397,11 @@ descrambler_keys ( th_descrambler_t *td, int type, if (td2 != td && td2->td_keystate == DS_RESOLVED) { tvhlog(LOG_DEBUG, "descrambler", "Already has a key from %s for service \"%s\", " - "ignoring key from \"%s\"", + "ignoring key from \"%s\"%s", td2->td_nicename, ((mpegts_service_t *)td2->td_service)->s_dvb_svcname, - td->td_nicename); + td->td_nicename, + dr->dr_key_const ? " (const)" : ""); td->td_keystate = DS_IDLE; if (td->td_ecm_idle) td->td_ecm_idle(td); @@ -394,9 +426,10 @@ descrambler_keys ( th_descrambler_t *td, int type, if (j) { if (td->td_keystate != DS_RESOLVED) tvhlog(LOG_DEBUG, "descrambler", - "Obtained keys from %s for service \"%s\"", + "Obtained keys from %s for service \"%s\"%s", td->td_nicename, - ((mpegts_service_t *)t)->s_dvb_svcname); + ((mpegts_service_t *)t)->s_dvb_svcname, + dr->dr_key_const ? " (const)" : ""); if (dr->dr_csa.csa_keylen == 8) { tvhtrace("descrambler", "Obtained keys " "%02X%02X%02X%02X%02X%02X%02X%02X:%02X%02X%02X%02X%02X%02X%02X%02X" @@ -425,9 +458,10 @@ descrambler_keys ( th_descrambler_t *td, int type, td->td_service->s_descrambler = td; } else { tvhlog(LOG_DEBUG, "descrambler", - "Empty keys received from %s for service \"%s\"", + "Empty keys received from %s for service \"%s\"%s", td->td_nicename, - ((mpegts_service_t *)t)->s_dvb_svcname); + ((mpegts_service_t *)t)->s_dvb_svcname, + dr->dr_key_const ? " (const)" : ""); } fin: @@ -530,6 +564,9 @@ static inline int key_late( th_descrambler_runtime_t *dr, uint8_t ki, time_t timestamp ) { uint8_t kidx = (ki & 0x40) >> 6; + /* constcw - do not handle keys */ + if (dr->dr_key_const) + return 0; /* required key is older than previous? */ if (dr->dr_key_timestamp[kidx] < dr->dr_key_timestamp[kidx^1]) { /* but don't take in account the keys modified just now */