Avoid mixing up keys from different pids

This commit is contained in:
Andreas Öman 2010-06-27 22:17:24 +00:00
parent 44a407c0d7
commit 3db2a37b25

View file

@ -99,7 +99,7 @@ static pthread_cond_t cwc_config_changed;
typedef struct ecm_section {
int es_section;
int es_channel;
uint16_t es_seq;
char es_nok;
char es_pending;
@ -110,6 +110,19 @@ typedef struct ecm_section {
} ecm_section_t;
/**
*
*/
typedef struct ecm_pid {
LIST_ENTRY(ecm_pid) ep_link;
uint16_t ep_pid;
int ep_last_section;
struct ecm_section *ep_sections[256];
} ecm_pid_t;
/**
*
*/
@ -142,8 +155,7 @@ typedef struct cwc_transport {
uint8_t *ct_tsbcluster;
int ct_fill;
int ct_last_section;
struct ecm_section *ct_sections[256];
LIST_HEAD(, ecm_pid) ct_pids;
} cwc_transport_t;
@ -651,6 +663,7 @@ handle_ecm_reply(cwc_transport_t *ct, ecm_section_t *es, uint8_t *msg,
int len, int seq)
{
th_transport_t *t = ct->ct_transport;
ecm_pid_t *ep;
char chaninfo[32];
int i;
@ -677,12 +690,13 @@ handle_ecm_reply(cwc_transport_t *ct, ecm_section_t *es, uint8_t *msg,
tvhlog(LOG_DEBUG, "cwc", "Received NOK for service \"%s\"%s (seqno: %d)",
t->tht_svcname, chaninfo, seq);
for(i = 0; i <= ct->ct_last_section; i++)
if(ct->ct_sections[i] == NULL ||
ct->ct_sections[i]->es_pending ||
ct->ct_sections[i]->es_nok == 0)
return;
LIST_FOREACH(ep, &ct->ct_pids, ep_link) {
for(i = 0; i <= ep->ep_last_section; i++)
if(ep->ep_sections[i] == NULL ||
ep->ep_sections[i]->es_pending ||
ep->ep_sections[i]->es_nok == 0)
return;
}
tvhlog(LOG_ERR, "cwc",
"Can not descramble service \"%s\", access denied (seqno: %d)",
t->tht_svcname, seq);
@ -737,6 +751,7 @@ static int
cwc_running_reply(cwc_t *cwc, uint8_t msgtype, uint8_t *msg, int len)
{
cwc_transport_t *ct;
ecm_pid_t *ep;
ecm_section_t *es;
uint16_t seq = (msg[2] << 8) | msg[3];
int i;
@ -748,12 +763,14 @@ cwc_running_reply(cwc_t *cwc, uint8_t msgtype, uint8_t *msg, int len)
case 0x80:
case 0x81:
LIST_FOREACH(ct, &cwc->cwc_transports, ct_link) {
for(i = 0; i <= ct->ct_last_section; i++) {
es = ct->ct_sections[i];
if(es != NULL) {
if(es->es_seq == seq && es->es_pending) {
handle_ecm_reply(ct, es, msg, len, seq);
return 0;
LIST_FOREACH(ep, &ct->ct_pids, ep_link) {
for(i = 0; i <= ep->ep_last_section; i++) {
es = ep->ep_sections[i];
if(es != NULL) {
if(es->es_seq == seq && es->es_pending) {
handle_ecm_reply(ct, es, msg, len, seq);
return 0;
}
}
}
}
@ -1203,6 +1220,7 @@ cwc_table_input(struct th_descrambler *td, struct th_transport *t,
cwc_t *cwc = ct->ct_cwc;
int channel;
int section;
ecm_pid_t *ep;
ecm_section_t *es;
char chaninfo[32];
caid_t *c;
@ -1213,6 +1231,18 @@ cwc_table_input(struct th_descrambler *td, struct th_transport *t,
if((data[0] & 0xf0) != 0x80)
return;
LIST_FOREACH(ep, &ct->ct_pids, ep_link) {
if(ep->ep_pid == st->st_pid)
break;
}
if(ep == NULL) {
ep = calloc(1, sizeof(ecm_pid_t));
ep->ep_pid = st->st_pid;
LIST_INSERT_HEAD(&ct->ct_pids, ep, ep_link);
}
LIST_FOREACH(c, &st->st_caids, link) {
if(cwc->cwc_caid == c->caid)
break;
@ -1232,19 +1262,19 @@ cwc_table_input(struct th_descrambler *td, struct th_transport *t,
if(cwc->cwc_caid >> 8 == 6) {
channel = data[6] << 8 | data[7];
snprintf(chaninfo, sizeof(chaninfo), " (channel %d)", channel);
ct->ct_last_section = data[5];
ep->ep_last_section = data[5];
section = data[4];
} else {
channel = -1;
chaninfo[0] = 0;
ct->ct_last_section = 0;
ep->ep_last_section = 0;
section = 0;
}
if(ct->ct_sections[section] == NULL)
ct->ct_sections[section] = calloc(1, sizeof(ecm_section_t));
if(ep->ep_sections[section] == NULL)
ep->ep_sections[section] = calloc(1, sizeof(ecm_section_t));
es = ct->ct_sections[section];
es = ep->ep_sections[section];
if(es->es_ecmsize == len && !memcmp(es->es_ecm, data, len))
break; /* key already sent */
@ -1271,8 +1301,9 @@ cwc_table_input(struct th_descrambler *td, struct th_transport *t,
es->es_seq = cwc_send_msg(cwc, data, len, sid, 1);
tvhlog(LOG_DEBUG, "cwc",
"Sending ECM%s section=%d/%d, for service %s (seqno: %d)",
chaninfo, section, ct->ct_last_section, t->tht_svcname, es->es_seq);
"Sending ECM%s section=%d/%d, for service %s (seqno: %d) PID %d",
chaninfo, section, ep->ep_last_section, t->tht_svcname, es->es_seq,
st->st_pid);
break;
default:
@ -1343,10 +1374,15 @@ static void
cwc_transport_destroy(th_descrambler_t *td)
{
cwc_transport_t *ct = (cwc_transport_t *)td;
ecm_pid_t *ep;
int i;
for(i = 0; i < 256; i++)
free(ct->ct_sections[i]);
while((ep = LIST_FIRST(&ct->ct_pids)) != NULL) {
for(i = 0; i < 256; i++)
free(ep->ep_sections[i]);
LIST_REMOVE(ep, ep_link);
free(ep);
}
LIST_REMOVE(td, td_transport_link);