From: Jaroslav Kysela Date: Tue, 6 Oct 2015 18:41:14 +0000 (+0200) Subject: descrambler/htsp server: add descramble info message, fixes #2616 X-Git-Tag: v4.2.1~1973 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1aa7dddbd457e33947236d0bdd6e953babb24bc8;p=thirdparty%2Ftvheadend.git descrambler/htsp server: add descramble info message, fixes #2616 The sources are capmt (oscam's DVBAPI) ECM INFO and cwc (newcamd) client. The latest DVBAPI network protocol should be used to get this info. --- diff --git a/src/descrambler.h b/src/descrambler.h index 201c43630..f97395e44 100644 --- a/src/descrambler.h +++ b/src/descrambler.h @@ -150,6 +150,11 @@ void descrambler_caid_changed ( struct service *t ); int descrambler_resolved ( struct service *t, th_descrambler_t *ignore ); void descrambler_keys ( th_descrambler_t *t, int type, const uint8_t *even, const uint8_t *odd ); +void descrambler_notify ( th_descrambler_t *t, + uint16_t caid, uint32_t provid, + const char *cardsystem, uint16_t pid, uint32_t ecmtime, + uint16_t hops, const char *reader, const char *from, + const char *protocol ); int descrambler_descramble ( struct service *t, struct elementary_stream *st, const uint8_t *tsb, int len ); diff --git a/src/descrambler/capmt.c b/src/descrambler/capmt.c index fe4061b84..6cea5c712 100644 --- a/src/descrambler/capmt.c +++ b/src/descrambler/capmt.c @@ -1063,6 +1063,32 @@ capmt_process_key(capmt_t *capmt, uint8_t adapter, uint16_t seq, pthread_mutex_unlock(&capmt->capmt_mutex); } +static void +capmt_process_notify(capmt_t *capmt, uint8_t adapter, + uint16_t sid, uint16_t caid, uint32_t provid, + const char *cardsystem, uint16_t pid, uint32_t ecmtime, + uint16_t hops, const char *reader, const char *from, + const char *protocol ) +{ + mpegts_service_t *t; + capmt_service_t *ct; + + pthread_mutex_lock(&capmt->capmt_mutex); + LIST_FOREACH(ct, &capmt->capmt_services, ct_link) { + t = (mpegts_service_t *)ct->td_service; + + if (sid != t->s_dvb_service_id) + continue; + if (adapter != ct->ct_adapter) + continue; + + descrambler_notify((th_descrambler_t *)ct, caid, provid, + cardsystem, pid, ecmtime, hops, reader, from, + protocol); + } + pthread_mutex_unlock(&capmt->capmt_mutex); +} + static int capmt_msg_size(capmt_t *capmt, sbuf_t *sb, int offset) { @@ -1245,6 +1271,10 @@ capmt_analyze_cmd(capmt_t *capmt, int adapter, sbuf_t *sb, int offset) char *protocol = capmt_peek_str(sb, &offset2); uint8_t hops = sbuf_peek_u8(sb, offset2); + capmt_process_notify(capmt, adapter, sid, caid, provid, + cardsystem, pid, ecmtime, hops, reader, + from, protocol); + tvhlog(LOG_DEBUG, "capmt", "%s: ECM_INFO: adapter=%d sid=%d caid=%04X(%s) pid=%04X provid=%06X ecmtime=%d hops=%d reader=%s from=%s protocol=%s", capmt_name(capmt), adapter, sid, caid, cardsystem, pid, provid, ecmtime, hops, reader, from, protocol); diff --git a/src/descrambler/cwc.c b/src/descrambler/cwc.c index 52980293e..f722b435c 100644 --- a/src/descrambler/cwc.c +++ b/src/descrambler/cwc.c @@ -102,6 +102,8 @@ typedef struct ecm_section { int es_section; int es_channel; + uint16_t es_caid; + uint16_t es_provid; uint16_t es_seq; char es_nok; @@ -654,7 +656,7 @@ handle_ecm_reply(cwc_service_t *ct, ecm_section_t *es, uint8_t *msg, cwc_t *cwc = ct->cs_cwc; ecm_pid_t *ep; ecm_section_t *es2; - char chaninfo[32]; + char chaninfo[128]; int i; int64_t delay = (getmonoclock() - es->es_time) / 1000LL; // in ms @@ -794,6 +796,13 @@ forbid: descrambler_keys((th_descrambler_t *)ct, DESCRAMBLER_AES, msg + 3, msg + 3 + 16); pthread_mutex_lock(&cwc->cwc_mutex); } + + snprintf(chaninfo, sizeof(chaninfo), "%s:%i", cwc->cwc_hostname, cwc->cwc_port); + descrambler_notify((th_descrambler_t *)ct, + es->es_caid, es->es_provid, + caid2name(es->es_caid), + es->es_channel, delay, + 1, "", chaninfo, "newcamd"); } } @@ -1265,7 +1274,7 @@ cwc_table_input(void *opaque, int pid, const uint8_t *data, int len, int emm) struct cs_card_data *pcard = NULL; caid_t *c; uint16_t caid; - uint32_t providerid; + uint32_t provid; if (data == NULL) return; @@ -1337,7 +1346,7 @@ prefcapid_ok: found: caid = c->caid; - providerid = c->providerid; + provid = c->providerid; switch(data[0]) { case 0x80: @@ -1374,6 +1383,8 @@ found: if (es->es_keystate == ES_FORBIDDEN || es->es_keystate == ES_IDLE) break; + es->es_caid = caid; + es->es_provid = provid; es->es_channel = channel; es->es_pending = 1; es->es_resolved = 0; @@ -1384,7 +1395,7 @@ found: goto end; } - es->es_seq = cwc_send_msg(cwc, data, len, sid, 1, caid, providerid); + es->es_seq = cwc_send_msg(cwc, data, len, sid, 1, caid, provid); tvhlog(LOG_DEBUG, "cwc", "Sending ECM%s section=%d/%d, for service \"%s\" (seqno: %d)", diff --git a/src/descrambler/descrambler.c b/src/descrambler/descrambler.c index 47374bdac..d2c72adbf 100644 --- a/src/descrambler/descrambler.c +++ b/src/descrambler/descrambler.c @@ -28,6 +28,7 @@ #include "input.h" #include "input/mpegts/tsdemux.h" #include "dvbcam.h" +#include "streaming.h" #define MAX_QUICK_ECM_ENTRIES 100 @@ -168,6 +169,41 @@ descrambler_caid_changed ( service_t *t ) } } +void +descrambler_notify( th_descrambler_t *td, + uint16_t caid, uint32_t provid, + const char *cardsystem, uint16_t pid, uint32_t ecmtime, + uint16_t hops, const char *reader, const char *from, + const char *protocol ) +{ + mpegts_service_t *t = (mpegts_service_t *)td->td_service; + streaming_message_t *sm; + descramble_info_t *di; + + tvhlog(LOG_DEBUG, "descrambler", "info - service='%s' caid=%04X(%s) " + "provid=%06X ecmtime=%d hops=%d " + "reader=%s from=%s protocol=%s", + t->s_dvb_svcname, caid, cardsystem, provid, + ecmtime, hops, reader, from, protocol); + + sm = streaming_msg_create(SMT_DESCRAMBLE_INFO); + sm->sm_data = di = calloc(1, sizeof(*di)); + + di->pid = pid; + di->caid = caid; + di->provid = provid; + di->ecmtime = ecmtime; + di->hops = hops; + strncpy(di->cardsystem, cardsystem, sizeof(di->cardsystem)-1); + strncpy(di->reader, reader, sizeof(di->reader)-1); + strncpy(di->from, from, sizeof(di->protocol)-1); + strncpy(di->protocol, protocol, sizeof(di->protocol)-1); + + pthread_mutex_lock(&t->s_stream_mutex); + streaming_pad_deliver(&t->s_streaming_pad, sm); + pthread_mutex_unlock(&t->s_stream_mutex); +} + int descrambler_resolved( service_t *t, th_descrambler_t *ignore ) { diff --git a/src/dvr/dvr_rec.c b/src/dvr/dvr_rec.c index 47483fc41..1db0d75da 100644 --- a/src/dvr/dvr_rec.c +++ b/src/dvr/dvr_rec.c @@ -1190,6 +1190,7 @@ dvr_thread(void *aux) case SMT_SKIP: case SMT_SIGNAL_STATUS: case SMT_TIMESHIFT_STATUS: + case SMT_DESCRAMBLE_INFO: break; case SMT_EXIT: diff --git a/src/htsp_server.c b/src/htsp_server.c index fe6dd8f71..69f9cc8e3 100644 --- a/src/htsp_server.c +++ b/src/htsp_server.c @@ -65,7 +65,7 @@ static void *htsp_server, *htsp_server_2; -#define HTSP_PROTO_VERSION 23 +#define HTSP_PROTO_VERSION 24 #define HTSP_ASYNC_OFF 0x00 #define HTSP_ASYNC_ON 0x01 @@ -3720,6 +3720,34 @@ htsp_subscription_signal_status(htsp_subscription_t *hs, signal_status_t *sig) htsp_send_message(hs->hs_htsp, m, &hs->hs_htsp->htsp_hmq_qstatus); } +/** + * + */ +static void +htsp_subscription_descramble_info(htsp_subscription_t *hs, descramble_info_t *di) +{ + /* don't bother old clients */ + if (hs->hs_htsp->htsp_version < 24) + return; + + htsmsg_t *m = htsmsg_create_map(); + htsmsg_add_str(m, "method", "descrambleInfo"); + htsmsg_add_u32(m, "pid", di->pid); + htsmsg_add_u32(m, "caid", di->caid); + htsmsg_add_u32(m, "provid", di->provid); + htsmsg_add_u32(m, "ecmtime", di->ecmtime); + htsmsg_add_u32(m, "hops", di->hops); + if (di->cardsystem[0]) + htsmsg_add_str(m, "cardsystem", di->cardsystem); + if (di->reader[0]) + htsmsg_add_str(m, "reader", di->reader); + if (di->from[0]) + htsmsg_add_str(m, "from", di->from); + if (di->protocol[0]) + htsmsg_add_str(m, "protocol", di->protocol); + htsp_send_message(hs->hs_htsp, m, &hs->hs_htsp->htsp_hmq_qstatus); +} + /** * */ @@ -3821,6 +3849,10 @@ htsp_streaming_input(void *opaque, streaming_message_t *sm) htsp_subscription_signal_status(hs, sm->sm_data); break; + case SMT_DESCRAMBLE_INFO: + htsp_subscription_descramble_info(hs, sm->sm_data); + break; + case SMT_NOSTART: case SMT_NOSTART_WARN: htsp_subscription_status(hs, streaming_code2txt(sm->sm_code), diff --git a/src/plumbing/globalheaders.c b/src/plumbing/globalheaders.c index c8d7e11c7..e5672d36b 100644 --- a/src/plumbing/globalheaders.c +++ b/src/plumbing/globalheaders.c @@ -331,6 +331,7 @@ gh_hold(globalheaders_t *gh, streaming_message_t *sm) case SMT_EXIT: case SMT_SERVICE_STATUS: case SMT_SIGNAL_STATUS: + case SMT_DESCRAMBLE_INFO: case SMT_NOSTART: case SMT_NOSTART_WARN: case SMT_MPEGTS: @@ -367,6 +368,7 @@ gh_pass(globalheaders_t *gh, streaming_message_t *sm) case SMT_EXIT: case SMT_SERVICE_STATUS: case SMT_SIGNAL_STATUS: + case SMT_DESCRAMBLE_INFO: case SMT_NOSTART: case SMT_NOSTART_WARN: case SMT_MPEGTS: diff --git a/src/plumbing/transcoding.c b/src/plumbing/transcoding.c index b5b625ee1..f1956359c 100644 --- a/src/plumbing/transcoding.c +++ b/src/plumbing/transcoding.c @@ -1879,6 +1879,7 @@ transcoder_input(void *opaque, streaming_message_t *sm) case SMT_EXIT: case SMT_SERVICE_STATUS: case SMT_SIGNAL_STATUS: + case SMT_DESCRAMBLE_INFO: case SMT_NOSTART: case SMT_NOSTART_WARN: case SMT_MPEGTS: diff --git a/src/plumbing/tsfix.c b/src/plumbing/tsfix.c index 08614401f..8dd7eaaef 100644 --- a/src/plumbing/tsfix.c +++ b/src/plumbing/tsfix.c @@ -548,6 +548,7 @@ tsfix_input(void *opaque, streaming_message_t *sm) case SMT_EXIT: case SMT_SERVICE_STATUS: case SMT_SIGNAL_STATUS: + case SMT_DESCRAMBLE_INFO: case SMT_NOSTART: case SMT_NOSTART_WARN: case SMT_MPEGTS: diff --git a/src/satip/rtp.c b/src/satip/rtp.c index 1edf3dc6b..4ef99a3ed 100644 --- a/src/satip/rtp.c +++ b/src/satip/rtp.c @@ -316,6 +316,7 @@ satip_rtp_thread(void *aux) case SMT_SPEED: case SMT_SERVICE_STATUS: case SMT_TIMESHIFT_STATUS: + case SMT_DESCRAMBLE_INFO: break; } diff --git a/src/streaming.c b/src/streaming.c index 0b8225643..b0b53f053 100644 --- a/src/streaming.c +++ b/src/streaming.c @@ -260,6 +260,11 @@ streaming_msg_clone(streaming_message_t *src) memcpy(dst->sm_data, src->sm_data, sizeof(signal_status_t)); break; + case SMT_DESCRAMBLE_INFO: + dst->sm_data = malloc(sizeof(descramble_info_t)); + memcpy(dst->sm_data, src->sm_data, sizeof(descramble_info_t)); + break; + case SMT_TIMESHIFT_STATUS: dst->sm_data = malloc(sizeof(timeshift_status_t)); memcpy(dst->sm_data, src->sm_data, sizeof(timeshift_status_t)); @@ -338,6 +343,7 @@ streaming_msg_free(streaming_message_t *sm) case SMT_SKIP: case SMT_SIGNAL_STATUS: + case SMT_DESCRAMBLE_INFO: #if ENABLE_TIMESHIFT case SMT_TIMESHIFT_STATUS: #endif diff --git a/src/timeshift/timeshift_reader.c b/src/timeshift/timeshift_reader.c index b3af8b5c0..1e47dfe54 100644 --- a/src/timeshift/timeshift_reader.c +++ b/src/timeshift/timeshift_reader.c @@ -137,6 +137,7 @@ static ssize_t _read_msg ( timeshift_file_t *tsf, int fd, streaming_message_t ** case SMT_NOSTART: case SMT_NOSTART_WARN: case SMT_SERVICE_STATUS: + case SMT_DESCRAMBLE_INFO: return -1; break; diff --git a/src/timeshift/timeshift_writer.c b/src/timeshift/timeshift_writer.c index 3c4ccb568..ee611ad70 100644 --- a/src/timeshift/timeshift_writer.c +++ b/src/timeshift/timeshift_writer.c @@ -311,6 +311,7 @@ static void _process_msg case SMT_NOSTART_WARN: case SMT_SERVICE_STATUS: case SMT_TIMESHIFT_STATUS: + case SMT_DESCRAMBLE_INFO: break; /* Store */ diff --git a/src/tvheadend.h b/src/tvheadend.h index 27402c9e1..81947fa59 100644 --- a/src/tvheadend.h +++ b/src/tvheadend.h @@ -270,6 +270,21 @@ typedef struct signal_status { int tc_block; /* total block count */ } signal_status_t; +/** + * Descramble info + */ +typedef struct descramble_info { + uint16_t pid; + uint16_t caid; + uint32_t provid; + uint32_t ecmtime; + uint16_t hops; + char cardsystem[128]; + char reader [128]; + char from [128]; + char protocol [128]; +} descramble_info_t; + /** * Streaming skip */ @@ -355,6 +370,13 @@ typedef enum { */ SMT_SIGNAL_STATUS, + /** + * Descrambler info message + * + * Notification about descrambler + */ + SMT_DESCRAMBLE_INFO, + /** * Streaming stop. * diff --git a/src/webui/webui.c b/src/webui/webui.c index 8e413a082..0d56c06d0 100644 --- a/src/webui/webui.c +++ b/src/webui/webui.c @@ -432,6 +432,7 @@ http_stream_run(http_connection_t *hc, profile_chain_t *prch, case SMT_SKIP: case SMT_SPEED: case SMT_SIGNAL_STATUS: + case SMT_DESCRAMBLE_INFO: case SMT_TIMESHIFT_STATUS: break;