[vdr] Problem: Conax not available after VDR startup

Klaus Schmidinger Klaus.Schmidinger at cadsoft.de
Sat Aug 20 17:44:49 CEST 2005


Rantanen Teemu wrote:
> Klaus Schmidinger wrote:
> 
>>I really don't see why tuning to a particular channel should speed up
>>the initial setup of the CAM communication.
> 
> 
> I only know that EPG scan did help, and did help every time...
> 
> But, in the meantime I've built a new vdr/file -server, and guess
> what... yep, the delay is gone. I have no idea what was the real fix as
> I've changed almost everything (except dvb-hardware):
> 
> 	P2-350		-> Celeron-2.5G
> 	vdr-1.3.23		-> vdr-1.3.29
> 	linux-2.4		-> linux-2.6
> 	dvb-20041226	-> dvb in kernel
> 	etc...
> 
> But I guess there are still some people who have the same problem. Why
> not add an option to VDR to allow EPG scan to start right away?

I strongly believe that the EPG scan thing was just a symptom, not the cause.

The attached patch makes VDR wait until all devices that have CAMs
are ready to decrypt. With this I can start VDR right away with
an encrypted channel, and it doesn't say "channel not available"
any more.

Please test whether this works for you, too.

Klaus
-------------- next part --------------
--- ./ci.c	2005/08/20 12:16:23	1.25
+++ ./ci.c	2005/08/20 15:27:35
@@ -1354,6 +1354,8 @@
   hasUserIO = false;
   for (int i = 0; i < MAX_CI_SESSION; i++)
       sessions[i] = NULL;
+  for (int i = 0; i < MAX_CI_SLOT; i++)
+      moduleReady[i] = false;
   tpl = new cCiTransportLayer(Fd, numSlots);
   tc = NULL;
 }
@@ -1506,6 +1508,19 @@
   return result;
 }
 
+bool cCiHandler::Ready(void)
+{
+  cMutexLock MutexLock(&mutex);
+  for (int Slot = 0; Slot < numSlots; Slot++) {
+      if (moduleReady[Slot]) {
+         cCiConditionalAccessSupport *cas = (cCiConditionalAccessSupport *)GetSessionByResourceId(RI_CONDITIONAL_ACCESS_SUPPORT, Slot);
+         if (!cas || !*cas->GetCaSystemIds())
+            return false;
+         }
+      }
+  return true;
+}
+
 bool cCiHandler::Process(void)
 {
   bool result = true;
@@ -1543,6 +1558,7 @@
          }
       else if (tpl->ModuleReady(Slot)) {
          dbgprotocol("Module ready in slot %d\n", Slot);
+         moduleReady[Slot] = true;
          tpl->NewConnection(Slot);
          }
       }
--- ./ci.h	2004/02/08 14:36:23	1.13
+++ ./ci.h	2005/08/20 14:56:11
@@ -77,6 +77,7 @@
   };
 
 #define MAX_CI_SESSION  16 //XXX
+#define MAX_CI_SLOT     16
 
 class cCiSession;
 class cCiTransportLayer;
@@ -89,6 +90,7 @@
   int numSlots;
   bool newCaSupport;
   bool hasUserIO;
+  bool moduleReady[MAX_CI_SLOT];
   cCiSession *sessions[MAX_CI_SESSION];
   cCiTransportLayer *tpl;
   cCiTransportConnection *tc;
@@ -105,6 +107,7 @@
   ~cCiHandler();
   static cCiHandler *CreateCiHandler(const char *FileName);
   int NumSlots(void) { return numSlots; }
+  bool Ready(void);
   bool Process(void);
   bool HasUserIO(void) { return hasUserIO; }
   bool EnterMenu(int Slot);
--- ./device.c	2005/08/14 10:52:08	1.105
+++ ./device.c	2005/08/20 15:31:53
@@ -195,6 +195,19 @@
   delete pesAssembler;
 }
 
+void cDevice::WaitForAllDevicesReady(int Timeout)
+{
+  for (time_t t0 = time(NULL); time(NULL) - t0 < Timeout; ) {
+      bool ready = true;
+      for (int i = 0; i < numDevices; i++) {
+          if (device[i] && !device[i]->Ready())
+             ready = false;
+          }
+      if (ready)
+         break;
+      }
+}
+
 void cDevice::SetUseDevice(int n)
 {
   if (n < MAXDEVICES)
@@ -1103,6 +1116,11 @@
   XXX*/
 }
 
+bool cDevice::Ready(void)
+{
+  return true;
+}
+
 int cDevice::ProvidesCa(const cChannel *Channel) const
 {
   int Ca = Channel->Ca();
--- ./device.h	2005/08/13 11:44:13	1.61
+++ ./device.h	2005/08/20 15:38:49
@@ -102,6 +102,9 @@
 public:
   static int NumDevices(void) { return numDevices; }
          ///< Returns the total number of devices.
+  static void WaitForAllDevicesReady(int Timeout = 0);
+         ///< Waits until all devices have become ready, or the given Timeout
+         ///< (seconds) has expired.
   static void SetUseDevice(int n);
          ///< Sets the 'useDevice' flag of the given device.
          ///< If this function is not called before initializing, all devices
@@ -136,6 +139,9 @@
 protected:
   cDevice(void);
   virtual ~cDevice();
+  virtual bool Ready(void);
+         ///< Returns true if this device is ready. Devices with conditional
+         ///< access hardware may need some time until they are up and running.
   static int NextCardIndex(int n = 0);
          ///< Calculates the next card index.
          ///< Each device in a given machine must have a unique card index, which
--- ./dvbdevice.c	2005/08/15 14:05:23	1.134
+++ ./dvbdevice.c	2005/08/20 15:22:36
@@ -478,6 +478,15 @@
   return fd_video >= 0 && fd_audio >= 0;
 }
 
+bool cDvbDevice::Ready(void)
+{
+  if (ciHandler) {
+     ciHandler->Process();
+     return ciHandler->Ready();
+     }
+  return true;
+}
+
 int cDvbDevice::ProvidesCa(const cChannel *Channel) const
 {
   if (Channel->Ca() >= 0x0100 && ciHandler) {
--- ./dvbdevice.h	2005/02/20 11:17:07	1.34
+++ ./dvbdevice.h	2005/08/20 15:20:15
@@ -42,6 +42,7 @@
 public:
   cDvbDevice(int n);
   virtual ~cDvbDevice();
+  virtual bool Ready(void);
   virtual int ProvidesCa(const cChannel *Channel) const;
   virtual bool HasDecoder(void) const;
 
--- ./vdr.c	2005/08/20 11:24:42	1.210
+++ ./vdr.c	2005/08/20 15:33:12
@@ -520,6 +520,7 @@
 
   // Channel:
 
+  cDevice::WaitForAllDevicesReady(30);
   Channels.SwitchTo(Setup.CurrentChannel);
   if (MuteAudio)
      cDevice::PrimaryDevice()->ToggleMute();


More information about the vdr mailing list