summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--HISTORY6
-rw-r--r--ci.c18
-rw-r--r--ci.h5
-rw-r--r--device.c21
-rw-r--r--device.h13
-rw-r--r--dvbdevice.c11
-rw-r--r--dvbdevice.h3
-rw-r--r--vdr.c5
8 files changed, 74 insertions, 8 deletions
diff --git a/HISTORY b/HISTORY
index 25304454..dce1b460 100644
--- a/HISTORY
+++ b/HISTORY
@@ -3700,8 +3700,12 @@ Video Disk Recorder Revision History
- Removed the VIDEO_STILLPICTURE_WORKS_WITH_VDR_FRAMES stuff from
cDvbDevice::StillPicture(), since apparently the VIDEO_STILLPICTURE call works.
-2005-08-20: Version 1.3.30
+2005-08-21: Version 1.3.30
- Improved responsiveness inside CAM menus.
- Added handling of the 'Close MMI' tag to avoid error log messages with CAMs
that actually use it.
+- Now waiting at startup until all DVB devices are ready. This includes having
+ all CAMs initialized and ready to decrypt, so that no more "channel not
+ available" happens if VDR is started with the current channel being an encrypted
+ one, or a timer on such a channel hits right after starting VDR.
diff --git a/ci.c b/ci.c
index 9bca64df..b99c5495 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 1.25 2005/08/20 12:16:23 kls Exp $
+ * $Id: ci.c 1.26 2005/08/20 15:27:35 kls Exp $
*/
#include "ci.h"
@@ -1354,6 +1354,8 @@ cCiHandler::cCiHandler(int Fd, int NumSlots)
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 @@ int cCiHandler::CloseAllSessions(int Slot)
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 @@ bool cCiHandler::Process(void)
}
else if (tpl->ModuleReady(Slot)) {
dbgprotocol("Module ready in slot %d\n", Slot);
+ moduleReady[Slot] = true;
tpl->NewConnection(Slot);
}
}
diff --git a/ci.h b/ci.h
index 7ae2b96e..9d718951 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 1.13 2004/02/08 14:36:23 kls Exp $
+ * $Id: ci.h 1.14 2005/08/20 14:56:11 kls Exp $
*/
#ifndef __CI_H
@@ -77,6 +77,7 @@ public:
};
#define MAX_CI_SESSION 16 //XXX
+#define MAX_CI_SLOT 16
class cCiSession;
class cCiTransportLayer;
@@ -89,6 +90,7 @@ private:
int numSlots;
bool newCaSupport;
bool hasUserIO;
+ bool moduleReady[MAX_CI_SLOT];
cCiSession *sessions[MAX_CI_SESSION];
cCiTransportLayer *tpl;
cCiTransportConnection *tc;
@@ -105,6 +107,7 @@ public:
~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);
diff --git a/device.c b/device.c
index 9fcc420b..2f614988 100644
--- a/device.c
+++ b/device.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: device.c 1.105 2005/08/14 10:52:08 kls Exp $
+ * $Id: device.c 1.106 2005/08/21 08:56:49 kls Exp $
*/
#include "device.h"
@@ -195,6 +195,20 @@ cDevice::~cDevice()
delete pesAssembler;
}
+bool 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)
+ return true;
+ }
+ return false;
+}
+
void cDevice::SetUseDevice(int n)
{
if (n < MAXDEVICES)
@@ -1103,6 +1117,11 @@ int cDevice::CanShift(int Ca, int Priority, int UsedCards) const
XXX*/
}
+bool cDevice::Ready(void)
+{
+ return true;
+}
+
int cDevice::ProvidesCa(const cChannel *Channel) const
{
int Ca = Channel->Ca();
diff --git a/device.h b/device.h
index fc9ba3a1..c7075cbd 100644
--- a/device.h
+++ b/device.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: device.h 1.61 2005/08/13 11:44:13 kls Exp $
+ * $Id: device.h 1.62 2005/08/21 08:52:20 kls Exp $
*/
#ifndef __DEVICE_H
@@ -102,6 +102,12 @@ private:
public:
static int NumDevices(void) { return numDevices; }
///< Returns the total number of devices.
+ static bool WaitForAllDevicesReady(int Timeout = 0);
+ ///< Waits until all devices have become ready, or the given Timeout
+ ///< (seconds) has expired. While waiting, the Ready() function of each
+ ///< device is called in turn, until they all return true.
+ ///< \return True if all devices have become ready within the given
+ ///< timeout.
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 +142,11 @@ private:
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.
+ ///< This function is called in a loop at startup until all devices
+ ///< are ready (see WaitForAllDevicesReady()).
static int NextCardIndex(int n = 0);
///< Calculates the next card index.
///< Each device in a given machine must have a unique card index, which
diff --git a/dvbdevice.c b/dvbdevice.c
index ccd9a982..c47717bb 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 1.134 2005/08/15 14:05:23 kls Exp $
+ * $Id: dvbdevice.c 1.135 2005/08/20 15:22:36 kls Exp $
*/
#include "dvbdevice.h"
@@ -478,6 +478,15 @@ bool cDvbDevice::HasDecoder(void) const
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) {
diff --git a/dvbdevice.h b/dvbdevice.h
index 4a705367..7da7e4f1 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 1.34 2005/02/20 11:17:07 kls Exp $
+ * $Id: dvbdevice.h 1.35 2005/08/20 15:20:15 kls Exp $
*/
#ifndef __DVBDEVICE_H
@@ -42,6 +42,7 @@ protected:
public:
cDvbDevice(int n);
virtual ~cDvbDevice();
+ virtual bool Ready(void);
virtual int ProvidesCa(const cChannel *Channel) const;
virtual bool HasDecoder(void) const;
diff --git a/vdr.c b/vdr.c
index c8f57a2b..c98ee0d6 100644
--- a/vdr.c
+++ b/vdr.c
@@ -22,7 +22,7 @@
*
* The project's page is at http://www.cadsoft.de/vdr
*
- * $Id: vdr.c 1.210 2005/08/20 11:24:42 kls Exp $
+ * $Id: vdr.c 1.211 2005/08/21 08:47:06 kls Exp $
*/
#include <getopt.h>
@@ -65,6 +65,7 @@
#define CHANNELSAVEDELTA 600 // seconds before saving channels.conf after automatic modifications
#define LASTCAMMENUTIMEOUT 3 // seconds to run the main loop 'fast' after a CAM menu has been closed
// in order to react on a possible new CAM menu as soon as possible
+#define DEVICEREADYTIMEOUT 30 // seconds to wait until all devices are ready
#define EXIT(v) { ExitCode = (v); goto Exit; }
@@ -520,6 +521,8 @@ int main(int argc, char *argv[])
// Channel:
+ if (!cDevice::WaitForAllDevicesReady(DEVICEREADYTIMEOUT))
+ dsyslog("not all devices ready after %d seconds", DEVICEREADYTIMEOUT);
Channels.SwitchTo(Setup.CurrentChannel);
if (MuteAudio)
cDevice::PrimaryDevice()->ToggleMute();