summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Hanisch <dvb@flensrocker.de>2011-02-02 21:44:20 +0100
committerLars Hanisch <dvb@flensrocker.de>2011-02-02 21:44:20 +0100
commit6fb28a2e29faf239b1b14fcac981d560a7550e65 (patch)
tree0fe226aad44f26d2d375fa9320bcfa2f2135123f
parent8a8770d8b8b8d19e5f7d07628f742957d1ade4f1 (diff)
downloadvdr-plugin-dynamite-6fb28a2e29faf239b1b14fcac981d560a7550e65.tar.gz
vdr-plugin-dynamite-6fb28a2e29faf239b1b14fcac981d560a7550e65.tar.bz2
add generic udev-filter
Other plugins can add a filter for different subsystems and devnodes. example: AddUdevMonitor video4linux /dev/video If udev signals an "add"-event whose devnode starts with "/dev/video" the whole devnode is queued for attaching.
-rw-r--r--dynamite.c32
-rw-r--r--monitor.c52
-rw-r--r--monitor.h16
-rw-r--r--udev.c7
-rw-r--r--udev.h1
5 files changed, 107 insertions, 1 deletions
diff --git a/dynamite.c b/dynamite.c
index 38eb69f..52b924a 100644
--- a/dynamite.c
+++ b/dynamite.c
@@ -219,6 +219,13 @@ bool cPluginDynamite::Service(const char *Id, void *Data)
}
return true;
}
+ if (strcmp(Id, "dynamite-AddUdevMonitor-v0.1") == 0) {
+ if (Data != NULL) {
+ int replyCode;
+ SVDRPCommand("AddUdevMonitor", (const char*)Data, replyCode);
+ }
+ return true;
+ }
return false;
}
@@ -265,6 +272,11 @@ const char **cPluginDynamite::SVDRPHelpPages(void)
" Sets the \"GetTSPacket\"-watchdog timeout for all attached devices\n"
" and all devices that will be attached.\n"
" alternate command: SetDefaultGetTSTimeout",
+ "ADUM subsystem begin-of-devnode\n"
+ " Adds a filter to the udev-monitor.\n"
+ " If an event occurs whose devnode starts with the supplied parameter\n"
+ " this devnode will be queued for attaching.\n"
+ " alternate command: AddUdevMonitor",
NULL
};
return HelpPages;
@@ -335,6 +347,26 @@ cString cPluginDynamite::SVDRPCommand(const char *Command, const char *Option, i
return cString::sprintf("set default GetTS-Timeout on all devices to %d seconds", seconds);
}
}
+
+ if ((strcasecmp(Command, "AUDM") == 0) || (strcasecmp(Command, "AddUdevMonitor") == 0)) {
+ int maxlen = strlen(Option);
+ if (maxlen > 0) {
+ char *subsystem = new char[maxlen + 1];
+ char *devnode = new char[maxlen + 1];
+ subsystem[0] = '\0';
+ devnode[0] = '\0';
+ cString msg;
+ if ((sscanf(Option, "%s %s", subsystem, devnode) == 2) && cUdevPatternFilter::AddFilter(subsystem, devnode))
+ msg = cString::sprintf("add udev-filter for %s %s", subsystem, devnode);
+ else {
+ ReplyCode = 550;
+ msg = cString::sprintf("can't add udev-filter for %s %s", subsystem, devnode);
+ }
+ delete [] subsystem;
+ delete [] devnode;
+ return msg;
+ }
+ }
return NULL;
}
diff --git a/monitor.c b/monitor.c
index ff9392c..e603c30 100644
--- a/monitor.c
+++ b/monitor.c
@@ -218,3 +218,55 @@ void cUdevDvbFilter::Process(cUdevDevice &Device)
cDynamicDeviceProbe::QueueDynamicDeviceCommand(ddpcAttach, devname);
}
}
+
+// --- cUdevPatternFilter ----------------------------------------------------
+
+cMutex cUdevPatternFilter::filtersMutex;
+cList<cUdevPatternFilter> cUdevPatternFilter::filters;
+
+bool cUdevPatternFilter::AddFilter(const char *Subsystem, const char *Pattern)
+{
+ if (Pattern == NULL)
+ return false;
+ cMutexLock lock(&filtersMutex);
+ cUdevPatternFilter *f = filters.First();
+ while (f) {
+ if (f->monitor && (strcmp(*f->pattern, Pattern) == 0)) {
+ if ((Subsystem == NULL) && (*f->monitor->GetSubsystem() == NULL))
+ return true;
+ if ((Subsystem != NULL)
+ && (*f->monitor->GetSubsystem() != NULL)
+ && (strcmp(*f->monitor->GetSubsystem(), Subsystem) == 0))
+ return true;
+ }
+ f = filters.Next(f);
+ }
+ return cUdevMonitor::AddFilter(Subsystem, new cUdevPatternFilter(Pattern));
+}
+
+cUdevPatternFilter::cUdevPatternFilter(const char *Pattern)
+:pattern(Pattern)
+{
+ cMutexLock lock(&filtersMutex);
+ filters.Add(this);
+}
+
+cUdevPatternFilter::~cUdevPatternFilter(void)
+{
+ cMutexLock lock(&filtersMutex);
+ filters.Del(this, false);
+}
+
+void cUdevPatternFilter::Process(cUdevDevice &Device)
+{
+ const char *action = Device.GetAction();
+ if (action && (strcmp(action, "add") == 0)) {
+ const char *devname = Device.GetDevnode();
+ if (devname != NULL) {
+ int dLen = strlen(devname);
+ int pLen = strlen(*pattern);
+ if ((pLen <= dLen) && (strncmp(devname, *pattern, pLen) == 0))
+ cDynamicDeviceProbe::QueueDynamicDeviceCommand(ddpcAttach, devname);
+ }
+ }
+}
diff --git a/monitor.h b/monitor.h
index 659e504..79634c0 100644
--- a/monitor.h
+++ b/monitor.h
@@ -54,5 +54,19 @@ class cUdevDvbFilter : public cUdevFilter {
protected:
virtual void Process(cUdevDevice &Device);
};
-
+
+class cUdevPatternFilter : public cUdevFilter {
+public:
+ static bool AddFilter(const char *Subsystem, const char *Pattern);
+protected:
+ static cMutex filtersMutex;
+ static cList<cUdevPatternFilter> filters;
+
+ virtual ~cUdevPatternFilter(void);
+ virtual void Process(cUdevDevice &Device);
+private:
+ cUdevPatternFilter(const char *Pattern);
+ cString pattern;
+ };
+
#endif // __DYNAMITEMONITOR_H
diff --git a/udev.c b/udev.c
index 77cc744..f37fc77 100644
--- a/udev.c
+++ b/udev.c
@@ -67,6 +67,13 @@ cUdevListEntry *cUdevDevice::GetDevlinksList(void) const
return new cUdevListEntry(listEntry);
}
+const char *cUdevDevice::GetDevnode(void) const
+{
+ if (device == NULL)
+ return false;
+ return udev_device_get_devnode(device);
+}
+
cUdevDevice *cUdevDevice::GetParent(void) const
{
if (device == NULL)
diff --git a/udev.h b/udev.h
index e72fe19..af079ab 100644
--- a/udev.h
+++ b/udev.h
@@ -25,6 +25,7 @@ public:
const char *GetAction(void) const;
cUdevListEntry *GetDevlinksList(void) const;
+ const char *GetDevnode(void) const;
cUdevDevice *GetParent(void) const;
const char *GetPropertyValue(const char *Key) const;
const char *GetSyspath(void) const;