Project

General

Profile

udev-plugin

Technical documentation
01/20/2011

UDEV  [1294879658.960734] add      /devices/pci0000:00/0000:00:08.0/video4linux/video0 (video4linux)
UDEV_LOG=3
ACTION=add
DEVPATH=/devices/pci0000:00/0000:00:08.0/video4linux/video0
SUBSYSTEM=video4linux
DEVNAME=/dev/video0
SEQNUM=1380
ID_V4L_VERSION=2
ID_V4L_PRODUCT=Hauppauge WinTV PVR-350
ID_V4L_CAPABILITIES=:capture:video_output:audio:tuner:radio:
ID_PATH=pci-0000:00:08.0
ACL_MANAGE=1
MAJOR=81
MINOR=0
DEVLINKS=/dev/char/81:0 /dev/v4l/by-path/pci-0000:00:08.0-video-index0
UDEV  [1294879659.237625] add      /devices/pci0000:00/0000:00:09.0/dvb/dvb0.frontend0 (dvb)
UDEV_LOG=3
ACTION=add
DEVPATH=/devices/pci0000:00/0000:00:09.0/dvb/dvb0.frontend0
SUBSYSTEM=dvb
DEVNAME=/dev/dvb/adapter0/frontend0
DVB_ADAPTER_NUM=0
DVB_DEVICE_TYPE=frontend
DVB_DEVICE_NUM=0
SEQNUM=1396
ACL_MANAGE=1
MAJOR=212
MINOR=3
DEVLINKS=/dev/char/212:3
/*******************************************
 libudev example.

 This example prints out properties of
 each of the hidraw devices. It then
 creates a monitor which will report when
 hidraw devices are connected or removed
 from the system.

 This code is meant to be a teaching
 resource. It can be used for anyone for
 any reason, including embedding into
 a commercial product.

 The document describing this file, and
 updated versions can be found at:
    http://www.signal11.us/oss/udev/

 Alan Ott
 Signal 11 Software
 2010-05-22 - Initial Revision
 2010-05-27 - Monitoring initializaion
              moved to before enumeration.
*******************************************/

#include <libudev.h>
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <unistd.h>

