[vdr-plugin-pvrinput] 01/04: Imported Upstream version 2014-01-11+git20150213
Tobias Grimm
tiber-guest at moszumanska.debian.org
Fri Feb 13 22:51:34 UTC 2015
This is an automated email from the git hooks/post-receive script.
tiber-guest pushed a commit to branch master
in repository vdr-plugin-pvrinput.
commit a044c87646ecb5c93c4e073fd1268d7148c67ad3
Author: etobi <git at e-tobi.net>
Date: Fri Feb 13 22:03:28 2015 +0100
Imported Upstream version 2014-01-11+git20150213
---
Makefile | 7 +-
device.c | 179 ++++++++++++++++++++++++++++------------------
device.h | 7 +-
pvrinput.c | 2 +-
udev.c | 236 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
udev.h | 56 +++++++++++++++
6 files changed, 411 insertions(+), 76 deletions(-)
diff --git a/Makefile b/Makefile
index 67f09e9..fd4b7e0 100644
--- a/Makefile
+++ b/Makefile
@@ -16,7 +16,7 @@ VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | awk '{ pri
### The directory environment:
# Use package data if installed...otherwise assume we're under the VDR source directory:
-PKGCFG = $(if $(VDRDIR),$(shell pkg-config --variable=$(1) $(VDRDIR)/vdr.pc),$(shell pkg-config --variable=$(1) vdr || pkg-config --variable=$(1) ../../../vdr.pc))
+PKGCFG = $(if $(VDRDIR),$(shell pkg-config --variable=$(1) $(VDRDIR)/vdr.pc),$(shell PKG_CONFIG_PATH="$$PKG_CONFIG_PATH:../../.." pkg-config --variable=$(1) vdr))
LIBDIR = $(call PKGCFG,libdir)
LOCDIR = $(call PKGCFG,locdir)
PLGCFG = $(call PKGCFG,plgcfg)
@@ -27,6 +27,7 @@ TMPDIR ?= /tmp
export CFLAGS = $(call PKGCFG,cflags)
export CXXFLAGS = $(call PKGCFG,cxxflags)
+export LDADD = $(shell pkg-config --libs libudev)
### The version number of VDR's plugin API:
@@ -53,7 +54,7 @@ DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
### The object files (add further files here):
-OBJS = $(PLUGIN).o common.o device.o reader.o menu.o setup.o filter.o sourceparams.o submenu.o
+OBJS = $(PLUGIN).o common.o device.o reader.o menu.o setup.o filter.o sourceparams.o submenu.o udev.o
### The main target:
@@ -102,7 +103,7 @@ install-i18n: $(I18Nmsgs)
### Targets:
$(SOFILE): $(OBJS)
- $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@
+ $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) $(LDADD) -o $@
install-lib: $(SOFILE)
install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION)
diff --git a/device.c b/device.c
index b90266c..1a57289 100644
--- a/device.c
+++ b/device.c
@@ -1,4 +1,5 @@
#include "common.h"
+#include "udev.h"
#include <linux/dvb/video.h>
char DRIVERNAME[][15] = {
@@ -33,7 +34,6 @@ cPvrDevice::cPvrDevice(int DeviceNumber, cDevice *ParentDevice)
isClosing(false),
readThreadRunning(false),
ChannelSettingsDone(false),
- FirstChannelSwitch(true),
pvrusb2_ready(true),
driver(undef),
cardname(UNDEF),
@@ -42,7 +42,7 @@ cPvrDevice::cPvrDevice(int DeviceNumber, cDevice *ParentDevice)
{
log(pvrDEBUG2, "new cPvrDevice (%d)", number);
v4l2_fd = mpeg_fd = radio_fd = -1;
- v4l2_dev = mpeg_dev = radio_dev = -1;
+ v4l2_dev = mpeg_dev = -1;
vpid = apid = tpid = -1;
cString devName;
struct v4l2_capability video_vcap;
@@ -90,44 +90,59 @@ cPvrDevice::cPvrDevice(int DeviceNumber, cDevice *ParentDevice)
VBIDeviceCount++;
log(pvrDEBUG1, "%s supports sliced VBI Capture, total number of VBI capable devices is now %d", *devName, VBIDeviceCount);
}
+ bool supports_radio = false;
+ if (video_vcap.capabilities & V4L2_CAP_RADIO)
+ supports_radio = true;
+
+ pvrinput::cUdev::Init();
+ pvrinput::cUdevDevice *v4ldev = pvrinput::cUdev::GetDeviceFromDevName(*devName);
+ if (v4ldev != NULL) {
+ static const char *propertyName = "ID_PATH";
+ static const char *vbi_dev_node = "/dev/vbi";
+ static const char *radio_dev_node = "/dev/radio";
+ const char *id_path = v4ldev->GetPropertyValue(propertyName);
+ if (id_path != NULL) {
+ cList<pvrinput::cUdevDevice> *v4ldevices = pvrinput::cUdev::EnumDevices("video4linux", propertyName, id_path);
+ for (pvrinput::cUdevDevice *dev = v4ldevices->First(); dev; dev = v4ldevices->Next(dev)) {
+ log(pvrDEBUG1, "pvrinput: %s is related to %s", *devName, dev->GetDevnode());
+ if (SupportsSlicedVBI && (*vbi_devname == NULL) && (strncmp(dev->GetDevnode(), vbi_dev_node, strlen(vbi_dev_node)) == 0))
+ vbi_devname = dev->GetDevnode();
+ else if (supports_radio && (*radio_devname == NULL) && (strncmp(dev->GetDevnode(), radio_dev_node, strlen(radio_dev_node)) == 0))
+ radio_devname = dev->GetDevnode();
+ }
+ delete v4ldevices;
+ }
+ delete v4ldev;
+ }
+ pvrinput::cUdev::Free();
+
if (video_vcap.capabilities & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)
hasDecoder = true; //can only be a PVR350
- for (i = 0; i < kMaxPvrDevices; i++) {
- if (radio_dev<0 && (video_vcap.capabilities & V4L2_CAP_RADIO)) { //searching matching radio dev
- devName = cString::sprintf("/dev/radio%d", i);
- radio_fd = open(devName, O_RDWR);
- if (radio_fd >= 0) {
- memset(&capability, 0, sizeof(capability));
- if (IOCTL(radio_fd, VIDIOC_QUERYCAP, &capability) != 0)
- log(pvrERROR, "VIDIOC_QUERYCAP failed, %d:%s", errno, strerror(errno));
- if (!strncmp(*BusID, (const char*)capability.bus_info, strlen(*BusID) - 1)) {
- radio_dev = i; // store info for later
- log(pvrDEBUG1, "/dev/radio%d = FM radio dev",radio_dev);
- }
- close(radio_fd); // a pvrusb2 will remain on input 3. The bool FirstChannelSwitch will solve this later
- radio_fd = -1;
- }
+
+ if (driver == cx88_blackbird) {
+ for (i = 0; i < kMaxPvrDevices; i++) {
+ if (mpeg_dev < 0) { // the blackbird uses two (!) different devices, search the other one.
+ close(v4l2_fd);
+ v4l2_fd = -1;
+ devName = cString::sprintf("/dev/video%d", i);
+ mpeg_fd = open(devName, O_RDWR);
+ if (mpeg_fd > 0) {
+ memset(&capability, 0, sizeof(capability));
+ IOCTL(mpeg_fd, VIDIOC_QUERYCAP, &capability);
+ if (!strncmp(*BusID, (const char*)capability.bus_info, strlen(*BusID) - 1)
+ && !strcmp("cx8800", (const char*)capability.driver)) {
+ mpeg_dev = v4l2_dev; //for this driver we found mpeg_dev up to now.
+ v4l2_dev = i; //reassigning, now with correct value.
+ log(pvrDEBUG1, "/dev/video%d = v4l2 dev (analog properties: volume/hue/brightness/inputs..)", v4l2_dev);
+ log(pvrDEBUG1, "/dev/video%d = mpeg dev (MPEG properties: bitrates/frame rate/filters..)", mpeg_dev);
+ }
+ close(mpeg_fd);
+ mpeg_fd = -1;
+ }
+ }
+ } // end device search loop
}
- if (mpeg_dev < 0 && (driver == cx88_blackbird)) { // the blackbird uses two (!) different devices, search the other one.
- close(v4l2_fd);
- v4l2_fd = -1;
- devName = cString::sprintf("/dev/video%d", i);
- mpeg_fd = open(devName, O_RDWR);
- if (mpeg_fd) {
- memset(&capability, 0, sizeof(capability));
- IOCTL(mpeg_fd, VIDIOC_QUERYCAP, &capability);
- if (!strncmp(*BusID, (const char*)capability.bus_info, strlen(*BusID) - 1)
- && !strcmp("cx8800", (const char*)capability.driver)) {
- mpeg_dev = v4l2_dev; //for this driver we found mpeg_dev up to now.
- v4l2_dev = i; //reassigning, now with correct value.
- log(pvrDEBUG1, "/dev/video%d = v4l2 dev (analog properties: volume/hue/brightness/inputs..)", v4l2_dev);
- log(pvrDEBUG1, "/dev/video%d = mpeg dev (MPEG properties: bitrates/frame rate/filters..)", mpeg_dev);
- }
- close(mpeg_fd);
- mpeg_fd = -1;
- }
- }
- } // end device search loop
+
switch (driver) {
case ivtv: //ivtv, cx18, pvrusb2 and hdpvr share the same device.
case cx18:
@@ -486,7 +501,7 @@ bool cPvrDevice::Tune(int freq)
bool cPvrDevice::SetInput(int input)
{
- if (input == CurrentInput && !FirstChannelSwitch)
+ if (input == CurrentInput)
return true;
log(pvrDEBUG1, "cPvrDevice::SetInput on /dev/video%d (%s) to %d", number, CARDNAME[cardname], input);
if (IOCTL(v4l2_fd, VIDIOC_S_INPUT, &input) != 0) {
@@ -662,37 +677,48 @@ void cPvrDevice::SetEncoderState(eEncState state)
bool cPvrDevice::SetVBImode(int vbiLinesPerFrame, int vbistatus)
{
- if (v4l2_fd >= 0 && SupportsSlicedVBI) {
- log(pvrDEBUG1, "SetVBImode(%d, %d) on /dev/video%d (%s)", vbiLinesPerFrame, vbistatus, number, CARDNAME[cardname]);
- struct v4l2_format vbifmt;
- struct v4l2_ext_controls ctrls;
- struct v4l2_ext_control ctrl;
- memset(&vbifmt, 0, sizeof(vbifmt));
- memset(&ctrls, 0, sizeof(ctrls));
- memset(&ctrl, 0, sizeof(ctrl));
- ctrl.id = V4L2_CID_MPEG_STREAM_VBI_FMT;
- ctrl.value = vbistatus;
- ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
- ctrls.controls = &ctrl;
- ctrls.count = 1;
- if (IOCTL(v4l2_fd, VIDIOC_S_EXT_CTRLS, &ctrls) != 0) {
- log(pvrERROR, "cPvrDevice::SetVBImode(): error setting vbi mode (ctrls) on /dev/video%d (%s), %d:%s",
- number, CARDNAME[cardname], errno, strerror(errno));
- return false;
- }
- if ((ctrl.value == V4L2_MPEG_STREAM_VBI_FMT_IVTV) && (vbiLinesPerFrame == 625)) {
+ if (*vbi_devname && SupportsSlicedVBI) {
+ log(pvrDEBUG1, "SetVBImode(%d, %d) on %s (%s)", vbiLinesPerFrame, vbistatus, *vbi_devname, CARDNAME[cardname]);
+
+ int vbi_fd = open(*vbi_devname, O_RDWR);
+ if (vbi_fd < 0) {
+ log(pvrERROR, "cPvrDevice::SetVBImode(): error opening %s (%s), %d:%s",
+ *vbi_devname, CARDNAME[cardname], errno, strerror(errno));
+ return false;
+ }
+
+ struct v4l2_format vbifmt;
+ struct v4l2_ext_controls ctrls;
+ struct v4l2_ext_control ctrl;
+ memset(&vbifmt, 0, sizeof(vbifmt));
+ memset(&ctrls, 0, sizeof(ctrls));
+ memset(&ctrl, 0, sizeof(ctrl));
+ ctrl.id = V4L2_CID_MPEG_STREAM_VBI_FMT;
+ ctrl.value = vbistatus;
+ ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+ ctrls.controls = &ctrl;
+ ctrls.count = 1;
+ if (IOCTL(vbi_fd, VIDIOC_S_EXT_CTRLS, &ctrls) != 0) {
+ log(pvrERROR, "cPvrDevice::SetVBImode(): error setting vbi mode (ctrls) on %s (%s), %d:%s",
+ *vbi_devname, CARDNAME[cardname], errno, strerror(errno));
+ close(vbi_fd);
+ return false;
+ }
+ if ((ctrl.value == V4L2_MPEG_STREAM_VBI_FMT_IVTV) && (vbiLinesPerFrame == 625)) {
vbifmt.fmt.sliced.service_set = V4L2_SLICED_VBI_625;
vbifmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
vbifmt.fmt.sliced.reserved[0] = 0;
vbifmt.fmt.sliced.reserved[1] = 0;
- if (IOCTL(v4l2_fd, VIDIOC_S_FMT, &vbifmt) < 0) {
- log(pvrERROR, "cPvrDevice::SetVBImode():error setting vbi mode (fmt) on /dev/video%d (%s), %d:%s",
- number, CARDNAME[cardname], errno, strerror(errno));
- return false;
- }
+ if (IOCTL(vbi_fd, VIDIOC_S_FMT, &vbifmt) < 0) {
+ log(pvrERROR, "cPvrDevice::SetVBImode():error setting vbi mode (fmt) on %s (%s), %d:%s",
+ *vbi_devname, CARDNAME[cardname], errno, strerror(errno));
+ close(vbi_fd);
+ return false;
+ }
}
- }
+ close(vbi_fd);
+ }
return true;
}
@@ -749,7 +775,7 @@ bool cPvrDevice::SetChannelDevice(const cChannel * Channel, bool LiveView)
if (!ParseChannel(Channel, &input, &norm, &LinesPerFrame, &card, &inputType, &apid, &vpid, &tpid))
return false;
- if ((Channel->Number() == CurrentChannel.Number()) && (Channel->Frequency() == CurrentFrequency) && (input == CurrentInput) && (norm == CurrentNorm))
+ if ((Channel->GetChannelID() == CurrentChannel.GetChannelID()) && (Channel->Frequency() == CurrentFrequency) && (input == CurrentInput) && (norm == CurrentNorm))
return true;
log(pvrDEBUG1, "cPvrDevice::SetChannelDevice prepare switch to %d (%s) %3.2fMHz (/dev/video%d = %s)",
Channel->Number(), Channel->Name(), (double)Channel->Frequency() / 1000, number, CARDNAME[cardname]);
@@ -854,13 +880,12 @@ bool cPvrDevice::OpenDvr(void)
case ivtv:
case cx18:
case pvrusb2:
- if (radio_dev < 0)
+ if (*radio_devname == NULL)
return false; //no hardware support.
if (radio_fd < 0) {
- cString devName = cString::sprintf("/dev/radio%d", radio_dev);
- radio_fd = open(devName, O_RDONLY);
+ radio_fd = open(*radio_devname, O_RDONLY);
if (radio_fd < 0) {
- log(pvrERROR, "Error opening FM radio device %s: %s", *devName, strerror(errno));
+ log(pvrERROR, "Error opening FM radio device %s: %s", *radio_devname, strerror(errno));
return false;
}
if (driver == pvrusb2)
@@ -900,7 +925,6 @@ bool cPvrDevice::OpenDvr(void)
} //end: switch (newInputType)
CurrentInputType = newInputType;
ChannelSettingsDone = true;
- FirstChannelSwitch = false;
} //end: if ((!ChannelSettingsDone)
if (CurrentInputType == eTelevision)
SetVBImode(newLinesPerFrame, PvrSetup.SliceVBI ? V4L2_MPEG_STREAM_VBI_FMT_IVTV : V4L2_MPEG_STREAM_VBI_FMT_NONE);
@@ -1021,6 +1045,21 @@ int cPvrDevice::SignalQuality(void) const
return -1;
}
+const cChannel *cPvrDevice::GetCurrentlyTunedTransponder(void) const
+{
+ return &CurrentChannel;
+}
+
+bool cPvrDevice::IsTunedToTransponder(const cChannel *Channel) const
+{
+ return CurrentChannel.GetChannelID() == Channel->GetChannelID();
+}
+
+bool cPvrDevice::MaySwitchTransponder(const cChannel *Channel) const
+{
+ return CurrentChannel.GetChannelID() == Channel->GetChannelID();
+}
+
bool cPvrDevice::ProvidesChannel(const cChannel *Channel, int Priority, bool *NeedsDetachReceivers) const
{
bool result = false;
@@ -1071,7 +1110,7 @@ bool cPvrDevice::ProvidesChannel(const cChannel *Channel, int Priority, bool *Ne
}
}
if (inputType == eRadio) {
- if (radio_dev < 0) {
+ if (*radio_devname == NULL) {
log(pvrDEBUG1, "cPvrDevice::ProvidesChannel: /dev/video%d (%s) has no radio", number, CARDNAME[cardname]);
return false;
}
diff --git a/device.h b/device.h
index f2f720a..fecfade 100644
--- a/device.h
+++ b/device.h
@@ -73,7 +73,7 @@ private:
int radio_fd;
int v4l2_dev;
int mpeg_dev;
- int radio_dev;
+ cString radio_devname;
int inputs[12];
int numInputs;
int vpid;
@@ -97,6 +97,7 @@ private:
eEncState EncoderState;
int driver_apiversion;
bool SupportsSlicedVBI;
+ cString vbi_devname;
bool hasDecoder;
bool hasTuner;
int streamType;
@@ -105,7 +106,6 @@ private:
bool isClosing;
bool readThreadRunning;
bool ChannelSettingsDone;
- bool FirstChannelSwitch;
bool pvrusb2_ready;
eV4l2Driver driver;
eV4l2CardName cardname;
@@ -135,6 +135,9 @@ public:
virtual int NumProvidedSystems(void) const;
virtual int SignalStrength(void) const;
virtual int SignalQuality(void) const;
+ virtual const cChannel *GetCurrentlyTunedTransponder(void) const;
+ virtual bool IsTunedToTransponder(const cChannel *Channel) const;
+ virtual bool MaySwitchTransponder(const cChannel *Channel) const;
bool ParseChannel(const cChannel *Channel, int *input, uint64_t *norm, int *LinesPerFrame, int *card,
eInputType *inputType, int *apid, int *vpid, int *tpid) const;
int ReOpen(void);
diff --git a/pvrinput.c b/pvrinput.c
index 4e74d55..b001c85 100644
--- a/pvrinput.c
+++ b/pvrinput.c
@@ -6,7 +6,7 @@
#endif
#endif
-static const char *VERSION = "2013-01-23";
+static const char *VERSION = "2014-01-11";
static const char *DESCRIPTION = tr("use Hauppauge PVR as input device");
static const char *MAINMENUENTRY = tr("PVR picture settings");
diff --git a/udev.c b/udev.c
new file mode 100644
index 0000000..dbd14fc
--- /dev/null
+++ b/udev.c
@@ -0,0 +1,236 @@
+#include "udev.h"
+#include <linux/stddef.h>
+
+// --- cUdevListEntry --------------------------------------------------------
+
+pvrinput::cUdevListEntry::cUdevListEntry(struct udev_list_entry *ListEntry)
+:listEntry(ListEntry)
+{
+}
+
+pvrinput::cUdevListEntry::~cUdevListEntry(void)
+{
+}
+
+pvrinput::cUdevListEntry *pvrinput::cUdevListEntry::GetNext(void) const
+{
+ if (listEntry == NULL)
+ return NULL;
+ struct udev_list_entry *next = udev_list_entry_get_next(listEntry);
+ if (next == NULL)
+ return NULL;
+ return new cUdevListEntry(next);
+}
+
+const char *pvrinput::cUdevListEntry::GetName(void) const
+{
+ if (listEntry == NULL)
+ return NULL;
+ return udev_list_entry_get_name(listEntry);
+}
+
+const char *pvrinput::cUdevListEntry::GetValue(void) const
+{
+ if (listEntry == NULL)
+ return NULL;
+ return udev_list_entry_get_value(listEntry);
+}
+
+// --- cUdevDevice -----------------------------------------------------------
+
+pvrinput::cUdevDevice::cUdevDevice(udev_device *Device, bool DoUnref)
+:device(Device)
+,doUnref(DoUnref)
+{
+}
+
+pvrinput::cUdevDevice::~cUdevDevice(void)
+{
+ if (doUnref && device)
+ udev_device_unref(device);
+}
+
+int pvrinput::cUdevDevice::Compare(const cListObject &ListObject) const
+{
+ const char *n1 = GetDevnode();
+ const char *n2 = ((cUdevDevice*)&ListObject)->GetDevnode();
+ if ((n1 != NULL) && (n2 != NULL))
+ return strcmp(n1, n2);
+ return 0;
+}
+
+const char *pvrinput::cUdevDevice::GetAction(void) const
+{
+ if (device == NULL)
+ return NULL;
+ return udev_device_get_action(device);
+}
+
+pvrinput::cUdevListEntry *pvrinput::cUdevDevice::GetDevlinksList(void) const
+{
+ if (device == NULL)
+ return NULL;
+ struct udev_list_entry *listEntry = udev_device_get_devlinks_list_entry(device);
+ if (listEntry == NULL)
+ return NULL;
+ return new cUdevListEntry(listEntry);
+}
+
+const char *pvrinput::cUdevDevice::GetDevnode(void) const
+{
+ if (device == NULL)
+ return false;
+ return udev_device_get_devnode(device);
+}
+
+const char *pvrinput::cUdevDevice::GetDevpath(void) const
+{
+ if (device == NULL)
+ return false;
+ return udev_device_get_devpath(device);
+}
+
+pvrinput::cUdevDevice *pvrinput::cUdevDevice::GetParent(void) const
+{
+ if (device == NULL)
+ return NULL;
+ struct udev_device *parent = udev_device_get_parent(device);
+ if (parent == NULL)
+ return NULL;
+ return new cUdevDevice(parent, false);
+}
+
+const char *pvrinput::cUdevDevice::GetPropertyValue(const char *Key) const
+{
+ if (device == NULL)
+ return false;
+ return udev_device_get_property_value(device, Key);
+}
+
+const char *pvrinput::cUdevDevice::GetSubsystem(void) const
+{
+ if (device == NULL)
+ return false;
+ return udev_device_get_subsystem(device);
+}
+
+const char *pvrinput::cUdevDevice::GetSysname(void) const
+{
+ if (device == NULL)
+ return false;
+ return udev_device_get_sysname(device);
+}
+
+const char *pvrinput::cUdevDevice::GetSyspath(void) const
+{
+ if (device == NULL)
+ return false;
+ return udev_device_get_syspath(device);
+}
+
+// --- cUdev -----------------------------------------------------------------
+
+cMutex pvrinput::cUdev::udev_mutex;
+int pvrinput::cUdev::udev_refcount = 0;
+struct udev *pvrinput::cUdev::udev = NULL;
+
+struct udev *pvrinput::cUdev::Init(void)
+{
+ udev_mutex.Lock();
+ if (udev == NULL)
+ udev = udev_new();
+ else
+ udev_ref(udev);
+ udev_refcount++;
+ udev_mutex.Unlock();
+ return udev;
+}
+
+void pvrinput::cUdev::Free(void)
+{
+ udev_mutex.Lock();
+ if (udev_refcount <= 0)
+ esyslog("udev: don't call cUdev::Free before cUdev::Init!");
+ else {
+ udev_refcount--;
+ udev_unref(udev);
+ if (udev_refcount <= 0)
+ udev = NULL;
+ }
+ udev_mutex.Unlock();
+}
+
+pvrinput::cUdevDevice *pvrinput::cUdev::GetDeviceFromDevName(const char *DevName)
+{
+ if (DevName == NULL)
+ return NULL;
+ struct stat statbuf;
+ if (stat(DevName, &statbuf) < 0)
+ return NULL;
+ char type;
+ if (S_ISBLK(statbuf.st_mode))
+ type = 'b';
+ else if (S_ISCHR(statbuf.st_mode))
+ type = 'c';
+ else
+ return NULL;
+ udev_device *dev = udev_device_new_from_devnum(udev, type, statbuf.st_rdev);
+ if (dev == NULL)
+ return NULL;
+ return new cUdevDevice(dev);
+}
+
+pvrinput::cUdevDevice *pvrinput::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<pvrinput::cUdevDevice> *pvrinput::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("udev: 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("udev: 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("udev: can't scan for devices: %d", rc);
+ goto unref;
+ }
+ l = udev_enumerate_get_list_entry(e);
+ if (l == NULL) {
+ isyslog("udev: no devices found for %s/%s=%s", Subsystem, Property, Value);
+ 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
new file mode 100644
index 0000000..9943541
--- /dev/null
+++ b/udev.h
@@ -0,0 +1,56 @@
+#ifndef __PVRINPUT_UDEV_H
+#define __PVRINPUT_UDEV_H
+
+#include <libudev.h>
+
+#include <vdr/tools.h>
+#include <vdr/thread.h>
+
+namespace pvrinput {
+ class cUdevListEntry {
+ private:
+ struct udev_list_entry *listEntry;
+ public:
+ cUdevListEntry(struct udev_list_entry *ListEntry);
+ virtual ~cUdevListEntry(void);
+
+ cUdevListEntry *GetNext(void) const;
+ const char *GetName(void) const;
+ const char *GetValue(void) const;
+ };
+
+ class cUdevDevice : public cListObject {
+ private:
+ struct udev_device *device;
+ bool doUnref;
+ public:
+ cUdevDevice(udev_device *Device, bool DoUnref = true);
+ virtual ~cUdevDevice(void);
+ virtual int Compare(const cListObject &ListObject) const;
+
+ const char *GetAction(void) const;
+ cUdevListEntry *GetDevlinksList(void) const;
+ const char *GetDevnode(void) const;
+ const char *GetDevpath(void) const;
+ cUdevDevice *GetParent(void) const;
+ const char *GetPropertyValue(const char *Key) const;
+ const char *GetSubsystem(void) const;
+ const char *GetSysname(void) const;
+ const char *GetSyspath(void) const;
+ };
+
+ class cUdev {
+ private:
+ static cMutex udev_mutex;
+ static int udev_refcount; // newer libudev does this on its own
+ static struct udev *udev;
+ 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 // __PVRINPUT_UDEV_H
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-vdr-dvb/vdr-plugin-pvrinput.git
More information about the pkg-vdr-dvb-changes
mailing list