cwc: use list for ep_sections rather than an array
This commit is contained in:
parent
4bce3dc4ae
commit
bdb31c36a2
1 changed files with 44 additions and 48 deletions
|
@ -50,6 +50,7 @@
|
|||
#define TVHEADEND_PROTOCOL_ID 0x6502
|
||||
#define CWC_KEEPALIVE_INTERVAL 30
|
||||
#define CWC_ES_PIDS 8
|
||||
#define CWC_MAX_NOKS 4
|
||||
|
||||
#define CWS_NETMSGSIZE 362
|
||||
#define CWS_FIRSTCMDNO 0xe0
|
||||
|
@ -95,6 +96,8 @@ static char *crypt_md5(const char *pw, const char *salt);
|
|||
*
|
||||
*/
|
||||
typedef struct ecm_section {
|
||||
LIST_ENTRY(ecm_section) es_link;
|
||||
|
||||
int es_section;
|
||||
int es_channel;
|
||||
|
||||
|
@ -118,7 +121,7 @@ typedef struct ecm_pid {
|
|||
uint16_t ep_pid;
|
||||
|
||||
int ep_last_section;
|
||||
struct ecm_section *ep_sections[256];
|
||||
LIST_HEAD(, ecm_section) ep_sections;
|
||||
} ecm_pid_t;
|
||||
|
||||
|
||||
|
@ -716,7 +719,7 @@ handle_ecm_reply(cwc_service_t *ct, ecm_section_t *es, uint8_t *msg,
|
|||
ecm_pid_t *ep;
|
||||
ecm_section_t *es2;
|
||||
char chaninfo[32];
|
||||
int i, j;
|
||||
int i;
|
||||
int64_t delay = (getmonoclock() - es->es_time) / 1000LL; // in ms
|
||||
|
||||
es->es_pending = 0;
|
||||
|
@ -727,7 +730,7 @@ handle_ecm_reply(cwc_service_t *ct, ecm_section_t *es, uint8_t *msg,
|
|||
|
||||
/* ERROR */
|
||||
|
||||
if (es->es_nok < 3)
|
||||
if (es->es_nok < CWC_MAX_NOKS)
|
||||
es->es_nok++;
|
||||
|
||||
if(ct->td_keystate == DS_FORBIDDEN)
|
||||
|
@ -753,18 +756,15 @@ handle_ecm_reply(cwc_service_t *ct, ecm_section_t *es, uint8_t *msg,
|
|||
"Req delay: %"PRId64" ms)", t->s_dvb_svcname, chaninfo, seq, delay);
|
||||
|
||||
forbid:
|
||||
j = 0;
|
||||
LIST_FOREACH(ep, &ct->cs_pids, ep_link) {
|
||||
for(i = 0; i <= ep->ep_last_section; i++) {
|
||||
es2 = ep->ep_sections[i];
|
||||
i = 0;
|
||||
LIST_FOREACH(ep, &ct->cs_pids, ep_link)
|
||||
LIST_FOREACH(es2, &ep->ep_sections, es_link)
|
||||
if(es2 && es2 != es && es2->es_nok == 0) {
|
||||
if (es2->es_pending)
|
||||
return;
|
||||
j++;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (j && es->es_nok < 2) /* only first hit is allowed */
|
||||
if (i && es->es_nok < 2) /* only first hit is allowed */
|
||||
return;
|
||||
|
||||
tvhlog(LOG_ERR, "cwc",
|
||||
|
@ -834,15 +834,11 @@ forbid:
|
|||
|
||||
descrambler_keys((th_descrambler_t *)ct, DESCRAMBLER_AES, msg + 3, msg + 3 + 16);
|
||||
}
|
||||
LIST_FOREACH(ep, &ct->cs_pids, ep_link) {
|
||||
for(i = 0; i < ep->ep_last_section; i++) {
|
||||
es2 = ep->ep_sections[i];
|
||||
if (es2) {
|
||||
es2->es_resolved = 1;
|
||||
es2->es_pending = 0;
|
||||
}
|
||||
LIST_FOREACH(ep, &ct->cs_pids, ep_link)
|
||||
LIST_FOREACH(es2, &ep->ep_sections, es_link) {
|
||||
es2->es_resolved = 1;
|
||||
es2->es_pending = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -858,7 +854,7 @@ cwc_running_reply(cwc_t *cwc, uint8_t msgtype, uint8_t *msg, int len)
|
|||
ecm_pid_t *ep;
|
||||
ecm_section_t *es;
|
||||
uint16_t seq = (msg[2] << 8) | msg[3];
|
||||
int plen,i;
|
||||
int plen;
|
||||
short caid;
|
||||
const char *n;
|
||||
unsigned int nprov;
|
||||
|
@ -868,29 +864,23 @@ cwc_running_reply(cwc_t *cwc, uint8_t msgtype, uint8_t *msg, int len)
|
|||
case 0x81:
|
||||
len -= 12;
|
||||
msg += 12;
|
||||
LIST_FOREACH(ct, &cwc->cwc_services, cs_link) {
|
||||
LIST_FOREACH(ep, &ct->cs_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) {
|
||||
if (es->es_resolved) {
|
||||
mpegts_service_t *t = (mpegts_service_t *)ct->td_service;
|
||||
tvhlog(LOG_WARNING, "cwc",
|
||||
"Ignore %sECM (PID %d) for service \"%s\" from %s (seq %i)",
|
||||
es->es_pending ? "duplicate " : "",
|
||||
ep->ep_pid, t->s_dvb_svcname, ct->td_nicename, es->es_seq);
|
||||
return 0;
|
||||
}
|
||||
if (es->es_pending) {
|
||||
handle_ecm_reply(ct, es, msg, len, seq);
|
||||
return 0;
|
||||
}
|
||||
LIST_FOREACH(ct, &cwc->cwc_services, cs_link)
|
||||
LIST_FOREACH(ep, &ct->cs_pids, ep_link)
|
||||
LIST_FOREACH(es, &ep->ep_sections, es_link)
|
||||
if(es->es_seq == seq) {
|
||||
if (es->es_resolved) {
|
||||
mpegts_service_t *t = (mpegts_service_t *)ct->td_service;
|
||||
tvhlog(LOG_WARNING, "cwc",
|
||||
"Ignore %sECM (PID %d) for service \"%s\" from %s (seq %i)",
|
||||
es->es_pending ? "duplicate " : "",
|
||||
ep->ep_pid, t->s_dvb_svcname, ct->td_nicename, es->es_seq);
|
||||
return 0;
|
||||
}
|
||||
if (es->es_pending) {
|
||||
handle_ecm_reply(ct, es, msg, len, seq);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
tvhlog(LOG_WARNING, "cwc", "Got unexpected ECM reply (seqno: %d)", seq);
|
||||
LIST_FOREACH(ct, &cwc->cwc_services, cs_link) {
|
||||
ct->ecm_state = ECM_RESET;
|
||||
|
@ -1757,10 +1747,14 @@ cwc_table_input(void *opaque, int pid, const uint8_t *data, int len)
|
|||
channel = pid;
|
||||
snprintf(chaninfo, sizeof(chaninfo), " (PID %d)", channel);
|
||||
|
||||
if(ep->ep_sections[section] == NULL)
|
||||
ep->ep_sections[section] = calloc(1, sizeof(ecm_section_t));
|
||||
|
||||
es = ep->ep_sections[section];
|
||||
LIST_FOREACH(es, &ep->ep_sections, es_link)
|
||||
if (es->es_section == section)
|
||||
break;
|
||||
if (es == NULL) {
|
||||
es = calloc(1, sizeof(ecm_section_t));
|
||||
es->es_section = section;
|
||||
LIST_INSERT_HEAD(&ep->ep_sections, es, es_link);
|
||||
}
|
||||
|
||||
if(es->es_ecmsize == len && !memcmp(es->es_ecm, data, len))
|
||||
break; /* key already sent */
|
||||
|
@ -1771,7 +1765,6 @@ cwc_table_input(void *opaque, int pid, const uint8_t *data, int len)
|
|||
break;
|
||||
}
|
||||
es->es_channel = channel;
|
||||
es->es_section = section;
|
||||
es->es_pending = 1;
|
||||
es->es_resolved = 0;
|
||||
|
||||
|
@ -1996,6 +1989,7 @@ cwc_service_destroy(th_descrambler_t *td)
|
|||
{
|
||||
cwc_service_t *ct = (cwc_service_t *)td;
|
||||
ecm_pid_t *ep;
|
||||
ecm_section_t *es;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CWC_ES_PIDS; i++)
|
||||
|
@ -2003,8 +1997,10 @@ cwc_service_destroy(th_descrambler_t *td)
|
|||
descrambler_close_pid(ct->cs_mux, ct, ct->cs_epids[i]);
|
||||
|
||||
while((ep = LIST_FIRST(&ct->cs_pids)) != NULL) {
|
||||
for(i = 0; i < 256; i++)
|
||||
free(ep->ep_sections[i]);
|
||||
while ((es = LIST_FIRST(&ep->ep_sections)) != NULL) {
|
||||
LIST_REMOVE(es, es_link);
|
||||
free(es);
|
||||
}
|
||||
LIST_REMOVE(ep, ep_link);
|
||||
free(ep);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue