diff --git a/src/descrambler.h b/src/descrambler.h index 26143b3d..2d21103c 100755 --- a/src/descrambler.h +++ b/src/descrambler.h @@ -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, diff --git a/src/descrambler/capmt.c b/src/descrambler/capmt.c index 382223f1..cdee0a2e 100644 --- a/src/descrambler/capmt.c +++ b/src/descrambler/capmt.c @@ -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; diff --git a/src/descrambler/cwc.c b/src/descrambler/cwc.c index 9506c877..551a9ecf 100755 --- a/src/descrambler/cwc.c +++ b/src/descrambler/cwc.c @@ -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); diff --git a/src/descrambler/descrambler.c b/src/descrambler/descrambler.c index 32eed830..964dcf7e 100755 --- a/src/descrambler/descrambler.c +++ b/src/descrambler/descrambler.c @@ -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;