int main (void)
{
    struct udev *udev;
    struct udev_enumerate *enumerate;
    struct udev_list_entry *devices, *dev_list_entry;
    struct udev_device *dev;

       struct udev_monitor *mon;
    int fd;

    /* Create the udev object */
    udev = udev_new();
    if (!udev) {
        printf("Can't create udev\n");
        exit(1);
    }

    /* This section sets up a monitor which will report events when
       devices attached to the system change.  Events include "add",
       "remove", "change", "online", and "offline".

       This section sets up and starts the monitoring. Events are
       polled for (and delivered) later in the file.

       It is important that the monitor be set up before the call to
       udev_enumerate_scan_devices() so that events (and devices) are
       not missed.  For example, if enumeration happened first, there
       would be no event generated for a device which was attached after
       enumeration but before monitoring began.

       Note that a filter is added so that we only get events for
       "hidraw" devices. */

    /* Set up a monitor to monitor hidraw devices */
    mon = udev_monitor_new_from_netlink(udev, "udev");
    udev_monitor_filter_add_match_subsystem_devtype(mon, "hidraw", NULL);
    udev_monitor_enable_receiving(mon);
    /* Get the file descriptor (fd) for the monitor.
       This fd will get passed to select() */
    fd = udev_monitor_get_fd(mon);

    /* Create a list of the devices in the 'hidraw' subsystem. */
    enumerate = udev_enumerate_new(udev);
    udev_enumerate_add_match_subsystem(enumerate, "hidraw");
    udev_enumerate_scan_devices(enumerate);
    devices = udev_enumerate_get_list_entry(enumerate);
    /* For each item enumerated, print out its information.
       udev_list_entry_foreach is a macro which expands to
       a loop. The loop will be executed for each member in
       devices, setting dev_list_entry to a list entry
       which contains the device's path in /sys. */
    udev_list_entry_foreach(dev_list_entry, devices) {
        const char *path;

        /* Get the filename of the /sys entry for the device
           and create a udev_device object (dev) representing it */
        path = udev_list_entry_get_name(dev_list_entry);
        dev = udev_device_new_from_syspath(udev, path);

        /* usb_device_get_devnode() returns the path to the device node
           itself in /dev. */
        printf("Device Node Path: %s\n", udev_device_get_devnode(dev));

        /* The device pointed to by dev contains information about
           the hidraw device. In order to get information about the
           USB device, get the parent device with the
           subsystem/devtype pair of "usb"/"usb_device". This will
           be several levels up the tree, but the function will find
           it.*/
        dev = udev_device_get_parent_with_subsystem_devtype(
               dev,
               "usb",
               "usb_device");
        if (!dev) {
            printf("Unable to find parent usb device.");
            exit(1);
        }

        /* From here, we can call get_sysattr_value() for each file
           in the device's /sys entry. The strings passed into these
           functions (idProduct, idVendor, serial, etc.) correspond
           directly to the files in the /sys directory which
           represents the USB device. Note that USB strings are
           Unicode, UCS2 encoded, but the strings returned from
           udev_device_get_sysattr_value() are UTF-8 encoded. */
        printf("  VID/PID: %s %s\n",
                udev_device_get_sysattr_value(dev,"idVendor"),
                udev_device_get_sysattr_value(dev, "idProduct"));
        printf("  %s\n  %s\n",
                udev_device_get_sysattr_value(dev,"manufacturer"),
                udev_device_get_sysattr_value(dev,"product"));
        printf("  serial: %s\n",
                 udev_device_get_sysattr_value(dev, "serial"));
        udev_device_unref(dev);
    }
    /* Free the enumerator object */
    udev_enumerate_unref(enumerate);

    /* Begin polling for udev events. Events occur when devices
       attached to the system are added, removed, or change state. 
       udev_monitor_receive_device() will return a device
       object representing the device which changed and what type of
       change occured.

       The select() system call is used to ensure that the call to
       udev_monitor_receive_device() will not block.

       The monitor was set up earler in this file, and monitoring is
       already underway.

       This section will run continuously, calling usleep() at the end
       of each pass. This is to demonstrate how to use a udev_monitor
       in a non-blocking way. */
    while (1) {
        /* Set up the call to select(). In this case, select() will
           only operate on a single file descriptor, the one
           associated with our udev_monitor. Note that the timeval
           object is set to 0, which will cause select() to not
           block. */
        fd_set fds;
        struct timeval tv;
        int ret;

        FD_ZERO(&fds);
        FD_SET(fd, &fds);
        tv.tv_sec = 0;
        tv.tv_usec = 0;

        ret = select(fd+1, &fds, NULL, NULL, &tv);

        /* Check if our file descriptor has received data. */
        if (ret > 0 && FD_ISSET(fd, &fds)) {
            printf("\nselect() says there should be data\n");

            /* Make the call to receive the device.
               select() ensured that this will not block. */
            dev = udev_monitor_receive_device(mon);
            if (dev) {
                printf("Got Device\n");
                printf("   Node: %s\n", udev_device_get_devnode(dev));
                printf("   Subsystem: %s\n", udev_device_get_subsystem(dev));
                printf("   Devtype: %s\n", udev_device_get_devtype(dev));

                printf("   Action: %s\n", udev_device_get_action(dev));
                udev_device_unref(dev);
            }
            else {
                printf("No Device from receive_device(). An error occured.\n");
            }                    
        }
        usleep(250*1000);
        printf(".");
        fflush(stdout);
    }

    udev_unref(udev);

    return 0;       
}
.......................
select() says there should be data
Got Device
   Node: /dev/bus/usb/001/007
   Subsystem: usb
   Devtype: usb_device
   Action: add
prop{UDEV_LOG} = 3
prop{ACTION} = add
prop{DEVPATH} = /devices/pci0000:00/0000:00:1d.7/usb1/1-1
prop{SUBSYSTEM} = usb
prop{DEVNAME} = /dev/bus/usb/001/007
prop{DEVTYPE} = usb_device
prop{PRODUCT} = 7ca/850a/101
prop{TYPE} = 0/0/0
prop{BUSNUM} = 001
prop{DEVNUM} = 007
prop{SEQNUM} = 1666
prop{ID_VENDOR} = AVerMedia
prop{ID_VENDOR_ENC} = AVerMedia
prop{ID_VENDOR_ID} = 07ca
prop{ID_MODEL} = A850_DVBT
prop{ID_MODEL_ENC} = A850\x20DVBT
prop{ID_MODEL_ID} = 850a
prop{ID_REVISION} = 0101
prop{ID_SERIAL} = AVerMedia_A850_DVBT_302471301133000
prop{ID_SERIAL_SHORT} = 302471301133000
prop{ID_BUS} = usb
prop{ID_USB_INTERFACES} = :ff0000:
prop{MAJOR} = 189
prop{MINOR} = 6
prop{DEVLINKS} = /dev/char/189:6
.
select() says there should be data
Got Device
   Node: (null)
   Subsystem: usb
   Devtype: usb_interface
   Action: add
