Verify that cwc utilize correct ECM stream based on provider id.

This commit is contained in:
Andreas Öman 2009-07-13 20:36:51 +00:00
parent 18141cbec1
commit 891ed4eb1a
3 changed files with 105 additions and 7 deletions

View file

@ -162,6 +162,11 @@ typedef struct cwc {
uint8_t cwc_buf[256];
int cwc_bufptr;
/* Provder IDs */
uint32_t cwc_provider_ids[256];
int cwc_num_providers;
/* From configuration */
uint8_t cwc_confedkey[14];
@ -419,7 +424,9 @@ cwc_send_ka(cwc_t *cwc)
static int
cwc_decode_card_data_reply(cwc_t *cwc, uint8_t *msg, int len)
{
int plen;
int plen, i;
unsigned int nprov;
uint32_t id;
const char *n;
msg += 12;
@ -433,7 +440,14 @@ cwc_decode_card_data_reply(cwc_t *cwc, uint8_t *msg, int len)
plen = (msg[1] & 0xf) << 8 | msg[2];
if(plen < 14) {
tvhlog(LOG_INFO, "cwc", "Invalid card data reply");
tvhlog(LOG_INFO, "cwc", "Invalid card data reply (message)");
return -1;
}
nprov = msg[14];
if(plen < nprov * 11) {
tvhlog(LOG_INFO, "cwc", "Invalid card data reply (provider list)");
return -1;
}
@ -446,7 +460,20 @@ cwc_decode_card_data_reply(cwc_t *cwc, uint8_t *msg, int len)
cwc->cwc_hostname,
msg[3], n, cwc->cwc_caid,
msg[6], msg[7], msg[8], msg[9], msg[10], msg[11], msg[12], msg[13],
msg[14]);
nprov);
msg += 15;
plen -= 12;
cwc->cwc_num_providers = nprov;
for(i = 0; i < nprov; i++) {
id = (msg[0] << 16) | (msg[1] << 8) | msg[2];
tvhlog(LOG_INFO, "cwc", "%s: Provider ID #%d: 0x%06x",
cwc->cwc_hostname, i + 1 , id);
cwc->cwc_provider_ids[i] = id;
msg += 11;
}
return 0;
}
@ -513,6 +540,7 @@ cwc_running_reply(cwc_t *cwc, uint8_t msgtype, uint8_t *msg, int len)
if(ct->ct_keystate != CT_RESOLVED)
tvhlog(LOG_INFO, "cwc",
"Obtained key for for service \"%s\"",t->tht_svcname);
ct->ct_keystate = CT_RESOLVED;
pthread_mutex_lock(&t->tht_stream_mutex);
set_control_words(ct->ct_keys, msg + 3, msg + 3 + 8);
@ -784,6 +812,24 @@ cwc_thread(void *aux)
}
/**
*
*/
static int
verify_provider(cwc_t *cwc, uint32_t providerid)
{
int i;
if(providerid == 0)
return 1;
for(i = 0; i < cwc->cwc_num_providers; i++)
if(providerid == cwc->cwc_provider_ids[i])
return 1;
return 0;
}
/**
*
*/
@ -798,6 +844,9 @@ cwc_table_input(struct th_descrambler *td, struct th_transport *t,
if(cwc->cwc_caid != st->st_caid)
return;
if(!verify_provider(cwc, st->st_providerid))
return;
if((data[0] & 0xf0) != 0x80)
return;

View file

@ -161,7 +161,39 @@ psi_build_pat(th_transport_t *t, uint8_t *buf, int maxlen, int pmtpid)
}
/**
* Parser for CA descriptor, viaccess
*/
static int
psi_desc_ca_viaccess(th_transport_t *t, th_stream_t *st, uint8_t *ptr, int len)
{
uint8_t tag, tlen;
uint32_t id;
while(len > 2) {
tag = ptr[0];
tlen = ptr[1];
ptr += 2;
len -= 2;
if(len < tlen)
return 0;
switch(tag) {
case 0x14:
id = (ptr[0] << 16) | (ptr[1] << 8) | (ptr[2] & 0xf0);
if(id != st->st_providerid) {
st->st_providerid = id;
return 1;
}
}
len -= tlen;
ptr += tlen;
}
return 0;
}
@ -169,7 +201,7 @@ psi_build_pat(th_transport_t *t, uint8_t *buf, int maxlen, int pmtpid)
* Parser for CA descriptor
*/
static int
psi_desc_ca(th_transport_t *t, uint8_t *ptr)
psi_desc_ca(th_transport_t *t, uint8_t *ptr, int len)
{
uint16_t pid = (ptr[2] & 0x1f) << 8 | ptr[3];
th_stream_t *st;
@ -187,6 +219,16 @@ psi_desc_ca(th_transport_t *t, uint8_t *ptr)
st->st_caid = caid;
r = 1;
}
len -= 4;
ptr += 4;
switch(caid >> 8) {
case 5:
r |= psi_desc_ca_viaccess(t, st, ptr, len);
break;
}
return r;
}
@ -247,7 +289,7 @@ psi_parse_pmt(th_transport_t *t, uint8_t *ptr, int len, int chksvcid)
switch(dtag) {
case DVB_DESC_CA:
update |= psi_desc_ca(t, ptr);
update |= psi_desc_ca(t, ptr, dlen);
break;
default:
@ -300,7 +342,7 @@ psi_parse_pmt(th_transport_t *t, uint8_t *ptr, int len, int chksvcid)
switch(dtag) {
case DVB_DESC_CA:
update |= psi_desc_ca(t, ptr);
update |= psi_desc_ca(t, ptr, dlen);
break;
case DVB_DESC_VIDEO_STREAM:
@ -647,9 +689,13 @@ psi_save_transport_settings(htsmsg_t *m, th_transport_t *t)
if(st->st_lang[0])
htsmsg_add_str(sub, "language", st->st_lang);
if(st->st_type == SCT_CA)
if(st->st_type == SCT_CA) {
htsmsg_add_str(sub, "caid", psi_caid2name(st->st_caid));
if(st->st_providerid)
htsmsg_add_u32(sub, "caproviderid", st->st_providerid);
}
if(st->st_frame_duration)
htsmsg_add_u32(sub, "frameduration", st->st_frame_duration);
@ -710,5 +756,7 @@ psi_load_transport_settings(htsmsg_t *m, th_transport_t *t)
i = str2val(v, caidnametab);
st->st_caid = i < 0 ? strtol(v, NULL, 0) : i;
}
htsmsg_get_u32(c, "caproviderid", &st->st_providerid);
}
}

View file

@ -306,6 +306,7 @@ typedef struct th_stream {
/* ca id for this stream */
uint16_t st_caid;
uint32_t st_providerid;
/* Remuxing information */
AVRational st_tb;