]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
cwc: Use "per stream" update id for Cryptoworks and Viaccess CA composed emms
authorJaroslav Kysela <perex@perex.cz>
Tue, 10 Apr 2012 13:48:07 +0000 (15:48 +0200)
committerJaroslav Kysela <perex@perex.cz>
Tue, 10 Apr 2012 18:57:33 +0000 (20:57 +0200)
This fixes possible shared EMM messages composing issues when multiple
streams are sending EMMs to the card reader. Just make sure, that both
parts of compose messages are from one "stream".

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
src/cwc.c
src/cwc.h
src/dvb/dvb_tables.c

index a90c1f3a6db81a64f9d5e7f12e4d8a6649c4ca71..e2442ea852c20b48544c814b565ffd639de1b736 100644 (file)
--- a/src/cwc.c
+++ b/src/cwc.c
@@ -243,6 +243,7 @@ typedef struct cwc {
     int shared_toggle;
     int shared_len;
     uint8_t * shared_emm;
+    void *ca_update_id;
   } cwc_viaccess_emm;
 #define cwc_cryptoworks_emm cwc_viaccess_emm
 
@@ -279,10 +280,10 @@ void cwc_emm_conax(cwc_t *cwc, uint8_t *data, int len);
 void cwc_emm_irdeto(cwc_t *cwc, uint8_t *data, int len);
 void cwc_emm_dre(cwc_t *cwc, uint8_t *data, int len);
 void cwc_emm_seca(cwc_t *cwc, uint8_t *data, int len);
-void cwc_emm_viaccess(cwc_t *cwc, uint8_t *data, int len);
+void cwc_emm_viaccess(cwc_t *cwc, uint8_t *data, int len, void *ca_update_id);
 void cwc_emm_nagra(cwc_t *cwc, uint8_t *data, int len);
 void cwc_emm_nds(cwc_t *cwc, uint8_t *data, int len);
-void cwc_emm_cryptoworks(cwc_t *cwc, uint8_t *data, int len);
+void cwc_emm_cryptoworks(cwc_t *cwc, uint8_t *data, int len, void *ca_update_id);
 
 
 /**
@@ -1188,7 +1189,7 @@ cwc_emm_cache_lookup(cwc_t *cwc, uint32_t crc)
  *
  */
 void
-cwc_emm(uint8_t *data, int len, uint16_t caid)
+cwc_emm(uint8_t *data, int len, uint16_t caid, void *ca_update_id)
 {
   cwc_t *cwc;
 
@@ -1208,7 +1209,7 @@ cwc_emm(uint8_t *data, int len, uint16_t caid)
        cwc_emm_seca(cwc, data, len);
        break;
       case CARD_VIACCESS:
-       cwc_emm_viaccess(cwc, data, len);
+       cwc_emm_viaccess(cwc, data, len, ca_update_id);
        break;
       case CARD_DRE:
        cwc_emm_dre(cwc, data, len);
@@ -1220,7 +1221,7 @@ cwc_emm(uint8_t *data, int len, uint16_t caid)
        cwc_emm_nds(cwc, data, len);
        break;
       case CARD_CRYPTOWORKS:
-       cwc_emm_cryptoworks(cwc, data, len);
+       cwc_emm_cryptoworks(cwc, data, len, ca_update_id);
        break;
       case CARD_UNKNOWN:
        break;
@@ -1382,7 +1383,7 @@ static int via_provider_id(uint8_t * data)
 
 
 void
-cwc_emm_viaccess(cwc_t *cwc, uint8_t *data, int mlen)
+cwc_emm_viaccess(cwc_t *cwc, uint8_t *data, int mlen, void *ca_update_id)
 {
   /* Get SCT len */
   int len = 3 + ((data[1] & 0x0f) << 8) + data[2];
@@ -1414,13 +1415,15 @@ cwc_emm_viaccess(cwc_t *cwc, uint8_t *data, int mlen)
          if (cwc->cwc_viaccess_emm.shared_emm) {
            cwc->cwc_viaccess_emm.shared_len = len;
            memcpy(cwc->cwc_viaccess_emm.shared_emm, data, len);
+           cwc->cwc_viaccess_emm.ca_update_id = ca_update_id;
          }
          cwc->cwc_viaccess_emm.shared_toggle = data[0];
        }
       }
       break;
     case 0x8e:
