summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Hanisch <dvb@flensrocker.de>2011-03-24 23:48:29 +0100
committerLars Hanisch <dvb@flensrocker.de>2011-03-24 23:48:29 +0100
commit2ad4f6c98465577159b3fa07df24dac37ee5a0e6 (patch)
treece71e562044708ba5e6ab5c5574dc0b6c06f3064
parente03b81ff043b9e1d29da4d48e8971d7fe7e3eccc (diff)
downloadvdr-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--README20
-rw-r--r--dynamicdevice.c21
-rw-r--r--dynamite.c16
-rw-r--r--udev.c55
-rw-r--r--udev.h6
5 files changed, 115 insertions, 3 deletions
diff --git a/README b/README
index 746c7a9..8f0c839 100644
--- a/README
+++ b/README
@@ -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)) {
diff --git a/dynamite.c b/dynamite.c
index 6832358..cc27ede 100644
--- a/dynamite.c
+++ b/dynamite.c
@@ -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;
diff --git a/udev.c b/udev.c
index 79207cf..cba448a 100644
--- a/udev.c
+++ b/udev.c
@@ -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;
+}
diff --git a/udev.h b/udev.h
index e3c82ea..2286b0f 100644
--- a/udev.h
+++ b/udev.h
@@ -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