]> www.vanbest.org Git - sasc-ng.git/commitdiff
add CAID tunneling to override.conf
authorleslie <unknown>
Sat, 15 Aug 2009 03:52:15 +0000 (11:52 +0800)
committerleslie <unknown>
Sat, 15 Aug 2009 03:52:15 +0000 (11:52 +0800)
cam.c
data.c
data.h
examples/override.conf.example
misc.c
misc.h
override.c
override.h
parse.c
parse.h

diff --git a/cam.c b/cam.c
index dad0adf050b560cf6a86b239ca56f830c66c3463..84db6abbcc17d48ebe0d5325db2552e708e67b8d 100644 (file)
--- a/cam.c
+++ b/cam.c
@@ -1167,6 +1167,10 @@ PRINTF(L_CORE_ECM,"%s: new caDescr",id);
       if(data && len>0) {
         HEXDUMP(L_HEX_ECM,data,len,"ECM sys 0x%04x id 0x%02x pid 0x%04x",ecm->caId,ecm->provId,filter->Pid());
         if(SCT_LEN(data)==len) {
+          if(ecm->rewriter) {
+            ecm->rewriter->Rewrite(data,len);
+            HEXDUMP(L_HEX_ECM,data,len,"rewritten to");
+            }
           LDUMP(L_CORE_ECMPROC,data,16,"%s: ECM",id);
           int n;
           if(!(n=sys->CheckECM(ecm,data,sync))) {
diff --git a/data.c b/data.c
index 875c86d3911b2595775cb621d7e237e8d18b1673..c45788297ac7e7a7c8b8765601f06ce2f8bc58c9 100644 (file)
--- a/data.c
+++ b/data.c
@@ -26,6 +26,7 @@
 #include <sys/stat.h>
 
 #include "data.h"
+#include "override.h"
 #include "misc.h"
 #include "scsetup.h"
 #include "log-core.h"
@@ -589,6 +590,8 @@ cEcmInfo::cEcmInfo(const cEcmInfo *e)
   prgId=e->prgId;
   source=e->source;
   transponder=e->transponder;
+  if((rewriterId=e->rewriterId)>0)
+    rewriter=cRewriters::CreateById(rewriterId);
 }
 
 cEcmInfo::cEcmInfo(const char *Name, int Pid, int CaId, int ProvId)
@@ -603,6 +606,7 @@ cEcmInfo::~cEcmInfo()
 {
   ClearCaDescr();
   free(name);
+  delete rewriter;
 }
 
 void cEcmInfo::Setup(void)
@@ -611,6 +615,7 @@ void cEcmInfo::Setup(void)
   name=0; caDescr=0; caDescrLen=0; dataIdx=-1;
   prgId=source=transponder=-1;
   ecm_table=0x80; emmCaId=0;
+  rewriter=0; rewriterId=0;
 }
 
 bool cEcmInfo::Compare(const cEcmInfo *e)
diff --git a/data.h b/data.h
index 26140ecc403a131750a70ef326f2cae55ef7cf30..238608d171937cdc3adb1ec989c9232cd4d73846 100644 (file)
--- a/data.h
+++ b/data.h
@@ -29,6 +29,7 @@ class cStructLoaders;
 class cLoaders;
 class cPidFilter;
 class cPlainKeys;
+class cRewriter;
 
 // ----------------------------------------------------------------
 
@@ -231,6 +232,8 @@ public:
   int ecm_pid, ecm_table;
   int caId, provId, emmCaId;
   int prgId, source, transponder;
+  cRewriter *rewriter;
+  int rewriterId;
   //
   cEcmInfo(void);
   cEcmInfo(const cEcmInfo *e);
index 3653012db0f4a0913ede04ae022d480686aa5057..a9a221a0a4173d7375d08b2f8b89692240e8b0f3 100644 (file)
@@ -81,3 +81,13 @@ emmcaid:{1234::}1801      # BEV
 ;
 emmtable:{1816:S61.5W-S148W:}83:84 # DISH N3
 emmtable:{1815:S82W-S91W:}83:84    # BEV N3
+
+;
+; Define caid tunneling for ECM messages (with optional data rewriting)
+;
+; format:
+; tunnel:{caid[-caid]:[src[-src]]:[freq[-freq]]}newcaid[:rewriter]
+;
+;
+; examples:
+; tunnel:{1833:S19.2E:}1702:nagra-beta
diff --git a/misc.c b/misc.c
index d63825e9968f4c5d126757613040a9e8a096ce52..04939db3fb8fee244ea4c1d4864e0913bc9c30cd 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -126,6 +126,12 @@ bool CheckFF(const unsigned char *data, int len)
   return true;
 }
 
