Tutorial :How to get USB vendor and product info programmatically on Linux?



Question:

Using udev I have been able to get this information for a certain USB device:

idVendor: 13b1  idProduct: 0018  manufacturer:    product: USB 2.0 Network Adapter ver.2   serial: 00FFFF  

Now I want to get the full strings that are associated with the vendor and product ids. I found that the file /usr/share/misc/usb.ids contains the information that I'm looking for:

13b1  Linksys          000b  WUSB11 v4.0 802.11b Adapter          000d  WUSB54G Wireless Adapter          0011  WUSB54GP v4.0 802.11g Adapter          0018  USB200M 10/100 Ethernet Adapter          001a  HU200TS Wireless Adapter          001e  WUSBF54G 802.11bg          0020  WUSB54GC 802.11g Adapter [ralink rt73]          0023  WUSB54GR          0024  WUSBF54G v1.1 802.11bg  

However, it's not clear to me how I should retrieve this data in my application. Is there an API available or should I just parse the file? If I choose to parse it, then is /usr/share/misc/usb.ids always going to be the correct location?


Solution:1

lsusb command queries information about currently plugged USB devices. You can use its -d option to query a certain vendor/product (but it seems to work only for currently plugged devices):

$ lsusb -d 0e21:0750  Bus 001 Device 005: ID 0e21:0750 Cowon Systems, Inc.  

You can show information for all devices:

$ lsusb  Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub  Bus 001 Device 004: ID 0421:01c7 Nokia Mobile Phones  Bus 001 Device 003: ID 0bda:8187 Realtek Semiconductor Corp. RTL8187 Wireless Adapter  Bus 001 Device 005: ID 0e21:0750 Cowon Systems, Inc.  Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub  Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub  Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub  Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub  Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub  Bus 006 Device 002: ID 046d:c01b Logitech, Inc. MX310 Optical Mouse  Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub  Bus 008 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub  

You can also make it be verbose (lsusb -v) and printing a lot of stuff.

Note that when accessing information about the system in Linux OS, it's much preferred to do it via shell commands (such as lsusb) than to directly parse the system files these commands access.


Solution:2

On my Ubuntu system, the lsusb(1) manpage says that /var/lib/usbutils/usb.ids is the location of the id file; in fact, there are two symlinks, one of which is your /usr/share/misc/usb.ids. I'd trust the actual location before trusting the symlinks:

$ ls -l /usr/share/misc/usb.ids /var/lib/misc/usb.ids /var/lib/usbutils/usb.ids  lrwxrwxrwx 1 root root     25 2010-04-29 18:08 /usr/share/misc/usb.ids -> /var/lib/usbutils/usb.ids  lrwxrwxrwx 1 root root     19 2010-04-29 18:08 /var/lib/misc/usb.ids -> ../usbutils/usb.ids  -rw-r--r-- 1 root root 368377 2009-11-06 09:26 /var/lib/usbutils/usb.ids  


Solution:3

Haven't tried this myself, but libudev's udev_device_get_property_value should be it; it is used in pulseaudio's udev-util.c as udev_device_get_property_value(card, "ID_VENDOR_FROM_DATABASE")).

Here is a small example I just put together, based on udev-util.c - note that I've used an Arduino Duemillanove with FTDI FT232 chip, whose udev path I find using udevadm (see comments in code below), and then I hardcoded it in the below program, udevl.c:

// sudo apt-get install libudev-dev  // build with: gcc -o udevl -ludev -Wall -g udevl.c    #include <stdio.h>    #include <libudev.h>    int main( int argc, char **argv )  {    const char *v;    char t[256];    struct udev *udev;    struct udev_device *card = NULL;      if (!(udev = udev_new())) {        fprintf(stderr, "Failed to allocate udev context.\n");        return -1;    }      // $ lsusb | grep FT232    // Bus 002 Device 002: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC        // $ udevadm info --name=/dev/ttyUSB0 --attribute-walk | grep "looking at device"    // looking at device '/devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2:1.0/ttyUSB0/tty/ttyUSB0'    // (that one is under /sys)    // hardcode that path below:      // udev_get_sys_path(udev) for me: '/sys'    sprintf(t, "%s/devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2:1.0/ttyUSB0/tty/ttyUSB0", udev_get_sys_path(udev));    fprintf(stdout, " path: %s\n", t);      card = udev_device_new_from_syspath(udev, t);    fprintf(stdout, " udev_device: 0x%08X\n", (unsigned int)card);      if ((v = udev_device_get_property_value(card, "ID_MODEL_FROM_DATABASE")) )      fprintf(stdout, "got ID_MODEL_FROM_DATABASE: %s\n", v);    else      fprintf(stdout, "failed getting ID_MODEL_FROM_DATABASE: %s\n", v);      fprintf(stdout, "Done.\n");      if (card)      udev_device_unref(card);      if (udev)      udev_unref(udev);      return 0;  }  

This program (with the Arduino attached) outputs:

$ ./udevl    path: /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2:1.0/ttyUSB0/tty/ttyUSB0   udev_device: 0x09FBF080  got ID_MODEL_FROM_DATABASE: FT232 USB-Serial (UART) IC  Done.  

... and "FT232 USB-Serial (UART) IC" is the right entry for VID:PID 0403:6001 in usb.ids.

Hope this helps,
Cheers!


Solution:4

Your USB device does not need to match vendor and product ids to the actual correct names.

It would be safer to get this info from the device itself with something like libusb or lsusb.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »