sidit77 / async-hid

A async Rust library for interacting with HID devices
MIT License
3 stars 2 forks source link

Add serial number to DeviceInfo #2

Open baadc0de opened 11 months ago

baadc0de commented 11 months ago

Hi! Thank you for authoring this library!

For most use cases, vendor ID and product ID are good enough, but in some cases we need to also filter by serial number string. The sync library has a get_serial_number_string method that helps with that.

Could that be added to DeviceInfo?

sidit77 commented 11 months ago

Hi, I'm currently still on vacation but once I have access to my computer again I can look into it. My main concern is the windows backend. The sync version uses the win32 api while this library uses winrt. Winrt not only provides native async support but also allows the windows backend to be almost completely free of unsafe (and the few uses could be removed at a slight performance cost). It should also make this library UWP compatible although I don't know how valuable this is. However it's also more limited and doesn't seem to provide a straightforward way to access the serial number. Maybe the property system can be used to retrieve it. Otherwise it might be necessary to fall back to win32. Another concern is that non-usb hid devices might not have a serial number.

Are you actually interested in the serial number or just some kind of unique identifier?

baadc0de commented 11 months ago

Hi thanks for considering it.

Yep, the serial is important because some devices share VID/PID and need an additional identifier to discern which is which. For example microcontrollers from STM do this by default. I'll have a cursory look at WinRT and see if there is any way to hack this in on windows.

sidit77 commented 11 months ago

I'll have a cursory look at WinRT and see if there is any way to hack this in on windows.

Some tips that might help you: FindAllAsync has an optional parameter that can request additional properties. See this gist on how to use this kind of API in Rust. It's important to add the implement feature or you won't be able to cast the Vec<HString> to the IIterable<HString>.

sidit77 commented 11 months ago

So I decided the simply expose the serial number through an extension trait instead of the core api:

pub trait SerialNumberExt {
    fn serial_number(&self) -> Option<&str>;
}

On Windows this function attempts to query the serial number on the first call using the Win32 api. This way you only pay the cost for it if you actually need this information and the addional unsafe code is isolated to the win32-extensions module.

On Linux and MacOS this trait will probably just be a getter once I implement it for these platforms.