+void SetSctLen(unsigned char *data, int len)
+{
+  data[1]=(len>>8) | 0x70;
+  data[2]=len & 0xFF;
+}
+
 unsigned char XorSum(const unsigned char *mem, int len)
 {
   unsigned char cs=0;
diff --git a/misc.h b/misc.h
index 9fcafd3b07ce297f9cd4f9c239064a8bf3ebcac6..3207e9c1eaf764cf6ed5512d43a6f80678ec844d 100644 (file)
--- a/misc.h
+++ b/misc.h
@@ -50,6 +50,8 @@ int DvbOpen(const char *Name, int n, int Mode, bool ReportError=false);
 const char *HexStr(char *str, const unsigned char *mem, int len);
 #define KeyStr(str,key) HexStr(str,key,8)
 
+void SetSctLen(unsigned char *data, int len);
+
 int GetHex(const char * &line, unsigned char *store, int count, bool fixedLen=true);
 int GetHexAsc(const char * &line, unsigned char *store, int count);
 int GetChar(const char * &line, int *store, int count);
index 734230d68ad4722d5a4bbbf4a63df3ec1e736259..37b6738ca19472525911cd4f60618a5e6084aa6e 100644 (file)
@@ -168,6 +168,7 @@ cString cValidityRange::Print(void)
 #define OV_EMMCAID  2
 #define OV_ECMTABLE 3
 #define OV_EMMTABLE 4
+#define OV_TUNNEL   5
 
 // -- cOverrideCat -------------------------------------------------------------
 
@@ -309,6 +310,129 @@ void cOverrideEmmTable::AddPids(cPids *pids, int pid, int caid)
   LBEND();
 }
 
