};
#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));
}
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;
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;
}
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
}
class cScCamSlot;
class cDeCSA;
class cPrg;
+class cScDevicePlugin;
// ----------------------------------------------------------------
//
cDeCSA *decsa;
#endif
- int cafd;
- cMutex cafdMutex;
+ cScDevicePlugin *devplugin;
bool softcsa, fullts;
//
cTimeMs caidTimer, triggerTimer;
bool rebuildcaids;
//
cTimeMs readTimer, writeTimer;
- cTimeMs lastDump;
//
cMutex camMutex;
cSimpleList<cEcmHandler> handlerList;
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);
#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 --------------------------------------------------------
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;
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));
}
}
}
return d!=0;
}
+bool cScHdDevicePlugin::SetCaDescr(cDevice *dev, ca_descr_t *ca_descr, bool initial)
+{
+ cScDvbHdFfDevice *d=dynamic_cast<cScDvbHdFfDevice *>(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<cScDvbHdFfDevice *>(dev);
+ if(d) return d->SetCaPid(ca_pid);
+ return false;
+}
+
#endif //WITH_HDDVB
#endif //APIVERSNUM >= 10711
#endif //SASC
#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 --------------------------------------------------------
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;
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;
return d!=0;
}
+bool cScSdDevicePlugin::SetCaDescr(cDevice *dev, ca_descr_t *ca_descr, bool initial)
+{
+ cScDvbSdFfDevice *d=dynamic_cast<cScDvbSdFfDevice *>(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<cScDvbSdFfDevice *>(dev);
+ if(d) return d->SetCaPid(ca_pid);
+ return d!=0;
+}
+
+bool cScSdDevicePlugin::DumpAV(cDevice *dev)
+{
+ cScDvbSdFfDevice *d=dynamic_cast<cScDvbSdFfDevice *>(dev);
+ if(d) d->DumpAV();
+ return d!=0;
+}
+
#endif //WITH_SDDVB
#endif //APIVERSNUM >= 10711
#endif //SASC
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];
//
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);
#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
#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);
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
}
#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)
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)
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)
#ifndef ___DEVICE_H
#define ___DEVICE_H
+#include <linux/dvb/ca.h>
#include <vdr/dvbdevice.h>
#include <vdr/thread.h>
#include "misc.h"
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