⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cam.c

📁 这是一个LINUX环境的 VDR 插件源代码,可支持Irdeto, Seca, Viaccess, Nagra, Conax & Cryptoworks等CA系统的读卡、共享等操作。
💻 C
📖 第 1 页 / 共 5 页
字号:
    else if(!chain->delayed) {      PRINTF(L_CORE_AUEXTRA,"%d: delaying chain %04x",cardNum,chain->caid);      chain->delayed=true;      chain->delay.Set(CHAIN_HOLD);      }    }}cPidFilter *cLogger::AddFilter(int Pid, int Section, int Mask, int Mode, int IdleTime, bool Crc){  cPidFilter *filter=NewFilter(IdleTime);  if(filter) {    if(Pid>1) filter->SetBuffSize(32768);    filter->Start(Pid,Section,Mask,Mode,Crc);    PRINTF(L_CORE_AUEXTRA,"%d: added filter pid=0x%.4x sct=0x%.2x/0x%.2x/0x%.2x idle=%d crc=%d",cardNum,Pid,Section,Mask,Mode,IdleTime,Crc);    }  else PRINTF(L_GEN_ERROR,"no free slot or filter failed to open for logger %d",cardNum);  return filter;}void cLogger::Process(cPidFilter *filter, unsigned char *data, int len){  if(data && len>0) {    if(filter==catfilt) {      int vers=(data[5]&0x3E)>>1;      if(data[0]==0x01 && vers!=catVers) {        PRINTF(L_CORE_AUEXTRA,"%d: got CAT version %02x",cardNum,vers);        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;              }            }          }        SetChains();        }      }    else {      HEXDUMP(L_HEX_EMM,data,len,"EMM pid 0x%04x",filter->Pid());      if(logstats) logstats->Count();      if(SCT_LEN(data)==len) {        cLogChain *chain=(cLogChain *)(filter->userData);        if(chain) {          chain->Process(filter->Pid(),data);          if(chain->delayed) StopChain(chain,false);          }        }      else PRINTF(L_CORE_AU,"%d: incomplete section %d != %d",cardNum,len,SCT_LEN(data));      }    }  else {    cLogChain *chain=(cLogChain *)(filter->userData);    if(chain && chain->delayed) StopChain(chain,false);    }}// -- cEcmData -----------------------------------------------------------------class cEcmData : public cEcmInfo {private:  bool del;public:  cEcmData(void);  cEcmData(cEcmInfo *e);  bool Save(FILE *f);  bool Parse(const char *buf);  void Delete(void) { del=true; }  bool IsDeleted(void) const { return del; }  };cEcmData::cEcmData(void):cEcmInfo(){  del=false;}cEcmData::cEcmData(cEcmInfo *e):cEcmInfo(e){  del=false;}bool cEcmData::Parse(const char *buf){  char Name[64];  int nu=0, num;  Name[0]=0;  if(sscanf(buf,"%d:%x:%x:%63[^:]:%x/%x:%x:%x/%x:%d%n",&prgId,&source,&transponder,Name,&caId,&emmCaId,&provId,&ecm_pid,&ecm_table,&nu,&num)>=9) {    SetName(Name);    const char *line=buf+num;    if(nu>0 && *line++==':') {      unsigned char dat[nu];      if(GetHex(line,dat,nu,true)==nu) AddData(dat,nu);      }    return true;    }  return false;}bool cEcmData::Save(FILE *f){  fprintf(f,"%d:%x:%x:%s:%x/%x:%x:%x/%x",prgId,source,transponder,name,caId,emmCaId,provId,ecm_pid,ecm_table);  if(data) {    char str[dataLen*2+2];    fprintf(f,":%d:%s\n",dataLen,HexStr(str,data,dataLen));    }  else    fprintf(f,":0\n");  return ferror(f)==0;}// -- cEcmCache ----------------------------------------------------------------cEcmCache ecmcache;cEcmCache::cEcmCache(void):cLoader("ECM"){}void cEcmCache::New(cEcmInfo *e){  Lock();  cEcmData *dat;  if(!(dat=Exists(e))) {    dat=new cEcmData(e);    Add(dat);    Modified();    PRINTF(L_CORE_ECM,"cache add prgId=%d source=%x transponder=%x ecm=%x/%x",e->prgId,e->source,e->transponder,e->ecm_pid,e->ecm_table);    }  else {    if(strcasecmp(e->name,dat->name)) {      dat->SetName(e->name);      Modified();      }    if(dat->Update(e))      Modified();    }  e->SetCached();  Unlock();}cEcmData *cEcmCache::Exists(cEcmInfo *e){  for(cEcmData *dat=First(); dat; dat=Next(dat))    if(!dat->IsDeleted() && dat->Compare(e)) return dat;  return 0;}int cEcmCache::GetCached(cSimpleList<cEcmInfo> *list, int sid, int Source, int Transponder){  int n=0;  list->Clear();  Lock();  for(cEcmData *dat=First(); dat; dat=Next(dat)) {    if(!dat->IsDeleted() && dat->prgId==sid && dat->source==Source && dat->transponder==Transponder) {      cEcmInfo *e=new cEcmInfo(dat);      if(e) {        PRINTF(L_CORE_ECM,"from cache: system %s (%04x) id %04x with ecm %x/%x",e->name,e->caId,e->provId,e->ecm_pid,e->ecm_table);        e->SetCached();        list->Add(e);        n++;        }      }    }  Unlock();  return n;}void cEcmCache::Delete(cEcmInfo *e){  Lock();  cEcmData *dat=Exists(e);  if(dat) {    dat->Delete();    Modified();    PRINTF(L_CORE_ECM,"invalidated cached prgId=%d source=%x transponder=%x ecm=%x/%x",dat->prgId,dat->source,dat->transponder,dat->ecm_pid,dat->ecm_table);    }  Unlock();}void cEcmCache::Flush(void){  Lock();  Clear();  Modified();  PRINTF(L_CORE_ECM,"cache flushed");  Unlock();    }void cEcmCache::Load(void){  Lock();  Clear();  Unlock();}bool cEcmCache::Save(FILE *f){  bool res=true;  Lock();  for(cEcmData *dat=First(); dat;) {    if(!dat->IsDeleted()) {      if(!dat->Save(f)) { res=false; break; }      dat=Next(dat);      }    else {      cEcmData *n=Next(dat);      Del(dat);      dat=n;      }    }  Modified(!res);  Unlock();  return res;}bool cEcmCache::ParseLine(const char *line, bool fromCache){  bool res=false;  cEcmData *dat=new cEcmData;  if(dat && dat->Parse(line)) {    if(!Exists(dat)) { Add(dat); dat=0; }    res=true;    }  delete dat;  return res;}// -- cPrgPid ---------------------------------------------------------------------class cPrgPid : public cSimpleItem {private:  int type;  int pid;  bool proc;public:  cPrgPid(int Type, int Pid);  int Pid(void) { return pid; }  int Type(void) { return type; }  bool Proc(void) { return proc; }  void Proc(bool is) { proc=is; };  };cPrgPid::cPrgPid(int Type, int Pid){  type=Type; pid=Pid;  proc=false;}// -- cPrg ---------------------------------------------------------------------class cPrg : public cSimpleItem {private:  int prg;  bool isUpdate;public:  cSimpleList<cPrgPid> pids;  //  cPrg(int Prg, bool IsUpdate);  int Prg(void) { return prg; }  bool IsUpdate(void) { return isUpdate; }  };cPrg::cPrg(int Prg, bool IsUpdate){  prg=Prg; isUpdate=IsUpdate;}// -- cEcmSys ------------------------------------------------------------------class cEcmPri : public cSimpleItem {public:  cEcmInfo *ecm;  int pri, sysIdent;  };// -- cEcmHandler --------------------------------------------------------------class cEcmHandler : public cSimpleItem, public cAction {private:  int cardNum, cwIndex;  cCam *cam;  char *id;  cTimeMs idleTime;  //  cMutex dataMutex;  int sid;  cSimpleList<cPrgPid> pids;  //  cSystem *sys;  cPidFilter *filter;  int filterCwIndex, filterSource, filterTransponder, filterSid;  unsigned char lastCw[16];  bool sync, noKey, trigger;  int triggerMode;  int mode, count;  cTimeMs lastsync, startecm, resendTime;  unsigned int cryptPeriod;  unsigned char parity;  cMsgCache failed;  //  cSimpleList<cEcmInfo> ecmList;  cSimpleList<cEcmPri> ecmPriList;  cEcmInfo *ecm;  cEcmPri *ecmPri;  cTimeMs ecmUpdTime;  //  int dolog;  //  void DeleteSys(void);  void NoSync(bool clearParity);  cEcmInfo *NewEcm(void);  cEcmInfo *JumpEcm(void);  void StopEcm(void);  bool UpdateEcm(void);  void EcmOk(void);  void EcmFail(void);  void ParseCAInfo(int sys);  void AddEcmPri(cEcmInfo *n);protected:  virtual void Process(cPidFilter *filter, unsigned char *data, int len);public:  cEcmHandler(cCam *Cam, int CardNum, int cwindex);  virtual ~cEcmHandler();  void Stop(void);  void SetPrg(cPrg *prg);  void ShiftCwIndex(int cwindex);  char *CurrentKeyStr(void) const;  bool IsRemoveable(void);  bool IsIdle(void);  int Sid(void) const { return sid; }  int CwIndex(void) const { return cwIndex; }  const char *Id(void) const { return id; }  };cEcmHandler::cEcmHandler(cCam *Cam, int CardNum, int cwindex):cAction("ecmhandler",CardNum),failed(32,0){  cam=Cam;  cardNum=CardNum;  cwIndex=cwindex;  sys=0; filter=0; ecm=0; ecmPri=0; mode=-1; sid=-1;  trigger=false; triggerMode=-1;  filterSource=filterTransponder=0; filterCwIndex=-1; filterSid=-1;  asprintf(&id,"%d.%d",cardNum,cwindex);}cEcmHandler::~cEcmHandler(){  Lock();  StopEcm();  DelAllFilter(); // delete filters before sys for multi-threading reasons  DeleteSys();  Unlock();  free(id);}bool cEcmHandler::IsIdle(void){  dataMutex.Lock();  int n=pids.Count();  dataMutex.Unlock();  return n==0;}bool cEcmHandler::IsRemoveable(void){  return IsIdle() && idleTime.Elapsed()>MAX_ECM_IDLE;}void cEcmHandler::Stop(void){  dataMutex.Lock();  if(!IsIdle() || sid!=-1) {    PRINTF(L_CORE_ECM,"%s: stop",id);    sid=-1;    idleTime.Set();    pids.Clear();    trigger=true;    }  dataMutex.Unlock();  if(filter) filter->Wakeup();}void cEcmHandler::ShiftCwIndex(int cwindex){  if(cwIndex!=cwindex) {    PRINTF(L_CORE_PIDS,"%s: shifting cwIndex from %d to %d",id,cwIndex,cwindex);    free(id);    asprintf(&id,"%d.%d",cardNum,cwindex);    dataMutex.Lock();    trigger=true;    cwIndex=cwindex;    for(cPrgPid *pid=pids.First(); pid; pid=pids.Next(pid))      cam->SetCWIndex(pid->Pid(),cwIndex);    dataMutex.Unlock();    if(filter) filter->Wakeup();    }}void cEcmHandler::SetPrg(cPrg *prg){  dataMutex.Lock();  bool wasIdle=IsIdle();  if(prg->Prg()!=sid) {    PRINTF(L_CORE_ECM,"%s: setting new SID %d",id,prg->Prg());    sid=prg->Prg();    idleTime.Set();    pids.Clear();    trigger=true;    }  LBSTART(L_CORE_PIDS);  LBPUT("%s: pids on entry",id);  for(cPrgPid *pid=pids.First(); pid; pid=pids.Next(pid))    LBPUT(" %s=%04x",TYPENAME(pid->Type()),pid->Pid());  LBEND();  for(cPrgPid *pid=pids.First(); pid;) {    cPrgPid *npid;    for(npid=prg->pids.First(); npid; npid=prg->pids.Next(npid)) {      if(pid->Pid()==npid->Pid()) {        npid->Proc(true);        break;        }      }    if(!npid) {      npid=pids.Next(pid);      pids.Del(pid);      pid=npid;      }    else pid=pids.Next(pid);    }  LBSTART(L_CORE_PIDS);  LBPUT("%s: pids after delete",id);  for(cPrgPid *pid=pids.First(); pid; pid=pids.Next(pid))    LBPUT(" %s=%04x",TYPENAME(pid->Type()),pid->Pid());  LBEND();  for(cPrgPid *npid=prg->pids.First(); npid; npid=prg->pids.Next(npid)) {    if(!npid->Proc()) {      cPrgPid *pid=new cPrgPid(npid->Type(),npid->Pid());      pids.Add(pid);      cam->SetCWIndex(pid->Pid(),cwIndex);      }    }  LBSTART(L_CORE_PIDS);  LBPUT("%s: pids after add",id);  for(cPrgPid *pid=pids.First(); pid; pid=pids.Next(pid))    LBPUT(" %s=%04x",TYPENAME(pid->Type()),pid->Pid());  LBEND();  if(!IsIdle()) {    trigger=true;    triggerMode=0;    if(wasIdle) PRINTF(L_CORE_ECM,"%s: is no longer idle",id);    }  else {    if(!wasIdle) idleTime.Set();    PRINTF(L_CORE_ECM,"%s: is idle%s",id,wasIdle?"":" now");    }  if(!filter) {    filter=NewFilter(IDLE_SLEEP);    if(!filter) PRINTF(L_GEN_ERROR,"failed to open ECM filter in handler %s",id);    }  dataMutex.Unlock();  if(filter) filter->Wakeup();}void cEcmHandler::Process(cPidFilter *filter, unsigned char *data, int len)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -