Merge remote-tracking branch 'upstream/master' into freebsd

* upstream/master:
  mpegts service: Add documentation for Lock Pref. CA PID
  cwc: little log fix (auto-reconnect)...
  mpegts dvb service: add CA PID filter (lock) mode 2 to force CA PID
  service: fix some compiler warnings
  cwc/mpegts dvb service: prevent auto-changes for prefcaid (see issue #2075)
  cwc: change the multiple CA PID handling
This commit is contained in:
Dreamcat4 2014-07-30 20:15:33 +01:00
commit c168cb3adc
6 changed files with 83 additions and 31 deletions

View file

@ -51,6 +51,17 @@
<dt>Pref. CA PID
<dd>The Preferred Conditional Access Packet Identifier. Used for decrypting scrambled streams.
<dt>Lock Pref. CA PID
<dd>The locking mechanism selection for The Preferred Conditional Access Packet Identifier.
<dl>
<dt>Off
<dd>Automatic Preferred Conditional Access Packet Identifier selection.
<dt>On
<dd>Keep Preferred Conditional Access Packet Identifier selection (no automatic modifications allowed).
<dt>Only Pref. CA PID
<dd>Filter mode - use only Preferred Conditional Access Packet Identifier for the streams decryption.
</dl>
<dt>Character Set
<dd>The character encoding for this service (e.g. UTF-8).

View file

@ -1530,6 +1530,9 @@ capmt_caid_change(th_descrambler_t *td)
lock_assert(&t->s_stream_mutex);
TAILQ_FOREACH(st, &t->s_filt_components, es_filt_link) {
if (t->s_dvb_prefcapid_lock == 2 &&
t->s_dvb_prefcapid != st->es_pid)
continue;
LIST_FOREACH(c, &st->es_caids, link) {
/* search ecmpid in list */
LIST_FOREACH(cce, &ct->ct_caid_ecm, cce_link)
@ -1809,6 +1812,9 @@ capmt_service_start(service_t *s)
pthread_mutex_lock(&t->s_stream_mutex);
TAILQ_FOREACH(st, &t->s_filt_components, es_filt_link) {
caid_t *c;
if (t->s_dvb_prefcapid_lock == 2 &&
t->s_dvb_prefcapid != st->es_pid)
continue;
LIST_FOREACH(c, &st->es_caids, link) {
if(c == NULL || c->use == 0)
continue;

View file

@ -101,6 +101,7 @@ typedef struct ecm_section {
uint16_t es_seq;
char es_nok;
char es_pending;
char es_resolved;
int64_t es_time; // time request was sent
size_t es_ecmsize;
uint8_t es_ecm[4070];
@ -711,10 +712,12 @@ handle_ecm_reply(cwc_service_t *ct, ecm_section_t *es, uint8_t *msg,
{
mpegts_service_t *t = (mpegts_service_t *)ct->td_service;
th_descrambler_t *td;
ecm_pid_t *ep, *epn;
ecm_pid_t *ep;
ecm_section_t *es2;
char chaninfo[32];
int i;
int i, j;
int64_t delay = (getmonoclock() - es->es_time) / 1000LL; // in ms
es->es_pending = 0;
snprintf(chaninfo, sizeof(chaninfo), " (PID %d)", es->es_channel);
@ -749,17 +752,20 @@ 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++)
if(ep->ep_sections[i] == NULL) {
if(es->es_nok < 2) /* only first hit is allowed */
return;
} else {
if(ep->ep_sections[i]->es_pending ||
ep->ep_sections[i]->es_nok == 0)
for(i = 0; i <= ep->ep_last_section; i++) {
es2 = ep->ep_sections[i];
if(es2 && es2 != es && es2->es_nok == 0) {
if (es2->es_pending)
return;
j++;
}
}
}
if (j && es->es_nok < 2) /* only first hit is allowed */
return;
tvhlog(LOG_ERR, "cwc",
"Can not descramble service \"%s\", access denied (seqno: %d "
"Req delay: %"PRId64" ms) from %s",
@ -776,7 +782,9 @@ forbid:
ct->cs_channel = es->es_channel;
ct->ecm_state = ECM_VALID;
if(t->s_dvb_prefcapid == 0 || t->s_dvb_prefcapid != ct->cs_channel) {
if(t->s_dvb_prefcapid == 0 ||
(t->s_dvb_prefcapid != ct->cs_channel &&
t->s_dvb_prefcapid_lock == 0)) {
t->s_dvb_prefcapid = ct->cs_channel;
tvhlog(LOG_DEBUG, "cwc", "Saving prefered PID %d for %s",
t->s_dvb_prefcapid, ct->td_nicename);
@ -802,20 +810,13 @@ forbid:
descrambler_keys((th_descrambler_t *)ct, msg + 3, msg + 3 + 8);
ep = LIST_FIRST(&ct->cs_pids);
while(ep != NULL) {
if (ct->cs_channel == ep->ep_pid) {
ep = LIST_NEXT(ep, ep_link);
}
else {
epn = LIST_NEXT(ep, ep_link);
for(i = 0; i < 256; i++)
free(ep->ep_sections[i]);
LIST_REMOVE(ep, ep_link);
tvhlog(LOG_WARNING, "cwc", "Delete ECM (PID %d) for service \"%s\" from %s",
ep->ep_pid, t->s_dvb_svcname, ct->td_nicename);
free(ep);
ep = epn;
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;
}
}
}
}
@ -848,9 +849,19 @@ cwc_running_reply(cwc_t *cwc, uint8_t msgtype, uint8_t *msg, int len)
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;
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;
}
}
}
}
@ -1194,8 +1205,8 @@ cwc_thread(void *aux)
ts.tv_nsec = 0;
tvhlog(LOG_INFO, "cwc",
"%s:%i: Automatic connection attempt in in %d seconds",
cwc->cwc_hostname, cwc->cwc_port, d);
"%s:%i: Automatic connection attempt in %d seconds",
cwc->cwc_hostname, cwc->cwc_port, d-1);
pthread_cond_timedwait(&cwc_config_changed, &cwc_mutex, &ts);
}
@ -1735,6 +1746,7 @@ cwc_table_input(void *opaque, int pid, const uint8_t *data, int len)
es->es_channel = channel;
es->es_section = section;
es->es_pending = 1;
es->es_resolved = 0;
memcpy(es->es_ecm, data, len);
es->es_ecmsize = len;
@ -1980,6 +1992,9 @@ cwc_service_start(service_t *t)
LIST_FOREACH(pcard, &cwc->cwc_cards, cs_card) {
if (pcard->cwc_caid == 0) continue;
TAILQ_FOREACH(st, &t->s_filt_components, es_filt_link) {
if (((mpegts_service_t *)t)->s_dvb_prefcapid_lock == 2 &&
((mpegts_service_t *)t)->s_dvb_prefcapid != st->es_pid)
continue;
LIST_FOREACH(c, &st->es_caids, link) {
if (c->use && c->caid == pcard->cwc_caid)
break;

View file

@ -428,6 +428,7 @@ struct mpegts_service
uint16_t s_dvb_servicetype;
char *s_dvb_charset;
uint16_t s_dvb_prefcapid;
int s_dvb_prefcapid_lock;
/*
* EIT/EPG control

View file

@ -55,6 +55,17 @@ mpegts_service_class_get_network ( void *ptr )
return &s;
}
static htsmsg_t *
mpegts_service_pref_capid_lock_list ( void *o )
{
static const struct strtab tab[] = {
{ "Off", 0 },
{ "On", 1 },
{ "Only Pref. CA PID", 2 },
};
return strtab2htsmsg(tab);
}
const idclass_t mpegts_service_class =
{
.ic_super = &service_class,
@ -133,6 +144,14 @@ const idclass_t mpegts_service_class =
.off = offsetof(mpegts_service_t, s_dvb_prefcapid),
.opts = PO_ADVANCED,
},
{
.type = PT_INT,
.id = "prefcapid_lock",
.name = "Lock Pref. CA PID",
.off = offsetof(mpegts_service_t, s_dvb_prefcapid_lock),
.opts = PO_ADVANCED,
.list = mpegts_service_pref_capid_lock_list,
},
{},
}
};

View file

@ -405,9 +405,9 @@ filter:
ca = NULL;
if ((esf->esf_caid != (uint16_t)-1 || esf->esf_caprovider != -1)) {
LIST_FOREACH(ca, &st->es_caids, link) {
if (esf->esf_caid != -1 && ca->caid != esf->esf_caid)
if (esf->esf_caid != (uint16_t)-1 && ca->caid != esf->esf_caid)
continue;
if (esf->esf_caprovider != -1 && ca->providerid != esf->esf_caprovider)
if (esf->esf_caprovider != (uint32_t)-1 && ca->providerid != esf->esf_caprovider)
continue;
break;
}