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

Async interface #51

Open
NickeZ opened this issue Feb 13, 2020 · 16 comments
Open

Async interface #51

NickeZ opened this issue Feb 13, 2020 · 16 comments

Comments

@NickeZ
Copy link

NickeZ commented Feb 13, 2020

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

@ruabmbua
Copy link
Owner

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
Copy link
Owner

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?

@NickeZ
Copy link
Author

NickeZ commented Feb 16, 2020

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.

@lnicola
Copy link
Contributor

lnicola commented Feb 16, 2020

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.

@NickeZ
Copy link
Author

NickeZ commented Feb 16, 2020

So the plan would be to wrap these interfaces?

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

@brokenthorn
Copy link

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.

@Yamakaky
Copy link

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.

@brokenthorn
Copy link

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

@lnicola
Copy link
Contributor

lnicola commented Aug 3, 2020

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

@ruabmbua
Copy link
Owner

ruabmbua commented Aug 6, 2020

Don`t forget BSD :P

@timfish
Copy link

timfish commented Oct 9, 2021

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

@darkdragon-001
Copy link

Any news on async hidraw on Linux?

@NickeZ
Copy link
Author

NickeZ commented Apr 26, 2022

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

@brokenthorn
Copy link

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.

@mcuee
Copy link

mcuee commented May 14, 2023

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

@zardini123
Copy link

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?

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

9 participants