diff options
author | Lars Hanisch <dvb@flensrocker.de> | 2011-02-17 01:44:32 +0100 |
---|---|---|
committer | Lars Hanisch <dvb@flensrocker.de> | 2011-02-17 01:44:32 +0100 |
commit | c3cc3a490df4937dc70cc2442c6724c4b6d956ec (patch) | |
tree | c2a58ac35d051230888a9d60ad405c44764994dc | |
parent | a5a5be51f1d261a43f142f8be86229f2c46b1482 (diff) | |
download | vdr-plugin-dynamite-c3cc3a490df4937dc70cc2442c6724c4b6d956ec.tar.gz vdr-plugin-dynamite-c3cc3a490df4937dc70cc2442c6724c4b6d956ec.tar.bz2 |
dynamite can call an external program if the GetTSTimeout of a device triggers
In setup.conf set dynamite.GetTSTimeoutHandler to a program you want
to execute. If the udev-property dynamite_timeout_handler_arg is set it will
be passed as the argument to it otherwise the devpath with wich the device was
attached to dynamite.
-rw-r--r-- | HISTORY | 10 | ||||
-rw-r--r-- | README | 16 | ||||
-rw-r--r-- | dynamicdevice.c | 31 | ||||
-rw-r--r-- | dynamicdevice.h | 2 | ||||
-rw-r--r-- | dynamite.c | 67 | ||||
-rw-r--r-- | monitor.c | 3 |
6 files changed, 127 insertions, 2 deletions
@@ -83,3 +83,13 @@ VDR Plugin 'dynamite' Revision History - add new command to cDynamicDeviceProbe to call dynamite-Service (no ABI changes) - extend udev-monitor with parsing of a timeout-value set by some udev rule + +2011-02-17: Version 0.0.5g + +- modify vdr-patch because zapping could interrupt recordings + +2011-02-18: Version 0.0.5h + +- add parsing of udev-property "dynamite_timeout_handler_arg" +- add "dynamite.GetTSTimeoutHandler = /path/to/program" to setup.conf +- call external program on GetTS-timeout @@ -137,11 +137,20 @@ ADUM subsystem begin-of-devnode (this is what pvrinput uses) alternate command: AddUdevMonitor +"dynamite-SetGetTSTimeoutHandlerArg-v0.1" +SetGetTSTimeoutHandlerArg /dev/path/to/device arg + Sets the argument for the timout handler program. + +"dynamite-CallGetTSTimeoutHandler-v0.1" +CallGetTSTimeoutHandler arg + Calls the timout handler program with the given arguments. + Don't forget to prefix them with "plug dynamite"... Parameters in setup.conf ------------------------ dynamite.DefaultGetTSTimeout = 0 +dynamite.GetTSTimeoutHandler = /path/to/program "GetTS" watchdog ---------------- @@ -160,7 +169,11 @@ Add a rule which sets with ENV{dynamite_timeout}="10" the needed timeout value. The udev-monitor in dynamite will evaluate this device-property. For now this only works for attaching via udev-monitor! example for udev rule: -ACTION=="add", SUBSYSTEM=="dvb", ENV{DVB_DEVICE_TYPE}=="frontend", ENV{dynamite_timeout}="10" +ACTION=="add", SUBSYSTEM=="dvb", ENV{DVB_DEVICE_TYPE}=="frontend", ENV{dynamite_timeout}="10", ENV{dynamite_timeout_handler_arg}="%k" + +After the device is detached and dynamite.GetTSTimeoutHandler in setup.conf is set +to a path, this program is called. If the udev-property "dynamite_timeout_handler_arg" +is not present the devpath is provided as argument, with which the device was attached. Known issues ------------ @@ -173,4 +186,5 @@ me how to do this... TODO ---- * implement interface for other plugins to use the udev monitor +* enumerate udev-properties on devices found at startup * implement some OSD functionality for detaching, locking etc. diff --git a/dynamicdevice.c b/dynamicdevice.c index c7841f0..328e146 100644 --- a/dynamicdevice.c +++ b/dynamicdevice.c @@ -251,6 +251,29 @@ void cDynamicDevice::SetDefaultGetTSTimeout(int Seconds) } } +eDynamicDeviceReturnCode cDynamicDevice::SetGetTSTimeoutHandlerArg(const char *DevPath, const char *Arg) +{ + if (!DevPath || !Arg) + return ddrcNotSupported; + + cMutexLock lock(&arrayMutex); + int freeIndex = -1; + int index = -1; + if (isnumber(DevPath)) + index = strtol(DevPath, NULL, 10) - 1; + else + index = IndexOf(DevPath, freeIndex); + + if ((index < 0) || (index >= numDynamicDevices)) + return ddrcNotFound; + + if (dynamicdevice[index]->getTSTimeoutHandlerArg) + delete dynamicdevice[index]->getTSTimeoutHandlerArg; + dynamicdevice[index]->getTSTimeoutHandlerArg = new cString(Arg); + isyslog("dynamite: set GetTSTimeoutHandlerArg on device %s to %s", DevPath, Arg); + return ddrcSuccess; +} + bool cDynamicDevice::IsAttached(const char *DevPath) { cMutexLock lock(&arrayMutex); @@ -262,6 +285,7 @@ bool cDynamicDevice::IsAttached(const char *DevPath) cDynamicDevice::cDynamicDevice() :index(-1) ,devpath(NULL) +,getTSTimeoutHandlerArg(NULL) ,isDetachable(true) ,getTSTimeout(defaultGetTSTimeout) { @@ -277,6 +301,9 @@ cDynamicDevice::cDynamicDevice() cDynamicDevice::~cDynamicDevice() { DeleteSubDevice(); + if (getTSTimeoutHandlerArg) + delete getTSTimeoutHandlerArg; + getTSTimeoutHandlerArg = NULL; } void cDynamicDevice::DeleteSubDevice() @@ -700,6 +727,10 @@ bool cDynamicDevice::GetTSPacket(uchar *&Data) d = **devpath; esyslog("dynamite: device %s hasn't delivered any data for %d seconds, it will be detached", d, getTSTimeout); cDynamicDeviceProbe::QueueDynamicDeviceCommand(ddpcDetach, *devpath); + const char *timeoutHandlerArg = *devpath; + if (getTSTimeoutHandlerArg) + timeoutHandlerArg = **getTSTimeoutHandlerArg; + cDynamicDeviceProbe::QueueDynamicDeviceCommand(ddpcService, *cString::sprintf("dynamite-CallGetTSTimeoutHandler-v0.1 %s", timeoutHandlerArg)); return false; } } diff --git a/dynamicdevice.h b/dynamicdevice.h index e499774..488b789 100644 --- a/dynamicdevice.h +++ b/dynamicdevice.h @@ -37,10 +37,12 @@ public: static eDynamicDeviceReturnCode SetLockDevice(const char *DevPath, bool Lock); static eDynamicDeviceReturnCode SetGetTSTimeout(const char *DevPath, int Seconds); static void SetDefaultGetTSTimeout(int Seconds); + static eDynamicDeviceReturnCode SetGetTSTimeoutHandlerArg(const char *DevPath, const char *Arg); static bool IsAttached(const char *DevPath); private: int index; cString *devpath; + cString *getTSTimeoutHandlerArg; bool isDetachable; time_t getTSWatchdog; int getTSTimeout; @@ -8,7 +8,7 @@ #include "dynamicdevice.h" #include "monitor.h" -static const char *VERSION = "0.0.5g"; +static const char *VERSION = "0.0.5h"; static const char *DESCRIPTION = "attach/detach devices on the fly"; static const char *MAINMENUENTRY = NULL; @@ -51,6 +51,7 @@ public: class cPluginDynamite : public cPlugin { private: cDynamiteDeviceProbe *probe; + cString *getTSTimeoutHandler; public: cPluginDynamite(void); virtual ~cPluginDynamite(); @@ -75,6 +76,7 @@ public: }; cPluginDynamite::cPluginDynamite(void) +:getTSTimeoutHandler(NULL) { cDynamicDevice::dynamite = this; cDynamicDevice::dvbprobe = new cDynamiteDvbDeviceProbe; @@ -94,6 +96,8 @@ cPluginDynamite::~cPluginDynamite() delete cDynamicDevice::dvbprobe; if (probe) delete probe; + if (getTSTimeoutHandler != NULL) + delete getTSTimeoutHandler; } const char *cPluginDynamite::CommandLineHelp(void) @@ -174,6 +178,15 @@ bool cPluginDynamite::SetupParse(const char *Name, const char *Value) int replyCode; if (strcasecmp(Name, "DefaultGetTSTimeout") == 0) SVDRPCommand("SetDefaultGetTSTimeout", Value, replyCode); + if (strcasecmp(Name, "GetTSTimeoutHandler") == 0) { + if (getTSTimeoutHandler != NULL) + delete getTSTimeoutHandler; + getTSTimeoutHandler = NULL; + if (Value != NULL) { + getTSTimeoutHandler = new cString(Value); + isyslog("dynamite: installed GetTSTimeoutHandler %s", **getTSTimeoutHandler); + } + } else return false; return true; @@ -227,6 +240,20 @@ bool cPluginDynamite::Service(const char *Id, void *Data) } return true; } + if (strcmp(Id, "dynamite-CallGetTSTimeoutHandler-v0.1") == 0) { + if (Data != NULL) { + int replyCode; + SVDRPCommand("CallGetTSTimeoutHandler", (const char*)Data, replyCode); + } + return true; + } + if (strcmp(Id, "dynamite-SetGetTSTimeoutHandlerArg-v0.1") == 0) { + if (Data != NULL) { + int replyCode; + SVDRPCommand("SetGetTSTimeoutHandlerArg", (const char*)Data, replyCode); + } + return true; + } return false; } @@ -280,6 +307,10 @@ const char **cPluginDynamite::SVDRPHelpPages(void) " AddUdevMonitor video4linux /dev/video\n" " (this is what pvrinput uses)\n" " alternate command: AddUdevMonitor", + "SetGetTSTimeoutHandlerArg /dev/path/to/device arg\n" + " Sets the argument for the timout handler program.", + "CallGetTSTimeoutHandler arg\n" + " Calls the timout handler program with the given arguments.", NULL }; return HelpPages; @@ -370,6 +401,40 @@ cString cPluginDynamite::SVDRPCommand(const char *Command, const char *Option, i return msg; } } + + if (strcasecmp(Command, "CallGetTSTimeoutHandler") == 0) { + if (getTSTimeoutHandler == NULL) { + cString msg = cString::sprintf("no GetTSTimeoutHandler configured, arg: %s", Option); + isyslog("dynamite: %s", *msg); + return cString("no GetTSTimeoutHandler configured, arg: %s", Option); + } + isyslog("dynamite: executing %s %s", **getTSTimeoutHandler, Option); + if (system(*cString::sprintf("%s %s", **getTSTimeoutHandler, Option)) < 0) { + cString msg = cString::sprintf("error (%d) on executing %s %s", errno, **getTSTimeoutHandler, Option); + isyslog("dynamite: %s", *msg); + return msg; + } + cString msg = cString::sprintf("success on executing %s %s", **getTSTimeoutHandler, Option); + isyslog("dynamite: %s", *msg); + return msg; + } + + if (strcasecmp(Command, "SetGetTSTimeoutHandlerArg") == 0) { + cString ret; + int len = strlen(Option); + if (len > 0) { + cString devPath(Option); + const char *arg = strchr(*devPath, ' '); + if (arg && (arg < (*devPath + len + 1))) { + devPath.Truncate(arg - *devPath); + arg++; + cDynamicDevice::SetGetTSTimeoutHandlerArg(*devPath, arg); + ret = cString::sprintf("set GetTS-Timeout-Handler-Arg on device %s to %s", *devPath, arg); + } + } + return ret; + } + return NULL; } @@ -219,6 +219,9 @@ void cUdevDvbFilter::Process(cUdevDevice &Device) const char *timeout = Device.GetPropertyValue("dynamite_timeout"); if (timeout) cDynamicDeviceProbe::QueueDynamicDeviceCommand(ddpcService, *cString::sprintf("dynamite-SetGetTSTimeout-v0.1 %s %s", devname, timeout)); + const char *timeoutHandlerArg = Device.GetPropertyValue("dynamite_timeout_handler_arg"); + if (timeoutHandlerArg) + cDynamicDeviceProbe::QueueDynamicDeviceCommand(ddpcService, *cString::sprintf("dynamite-SetGetTSTimeoutHandlerArg-v0.1 %s %s", devname, timeoutHandlerArg)); } } |