Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stable path for multiple USB devices (on LInux)? #405

Open
derekatkins opened this issue Aug 20, 2018 · 8 comments
Open

Stable path for multiple USB devices (on LInux)? #405

derekatkins opened this issue Aug 20, 2018 · 8 comments

Comments

@derekatkins
Copy link

I've got multiple devices that I'm trying to access in a stable manner. They do not provide a serial number or other uniquifying data that I can see. I tried to use the HID path but it looks like that's not a stable number -- each time I remove and re-insert the device (into the same USB port) the HID path changes. Is there some way to access the underlying USB path (which DOES appear to be stable)? E.g.:

[2332915.679529] hid-generic 0003:0416:5020.0005: input,hidraw0: USB HID v1.10 Device [Nuvoton HID Transfer] on usb-0000:00:14.0-4/input0
[2333625.965356] hid-generic 0003:0416:5020.0006: input,hidraw0: USB HID v1.10 Device [Nuvoton HID Transfer] on usb-0000:00:14.0-4/input0
[2336516.928041] hid-generic 0003:0416:5020.0007: input,hidraw0: USB HID v1.10 Device [Nuvoton HID Transfer] on usb-0000:00:14.0-4/input0
[2337168.447530] hid-generic 0003:0416:5020.0008: input,hidraw0: USB HID v1.10 Device [Nuvoton HID Transfer] on usb-0000:00:14.0-1/input0

I had the first device on usb-0000:00:14.0-4 which I removed and reinserted, and then I removed/reinserted the second device on usb-0000:00:14.0-1. Unfortunately I don't see any way to access this information from hidapi. Worse, the hid path changes on every insert (see the 0005, 0006, 0007, 0008? That gets reflected in an increasing hid path).

So without a serial number, what's the path (pun intended) to a stable reference to a HID device? The full dmesg for an insertion looks like:

[2336516.733051] usb 1-4: new full-speed USB device number 16 using xhci_hcd
[2336516.919895] usb 1-4: New USB device found, idVendor=0416, idProduct=5020
[2336516.919896] usb 1-4: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[2336516.919897] usb 1-4: Product: HID Transfer
[2336516.919898] usb 1-4: Manufacturer: Nuvoton
[2336516.927801] input: Nuvoton HID Transfer as /devices/pci0000:00/0000:00:14.0/usb1/1-4/1-4:1.0/0003:0416:5020.0007/input/input24

Thanks.

@todbot
Copy link

todbot commented Aug 20, 2018

Hi,

You may find that if you recompile hidapi to use the libusb driver instead of the hidraw driver, the path property you get back could be constant enough for you.

Also, you say you don't have a serial number, but is there something in your device's protocol where you can write a non-volatile bit of data you could use as an ID?

@derekatkins
Copy link
Author

HI,

You may find that if you recompile hidapi to use the libusb driver instead of the hidraw driver, the path property you get back could be constant enough for you.

This is on Fedora. I am not (yet) building from source. It does depend on libusb, but I haven't checked to see how it's built, nor have I tried to rebuild it, yet.

Also, you say you don't have a serial number, but is there something in your device's protocol where you can write a non-volatile bit of data you could use as an ID?

Not that I'm aware of. It's a Sainsmart-16 relay board. The protocol appears to be pretty simple, to get and set 16 bits of data (to turn on and off each of the 16 relays). I know of no NV data, but the docs are pretty thin as-is.

@todbot
Copy link

todbot commented Aug 21, 2018

Here's a quick hidapi test program you can try:
https://gist.github.com/todbot/12f4a26e840e3229a04aeac883fae332
Compile the libusb version and run it. You should see your devices listed with their paths listed. These paths are based on the USB port so shouldn't change on replug.

@todbot
Copy link

todbot commented Aug 21, 2018

Apologies, I am wrong. Disregard the above comment. I really thought the path on Linux libusb was consistent across replugs but I'm seeing it increment now as you originally describe.

@derekatkins
Copy link
Author

I know that the kernel has the information about what port the device is plugged into. It's printed clearly in the dmesg log, so the information is available -- it's just a question of reading it (or using it).
I wonder if I can use a udev rule to "stabilize" the HID Path for the device?

@derekatkins
Copy link
Author

@todbot -- it looks like libusb_get_port_numbers(), possibly combined with libusb_get_bus_number(), will get me a stable identifier. I modified the libusb hid_enumerate to print out the bus/portnum-list and the results are 100% stable across plug-ins, even with the "path" changes on each plug-in. Unfortunately it does not appear that hidapi gives me access to the underlying libusb_dev.

@derekatkins
Copy link
Author

For the record, if I use the linux/hidraw version I could easily combine it with a udev rule to stabilize the path.

I think the problem here is hidapi using libusb_get_device_address() in make_path() instead of using libusb_get_port_numbers() and building the path that way. The address clearly changes over time (at every re-plug).

@derekatkins
Copy link
Author

C.f. #406

erikolofsson pushed a commit to Malterlib/hidapi that referenced this issue May 14, 2022
- explicitly add Iconv as a dependent library;
- check if iconv requires pointer-to-const as input (introduce ICONV_CONST check);
- NetBSD CI (has external Iconv library implementation that uses all of the above);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants