#define MAX_ECM_HOLD 15000 // delay before an idle handler stops processing
#define CAID_TIME 300000 // time between caid scans
+#define ECMCACHE_FILE "ecm.cache"
+
#define L_HEX 2
#define L_HEX_ECM LCLASS(L_HEX,2)
#define L_HEX_EMM LCLASS(L_HEX,4)
// -- cEcmData -----------------------------------------------------------------
class cEcmData : public cEcmInfo {
-private:
- bool del;
public:
- cEcmData(void);
- cEcmData(cEcmInfo *e);
- bool Save(FILE *f);
+ cEcmData(void):cEcmInfo() {}
+ cEcmData(cEcmInfo *e):cEcmInfo(e) {}
+ virtual cString ToString(bool hide=false);
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];
return false;
}
-bool cEcmData::Save(FILE *f)
+cString cEcmData::ToString(bool hide)
{
- fprintf(f,"%d:%x:%x:%s:%x/%x:%x:%x/%x",prgId,source,transponder,name,caId,emmCaId,provId,ecm_pid,ecm_table);
+ char *str;
if(data) {
- char *str=AUTOARRAY(char,dataLen*2+2);
- fprintf(f,":%d:%s\n",dataLen,HexStr(str,data,dataLen));
+ str=AUTOARRAY(char,dataLen*2+2);
+ sprintf(str,":%d:%s",dataLen,HexStr(str,data,dataLen));
+ }
+ else {
+ str=AUTOARRAY(char,4);
+ strcpy(str,":0");
}
- else
- fprintf(f,":0\n");
- return ferror(f)==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)
-:cLoader("ECM")
+:cStructList<cEcmData>("ecm cache",ECMCACHE_FILE,true,true,false,false)
{}
void cEcmCache::New(cEcmInfo *e)
{
- Lock();
+ ListLock(true);
cEcmData *dat;
if(!(dat=Exists(e))) {
+ ListUnlock();
+ AutoGenWarn();
dat=new cEcmData(e);
- Add(dat);
- Modified();
+ AddItem(dat,0,0);
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(dat->Update(e))
Modified();
+ ListUnlock();
}
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;
+ cEcmData *dat;
+ for(dat=First(); dat; dat=Next(dat))
+ if(dat->Valid() && dat->Compare(e)) break;
+ return dat;
}
int cEcmCache::GetCached(cSimpleList<cEcmInfo> *list, int sid, int Source, int Transponder)
{
int n=0;
list->Clear();
- Lock();
+ ListLock(false);
for(cEcmData *dat=First(); dat; dat=Next(dat)) {
- if(!dat->IsDeleted() && dat->prgId==sid && dat->source==Source && dat->transponder==Transponder) {
+ if(dat->Valid() && 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);
}
}
}
- Unlock();
+ ListUnlock();
return n;
}
void cEcmCache::Delete(cEcmInfo *e)
{
- Lock();
+ ListLock(false);
cEcmData *dat=Exists(e);
+ ListUnlock();
if(dat) {
- dat->Delete();
- Modified();
+ 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);
}
- Unlock();
}
void cEcmCache::Flush(void)
{
- Lock();
+ ListLock(true);
Clear();
Modified();
PRINTF(L_CORE_ECM,"cache flushed");
- Unlock();
+ ListUnlock();
}
-void cEcmCache::Load(void)
+cStructItem *cEcmCache::ParseLine(char *line)
{
- 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;
- }
+ if(dat && dat->Parse(line) && !Exists(dat)) return dat;
delete dat;
- return res;
+ return 0;
}
// -- cEcmSys ------------------------------------------------------------------
bool IsModified(void) const { return modified; }
void ListLock(bool rw) { lock.Lock(rw); }
void ListUnlock(void) { lock.Unlock(); }
+ void AutoGenWarn(void);
virtual void PostLoad(void) {}
public:
cStructLoader(const char *Type, const char *Filename, bool rw, bool miok, bool wat, bool verb);
// ----------------------------------------------------------------
-class cEcmInfo : public cSimpleItem {
+class cEcmInfo : public cStructItem {
private:
bool cached, failed;
//
cEcmInfo(const cEcmInfo *e);
cEcmInfo(const char *Name, int Pid, int CaId, int ProvId);
~cEcmInfo();
+ virtual cString ToString(bool hide=false) { return ""; }
bool Compare(const cEcmInfo *e);
bool Update(const cEcmInfo *e);
void SetSource(int PrgId, int Source, int Transponder);