简体   繁体   中英

Get unique serial number of USB device mounted to /dev folder

I attach 2 webcam to computer and it was listed in /dev folder: /dev/video0; /dev/video1.

Can you help me write C code to get serial number of webcam with input: /dev/video[0;1]

Just ran into this same problem and it took a bit to find the solution. Any solution which starts with "just use lsusb" is incorrect. You can figure out the devices serial, but none of the extra information it provides help you determine which /dev/video it links to.

Solution:

/bin/udevadm info --name=/dev/video1 | grep SERIAL_SHORT

Output:

E: ID_SERIAL_SHORT=256DEC57

Based on the hint of using udevadm and the tutorial from http://www.signal11.us/oss/udev/ I got below code to get the serial info of my webcam.

#include "stdio.h"
#include <libudev.h>

int main(int argc, char **argv)
{
  struct udev *udev;
  struct udev_device *dev;
  struct udev_enumerate *enumerate;
  struct udev_list_entry *list, *node;
  const char *path;

  udev = udev_new();
  if (!udev) {
    printf("can not create udev");
    return 0;
  }

  enumerate = udev_enumerate_new(udev);
  udev_enumerate_add_match_subsystem(enumerate, "video4linux");
  udev_enumerate_scan_devices(enumerate);

  list = udev_enumerate_get_list_entry(enumerate);
  udev_list_entry_foreach(node, list) {
    path = udev_list_entry_get_name(node);
    dev = udev_device_new_from_syspath(udev, path);

    printf("Printing serial for %s\n", path);
    printf("ID_SERIAL=%s\n",
        udev_device_get_property_value(dev, "ID_SERIAL"));
    printf("ID_SERIAL_SHORT=%s\n",
        udev_device_get_property_value(dev, "ID_SERIAL_SHORT"));

    udev_device_unref(dev);
  }
  return 0;
}

You can use lsusb , but you need to add verbose flag and make sure you use sudo with it, otherwise the serial will be incorrect.

sudo lsusb -v

If that is too verbose, then run lsusb to get the device id:

$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 012: ID 1ab1:0e11 Rigol Technologies
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Then run lsusb with device flag and grep the serial number.

So for the serial number of Rigol device:

$ sudo lsusb -s 012 -v|grep -i iserial
  iSerial                 3 DP8C221100000

Playing around with libusb , it looks like there's a standard getSerialNumber() method. Unfortunately, not all USB devices implement this. I have a couple cheap $4 webcams that return None for it. These interfaces expose other metadata, like VendorID and ProductID, which I've seen some code try and use as a unique identifier, but it's not guaranteed to be unique, especially if you have multiple devices of the same make and model.

But assuming you get a serial number for your device, the next problem is figuring out which /dev/videoN file it corresponds to. I have an old version of libusb installed, so I couldn't get the method working that returned the full sysfs path of the USB device, so instead I scrapped the output from hwinfo . I extracted all the chunks corresponding to cameras, and then from those I extracted the piece that looked like:

SysFS BusID: 1-1.2:1.0

USB devices actually form a complicated tree, and that BusID encodes where the device is located in that tree.

You can then take that BusID to find where the device lives in the filesystem as well as the video path, which should be at:

/sys/bus/usb/devices/<BusID>/video4linux/

That's a directory, and inside it you'll find a videoN file matching one in /dev.

Looking at lsusb you find out that it uses libusb , it has many functions, notably for usb device handling and enumeration . libudev might be relevant too.

Alternatively, popen the lsusb command...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM