Linux Hotplug: connection-callback implementation for libusb backend #645
No reviewers
Labels
No labels
3rdparty
Android
API
Author does not respond
bsd
bug
build system/CI
ci-virtual-device
CMake
Contributions Welcome
Core
dependencies
device-specific
documentation
don't_merge
duplicate
enhancement
Example
Haiku
hidraw
hotplug
info required
invalid
libusb
macOS
Misc
Not an issue
question
Release
Test
Test GUI
Windows
wontfix
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gh-libusb/hidapi!645
Loading…
Reference in a new issue
No description provided.
Delete branch "connection-callback-libusb"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Before looking into this - lets finish with #646 - probably some comments are applicable here as well
Agreed. Going to squash all the commits into one so it's a little less messy, then will try to check for similar macro check related issues.
For now, my biggest concern is the
match_libusb_to_infofunction. It is the only way I found to match the devices, yet it itself relies on some features that may be unavailable for a device that has already left.Attempted to adjust the code-style to the current style of the library, it only ended up messing some other locations where indentation is done with both tabs AND spaces :(
Added some changes to list management during device removal.
Ubuntu-cmake and Arch Linux github action build are still failing.
Ubuntu-cmake and Arch Linux github action build are still failing.
Interesting. I will see to it right away.
UPD: It is just some warnings for unused parameters, treated as errors. Easy to fix.
Addressed the issue, should be fine now
Not so sure how to re-run the github actions as there were build error previously.
However, previous Windows CMake error has nothing to do with this PR. So it should still be okay.
I will test this under Linux later.
This may be a bit tricky to test under Linux as we need to detach the kernel HID driver in order to use hidapi-libusb.
BTW, libusb currently only supports hotplug under Linux and macOS. There is a PR for Windows.
FreeBSD has its own libusb implementation and it supports hotplug. I will also test this PR under FreeBSD.
https://man.freebsd.org/cgi/man.cgi?query=libusb
I just rebased this onto the updated
connection-callbackbranch. There were quite a few significant conflicts, there might even be compilation errors, will ensure it builds later today.@k1-801
It does not seem to work under Ubuntu Linux 20.04.
No issues with PR #647 with the same system (Acer Laptop, dual boot Windows 11 and Ubuntu 20.04).
I have tried to detached kernel usbhid driver (same results if I do not detach the kernel driver).
https://lwn.net/Articles/143397/
Okay, thank you for the info, I'll see what I can do. Keeping as a draft until I have tested it myself.
Thanks.
FYI: libusb hotplug works fine.
It took me some time to track the issue, but I found it.
Turns out that, despite the documentation foe libusb NEVER explicitly stating so, the hotplug system actually does NOT start it's own background thread and requires a call to any variationthis is actually described in the documentation, but the explanation is not super clear.libusb_handle_eventsIn turn, calling
libusb_handle_eventsin a seprate thread, according to the documentation, may or may not cause issues with theread threadand it's own call tolibusb_handle_events. I don't really understand how multipleread_thread's for multiple devices don't interfere with one another.The way I see it, the best solution here would be to have a separate libusb context dedicated to the hotplug events. Will test and report my findings in 2 hours.
I managed to get the events going (there is some debug output in the printout below that will not be present in the real tests), BUT, the device info is always empty. So far, it's definitely an impovement.
I don't know why the fields are empty or how to fix them,
get_usb_stringkeeps returning NULL. But, as long as we have the events firing, as long as the paths are not empty and as long as we still get VID/PID pairs, I assume the patch does it's job.Maybe it is related to the fact that I used a second libusb context, but the documentation states they should not interfere with one another, and the processing code never mentions the context at all.
UPD: every call to
libusb_get_string_descriptorreturns error -6, which is LIBUSB_ERROR_BUSY, and that's why no strings are returned.UPD2: https://github.com/libusb/libusb/issues/408 - it is impossible to retrieve any strings while in the libusb's hotplug callback. Will think of a workaround, but this is really becoming complicated. I can imagine it running two threads, one for libusb running it's event processing, in which the events would be put on a queue. The other would be actually processing the queue and calling the callbacks registered in hidapi.
Handle 1: New device is connected: 3-3:1.1.
type: 04d9 fc38
serial_number: (null)
Manufacturer: (null)
Product: USB Gaming Mouse
Release: 110
Interface: 1
Usage (page): 0x0 (0x0)
Handle 1: New device is connected: 3-3:1.2.
type: 04d9 fc38
serial_number: (null)
Manufacturer: (null)
Product: USB Gaming Mouse
Release: 110
Interface: 2
Usage (page): 0x0 (0x0)
libusb callback fired! Event: out
Handle 1: Device was disconnected: 3-3:1.0.
type: 04d9 fc38
serial_number: (null)
Manufacturer: (null)
Product: USB Gaming Mouse
Release: 110
Interface: 0
Usage (page): 0x0 (0x0)
Handle 1: Device was disconnected: 3-3:1.1.
type: 04d9 fc38
serial_number: (null)
Manufacturer: (null)
Product: USB Gaming Mouse
Release: 110
Interface: 1
Usage (page): 0x0 (0x0)
Handle 1: Device was disconnected: 3-3:1.2.
type: 04d9 fc38
serial_number: (null)
Manufacturer: (null)
Product: USB Gaming Mouse
Release: 110
Interface: 2
Usage (page): 0x0 (0x0)
libusb callback fired! Event: in
Handle 1: New device is connected: 3-3:1.0.
type: 04d9 fc38
serial_number: (null)
Manufacturer: (null)
Product: (null)
Release: 110
Interface: 0
Usage (page): 0x0 (0x0)
Handle 1: New device is connected: 3-3:1.1.
type: 04d9 fc38
serial_number: (null)
Manufacturer: (null)
Product: (null)
Release: 110
Interface: 1
Usage (page): 0x0 (0x0)
Handle 1: New device is connected: 3-3:1.2.
type: 04d9 fc38
serial_number: (null)
Manufacturer: (null)
Product: (null)
Release: 110
Interface: 2
Usage (page): 0x0 (0x0)
libusb callback fired! Event: out
Handle 1: Device was disconnected: 3-3:1.0.
type: 04d9 fc38
serial_number: (null)
Manufacturer: (null)
Product: (null)
Release: 110
Interface: 0
Usage (page): 0x0 (0x0)
Handle 1: Device was disconnected: 3-3:1.1.
type: 04d9 fc38
serial_number: (null)
Manufacturer: (null)
Product: (null)
Release: 110
Interface: 1
Usage (page): 0x0 (0x0)
Handle 1: Device was disconnected: 3-3:1.2.
type: 04d9 fc38
serial_number: (null)
Manufacturer: (null)
Product: (null)
Release: 110
Interface: 2
Usage (page): 0x0 (0x0)
libusb callback fired! Event: in
Handle 1: New device is connected: 3-2:1.0.
type: 04d9 fc38
serial_number: (null)
Manufacturer: (null)
Product: (null)
Release: 110
Interface: 0
Usage (page): 0x0 (0x0)
Handle 1: New device is connected: 3-2:1.1.
type: 04d9 fc38
serial_number: (null)
Manufacturer: (null)
Product: (null)
Release: 110
Interface: 1
Usage (page): 0x0 (0x0)
Handle 1: New device is connected: 3-2:1.2.
type: 04d9 fc38
serial_number: (null)
Manufacturer: (null)
Product: (null)
Release: 110
Interface: 2
Usage (page): 0x0 (0x0)
Implemented a two-thread queue processing. Will push in a moment, needs some indentation cleanup.
Handle 1: New device is connected: 3-2:1.1.
type: 04d9 fc38
serial_number: (null)
Manufacturer: (null)
Product: USB Gaming Mouse
Release: 110
Interface: 1
Usage (page): 0x0 (0x0)
Handle 1: New device is connected: 3-2:1.2.
type: 04d9 fc38
serial_number: (null)
Manufacturer: (null)
Product: USB Gaming Mouse
Release: 110
Interface: 2
Usage (page): 0x0 (0x0)
Handle 1: Device was disconnected: 3-2:1.0.
type: 04d9 fc38
serial_number: (null)
Manufacturer: (null)
Product: USB Gaming Mouse
Release: 110
Interface: 0
Usage (page): 0x0 (0x0)
Handle 1: Device was disconnected: 3-2:1.1.
type: 04d9 fc38
serial_number: (null)
Manufacturer: (null)
Product: USB Gaming Mouse
Release: 110
Interface: 1
Usage (page): 0x0 (0x0)
Handle 1: Device was disconnected: 3-2:1.2.
type: 04d9 fc38
serial_number: (null)
Manufacturer: (null)
Product: USB Gaming Mouse
Release: 110
Interface: 2
Usage (page): 0x0 (0x0)
Handle 1: New device is connected: 3-2:1.0.
type: 04d9 fc38
serial_number: (null)
Manufacturer: (null)
Product: USB Gaming Mouse
Release: 110
Interface: 0
Usage (page): 0x0 (0x0)
Handle 1: New device is connected: 3-2:1.1.
type: 04d9 fc38
serial_number: (null)
Manufacturer: (null)
Product: USB Gaming Mouse
Release: 110
Interface: 1
Usage (page): 0x0 (0x0)
Handle 1: New device is connected: 3-2:1.2.
type: 04d9 fc38
serial_number: (null)
Manufacturer: (null)
Product: USB Gaming Mouse
Release: 110
Interface: 2
Usage (page): 0x0 (0x0)
@mcuee this monstrocity is now more or less ready to be tested, reviewed
and insulted.Forgot a call to trigger the pthread_condition...
Does not affect the funcction, but the event is delayed for up to 5ms.
Going to fix later.done.Now this works fine. Thanks. And yes it is not requird to detach kernel driver for event.
Tested under Ubuntu Linux 20.04.
Unplug and plug of Platronics USB headset
Unplug and plug of a USB mouse receiver
Unplug and plug of another USB mouse receiver
I've fixed some formatting concerns of mine, but still don't have enough time to go thru all of the code.
But I trust the community to review it properly and fix if anything needs to be fixed.
That said, I will not block the PR from getting into a feature branch.