/**
*
*/
-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;
cm->cm_len = len;
cc_write_message((cclient_t *)cccam, cm, enq);
- return seq;
+ return 0;
}
/**
/**
*
*/
-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)
{
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);
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;
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\"",
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);
* 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;
cm->cm_len = len;
cc_write_message(cc, cm, enq);
- return seq & 0xffff;
+ if (_seq)
+ *_seq = seq;
+
+ return 0;
}
/**
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);
}
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);
}
/**
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;
}
/**
*
*/
-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;
}
/**
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);
}
/**