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

📄 cam.c

📁 VDR softcam plugin 0.9.1
💻 C
📖 第 1 页 / 共 5 页
字号:
    chain->active=true;    for(cPid *pid=chain->pids.First(); pid; pid=chain->pids.Next(pid)) {      cPidFilter *filter=AddFilter(pid->pid,pid->sct,pid->mask,pid->mode,CHAIN_HOLD/8,false);      if(filter) {        filter->userData=(void *)chain;        pid->filter=filter;        }      }    }}void cLogger::StopChain(cLogChain *chain, bool force){  if(chain->active) {    if(force || (chain->delayed && chain->delay.TimedOut())) {      PRINTF(L_CORE_AU,"%d: stopping chain %04x",cardNum,chain->caid);      chain->active=false;      for(cPid *pid=chain->pids.First(); pid; pid=chain->pids.Next(pid)) {        cPidFilter *filter=pid->filter;        if(filter) {          DelFilter(filter);          pid->filter=0;          }        }      }    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();        if(prescan==pmStart) { prescan=pmWait; pretime.Set(2000); }        }      if(prescan==pmWait && pretime.TimedOut()) { prescan=pmActive; 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 {public:  cEcmData(void):cEcmInfo() {}  cEcmData(cEcmInfo *e):cEcmInfo(e) {}  virtual cString ToString(bool hide);  bool Parse(const char *buf);  };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=AUTOMEM(nu);      if(GetHex(line,dat,nu,true)==nu) AddData(dat,nu);      }    return true;    }  return false;}cString cEcmData::ToString(bool hide){  char *str;  if(data) {    str=AUTOARRAY(char,dataLen*2+2);    sprintf(str,":%d:%s",dataLen,HexStr(str,data,dataLen));    }  else {    str=AUTOARRAY(char,4);    strcpy(str,":0");    }  return cString::sprintf("%d:%x:%x:%s:%x/%x:%x:%x/%x%s",                            prgId,source,transponder,name,                            caId,emmCaId,provId,ecm_pid,ecm_table,                            str);}// -- cEcmCache ----------------------------------------------------------------cEcmCache ecmcache;cEcmCache::cEcmCache(void):cStructListPlain<cEcmData>("ecm cache",ECMCACHE_FILE,SL_READWRITE|SL_MISSINGOK){}void cEcmCache::New(cEcmInfo *e){  if(ScSetup.EcmCache>0) return;  ListLock(true);  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();    }  ListUnlock();  e->SetCached();}cEcmData *cEcmCache::Exists(cEcmInfo *e){  cEcmData *dat;  for(dat=First(); dat; dat=Next(dat))    if(dat->Compare(e)) break;  return dat;}int cEcmCache::GetCached(cSimpleList<cEcmInfo> *list, int sid, int Source, int Transponder){  int n=0;  list->Clear();  if(ScSetup.EcmCache>1) return 0;  ListLock(false);  for(cEcmData *dat=First(); dat; dat=Next(dat)) {    if(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++;        }      }    }  ListUnlock();  return n;}void cEcmCache::Delete(cEcmInfo *e){  if(ScSetup.EcmCache>0) return;  ListLock(false);  cEcmData *dat=Exists(e);  ListUnlock();  if(dat) {    DelItem(dat);    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);    }}void cEcmCache::Flush(void){  ListLock(true);  Clear();  Modified();  PRINTF(L_CORE_ECM,"cache flushed");  ListUnlock();}bool cEcmCache::ParseLinePlain(const char *line){  cEcmData *dat=new cEcmData;  if(dat && dat->Parse(line) && !Exists(dat)) { Add(dat); return true; }  delete dat;  return false;}// -- 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){  dataMutex.Lock();  if(trigger) {    PRINTF(L_CORE_ECM,"%s: triggered SID %d/%d idx %d/%d mode %d/%d %s",      id,filterSid,sid,filterCwIndex,cwIndex,mode,triggerMode,(mode==3 && sync)?"sync":"-");    trigger=false;    if(filterSid!=sid) {      filterSid=sid;      filterSource=cam->Source();      filterTransponder=cam->Transponder();      filterCwIndex=cwIndex;      noKey=true; mode=0;      }    else {      if(filterCwIndex!=cwIndex) {        filterCwIndex=cwIndex;        if(mode==3 && sync)          cam->WriteCW(filterCwIndex,lastCw,true);        }      if(mode<triggerMode) mode=triggerMode;      }    triggerMode=-1;    }  dataMutex.Unlock();  switch(mode) {    case -1:      filter->SetIdleTime(IDLE_SLEEP);      break;    case 0:      StopEcm();      if(IsIdle()) { mode=-1; break; }      dolog=LOG_COUNT;      NewEcm();      filter->SetIdleTime(IDLE_GETCA);      startecm.Set();      mode=1;      break;    case 1:      if(!ecm && !JumpEcm()) {        if(startecm.Elapsed()>IDLE_GETCA_SLOW) {

⌨️ 快捷键说明

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