+// -- cRewriter ----------------------------------------------------------------
+
+cRewriter::cRewriter(const char *Name, int Id)
+{
+  name=Name; id=Id;
+  mem=0; mlen=0;
+}
+
+cRewriter::~cRewriter()
+{
+  free(mem);
+}
+
+unsigned char *cRewriter::Alloc(int len)
+{
+  if(!mem || mlen<len) {
+    free(mem);
+    if(len<256) len=256;
+    mem=MALLOC(unsigned char,len);
+    mlen=len;
+    }
+  if(!mem) PRINTF(L_CORE_OVER,"rewriter %s: failed to alloc rewrite buffer",name);
+  return mem;
+}
+
+// -- cRewriterNagraBeta -------------------------------------------------------
+
+#define RWID_NAGRA_BETA   1001
+#define RWNAME_NAGRA_BETA "nagra-beta"
+
+class cRewriterNagraBeta : public cRewriter {
+public:
+  cRewriterNagraBeta(void);
+  virtual bool Rewrite(unsigned char *&data, int &len);
+  };
+
+cRewriterNagraBeta::cRewriterNagraBeta(void)
+:cRewriter(RWNAME_NAGRA_BETA,RWID_NAGRA_BETA)
+{}
+
+bool cRewriterNagraBeta::Rewrite(unsigned char *&data, int &len)
+{
+  unsigned char *d=Alloc(len+10);
+  if(d) {
+    static const unsigned char tunnel[] = { 0xc9,0x00,0x00,0x00,0x01,0x10,0x10,0x00,0x48,0x12,0x07 };
+    d[0]=data[0];
+    SetSctLen(d,len+10);
+    memcpy(&d[3],tunnel,sizeof(tunnel));
+    memcpy(&d[14],&data[4],len-4);
+    if(len>0x88) { // assume N3
+      d[3]=0xc7; d[11]=0x87;
+      }
+    if(d[0]&0x01) d[12]++;
+
+    data=d; len+=10;
+    return true;
+    }
+  return false;
+}
+
+// -- cRewriters ---------------------------------------------------------------
+
+cRewriter *cRewriters::CreateById(int id)
+{
+  switch(id) {
+    case RWID_NAGRA_BETA: return new cRewriterNagraBeta;
+    default: return 0;
+    }
+}
+
+int cRewriters::GetIdByName(const char *name)
+{
+  if(!strcasecmp(name,RWNAME_NAGRA_BETA)) return RWID_NAGRA_BETA;
+  else return 0;
+}
+
+// -- cOverrideTunnel ----------------------------------------------------------
+
+class cOverrideTunnel : public cOverride {
+private:
+  int caid, rewriterId;
+public:
+  cOverrideTunnel(void) { type=OV_TUNNEL; }
+  virtual bool Parse(char *str);
+  int GetTunnel(int *id, bool log);
+  };
+
+bool cOverrideTunnel::Parse(char *str)
+{
+  bool res=false;
+  if((str=Parse3(str))) {
+    char *name=0;
+    if(sscanf(str,"%x:%a[^:]",&caid,&name)>=1) {
+      char rw[48];
+      if(name) {
+        if((rewriterId=cRewriters::GetIdByName(name))>0) {
+          snprintf(rw,sizeof(rw),"%s(%d)",name,rewriterId);
+          res=true;
+          }
+        else PRINTF(L_CORE_LOAD,"override: REWRITER name error");
+        }
+      else {
+        strcpy(rw,"<none>");
+        rewriterId=0;
+        res=true;
+        }
+      if(res) {
+        PRINTF(L_CORE_OVER,"tunnel: %s - to %04x, rewriter %s",*Print(),caid,rw);
+        }
+      }
+    else PRINTF(L_CORE_LOAD,"override: TUNNEL format error");
+    free(name);
+    }
+  return res;
+}
+
+int cOverrideTunnel::GetTunnel(int *id, bool log)
+{
+  if(log) PRINTF(L_CORE_OVER,"tunnel: to %04x (%d)",caid,rewriterId);
+  if(id) *id=rewriterId;
+  return caid;
+}
+
 // -- cOverrides ---------------------------------------------------------------
 
 cOverrides overrides;
@@ -328,15 +452,16 @@ cOverride *cOverrides::ParseLine(char *line)
     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;
+    else if(!strncasecmp(line,"tunnel",6)) ov=new cOverrideTunnel;
     if(ov && !ov->Parse(p)) { delete ov; ov=0; }
     }
   return ov;
 }
 
-cOverride *cOverrides::Find(int type, int caid, int source, int freq, cOverride *ov)
+cOverride *cOverrides::Find(int type, int caid, int source, int transponder, cOverride *ov)
 {
   for(ov=ov?Next(ov):First(); ov; ov=Next(ov))
-    if(ov->Type()==type && ov->Match(caid,source,freq)) break;
+    if(ov->Type()==type && ov->Match(caid,source,transponder%100000)) break;
   return ov;
 }
 
