📄 cam.c
字号:
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 + -