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

📄 system.c

📁 这是一个LINUX环境的 VDR 插件源代码,可支持Irdeto, Seca, Viaccess, Nagra, Conax & Cryptoworks等CA系统的读卡、共享等操作。
💻 C
📖 第 1 页 / 共 2 页
字号:
}// -- cSystems -----------------------------------------------------------------cSystemLink *cSystems::first=0;int cSystems::nextSysIdent=0x1000;void cSystems::Register(cSystemLink *sysLink){  PRINTF(L_CORE_DYN,"systems: registering CA system %s, pri %d, ident %04X",sysLink->name,sysLink->pri,nextSysIdent);  sysLink->next=first;  sysLink->sysIdent=nextSysIdent++;  first=sysLink;}int cSystems::Provides(const unsigned short *SysIds, bool ff){  int n=0;  for(; *SysIds; SysIds++) {    if(ScSetup.Ignore(*SysIds)) continue;    cSystemLink *sl=first;    while(sl) {      if(sl->CanHandle(*SysIds)) {        if(sl->noFF && ff) return 0;        n++;        break;        }      sl=sl->next;      }    }  return n;}cSystemLink *cSystems::FindByName(const char *Name){  cSystemLink *sl=first;  while(sl) {    if(!strcasecmp(sl->name,Name)) return sl;    sl=sl->next;    }  return 0;}cSystemLink *cSystems::FindById(unsigned short SysId, bool ff, int oldPri){  // all pri's are negative!  // oldPri = 0 -> get highest pri system  // oldPri < 0 -> get highest pri system with pri<oldPri  // oldPri > 0 -> get lowest pri system  cSystemLink *sl=first, *csl=0;  while(sl) {    if((!ff || !sl->noFF) && sl->CanHandle(SysId)       && sl->pri<oldPri       && (!csl            || (oldPri<=0 && sl->pri>csl->pri)           || (oldPri>0 && sl->pri<csl->pri)          )       ) csl=sl;    sl=sl->next;    }  return csl;}cSystemLink *cSystems::FindByIdent(int ident){  cSystemLink *sl=first;  while(sl) {    if(sl->sysIdent==ident) return sl;    sl=sl->next;    }  return 0;}cSystem *cSystems::FindBySysName(unsigned short SysId, bool ff, const char *Name){  cSystemLink *sl=FindByName(Name);  if(sl && (!ff || !sl->noFF) && !ScSetup.Ignore(SysId) && sl->CanHandle(SysId)) return sl->Create();  return 0;}cSystem *cSystems::FindBySysId(unsigned short SysId, bool ff, int oldPri){  if(!ScSetup.Ignore(SysId)) {    cSystemLink *csl=FindById(SysId,ff,oldPri);    if(csl) return csl->Create();    }  return 0;}int cSystems::FindIdentBySysId(unsigned short SysId, bool ff, int &Pri){  if(!ScSetup.Ignore(SysId)) {    cSystemLink *csl=FindById(SysId,ff,Pri);    if(csl) {      Pri=csl->pri;      return csl->sysIdent;      }    }  return 0;}cSystem *cSystems::FindBySysIdent(int ident){  cSystemLink *csl=FindByIdent(ident);  return csl ? csl->Create() : 0;}bool cSystems::Init(const char *cfgdir){  PRINTF(L_CORE_LOAD,"** registered systems:");  for(cSystemLink *sl=first; sl; sl=sl->next)    PRINTF(L_CORE_LOAD,"** %-16s  (pri %3d)",sl->name,sl->pri);  for(cSystemLink *sl=first; sl; sl=sl->next)    if(!sl->Init(cfgdir)) return false;  return true;}void cSystems::Clean(void){  for(cSystemLink *sl=first; sl; sl=sl->next) sl->Clean();}bool cSystems::ConfigParse(const char *Name, const char *Value){  char sysName[32];  unsigned int i;  for(i=0; Name[i] && Name[i]!='.' && i<sizeof(sysName); i++)    sysName[i]=Name[i];  if(Name[i]) {    sysName[i]=0; i++;    cSystemLink *sl=FindByName(sysName);    if(sl && sl->opts) return sl->opts->Parse(&Name[i],Value);    }  return false;}void cSystems::ConfigStore(bool AsIs){  for(cSystemLink *sl=first; sl; sl=sl->next)    if(sl->opts && sl->opts->Store(AsIs)) sl->NewConfig();}cOpts *cSystems::GetSystemOpts(bool start){  static cSystemLink *sl=0;  sl=(start || !sl) ? first : sl->next;  while(sl) {    if(sl->opts) return sl->opts;    sl=sl->next;    }  return 0;}// -- cMsgCache ----------------------------------------------------------------#define FREE   0x00 // modes#define FAIL1  0x01#define FAIL2  0x3D#define FAILN  0x3E#define GOOD   0x3F#define MASK   0x3F#define QUEUED 0x40#define WAIT   0x80struct Cache {  int crc;  int mode;  };cMsgCache::cMsgCache(int NumCache, int StoreSize){  numCache=NumCache;  storeSize=StoreSize;  ptr=0; stores=0; maxFail=2;  caches=MALLOC(struct Cache,numCache);  if(caches) {    Clear();    if(storeSize>0) {      stores=MALLOC(unsigned char,numCache*storeSize);      if(!stores) PRINTF(L_GEN_ERROR,"msgcache: no memory for store area");      }    }  else PRINTF(L_GEN_ERROR,"msgcache: no memory for cache");}cMsgCache::~cMsgCache(){  free(caches);  free(stores);}void cMsgCache::SetMaxFail(int maxfail){  maxFail=min(maxfail,FAILN);  PRINTF(L_CORE_MSGCACHE,"%d/%p: maxFail set to %d",getpid(),this,maxFail);}void cMsgCache::Clear(void){  cMutexLock lock(&mutex);  memset(caches,0,sizeof(struct Cache)*numCache);  ptr=0;  PRINTF(L_CORE_MSGCACHE,"%d/%p: clear",getpid(),this);}struct Cache *cMsgCache::FindMsg(int crc){  int i=ptr;  while(1) {    if(--i<0) i=numCache-1;    struct Cache * const s=&caches[i];    if(!s->mode) break;    if(s->crc==crc) return s;    if(i==ptr) break;    }  return 0;}// returns:// -1 - msg cached as failed (max failed)// 0  - msg cached as good, result stored// >0 - msg not cached, queue idint cMsgCache::Get(const unsigned char *msg, int len, unsigned char *store){  int crc=crc32_le(0,msg,len);  cMutexLock lock(&mutex);  if(!caches || (storeSize>0 && !stores)) return -1; // sanity  struct Cache *s;  while((s=FindMsg(crc))) {    if(!(s->mode&QUEUED)) break;    s->mode|=WAIT;    PRINTF(L_CORE_MSGCACHE,"%d/%p: msg already queued. waiting to complete",getpid(),this);    wait.Wait(mutex);    }  int id;  if(!s) {    while(1) {      s=&caches[ptr];      if(!(s->mode&QUEUED)) break;      s->mode|=WAIT;      PRINTF(L_CORE_MSGCACHE,"%d/%p: queue overwrite protection id=%d",getpid(),this,ptr+1);      wait.Wait(mutex); // don't overwrite queued msg's      }    id=ptr+1;    s->crc=crc;    s->mode=QUEUED;    PRINTF(L_CORE_MSGCACHE,"%d/%p: queued msg with id=%d",getpid(),this,id);    ptr++; if(ptr>=numCache) { ptr=0; PRINTF(L_CORE_MSGCACHE,"msgcache: roll-over (%d)",numCache); }    return id;    }  else {    id=(s-&caches[0])+1;    switch(s->mode) {      case GOOD:        if(store && storeSize>0)          memcpy(store,&stores[(id-1)*storeSize],storeSize);        PRINTF(L_CORE_MSGCACHE,"%d/%p: msg is cached as GOOD (%d)",getpid(),this,id);        return 0;      case FAIL1...FAIL2:        PRINTF(L_CORE_MSGCACHE,"%d/%p: msg is cached as FAIL%d (%d)",getpid(),this,s->mode,id);        s->mode|=QUEUED;        return id;      case FAILN:      default:        PRINTF(L_CORE_MSGCACHE,"%d/%p: msg is cached as FAILN (%d)",getpid(),this,id);        return -1;      }    }}int cMsgCache::Cache(int id, bool result, const unsigned char *store){  cMutexLock lock(&mutex);  if(id<1 || !caches || (storeSize>0 && !stores)) return 0; // sanity  struct Cache *s=&caches[id-1];  LBSTARTF(L_CORE_MSGCACHE);  LBPUT("%d/%p: de-queued msg with id=%d ",getpid(),this,id);  if(s->mode&WAIT) wait.Broadcast();  if(result) {    if(store && storeSize>0)      memcpy(&stores[(id-1)*storeSize],store,storeSize);    s->mode=GOOD;    LBPUT("(GOOD)");    return 0;    }  else {    switch(s->mode&MASK) {      case GOOD:        s->mode=FREE;        // fall through      case FREE:      case FAIL1...FAIL2:        s->mode=(s->mode&MASK)+1;        if(s->mode<maxFail) {          LBPUT("(FAIL%d)",s->mode);          break;          }        // fall through      case FAILN:        s->mode=FAILN;        LBPUT("(FAILN)");        break;      }    return s->mode;    }  LBEND();}

⌨️ 快捷键说明

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