hidapi-rs icon indicating copy to clipboard operation
hidapi-rs copied to clipboard

Async interface

Open NickeZ opened this issue 4 years ago • 16 comments

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

NickeZ avatar Feb 13 '20 09:02 NickeZ

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.

https://github.com/ruabmbua/hidapi-rs/projects/1

ruabmbua avatar Feb 14 '20 17:02 ruabmbua

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?

ruabmbua avatar Feb 14 '20 17:02 ruabmbua

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.

NickeZ avatar Feb 16 '20 12:02 NickeZ

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.

lnicola avatar Feb 16 '20 12:02 lnicola

So the plan would be to wrap these interfaces?

  • Windows (using hid.dll)
  • Linux (using the Kernel's hidraw driver)
  • Mac (using IOHidManager)

NickeZ avatar Feb 16 '20 13:02 NickeZ

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.

brokenthorn avatar Feb 17 '20 09:02 brokenthorn

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.

Yamakaky avatar Jun 12 '20 13:06 Yamakaky

What about rust/winrt? Does it supersede this crate?

brokenthorn avatar Aug 03 '20 11:08 brokenthorn

@brokenthorn WinRT might have some USB functions, but it doesn't deprecate this crate which is portable across Windows, Linux and MacOS.

lnicola avatar Aug 03 '20 11:08 lnicola

Don`t forget BSD :P

ruabmbua avatar Aug 06 '20 13:08 ruabmbua

Just dropping in here to mention that it looks like the winapi crate has effectively been superseded by the official Microsoft windows crate!

timfish avatar Oct 09 '21 18:10 timfish

Any news on async hidraw on Linux?

darkdragon-001 avatar Apr 26 '22 14:04 darkdragon-001

Nope sorry, I don't work with usb hardware right now so I'm not looking into it anymore.

NickeZ avatar Apr 26 '22 19:04 NickeZ

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.

brokenthorn avatar May 08 '22 01:05 brokenthorn

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

mcuee avatar May 14 '23 04:05 mcuee