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

📄 cam.c

📁 这是一个LINUX环境的 VDR 插件源代码,可支持Irdeto, Seca, Viaccess, Nagra, Conax & Cryptoworks等CA系统的读卡、共享等操作。
💻 C
📖 第 1 页 / 共 5 页
字号:
    if(!handler->IsIdle() && handler->Sid()==prg)      return true;  return false;}char *cCam::CurrentKeyStr(int num){  cMutexLock lock(this);  cEcmHandler *handler;  for(handler=handlerList.First(); handler; handler=handlerList.Next(handler))    if(--num<0) return handler->CurrentKeyStr();  return 0;}bool cCam::Active(void){  cMutexLock lock(this);  for(cEcmHandler *handler=handlerList.First(); handler; handler=handlerList.Next(handler))    if(!handler->IsIdle()) {      PRINTF(L_GEN_INFO,"handler %s on card %d is not idle",handler->Id(),cardNum);      return true;      }  return false;}void cCam::HouseKeeping(void){  cMutexLock lock(this);  for(cEcmHandler *handler=handlerList.First(); handler;) {    cEcmHandler *next=handlerList.Next(handler);    if(handler->IsRemoveable()) RemHandler(handler);    handler=next;    }  if(handlerList.Count()<1) {    delete hookman; hookman=0;    delete logger; logger=0;    }}bool cCam::GetPrgCaids(int source, int transponder, int prg, caid_t *c){  return device->GetPrgCaids(source,transponder,prg,c);}void cCam::LogEcmStatus(const cEcmInfo *ecm, bool on){  cMutexLock lock(this);  if(!logger && on && ScSetup.AutoUpdate) {    logger=new cLogger(cardNum,IsSoftCSA());    LogStatsUp();    }  if(logger) logger->EcmStatus(ecm,on);}void cCam::AddHook(cLogHook *hook){  cMutexLock lock(this);  if(!hookman) hookman=new cHookManager(cardNum);  if(hookman) hookman->AddHook(hook);}bool cCam::TriggerHook(int id){  return hookman && hookman->TriggerHook(id);}void cCam::SetCWIndex(int pid, int index){  if(index<MAX_CW_IDX) {    ca_pid_t ca_pid;    ca_pid.pid=pid;    ca_pid.index=index;    PRINTF(L_CORE_PIDS,"%d: descrambling pid %04x on index %x",cardNum,pid,index);    if(!device->SetCaPid(&ca_pid))      if(index>0) {        PRINTF(L_GEN_ERROR,"CA_SET_PID failed (%s). Expect a black screen/bad recording. Do you use the patched DVB driver?",strerror(errno));        PRINTF(L_GEN_WARN,"Adjusting 'Concurrent FF streams' to NO");        ScSetup.ConcurrentFF=0;        ScSetup.Store(true);        }    }}void cCam::WriteCW(int index, unsigned char *cw, bool force){  if(index<MAX_CW_IDX) {    for(int i=0; i<16; i+=4) cw[i+3]=cw[i]+cw[i+1]+cw[i+2];    ca_descr_t ca_descr;    ca_descr.index=index;    unsigned char *last=lastCW[index];    if(force || memcmp(&cw[0],&last[0],8)) {      memcpy(&last[0],&cw[0],8);      ca_descr.parity=0;      memcpy(ca_descr.cw,&cw[0],8);      if(!device->SetCaDescr(&ca_descr))        PRINTF(L_GEN_ERROR,"CA_SET_DESCR failed (%s). Expect a black screen.",strerror(errno));      }    if(force || memcmp(&cw[8],&last[8],8)) {      memcpy(&last[8],&cw[8],8);      ca_descr.parity=1;      memcpy(ca_descr.cw,&cw[8],8);      if(!device->SetCaDescr(&ca_descr))        PRINTF(L_GEN_ERROR,"CA_SET_DESCR failed (%s). Expect a black screen.",strerror(errno));      }    }}void cCam::DumpAV7110(void){  device->DumpAV7110();}int cCam::GetFreeIndex(void){  for(int idx=0; idx<MAX_CW_IDX; idx++)    if(!indexMap[idx]) return idx;  return -1;}cEcmHandler *cCam::GetHandler(int sid, bool needZero, bool noshift){  cEcmHandler *zerohandler=0, *sidhandler=0, *idlehandler=0;  for(cEcmHandler *handler=handlerList.First(); handler; handler=handlerList.Next(handler)) {    if(handler->Sid()==sid)      sidhandler=handler;    if(handler->CwIndex()==0)      zerohandler=handler;    if(handler->IsIdle() && (!idlehandler || (!(needZero ^ (idlehandler->CwIndex()!=0)) && (needZero ^ (handler->CwIndex()!=0))) ))      idlehandler=handler;    }  LBSTART(L_CORE_PIDS);  LBPUT("%d: SID=%d zero=%d |",cardNum,sid,needZero);  if(sidhandler) LBPUT(" sid=%d/%d/%d",sidhandler->CwIndex(),sidhandler->Sid(),sidhandler->IsIdle());  else LBPUT(" sid=-/-/-");  if(zerohandler) LBPUT(" zero=%d/%d/%d",zerohandler->CwIndex(),zerohandler->Sid(),zerohandler->IsIdle());  else LBPUT(" zero=-/-/-");  if(idlehandler) LBPUT(" idle=%d/%d/%d",idlehandler->CwIndex(),idlehandler->Sid(),idlehandler->IsIdle());  else LBPUT(" idle=-/-/-");  LBEND();  if(sidhandler) {    if(needZero && sidhandler->CwIndex()!=0 && !noshift) {      if(!sidhandler->IsIdle())        PRINTF(L_CORE_ECM,"%d: shifting cwindex on non-idle handler.",cardNum);      if(zerohandler) {        if(!zerohandler->IsIdle())          PRINTF(L_CORE_ECM,"%d: shifting non-idle zero handler. This shouldn't happen!",cardNum);        zerohandler->ShiftCwIndex(sidhandler->CwIndex());        sidhandler->ShiftCwIndex(0);        }      else if(indexMap[0]==0) {        indexMap[0]=1;        indexMap[sidhandler->CwIndex()]=0;        sidhandler->ShiftCwIndex(0);        }      else PRINTF(L_CORE_ECM,"%d: zero index not free.",cardNum);      }    if(!needZero && sidhandler->CwIndex()==0 && !noshift) {      if(!sidhandler->IsIdle())        PRINTF(L_CORE_ECM,"%d: shifting cwindex on non-idle handler.",cardNum);      int idx=GetFreeIndex();      if(idx>=0) {        indexMap[idx]=1;        sidhandler->ShiftCwIndex(idx);        indexMap[0]=0;        }      else PRINTF(L_CORE_ECM,"%d: no free cwindex. Can't free zero index.",cardNum);      }    return sidhandler;    }  if(needZero && zerohandler) {    if(!zerohandler->IsIdle())      PRINTF(L_CORE_ECM,"%d: changing SID on non-idle zero handler. This shouldn't happen!",cardNum);    return zerohandler;    }    if(idlehandler) {    if(needZero && idlehandler->CwIndex()!=0 && !noshift) {      if(indexMap[0]==0) {        indexMap[0]=1;        indexMap[idlehandler->CwIndex()]=0;        idlehandler->ShiftCwIndex(0);        }      else PRINTF(L_CORE_ECM,"%d: zero index not free. (2)",cardNum);      }    if(!needZero && idlehandler->CwIndex()==0 && !noshift) {      int idx=GetFreeIndex();      if(idx>=0) {        indexMap[idx]=1;        idlehandler->ShiftCwIndex(idx);        indexMap[0]=0;        }      else PRINTF(L_CORE_ECM,"%d: no free cwindex. Can't free zero index. (2)",cardNum);      }    if((needZero ^ (idlehandler->CwIndex()==0)))      PRINTF(L_CORE_ECM,"%d: idlehandler index doesn't match needZero",cardNum);    return idlehandler;    }  int idx=GetFreeIndex();  if(!needZero && idx==0) {    indexMap[0]=1;    idx=GetFreeIndex();    indexMap[0]=0;    if(idx<0) {      idx=0;      PRINTF(L_CORE_ECM,"%d: can't respect !needZero for new handler",cardNum);      }    }  if(idx<0) {    PRINTF(L_CORE_ECM,"%d: no free cwindex",cardNum);    return 0;    }  indexMap[idx]=1;  idlehandler=new cEcmHandler(this,cardNum,idx);  handlerList.Add(idlehandler);  return idlehandler;}void cCam::RemHandler(cEcmHandler *handler){  int idx=handler->CwIndex();  PRINTF(L_CORE_PIDS,"%d: removing %s on cw index %d",cardNum,handler->Id(),idx);  handlerList.Del(handler);  indexMap[idx]=0;}// --- cChannelCaids -----------------------------------------------------------#if APIVERSNUM >= 10500class cChannelCaids : public cSimpleItem {private:  int prg, source, transponder;  int numcaids;  caid_t caids[MAX_CI_SLOT_CAIDS+1];public:  cChannelCaids(cChannel *channel);  bool IsChannel(cChannel *channel);  void Sort(void);  void Del(caid_t caid);  bool HasCaid(caid_t caid);  bool Same(cChannelCaids *ch);  void HistAdd(unsigned short *hist);  void Dump(int n);  const caid_t *Caids(void) { caids[numcaids]=0; return caids; }  int NumCaids(void) { return numcaids; }  };cChannelCaids::cChannelCaids(cChannel *channel){  prg=channel->Sid(); source=channel->Source(); transponder=channel->Transponder();  numcaids=0;  for(const caid_t *ids=channel->Caids(); *ids; ids++)    if(numcaids<MAX_CI_SLOT_CAIDS) caids[numcaids++]=*ids;  Sort();}bool cChannelCaids::IsChannel(cChannel *channel){  return prg==channel->Sid() && source==channel->Source() && transponder==channel->Transponder();}void cChannelCaids::Sort(void){  caid_t tmp[MAX_CI_SLOT_CAIDS];  int c=0xFFFF;  for(int i=0; i<numcaids; i++) {    int d=0;    for(int j=0; j<numcaids; j++) if(caids[j]>d && caids[j]<c) d=caids[j];    tmp[i]=d; c=d;    }  memcpy(caids,tmp,sizeof(caids));}void cChannelCaids::Del(caid_t caid){  for(int i=0; i<numcaids; i++)    if(caids[i]==caid) {      numcaids--; caids[i]=caids[numcaids];      if(numcaids>0) Sort();      caids[numcaids]=0;      break;      }}bool cChannelCaids::HasCaid(caid_t caid){  for(int i=0; i<numcaids; i++) if(caids[i]==caid) return true;  return false;}bool cChannelCaids::Same(cChannelCaids *ch){  if(numcaids!=ch->numcaids) return false;  return memcmp(caids,ch->caids,numcaids*sizeof(caid_t))==0;}void cChannelCaids::HistAdd(unsigned short *hist){  for(int i=numcaids-1; i>=0; i--) hist[caids[i]]++;}void cChannelCaids::Dump(int n){  LBSTART(L_CORE_CAIDS);  LBPUT("%d: channel %d/%x/%x",n,prg,source,transponder);  for(const caid_t *ids=Caids(); *ids; ids++) LBPUT(" %04x",*ids);  LBEND();}// --- cChannelList ------------------------------------------------------------class cChannelList : public cSimpleList<cChannelCaids> {private:  int n;public:  cChannelList(int N);  void Unique(void);  void CheckIgnore(void);  int Histo(void);  void Purge(int caid);  };cChannelList::cChannelList(int N){  n=N;}void cChannelList::CheckIgnore(void){  for(cChannelCaids *ch=First(); ch; ch=Next(ch)) {    const caid_t *ids=ch->Caids();    while(*ids) {      int pri=0;      if(!cSystems::FindIdentBySysId(*ids,false,pri)) {        for(cChannelCaids *ch2=Next(ch); ch2; ch2=Next(ch2)) ch2->Del(*ids);        ch->Del(*ids);        }      else ids++;      }    }  PRINTF(L_CORE_CAIDS,"%d: after check",n);  for(cChannelCaids *ch=First(); ch; ch=Next(ch)) ch->Dump(n);}void cChannelList::Unique(void){  for(cChannelCaids *ch1=First(); ch1; ch1=Next(ch1)) {    for(cChannelCaids *ch2=Next(ch1); ch2;) {      if(ch1->Same(ch2) || ch2->NumCaids()<1) {        cChannelCaids *t=Next(ch2);        Del(ch2);        ch2=t;        }      else ch2=Next(ch2);      }    }  if(Count()==1 && First() && First()->NumCaids()<1) Del(First());  PRINTF(L_CORE_CAIDS,"%d: after unique",n);  for(cChannelCaids *ch=First(); ch; ch=Next(ch)) ch->Dump(n);}int cChannelList::Histo(void){  int h=-1;  unsigned short *hist=MALLOC(unsigned short,0x10000);  if(hist) {    memset(hist,0,sizeof(unsigned short)*0x10000);    for(cChannelCaids *ch=First(); ch; ch=Next(ch)) ch->HistAdd(hist);    int c=0;    for(int i=0; i<0x10000; i++)      if(hist[i]>c) { h=i; c=hist[i]; }    free(hist);    }  else PRINTF(L_GEN_ERROR,"malloc failed in cChannelList::Histo");  return h;}void cChannelList::Purge(int caid){  for(cChannelCaids *ch=First(); ch;) {    if(ch->NumCaids()<=0 || ch->HasCaid(caid)) {      cChannelCaids *t=Next(ch);      Del(ch);      ch=t;      }    else ch=Next(ch);    }  if(Count()>0) {    PRINTF(L_CORE_CAIDS,"%d: still left",n);    for(cChannelCaids *ch=First(); ch; ch=Next(ch)) ch->Dump(n);    }}// -- cScCiAdapter -------------------------------------------------------------struct TPDU {  unsigned char slot;  unsigned char tcid;  unsigned char tag;  unsigned char len;  unsigned char data[1];  };class cScCamSlot;class cScCiAdapter : public cCiAdapter {private:  cDevice *device;  cCam *cam;  cMutex ciMutex;  int cardIndex;  cRingBufferLinear *rb;  cScCamSlot *slots[MAX_CI_SLOTS];  //  cTimeMs caidTimer;  int version[MAX_CI_SLOTS];  caid_t caids[MAX_CI_SLOTS][MAX_CI_SLOT_CAIDS+1];  int tcid;  //  cTimeMs readTimer, writeTimer;  //  void BuildCaids(bool force);protected:  virtual int Read(unsigned char *Buffer, int MaxLength);  virtual void Write(const unsigned char *Buffer, int Length);  virtual bool Reset(int Slot);  virtual eModuleStatus ModuleStatus(int Slot);  virtual bool Assign(cDevice *Device, bool Query=false);public:  cScCiAdapter(cDevice *Device, int CardIndex, cCam *Cam);  ~cScCiAdapter();  void CamStop(void);  void CamAddPrg(cPrg *prg);  bool CamSoftCSA(void);  int GetCaids(int slot, unsigned short *Caids, int max);  };// -- cScCamSlot ---------------------------------------------------------------#define SLOT_CAID_CHECK 10000#define SLOT_RESET_TIME 600class cScCamSlot : public cCamSlot, public cRingBufferLinear {private:  cScCiAdapter *ciadapter;  unsigned short caids[MAX_CI_SLOT_CAIDS+1];  int slot, cardIndex, version;  cTimeMs checkTimer;  bool reset, doReply;  cTimeMs resetTimer;  eModuleStatus lastStatus;  //  int GetLength(const unsigned char * &data);  void CaInfo(unsigned char *b, int tcid, int cid);  bool Check(void);public:  cScCamSlot(cScCiAdapter *ca, int CardIndex, int Slot);  void Process(const unsigned char *data, int len);  eModuleStatus Status(void);  bool Reset(bool log=true);  };cScCamSlot::cScCamSlot(cScCiAdapter *ca, int CardIndex, int Slot):cCamSlot(ca),cRingBufferLinear(KILOBYTE(2),5+1,false,"SC-CI slot answer"),checkTimer(-SLOT_CAID_CHECK-1000){  ciadapter=ca; cardIndex=CardIndex; slot=Slot;  version=0; caids[0]=0; doReply=false; lastStatus=msReset;  Reset(false);}eModuleStatus cScCamSlot::Status(void){  eModuleStatus status;  if(reset) { 

⌨️ 快捷键说明

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