prop{UDEV_LOG} = 3
prop{ACTION} = add
prop{DEVPATH} = /devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0
prop{SUBSYSTEM} = usb
prop{DEVTYPE} = usb_interface
prop{PRODUCT} = 7ca/850a/101
prop{TYPE} = 0/0/0
prop{INTERFACE} = 255/0/0
prop{MODALIAS} = usb:v07CAp850Ad0101dc00dsc00dp00icFFisc00ip00
prop{SEQNUM} = 1667
.
select() says there should be data
Got Device
   Node: /dev/dvb/adapter0/dvr0
   Subsystem: dvb
   Devtype: (null)
   Action: add
prop{UDEV_LOG} = 3
prop{ACTION} = add
prop{DEVPATH} = /devices/pci0000:00/0000:00:1d.7/usb1/1-1/dvb/dvb0.dvr0
prop{SUBSYSTEM} = dvb
prop{DEVNAME} = /dev/dvb/adapter0/dvr0
prop{DVB_ADAPTER_NUM} = 0
prop{DVB_DEVICE_TYPE} = dvr
prop{DVB_DEVICE_NUM} = 0
prop{SEQNUM} = 1672
prop{ACL_MANAGE} = 1
prop{MAJOR} = 212
prop{MINOR} = 1
prop{DEVLINKS} = /dev/char/212:1
.
select() says there should be data
Got Device
   Node: /dev/dvb/adapter0/net0
   Subsystem: dvb
   Devtype: (null)
   Action: add
prop{UDEV_LOG} = 3
prop{ACTION} = add
prop{DEVPATH} = /devices/pci0000:00/0000:00:1d.7/usb1/1-1/dvb/dvb0.net0
prop{SUBSYSTEM} = dvb
prop{DEVNAME} = /dev/dvb/adapter0/net0
prop{DVB_ADAPTER_NUM} = 0
prop{DVB_DEVICE_TYPE} = net
prop{DVB_DEVICE_NUM} = 0
prop{SEQNUM} = 1673
prop{ACL_MANAGE} = 1
prop{MAJOR} = 212
prop{MINOR} = 2
prop{DEVLINKS} = /dev/char/212:2
.
select() says there should be data
Got Device
   Node: /dev/dvb/adapter0/demux0
   Subsystem: dvb
   Devtype: (null)
   Action: add
prop{UDEV_LOG} = 3
prop{ACTION} = add
prop{DEVPATH} = /devices/pci0000:00/0000:00:1d.7/usb1/1-1/dvb/dvb0.demux0
prop{SUBSYSTEM} = dvb
prop{DEVNAME} = /dev/dvb/adapter0/demux0
prop{DVB_ADAPTER_NUM} = 0
prop{DVB_DEVICE_TYPE} = demux
prop{DVB_DEVICE_NUM} = 0
prop{SEQNUM} = 1671
prop{ACL_MANAGE} = 1
prop{MAJOR} = 212
prop{MINOR} = 0
prop{DEVLINKS} = /dev/char/212:0
.
select() says there should be data
Got Device
   Node: /dev/dvb/adapter0/frontend0
   Subsystem: dvb
   Devtype: (null)
   Action: add
prop{UDEV_LOG} = 3
prop{ACTION} = add
prop{DEVPATH} = /devices/pci0000:00/0000:00:1d.7/usb1/1-1/dvb/dvb0.frontend0
prop{SUBSYSTEM} = dvb
prop{DEVNAME} = /dev/dvb/adapter0/frontend0
prop{DVB_ADAPTER_NUM} = 0
prop{DVB_DEVICE_TYPE} = frontend
prop{DVB_DEVICE_NUM} = 0
prop{SEQNUM} = 1675
prop{ACL_MANAGE} = 1
prop{MAJOR} = 212
prop{MINOR} = 3
prop{DEVLINKS} = /dev/char/212:3
...............
select() says there should be data
Got Device
   Node: /dev/dvb/adapter0/frontend0
   Subsystem: dvb
   Devtype: (null)
   Action: remove
prop{UDEV_LOG} = 3
prop{ACTION} = remove
prop{DEVPATH} = /devices/pci0000:00/0000:00:1d.7/usb1/1-1/dvb/dvb0.frontend0
prop{SUBSYSTEM} = dvb
prop{DEVNAME} = /dev/dvb/adapter0/frontend0
prop{DVB_ADAPTER_NUM} = 0
prop{DVB_DEVICE_TYPE} = frontend
prop{DVB_DEVICE_NUM} = 0
prop{SEQNUM} = 1677
prop{ACL_MANAGE} = 1
prop{MAJOR} = 212
prop{MINOR} = 3
prop{DEVLINKS} = /dev/char/212:3
.
select() says there should be data
Got Device
   Node: (null)
   Subsystem: usb
   Devtype: usb_interface
   Action: remove
