descrambler: move some of the reader logic to the common code

This commit is contained in:
Jaroslav Kysela 2014-06-09 22:07:20 +02:00
parent 11bd63d590
commit 2a4d765e1c
4 changed files with 68 additions and 48 deletions

View file

@ -37,6 +37,8 @@ struct mpegts_mux;
typedef struct th_descrambler {
LIST_ENTRY(th_descrambler) td_service_link;
char *td_nicename;
enum {
DS_UNKNOWN,
DS_RESOLVED,

View file

@ -739,6 +739,7 @@ capmt_service_destroy(th_descrambler_t *td)
pthread_mutex_unlock(&capmt->capmt_mutex);
tvhcsa_destroy(&ct->ct_csa);
free(ct->td_nicename);
free(ct);
}
@ -1660,6 +1661,7 @@ capmt_service_start(service_t *s)
mpegts_service_t *t = (mpegts_service_t*)s;
elementary_stream_t *st;
int tuner = -1, i, change;
char buf[512];
lock_assert(&global_lock);
@ -1748,6 +1750,10 @@ capmt_service_start(service_t *s)
td = (th_descrambler_t *)ct;
tvhcsa_init(td->td_csa = &ct->ct_csa);
snprintf(buf, sizeof(buf), "capmt-%s-%i",
capmt->capmt_sockfile,
capmt->capmt_port);
td->td_nicename = strdup(buf);
td->td_service = s;
td->td_stop = capmt_service_destroy;
td->td_caid_change = capmt_caid_change;

View file

@ -687,9 +687,8 @@ handle_ecm_reply(cwc_service_t *ct, ecm_section_t *es, uint8_t *msg,
int len, int seq)
{
mpegts_service_t *t = (mpegts_service_t *)ct->td_service;
th_descrambler_t *td;
ecm_pid_t *ep, *epn;
cwc_service_t *ct2;
cwc_t *cwc2;
char chaninfo[32];
int i;
int64_t delay = (getmonoclock() - es->es_time) / 1000LL; // in ms
@ -709,25 +708,19 @@ handle_ecm_reply(cwc_service_t *ct, ecm_section_t *es, uint8_t *msg,
if (es->es_nok > 2) {
tvhlog(LOG_DEBUG, "cwc",
"Too many NOKs for service \"%s\"%s from %s:%i",
t->s_dvb_svcname, chaninfo, ct->cs_cwc->cwc_hostname,
ct->cs_cwc->cwc_port);
"Too many NOKs for service \"%s\"%s from %s",
t->s_dvb_svcname, chaninfo, ct->td_nicename);
goto forbid;
}
TAILQ_FOREACH(cwc2, &cwcs, cwc_link) {
LIST_FOREACH(ct2, &cwc2->cwc_services, cs_link) {
if (ct != ct2 && ct2->td_service == (service_t *)t &&
ct2->td_keystate == DS_RESOLVED) {
tvhlog(LOG_DEBUG, "cwc",
"NOK from %s:%i: Already has a key for service \"%s\", from %s:%i",
ct->cs_cwc->cwc_hostname, ct->cs_cwc->cwc_port,
t->s_dvb_svcname, ct2->cs_cwc->cwc_hostname, ct2->cs_cwc->cwc_port);
es->es_nok = 3; /* do not send more ECM requests */
goto forbid;
}
LIST_FOREACH(td, &t->s_descramblers, td_service_link)
if (td != (th_descrambler_t *)ct && td->td_keystate == DS_RESOLVED) {
tvhlog(LOG_DEBUG, "cwc",
"NOK from %s: Already has a key for service \"%s\", from %s",
ct->td_nicename, t->s_dvb_svcname, td->td_nicename);
es->es_nok = 3; /* do not send more ECM requests */
ct->td_keystate = DS_IDLE;
}
}
tvhlog(LOG_DEBUG, "cwc", "Received NOK for service \"%s\"%s (seqno: %d "
"Req delay: %"PRId64" ms)", t->s_dvb_svcname, chaninfo, seq, delay);
@ -746,8 +739,8 @@ forbid:
}
tvhlog(LOG_ERR, "cwc",
"Can not descramble service \"%s\", access denied (seqno: %d "
"Req delay: %"PRId64" ms)",
t->s_dvb_svcname, seq, delay);
"Req delay: %"PRId64" ms) from %s",
t->s_dvb_svcname, seq, delay, ct->td_nicename);
ct->td_keystate = DS_FORBIDDEN;
ct->ecm_state = ECM_RESET;
@ -762,7 +755,8 @@ forbid:
if(t->s_dvb_prefcapid == 0 || t->s_dvb_prefcapid != ct->cs_channel) {
t->s_dvb_prefcapid = ct->cs_channel;
tvhlog(LOG_DEBUG, "cwc", "Saving prefered PID %d", t->s_dvb_prefcapid);
tvhlog(LOG_DEBUG, "cwc", "Saving prefered PID %d for %s",
t->s_dvb_prefcapid, ct->td_nicename);
service_request_save((service_t*)t, 0);
}
@ -778,24 +772,10 @@ forbid:
msg[3 + 10],msg[3 + 11],msg[3 + 12],msg[3 + 13],msg[3 + 14],
msg[3 + 15], seq, delay);
TAILQ_FOREACH(cwc2, &cwcs, cwc_link) {
LIST_FOREACH(ct2, &cwc2->cwc_services, cs_link) {
if (ct != ct2 && ct2->td_service == (service_t *)t &&
ct2->td_keystate == DS_RESOLVED) {
ct->td_keystate = DS_IDLE;
tvhlog(LOG_DEBUG, "cwc",
"Already has a key for service \"%s\", from %s:%i",
t->s_dvb_svcname, ct2->cs_cwc->cwc_hostname, ct2->cs_cwc->cwc_port);
return;
}
}
}
if(ct->td_keystate != DS_RESOLVED)
tvhlog(LOG_DEBUG, "cwc",
"Obtained key for service \"%s\" in %"PRId64" ms, from %s:%i",
t->s_dvb_svcname, delay, ct->cs_cwc->cwc_hostname,
ct->cs_cwc->cwc_port);
"Obtained key for service \"%s\" in %"PRId64" ms, from %s",
t->s_dvb_svcname, delay, ct->td_nicename);
descrambler_keys((th_descrambler_t *)ct, msg + 3, msg + 3 + 8);
@ -809,7 +789,8 @@ forbid:
for(i = 0; i < 256; i++)
free(ep->ep_sections[i]);
LIST_REMOVE(ep, ep_link);
tvhlog(LOG_WARNING, "cwc", "Delete ECM (PID %d) for service \"%s\"", ep->ep_pid, t->s_dvb_svcname);
tvhlog(LOG_WARNING, "cwc", "Delete ECM (PID %d) for service \"%s\" from %s",
ep->ep_pid, t->s_dvb_svcname, ct->td_nicename);
free(ep);
ep = epn;
}
@ -1920,6 +1901,7 @@ cwc_service_destroy(th_descrambler_t *td)
LIST_REMOVE(ct, cs_link);
tvhcsa_destroy(&ct->cs_csa);
free(ct->td_nicename);
free(ct);
}
@ -1937,6 +1919,7 @@ cwc_service_start(service_t *t)
elementary_stream_t *st;
caid_t *c;
struct cs_card_data *pcard;
char buf[512];
extern const idclass_t mpegts_service_class;
if (!idnode_is_instance(&t->s_id, &mpegts_service_class))
@ -1975,6 +1958,8 @@ cwc_service_start(service_t *t)
td = (th_descrambler_t *)ct;
tvhcsa_init(td->td_csa = &ct->cs_csa);
snprintf(buf, sizeof(buf), "cwc-%s-%i", cwc->cwc_hostname, cwc->cwc_port);
td->td_nicename = strdup(buf);
td->td_service = t;
td->td_stop = cwc_service_destroy;
LIST_INSERT_HEAD(&t->s_descramblers, td, td_service_link);

