]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
descrambler/htsp server: add descramble info message, fixes #2616
authorJaroslav Kysela <perex@perex.cz>
Tue, 6 Oct 2015 18:41:14 +0000 (20:41 +0200)
committerJaroslav Kysela <perex@perex.cz>
Tue, 6 Oct 2015 19:08:21 +0000 (21:08 +0200)
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.

15 files changed:
src/descrambler.h
src/descrambler/capmt.c
src/descrambler/cwc.c
src/descrambler/descrambler.c
src/dvr/dvr_rec.c
src/htsp_server.c
src/plumbing/globalheaders.c
src/plumbing/transcoding.c
src/plumbing/tsfix.c
src/satip/rtp.c
src/streaming.c
src/timeshift/timeshift_reader.c
src/timeshift/timeshift_writer.c
src/tvheadend.h
src/webui/webui.c

index 201c43630ad8a23e939fcdf44fb0ee1b2e7547fa..f97395e44987a18389ceadca0e8ac0fde802fbe6 100644 (file)
@@ -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 );
index fe4061b84c6726c129fda80a686c6a00388968b0..6cea5c712779946ede9cb0994ff1b5860bac9d29 100644 (file)
@@ -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);
 
index 52980293e261d8003b4de566974234223e2d9e47..f722b435c5fdb33c8f1127e4b0ef43545e9151de 100644 (file)
@@ -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)",
index 47374bdac63b8b816c3f5d5363aa001dc17199b6..d2c72adbffeb5b9fdb87a7a805d4fdfec8cd8fce 100644 (file)
@@ -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 )
 {
index 47483fc413a7d56b9efb03bcc1ed6349045ab8f4..1db0d75dab1067a577b5f132f9a84669124680a0 100644 (file)
@@ -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:
index fe6dd8f711923b934e149ec969946c93285cfef0..69f9cc8e38af6994c8fb35af7d7a113869e30fdb 100644 (file)
@@ -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),
index c8d7e11c77d8608d8717a899165124ab217701e2..e5672d36b7e308951f217b35eea03fb98ea4a185 100644 (file)
@@ -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:
index b5b625ee1e0ed193d3977fda557bb3c90e60ff7c..f1956359cfc1b5416da358817dfa8504a2cfbe5e 100644 (file)
@@ -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:
index 08614401f001d70c08db7014cae4a4bf78361ba8..8dd7eaaefdbb70bfff7b41573b251f4eeb669d90 100644 (file)
@@ -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:
index 1edf3dc6b9db0c3ab6ff88e72080d90c960d8079..4ef99a3edd670d7fa2aa0680cd5ae78fb0f92c6a 100644 (file)
@@ -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;
     }
 
index 0b822564371239044ae88e8774112469dd39b70b..b0b53f053a99fc7e229ba348d7b80b464687178b 100644 (file)
@@ -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
index b3af8b5c0687330215b7ae9e7e5bd9b3d90aa1d3..1e47dfe54f4b16b582776e75257644588bb8d3dc 100644 (file)
@@ -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;
 
index 3c4ccb5683cd0619aaad305f015dbcd4cda9053b..ee611ad706e06401f25694a41278da37f3bc649f 100644 (file)
@@ -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 */
index 27402c9e1a069158a445fbdd10b58524ae3e22b8..81947fa599f7eb91c5e9ea078aa96151474c5f7a 100644 (file)
@@ -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.
    *
index 8e413a082e67f1a2e3eb9427f82f90293870f059..0d56c06d06d5e363b453ad28ecc72443ea3c85a2 100644 (file)
@@ -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;