prop{UDEV_LOG} = 3
prop{ACTION} = remove
prop{DEVPATH} = /devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0
prop{SUBSYSTEM} = usb
prop{DEVTYPE} = usb_interface
prop{PRODUCT} = 7ca/850a/101
prop{TYPE} = 0/0/0
prop{INTERFACE} = 255/0/0
prop{MODALIAS} = usb:v07CAp850Ad0101dc00dsc00dp00icFFisc00ip00
prop{SEQNUM} = 1682
.
select() says there should be data
Got Device
   Node: /dev/dvb/adapter0/dvr0
   Subsystem: dvb
   Devtype: (null)
   Action: remove
prop{UDEV_LOG} = 3
prop{ACTION} = remove
prop{DEVPATH} = /devices/pci0000:00/0000:00:1d.7/usb1/1-1/dvb/dvb0.dvr0
prop{SUBSYSTEM} = dvb
prop{DEVNAME} = /dev/dvb/adapter0/dvr0
prop{DVB_ADAPTER_NUM} = 0
prop{DVB_DEVICE_TYPE} = dvr
prop{DVB_DEVICE_NUM} = 0
prop{SEQNUM} = 1680
prop{ACL_MANAGE} = 1
prop{MAJOR} = 212
prop{MINOR} = 1
prop{DEVLINKS} = /dev/char/212:1
.
select() says there should be data
Got Device
   Node: /dev/dvb/adapter0/demux0
   Subsystem: dvb
   Devtype: (null)
   Action: remove
prop{UDEV_LOG} = 3
prop{ACTION} = remove
prop{DEVPATH} = /devices/pci0000:00/0000:00:1d.7/usb1/1-1/dvb/dvb0.demux0
prop{SUBSYSTEM} = dvb
prop{DEVNAME} = /dev/dvb/adapter0/demux0
prop{DVB_ADAPTER_NUM} = 0
prop{DVB_DEVICE_TYPE} = demux
prop{DVB_DEVICE_NUM} = 0
prop{SEQNUM} = 1679
prop{ACL_MANAGE} = 1
prop{MAJOR} = 212
prop{MINOR} = 0
prop{DEVLINKS} = /dev/char/212:0
.
select() says there should be data
Got Device
   Node: /dev/dvb/adapter0/net0
   Subsystem: dvb
   Devtype: (null)
   Action: remove
prop{UDEV_LOG} = 3
prop{ACTION} = remove
prop{DEVPATH} = /devices/pci0000:00/0000:00:1d.7/usb1/1-1/dvb/dvb0.net0
prop{SUBSYSTEM} = dvb
prop{DEVNAME} = /dev/dvb/adapter0/net0
prop{DVB_ADAPTER_NUM} = 0
prop{DVB_DEVICE_TYPE} = net
prop{DVB_DEVICE_NUM} = 0
prop{SEQNUM} = 1678
prop{ACL_MANAGE} = 1
prop{MAJOR} = 212
prop{MINOR} = 2
prop{DEVLINKS} = /dev/char/212:2
.
select() says there should be data
Got Device
   Node: /dev/bus/usb/001/007
   Subsystem: usb
   Devtype: usb_device
   Action: remove
prop{UDEV_LOG} = 3
prop{ACTION} = remove
prop{DEVPATH} = /devices/pci0000:00/0000:00:1d.7/usb1/1-1
prop{SUBSYSTEM} = usb
prop{DEVNAME} = /dev/bus/usb/001/007
prop{DEVTYPE} = usb_device
prop{PRODUCT} = 7ca/850a/101
prop{TYPE} = 0/0/0
prop{BUSNUM} = 001
prop{DEVNUM} = 007
prop{SEQNUM} = 1683
prop{ID_VENDOR} = AVerMedia
prop{ID_VENDOR_ENC} = AVerMedia
prop{ID_VENDOR_ID} = 07ca
prop{ID_MODEL} = A850_DVBT
prop{ID_MODEL_ENC} = A850\x20DVBT
prop{ID_MODEL_ID} = 850a
prop{ID_REVISION} = 0101
prop{ID_SERIAL} = AVerMedia_A850_DVBT_302471301133000
prop{ID_SERIAL_SHORT} = 302471301133000
prop{ID_BUS} = usb
prop{ID_USB_INTERFACES} = :ff0000:
prop{MAJOR} = 189
prop{MINOR} = 6
prop{DEVLINKS} = /dev/char/189:6

Files