]> www.vanbest.org Git - sasc-ng.git/commitdiff
virtualise CAM hardware access
authorleslie <unknown>
Sun, 21 Aug 2011 18:51:37 +0000 (20:51 +0200)
committerleslie <unknown>
Sun, 21 Aug 2011 18:51:37 +0000 (20:51 +0200)
cam.c
cam.h
device-hd.c
device-sd.c
device-tmpl.c
device.c
device.h

diff --git a/cam.c b/cam.c
index d438e4b24e768ecdd6a90e55506c4bc304cca21f..2ac321346a4ff15eb485c91966931d5e5ee1c17f 100644 (file)
--- 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 85137f29975777f4ca13f1bb5d3071bac5efa8a5..f66004ae4add8c671bc07f1cdb73d2ea8ffca530 100644 (file)
--- 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<cEcmHandler> 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);
index 36d2a25a43d5c38f3cd7f4401ff9bb861afbf9c7..24364d5c50036e25eba86bf1688209fa5f12a728 100644 (file)
@@ -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<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
index 38e7389f95e90079b4e07bac28de99ac0db72f53..b4551da7d75a3557a26d8f95f6596f42e1ba2ecd 100644 (file)
@@ -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<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
index 1bb8f5117bf3bbed9a1a12680a4482fde9c064b2..adac307a9389fb31affbb6ecca30e2e60d4a5cc2 100644 (file)
@@ -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)
index 0efe2a096e9987f0063abfc00dc9ebd40642f6a4..7e25f57b230c524a3f956ea945a78e0a7ee17407 100644 (file)
--- 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)
index 79a052d2e393641d6a6b2223d1ae1c212258af3e..8a339fce6737f4f7ed47a3b793790404c3817840 100644 (file)
--- a/device.h
+++ b/device.h
@@ -20,6 +20,7 @@
 #ifndef ___DEVICE_H
 #define ___DEVICE_H
 
+#include <linux/dvb/ca.h>
 #include <vdr/dvbdevice.h>
 #include <vdr/thread.h>
 #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