View file

@ -176,9 +176,29 @@ void
descrambler_keys ( th_descrambler_t *td,
const uint8_t *even, const uint8_t *odd )
{
th_descrambler_runtime_t *dr = td->td_service->s_descramble;
service_t *t = td->td_service;
th_descrambler_runtime_t *dr;
th_descrambler_t *td2;
int i, j = 0;
if (t == NULL || (dr = t->s_descramble) == NULL) {
td->td_keystate = DS_FORBIDDEN;
return;
}
pthread_mutex_lock(&t->s_stream_mutex);
LIST_FOREACH(td2, &t->s_descramblers, td_service_link)
if (td2 != td && td->td_keystate == DS_RESOLVED) {
tvhlog(LOG_DEBUG, "descrambler",
"Already has a key from %s for service \"%s\", ignoring %s",
td->td_nicename,
((mpegts_service_t *)td2->td_service)->s_dvb_svcname,
((mpegts_service_t *)t)->s_dvb_svcname);
td->td_keystate = DS_IDLE;
goto fin;
}
for (i = 0; i < 8; i++)
if (even[i]) {
j++;
@ -192,18 +212,23 @@ descrambler_keys ( th_descrambler_t *td,
break;
}
if (j == 0) {
tvhlog(LOG_DEBUG, "descrambler", "Empty keys received for service \"%s\"",
((mpegts_service_t *)td->td_service)->s_dvb_svcname);
return;
if (j > 0) {
if (td->td_keystate != DS_RESOLVED)
tvhlog(LOG_DEBUG, "descrambler",
"Obtained key from %s for service \"%s\"",
td->td_nicename,
((mpegts_service_t *)t)->s_dvb_svcname);
dr->dr_ecm_key_time = dispatch_clock;
td->td_keystate = DS_RESOLVED;
} else {
tvhlog(LOG_DEBUG, "descrambler",
"Empty keys received from %s for service \"%s\"",
td->td_nicename,
((mpegts_service_t *)t)->s_dvb_svcname);
}
if (td->td_keystate != DS_RESOLVED)
tvhlog(LOG_DEBUG, "descrambler", "Obtained key for service \"%s\"",
((mpegts_service_t *)td->td_service)->s_dvb_svcname);
dr->dr_ecm_key_time = dispatch_clock;
td->td_keystate = DS_RESOLVED;
fin:
pthread_mutex_unlock(&t->s_stream_mutex);
}
static inline void
@ -224,6 +249,8 @@ descrambler_descramble ( service_t *t,
int count, failed, off, size;
uint8_t *tsb2;
lock_assert(&t->s_stream_mutex);
if (dr == NULL)
return -1;
count = failed = 0;