]> www.vanbest.org Git - sasc-ng.git/commitdiff
add override config (see example conf file)
authorleslie <unknown>
Mon, 8 Jun 2009 11:48:22 +0000 (19:48 +0800)
committerleslie <unknown>
Mon, 8 Jun 2009 11:48:22 +0000 (19:48 +0800)
12 files changed:
Makefile
cam.c
examples/override.conf.example [new file with mode: 0644]
log-core.h
log.c
override.c [new file with mode: 0644]
override.h [new file with mode: 0644]
sc.c
system.c
system.h
testing/Makefile
testing/compat.c

index 3cd15d6f4ae31eb86500775470ec2807ad991701..7641ec318babf448c0040cd0da3079b09524beb8 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -81,7 +81,8 @@ endif
 ### 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):
 
diff --git a/cam.c b/cam.c
index a6e0b97870b1a2968b781f5427de44855089527e..66caf45a54932ae2331c280a2743372f78b3a7a0 100644 (file)
--- a/cam.c
+++ b/cam.c
@@ -42,6 +42,7 @@
 #include "filter.h"
 #include "system.h"
 #include "data.h"
+#include "override.h"
 #include "misc.h"
 #include "log-core.h"
 
@@ -282,20 +283,21 @@ void cHookManager::Process(cPidFilter *filter, unsigned char *data, int len)
 
 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)
@@ -316,7 +318,7 @@ bool cLogChain::Parse(const unsigned char *cat)
     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(" ->");
@@ -325,7 +327,7 @@ bool cLogChain::Parse(const unsigned char *cat)
         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());
           }
@@ -354,6 +356,7 @@ private:
   //
   cPidFilter *catfilt;
   int catVers;
+  int source, transponder;
   //
   enum ePreMode { pmNone, pmStart, pmWait, pmActive, pmStop };
   ePreMode prescan;
@@ -364,6 +367,7 @@ private:
   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:
@@ -372,7 +376,7 @@ 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)
@@ -412,9 +416,10 @@ void cLogger::Down(void)
   Unlock();
 }
 
-void cLogger::PreScan(void)
+void cLogger::PreScan(int src, int tr)
 {
   Lock();
+  source=src; transponder=tr;
   prescan=pmStart; Up();
   Unlock();
 }
@@ -423,6 +428,7 @@ void cLogger::EcmStatus(const cEcmInfo *ecm, bool on)
 {
   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);
@@ -517,6 +523,27 @@ cPidFilter *cLogger::AddFilter(int Pid, int Section, int Mask, int Mode, int Idl
   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) {
@@ -527,22 +554,11 @@ void cLogger::Process(cPidFilter *filter, unsigned char *data, int len)
         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); }
@@ -1255,8 +1271,9 @@ void cEcmHandler::ParseCAInfo(int SysId)
             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) {
@@ -1336,7 +1353,7 @@ void cCam::PostTune(void)
 {
   if(ScSetup.PrestartAU) {
     LogStartup();
-    if(logger) logger->PreScan();
+    if(logger) logger->PreScan(source,transponder);
     }
 }
 
diff --git a/examples/override.conf.example b/examples/override.conf.example
new file mode 100644 (file)
index 0000000..c14c576
--- /dev/null
@@ -0,0 +1,83 @@
+;
+; 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
index a8abe41a1a0949ef8c8f1db71b0a21e226a87a60..b85a738f9409550f395ffd9be2ac9b862e04b8cf 100644 (file)
@@ -49,7 +49,8 @@
 #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
diff --git a/log.c b/log.c
index 1d99450be27d89697714c2f1b5ed3417dc92663d..ef193d405e19fdf821e85171d41ca3b97fb73b0f 100644 (file)
--- a/log.c
+++ b/log.c
@@ -68,7 +68,7 @@ bool cLogging::AddModule(int m, const struct LogModule *lm)
     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;
diff --git a/override.c b/override.c
new file mode 100644 (file)
index 0000000..734230d
--- /dev/null
@@ -0,0 +1,376 @@
+/*
+ * 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;
+}
diff --git a/override.h b/override.h
new file mode 100644 (file)
index 0000000..fad5bf3
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * 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
diff --git a/sc.c b/sc.c
index 82433bb46a53d9714b88cede714ab6eb7eb56633..7fb7e119cfc6b2fe70285c2efd7866b253231dc6 100644 (file)
--- a/sc.c
+++ b/sc.c
@@ -86,11 +86,11 @@ static const char * const cfgsub="sc";
 
 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)
 
index de0595a24e1b36fad697183c0b048a2b4cc1ce68..c29474f94ca14e0ef61082f5e7a4f3ea814c5e1d 100644 (file)
--- a/system.c
+++ b/system.c
@@ -29,6 +29,7 @@
 #include "scsetup.h"
 #include "system.h"
 #include "data.h"
+#include "override.h"
 #include "opts.h"
 #include "log-core.h"
 #include "i18n.h"
@@ -145,23 +146,17 @@ void cSystem::ParseCADescriptor(cSimpleList<cEcmInfo> *ecms, unsigned short sysI
           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) {
@@ -178,8 +173,7 @@ void cSystem::ParseCAT(cPids *pids, const unsigned char *buffer)
         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);
index 38b0fc5c90906f7f387b7760a964249b322fcd30..18cdac91cd5c084237ed1f09c13f845e9c4c8d5e 100644 (file)
--- a/system.h
+++ b/system.h
@@ -118,7 +118,7 @@ public:
   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; }
index db59a91be66f4a22fe0405c156e84cfdd582b1fa..189fea5f68794a1c1552f74aeebcf893eadea584 100644 (file)
@@ -21,7 +21,7 @@ APIVERSNUM = $(shell sed -ne '/define APIVERSNUM/ s/^.[a-zA-Z ]*\([0-9]*\) .*$$/
 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
index 0099986a17a67df18ba3eca0908ed09bf5e520e4..56d8ac67db613bda1b6c0b7a5ed6b612b3467347 100644 (file)
@@ -132,11 +132,11 @@ extern const char *I18nTranslate(const char *s, const char *Plugin)
 
 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)