-      if (cwc->cwc_viaccess_emm.shared_emm) {
+      if (cwc->cwc_viaccess_emm.shared_emm &&
+          cwc->cwc_viaccess_emm.ca_update_id == ca_update_id) {
        int match = 0;
        int i;
        /* Match SA and provider in shared */
@@ -1667,7 +1670,7 @@ cwc_emm_nds(cwc_t *cwc, uint8_t *data, int len)
 }
 
 void
-cwc_emm_cryptoworks(cwc_t *cwc, uint8_t *data, int len)
+cwc_emm_cryptoworks(cwc_t *cwc, uint8_t *data, int len, void *ca_update_id)
 {
   int match = 0;
 
@@ -1686,11 +1689,13 @@ cwc_emm_cryptoworks(cwc_t *cwc, uint8_t *data, int len)
       if (cwc->cwc_cryptoworks_emm.shared_emm) {
         cwc->cwc_cryptoworks_emm.shared_len = len;
         memcpy(cwc->cwc_cryptoworks_emm.shared_emm, data, len);
+        cwc->cwc_cryptoworks_emm.ca_update_id = ca_update_id;
       }
     }
     break;
   case 0x86: /* emm-sb */ 
-    if (cwc->cwc_cryptoworks_emm.shared_emm) {
+    if (cwc->cwc_cryptoworks_emm.shared_emm &&
+        cwc->cwc_cryptoworks_emm.ca_update_id == ca_update_id) {
       /* python: EMM_SH[0:12] + EMM_SB[5:-1] + EMM_SH[12:-1] */
       uint32_t elen = len - 5 + cwc->cwc_cryptoworks_emm.shared_len - 12;
       uint8_t *tmp = malloc(elen);
index da2381bfdb84eeee28d68b97be0c6d81a8d0eb05..3c28710a733342db7aa8d47a8be6362ebcf52d09 100644 (file)
--- a/src/cwc.h
+++ b/src/cwc.h
@@ -23,6 +23,6 @@ void cwc_init(void);
 
 void cwc_service_start(struct service *t);
 
-void cwc_emm(uint8_t *data, int len, uint16_t caid);
+void cwc_emm(uint8_t *data, int len, uint16_t caid, void *ca_update_id);
 
 #endif /* CWC_H_ */
index efcd50249d466b6bc040633d29650c0d77803bdc..f2e83653131617c13afb94d9e7b4f16f43c9824e 100644 (file)
@@ -44,7 +44,7 @@
 
 #define TDT_CRC           0x1
 #define TDT_QUICKREQ      0x2
-#define TDT_INC_TABLE_HDR 0x4
+#define TDT_CA           0x4
 
 static void dvb_table_add_pmt(th_dvb_mux_instance_t *tdmi, int pmt_pid);
 
@@ -214,8 +214,9 @@ dvb_proc_table(th_dvb_mux_instance_t *tdmi, th_dvb_table_t *tdt, uint8_t *sec,
   ptr = &sec[3];
   if(chkcrc) len -= 4;   /* Strip trailing CRC */
 
-  if(tdt->tdt_flags & TDT_INC_TABLE_HDR)
-    ret = tdt->tdt_callback(tdmi, sec, len + 3, tableid, tdt->tdt_opaque);
+  if(tdt->tdt_flags & TDT_CA)
+    ret = tdt->tdt_callback((th_dvb_mux_instance_t *)tdt,
+                                sec, len + 3, tableid, tdt->tdt_opaque);
   else
     ret = tdt->tdt_callback(tdmi, ptr, len, tableid, tdt->tdt_opaque);
   
@@ -828,7 +829,7 @@ static int
 dvb_ca_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
                uint8_t tableid, void *opaque)
 {
-  cwc_emm(ptr, len, (uintptr_t)opaque);
+  cwc_emm(ptr, len, (uintptr_t)opaque, (void *)tdmi);
   return 0;
 }
 
@@ -864,7 +865,7 @@ dvb_cat_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
        break;
 
       tdt_add(tdmi, NULL, dvb_ca_callback, (void *)caid, "CA", 
-             TDT_INC_TABLE_HDR, pid, NULL);
+             TDT_CA, pid, NULL);
       break;
 
     default: