From 8d9aa83aa0635a3ae01d200dfee7ec6ab3a1d7b4 Mon Sep 17 00:00:00 2001 From: leslie Date: Sat, 15 Aug 2009 11:52:15 +0800 Subject: [PATCH] add CAID tunneling to override.conf --- cam.c | 4 + data.c | 5 ++ data.h | 3 + examples/override.conf.example | 10 +++ misc.c | 6 ++ misc.h | 2 + override.c | 144 +++++++++++++++++++++++++++++++-- override.h | 28 ++++++- parse.c | 6 -- parse.h | 4 - 10 files changed, 195 insertions(+), 17 deletions(-) diff --git a/cam.c b/cam.c index dad0adf..84db6ab 100644 --- 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 875c86d..c457882 100644 --- a/data.c +++ b/data.c @@ -26,6 +26,7 @@ #include #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 26140ec..238608d 100644 --- 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); diff --git a/examples/override.conf.example b/examples/override.conf.example index 3653012..a9a221a 100644 --- a/examples/override.conf.example +++ b/examples/override.conf.example @@ -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 d63825e..04939db 100644 --- 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 9fcafd3..3207e9c 100644 --- 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); diff --git a/override.c b/override.c index 734230d..37b6738 100644 --- a/override.c +++ b/override.c @@ -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 || mlen0x88) { // 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,""); + 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(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(Find(OV_ECMTABLE,ecm->caId,ecm->source,ecm->transponder%100000)); + cOverrideEcmTable *ovt=dynamic_cast(Find(OV_ECMTABLE,ecm->caId,ecm->source,ecm->transponder)); if(ovt) ecm->ecm_table=ovt->GetTable(log); - cOverrideEmmCaid *ovc=dynamic_cast(Find(OV_EMMCAID,ecm->caId,ecm->source,ecm->transponder%100000)); + cOverrideEmmCaid *ovc=dynamic_cast(Find(OV_EMMCAID,ecm->caId,ecm->source,ecm->transponder)); if(ovc) ecm->emmCaId=ovc->GetCaid(log); + cOverrideTunnel *ovu=dynamic_cast(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(Find(OV_EMMTABLE,caid,source,transponder%100000)); + cOverrideEmmTable *ovt=dynamic_cast(Find(OV_EMMTABLE,caid,source,transponder)); if(ovt) { ovt->AddPids(pids,pid,caid); res=true; diff --git a/override.h b/override.h index fad5bf3..87fdb78 100644 --- a/override.h +++ b/override.h @@ -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 { 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 8d622e1..ce0893d 100644 --- a/parse.c +++ b/parse.c @@ -27,12 +27,6 @@ // ----------------------------------------------------------------------------- -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 7263723..125c01d 100644 --- a/parse.h +++ b/parse.h @@ -24,10 +24,6 @@ // ---------------------------------------------------------------- -void SetSctLen(unsigned char *data, int len); - -// ---------------------------------------------------------------- - class cAssSct : public cSimpleItem { private: const unsigned char *data; -- 2.39.5