Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

linux / libusb get usb device path

I use libusb to enumerate over a few usb-devices. Now i like to get the "device-path". I think it's not called usb device-path, because i was not successful with google.

If i connect a usb-device with linux, i get a message in dmesg, here are a few examples for such a "device-path" with an usb temperature sensor (something like this):

Directly to a 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 a usb hub on the first used port: [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 hub: [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

An now to a usb hub on the usb hub used before: [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

Long story short: The kernel message always contains a unique path for the physical usb device location (see the bold text before). Is it possible to get this "path" in the user space via libusb? I tried many things with struct usb_bus and struct usb_device, but i always was unsuccessfully.

I need this to identify multiple 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 id's. So i think the only way to identify them is via the physical location.

Thanks for the help,

Best Regards Kevin M.

-edit-

Currently i use the following code to search 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 cannot get a unique physical position id. The bus->location returns an integer (bus->dirname contains the same, but as string), which is not unique. I know usb has a hierarchy and in the dmesg i can see this hierarchys path.

With libusb i only can get the bus-id (?) and some device id's. But they don't help me, because i need to identify two or more of these temperature sensors. The device-id always changes when the temperature sensor reset's the connection (every 5 to 60 seconds) and the bus id is not unique. Unfortunately the temperature sensor has no unique serial id.

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

Best regards Kevin M.

like image 398
Kevin Meier Avatar asked Jan 11 '13 14:01

Kevin Meier


People also ask

How do I find my USB ID in Linux?

To find PID & VID on Linux:Run the lsusb command to list details of your connected USB devices. Find your desired USB device in the list to see your PID and VID.

Where are external devices usually located Linux?

In Linux, it is mounted usually under the “/media” directory and can be accessed using the File Manager. However, in some scenarios, your system may not mount the USB drive automatically after you plug it in and you will be required to mount it manually in order to transfer the files between systems.

How do I find the device path in Windows?

Finding the Device Path Parameters using Device ManagerOpen the properties for a USB device and click on the 'Details' tab. Select the 'Device Instance Path' property from the combo box to display the device instance path which shares the components of the device path used for CreateFile().


2 Answers

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

like image 125
ndyer Avatar answered Sep 21 '22 15:09

ndyer


Overall summery 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 information here

like image 20
premal Avatar answered Sep 22 '22 15:09

premal