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:
commit
c168cb3adc
6 changed files with 83 additions and 31 deletions
|
@ -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).
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
{},
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue