diff options
author | Lars Hanisch <dvb@flensrocker.de> | 2011-03-24 23:48:29 +0100 |
---|---|---|
committer | Lars Hanisch <dvb@flensrocker.de> | 2011-03-24 23:48:29 +0100 |
commit | 2ad4f6c98465577159b3fa07df24dac37ee5a0e6 (patch) | |
tree | ce71e562044708ba5e6ab5c5574dc0b6c06f3064 | |
parent | e03b81ff043b9e1d29da4d48e8971d7fe7e3eccc (diff) | |
download | vdr-plugin-dynamite-2ad4f6c98465577159b3fa07df24dac37ee5a0e6.tar.gz vdr-plugin-dynamite-2ad4f6c98465577159b3fa07df24dac37ee5a0e6.tar.bz2 |
enumerate dvb devices with udev so every adapter is found even if not "in a row"
You can use the udev property "dynamite_ignore" to preserve a device from being attached.
With the udev property "dynamite_instanceid" the devices can be associated with different vdr instances.
-rw-r--r-- | README | 20 | ||||
-rw-r--r-- | dynamicdevice.c | 21 | ||||
-rw-r--r-- | dynamite.c | 16 | ||||
-rw-r--r-- | udev.c | 55 | ||||
-rw-r--r-- | udev.h | 6 |
5 files changed, 115 insertions, 3 deletions
@@ -214,12 +214,30 @@ If you want to add a timeout only to specific devices you can do this with udev. 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_timeout}="10", ENV{dynamite_timeout_handler_arg}="%k" +ACTION=="add", SUBSYSTEM=="dvb", ENV{DVB_DEVICE_TYPE}=="frontend" \ + , ENV{dynamite_ignore}="no" \ + , ENV{dynamite_instanceid}="0" \ + , 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. +Udev Properties +--------------- +dynamite_ignore + "yes", "y", "1": don't attach this device + +dynamite_instanceid + n: attach only at vdr with matching instance id + +dynamite_timeout + n: set GetTS timeout in seconds on this device + +dynamite_timeout_handler_arg + string: set a argument passed through to the auto-detach script + Known issues ------------ If a device managed by this plugin is the primary device it cannot be diff --git a/dynamicdevice.c b/dynamicdevice.c index 6ec9e2a..5ed2276 100644 --- a/dynamicdevice.c +++ b/dynamicdevice.c @@ -133,6 +133,27 @@ eDynamicDeviceReturnCode cDynamicDevice::AttachDevice(const char *DevPath) return ddrcNoFreeDynDev; } + cUdevDevice *dev = cUdev::GetDeviceFromDevName(DevPath); + if (dev != NULL) { + bool ignore = false; + const char *tmp; + if (((tmp = dev->GetPropertyValue("dynamite_ignore")) != NULL) + && ((strcasecmp(tmp, "yes") == 0) || (strcasecmp(tmp, "y") == 0) || (strcmp(tmp, "1") == 0))) { + isyslog("dynamite: udev says ignore %s", DevPath); + ignore = true; + } + else if (((tmp = dev->GetPropertyValue("dynamite_instanceid")) != NULL) && isnumber(tmp)) { + int devInstanceId = strtol(tmp, NULL, 10); + if (devInstanceId != InstanceId) { + isyslog("dynamite: device %s is for vdr instance %d, we are %d", DevPath, devInstanceId, InstanceId); + ignore = true; + } + } + delete dev; + if (ignore) + return ddrcNotSupported; + } + cDevice::nextParentDevice = dynamicdevice[freeIndex]; for (cDynamicDeviceProbe *ddp = DynamicDeviceProbes.First(); ddp; ddp = DynamicDeviceProbes.Next(ddp)) { @@ -9,7 +9,7 @@ #include "dynamicdevice.h" #include "monitor.h" -static const char *VERSION = "0.0.5o"; +static const char *VERSION = "0.0.6"; static const char *DESCRIPTION = "attach/detach devices on the fly"; static const char *MAINMENUENTRY = NULL; @@ -178,6 +178,20 @@ bool cPluginDynamite::Initialize(void) while (cDevice::NumDevices() < MAXDEVICES) new cDynamicDevice; } + // look for all dvb devices + cList<cUdevDevice> *devices = cUdev::EnumDevices("dvb", "DVB_DEVICE_TYPE", "frontend"); + if (devices != NULL) { + int dummy = 0; + for (cUdevDevice *d = devices->First(); d; d = devices->Next(d)) { + const char *devpath = d->GetDevnode(); + if ((devpath != NULL) && (cDynamicDevice::IndexOf(devpath, dummy) < 0)) { + isyslog("dynamite: probing %s", devpath); + cDynamicDeviceProbe::QueueDynamicDeviceCommand(ddpcAttach, devpath); + } + } + delete devices; + } + if (!cDynamicDevice::ProcessQueuedCommands()) esyslog("dynamite: can't process all queued commands"); return true; @@ -135,3 +135,58 @@ cUdevDevice *cUdev::GetDeviceFromDevName(const char *DevName) return NULL; return new cUdevDevice(dev); } + +cUdevDevice *cUdev::GetDeviceFromSysPath(const char *SysPath) +{ + if (SysPath == NULL) + return NULL; + udev_device *dev = udev_device_new_from_syspath(udev, SysPath); + if (dev == NULL) + return NULL; + return new cUdevDevice(dev); +} + +cList<cUdevDevice> *cUdev::EnumDevices(const char *Subsystem, const char *Property, const char *Value) +{ + cList<cUdevDevice> *devices = new cList<cUdevDevice>; + struct udev_enumerate *e = udev_enumerate_new(udev); + struct udev_list_entry *l; + cUdevListEntry *listEntry; + const char *path; + cUdevDevice *dev; + if (e != NULL) { + int rc = 0; + if (Subsystem && ((rc = udev_enumerate_add_match_subsystem(e, Subsystem)) < 0)) { + esyslog("dynamite: can't add subsystem %s to enum-filter: %d", Subsystem, rc); + goto unref; + } + if (Property && Value && ((rc = udev_enumerate_add_match_property(e, Property, Value)) < 0)) { + esyslog("dynamite: can't add property %s value %s to enum-filter: %d", Property, Value, rc); + goto unref; + } + if ((rc = udev_enumerate_scan_devices(e)) < 0) { + esyslog("dynamite: can't scan for devices: %d", rc); + goto unref; + } + l = udev_enumerate_get_list_entry(e); + if (l == NULL) { + esyslog("dynamite: can't get list of devices"); + goto unref; + } + listEntry = new cUdevListEntry(l); + while (listEntry) { + path = listEntry->GetName(); + if (path != NULL) { + dev = GetDeviceFromSysPath(path); + if (dev != NULL) + devices->Add(dev); + } + cUdevListEntry *tmp = listEntry->GetNext(); + delete listEntry; + listEntry = tmp; + } +unref: + udev_enumerate_unref(e); + } + return devices; +} @@ -3,6 +3,8 @@ #include <libudev.h> +#include <vdr/tools.h> + class cUdevListEntry { private: struct udev_list_entry *listEntry; @@ -15,7 +17,7 @@ public: const char *GetValue(void) const; }; -class cUdevDevice { +class cUdevDevice : public cListObject { private: struct udev_device *device; bool doUnref; @@ -38,6 +40,8 @@ public: static struct udev *Init(void); static void Free(void); static cUdevDevice *GetDeviceFromDevName(const char *DevName); + static cUdevDevice *GetDeviceFromSysPath(const char *SysPath); + static cList<cUdevDevice> *EnumDevices(const char *Subsystem, const char *Property, const char *Value); }; #endif // __DYNAMITEUDEV_H |