descrambler: improve the ECM handling
- for constcw (CAID 2600) do not expect any key change - when the stream is broken, try to issue new ECM request Note: The TS data might be wrong (which may cause the ECM late situations). This patch tries to ask for new ECM to be sure that the keys are correct. The constcw specific code is just an optimization. The new ECM request is not required for it.
This commit is contained in:
parent
41a6af0c76
commit
f0b284065d
4 changed files with 62 additions and 6 deletions
|
@ -51,6 +51,7 @@ typedef struct th_descrambler {
|
|||
|
||||
void (*td_stop) (struct th_descrambler *d);
|
||||
void (*td_caid_change)(struct th_descrambler *d);
|
||||
int (*td_ecm_reset) (struct th_descrambler *d);
|
||||
|
||||
} th_descrambler_t;
|
||||
|
||||
|
|
|
@ -182,6 +182,7 @@ 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 */
|
||||
|
||||
tvhcsa_t ct_csa;
|
||||
|
||||
|
@ -935,6 +936,17 @@ capmt_abort(capmt_t *capmt, int keystate)
|
|||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
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;
|
||||
}
|
||||
|
||||
static void
|
||||
capmt_process_key(capmt_t *capmt, uint8_t adapter, uint16_t seq,
|
||||
const uint8_t *even, const uint8_t *odd,
|
||||
|
@ -1538,6 +1550,7 @@ capmt_caid_change(th_descrambler_t *td)
|
|||
cce->cce_ecmpid = st->es_pid;
|
||||
cce->cce_providerid = c->providerid;
|
||||
LIST_INSERT_HEAD(&ct->ct_caid_ecm, cce, cce_link);
|
||||
ct->ct_constcw |= c->caid == 0x2600 ? 1 : 0;
|
||||
change = 1;
|
||||
}
|
||||
}
|
||||
|
@ -1812,6 +1825,7 @@ capmt_service_start(service_t *s)
|
|||
cce->cce_ecmpid = st->es_pid;
|
||||
cce->cce_providerid = c->providerid;
|
||||
LIST_INSERT_HEAD(&ct->ct_caid_ecm, cce, cce_link);
|
||||
ct->ct_constcw |= c->caid == 0x2600 ? 1 : 0;
|
||||
change = 1;
|
||||
}
|
||||
}
|
||||
|
@ -1826,6 +1840,7 @@ capmt_service_start(service_t *s)
|
|||
td->td_service = s;
|
||||
td->td_stop = capmt_service_destroy;
|
||||
td->td_caid_change = capmt_caid_change;
|
||||
td->td_ecm_reset = capmt_ecm_reset;
|
||||
LIST_INSERT_HEAD(&t->s_descramblers, td, td_service_link);
|
||||
|
||||
LIST_INSERT_HEAD(&capmt->capmt_services, ct, ct_link);
|
||||
|
|
|
@ -147,6 +147,7 @@ typedef struct cwc_service {
|
|||
tvhcsa_t cs_csa;
|
||||
|
||||
LIST_HEAD(, ecm_pid) cs_pids;
|
||||
int cs_constcw;
|
||||
|
||||
} cwc_service_t;
|
||||
|
||||
|
@ -692,7 +693,17 @@ cwc_send_login(cwc_t *cwc)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
cwc_ecm_reset(th_descrambler_t *th)
|
||||
{
|
||||
cwc_service_t *ct = (cwc_service_t *)th;
|
||||
|
||||
if (ct->cs_constcw)
|
||||
return 1; /* keys will not change */
|
||||
ct->td_keystate = DS_UNKNOWN;
|
||||
ct->ecm_state = ECM_RESET;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_ecm_reply(cwc_service_t *ct, ecm_section_t *es, uint8_t *msg,
|
||||
|
@ -1991,6 +2002,7 @@ cwc_service_start(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->cwc_caid == 0x2600;
|
||||
|
||||
td = (th_descrambler_t *)ct;
|
||||
tvhcsa_init(td->td_csa = &ct->cs_csa);
|
||||
|
@ -1998,6 +2010,7 @@ cwc_service_start(service_t *t)
|
|||
td->td_nicename = strdup(buf);
|
||||
td->td_service = t;
|
||||
td->td_stop = cwc_service_destroy;
|
||||
td->td_ecm_reset = cwc_ecm_reset;
|
||||
LIST_INSERT_HEAD(&t->s_descramblers, td, td_service_link);
|
||||
|
||||
LIST_INSERT_HEAD(&cwc->cwc_services, ct, cs_link);
|
||||
|
|
|
@ -222,6 +222,30 @@ fin:
|
|||
pthread_mutex_unlock(&t->s_stream_mutex);
|
||||
}
|
||||
|
||||
static void
|
||||
descrambler_flush_table_data( service_t *t )
|
||||
{
|
||||
mpegts_service_t *ms = (mpegts_service_t *)t;
|
||||
mpegts_mux_t *mux = ms->s_dvb_mux;
|
||||
descrambler_table_t *dt;
|
||||
descrambler_section_t *ds;
|
||||
|
||||
if (mux == NULL)
|
||||
return;
|
||||
tvhtrace("descrabler", "flush table data for service \"%s\"", ms->s_dvb_svcname);
|
||||
pthread_mutex_lock(&mux->mm_descrambler_lock);
|
||||
TAILQ_FOREACH(dt, &mux->mm_descrambler_tables, link) {
|
||||
if (dt->table == NULL || dt->table->mt_service != ms)
|
||||
continue;
|
||||
TAILQ_FOREACH(ds, &dt->sections, link) {
|
||||
free(ds->last_data);
|
||||
ds->last_data = NULL;
|
||||
ds->last_data_len = 0;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&mux->mm_descrambler_lock);
|
||||
}
|
||||
|
||||
static inline void
|
||||
key_update( th_descrambler_runtime_t *dr, uint8_t key )
|
||||
{
|
||||
|
@ -238,7 +262,7 @@ descrambler_descramble ( service_t *t,
|
|||
#define KEY_MASK(k) (((k) & 0x40) + 0x40) /* 0x40 (for even) or 0x80 (for odd) */
|
||||
th_descrambler_t *td;
|
||||
th_descrambler_runtime_t *dr = t->s_descramble;
|
||||
int count, failed, off, size;
|
||||
int count, failed, off, size, flush_data = 0;
|
||||
uint8_t *tsb2, ki;
|
||||
|
||||
lock_assert(&t->s_stream_mutex);
|
||||
|
@ -270,7 +294,8 @@ descrambler_descramble ( service_t *t,
|
|||
((mpegts_service_t *)t)->s_dvb_svcname);
|
||||
if (dr->dr_ecm_key_time + 2 < dr->dr_key_start) {
|
||||
sbuf_cut(&dr->dr_buf, off);
|
||||
goto idle;
|
||||
if (!td->td_ecm_reset(td))
|
||||
goto next;
|
||||
}
|
||||
key_update(dr, ki);
|
||||
}
|
||||
|
@ -300,7 +325,8 @@ descrambler_descramble ( service_t *t,
|
|||
tvhtrace("descrambler", "ECM late (%ld seconds) for service \"%s\"",
|
||||
dispatch_clock - dr->dr_ecm_key_time,
|
||||
((mpegts_service_t *)t)->s_dvb_svcname);
|
||||
goto idle;
|
||||
if (!td->td_ecm_reset(td))
|
||||
goto next;
|
||||
}
|
||||
key_update(dr, ki);
|
||||
}
|
||||
|
@ -310,9 +336,8 @@ descrambler_descramble ( service_t *t,
|
|||
tsb);
|
||||
dr->dr_last_descramble = dispatch_clock;
|
||||
return 1;
|
||||
idle:
|
||||
td->td_keystate = DS_IDLE;
|
||||
failed++;
|
||||
next:
|
||||
flush_data = 1;
|
||||
continue;
|
||||
}
|
||||
if (dr->dr_ecm_start) { /* ECM sent */
|
||||
|
@ -344,6 +369,8 @@ idle:
|
|||
sbuf_append(&dr->dr_buf, tsb, 188);
|
||||
}
|
||||
}
|
||||
if (flush_data)
|
||||
descrambler_flush_table_data(t);
|
||||
if (dr->dr_last_descramble + 25 < dispatch_clock)
|
||||
return -1;
|
||||
if (count && count == failed)
|
||||
|
|
Loading…
Add table
Reference in a new issue