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 <[email protected]> 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 _______________________________________________ pkg-vdr-dvb-changes mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-vdr-dvb-changes