@@ -344,7 +469,7 @@ 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;) {
+  for(cOverride *ov=0; (ov=Find(OV_CAT,-1,source,transponder,ov)) && n<len-32;) {
     cOverrideCat *ovc=dynamic_cast<cOverrideCat *>(ov);
     if(ovc) n+=ovc->GetCatEntry(&buff[n]);
     }
@@ -355,10 +480,17 @@ int cOverrides::GetCat(int source, int transponder, unsigned char *buff, int len
 void cOverrides::UpdateEcm(cEcmInfo *ecm, bool log)
 {
   ListLock(false);
-  cOverrideEcmTable *ovt=dynamic_cast<cOverrideEcmTable *>(Find(OV_ECMTABLE,ecm->caId,ecm->source,ecm->transponder%100000));
+  cOverrideEcmTable *ovt=dynamic_cast<cOverrideEcmTable *>(Find(OV_ECMTABLE,ecm->caId,ecm->source,ecm->transponder));
   if(ovt) ecm->ecm_table=ovt->GetTable(log);
-  cOverrideEmmCaid *ovc=dynamic_cast<cOverrideEmmCaid *>(Find(OV_EMMCAID,ecm->caId,ecm->source,ecm->transponder%100000));
+  cOverrideEmmCaid *ovc=dynamic_cast<cOverrideEmmCaid *>(Find(OV_EMMCAID,ecm->caId,ecm->source,ecm->transponder));
   if(ovc) ecm->emmCaId=ovc->GetCaid(log);
+  cOverrideTunnel *ovu=dynamic_cast<cOverrideTunnel *>(Find(OV_TUNNEL,ecm->caId,ecm->source,ecm->transponder));
+  if(ovu) {
+    if(ecm->emmCaId==0) ecm->emmCaId=ecm->caId;
+    ecm->caId=ovu->GetTunnel(&ecm->rewriterId,log);
+    ecm->provId=0;
+    if(ecm->rewriterId) ecm->rewriter=cRewriters::CreateById(ecm->rewriterId);
+    }
   ListUnlock();
 }
 
@@ -366,7 +498,7 @@ bool cOverrides::AddEmmPids(int caid, int source, int transponder, cPids *pids,
 {
   bool res=false;
   ListLock(false);
-  cOverrideEmmTable *ovt=dynamic_cast<cOverrideEmmTable *>(Find(OV_EMMTABLE,caid,source,transponder%100000));
+  cOverrideEmmTable *ovt=dynamic_cast<cOverrideEmmTable *>(Find(OV_EMMTABLE,caid,source,transponder));
   if(ovt) {
     ovt->AddPids(pids,pid,caid);
     res=true;
index fad5bf3810f2681acbf43a6071173ec1ff0a55fe..87fdb78e7a4b37b5a62fce0e3141826d5c62ddd6 100644 (file)
@@ -44,6 +44,32 @@ public:
 
 // ----------------------------------------------------------------
 
+class cRewriter {
+private:
+  unsigned char *mem;
+  int mlen;
+protected:
+  const char *name;
+  int id;
+  //
+  unsigned char *Alloc(int len);
+public:
+  cRewriter(const char *Name, int Id);
+  virtual ~cRewriter();
+  virtual bool Rewrite(unsigned char *&data, int &len)=0;
+  int Id(void) const { return id; }
+  };
+
+// ----------------------------------------------------------------
+
+class cRewriters {
+public:
+  static cRewriter *CreateById(int id);
+  static int GetIdByName(const char *name);
+  };
+
+// ----------------------------------------------------------------
+
 class cOverride : public cStructItem, public cValidityRange {
 protected:
   int type;
@@ -57,7 +83,7 @@ public:
 
 class cOverrides : public cStructList<cOverride> {
 protected:
-  cOverride *Find(int type, int caid, int source, int freq, cOverride *ov=0);
+  cOverride *Find(int type, int caid, int source, int transponder, cOverride *ov=0);
   virtual cOverride *ParseLine(char *line);
 public:
   cOverrides(void);
diff --git a/parse.c b/parse.c
index 8d622e1f3b989ec26956e6f02887cd74e76729bb..ce0893de5c86f03df4d572a436db5fea0911f11e 100644 (file)
--- a/parse.c
+++ b/parse.c
 
 // -----------------------------------------------------------------------------
 
-void SetSctLen(unsigned char *data, int len)
-{
-  data[1]=(len>>8) | 0x70;
-  data[2]=len & 0xFF;
-}
-
 static void SortNanos(unsigned char *dest, const unsigned char *src, int len)
 {
   int w=0, c=-1;
diff --git a/parse.h b/parse.h
index 7263723172a347a935bcb2068d00f47a612d8162..125c01dc99fe1c5c4d234c44d164c742d57ff7c4 100644 (file)
--- a/parse.h
+++ b/parse.h
 
 // ----------------------------------------------------------------
 
-void SetSctLen(unsigned char *data, int len);
-
-// ----------------------------------------------------------------
-
 class cAssSct : public cSimpleItem {
 private:
   const unsigned char *data;