Open NickeZ opened 4 years ago
Hi @NickeZ .
I was already working on a raw rust backend for this crate, which would skip hidapi (the C library), and use the os interfaces directly.
At the time I did this, I also wanted to add async support, but the rust async story was not really stable. I decided to wait, until async ecosystem / language integration catches up. I have not looked into async / await since then, but from what I heard, it might be ready
Regarding libusb, I do not plan on using it at all. All somewhat modern Linux systems should have the hidraw kernel interface.
I might be able to spend some time on this starting next week, but I have some other hobby projects going on.
If you have any pointers, if I should try it with the tokio ecosystem, or async-std, please tell me. Maybe it`s possible to be runtime independent by just using mio, std::future and std::task?
I haven't looked close enough to know exactly what crates are needed, but I think you shouldn't need tokio
. I think technically it should be enough with std::future
, std::task
and AsyncRead/Write
from futures
. However it would be great if we could reuse some platform specific code from mio
to avoid reimplementing it. But it sounds to me like that depends on how usb works on the different platforms.
One caveat is that we may have to implement AsyncRead/Write
from tokio
as well to support that ecosystem. Currently it is in a bit of flux how the final std traits will look.
Tokio will migrate to the version of the async traits that gets standardized, but until then it would be nice to support both, if possible.
So the plan would be to wrap these interfaces?
So the plan would be to wrap these interfaces?
- Windows (using hid.dll)
- Linux (using the Kernel's hidraw driver)
- Mac (using IOHidManager)
For Windows, there's winapi-rs which provides raw FFI bindings to all of Windows API.
In the mean time, I think we could use https://docs.rs/smol as a hidapi async wrapper. The only thing we would need would be to make HidDevice AsRawFd (on linux at least). For testing, we can get the fd by casting the device handle as it is the first member (https://github.com/libusb/hidapi/blob/master/linux/hid.c#L65). A more robust solution would be to patch hidapi with a method returning the device specific fd.
What about rust/winrt? Does it supersede this crate?
@brokenthorn WinRT might have some USB functions, but it doesn't deprecate this crate which is portable across Windows, Linux and MacOS.
Don`t forget BSD :P
Just dropping in here to mention that it looks like the winapi
crate has effectively been superseded by the official Microsoft windows
crate!
Any news on async hidraw on Linux?
Nope sorry, I don't work with usb hardware right now so I'm not looking into it anymore.
What about rust/winrt? Does it supersede this crate?
That crate has now been deprecated in favor of the windows crate which is wider reaching and might now expose more of the Windows APIs.
Don`t forget BSD :P
It is interesting to see such efforts to bypass hidapi. :-)
In the case of FreeBSD, take note there is the new hidraw (similar to hidraw under Linux) for newer version of FreeBSD.
Reference: the following hidraw feature has been merged. https://reviews.freebsd.org/D27992
Another reference: https://github.com/Yubico/libfido2/blob/main/src/hid_freebsd.c
I came across this thread as I am also interested in async HID in Rust. Doing a search, I found someone created a async HID crate using platform-native bindings called async-hid. The library seems rather unknown (73 downloads all time), and entire commit history is 3 months (July 8th, 2023 to Oct 12, 2023). With that, I have no idea the state of support for the project.
Has anyone here given that project a shot?
I made an async interface to this crate. However, since there is no way to register to become awakened when there is data to read I have to create a thread and do blocking reads.
Reading through libhidapi (the C library) I realised that the libusb interface actually is asynchronous and that libhidapi conveniently (unfortunately) wraps away that using an internal thread. So the result feels incredible clunky with two threads and multiple mutexes / synchronization primitives.
I think the best approach actually is to skip hidapi and rewrite using the platform specific bindings from scratch. But before I start such a big effort I wanted to check in here if anyone else already is working on it.
Thanks