Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
descrambler: unify, fix and improve the constcw handling, fixes #3313
  • Loading branch information
perexg committed Nov 18, 2015
1 parent ee9b6da commit 07d7af6
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 20 deletions.
6 changes: 6 additions & 0 deletions data/conf/descrambler
@@ -1,4 +1,10 @@
{
"const_cw" : [
{
"name" : "BISS",
"caid" : "2600"
}
],
"quick_ecm" : [
{
"name" : "Sky UK",
Expand Down
1 change: 1 addition & 0 deletions src/descrambler.h
Expand Up @@ -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;
Expand Down
5 changes: 0 additions & 5 deletions src/descrambler/capmt.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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;
}
}
Expand Down
5 changes: 0 additions & 5 deletions src/descrambler/cwc.c
Expand Up @@ -151,7 +151,6 @@ typedef struct cwc_service {
} ecm_state;

LIST_HEAD(, ecm_pid) cs_pids;
int cs_constcw;

} cwc_service_t;

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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);
Expand Down
57 changes: 47 additions & 10 deletions src/descrambler/descrambler.c
Expand Up @@ -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;
Expand All @@ -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;

/*
*
Expand Down Expand Up @@ -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);
}
}
Expand All @@ -183,6 +199,8 @@ descrambler_done ( void )
caclient_done();
free(quick_ecm_table);
quick_ecm_table = NULL;
free(constcw_table);
constcw_table = NULL;
}

/*
Expand Down Expand Up @@ -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;

}
Expand All @@ -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);
}
Expand Down Expand Up @@ -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);
Expand All @@ -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"
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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 */
Expand Down

0 comments on commit 07d7af6

Please sign in to comment.