]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
cclient: handle send_ecm return value correctly, issue #4876
authorJaroslav Kysela <perex@perex.cz>
Wed, 24 Jan 2018 08:04:01 +0000 (09:04 +0100)
committerJaroslav Kysela <perex@perex.cz>
Wed, 24 Jan 2018 08:04:01 +0000 (09:04 +0100)
src/descrambler/cccam.c
src/descrambler/cclient.c
src/descrambler/cclient.h
src/descrambler/cwc.c

index 71545c5852f48b1dfc1130bc3eec8cc1b588c5a0..9eb0251258c9586b39a1a732dafe87c82380f39d 100644 (file)
@@ -523,9 +523,10 @@ cccam_read_message0(cccam_t *cccam, const char *state, sbuf_t *rbuf, int timeout
 /**
  *
  */
-static uint32_t
+static int
 cccam_send_msg(cccam_t *cccam, cccam_msg_type_t cmd,
-               uint8_t *buf, size_t len, int enq, int seq, uint32_t card_id)
+               uint8_t *buf, size_t len, int enq,
+               uint8_t seq, uint32_t card_id)
 {
   cc_message_t *cm;
   uint8_t *netbuf;
@@ -554,7 +555,7 @@ cccam_send_msg(cccam_t *cccam, cccam_msg_type_t cmd,
   cm->cm_len = len;
   cc_write_message((cclient_t *)cccam, cm, enq);
 
-  return seq;
+  return 0;
 }
 
 /**
@@ -747,7 +748,7 @@ cccam_init_session(void *cc)
 /**
  *
  */
-static uint32_t
+static int
 cccam_send_ecm(void *cc, cc_service_t *ct, cc_ecm_section_t *es,
                cc_card_data_t *pcard, const uint8_t *msg, int len)
 {
@@ -760,13 +761,13 @@ cccam_send_ecm(void *cc, cc_service_t *ct, cc_ecm_section_t *es,
 
   if (len > 255) {
     tvherror(cccam->cc_subsys, "%s: ECM too big (%d bytes)", cccam->cc_name, len);
-    return 0;
+    return -1;
   }
 
   if (cccam_set_busy(cccam)) {
     tvhinfo(cccam->cc_subsys, "%s: Ignore ECM request %02X (server is busy)",
             cccam->cc_name, msg[0]);
-    return 0;
+    return -1;
   }
 
   seq = atomic_add(&cccam->cc_seq, 1);
@@ -775,6 +776,7 @@ cccam_send_ecm(void *cc, cc_service_t *ct, cc_ecm_section_t *es,
   card_id = pcard->cs_id;
   es->es_card_id = card_id;
   sid = t->s_dvb_service_id;
+  es->es_seq = seq & 0xff;
 
   buf = alloca(len + 13);
   buf[ 0] = caid >> 8;
index 577f7f38cb080166c56b4a9bf62eae7ce45371c0..901589397cd21353074be8fe0de3995f7684eedb 100644 (file)
@@ -967,13 +967,15 @@ found:
       goto end;
     }
 
-    es->es_seq = cc->cc_send_ecm(cc, ct, es, pcard, data, len);
-
-    tvhdebug(cc->cc_subsys,
-             "%s: Sending ECM%s section=%d/%d for service \"%s\" (seqno: %d)",
-             cc->cc_name, chaninfo, section,
-             ep->ep_last_section, t->s_dvb_svcname, es->es_seq);
-    es->es_time = getfastmonoclock();
+    if (cc->cc_send_ecm(cc, ct, es, pcard, data, len) == 0) {
+      tvhdebug(cc->cc_subsys,
+               "%s: Sending ECM%s section=%d/%d for service \"%s\" (seqno: %d)",
+               cc->cc_name, chaninfo, section,
+               ep->ep_last_section, t->s_dvb_svcname, es->es_seq);
+      es->es_time = getfastmonoclock();
+    } else {
+      es->es_pending = 0;
+    }
   } else {
     if (cc->cc_forward_emm && data[0] >= 0x82 && data[0] <= 0x92) {
       tvhtrace(cc->cc_subsys, "%s: sending EMM for %04X:%06X service \"%s\"",
index 9f68815812286520ce898cf6ad3edb33f8b13101..acecd679f526b54bf9cdb6d1df8d2ca6860e4aca 100644 (file)
@@ -142,8 +142,8 @@ typedef struct cclient {
   int (*cc_init_session)(void *cc);
   int (*cc_read)(void *cc, sbuf_t *sbuf);
   void (*cc_keepalive)(void *cc);
-  uint32_t (*cc_send_ecm)(void *cc, cc_service_t *ct, cc_ecm_section_t *es,
-                          cc_card_data_t *pcard, const uint8_t *data, int len);
+  int (*cc_send_ecm)(void *cc, cc_service_t *ct, cc_ecm_section_t *es,
+                     cc_card_data_t *pcard, const uint8_t *data, int len);
   void (*cc_send_emm)(void *cc, cc_service_t *ct, cc_card_data_t *pcard,
                       uint32_t provid, const uint8_t *data, int len);
 
index 3cfc0faef71afa2b877d13573e6d557c70c5bf98..295538c3281a48284549dc3ca20a5bff6845bd5c 100644 (file)
@@ -212,9 +212,10 @@ des_make_session_key(cwc_t *cwc)
  * Note, this function is called from multiple threads so beware of
  * the ID)
  */
-static uint32_t
+static int
 cwc_send_msg(void *cc, const uint8_t *msg, size_t len,
-             int sid, int enq, uint16_t st_caid, uint32_t st_provider)
+             int sid, int enq, uint16_t st_caid, uint32_t st_provider,
+             uint16_t *_seq)
 {
   cwc_t *cwc = cc;
   cc_message_t *cm;
@@ -261,7 +262,10 @@ cwc_send_msg(void *cc, const uint8_t *msg, size_t len,
   cm->cm_len = len;
   cc_write_message(cc, cm, enq);
 
-  return seq & 0xffff;
+  if (_seq)
+    *_seq = seq;
+
+  return 0;
 }
 
 /**
@@ -276,7 +280,7 @@ cwc_send_data_req(cwc_t *cwc)
   buf[1] = 0;
   buf[2] = 0;
 
-  cwc_send_msg(cwc, buf, 3, 0, 0, 0, 1);
+  cwc_send_msg(cwc, buf, 3, 0, 0, 0, 1, NULL);
 }
 
 
@@ -293,7 +297,7 @@ cwc_send_ka(void *cc)
   buf[1] = 0;
   buf[2] = 0;
 
-  cwc_send_msg(cwc, buf, 3, 0, 1, 0, 0);
+  cwc_send_msg(cwc, buf, 3, 0, 1, 0, 0, NULL);
 }
 
 /**
@@ -373,7 +377,7 @@ cwc_send_login(cwc_t *cwc)
   memcpy(buf + 3,      cwc->cc_username, ul);
   memcpy(buf + 3 + ul, cwc->cwc_password_salted, pl);
 
-  cwc_send_msg(cwc, buf, ul + pl + 3, TVHEADEND_PROTOCOL_ID, 0, 0, 0);
+  cwc_send_msg(cwc, buf, ul + pl + 3, TVHEADEND_PROTOCOL_ID, 0, 0, 0, NULL);
 
   return 0;
 }
@@ -625,14 +629,19 @@ cwc_read(void *cc, sbuf_t *rbuf)
 /**
  *
  */
-static uint32_t
+static int
 cwc_send_ecm(void *cc, cc_service_t *ct, cc_ecm_section_t *es,
              cc_card_data_t *pcard, const uint8_t *data, int len)
 {
   mpegts_service_t *t = (mpegts_service_t *)ct->td_service;
   uint16_t sid = t->s_dvb_service_id;
+  uint16_t seq;
+  int r;
 
-  return cwc_send_msg(cc, data, len, sid, 1, es->es_caid, es->es_provid);
+  r = cwc_send_msg(cc, data, len, sid, 1, es->es_caid, es->es_provid, &seq);
+  if (r == 0)
+    es->es_seq = seq;
+  return r;
 }
 
 /**
@@ -651,7 +660,7 @@ cwc_send_emm(void *cc, cc_service_t *ct,
     sid = t->s_dvb_service_id;
   }
 
-  cwc_send_msg(cc, data, len, sid, 1, pcard->cs_ra.caid, provid);
+  cwc_send_msg(cc, data, len, sid, 1, pcard->cs_ra.caid, provid, NULL);
 }
 
 /**