From: leslie Date: Sun, 21 Aug 2011 18:51:37 +0000 (+0200) Subject: virtualise CAM hardware access X-Git-Tag: upstream/620~42 X-Git-Url: http://www.vanbest.org/gitweb/?a=commitdiff_plain;h=6a033ad97e054c41c3b1c5134339035c2a567dbe;p=sasc-ng.git virtualise CAM hardware access --- diff --git a/cam.c b/cam.c index d438e4b..2ac3213 100644 --- a/cam.c +++ b/cam.c @@ -2036,11 +2036,11 @@ struct TPDU { }; #endif -cCam::cCam(cDevice *Device, int Adapter, int Frontend, const char *DevId, int Cafd, bool SoftCSA, bool FullTS) +cCam::cCam(cDevice *Device, int Adapter, int Frontend, const char *DevId, cScDevicePlugin *DevPlugin, bool SoftCSA, bool FullTS) { - device=Device; adapter=Adapter; frontend=Frontend; devId=DevId; cafd=Cafd; + device=Device; devplugin=DevPlugin; adapter=Adapter; frontend=Frontend; devId=DevId; softcsa=SoftCSA; fullts=FullTS; - tcid=0; rebuildcaids=false; + decsa=0; tcid=0; rebuildcaids=false; memset(version,0,sizeof(version)); #ifndef SASC memset(slots,0,sizeof(slots)); @@ -2055,7 +2055,7 @@ cCam::cCam(cDevice *Device, int Adapter, int Frontend, const char *DevId, int Ca } else PRINTF(L_GEN_ERROR,"failed to create ringbuffer for SC-CI adapter %s.",devId); - decsa=softcsa ? new cDeCSA(devId) : 0; + if(softcsa) decsa=new cDeCSA(devId); #endif //!SASC source=transponder=-1; liveVpid=liveApid=0; logger=0; hookman=0; @@ -2563,11 +2563,10 @@ void cCam::WriteCW(int index, unsigned char *cw, bool force) bool cCam::SetCaDescr(ca_descr_t *ca_descr, bool initial) { #ifndef SASC - if(!softcsa || (fullts && ca_descr->index==0)) { - cMutexLock lock(&cafdMutex); - return ioctl(cafd,CA_SET_DESCR,ca_descr)>=0; - } - else if(decsa) return decsa->SetDescr(ca_descr,initial); + if(!softcsa || (fullts && ca_descr->index==0)) + return devplugin->SetCaDescr(device,ca_descr,initial); + else if(decsa) + return decsa->SetDescr(ca_descr,initial); #endif //!SASC return false; } @@ -2575,93 +2574,18 @@ bool cCam::SetCaDescr(ca_descr_t *ca_descr, bool initial) bool cCam::SetCaPid(ca_pid_t *ca_pid) { #ifndef SASC - if(!softcsa || (fullts && ca_pid->index==0)) { - cMutexLock lock(&cafdMutex); - return ioctl(cafd,CA_SET_PID,ca_pid)>=0; - } - else if(decsa) return decsa->SetCaPid(ca_pid); + if(!softcsa || (fullts && ca_pid->index==0)) + return devplugin->SetCaPid(device,ca_pid); + else if(decsa) + return decsa->SetCaPid(ca_pid); #endif //!SASC return false; } -#ifndef SASC -static unsigned int av7110_read(int fd, unsigned int addr) -{ - ca_pid_t arg; - arg.pid=addr; - ioctl(fd,CA_GET_MSG,&arg); - return arg.index; -} -#endif //!SASC - -#if 0 -static void av7110_write(int fd, unsigned int addr, unsigned int val) -{ - ca_pid_t arg; - arg.pid=addr; - arg.index=val; - ioctl(fd,CA_SEND_MSG,&arg); -} -#endif - void cCam::DumpAV7110(void) { #ifndef SASC - if(LOG(L_CORE_AV7110)) { -#define CODEBASE (0x2e000404+0x1ce00) - cMutexLock lock(&cafdMutex); - if(device->HasDecoder() && lastDump.Elapsed()>20000) { - lastDump.Set(); - static unsigned int handles=0, hw_handles=0; - static const unsigned int code[] = { - 0xb5100040,0x4a095a12,0x48094282,0xd00b4b09,0x20000044, - 0x5b1c4294,0xd0033001,0x281cdbf8,0xe001f7fe,0xfd14bc10 - }; - static const unsigned int mask[] = { - 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff, - 0xffffffff,0xffffffff,0xffffffff,0xfffff800,0xf800ffff - }; - if(!handles) { - handles=1; - PRINTF(L_CORE_AV7110,"searching handle tables"); - for(int i=0; i<0x2000; i+=4) { - int j; - for(j=0; j<20; j+=4) { - int r=av7110_read(cafd,CODEBASE+i+j); - if((r&mask[j/4])!=(code[j/4]&mask[j/4])) break; - } - if(j==20) { - handles=av7110_read(cafd,CODEBASE+i+44); - hw_handles=av7110_read(cafd,CODEBASE+i+52); - PRINTF(L_CORE_AV7110,"found handles=%08x hw_handles=%08x at 0x%08x",handles,hw_handles,CODEBASE+i); - if((handles>>16)!=0x2e08 || (hw_handles>>16)!=0x2e08) { - PRINTF(L_CORE_AV7110,"seems to be invalid"); - } - break; - } - } - } - - unsigned int hdl=0, hwhdl=0; - PRINTF(L_CORE_AV7110," : 64000080 64000400"); - for(int i=0; i<=31; i++) { - unsigned int off80 =av7110_read(cafd,0x64000080+i*4); - unsigned int off400=av7110_read(cafd,0x64000400+i*8); - LBSTART(L_CORE_AV7110); - LBPUT("handle %2d: %08x %08x %s pid=%04x idx=%d", - i,off80,off400,off80&0x2000?"ACT":"---",off80&0x1fff,(off400&0x1e)>>1); - if(handles>1 && i<=27) { - if((i&1)==0) { - hdl=av7110_read(cafd,handles+i*2); - hwhdl=av7110_read(cafd,hw_handles+i*2); - } - unsigned int s=((~i)&1)<<4; - LBPUT(" | %02d hdl=%04x hwfilt=%04x",i,(hdl>>s)&0xffff,(hwhdl>>s)&0xffff); - } - LBEND(); - } - } - } + devplugin->DumpAV(device); #endif //!SASC } diff --git a/cam.h b/cam.h index 85137f2..f66004a 100644 --- a/cam.h +++ b/cam.h @@ -38,6 +38,7 @@ class cLogHook; class cScCamSlot; class cDeCSA; class cPrg; +class cScDevicePlugin; // ---------------------------------------------------------------- @@ -161,8 +162,7 @@ private: // cDeCSA *decsa; #endif - int cafd; - cMutex cafdMutex; + cScDevicePlugin *devplugin; bool softcsa, fullts; // cTimeMs caidTimer, triggerTimer; @@ -172,7 +172,6 @@ private: bool rebuildcaids; // cTimeMs readTimer, writeTimer; - cTimeMs lastDump; // cMutex camMutex; cSimpleList handlerList; @@ -196,7 +195,7 @@ protected: virtual bool Assign(cDevice *Device, bool Query=false); #endif public: - cCam(cDevice *Device, int Adapter, int Frontend, const char *DevId, int Cafd, bool SoftCSA, bool FullTS); + cCam(cDevice *Device, int Adapter, int Frontend, const char *DevId, cScDevicePlugin *DevPlugin, bool SoftCSA, bool FullTS); virtual ~cCam(); // CI adapter API int GetCaids(int slot, unsigned short *Caids, int max); diff --git a/device-hd.c b/device-hd.c index 36d2a25..24364d5 100644 --- a/device-hd.c +++ b/device-hd.c @@ -42,9 +42,23 @@ SCAPIVERSTAG(); #include "../dvbhddevice/dvbhdffdevice.h" #define SCDEVICE cScDvbHdFfDevice #define DVBDEVICE cDvbHdFfDevice +#define OWN_SETCA #include "device-tmpl.c" #undef SCDEVICE #undef DVBDEVICE +#undef OWN_SETCA + +bool cScDvbHdFfDevice::SetCaDescr(ca_descr_t *ca_descr, bool initial) +{ + cMutexLock lock(&cafdMutex); + return ioctl(fd_ca,CA_SET_DESCR,ca_descr)>=0; +} + +bool cScDvbHdFfDevice::SetCaPid(ca_pid_t *ca_pid) +{ + cMutexLock lock(&cafdMutex); + return ioctl(fd_ca,CA_SET_PID,ca_pid)>=0; +} // -- cScHdDevicePlugin -------------------------------------------------------- @@ -53,6 +67,8 @@ public: virtual cDevice *Probe(int Adapter, int Frontend, uint32_t SubSystemId); virtual bool LateInit(cDevice *dev); virtual bool EarlyShutdown(cDevice *dev); + virtual bool SetCaDescr(cDevice *dev, ca_descr_t *ca_descr, bool initial); + virtual bool SetCaPid(cDevice *dev, ca_pid_t *ca_pid); }; static cScHdDevicePlugin _hddevplugin; @@ -70,7 +86,7 @@ cDevice *cScHdDevicePlugin::Probe(int Adapter, int Frontend, uint32_t SubSystemI if(fd>=0) { close(fd); PRINTF(L_GEN_DEBUG,"creating HD-FF device %d/%d",Adapter,Frontend); - return new cScDvbHdFfDevice(Adapter,Frontend,cScDevices::DvbOpen(DEV_DVB_CA,Adapter,Frontend,O_RDWR)); + return new cScDvbHdFfDevice(this,Adapter,Frontend,cScDevices::DvbOpen(DEV_DVB_CA,Adapter,Frontend,O_RDWR)); } } } @@ -91,6 +107,20 @@ bool cScHdDevicePlugin::EarlyShutdown(cDevice *dev) return d!=0; } +bool cScHdDevicePlugin::SetCaDescr(cDevice *dev, ca_descr_t *ca_descr, bool initial) +{ + cScDvbHdFfDevice *d=dynamic_cast(dev); + if(d) return d->SetCaDescr(ca_descr,initial); + return false; +} + +bool cScHdDevicePlugin::SetCaPid(cDevice *dev, ca_pid_t *ca_pid) +{ + cScDvbHdFfDevice *d=dynamic_cast(dev); + if(d) return d->SetCaPid(ca_pid); + return false; +} + #endif //WITH_HDDVB #endif //APIVERSNUM >= 10711 #endif //SASC diff --git a/device-sd.c b/device-sd.c index 38e7389..b4551da 100644 --- a/device-sd.c +++ b/device-sd.c @@ -42,9 +42,102 @@ SCAPIVERSTAG(); #include "../dvbsddevice/dvbsdffdevice.h" #define SCDEVICE cScDvbSdFfDevice #define DVBDEVICE cDvbSdFfDevice +#define OWN_SETCA +#define OWN_DUMPAV #include "device-tmpl.c" #undef SCDEVICE #undef DVBDEVICE +#undef OWN_SETCA +#undef OWN_DUMPAV + +bool cScDvbSdFfDevice::SetCaDescr(ca_descr_t *ca_descr, bool initial) +{ + cMutexLock lock(&cafdMutex); + return ioctl(fd_ca,CA_SET_DESCR,ca_descr)>=0; +} + +bool cScDvbSdFfDevice::SetCaPid(ca_pid_t *ca_pid) +{ + cMutexLock lock(&cafdMutex); + return ioctl(fd_ca,CA_SET_PID,ca_pid)>=0; +} + +static unsigned int av7110_read(int fd, unsigned int addr) +{ + ca_pid_t arg; + arg.pid=addr; + ioctl(fd,CA_GET_MSG,&arg); + return arg.index; +} + +#if 0 +static void av7110_write(int fd, unsigned int addr, unsigned int val) +{ + ca_pid_t arg; + arg.pid=addr; + arg.index=val; + ioctl(fd,CA_SEND_MSG,&arg); +} +#endif + +void cScDvbSdFfDevice::DumpAV(void) +{ + if(LOG(L_CORE_AV7110)) { +#define CODEBASE (0x2e000404+0x1ce00) + cMutexLock lock(&cafdMutex); + if(HasDecoder() && lastDump.Elapsed()>20000) { + lastDump.Set(); + static unsigned int handles=0, hw_handles=0; + static const unsigned int code[] = { + 0xb5100040,0x4a095a12,0x48094282,0xd00b4b09,0x20000044, + 0x5b1c4294,0xd0033001,0x281cdbf8,0xe001f7fe,0xfd14bc10 + }; + static const unsigned int mask[] = { + 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff, + 0xffffffff,0xffffffff,0xffffffff,0xfffff800,0xf800ffff + }; + if(!handles) { + handles=1; + PRINTF(L_CORE_AV7110,"searching handle tables"); + for(int i=0; i<0x2000; i+=4) { + int j; + for(j=0; j<20; j+=4) { + int r=av7110_read(fd_ca,CODEBASE+i+j); + if((r&mask[j/4])!=(code[j/4]&mask[j/4])) break; + } + if(j==20) { + handles=av7110_read(fd_ca,CODEBASE+i+44); + hw_handles=av7110_read(fd_ca,CODEBASE+i+52); + PRINTF(L_CORE_AV7110,"found handles=%08x hw_handles=%08x at 0x%08x",handles,hw_handles,CODEBASE+i); + if((handles>>16)!=0x2e08 || (hw_handles>>16)!=0x2e08) { + PRINTF(L_CORE_AV7110,"seems to be invalid"); + } + break; + } + } + } + + unsigned int hdl=0, hwhdl=0; + PRINTF(L_CORE_AV7110," : 64000080 64000400"); + for(int i=0; i<=31; i++) { + unsigned int off80 =av7110_read(fd_ca,0x64000080+i*4); + unsigned int off400=av7110_read(fd_ca,0x64000400+i*8); + LBSTART(L_CORE_AV7110); + LBPUT("handle %2d: %08x %08x %s pid=%04x idx=%d", + i,off80,off400,off80&0x2000?"ACT":"---",off80&0x1fff,(off400&0x1e)>>1); + if(handles>1 && i<=27) { + if((i&1)==0) { + hdl=av7110_read(fd_ca,handles+i*2); + hwhdl=av7110_read(fd_ca,hw_handles+i*2); + } + unsigned int s=((~i)&1)<<4; + LBPUT(" | %02d hdl=%04x hwfilt=%04x",i,(hdl>>s)&0xffff,(hwhdl>>s)&0xffff); + } + LBEND(); + } + } + } +} // -- cScSdDevicePlugin -------------------------------------------------------- @@ -53,6 +146,9 @@ public: virtual cDevice *Probe(int Adapter, int Frontend, uint32_t SubSystemId); virtual bool LateInit(cDevice *dev); virtual bool EarlyShutdown(cDevice *dev); + virtual bool SetCaDescr(cDevice *dev, ca_descr_t *ca_descr, bool initial); + virtual bool SetCaPid(cDevice *dev, ca_pid_t *ca_pid); + virtual bool DumpAV(cDevice *dev); }; static cScSdDevicePlugin _sddevplugin; @@ -76,7 +172,7 @@ cDevice *cScSdDevicePlugin::Probe(int Adapter, int Frontend, uint32_t SubSystemI for(uint32_t *sid=SubsystemIds; *sid; sid++) { if(*sid==SubSystemId) { PRINTF(L_GEN_DEBUG,"creating SD-FF device %d/%d",Adapter,Frontend); - return new cScDvbSdFfDevice(Adapter,Frontend,cScDevices::DvbOpen(DEV_DVB_CA,Adapter,Frontend,O_RDWR)); + return new cScDvbSdFfDevice(this,Adapter,Frontend,cScDevices::DvbOpen(DEV_DVB_CA,Adapter,Frontend,O_RDWR)); } } return 0; @@ -96,6 +192,27 @@ bool cScSdDevicePlugin::EarlyShutdown(cDevice *dev) return d!=0; } +bool cScSdDevicePlugin::SetCaDescr(cDevice *dev, ca_descr_t *ca_descr, bool initial) +{ + cScDvbSdFfDevice *d=dynamic_cast(dev); + if(d) return d->SetCaDescr(ca_descr,initial); + return false; +} + +bool cScSdDevicePlugin::SetCaPid(cDevice *dev, ca_pid_t *ca_pid) +{ + cScDvbSdFfDevice *d=dynamic_cast(dev); + if(d) return d->SetCaPid(ca_pid); + return d!=0; +} + +bool cScSdDevicePlugin::DumpAV(cDevice *dev) +{ + cScDvbSdFfDevice *d=dynamic_cast(dev); + if(d) d->DumpAV(); + return d!=0; +} + #endif //WITH_SDDVB #endif //APIVERSNUM >= 10711 #endif //SASC diff --git a/device-tmpl.c b/device-tmpl.c index 1bb8f51..adac307 100644 --- a/device-tmpl.c +++ b/device-tmpl.c @@ -26,10 +26,13 @@ private: cMutex tsMutex; #endif //!SASC cCam *cam; + cScDevicePlugin *devplugin; #ifndef SASC cCiAdapter *hwciadapter; + cTimeMs lastDump; #endif //!SASC int fd_dvr, fd_ca, fd_ca2; + cMutex cafdMutex; bool softcsa, fullts; char devId[8]; // @@ -46,8 +49,11 @@ protected: virtual bool GetTSPacket(uchar *&Data); #endif //!SASC public: - SCDEVICE(int Adapter, int Frontend, int cafd); + SCDEVICE(cScDevicePlugin *DevPlugin, int Adapter, int Frontend, int cafd); ~SCDEVICE(); + bool SetCaDescr(ca_descr_t *ca_descr, bool initial); + bool SetCaPid(ca_pid_t *ca_pid); + void DumpAV(void); #ifndef SASC virtual bool HasCi(void); void LateInit(void); @@ -57,7 +63,7 @@ public: #endif //!SASC }; -SCDEVICE::SCDEVICE(int Adapter, int Frontend, int cafd) +SCDEVICE::SCDEVICE(cScDevicePlugin *DevPlugin, int Adapter, int Frontend, int cafd) #if APIVERSNUM >= 10711 :DVBDEVICE(Adapter,Frontend) #else @@ -67,7 +73,7 @@ SCDEVICE::SCDEVICE(int Adapter, int Frontend, int cafd) #ifndef SASC tsBuffer=0; hwciadapter=0; #endif - cam=0; softcsa=fullts=false; + cam=0; devplugin=DevPlugin; softcsa=fullts=false; fd_ca=cafd; fd_ca2=dup(fd_ca); fd_dvr=-1; #if APIVERSNUM >= 10711 snprintf(devId,sizeof(devId),"%d/%d",Adapter,Frontend); @@ -75,7 +81,7 @@ SCDEVICE::SCDEVICE(int Adapter, int Frontend, int cafd) snprintf(devId,sizeof(devId),"%d",Adapter); #endif #ifdef SASC - cam=new cCam(this,Adapter,0,devId,fd_ca,softcsa,fullts); + cam=new cCam(this,Adapter,0,devId,devplugin,softcsa,fullts); #endif // !SASC } @@ -93,6 +99,23 @@ SCDEVICE::~SCDEVICE() #endif } +#ifndef OWN_SETCA +bool SCDEVICE::SetCaDescr(ca_descr_t *ca_descr, bool initial) +{ + return false; +} + +bool SCDEVICE::SetCaPid(ca_pid_t *ca_pid) +{ + return false; +} +#endif //!OWN_SETCA + +#ifndef OWN_DUMPAV +void SCDEVICE::DumpAV(void) +{} +#endif + #ifndef SASC void SCDEVICE::EarlyShutdown(void) @@ -123,7 +146,7 @@ void SCDEVICE::LateInit(void) else PRINTF(L_GEN_INFO,"Using software decryption on card %s",devId); } if(fd_ca2>=0) hwciadapter=cDvbCiAdapter::CreateCiAdapter(this,fd_ca2); - cam=new cCam(this,DVB_DEV_SPEC,devId,fd_ca,softcsa,fullts); + cam=new cCam(this,DVB_DEV_SPEC,devId,devplugin,softcsa,fullts); } bool SCDEVICE::HasCi(void) diff --git a/device.c b/device.c index 0efe2a0..7e25f57 100644 --- a/device.c +++ b/device.c @@ -155,7 +155,7 @@ public: cDevice *cScDvbDevicePlugin::Probe(int Adapter, int Frontend, uint32_t SubSystemId) { PRINTF(L_GEN_DEBUG,"creating standard device %d/%d",Adapter,Frontend); - return new cScDvbDevice(Adapter,Frontend,cScDevices::DvbOpen(DEV_DVB_CA,Adapter,Frontend,O_RDWR)); + return new cScDvbDevice(this,Adapter,Frontend,cScDevices::DvbOpen(DEV_DVB_CA,Adapter,Frontend,O_RDWR)); } bool cScDvbDevicePlugin::LateInit(cDevice *dev) diff --git a/device.h b/device.h index 79a052d..8a339fc 100644 --- a/device.h +++ b/device.h @@ -20,6 +20,7 @@ #ifndef ___DEVICE_H #define ___DEVICE_H +#include #include #include #include "misc.h" @@ -95,6 +96,9 @@ public: virtual cDevice *Probe(int Adapter, int Frontend, uint32_t SubSystemId)=0; virtual bool LateInit(cDevice *dev)=0; virtual bool EarlyShutdown(cDevice *dev)=0; + virtual bool SetCaDescr(cDevice *dev, ca_descr_t *ca_descr, bool initial) { return false; } + virtual bool SetCaPid(cDevice *dev, ca_pid_t *ca_pid) { return false; } + virtual bool DumpAV(cDevice *dev) { return false; } }; #endif //!SASC