From: Jaroslav Kysela Date: Tue, 21 Nov 2017 07:40:18 +0000 (+0100) Subject: descrambler: add DS_FATAL state, handle better TSS_NO_DESCRAMBLER flag X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d65c9d212fd8b4d2026ae63ae4452011cc12d7d3;p=thirdparty%2Ftvheadend.git descrambler: add DS_FATAL state, handle better TSS_NO_DESCRAMBLER flag --- diff --git a/src/descrambler.h b/src/descrambler.h index 42528cb83..b2d06fffa 100644 --- a/src/descrambler.h +++ b/src/descrambler.h @@ -46,6 +46,7 @@ typedef enum { DS_READY, DS_RESOLVED, DS_FORBIDDEN, + DS_FATAL, DS_IDLE } th_descrambler_keystate_t; @@ -92,6 +93,7 @@ typedef struct th_descrambler_runtime { int dr_ca_count; int dr_ca_resolved; int dr_ca_failed; + int dr_ca_fatal; uint32_t dr_external:1; uint32_t dr_skip:1; uint32_t dr_quick_ecm:1; diff --git a/src/descrambler/capmt.c b/src/descrambler/capmt.c index 22af8bca3..f7d93b4d7 100644 --- a/src/descrambler/capmt.c +++ b/src/descrambler/capmt.c @@ -193,6 +193,10 @@ typedef struct capmt_service { /* Elementary stream types */ uint8_t ct_types[MAX_PIDS]; uint8_t ct_type_sok[MAX_PIDS]; + + /* OK flag - seems that descrambling is going on */ + uint8_t ct_ok_flag; + mtimer_t ct_ok_timer; } capmt_service_t; /** @@ -840,6 +844,8 @@ capmt_service_destroy(th_descrambler_t *td) "%s: Removing CAPMT Server from service \"%s\" on adapter %d", capmt_name(capmt), s->s_dvb_svcname, ct->ct_adapter); + mtimer_disarm(&ct->ct_ok_timer); + pthread_mutex_lock(&capmt->capmt_mutex); /* send stop to client */ @@ -942,10 +948,10 @@ capmt_set_filter(capmt_t *capmt, int adapter, sbuf_t *sb, int offset) if (cce->cce_ecmpid == pid) { flags = CAPMT_MSG_FAST; t = cce->cce_service; - break; + goto service_found; } - if (t) break; } +service_found: if (t) { dmx_filter_t *pf = (dmx_filter_t *)sbuf_peek(sb, offset + 4); /* OK, probably ECM, but sometimes, it's shared */ @@ -958,9 +964,13 @@ capmt_set_filter(capmt_t *capmt, int adapter, sbuf_t *sb, int offset) if (i < DMX_FILTER_SIZE || pf->mode[0] || (pf->filter[0] & 0xf0) != 0x80 || - (pf->mask[0] & 0xf0) != 0xf0) + (pf->mask[0] & 0xf0) != 0xf0) { t = NULL; + flags = 0; + } } + if (t) + ct->ct_ok_flag = 1; cf->adapter = adapter; filter = &cf->dmx[filter_index]; @@ -1121,6 +1131,7 @@ capmt_process_key(capmt_t *capmt, uint8_t adapter, ca_info_t *cai, if (pid == 0) break; if (pid == pids[i]) { if (multipid) { + ct->ct_ok_flag = 1; descrambler_keys((th_descrambler_t *)ct, type, pid, even, odd); continue; } else if (ct->ct_type_sok[j]) @@ -1131,6 +1142,7 @@ capmt_process_key(capmt_t *capmt, uint8_t adapter, ca_info_t *cai, continue; found: + ct->ct_ok_flag = 1; descrambler_keys((th_descrambler_t *)ct, type, pid, even, odd); } pthread_mutex_unlock(&capmt->capmt_mutex); @@ -2127,6 +2139,15 @@ capmt_caid_change(th_descrambler_t *td) capmt_notify_server(capmt, ct, 1); } +static void +capmt_ok_timer_cb(void *aux) +{ + capmt_service_t *ct = aux; + + if (!ct->ct_ok_flag) + descrambler_change_keystate((th_descrambler_t *)ct, DS_FATAL, 1); +} + static void capmt_send_request(capmt_service_t *ct, int lm) { @@ -2290,6 +2311,8 @@ capmt_send_request(capmt_service_t *ct, int lm) capmt_name(capmt), t->s_dvb_svcname); capmt_queue_msg(capmt, adapter_num, sid, buf, pos, 0); + + mtimer_arm_rel(&ct->ct_ok_timer, capmt_ok_timer_cb, ct, sec2mono(3)/2); } static void diff --git a/src/descrambler/descrambler.c b/src/descrambler/descrambler.c index 3bf729809..ffa509be1 100644 --- a/src/descrambler/descrambler.c +++ b/src/descrambler/descrambler.c @@ -542,6 +542,7 @@ static struct strtab keystatetab[] = { { "READY", DS_READY }, { "RESOLVED", DS_RESOLVED }, { "FORBIDDEN", DS_FORBIDDEN }, + { "FATAL", DS_FATAL }, { "IDLE", DS_IDLE }, }; @@ -556,7 +557,7 @@ descrambler_change_keystate( th_descrambler_t *td, th_descrambler_keystate_t key { service_t *t = td->td_service; th_descrambler_runtime_t *dr; - int count = 0, failed = 0, resolved = 0; + int count = 0, fatal = 0, failed = 0, resolved = 0; if (td->td_keystate == keystate) return; @@ -576,6 +577,7 @@ descrambler_change_keystate( th_descrambler_t *td, th_descrambler_keystate_t key LIST_FOREACH(td, &t->s_descramblers, td_service_link) { count++; switch (td->td_keystate) { + case DS_FATAL: fatal++; break; case DS_FORBIDDEN: failed++; break; case DS_RESOLVED : resolved++; break; default: break; @@ -584,8 +586,9 @@ descrambler_change_keystate( th_descrambler_t *td, th_descrambler_keystate_t key dr->dr_ca_count = count; dr->dr_ca_resolved = resolved; dr->dr_ca_failed = failed; - tvhtrace(LS_DESCRAMBLER, "service \"%s\": %d descramblers (%d ok %d failed)", - t->s_nicename, count, resolved, failed); + dr->dr_ca_fatal = fatal; + tvhtrace(LS_DESCRAMBLER, "service \"%s\": %d descramblers (%d ok %d failed %d fatal)", + t->s_nicename, count, resolved, failed, fatal); if (lock) pthread_mutex_unlock(&t->s_stream_mutex); } @@ -1186,8 +1189,12 @@ queue: descrambler_flush_table_data(t); end: debug2("%p: end, %s", dr, keystr(tsb)); - if (dr->dr_ca_count > 0 && dr->dr_ca_count == dr->dr_ca_failed) - return -1; + if (dr->dr_ca_count > 0) { + if (dr->dr_ca_count == dr->dr_ca_fatal) + return 0; + if (dr->dr_ca_count == dr->dr_ca_failed) + return -1; + } return dr->dr_ca_count; } diff --git a/src/descrambler/dvbcam.c b/src/descrambler/dvbcam.c index 4569d9437..08cfd155e 100644 --- a/src/descrambler/dvbcam.c +++ b/src/descrambler/dvbcam.c @@ -535,6 +535,7 @@ dvbcam_cat_update(caclient_t *cac, mpegts_mux_t *mux, const uint8_t *data, int l mpegts_apids_t pids; const uint8_t *data1; int len1; + uint8_t dtag; uint8_t dlen; uint16_t caid; uint16_t pid; diff --git a/src/service.c b/src/service.c index 99a87705a..f0a30a320 100644 --- a/src/service.c +++ b/src/service.c @@ -1840,15 +1840,15 @@ service_tss2text(int flags) int tss2errcode(int tss) { + if(tss & TSS_NO_DESCRAMBLER) + return SM_CODE_NO_DESCRAMBLER; + if(tss & TSS_NO_ACCESS) return SM_CODE_NO_ACCESS; if(tss & TSS_TUNING) return SM_CODE_TUNING_FAILED; - if(tss & TSS_NO_DESCRAMBLER) - return SM_CODE_NO_DESCRAMBLER; - if(tss & (TSS_GRACEPERIOD|TSS_TIMEOUT)) return SM_CODE_NO_INPUT; diff --git a/src/subscriptions.c b/src/subscriptions.c index 22ffd8893..e55f0e0e3 100644 --- a/src/subscriptions.c +++ b/src/subscriptions.c @@ -613,7 +613,7 @@ subscription_input(void *opaque, streaming_message_t *sm) } if (sm->sm_type == SMT_SERVICE_STATUS && - (sm->sm_code & (TSS_TUNING|TSS_TIMEOUT|TSS_CA_CHECK))) { + (sm->sm_code & (TSS_TUNING|TSS_TIMEOUT|TSS_NO_DESCRAMBLER|TSS_CA_CHECK))) { error = tss2errcode(sm->sm_code); if (error != SM_CODE_OK) if (error != SM_CODE_NO_ACCESS ||