]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
dvbpsi: move the cat decoder from descrambler to a common place and use it everywhere 1210/head
authorJaroslav Kysela <perex@perex.cz>
Mon, 19 Nov 2018 13:39:14 +0000 (14:39 +0100)
committerJaroslav Kysela <perex@perex.cz>
Mon, 19 Nov 2018 13:39:14 +0000 (14:39 +0100)
src/descrambler/descrambler.c
src/descrambler/dvbcam.c
src/input/mpegts.h
src/input/mpegts/dvb_psi.c
src/input/mpegts/mpegts_input.c

index 506e464b05f9025c2f64925c2378cd11535e74d3..cc2bc94fe5670eb5738b6eb9757147423dc9b58f 100644 (file)
@@ -1532,8 +1532,9 @@ descrambler_flush_tables( mpegts_mux_t *mux )
 }
 
 static void descrambler_cat_entry
-  ( mpegts_mux_t *mux, uint16_t caid, uint32_t prov, uint16_t pid )
+  ( void *_mux, uint16_t caid, uint32_t prov, uint16_t pid )
 {
+  mpegts_mux_t *mux = _mux;
   descrambler_emm_t *emm;
   caclient_caid_update(mux, caid, prov, pid, 1);
   pthread_mutex_lock(&mux->mm_descrambler_lock);
@@ -1586,12 +1587,6 @@ void
 descrambler_cat_data( mpegts_mux_t *mux, const uint8_t *data, int len )
 {
   descrambler_emm_t *emm;
-  uint8_t dtag, dlen, dlen2;
-  uint16_t caid = 0, pid = 0;
-  uint32_t prov;
-  const uint8_t *data2;
-  int len2;
-  card_type_t ctype;
 
   tvhtrace(LS_DESCRAMBLER, "CAT data (len %d)", len);
   tvhlog_hexdump(LS_DESCRAMBLER, data, len);
@@ -1600,35 +1595,7 @@ descrambler_cat_data( mpegts_mux_t *mux, const uint8_t *data, int len )
   TAILQ_FOREACH(emm, &mux->mm_descrambler_emms, link)
     emm->to_be_removed = 1;
   pthread_mutex_unlock(&mux->mm_descrambler_lock);
-  while (len > 2) {
-    dtag = *data++;
-    dlen = *data++;
-    len -= 2;
-    if (dtag != DVB_DESC_CA || len < 4 || dlen < 4)
-      goto next;
-    caid =  (data[0] << 8) | data[1];
-    pid  = ((data[2] << 8) | data[3]) & 0x1fff;
-    if (pid > 0) {
-      ctype = detect_card_type(caid);
-      descrambler_cat_entry(mux, caid, 0, pid);
-      if (ctype == CARD_SECA) {
-        dlen2 = dlen - 5;
-        data2 = data + 5;
-        len2  = len - 5;
-        while (dlen2 >= 4 && len2 >= 4) {
-          pid = ((data2[0] << 8) | data2[1]) & 0xfff;
-          prov = (data2[2] << 8) | data2[3];
-          descrambler_cat_entry(mux, caid, prov, pid);
-          data2 += 4;
-          len2 -= 4;
-          dlen2 -= 4;
-        }
-      }
-    }
-next:
-    data += dlen;
-    len  -= dlen;
-  }
+  dvb_cat_decode(data, len, descrambler_cat_entry, mux);
   descrambler_cat_clean(mux);
 }
 
index 8fd1a5ab590224ced63a0af0df3838a337318d57..461a0146f64c9a7e1df44734c7143189e590b5bd 100644 (file)
@@ -666,6 +666,27 @@ typedef struct __cat_update {
   mpegts_apids_t to_close;
 } __cat_update_t;
 
+typedef struct __cat_entry {
+  mpegts_apids_t *pids;
+  mpegts_service_t *service;
+} __cat_entry_t;
+
+/*
+ *
+ */
+#if ENABLE_DDCI
+static void dvbcam_cat_entry
+  ( void *_aux, uint16_t caid, uint32_t prov, uint16_t pid )
+{
+  __cat_entry_t *aux = _aux;
+  if (!mpegts_pid_rexists(aux->pids, pid)) {
+    mpegts_pid_add(aux->pids, pid, 0);
+    tvhtrace(LS_DVBCAM, "%p: add EMM PID %d (%04X) for CAID %04X",
+                        aux->service, pid, pid, caid);
+  }
+}
+#endif
+
 /*
  *
  */
@@ -677,13 +698,8 @@ dvbcam_cat_update(caclient_t *cac, mpegts_mux_t *mux, const uint8_t *data, int l
   int i, services_count;
   dvbcam_active_service_t *as;
   mpegts_apids_t pids;
-  const uint8_t *data1;
-  int len1;
-  uint8_t dtag;
-  uint8_t dlen;
-  uint16_t caid;
-  uint16_t pid;
   mpegts_input_t *mi;
+  __cat_entry_t cat_aux;
 
   if (len <= 0)
     return;
@@ -708,24 +724,9 @@ dvbcam_cat_update(caclient_t *cac, mpegts_mux_t *mux, const uint8_t *data, int l
       mpegts_pid_init(&sp->to_open);
       mpegts_pid_init(&sp->to_close);
       mpegts_pid_init(&pids);
-      data1 = data;
-      len1  = len;
-      while (len1 > 2) {
-        dtag = *data1++;
-        dlen = *data1++;
-        len1 -= 2;
-        if (dtag == DVB_DESC_CA && len1 >= 4 && dlen >= 4) {
-          caid =  (data1[0] << 8) | data1[1];
-          pid  = ((data1[2] << 8) | data1[3]) & 0x1fff;
-          if (dvbcam_service_check_caid(as, caid) && pid != 0) {
-            tvhtrace(LS_DVBCAM, "%p: add EMM PID %d (%04X) for CAID %04X",
-                                sp->service, pid, pid, caid);
-            mpegts_pid_add(&pids, pid, 0);
-          }
-        }
-        data1 += dlen;
-        len1  -= dlen;
-      }
+      cat_aux.pids = &pids;
+      cat_aux.service = sp->service;
+      dvb_cat_decode(data, len, dvbcam_cat_entry, &cat_aux);
       mpegts_pid_compare(&pids, &as->cat_pids, &sp->to_open, &sp->to_close);
       mpegts_pid_copy(&as->cat_pids, &pids);
       mpegts_pid_done(&pids);
index 696e842f63d881ae8c207f0e6f49dc7046d442a8..e95b155119ac839e5b68b45733c5e1a3e17f55c5 100644 (file)
@@ -1065,6 +1065,10 @@ void mpegts_table_consistency_check(mpegts_mux_t *mm);
 
 void dvb_bat_destroy(struct mpegts_table *mt);
 
+void dvb_cat_decode( const uint8_t *data, int len,
+                     void (*add_emm)(void *aux, uint16_t caid, uint32_t prov, uint16_t pid),
+                     void *aux );
+
 int dvb_pat_callback
   (struct mpegts_table *mt, const uint8_t *ptr, int len, int tableid);
 int dvb_cat_callback
index e04d2df6c2355787fdc152205be09f9fee5dcaac..0475384f2381e82c07389a5f70202a89570fd555 100644 (file)
@@ -1041,14 +1041,62 @@ end:
 /*
  * CAT processing
  */
+void
+dvb_cat_decode( const uint8_t *data, int len,
+                void (*add_emm)(void *aux, uint16_t caid, uint32_t prov, uint16_t pid),
+                void *aux )
+{
+  uint8_t dtag, dlen, dlen2;
+  uint16_t caid = 0, pid = 0;
+  uint32_t prov;
+  const uint8_t *data2;
+  int len2;
+  card_type_t ctype;
+
+  while (len > 2) {
+    dtag = *data++;
+    dlen = *data++;
+    len -= 2;
+    if (dtag != DVB_DESC_CA || len < 4 || dlen < 4)
+      goto next;
+    caid =  (data[0] << 8) | data[1];
+    pid  = ((data[2] << 8) | data[3]) & 0x1fff;
+    if (pid > 0) {
+      ctype = detect_card_type(caid);
+      add_emm(aux, caid, 0, pid);
+      if (ctype == CARD_SECA) {
+        dlen2 = dlen - 5;
+        data2 = data + 5;
+        len2  = len - 5;
+        while (dlen2 >= 4 && len2 >= 4) {
+          pid = ((data2[0] << 8) | data2[1]) & 0xfff;
+          prov = (data2[2] << 8) | data2[3];
+          add_emm(aux, caid, prov, pid);
+          data2 += 4;
+          len2 -= 4;
+          dlen2 -= 4;
+        }
+      }
+    }
+next:
+    data += dlen;
+    len  -= dlen;
+  }
+}
+
+static void
+dvb_cat_entry(void *_mt, uint16_t caid, uint32_t prov, uint16_t pid)
+{
+  mpegts_table_t *mt = _mt;
+  tvhdebug(mt->mt_subsys, "%s:  caid %04X (%d) pid %04X (%d)",
+           mt->mt_name, (uint16_t)caid, (uint16_t)caid, pid, pid);
+}
+
 int
 dvb_cat_callback
   (mpegts_table_t *mt, const uint8_t *ptr, int len, int tableid)
 {
   int r, sect, last, ver;
-  uint8_t dtag, dlen;
-  uint16_t pid; 
-  uintptr_t caid;
   mpegts_mux_t             *mm  = mt->mt_mux;
   mpegts_psi_table_state_t *st  = NULL;
 
@@ -1062,27 +1110,8 @@ dvb_cat_callback
   /* Send CAT data for descramblers */
   descrambler_cat_data(mm, ptr, len);
 
-  while(len > 2) {
-    dtag = *ptr++;
-    dlen = *ptr++;
-    len -= 2;
-
-    switch(dtag) {
-      case DVB_DESC_CA:
-        if (len >= 4 && dlen >= 4) {
-          caid = extract_2byte(ptr);
-          pid  = extract_pid(ptr + 2);
-          tvhdebug(mt->mt_subsys, "%s:  caid %04X (%d) pid %04X (%d)",
-                   mt->mt_name, (uint16_t)caid, (uint16_t)caid, pid, pid);
-        }
-        break;
-      default:
-        break;
-    }
-
-    ptr += dlen;
-    len -= dlen;
-  }
+  /* show CAT data */
+  dvb_cat_decode(ptr, len, dvb_cat_entry, mt);
 
   /* Finish */
   return dvb_table_end((mpegts_psi_table_t *)mt, st, sect);
index 0bcc603dbf7ac149c504ade5e7e560aff3060de5..7fb5f46953f02b51df55b6d5657f9d6140ec8be3 100644 (file)
@@ -704,20 +704,59 @@ int mpegts_mps_weight(elementary_stream_t *st)
      return MPS_WEIGHT_ESOTHER + MIN(st->es_index, 49);
 }
 
+typedef struct __cat_pass_aux {
+  mpegts_input_t *mi;
+  mpegts_mux_t *mm;
+  service_t *service;
+} __cat_pass_aux_t;
+
+static void
+mpegts_input_cat_pass_entry
+  (void *_aux, uint16_t caid, uint32_t prov, uint16_t pid)
+{
+  __cat_pass_aux_t *aux = _aux;
+  elementary_stream_t *es;
+  caid_t *c;
+
+  tvhdebug(LS_TBL_BASE, "cat:  pass: caid %04X (%d) pid %04X (%d)",
+           (uint16_t)caid, (uint16_t)caid, pid, pid);
+  es = mpegts_input_open_service_pid(aux->mi, aux->mm, aux->service,
+                                     SCT_CAT, pid, MPS_WEIGHT_CAT, 1);
+  if (es) {
+    LIST_FOREACH(c, &es->es_caids, link) {
+      if (c->pid == pid) {
+        c->caid = caid;
+        c->delete_me = 0;
+        es->es_delete_me = 0;
+        break;
+      }
+    }
+    if (c == NULL) {
+      c = malloc(sizeof(caid_t));
+      c->caid = caid;
+      c->providerid = 0;
+      c->use = 1;
+      c->pid = pid;
+      c->delete_me = 0;
+      c->filter = 0;
+      LIST_INSERT_HEAD(&es->es_caids, c, link);
+      es->es_delete_me = 0;
+    }
+  }
+}
+
 static int
 mpegts_input_cat_pass_callback
   (mpegts_table_t *mt, const uint8_t *ptr, int len, int tableid)
 {
   int r, sect, last, ver;
-  uint8_t dtag, dlen;
-  uint16_t pid;
-  uintptr_t caid;
   mpegts_mux_t             *mm  = mt->mt_mux;
   mpegts_psi_table_state_t *st  = NULL;
   service_t                *s   = mt->mt_opaque;
   mpegts_input_t           *mi;
   elementary_stream_t      *es, *next;
   caid_t                   *c, *cn;
+  __cat_pass_aux_t aux;
 
   /* Start */
   r = dvb_table_begin((mpegts_psi_table_t *)mt, ptr, len,
@@ -742,50 +781,10 @@ mpegts_input_cat_pass_callback
       c->delete_me = 1;
   }
 
-  while(len > 2) {
-    dtag = *ptr++;
-    dlen = *ptr++;
-    len -= 2;
-
-    switch(dtag) {
-      case DVB_DESC_CA:
-        if (len >= 4 && dlen >= 4 && mm->mm_active) {
-          caid = ( ptr[0]         << 8) | ptr[1];
-          pid  = ((ptr[2] & 0x1f) << 8) | ptr[3];
-          tvhdebug(LS_TBL_BASE, "cat:  pass: caid %04X (%d) pid %04X (%d)",
-                   (uint16_t)caid, (uint16_t)caid, pid, pid);
-          es = mpegts_input_open_service_pid(mi, mm, s, SCT_CAT, pid,
-                                             MPS_WEIGHT_CAT, 1);
-          if (es) {
-            LIST_FOREACH(c, &es->es_caids, link) {
-              if (c->pid == pid) {
-                c->caid = caid;
-                c->delete_me = 0;
-                es->es_delete_me = 0;
-                break;
-              }
-            }
-            if (c == NULL) {
-              c = malloc(sizeof(caid_t));
-              c->caid = caid;
-              c->providerid = 0;
-              c->use = 1;
-              c->pid = pid;
-              c->delete_me = 0;
-              c->filter = 0;
-              LIST_INSERT_HEAD(&es->es_caids, c, link);
-              es->es_delete_me = 0;
-            }
-          }
-        }
-        break;
-      default:
-        break;
-    }
-
-    ptr += dlen;
-    len -= dlen;
-  }
+  aux.mi = mi;
+  aux.mm = mm;
+  aux.service = s;
+  dvb_cat_decode(ptr, len, mpegts_input_cat_pass_entry, &aux);
 
   for (es = TAILQ_FIRST(&s->s_components.set_all); es != NULL; es = next) {
     next = TAILQ_NEXT(es, es_link);