From: leslie Date: Tue, 21 Jul 2009 03:04:15 +0000 (+0800) Subject: use CA descriptor out of CAM msg X-Git-Tag: upstream/620~258 X-Git-Url: http://www.vanbest.org/gitweb/?a=commitdiff_plain;h=0f8cc5f67e8c0fc4705d9837e75f5aeb8e16a7a9;p=sasc-ng.git use CA descriptor out of CAM msg --- diff --git a/cam.c b/cam.c index 8b384f2..1005452 100644 --- a/cam.c +++ b/cam.c @@ -599,12 +599,13 @@ 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) { + if(sscanf(buf,"%d:%x:%x:%63[^:]:%x/%x:%x:%x/%x:%d/%d%n",&prgId,&source,&transponder,Name,&caId,&emmCaId,&provId,&ecm_pid,&ecm_table,&nu,&dataIdx,&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); + if(GetHex(line,dat,nu,true)==nu && dat[0]==0x09 && dat[1]==nu-2) + AddCaDescr(dat,nu); } return true; } @@ -614,9 +615,9 @@ bool cEcmData::Parse(const char *buf) cString cEcmData::ToString(bool hide) { char *str; - if(data) { - str=AUTOARRAY(char,dataLen*2+2); - sprintf(str,":%d:%s",dataLen,HexStr(str,data,dataLen)); + if(caDescr) { + str=AUTOARRAY(char,caDescrLen*2+16); + sprintf(str,":%d/%d:%s",caDescrLen,dataIdx,HexStr(str,caDescr,caDescrLen)); } else { str=AUTOARRAY(char,4); @@ -652,7 +653,7 @@ void cEcmCache::New(cEcmInfo *e) dat->SetName(e->name); Modified(); } - if(dat->Update(e)) + if(dat->AddCaDescr(e)) Modified(); } ListUnlock(); @@ -717,6 +718,153 @@ bool cEcmCache::ParseLinePlain(const char *line) return false; } +// -- cCaDescr ----------------------------------------------------------------- + +cCaDescr::cCaDescr(void) +{ + descr=0; len=0; +} + +cCaDescr::cCaDescr(const cCaDescr &cd) +{ + descr=0; len=0; + Set(cd.descr,cd.len); +} + +cCaDescr::~cCaDescr() +{ + Clear(); +} + +const unsigned char *cCaDescr::Get(int &l) const +{ + l=len; + return descr; +} + +void cCaDescr::Set(const cCaDescr *d) +{ + Set(d->descr,d->len); +} + +void cCaDescr::Set(const unsigned char *de, int l) +{ + Clear(); + if(l) { + descr=MALLOC(unsigned char,l); + if(descr) { + memcpy(descr,de,l); + len=l; + } + } +} + +void cCaDescr::Clear(void) +{ + free(descr); descr=0; len=0; +} + +void cCaDescr::Join(const cCaDescr *cd, bool rev) +{ + if(cd->descr) { + int l=len+cd->len; + unsigned char *m=MALLOC(unsigned char,l); + if(m) { + if(!rev) { + if(descr) memcpy(m,descr,len); + memcpy(m+len,cd->descr,cd->len); + } + else { + memcpy(m,cd->descr,cd->len); + if(descr) memcpy(m+cd->len,descr,len); + } + Clear(); + descr=m; len=l; + } + } +} + +bool cCaDescr::operator== (const cCaDescr &cd) const +{ + return len==cd.len && (len==0 || memcmp(descr,cd.descr,len)==0); +} + +// -- cPrg --------------------------------------------------------------------- + +cPrg::cPrg(void) +{ + Setup(); +} + +cPrg::cPrg(int Sid, bool IsUpdate) +{ + Setup(); + sid=Sid; isUpdate=IsUpdate; +} + +void cPrg::Setup(void) +{ + sid=-1; source=-1; transponder=-1; + isUpdate=pidCaDescr=false; +} + +bool cPrg::SimplifyCaDescr(void) +{ +//XXX +{ +PRINTF(L_CORE_PIDS,"SimplyCa entry pidCa=%d",HasPidCaDescr()); +const unsigned char *d; +int l; +d=caDescr.Get(l); +if(d) LDUMP(L_CORE_PIDS,d,l,"prgca:"); +else PRINTF(L_CORE_PIDS,"prgca: "); +for(cPrgPid *pid=pids.First(); pid; pid=pids.Next(pid)) { + d=pid->caDescr.Get(l); + if(d) LDUMP(L_CORE_PIDS,d,l,"pidca %04x:",pid->pid); + else PRINTF(L_CORE_PIDS,"pidca %04x: ",pid->pid); + } +} +//XXX + + if(HasPidCaDescr()) { + bool equal=true; + if(pids.Count()>1) { + cPrgPid *pid0=pids.First(); + for(cPrgPid *pid1=pids.Next(pid0); pid1; pid1=pids.Next(pid1)) + if(!(pid0->caDescr==pid1->caDescr)) { equal=false; break; } + } + if(equal) { + cPrgPid *pid=pids.First(); + caDescr.Join(&pid->caDescr); + for(; pid; pid=pids.Next(pid)) pid->caDescr.Clear(); + SetPidCaDescr(false); + } + } + if(HasPidCaDescr()) { + for(cPrgPid *pid=pids.First(); pid; pid=pids.Next(pid)) + pid->caDescr.Join(&caDescr,true); + caDescr.Clear(); + } + +//XXX +{ +PRINTF(L_CORE_PIDS,"SimplyCa exit pidCa=%d",HasPidCaDescr()); +const unsigned char *d; +int l; +d=caDescr.Get(l); +if(d) LDUMP(L_CORE_PIDS,d,l,"prgca:"); +else PRINTF(L_CORE_PIDS,"prgca: "); +for(cPrgPid *pid=pids.First(); pid; pid=pids.Next(pid)) { + d=pid->caDescr.Get(l); + if(d) LDUMP(L_CORE_PIDS,d,l,"pidca %04x:",pid->pid); + else PRINTF(L_CORE_PIDS,"pidca %04x: ",pid->pid); + } +} +//XXX + + return HasPidCaDescr(); +} + // -- cEcmSys ------------------------------------------------------------------ class cEcmPri : public cSimpleItem { @@ -735,12 +883,12 @@ private: cTimeMs idleTime; // cMutex dataMutex; - int sid; - cSimpleList pids; + cPrg prg; // cSystem *sys; cPidFilter *filter; int filterCwIndex, filterSource, filterTransponder, filterSid; + cCaDescr filterCaDescr; unsigned char lastCw[16]; bool sync, noKey, trigger; int triggerMode; @@ -774,12 +922,12 @@ public: cEcmHandler(cCam *Cam, int CardNum, int cwindex); virtual ~cEcmHandler(); void Stop(void); - void SetPrg(cPrg *prg); + 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 Sid(void) const { return prg.sid; } int CwIndex(void) const { return cwIndex; } const char *Id(void) const { return id; } }; @@ -791,7 +939,7 @@ cEcmHandler::cEcmHandler(cCam *Cam, int CardNum, int cwindex) cam=Cam; cardNum=CardNum; cwIndex=cwindex; - sys=0; filter=0; ecm=0; ecmPri=0; mode=-1; sid=-1; + sys=0; filter=0; ecm=0; ecmPri=0; mode=-1; trigger=false; triggerMode=-1; filterSource=filterTransponder=0; filterCwIndex=-1; filterSid=-1; id=bprintf("%d.%d",cardNum,cwindex); @@ -810,7 +958,7 @@ cEcmHandler::~cEcmHandler() bool cEcmHandler::IsIdle(void) { dataMutex.Lock(); - int n=pids.Count(); + int n=prg.pids.Count(); dataMutex.Unlock(); return n==0; } @@ -823,11 +971,11 @@ bool cEcmHandler::IsRemoveable(void) void cEcmHandler::Stop(void) { dataMutex.Lock(); - if(!IsIdle() || sid!=-1) { + if(!IsIdle() || prg.sid!=-1) { PRINTF(L_CORE_ECM,"%s: stop",id); - sid=-1; + prg.sid=-1; idleTime.Set(); - pids.Clear(); + prg.pids.Clear(); trigger=true; } dataMutex.Unlock(); @@ -843,61 +991,69 @@ void cEcmHandler::ShiftCwIndex(int cwindex) dataMutex.Lock(); trigger=true; cwIndex=cwindex; - for(cPrgPid *pid=pids.First(); pid; pid=pids.Next(pid)) - cam->SetCWIndex(pid->Pid(),cwIndex); + for(cPrgPid *pid=prg.pids.First(); pid; pid=prg.pids.Next(pid)) + cam->SetCWIndex(pid->pid,cwIndex); dataMutex.Unlock(); if(filter) filter->Wakeup(); } } -void cEcmHandler::SetPrg(cPrg *prg) +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(); + if(Prg->sid!=prg.sid) { + PRINTF(L_CORE_ECM,"%s: setting new SID %d",id,Prg->sid); + prg.sid=Prg->sid; + prg.source=Prg->source; + prg.transponder=Prg->transponder; idleTime.Set(); - pids.Clear(); + prg.pids.Clear(); + trigger=true; + } + if(!(prg.caDescr==Prg->caDescr)) { + prg.caDescr.Set(&Prg->caDescr); trigger=true; } + if(Prg->HasPidCaDescr()) + PRINTF(L_GEN_DEBUG,"internal: pid specific caDescr not supported at this point (sid=%d)",Prg->sid); 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()); + for(cPrgPid *pid=prg.pids.First(); pid; pid=prg.pids.Next(pid)) + LBPUT(" %s=%04x",TYPENAME(pid->type),pid->pid); LBEND(); - for(cPrgPid *pid=pids.First(); pid;) { + for(cPrgPid *pid=prg.pids.First(); pid;) { cPrgPid *npid; - for(npid=prg->pids.First(); npid; npid=prg->pids.Next(npid)) { - if(pid->Pid()==npid->Pid()) { + 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); + npid=prg.pids.Next(pid); + prg.pids.Del(pid); pid=npid; } - else pid=pids.Next(pid); + else pid=prg.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()); + for(cPrgPid *pid=prg.pids.First(); pid; pid=prg.pids.Next(pid)) + LBPUT(" %s=%04x",TYPENAME(pid->type),pid->pid); LBEND(); - for(cPrgPid *npid=prg->pids.First(); npid; npid=prg->pids.Next(npid)) { + 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); + cPrgPid *pid=new cPrgPid(npid->type,npid->pid); + prg.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()); + for(cPrgPid *pid=prg.pids.First(); pid; pid=prg.pids.Next(pid)) + LBPUT(" %s=%04x",TYPENAME(pid->type),pid->pid); LBEND(); if(!IsIdle()) { trigger=true; @@ -922,12 +1078,12 @@ 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":"-"); + id,filterSid,prg.sid,filterCwIndex,cwIndex,mode,triggerMode,(mode==3 && sync)?"sync":"-"); trigger=false; - if(filterSid!=sid) { - filterSid=sid; - filterSource=cam->Source(); - filterTransponder=cam->Transponder(); + if(filterSid!=prg.sid) { + filterSid=prg.sid; + filterSource=prg.source; + filterTransponder=prg.transponder; filterCwIndex=cwIndex; noKey=true; mode=0; } @@ -937,6 +1093,10 @@ void cEcmHandler::Process(cPidFilter *filter, unsigned char *data, int len) if(mode==3 && sync) cam->WriteCW(filterCwIndex,lastCw,true); } + if(!(prg.caDescr==filterCaDescr)) { + filterCaDescr.Set(&prg.caDescr); + //XXX do we need to trigger something here?? + } if(modeGetPrgCaids(filterSource,filterTransponder,filterSid,casys)) { - PRINTF(L_CORE_ECM,"%s: no CAIDs for SID %d",id,sid); - return; - } - } - else { - casys[0]=SysId; - casys[1]=0; - } - bool streamFlag; - int len=GetCaDescriptors(filterSource,filterTransponder,filterSid,casys,sizeof(buff),buff,streamFlag); - if(len>0) { - if(dolog) PRINTF(L_CORE_ECM,"%s: got CaDescriptors for SID %d (len=%d)",id,sid,len); + int len; + const unsigned char *buff=filterCaDescr.Get(len); + if(buff && len>0) { + if(dolog) PRINTF(L_CORE_ECM,"%s: CA descriptors for SID %d (len=%d)",id,filterSid,len); HEXDUMP(L_HEX_PMT,buff,len,"PMT"); for(int index=0; indexIsSoftCSA(filterCwIndex==0),sysPri))) { @@ -1278,9 +1427,7 @@ void cEcmHandler::ParseCAInfo(int SysId) while(e) { if(e->ecm_pid==n->ecm_pid) { if(e->caId==n->caId && e->provId==n->provId) { - if(n->Data()) { - if(e->Update(n) && dolog) LBPUT("(updated) "); - } + if(e->AddCaDescr(n) && dolog) LBPUT("(updated) "); if(dolog) LBPUT("(already present)"); delete n; n=0; break; @@ -1294,7 +1441,8 @@ void cEcmHandler::ParseCAInfo(int SysId) } if(n) { if(dolog) LBPUT("(new)"); - n->SetSource(sid,filterSource,filterTransponder); + n->SetSource(filterSid,filterSource,filterTransponder); + n->AddCaDescr(&buff[index+2],buff[index+1]); ecmList.Add(n); AddEcmPri(n); } @@ -1383,23 +1531,33 @@ void cCam::AddPrg(cPrg *prg) cMutexLock lock(this); bool islive=false; for(cPrgPid *pid=prg->pids.First(); pid; pid=prg->pids.Next(pid)) - if(pid->Pid()==liveVpid || pid->Pid()==liveApid) { + if(pid->pid==liveVpid || pid->pid==liveApid) { islive=true; break; } bool needZero=!IsSoftCSA(islive) && (islive || !ScSetup.ConcurrentFF); bool noshift=IsSoftCSA(true) || (prg->IsUpdate() && prg->pids.Count()==0); - PRINTF(L_CORE_PIDS,"%d: %s SID %d (zero=%d noshift=%d)",cardNum,prg->IsUpdate()?"update":"add",prg->Prg(),needZero,noshift); + PRINTF(L_CORE_PIDS,"%d: %s SID %d (zero=%d noshift=%d)",cardNum,prg->IsUpdate()?"update":"add",prg->sid,needZero,noshift); if(prg->pids.Count()>0) { LBSTART(L_CORE_PIDS); LBPUT("%d: pids",cardNum); for(cPrgPid *pid=prg->pids.First(); pid; pid=prg->pids.Next(pid)) - LBPUT(" %s=%04x",TYPENAME(pid->Type()),pid->Pid()); + LBPUT(" %s=%04x",TYPENAME(pid->type),pid->pid); LBEND(); } - cEcmHandler *handler=GetHandler(prg->Prg(),needZero,noshift); + if(prg->pids.Count()>0 && prg->SimplifyCaDescr()) { + PRINTF(L_GEN_WARN,"Stream specific caDescr (aka split-ecm) cannot be handled yet (SID %d)",prg->sid); + // take first caDescr and ignore the rest.... + cPrgPid *pid=prg->pids.First(); + prg->caDescr.Set(&pid->caDescr); + for(; pid; pid=prg->pids.Next(pid)) pid->caDescr.Clear(); + prg->SetPidCaDescr(false); + } + cEcmHandler *handler=GetHandler(prg->sid,needZero,noshift); if(handler) { - PRINTF(L_CORE_PIDS,"%d: found handler for SID %d (%s idle=%d idx=%d)",cardNum,prg->Prg(),handler->Id(),handler->IsIdle(),handler->CwIndex()); + PRINTF(L_CORE_PIDS,"%d: found handler for SID %d (%s idle=%d idx=%d)",cardNum,prg->sid,handler->Id(),handler->IsIdle(),handler->CwIndex()); + prg->source=source; + prg->transponder=transponder; handler->SetPrg(prg); } } @@ -1447,11 +1605,6 @@ void cCam::HouseKeeping(void) } } -bool cCam::GetPrgCaids(int source, int transponder, int prg, caid_t *c) -{ - return device->GetPrgCaids(source,transponder,prg,c); -} - void cCam::LogStartup(void) { cMutexLock lock(this); @@ -2015,6 +2168,7 @@ void cScCamSlot::Process(const unsigned char *data, int len) LBPUT("/%x",dlen); if(ilen>0 && dlen>=ilen) { ci_cmd=data[0]; + prg->caDescr.Set(&data[1],ilen-1); LBPUT(" ci_cmd(G)=%02x",ci_cmd); } data+=ilen; dlen-=ilen; @@ -2027,6 +2181,8 @@ void cScCamSlot::Process(const unsigned char *data, int len) LBPUT("/%x",dlen); if(ilen>0 && dlen>=ilen) { ci_cmd=data[0]; + pid->caDescr.Set(&data[1],ilen-1); + prg->SetPidCaDescr(true); LBPUT(" ci_cmd(S)=%x",ci_cmd); } data+=ilen; dlen-=ilen; @@ -2038,20 +2194,20 @@ void cScCamSlot::Process(const unsigned char *data, int len) b[3]=0x90; b[4]=0x02; b[5]=cid<<8; b[6]=cid&0xff; b[7]=0x9f; b[8]=0x80; b[9]=0x33; // AOT_CA_PMT_REPLY - b[11]=prg->Prg()<<8; - b[12]=prg->Prg()&0xff; + b[11]=prg->sid<<8; + b[12]=prg->sid&0xff; b[13]=0x00; b[14]=0x81; // CA_ENABLE b[10]=4; b[1]=4+9; a[0]=4+11; Put(a,4+12); PRINTF(L_CORE_CI,"%d.%d answer to query",cardIndex,slot); } - if(prg->Prg()!=0) { + if(prg->sid!=0) { if(ci_cmd==0x04) { PRINTF(L_CORE_CI,"%d.%d stop decrypt",cardIndex,slot); ciadapter->CamStop(); } if(ci_cmd==0x01 || (ci_cmd==-1 && (ca_lm==0x04 || ca_lm==0x05))) { - PRINTF(L_CORE_CI,"%d.%d set CAM decrypt (prg %d)",cardIndex,slot,prg->Prg()); + PRINTF(L_CORE_CI,"%d.%d set CAM decrypt (prg %d)",cardIndex,slot,prg->sid); ciadapter->CamAddPrg(prg); } } @@ -2575,7 +2731,6 @@ cScDvbDevice::cScDvbDevice(int n, int cafd) #if APIVERSNUM >= 10500 ciadapter=0; hwciadapter=0; #endif - memset(lrucaid,0,sizeof(lrucaid)); fd_ca=cafd; fd_ca2=dup(fd_ca); fd_dvr=-1; softcsa=(fd_ca<0); } @@ -2758,46 +2913,12 @@ bool cScDvbDevice::SetPid(cPidHandle *Handle, int Type, bool On) bool cScDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) { - lruMutex.Lock(); - int i=FindLRUPrg(Channel->Source(),Channel->Transponder(),Channel->Sid()); - if(i<0) i=MAX_LRU_CAID-1; - if(i>0) memmove(&lrucaid[1],&lrucaid[0],sizeof(struct LruCaid)*i); -#if APIVERSNUM >= 10500 - const caid_t *c=Channel->Caids(); - for(i=0; iCa(i))==0) break; -#endif - lrucaid[0].src=Channel->Source(); - lrucaid[0].tr=Channel->Transponder(); - lrucaid[0].prg=Channel->Sid(); - lruMutex.Unlock(); if(cam) cam->Tune(Channel); bool ret=cDvbDevice::SetChannelDevice(Channel,LiveView); if(ret && cam) cam->PostTune(); return ret; } -bool cScDvbDevice::GetPrgCaids(int source, int transponder, int prg, caid_t *c) -{ - cMutexLock lock(&lruMutex); - int i=FindLRUPrg(source,transponder,prg); - if(i>=0) { - for(int j=0; j pids; + cCaDescr caDescr; // - cPrg(int Prg, bool IsUpdate) { prg=Prg; isUpdate=IsUpdate; } - int Prg(void) { return prg; } - bool IsUpdate(void) { return isUpdate; } + cPrg(void); + cPrg(int Sid, bool IsUpdate); + bool IsUpdate(void) const { return isUpdate; } + bool HasPidCaDescr(void) const { return pidCaDescr; } + void SetPidCaDescr(bool val) { pidCaDescr=val; } + bool SimplifyCaDescr(void); }; // ---------------------------------------------------------------- @@ -122,7 +146,6 @@ public: void SetCWIndex(int pid, int index); void DumpAV7110(void); void LogEcmStatus(const cEcmInfo *ecm, bool on); - bool GetPrgCaids(int source, int transponder, int prg, caid_t *c); void AddHook(cLogHook *hook); bool TriggerHook(int id); // Plugin API @@ -137,16 +160,12 @@ public: char *CurrentKeyStr(int num); // bool IsSoftCSA(bool live); - int Source(void) { return source; } - int Transponder(void) { return transponder; } }; void LogStatsDown(void); // ---------------------------------------------------------------- -#define MAX_LRU_CAID 10 - class cScDvbDevice : public cDvbDevice { private: cDeCSA *decsa; @@ -161,17 +180,11 @@ private: bool softcsa, fullts; cMutex cafdMutex; cTimeMs lastDump; - struct LruCaid { - int src, tr, prg; - caid_t caids[MAXCAIDS+1]; - } lrucaid[MAX_LRU_CAID]; - cMutex lruMutex; static int budget; // #ifndef SASC void LateInit(void); void EarlyShutdown(void); - int FindLRUPrg(int source, int transponder, int prg); bool ScActive(void); #endif //SASC protected: @@ -210,7 +223,6 @@ public: void DumpAV7110(void); cCam *Cam(void) { return cam; } bool SoftCSA(bool live); - virtual bool GetPrgCaids(int source, int transponder, int prg, caid_t *c); }; #endif // ___CAM_H diff --git a/data.c b/data.c index 4261f0b..875c86d 100644 --- a/data.c +++ b/data.c @@ -584,7 +584,8 @@ cEcmInfo::cEcmInfo(const cEcmInfo *e) caId=e->caId; emmCaId=e->emmCaId; provId=e->provId; - Update(e); + AddCaDescr(e); + dataIdx=e->dataIdx; prgId=e->prgId; source=e->source; transponder=e->transponder; @@ -600,14 +601,14 @@ cEcmInfo::cEcmInfo(const char *Name, int Pid, int CaId, int ProvId) cEcmInfo::~cEcmInfo() { - ClearData(); + ClearCaDescr(); free(name); } void cEcmInfo::Setup(void) { cached=failed=false; - name=0; data=0; + name=0; caDescr=0; caDescrLen=0; dataIdx=-1; prgId=source=transponder=-1; ecm_table=0x80; emmCaId=0; } @@ -618,11 +619,6 @@ bool cEcmInfo::Compare(const cEcmInfo *e) caId==e->caId && ecm_pid==e->ecm_pid && provId==e->provId; } -bool cEcmInfo::Update(const cEcmInfo *e) -{ - return (e->data && (!data || e->dataLen!=dataLen)) ? AddData(e->data,e->dataLen) : false; -} - void cEcmInfo::SetSource(int PrgId, int Source, int Transponder) { prgId=PrgId; @@ -630,21 +626,49 @@ void cEcmInfo::SetSource(int PrgId, int Source, int Transponder) transponder=Transponder; } -void cEcmInfo::ClearData(void) +void cEcmInfo::ClearCaDescr(void) +{ + free(caDescr); caDescr=0; caDescrLen=0; +} + +bool cEcmInfo::AddCaDescr(const cEcmInfo *e) { - free(data); data=0; + bool res=AddCaDescr(e->caDescr,e->caDescrLen); + if(e->dataIdx>=0 && (dataIdx<0 || e->dataIdx!=dataIdx)) res=true; + dataIdx=e->dataIdx; + return res; } -bool cEcmInfo::AddData(const unsigned char *Data, int DataLen) +bool cEcmInfo::AddCaDescr(const unsigned char *descr, int len) { - ClearData(); - data=MALLOC(unsigned char,DataLen); - if(data) { - memcpy(data,Data,DataLen); - dataLen=DataLen; + bool res=false; + if(descr && (!caDescr || caDescrLen!=len || memcmp(caDescr,descr,len)!=0)) { + unsigned char *mem=MALLOC(unsigned char,len); + if(mem) { + ClearCaDescr(); + memcpy(mem,descr,len); + caDescr=mem; caDescrLen=len; + res=true; + } + else PRINTF(L_GEN_ERROR,"malloc failed in cEcmInfo::AddCaDescr()"); } - else PRINTF(L_GEN_ERROR,"malloc failed in cEcmInfo::AddData()"); - return (data!=0); + return res; +} + +const unsigned char *cEcmInfo::GetCaDescr(int *l) const +{ + if(l) *l=caDescrLen; + return caDescr; +} + +void cEcmInfo::SetDataIdx(int idx) +{ + dataIdx=idx; +} + +const unsigned char *cEcmInfo::Data(void) const +{ + return (dataIdx>=0 && caDescr && caDescrLen>dataIdx) ? &caDescr[dataIdx] : 0; } void cEcmInfo::SetName(const char *Name) diff --git a/data.h b/data.h index e5f7c5c..26140ec 100644 --- a/data.h +++ b/data.h @@ -222,10 +222,10 @@ private: // void Setup(void); protected: - int dataLen; - unsigned char *data; + int caDescrLen, dataIdx; + unsigned char *caDescr; // - void ClearData(void); + void ClearCaDescr(void); public: char *name; int ecm_pid, ecm_table; @@ -238,11 +238,13 @@ public: ~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); void SetName(const char *Name); - bool AddData(const unsigned char *Data, int DataLen); - const unsigned char *Data(void) const { return data; } + void SetDataIdx(int idx); + const unsigned char *Data(void) const; + bool AddCaDescr(const cEcmInfo *e); + bool AddCaDescr(const unsigned char *descr, int len); + const unsigned char *GetCaDescr(int *l) const; void Fail(bool st) { failed=st; } bool Failed(void) const { return failed; } void SetCached(void) { cached=true; } diff --git a/system.c b/system.c index 28ed4ce..ab6d2c6 100644 --- a/system.c +++ b/system.c @@ -136,7 +136,7 @@ void cSystem::ParseCADescriptor(cSimpleList *ecms, unsigned short sysI case 0x01: // Seca style for(int p=2; pAddData(&data[p+5],10); + if(data[p+4]==0xFF) n->SetDataIdx(p+5); ecms->Add(n); } break; diff --git a/systems/cardclient/cccam.c b/systems/cardclient/cccam.c index f1c1aed..920392a 100644 --- a/systems/cardclient/cccam.c +++ b/systems/cardclient/cccam.c @@ -227,6 +227,13 @@ bool cCardClientCCcam::ProcessECM(const cEcmInfo *ecm, const unsigned char *data cCCcamCard *c=&card[cardnum]; int timeout=3000; if(ecm->ecm_pid!=c->Pid() || !c->Connected()) { // channel change + int n; + const unsigned char *descr=ecm->GetCaDescr(&n); + if(!descr) { + PRINTF(L_CC_CCCAM,"%d: no CA descriptor for caid %04x sid %d prov %04x",cardnum,ecm->caId,ecm->prgId,ecm->provId); + return false; + } + static const unsigned char pmt[] = { 0x9f,0x80,0x32,0x82,0xFF,0xFF, 0x01, @@ -244,7 +251,7 @@ bool cCardClientCCcam::ProcessECM(const cEcmInfo *ecm, const unsigned char *data #define PID_POS 27 0x84,0x02,0xFF,0xFF // pmt pid }; - unsigned char capmt[2048]; + unsigned char *capmt=AUTOMEM(sizeof(pmt)+n+32); memcpy(capmt,pmt,sizeof(pmt)); int wp=sizeof(pmt); int len=wp-LEN_POS-2; @@ -261,19 +268,7 @@ bool cCardClientCCcam::ProcessECM(const cEcmInfo *ecm, const unsigned char *data capmt[DMX_POS+3]=cardnum ; capmt[PID_POS+2]=ecm->ecm_pid>>8; capmt[PID_POS+3]=ecm->ecm_pid&0xFF; - bool streamflag=1; -#if APIVERSNUM >= 10500 - int casys[2]; -#else - unsigned short casys[2]; -#endif - casys[0]=ecm->caId; - casys[1]=0; - int n=GetCaDescriptors(ecm->source,ecm->transponder,ecm->prgId,casys,sizeof(capmt)-wp,&capmt[wp],streamflag); - if(n<=0) { - PRINTF(L_CC_CCCAM,"%d: no CA descriptor for caid %04x sid %d prov %04x",cardnum,ecm->caId,ecm->prgId,ecm->provId); - return false; - } + memcpy(&capmt[wp],descr,n); len+=n; wp+=n; capmt[wp++]=0x01; capmt[wp++]=0x0f; diff --git a/systems/cardclient/gbox.c b/systems/cardclient/gbox.c index 81d08c5..7be1a47 100644 --- a/systems/cardclient/gbox.c +++ b/systems/cardclient/gbox.c @@ -89,6 +89,12 @@ bool cCardClientGbox::ProcessECM(const cEcmInfo *ecm, const unsigned char *data, const int caid=ecm->caId; const int pid =ecm->ecm_pid; + int n; + const unsigned char *descr=ecm->GetCaDescr(&n); + if(!descr) { + PRINTF(L_CC_GBOX,"no CA descriptor for caid %04x sid %d prov %04x",caid,ecm->prgId,ecm->provId); + return false; + } static const unsigned char pmt[] = { 0x87, @@ -99,23 +105,11 @@ bool cCardClientGbox::ProcessECM(const cEcmInfo *ecm, const unsigned char *data, 0xf0,0x00, // prg info len 0x02, 0xff,0xec, 0xf0,0x00 }; - unsigned char buff[512]; + unsigned char *buff=AUTOMEM(sizeof(pmt)+8+n); memcpy(buff,pmt,sizeof(pmt)); buff[4]=ecm->prgId >> 8; buff[5]=ecm->prgId & 0xFF; -#if APIVERSNUM >= 10500 - int casys[2]; -#else - unsigned short casys[2]; -#endif - casys[0]=caid; - casys[1]=0; - bool streamFlag; - int n=GetCaDescriptors(ecm->source,ecm->transponder,ecm->prgId,casys,sizeof(buff)-sizeof(pmt),&buff[sizeof(pmt)],streamFlag); - if(n<=0) { - PRINTF(L_CC_GBOX,"no CA descriptor for caid %04x sid %d prov %04x",caid,ecm->prgId,ecm->provId); - return false; - } + memcpy(&buff[sizeof(pmt)],descr,n); buff[16]=0xF0 | ((n>>8)&0x0F); buff[17]=n & 0xFF; SetSctLen(&buff[1],sizeof(pmt)-4+n+4);