Linux / libusb get USB device path

I use libusb to list several USB devices. Now I like to get the "path to the device." I think this is not called usb device-path, because I failed with google.

If I connect a USB device with linux, I get a message in dmesg , here are some examples for such a “device path” with a USB temperature sensor (something like this ):

Directly to the USB port: [68448.099682] generic-usb 0003:0C45:7401.0056: input,hidraw1: USB HID v1.10 Keyboard [RDing TEMPer1V1.2] on usb-0000:00:12.0-1/input0 => 12.0-1

Directly to another port: [68560.853108] generic-usb 0003:0C45:7401.0058: input,hidraw1: USB HID v1.10 Keyboard [RDing TEMPer1V1.2] on usb-0000:00:13.0-1/input0 => 13.0-1

To the usb hub on the first port used: [68600.245809] generic-usb 0003:0C45:7401.005A: input,hidraw1: USB HID v1.10 Keyboard [RDing TEMPer1V1.2] on usb-0000:00:12.2-1.4/input0 = > 12.2-1.4

To another port on the same usb host: [68647.925092] generic-usb 0003:0C45:7401.005C: input,hidraw1: USB HID v1.10 Keyboard [RDing TEMPer1V1.2] on usb-0000:00:12.2-1.3/input0 => 12.2-1.3

Now to the usb node on the usb hub that was used previously: [68740.715518] generic-usb 0003:0C45:7401.005E: input,hidraw1: USB HID v1.10 Keyboard [RDing TEMPer1V1.2] on usb-0000:00:12.2-1.4.4/input0 => 12.2-1.4.4

In short: The kernel message always contains a unique path for the physical location of the USB device (see Bold text before). Is it possible to get this "path" in user space via libusb? I have tried many things with struct usb_bus and struct usb_device , but I have always been unsuccessful.

I need this to identify several of these usb thermometers because they don’t have a unique serial number, and sometimes they just “reconnect” at runtime, so they get different usb identifiers. Therefore, I believe that the only way to identify them is through a physical location.

Thanks for the help,

Best regards Kevin M.

-edit -

I am currently using the following code to search for my USB device:

 usb_dev_handle *find_lvr_winusb() { struct usb_bus *bus; struct usb_device *dev; for (bus = usb_busses; bus; bus = bus->next) { for (dev = bus->devices; dev; dev = dev->next) { if (dev->descriptor.idVendor == VENDOR_ID && dev->descriptor.idProduct == PRODUCT_ID ) { usb_dev_handle *handle; if(debug) { printf("lvr_winusb with Vendor Id: %x and Product Id: %x found.\n", VENDOR_ID, PRODUCT_ID); printf("INFO: %d\n", dev->bus->location); printf("INFO: %d %s\n", bus->location, bus->dirname); } if (!(handle = usb_open(dev))) { printf("Could not open USB device\n"); return NULL; } return handle; } } } return NULL; } 

But with this code, I can’t get a unique identifier for the physical position. bus->location returns an integer (bus-> dirname contains the same thing as a string), which is not unique. I know that usb has a hierarchy, and in dmesg I see this hierarchy path.

With libusb, I can only get the bus identifier (?) And some device identifiers. But they do not help me, because I need to identify two or more of these temperature sensors. The device identifier always changes when the temperature sensor reset is connected (every 5-60 seconds) and the bus identifier is not unique. Unfortunately, the temperature sensor does not have a unique serial identifier.

So, I think the physical path is the only way to identify the device.

Regards Kevin M.

+4
source share
3 answers

Starting with libusb 1.0.12, they introduced libusb_get_port_path (), and in 1.0.16 they replaced it with libusb_get_port_numbers () , which allows you to query the bus topology.

+5
source

Total runtime of the sysfs structure path:

 1-1.3:1.0 |_usb root hub - bus number - 1 |_ port number - 1 of root hub |_port number - 3 of intermediate hub |_current configuration number - 1 |_ current interface number - 0 

More info here

+3
source

Maybe like here .

Just scan all USB devices on all buses. When you find the required VID / PID, this is your device.

Or you can make it simpler: write a udev rule that will create a symbolic link, for example / dev / thermoX, when you attach your device. All you need to do is open the required / dev / thermoX.

0
source

All Articles