Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
descrambler: reset ecm states for all readers when key is late
  • Loading branch information
perexg committed Feb 1, 2015
1 parent 4835c6c commit 3a92f1d
Showing 1 changed file with 39 additions and 24 deletions.
63 changes: 39 additions & 24 deletions src/descrambler/descrambler.c
Expand Up @@ -347,48 +347,69 @@ key_late( th_descrambler_runtime_t *dr, uint8_t ki )
return dr->dr_ecm_key_time + 2 < dr->dr_key_start;
}

static int
ecm_reset( service_t *t, th_descrambler_runtime_t *dr )
{
th_descrambler_t *td;
int ret = 0;

/* reset the reader ECM state */
LIST_FOREACH(td, &t->s_descramblers, td_service_link) {
if (!td->td_ecm_reset(td)) {
dr->dr_key_valid = 0;
ret = 1;
}
}
return ret;
}

int
descrambler_descramble ( service_t *t,
elementary_stream_t *st,
const uint8_t *tsb )
{
th_descrambler_t *td;
th_descrambler_runtime_t *dr = t->s_descramble;
int count, failed, off, size, flush_data = 0;
int count, failed, resolved, off, size, flush_data = 0;
uint8_t *tsb2, ki;

lock_assert(&t->s_stream_mutex);

if (dr == NULL)
return -1;

count = failed = 0;
count = failed = resolved = 0;
LIST_FOREACH(td, &t->s_descramblers, td_service_link) {
count++;
if (td->td_keystate == DS_FORBIDDEN) {
failed++;
continue;
switch (td->td_keystate) {
case DS_FORBIDDEN: failed++; break;
case DS_RESOLVED : resolved++; break;
default: break;
}
if (td->td_keystate != DS_RESOLVED)
continue;
}

if (resolved) {

/* update the keys */
if (dr->dr_key_changed) {
dr->dr_csa.csa_flush(&dr->dr_csa, (mpegts_service_t *)td->td_service);
dr->dr_csa.csa_flush(&dr->dr_csa, (mpegts_service_t *)t);
if (dr->dr_key_changed & 1)
tvhcsa_set_key_even(&dr->dr_csa, dr->dr_key_even);
if (dr->dr_key_changed & 2)
tvhcsa_set_key_odd(&dr->dr_csa, dr->dr_key_odd);
dr->dr_key_changed = 0;
}

/* process the queued TS packets */
if (dr->dr_buf.sb_ptr > 0) {
for (off = 0, size = dr->dr_buf.sb_ptr; off < size; off += 188) {
tsb2 = dr->dr_buf.sb_data + off;
ki = tsb2[3];
if ((ki & 0x80) != 0x00) {
if (key_valid(dr, ki) == 0) {
sbuf_cut(&dr->dr_buf, off);
goto next2;
flush_data = 1;
goto next;
}
if (dr->dr_key_index != (ki & 0x40) &&
dr->dr_key_start + 2 < dispatch_clock) {
Expand All @@ -397,23 +418,22 @@ descrambler_descramble ( service_t *t,
((mpegts_service_t *)t)->s_dvb_svcname);
if (key_late(dr, ki)) {
sbuf_cut(&dr->dr_buf, off);
if (!td->td_ecm_reset(td)) {
dr->dr_key_valid = 0;
if (ecm_reset(t, dr)) {
flush_data = 1;
goto next;
}
}
key_update(dr, ki);
}
}
dr->dr_csa.csa_descramble(&dr->dr_csa,
(mpegts_service_t *)td->td_service,
tsb2);
dr->dr_csa.csa_descramble(&dr->dr_csa, (mpegts_service_t *)t, tsb2);
}
if (off > 0)
service_reset_streaming_status_flags(t, TSS_NO_ACCESS);
sbuf_free(&dr->dr_buf);
}

/* check for key change */
ki = tsb[3];
if ((ki & 0x80) != 0x00) {
if (key_valid(dr, ki) == 0) {
Expand All @@ -422,7 +442,7 @@ descrambler_descramble ( service_t *t,
((mpegts_service_t *)t)->s_dvb_svcname,
(ki & 0x40) ? "odd stream key is not valid" :
"even stream key is not valid");
continue;
goto next;
}
if (dr->dr_key_index != (ki & 0x40) &&
dr->dr_key_start + 2 < dispatch_clock) {
Expand All @@ -433,24 +453,19 @@ 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);
if (!td->td_ecm_reset(td)) {
dr->dr_key_valid = 0;
if (ecm_reset(t, dr)) {
flush_data = 1;
goto next;
}
}
key_update(dr, ki);
}
}
dr->dr_csa.csa_descramble(&dr->dr_csa,
(mpegts_service_t *)td->td_service,
tsb);
dr->dr_csa.csa_descramble(&dr->dr_csa, (mpegts_service_t *)t, tsb);
service_reset_streaming_status_flags(t, TSS_NO_ACCESS);
return 1;
next:
flush_data = 1;
next2:
continue;
}
next:
if (dr->dr_ecm_start) { /* ECM sent */
ki = tsb[3];
if ((ki & 0x80) != 0x00) {
Expand Down

0 comments on commit 3a92f1d

Please sign in to comment.