summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--HISTORY5
-rw-r--r--README6
-rw-r--r--dynamicdevice.c79
-rw-r--r--dynamicdevice.h24
-rw-r--r--dynamite.c2
5 files changed, 99 insertions, 17 deletions
diff --git a/HISTORY b/HISTORY
index 31b4d56..67092c1 100644
--- a/HISTORY
+++ b/HISTORY
@@ -222,3 +222,8 @@ VDR Plugin 'dynamite' Revision History
2011-12-15: Version 0.0.8h
- correct define for new virtual functions added by yaVDR-patches
+
+2011-12-15: Version 0.0.8i
+
+- add udev attribute "dynamite_attach_delay" for delaying the attach of specific devices
+ useful for device if the firmware upload needs some time
diff --git a/README b/README
index 2e43776..34c2761 100644
--- a/README
+++ b/README
@@ -284,10 +284,11 @@ Add a rule which sets with ENV{dynamite_timeout}="10" the needed timeout value.
example for udev rule:
ACTION=="add", SUBSYSTEM=="dvb", ENV{DVB_DEVICE_TYPE}=="frontend" \
, ENV{dynamite_attach}="yes" \
+ , ENV{dynamite_attach_delay}="10" \
, ENV{dynamite_instanceid}="0" \
, ENV{dynamite_cardindex}="5" \
, ENV{dynamite_timeout}="10" \
- , ENV{dynamite_timeout_handler_arg}="%k"
+ , ENV{dynamite_timeout_handler_arg}="%k" \
, ENV{dynamite_disable_autoidle}="no"
After the device is detached and dynamite.GetTSTimeoutHandler in setup.conf is set
@@ -302,6 +303,9 @@ set by a udev rule (see example above).
dynamite_attach
"no", "n", "0", "ignore": don't attach this device, any other string will be like "yes"
+dynamite_attach_delay
+ n: wait with attaching this device at least n seconds
+
dynamite_instanceid
n: attach only at vdr with matching instance id
diff --git a/dynamicdevice.c b/dynamicdevice.c
index bf643ca..12a94ce 100644
--- a/dynamicdevice.c
+++ b/dynamicdevice.c
@@ -15,6 +15,35 @@ bool cDynamicDevice::enableOsdMessages = false;
int cDynamicDevice::numDynamicDevices = 0;
cMutex cDynamicDevice::arrayMutex;
cDynamicDevice *cDynamicDevice::dynamicdevice[MAXDEVICES] = { NULL };
+cList<cDynamicDeviceProbe::cDynamicDeviceProbeItem> cDynamicDevice::commandRequeue;
+
+cList<cDynamicDevice::cDelayedDeviceItems> cDynamicDevice::cDelayedDeviceItems::delayedItems;
+
+cDynamicDevice::cDelayedDeviceItems::cDelayedDeviceItems(const char *DevPath, int AttachDelay)
+ :devPath(DevPath)
+{
+ dontAttachBefore = time(NULL) + AttachDelay;
+ delayedItems.Add(this);
+}
+
+int cDynamicDevice::cDelayedDeviceItems::CanBeAttached(const char *DevPath)
+{
+ if (DevPath == NULL)
+ return false;
+ time_t now = time(NULL);
+ for (cDelayedDeviceItems *item = delayedItems.First(); item; item = delayedItems.Next(item)) {
+ if (strcmp(*item->devPath, DevPath) == 0) {
+ if (item->dontAttachBefore < now) {
+ delayedItems.Del(item);
+ isyslog("dynamite: %s can be attached now", DevPath);
+ return 1;
+ }
+ isyslog("dynamite: %s should not be attached yet", DevPath);
+ return 0;
+ }
+ }
+ return 2;
+}
int cDynamicDevice::IndexOf(const char *DevPath, int &NextFreeIndex, int WishIndex)
{
@@ -52,7 +81,11 @@ bool cDynamicDevice::ProcessQueuedCommands(void)
switch (dev->cmd) {
case ddpcAttach:
{
- AttachDevice(*dev->devpath);
+ int delayed = cDelayedDeviceItems::CanBeAttached(*dev->devpath);
+ if (delayed == 0)
+ commandRequeue.Add(new cDynamicDeviceProbe::cDynamicDeviceProbeItem(ddpcAttach, new cString(*dev->devpath)));
+ else if (delayed > 0)
+ AttachDevice(*dev->devpath, delayed);
break;
}
case ddpcDetach:
@@ -78,24 +111,38 @@ bool cDynamicDevice::ProcessQueuedCommands(void)
}
}
cDynamicDeviceProbe::commandQueue.Clear();
+ for (cDynamicDeviceProbe::cDynamicDeviceProbeItem *dev = commandRequeue.First(); dev; dev = commandRequeue.Next(dev))
+ cDynamicDeviceProbe::commandQueue.Add(new cDynamicDeviceProbe::cDynamicDeviceProbeItem(dev->cmd, new cString(**dev->devpath)));
+ commandRequeue.Clear();
return true;
}
-int cDynamicDevice::GetProposedCardIndex(const char *DevPath)
+int cDynamicDevice::GetUdevAttributesForAttach(const char *DevPath, int &CardIndex, int &AttachDelay)
{
- int cardindex = -1;
+ CardIndex = -1;
+ AttachDelay = 0;
if (DevPath == NULL)
- return cardindex;
+ return -1;
cUdevDevice *dev = cUdev::GetDeviceFromDevName(DevPath);
- if (dev != NULL) {
- const char *val = dev->GetPropertyValue("dynamite_cardindex");
+ if (dev == NULL)
+ return -1;
+ int intVal;
+ const char *val = dev->GetPropertyValue("dynamite_cardindex");
+ if (val) {
isyslog("dynamite: udev cardindex is %s", val);
- int intVal = -1;
+ intVal = -1;
if (val && (sscanf(val, "%d", &intVal) == 1) && (intVal >= 0) && (intVal <= MAXDEVICES))
- cardindex = intVal;
- delete dev;
+ CardIndex = intVal;
+ }
+ val = dev->GetPropertyValue("dynamite_attach_delay");
+ if (val) {
+ isyslog("dynamite: udev attach_delay is %s", val);
+ intVal = 0;
+ if (val && (sscanf(val, "%d", &intVal) == 1) && (intVal > 0))
+ AttachDelay = intVal;
}
- return cardindex;
+ delete dev;
+ return 0;
}
void cDynamicDevice::DetachAllDevices(bool Force)
@@ -147,13 +194,15 @@ cString cDynamicDevice::AttachDevicePattern(const char *Pattern)
return reply;
}
-eDynamicDeviceReturnCode cDynamicDevice::AttachDevice(const char *DevPath)
+eDynamicDeviceReturnCode cDynamicDevice::AttachDevice(const char *DevPath, int Delayed)
{
if (!DevPath)
return ddrcNotSupported;
cMutexLock lock(&arrayMutex);
- int wishIndex = GetProposedCardIndex(DevPath);
+ int wishIndex = -1;
+ int attachDelay = 0;
+ GetUdevAttributesForAttach(DevPath, wishIndex, attachDelay);
if (wishIndex >= 0)
isyslog("dynamite: %s wants card index %d", DevPath, wishIndex);
int freeIndex = -1;
@@ -171,6 +220,12 @@ eDynamicDeviceReturnCode cDynamicDevice::AttachDevice(const char *DevPath)
return ddrcNoFreeDynDev;
}
+ if ((attachDelay > 0) && (Delayed > 1)) {
+ commandRequeue.Add(new cDynamicDeviceProbe::cDynamicDeviceProbeItem(ddpcAttach, new cString(DevPath)));
+ new cDelayedDeviceItems(DevPath, attachDelay);
+ return ddrcAttachDelayed;
+ }
+
cUdevDevice *dev = cUdev::GetDeviceFromDevName(DevPath);
if (dev != NULL) {
bool ignore = false;
diff --git a/dynamicdevice.h b/dynamicdevice.h
index e8acb9d..ae0cb21 100644
--- a/dynamicdevice.h
+++ b/dynamicdevice.h
@@ -11,12 +11,29 @@ enum eDynamicDeviceReturnCode { ddrcSuccess,
ddrcIsPrimaryDevice,
ddrcIsReceiving,
ddrcNotAllowed,
- ddrcNotSupported
+ ddrcNotSupported,
+ ddrcAttachDelayed
};
class cDynamicDevice : public cDevice {
friend class cPluginDynamite;
private:
+ class cDelayedDeviceItems : public cListObject {
+ private:
+ static cList<cDelayedDeviceItems> delayedItems;
+
+ cString devPath;
+ time_t dontAttachBefore;
+
+ public:
+ cDelayedDeviceItems(const char *DevPath, int AttachDelay);
+
+ static int CanBeAttached(const char *DevPath);
+ ///< Returns 0 if delay has not expired,
+ ///< 1 if delay has expired,
+ ///< 2 if no delay is given
+ };
+
static cPlugin *dynamite;
static int defaultGetTSTimeout;
static int idleTimeoutMinutes;
@@ -26,6 +43,7 @@ private:
static int numDynamicDevices;
static cMutex arrayMutex;
static cDynamicDevice *dynamicdevice[MAXDEVICES];
+ static cList<cDynamicDeviceProbe::cDynamicDeviceProbeItem> commandRequeue;
public:
static cDvbDeviceProbe *dvbprobe;
static bool enableOsdMessages;
@@ -34,11 +52,11 @@ public:
///< Returns the total number of dynamic devices.
static cDynamicDevice *GetDynamicDevice(int Index);
static bool ProcessQueuedCommands(void);
- static int GetProposedCardIndex(const char *DevPath);
+ static int GetUdevAttributesForAttach(const char *DevPath, int &CardIndex, int &AttachDelay);
static void DetachAllDevices(bool Force);
static cString ListAllDevices(int &ReplyCode); // for SVDRP command LSTD
static cString AttachDevicePattern(const char *Pattern);
- static eDynamicDeviceReturnCode AttachDevice(const char *DevPath);
+ static eDynamicDeviceReturnCode AttachDevice(const char *DevPath, int Delayed);
static eDynamicDeviceReturnCode DetachDevice(const char *DevPath, bool Force);
static eDynamicDeviceReturnCode SetLockDevice(const char *DevPath, bool Lock);
static eDynamicDeviceReturnCode SetIdle(const char *DevPath, bool Idle);
diff --git a/dynamite.c b/dynamite.c
index 7925b2f..0023b90 100644
--- a/dynamite.c
+++ b/dynamite.c
@@ -11,7 +11,7 @@
#include "monitor.h"
#include "status.h"
-static const char *VERSION = "0.0.8h";
+static const char *VERSION = "0.0.8i";
static const char *DESCRIPTION = tr("attach/detach devices on the fly");
static const char *MAINMENUENTRY = NULL;