From d472fe2e251744dbc0baa942225b5705eaec8fd2 Mon Sep 17 00:00:00 2001 From: Lars Hanisch Date: Sat, 17 Dec 2011 15:15:55 +0100 Subject: add udev attribute dynamite_attach_delay for delaying the attach of specific devices --- HISTORY | 5 ++++ README | 6 ++++- dynamicdevice.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++--------- dynamicdevice.h | 24 +++++++++++++++--- dynamite.c | 2 +- 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 cDynamicDevice::commandRequeue; + +cList 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 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 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; -- cgit v1.2.3