cwc: Use "per stream" update id for Cryptoworks and Viaccess CA composed emms

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>
This commit is contained in:
Jaroslav Kysela 2012-04-10 15:48:07 +02:00
parent 7604e83047
commit 98dd35342f
3 changed files with 21 additions and 15 deletions

View file

@ -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);

View file

@ -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_ */

View 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: