#include <netinet/in.h>
#include <arpa/inet.h>
#include <ctype.h>
-
#include "tvheadend.h"
#include "tcp.h"
#include "psi.h"
#include "atomic.h"
#include "dtable.h"
#include "subscriptions.h"
-
+#include "service.h"
#include <openssl/des.h>
/**
int len, int seq)
{
service_t *t = ct->cs_service;
+ ecm_pid_t *ep, *epn;
cwc_service_t *ct2;
cwc_t *cwc2;
- ecm_pid_t *ep;
char chaninfo[32];
int i;
int64_t delay = (getmonoclock() - es->es_time) / 1000LL; // in ms
/* ERROR */
- if(ct->cs_okchannel == es->es_channel)
- ct->cs_okchannel = -1;
-
if (es->es_nok < 3)
es->es_nok++;
} else {
ct->cs_okchannel = es->es_channel;
+ tvhlog(LOG_DEBUG, "cwc", "es->es_nok %d t->tht_prefcapid %d", es->es_nok, t->s_prefcapid);
+ if(es->es_nok == 1 || t->s_prefcapid == 0) {
+ t->s_prefcapid = ct->cs_okchannel;
+ service_request_save(t, 0);
+ }
es->es_nok = 0;
tvhlog(LOG_DEBUG, "cwc",
ct->cs_keystate = CS_RESOLVED;
memcpy(ct->cs_cw, msg + 3, 16);
ct->cs_pending_cw_update = 1;
+
+ ep = LIST_FIRST(&ct->cs_pids);
+ while(ep != NULL) {
+ if (ct->cs_okchannel == 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 ECMpid %d", ep->ep_pid);
+ free(ep);
+ ep = epn;
+ }
+ }
}
}
}
}
tvhlog(LOG_WARNING, "cwc", "Got unexpected ECM reply (seqno: %d)", seq);
+ LIST_FOREACH(ct, &cwc->cwc_services, cs_link) {
+ tvhlog(LOG_DEBUG, "cwc", "After got unexpected (ct->cs_okchannel: %d)", ct->cs_okchannel);
+ if (ct->cs_okchannel == -3) ct->cs_okchannel = -2;
+ }
break;
}
return 0;
}
if(ep == NULL) {
- ep = calloc(1, sizeof(ecm_pid_t));
- ep->ep_pid = st->es_pid;
- LIST_INSERT_HEAD(&ct->cs_pids, ep, ep_link);
+ if (ct->cs_okchannel == -2) {
+ t->s_prefcapid = 0;
+ ct->cs_okchannel = -1;
+ tvhlog(LOG_DEBUG, "cwc", "Insert after unexpected reply");
+ }
+
+ if (ct->cs_okchannel == -3 && t->s_prefcapid == st->es_pid) {
+ ep = calloc(1, sizeof(ecm_pid_t));
+ ep->ep_pid = t->s_prefcapid;
+ LIST_INSERT_HEAD(&ct->cs_pids, ep, ep_link);
+ tvhlog(LOG_DEBUG, "cwc", "Insert only one new ECM channel %d for service id %d", t->s_prefcapid, sid);
+ }
+
+ if (ct->cs_okchannel == -1 || (ct->cs_okchannel == -3 && t->s_prefcapid == 0)) {
+ ep = calloc(1, sizeof(ecm_pid_t));
+ ep->ep_pid = st->es_pid;
+ LIST_INSERT_HEAD(&ct->cs_pids, ep, ep_link);
+ tvhlog(LOG_DEBUG, "cwc", "Insert new ECM channel %d", st->es_pid);
+ }
+ else {
+ return;
+ }
}
section = 0;
}
+ channel = st->es_pid;
+ snprintf(chaninfo, sizeof(chaninfo), " (channel %d)", channel);
+
if(ep->ep_sections[section] == NULL)
ep->ep_sections[section] = calloc(1, sizeof(ecm_section_t));
memcpy(es->es_ecm, data, len);
es->es_ecmsize = len;
- if(ct->cs_okchannel != -1 && channel != -1 &&
+ if(ct->cs_okchannel >= 0 && channel != -1 &&
ct->cs_okchannel != channel) {
tvhlog(LOG_DEBUG, "cwc", "Filtering ECM channel %d", channel);
return;
ct->cs_keys = get_key_struct();
ct->cs_cwc = cwc;
ct->cs_service = t;
- ct->cs_okchannel = -1;
+ ct->cs_okchannel = -3;
td = &ct->cs_head;
td->td_stop = cwc_service_destroy;
if((chname = htsmsg_get_str(c, "channelname")) != NULL)
service_map_channel(t, channel_find_by_name(chname, 1, 0), 1);
+ if(!htsmsg_get_u32(c, "prefcapid", &u32))
+ service_set_prefcapid(t, u32);
+
if((dvb_charset = htsmsg_get_str(c, "dvb_charset")) != NULL)
service_set_dvb_charset(t, dvb_charset);
if(!htsmsg_get_u32(c, "enabled", &u32))
service_set_enable(t, u32);
+ if(!htsmsg_get_u32(c, "prefcapid", &u32))
+ service_set_prefcapid(t, u32);
+
if((chname = htsmsg_get_str(c, "channelname")) != NULL)
service_map_channel(t, channel_find_by_name(chname, 1, 0), 1);
dataIndex : 'sid',
width : 50,
hidden : true
+ }, {
+ header: "Preffered CA pid",
+ dataIndex: 'prefcapid',
+ width: 50,
+ editor: new fm.TextField({allowBlank: true})
}, {
header : "PMT PID",
dataIndex : 'pmt',
var store = new Ext.data.JsonStore({
root : 'entries',
fields : Ext.data.Record.create([ 'id', 'enabled', 'type', 'sid', 'pmt',
- 'pcr', 'svcname', 'network', 'provider', 'mux', 'channelname',
+ 'pcr', 'svcname', 'network', 'provider', 'mux', 'channelname', 'prefcapid',
'dvb_charset', 'dvb_eit_enable' ]),
url : "dvb/services/" + adapterId,
autoLoad : true,