From 1df6a87249291566d978f3d104ca68dbb075b37b Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Thu, 16 Jan 2014 11:57:54 +0100 Subject: [PATCH] Now waiting explicitly until all CAM slots are ready before switching to the initial channel when VDR is started --- HISTORY | 4 ++++ ci.c | 33 +++++++++++++++++++++------------ ci.h | 14 ++++++++++---- dvbdevice.c | 9 +-------- dvbdevice.h | 3 +-- vdr.c | 4 +++- 6 files changed, 40 insertions(+), 27 deletions(-) diff --git a/HISTORY b/HISTORY index 0b8a6c83..ba441d45 100644 --- a/HISTORY +++ b/HISTORY @@ -8148,3 +8148,7 @@ Video Disk Recorder Revision History Eike Sauer). - Fixed deleting the source recording after moving it to a different volume (reported by Christoph Haubrich). +- Now waiting explicitly until all CAM slots are ready before switching to the + initial channel when VDR is started. This is necessary in case CI adapters are + used that are not physically connected to a dedicated device. The respective checks + in cDvbDevice have been removed to avoid redundancy. diff --git a/ci.c b/ci.c index 90903fbd..1d55ca7f 100644 --- a/ci.c +++ b/ci.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: ci.c 3.7 2014/01/15 10:20:48 kls Exp $ + * $Id: ci.c 3.8 2014/01/16 11:43:33 kls Exp $ */ #include "ci.h" @@ -1536,15 +1536,6 @@ void cCiAdapter::AddCamSlot(cCamSlot *CamSlot) } } -bool cCiAdapter::Ready(void) -{ - for (int i = 0; i < MAX_CAM_SLOTS_PER_ADAPTER; i++) { - if (camSlots[i] && !camSlots[i]->Ready()) - return false; - } - return true; -} - void cCiAdapter::Action(void) { cTPDU TPDU; @@ -1566,8 +1557,6 @@ void cCiAdapter::Action(void) // --- cCamSlot -------------------------------------------------------------- -cCamSlots CamSlots; - #define MODULE_CHECK_INTERVAL 500 // ms #define MODULE_RESET_TIMEOUT 2 // s @@ -2034,6 +2023,26 @@ uchar *cCamSlot::Decrypt(uchar *Data, int &Count) return Data; } +// --- cCamSlots ------------------------------------------------------------- + +cCamSlots CamSlots; + +bool cCamSlots::WaitForAllCamSlotsReady(int Timeout) +{ + for (time_t t0 = time(NULL); time(NULL) - t0 < Timeout; ) { + bool ready = true; + for (cCamSlot *CamSlot = CamSlots.First(); CamSlot; CamSlot = CamSlots.Next(CamSlot)) { + if (!CamSlot->Ready()) { + ready = false; + cCondWait::SleepMs(100); + } + } + if (ready) + return true; + } + return false; +} + // --- cChannelCamRelation --------------------------------------------------- #define CAM_CHECKED_TIMEOUT 15 // seconds before a CAM that has been checked for a particular channel will be checked again diff --git a/ci.h b/ci.h index e3b85912..190e3e08 100644 --- a/ci.h +++ b/ci.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: ci.h 3.4 2014/01/14 11:53:52 kls Exp $ + * $Id: ci.h 3.5 2014/01/16 11:45:08 kls Exp $ */ #ifndef __CI_H @@ -113,8 +113,6 @@ public: cCiAdapter(void); virtual ~cCiAdapter(); ///< The derived class must call Cancel(3) in its destructor. - virtual bool Ready(void); - ///< Returns 'true' if all present CAMs in this adapter are ready. }; class cTPDU; @@ -267,7 +265,15 @@ public: ///< constructor to true in order to receive the CA pid data. }; -class cCamSlots : public cList {}; +class cCamSlots : public cList { +public: + bool WaitForAllCamSlotsReady(int Timeout = 0); + ///< Waits until all CAM slots have become ready, or the given Timeout + ///< (seconds) has expired. While waiting, the Ready() function of each + ///< CAM slot is called in turn, until they all return true. + ///< Returns true if all CAM slots have become ready within the given + ///< timeout. + }; extern cCamSlots CamSlots; diff --git a/dvbdevice.c b/dvbdevice.c index 62f29dac..6842a4ca 100644 --- a/dvbdevice.c +++ b/dvbdevice.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbdevice.c 3.8 2014/01/02 10:30:15 kls Exp $ + * $Id: dvbdevice.c 3.9 2014/01/16 11:45:22 kls Exp $ */ #include "dvbdevice.h" @@ -1320,13 +1320,6 @@ bool cDvbDevice::QueryDeliverySystems(int fd_frontend) return false; } -bool cDvbDevice::Ready(void) -{ - if (ciAdapter) - return ciAdapter->Ready(); - return true; -} - bool cDvbDevice::BondDevices(const char *Bondings) { UnBondDevices(); diff --git a/dvbdevice.h b/dvbdevice.h index 0a76d9df..278edd0c 100644 --- a/dvbdevice.h +++ b/dvbdevice.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbdevice.h 3.3 2014/01/01 14:00:56 kls Exp $ + * $Id: dvbdevice.h 3.4 2014/01/16 11:45:35 kls Exp $ */ #ifndef __DVBDEVICE_H @@ -185,7 +185,6 @@ public: virtual ~cDvbDevice(); int Adapter(void) const { return adapter; } int Frontend(void) const { return frontend; } - virtual bool Ready(void); virtual cString DeviceType(void) const; virtual cString DeviceName(void) const; static bool BondDevices(const char *Bondings); diff --git a/vdr.c b/vdr.c index a2ede09f..657bec7a 100644 --- a/vdr.c +++ b/vdr.c @@ -22,7 +22,7 @@ * * The project's page is at http://www.tvdr.de * - * $Id: vdr.c 3.7 2013/12/25 11:24:26 kls Exp $ + * $Id: vdr.c 3.8 2014/01/16 11:25:03 kls Exp $ */ #include @@ -810,6 +810,8 @@ int main(int argc, char *argv[]) if (!cDevice::WaitForAllDevicesReady(DEVICEREADYTIMEOUT)) dsyslog("not all devices ready after %d seconds", DEVICEREADYTIMEOUT); + if (!CamSlots.WaitForAllCamSlotsReady(DEVICEREADYTIMEOUT)) + dsyslog("not all CAM slots ready after %d seconds", DEVICEREADYTIMEOUT); if (*Setup.InitialChannel) { if (isnumber(Setup.InitialChannel)) { // for compatibility with old setup.conf files if (cChannel *Channel = Channels.GetByNumber(atoi(Setup.InitialChannel)))