libusb backend for Windows and macOS #319
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#319
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
As discussed in #61 , it may make sense to create a new libusb backend to remove some limitations of the native HID APIs under Windows. The users will need to use WinUSB driver to replace the native HID driver in order to make use of this (if using libusb HID backend, then the limitation still applies).
I am not so sure if there is any benefit to extend this to macOS, but it can be done as well with the latest kernel driver detaching function of libusb under macOS.
Reference discussion for macOS: https://github.com/libusb/libusb/pull/911
Quick hack for mac/hid.c
Codes from:
https://blog.albertarmea.com/post/47089939939/using-pthreadbarrier-on-mac-os-x
Quick hack for Makefile.macOS
Runlog for macOS with hidtest using the quick mod libusb backend.
Under Windows, here is the output, with a quick mod of the following file.
https://gitlab.com/CalcProgrammer1/OpenRGB/-/blob/master/dependencies/hidapi/hidapi.c
I choose to use usbdk backend so that I do not need to replace the HID driver with WinUSB. And it may be able to find more devices like USB keyboard and mouse if they are present.
modified files and Windows 64bit binaries are included in the following zip file.
hidapi_libusb.zip
Of course, it is also possible not to use usbdk, just comment out the following line in hid.c.
hidapi_libusb2.zip
Instead of using "hacks" to make it functional I'd rather suggest to refactor libusb backend of HIDAPI and switch to C11 instead of using POSIX/pthread API.
That way we will have a clean implementation compliant with the C Standard.
Thoughts?
Yes, that will be great.
Haha, my hack is just a quick demo to show that it is possible.
In order for your USB HID device to be found by the libusb backend (hidapi_libusb2.zip), there are two possibilities.
Take note this is only applicable to device listed under Windows Device Manager as "Human Interface Devices" --> "USB Input Device". Keyboard/mouse and Bluetooth/I2C/SPI HID devices are not supported.
https://github.com/libusb/libusb/wiki/Windows#known-restrictions
HID keyboards and mice cannot be accessed using the native HID driver as Windows reserves exclusive access to them.
Multiple HID top level collections are currently not supported (only the first top level collection will be used).
hidapi_libusb.zip uses the USBDK backend of the libusb, so it may be able to find more devices than hidapi_libusb2.zip. For example, it may be able to find some USB mice/keyboards. But it requires the installation of usbdk. libusb usbdk backend may be less stable than using WinUSB backend.
https://github.com/daynix/UsbDk/releases
64bit Windows binary with hidapitester here (not using usbdk). libusb-1.0.dll is a mod version of 1.0.24.11650 with pull request libusb/libusb#986 to fix the Windows HID backend issue.
https://github.com/mcuee/hidapitester/releases/tag/v8610dc6
@Youw
Since I do not know much about pthread and C++11 threading, and since ChatGPT is now popular, I asked ChatGPT to do the job.
Unfortuantely ChatGPT is not able to finish the full conversion and always got stuck.
(Edit: delete the code as it is not good).
Loool :)
Writing it in C++11 would be even easier, for sure)
Glad to hear that.
Interestingly I ask ChatGPT to convert the simple libusb
stress_mt.cpthread based test codes to C++11 threading and it has no problems. But the result codes do not work under WIndows but work under Linux. Maybe libusb Windows has some issues under stress.https://github.com/libusb/libusb/blob/master/tests/stress_mt.c
However, if I ask it to convert into C11, the result codes do not even compile since MinGW does not support C11
<threads>.That's a bummer :(
I never actually used C11 threads. I only assumed, that compilers that have C++11 threads would have C implementation as well...
Writing an entire backend in C++ has many proc and cons. One of the most important ones - dependency on C++ Standard library.
And I'm pretty sure there will be some part of the (C) community that will not support such huge change as switching from C to C++.
But maybe, having an experimental (additional, not replacement) C++ port of libusb backend of HIDAPI - should be a "fun project" at least.
And I'm not talking about "just replacing pthreads with C++11 threads". I'm talking of taking a full advantage of Modern C++ (yes - that is a "thing").
FYI: Apple clang does not support C11 threading either.
Ref:
https://stackoverflow.com/questions/16244153/clang-c11-threads-h-not-found
I think in the end, this is not an important work (not much real use in reality) and therefore I will close it for now.
Re-open as a low priority item.
From #706, comment by mandar1jn.
I'll add some context to this: I'm working with skylanders portals which are HID devices, but they recieve commands over control transfers, something you wouldn't normally do for an HID device, but what can you do about it. My current code uses hidapi with a workaround to get the device handle from hidapi and manually runs the required win32 functions, but I'd prefer to use libusb (I can still extract the libusb handle from what I saw) and then use that functionality to send control transfers, and maybe utilize the hotplug functionality
Right now there is no official support of libusb backend for Windows or macOS, but there steps has been made towards that direction with the help of the community.
You may try in scope of your project (or even contribute if you feel like it) to define the HIDAPI thread abstraction for libusb and define the
HIDAPI_THREAD_MODEL_INCLUDEpointing to that implementation.See https://github.com/libusb/hidapi/pull/582/files for details.
Quick hack for hidapitester to use libusb backend under Windows.
PR #728 almost works under Windows but there is one extra byte written and read.
So you've replaced a standard HID driver with WinUSB one to perform this test?
No, the above test was using libusb-1.0 Windows HID backend.
If I switch to WinUSB driver, it does not work, matching the testing result I had with PR #728 under Linux and FreeBSD.
@Youw
But it will work if I test with the default fx2hid FW (two bytes input/output report loopback), if I switch the driver to WinUSB. So I will say the current libusb codes kind of work under Windows even though it will suffer the same issue as #274.
You can see that libusb mod works in this case while unmodifed hidapitester will not work since it only works with Windows HID driver.
Of course my mod is a quick hack -- needs proper changes to the code, auto-tools script and CMake files.
And it may need further work to remove the dependanices to libiconv as well.
I will also need to test under macOS.
BTW, I am not so sure where I introduce the dependancy to libwinpthread-1.dll. It would be good to remove the dependancy as well. The default Windows version (using native Windows HID API) does not have those dependancies.
My mod of hidapitester Makefiles and the binaries (MSYS2 uscrt64 build).
hidapitester_git.zip
Same if I use my mod of Jan Axelson's USB PIC Generic HID example, mentioned here. Both hidapi git and PR #728 work fine, basically with report IDs for input/output reports and feature reports.
Using WinUSB driver and not native Windows HID driver in the following tests.
Switch back to Windows HID driver and use hidapi git. This is just to prove the FW is working.