### The object files (add further files here):
OBJS = $(PLUGIN).o data.o filter.o system.o misc.o cam.o version.o \
- smartcard.o network.o crypto.o system-common.o parse.o log.o
+ smartcard.o network.o crypto.o system-common.o parse.o log.o \
+ override.o
### Internationalization (I18N):
#include "filter.h"
#include "system.h"
#include "data.h"
+#include "override.h"
#include "misc.h"
#include "log-core.h"
class cLogChain : public cSimpleItem {
public:
- int cardNum, caid;
+ int cardNum, caid, source, transponder;
bool softCSA, active, delayed;
cTimeMs delay;
cPids pids;
cSimpleList<cSystem> systems;
//
- cLogChain(int CardNum, bool soft);
+ cLogChain(int CardNum, bool soft, int src, int tr);
void Process(int pid, unsigned char *data);
bool Parse(const unsigned char *cat);
};
-cLogChain::cLogChain(int CardNum, bool soft)
+cLogChain::cLogChain(int CardNum, bool soft, int src, int tr)
{
- cardNum=CardNum; softCSA=soft; active=delayed=false;
+ cardNum=CardNum; softCSA=soft; source=src; transponder=tr;
+ active=delayed=false;
}
void cLogChain::Process(int pid, unsigned char *data)
if(systems.Count()>0) {
LBPUT(" ++");
for(sys=systems.First(); sys; sys=systems.Next(sys))
- sys->ParseCAT(&pids,cat);
+ sys->ParseCAT(&pids,cat,source,transponder);
}
else {
LBPUT(" ->");
Pri=sys->Pri();
if(sys->HasLogger()) {
sys->CardNum(cardNum);
- sys->ParseCAT(&pids,cat);
+ sys->ParseCAT(&pids,cat,source,transponder);
systems.Add(sys);
LBPUT(" %s(%d)",sys->Name(),sys->Pri());
}
//
cPidFilter *catfilt;
int catVers;
+ int source, transponder;
//
enum ePreMode { pmNone, pmStart, pmWait, pmActive, pmStop };
ePreMode prescan;
void ClearChains(void);
void StartChain(cLogChain *chain);
void StopChain(cLogChain *chain, bool force);
+ void ProcessCat(unsigned char *data, int len);
protected:
virtual void Process(cPidFilter *filter, unsigned char *data, int len);
public:
void EcmStatus(const cEcmInfo *ecm, bool on);
void Up(void);
void Down(void);
- void PreScan(void);
+ void PreScan(int src, int tr);
};
cLogger::cLogger(int CardNum, bool soft)
Unlock();
}
-void cLogger::PreScan(void)
+void cLogger::PreScan(int src, int tr)
{
Lock();
+ source=src; transponder=tr;
prescan=pmStart; Up();
Unlock();
}
{
Lock();
PRINTF(L_CORE_AUEXTRA,"%d: ecm prgid=%d caid=%04x prov=%.4x %s",cardNum,ecm->prgId,ecm->caId,ecm->provId,on ? "active":"inactive");
+ source=ecm->source; transponder=ecm->transponder;
cEcmInfo *e;
if(on) {
e=new cEcmInfo(ecm);
return filter;
}
+void cLogger::ProcessCat(unsigned char *data, int len)
+{
+ for(int i=0; i<len; i+=data[i+1]+2) {
+ if(data[i]==0x09) {
+ int caid=WORD(data,i+2,0xFFFF);
+ cLogChain *chain;
+ for(chain=chains.First(); chain; chain=chains.Next(chain))
+ if(chain->caid==caid) break;
+ if(chain)
+ chain->Parse(&data[i]);
+ else {
+ chain=new cLogChain(cardNum,softCSA,source,transponder);
+ if(chain->Parse(&data[i]))
+ chains.Add(chain);
+ else
+ delete chain;
+ }
+ }
+ }
+}
+
void cLogger::Process(cPidFilter *filter, unsigned char *data, int len)
{
if(data && len>0) {
catVers=vers;
HEXDUMP(L_HEX_CAT,data,len,"CAT vers %02x",catVers);
ClearChains();
- for(int i=8; i<len-4; i+=data[i+1]+2) {
- if(data[i]==0x09) {
- int caid=WORD(data,i+2,0xFFFF);
- cLogChain *chain;
- for(chain=chains.First(); chain; chain=chains.Next(chain))
- if(chain->caid==caid) break;
- if(chain)
- chain->Parse(&data[i]);
- else {
- chain=new cLogChain(cardNum,softCSA);
- if(chain->Parse(&data[i]))
- chains.Add(chain);
- else
- delete chain;
- }
- }
+ ProcessCat(&data[8],len-4-8);
+ unsigned char buff[2048];
+ if((len=overrides.GetCat(source,transponder,buff,sizeof(buff)))>0) {
+ HEXDUMP(L_HEX_CAT,buff,len,"override CAT");
+ ProcessCat(buff,len);
}
SetChains();
if(prescan==pmStart) { prescan=pmWait; pretime.Set(2000); }
cEcmInfo *n;
while((n=ecms.First())) {
ecms.Del(n,false);
+ overrides.UpdateEcm(ecm,dolog);
LBSTARTF(L_CORE_ECM);
- if(dolog) LBPUT("%s: found %04x (%s) id %04x with ecm %x ",id,n->caId,n->name,n->provId,n->ecm_pid);
+ if(dolog) LBPUT("%s: found %04x(%04x) (%s) id %04x with ecm %x/%x ",id,n->caId,n->emmCaId,n->name,n->provId,n->ecm_pid,n->ecm_table);
cEcmInfo *e=ecmList.First();
while(e) {
if(e->ecm_pid==n->ecm_pid) {
{
if(ScSetup.PrestartAU) {
LogStartup();
- if(logger) logger->PreScan();
+ if(logger) logger->PreScan(source,transponder);
}
}
--- /dev/null
+;
+; Comment lines can start with # or ;
+;
+
+; NOTE: everything which was hardcoded to SC before has been added as an active
+; example to this file.
+; But the entries may already be out-dated at the time you are reading this.
+; Please feel free to submit updates on this...
+
+;
+; In general every entry has a validity range, specified by caid/source/freq or
+; source/freq. The validity range is enclosed with {} brakets. Some specifiers
+; may be obmited, but you cannot omit the ':' delimiters.
+;
+; format:
+; {caid[-caid]:[src[-src]]:[freq[-freq]]}
+; {src[-src]:[freq[-freq]]}
+;
+; examples:
+; matches caid 1815-1830 on sat 19.2E. Freqency is empty, so match all.
+; {1815-1830:S19.2E:}
+; same, but only matches on one frequency
+; {1815-1830:S19.2E:12973}
+; matches a lot of NA sats, all frequencies
+; {S61.5W-S148W:}
+; matches a single caid on a single sat
+; {1801:S28.5E:}
+; matches a frequency range on a sat
+; {S13W:10500-11674}
+; matches a caid on everything
+; {1234::}
+;
+
+;
+; Add entries to the CAT (conditional access table) in case a EMM stream is
+; not announced there.
+;
+; format
+; cat:{src[-src]:[freq[-freq]]}caid:pid
+;
+; examples:
+; cat:{S61.5W-S148W:}1816:0120
+;
+cat:{S61.5W-S148W:}1816:0120 # DISH N3
+
+;
+; Define an alternative table for ECM data (default is 80/81)
+;
+; format:
+; ecmtable:{caid[-caid]:[src[-src]]:[freq[-freq]]}table
+;
+; examples:
+; ecmtable:{1234::}8E
+;
+ecmtable:{1234::}8E # DISH
+ecmtable:{1801:S82W:}8E # BEV
+ecmtable:{1801:S91W:}8E # BEV
+
+;
+; Define an alternative caid to use for EMM data.
+;
+; format:
+; emmcaid:{caid[-caid]:[src[-src]]:[freq[-freq]]}emmcaid
+;
+; examples
+; emmcaid:{1234::}1801
+; emmcaid:{1816:S61.5W-S148W:}1801
+;
+emmcaid:{1234::}1801 # DISH
+
+;
+; Define alternative table for EMM data
+;
+; format:
+; emmtable:{caid[-caid]:[src[-src]]:[freq[-freq]]}table[/mask][:table[/mask]][...]
+;
+; examples:
+; emmtable:{1816:S61.5W-S148W:}83:84
+; emmtable:{1815:S61.5W-S148W:}83:84
+; emmtable:{1811:S19.2E:}82/FE
+;
+emmtable:{1816:S61.5W-S148W:}83:84 # DISH N3
+emmtable:{1815:S61.5W-S148W:}83:84 # BEV N3
#define L_CORE_HOOK LCLASS(L_CORE,0x200000)
#define L_CORE_CIFULL LCLASS(L_CORE,0x400000)
#define L_CORE_CSAVERB LCLASS(L_CORE,0x800000)
+#define L_CORE_OVER LCLASS(L_CORE,0x1000000)
-#define L_CORE_ALL LALL(L_CORE_CSAVERB)
+#define L_CORE_ALL LALL(L_CORE_OVER)
#endif //___LOG_CORE_H
mods[m]=lm;
if(config[m]&LMOD_CFG_VALID) UpgradeOptions(m);
else SetModuleDefault(LCLASS(m,0));
-//printf("module %-16s added. mod=%x supp=%x def=%x cfg=%x\n",lm->Name,m,lm->OptSupported,lm->OptDefault,config[m]);
+//printf("module %-16s added. mod=%x supp=%08x def=%08x cfg=%08x\n",lm->Name,m,lm->OptSupported,lm->OptDefault,config[m]);
}
else Printf(L_GEN_DEBUG,"failed to add logging module %d (%s)",m,lm->Name);
return true;
--- /dev/null
+/*
+ * Softcam plugin to VDR (C++)
+ *
+ * This code is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This code is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <vdr/sources.h>
+
+#include "override.h"
+#include "misc.h"
+#include "log-core.h"
+
+// -- cValidityRange -----------------------------------------------------------
+
+cValidityRange::cValidityRange(void)
+{
+ fromCaid=toCaid=-1; fromSource=toSource=-1; fromFreq=toFreq=-1;
+}
+
+bool cValidityRange::Match(int caid, int source, int freq) const
+{
+ return (caid<0 || fromCaid<0 || (toCaid<0 && caid==fromCaid) || (caid>=fromCaid && caid<=toCaid)) &&
+ (fromSource<0 || (toSource<0 && source==fromSource) || (source>=fromSource && source<=toSource)) &&
+ (fromFreq<0 || (toFreq<0 && freq==fromFreq) || (freq>=fromFreq && freq<=toFreq));
+}
+
+char *cValidityRange::Parse3(char *s)
+{
+ bool log=true;
+ s=skipspace(s);
+ char *e=index(s,'}');
+ if(e && *s++=='{') {
+ *e=0; e=skipspace(e+1);
+ char *p;
+ if((p=index(s,':'))) {
+ *p=0;
+ if(ParseCaidRange(s)) {
+ s=p+1;
+ if((p=index(s,':'))) {
+ *p=0;
+ if(s==p || ParseSourceRange(s)) {
+ s=p+1;
+ if(!*s || ParseFreqRange(s)) return e;
+ }
+ log=false;
+ }
+ }
+ else log=false;
+ }
+ }
+ if(log) PRINTF(L_CORE_LOAD,"override: RANGE format error");
+ return 0;
+}
+
+char *cValidityRange::Parse2(char *s)
+{
+ bool log=true;
+ s=skipspace(s);
+ char *e=index(s,'}');
+ if(e && *s++=='{') {
+ *e=0; e=skipspace(e+1);
+ char *p;
+ if((p=index(s,':'))) {
+ *p=0;
+ if(ParseSourceRange(s)) {
+ s=p+1;
+ if(!*s || ParseFreqRange(s)) return e;
+ }
+ log=false;
+ }
+ }
+ if(log) PRINTF(L_CORE_LOAD,"override: RANGE format error");
+ return 0;
+}
+
+bool cValidityRange::ParseCaidRange(const char *str)
+{
+ if(sscanf(str,"%x-%x",&fromCaid,&toCaid)<1) {
+ PRINTF(L_CORE_LOAD,"override: CAID format error");
+ return false;
+ }
+ if(fromCaid<0x0001 || fromCaid>0xFFFF ||
+ (toCaid>0 && (toCaid<0x0001 || toCaid>0xFFFF || fromCaid>toCaid))) {
+ PRINTF(L_CORE_LOAD,"override: CAID range error");
+ return false;
+ }
+ return true;
+}
+
+bool cValidityRange::ParseFreqRange(const char *str)
+{
+ if(sscanf(str,"%d-%d",&fromFreq,&toFreq)<1) {
+ PRINTF(L_CORE_LOAD,"override: FREQ format error");
+ return false;
+ }
+ if(fromFreq<1 || fromFreq>50000 ||
+ (toFreq>0 && (toFreq<1 || toFreq>50000 || fromFreq>toFreq))) {
+ PRINTF(L_CORE_LOAD,"override: FREQ range error");
+ return false;
+ }
+ return true;
+}
+
+bool cValidityRange::ParseSourceRange(const char *str)
+{
+ bool res=false;
+ int l;
+ char *s1=0, *s2=0;
+ if((l=sscanf(str,"%a[^-:]-%a[^-:]",&s1,&s2))>=1) {
+ if(s1 && (fromSource=cSource::FromString(s1))>0 &&
+ (l<2 || (s2 && (toSource=cSource::FromString(s2))>0))) {
+ if(cSource::IsSat(fromSource) && (toSource<0 || (cSource::IsSat(toSource) && toSource>fromSource))) {
+ res=true;
+ }
+ else PRINTF(L_CORE_LOAD,"override: SOURCE range error");
+ }
+ else PRINTF(L_CORE_LOAD,"override: SOURCE parse error");
+ }
+ else PRINTF(L_CORE_LOAD,"override: SOURCE format error");
+ free(s1); free(s2);
+ return res;
+}
+
+cString cValidityRange::Print(void)
+{
+ char buff[256];
+ int q=0;
+ if(fromCaid>0) {
+ q+=snprintf(buff+q,sizeof(buff)-q,"%04x",fromCaid);
+ if(toCaid>0)
+ q+=snprintf(buff+q,sizeof(buff)-q,"-%04x",toCaid);
+ q+=snprintf(buff+q,sizeof(buff)-q,":");
+ }
+ if(fromSource>0) {
+ q+=snprintf(buff+q,sizeof(buff)-q,"%s",*cSource::ToString(fromSource));
+ if(toSource>0)
+ q+=snprintf(buff+q,sizeof(buff)-q,"-%s",*cSource::ToString(toSource));
+ }
+ q+=snprintf(buff+q,sizeof(buff)-q,":");
+ if(fromFreq>0) {
+ q+=snprintf(buff+q,sizeof(buff)-q,"%d",fromFreq);
+ if(toFreq>0)
+ q+=snprintf(buff+q,sizeof(buff)-q,"-%d",toFreq);
+ }
+ return buff;
+}
+
+// -- cOverride ----------------------------------------------------------------
+
+#define OV_CAT 1
+#define OV_EMMCAID 2
+#define OV_ECMTABLE 3
+#define OV_EMMTABLE 4
+
+// -- cOverrideCat -------------------------------------------------------------
+
+class cOverrideCat : public cOverride {
+private:
+ int caid, pid;
+public:
+ cOverrideCat(void) { type=OV_CAT; }
+ virtual bool Parse(char *str);
+ int GetCatEntry(unsigned char *buff);
+ };
+
+bool cOverrideCat::Parse(char *str)
+{
+ if((str=Parse2(str))) {
+ if(sscanf(str,"%x:%x",&caid,&pid)==2) {
+ PRINTF(L_CORE_OVER,"cat: %s - caid %04x pid %04x",*Print(),caid,pid);
+ return true;
+ }
+ PRINTF(L_CORE_LOAD,"override: CAT format error");
+ }
+ return false;
+}
+
+int cOverrideCat::GetCatEntry(unsigned char *buff)
+{
+ PRINTF(L_CORE_OVER,"cat: added caid %04x pid %04x",caid,pid);
+ buff[0]=0x09;
+ buff[1]=0x04;
+ buff[2]=(caid>>8)&0xFF;
+ buff[3]= caid &0xFF;
+ buff[4]=(pid >>8)&0xFF;
+ buff[5]= pid &0xFF;
+ return 6;
+}
+
+// -- cOverrideEmmCaid ---------------------------------------------------------
+
+class cOverrideEmmCaid : public cOverride {
+private:
+ int caid;
+public:
+ cOverrideEmmCaid(void) { type=OV_EMMCAID; }
+ virtual bool Parse(char *str);
+ int GetCaid(bool log);
+ };
+
+bool cOverrideEmmCaid::Parse(char *str)
+{
+ if((str=Parse3(str))) {
+ if(sscanf(str,"%x",&caid)==1) {
+ PRINTF(L_CORE_OVER,"emmcaid: %s - caid %04x",*Print(),caid);
+ return true;
+ }
+ PRINTF(L_CORE_LOAD,"override: EMMCAID format error");
+ }
+ return false;
+}
+
+int cOverrideEmmCaid::GetCaid(bool log)
+{
+ if(log) PRINTF(L_CORE_OVER,"emmcaid: %04x",caid);
+ return caid;
+}
+
+// -- cOverrideEcmTable --------------------------------------------------------
+
+class cOverrideEcmTable : public cOverride {
+private:
+ int table;
+public:
+ cOverrideEcmTable(void) { type=OV_ECMTABLE; }
+ virtual bool Parse(char *str);
+ int GetTable(bool log);
+ };
+
+bool cOverrideEcmTable::Parse(char *str)
+{
+ if((str=Parse3(str))) {
+ if(sscanf(str,"%x",&table)==1) {
+ PRINTF(L_CORE_OVER,"ecmtable: %s - table %02x",*Print(),table);
+ return true;
+ }
+ PRINTF(L_CORE_LOAD,"override: ECMTABLE format error");
+ }
+ return false;
+}
+
+int cOverrideEcmTable::GetTable(bool log)
+{
+ if(log) PRINTF(L_CORE_OVER,"ecmtable: %02x",table);
+ return table;
+}
+
+// -- cOverrideEmmTable --------------------------------------------------------
+
+#define OV_MAXTABLES 4
+
+class cOverrideEmmTable : public cOverride {
+public:
+ int num, table[OV_MAXTABLES], mask[OV_MAXTABLES];
+ //
+ cOverrideEmmTable(void) { type=OV_EMMTABLE; }
+ virtual bool Parse(char *str);
+ void AddPids(cPids *pids, int pid, int caid);
+ };
+
+bool cOverrideEmmTable::Parse(char *str)
+{
+ if((str=Parse3(str))) {
+ num=0;
+ int n=-1;
+ do {
+ mask[num]=0xFF;
+ int l=n+1;
+ if(sscanf(&str[l],"%x%n/%x%n",&table[num],&n,&mask[num],&n)<1) {
+ PRINTF(L_CORE_LOAD,"override: EMMTABLE format error");
+ return false;
+ }
+ n+=l; num++;
+ } while(num<OV_MAXTABLES && str[n]==':');
+ LBSTART(L_CORE_OVER);
+ LBPUT("emmtable: %s - tables",*Print());
+ for(int i=0; i<num; i++) LBPUT(" %02x/%02x",table[i],mask[i]);
+ LBEND();
+ return true;
+ }
+ return false;
+}
+
+void cOverrideEmmTable::AddPids(cPids *pids, int pid, int caid)
+{
+ LBSTARTF(L_CORE_OVER);
+ LBPUT("emmtable: %04x:",caid);
+ for(int i=0; i<num; i++) {
+ LBPUT(" %02x/%02x",table[i],mask[i]);
+ pids->AddPid(pid,table[i],mask[i]);
+ }
+ LBEND();
+}
+
+// -- cOverrides ---------------------------------------------------------------
+
+cOverrides overrides;
+
+cOverrides::cOverrides(void)
+:cStructList<cOverride>("overrides","override.conf",SL_MISSINGOK|SL_WATCH|SL_VERBOSE)
+{}
+
+cOverride *cOverrides::ParseLine(char *line)
+{
+ cOverride *ov=0;
+ line=skipspace(line);
+ char *p=index(line,':');
+ if(p) {
+ *p++=0;
+ if(!strncasecmp(line,"cat",3)) ov=new cOverrideCat;
+ else if(!strncasecmp(line,"emmcaid",7)) ov=new cOverrideEmmCaid;
+ else if(!strncasecmp(line,"ecmtable",8)) ov=new cOverrideEcmTable;
+ else if(!strncasecmp(line,"emmtable",8)) ov=new cOverrideEmmTable;
+ if(ov && !ov->Parse(p)) { delete ov; ov=0; }
+ }
+ return ov;
+}
+
+cOverride *cOverrides::Find(int type, int caid, int source, int freq, cOverride *ov)
+{
+ for(ov=ov?Next(ov):First(); ov; ov=Next(ov))
+ if(ov->Type()==type && ov->Match(caid,source,freq)) break;
+ return ov;
+}
+
+int cOverrides::GetCat(int source, int transponder, unsigned char *buff, int len)
+{
+ int n=0;
+ ListLock(false);
+ for(cOverride *ov=0; (ov=Find(OV_CAT,-1,source,transponder%100000,ov)) && n<len-32;) {
+ cOverrideCat *ovc=dynamic_cast<cOverrideCat *>(ov);
+ if(ovc) n+=ovc->GetCatEntry(&buff[n]);
+ }
+ ListUnlock();
+ return n;
+}
+
+void cOverrides::UpdateEcm(cEcmInfo *ecm, bool log)
+{
+ ListLock(false);
+ cOverrideEcmTable *ovt=dynamic_cast<cOverrideEcmTable *>(Find(OV_ECMTABLE,ecm->caId,ecm->source,ecm->transponder%100000));
+ if(ovt) ecm->ecm_table=ovt->GetTable(log);
+ cOverrideEmmCaid *ovc=dynamic_cast<cOverrideEmmCaid *>(Find(OV_EMMCAID,ecm->caId,ecm->source,ecm->transponder%100000));
+ if(ovc) ecm->emmCaId=ovc->GetCaid(log);
+ ListUnlock();
+}
+
+bool cOverrides::AddEmmPids(int caid, int source, int transponder, cPids *pids, int pid)
+{
+ bool res=false;
+ ListLock(false);
+ cOverrideEmmTable *ovt=dynamic_cast<cOverrideEmmTable *>(Find(OV_EMMTABLE,caid,source,transponder%100000));
+ if(ovt) {
+ ovt->AddPids(pids,pid,caid);
+ res=true;
+ }
+ ListUnlock();
+ return res;
+}
--- /dev/null
+/*
+ * Softcam plugin to VDR (C++)
+ *
+ * This code is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This code is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef ___OVERRIDE_H
+#define ___OVERRIDE_H
+
+#include "data.h"
+
+// ----------------------------------------------------------------
+
+class cValidityRange {
+private:
+ int fromCaid, toCaid;
+ int fromSource, toSource;
+ int fromFreq, toFreq;
+ //
+ bool ParseCaidRange(const char *str);
+ bool ParseSourceRange(const char *str);
+ bool ParseFreqRange(const char *str);
+protected:
+ char *Parse3(char *s);
+ char *Parse2(char *s);
+ cString Print(void);
+public:
+ cValidityRange(void);
+ bool Match(int caid, int source, int freq) const;
+ };
+
+// ----------------------------------------------------------------
+
+class cOverride : public cStructItem, public cValidityRange {
+protected:
+ int type;
+public:
+ virtual ~cOverride() {}
+ virtual bool Parse(char *str)=0;
+ int Type(void) { return type; }
+ };
+
+// ----------------------------------------------------------------
+
+class cOverrides : public cStructList<cOverride> {
+protected:
+ cOverride *Find(int type, int caid, int source, int freq, cOverride *ov=0);
+ virtual cOverride *ParseLine(char *line);
+public:
+ cOverrides(void);
+ int GetCat(int source, int transponder, unsigned char *buff, int len);
+ void UpdateEcm(cEcmInfo *ecm, bool log);
+ bool AddEmmPids(int caid, int source, int transponder, cPids *pids, int pid);
+ };
+
+extern cOverrides overrides;
+
+#endif //___OVERRIDE_H
static const struct LogModule lm_core = {
(LMOD_ENABLE|L_CORE_ALL)&LOPT_MASK,
- (LMOD_ENABLE|L_CORE_LOAD|L_CORE_ECM|L_CORE_PIDS|L_CORE_AU|L_CORE_AUSTATS|L_CORE_CAIDS|L_CORE_NET|L_CORE_CI|L_CORE_SC|L_CORE_HOOK)&LOPT_MASK,
+ (LMOD_ENABLE|L_CORE_LOAD|L_CORE_ECM|L_CORE_PIDS|L_CORE_AU|L_CORE_AUSTATS|L_CORE_CAIDS|L_CORE_NET|L_CORE_CI|L_CORE_SC|L_CORE_HOOK|L_CORE_OVER)&LOPT_MASK,
"core",
{ "load","action","ecm","ecmProc","pids","au","auStats","auExtra","auExtern",
"caids","keys","dynamic","csa","ci","av7110","net","netData","msgcache",
- "serial","smartcard","hook","ciFull","csaVerb" }
+ "serial","smartcard","hook","ciFull","csaVerb","override" }
};
ADD_MODULE(L_CORE,lm_core)
#include "scsetup.h"
#include "system.h"
#include "data.h"
+#include "override.h"
#include "opts.h"
#include "log-core.h"
#include "i18n.h"
ecms->Add(new cEcmInfo(name,pid,sysId,(data[p+2]<<16)|(data[p+3]<<8)|(data[p+4]&0xF0)));
break;
default: // default style
- {
- cEcmInfo *n=new cEcmInfo(name,pid,sysId,0);
- if(sysId==0x1234 || (sysId==0x1801 && (source==0x8334 || source==0x838e))) { // BEV
- n->ecm_table=0x8e;
- n->emmCaId=0x1801;
- }
- ecms->Add(n);
+ ecms->Add(new cEcmInfo(name,pid,sysId,0));
break;
- }
}
}
-void cSystem::ParseCAT(cPids *pids, const unsigned char *buffer)
+void cSystem::ParseCAT(cPids *pids, const unsigned char *buffer, int source, int transponder)
{
if(buffer[0]==0x09) {
int caid=WORD(buffer,2,0xFFFF);
int pid=WORD(buffer,4,0x1FFF);
+ if(overrides.AddEmmPids(caid,source,transponder,pids,pid)) return;
switch(caid>>8) {
case 0x01: // Seca style (82/84)
if(buffer[1]>4) {
pids->AddPid(pid,0x88,0xFE);
break;
case 0x18: // Nagra style, Nagra1(82) Nagra2(82/83) Nagra3(84/83)
- if(caid>=0x1801) pids->AddPid(pid,0x80,0xFE,0x06); // mismatching 85/86/87
- else pids->AddPid(pid,0x82,0xFF);
+ pids->AddPid(pid,0x82,0xFE);
break;
default: // default style (82)
pids->AddPid(pid,0x82,0xFF);
virtual bool ProcessECM(const cEcmInfo *ecm, unsigned char *buffer)=0;
virtual void ProcessEMM(int pid, int caid, unsigned char *buffer) {};
virtual void ParseCADescriptor(cSimpleList<cEcmInfo> *ecms, unsigned short sysId, int source, const unsigned char *data, int len);
- virtual void ParseCAT(cPids *pids, const unsigned char *buffer);
+ virtual void ParseCAT(cPids *pids, const unsigned char *buffer, int source, int transponder);
unsigned char *CW(void) { return cw; }
void DoLog(bool Log) { doLog=Log; }
int Pri(void) { return pri; }
INCLUDES = -I.. -I$(VDRDIR)/include
DEFINES = -DAPIVERSNUM=$(APIVERSNUM) -DAPIVERSION='"$(APIVERSION)"' -DSCAPIVERS=$(SCAPIVERS) -D_GNU_SOURCE
-OBJS = misc.o log.o data.o crypto.o parse.o system.o system-common.o smartcard.o network.o filter.o version.o
+OBJS = misc.o log.o override.o data.o crypto.o parse.o system.o system-common.o smartcard.o network.o filter.o version.o
SHAREDOBJS = compat.o $(VDRDIR)/tools.o $(VDRDIR)/thread.o
LIBS = -lpthread -lrt -ljpeg -lcrypto
DYNLIBS = -ldl $(VDRDIR)/libsi/libsi.a
static const struct LogModule lm_core = {
(LMOD_ENABLE|L_CORE_ALL)&LOPT_MASK,
- (LMOD_ENABLE|L_CORE_LOAD|L_CORE_ECM|L_CORE_PIDS|L_CORE_AU|L_CORE_AUSTATS|L_CORE_CAIDS|L_CORE_NET|L_CORE_CI|L_CORE_SC|L_CORE_HOOK)&LOPT_MASK,
+ (LMOD_ENABLE|L_CORE_LOAD|L_CORE_ECM|L_CORE_PIDS|L_CORE_AU|L_CORE_AUSTATS|L_CORE_CAIDS|L_CORE_NET|L_CORE_CI|L_CORE_SC|L_CORE_HOOK|L_CORE_OVER)&LOPT_MASK,
"core",
{ "load","action","ecm","ecmProc","pids","au","auStats","auExtra","auExtern",
"caids","keys","dynamic","csa","ci","av7110","net","netData","msgcache",
- "serial","smartcard","hook","ciFull" }
+ "serial","smartcard","hook","ciFull","csaVerb","override" }
};
ADD_MODULE(L_CORE,lm_core)