Open Nemo157 opened 6 months ago
hidapi
itself does not have hotplug support yet (see libusb/hidapi#238) so I guess any monitoring in native backend should be modeled after it, but I'm not sure if they have a stable API defined yet.
I think an approach for this is to use libusb
which has hotplug notification support (not in Windows yet though, it's WIP, see libusb/libusb#736). At least this is what node-hid
recommends instead of polling (unsure if the recommendation still stands though, but it's because hidapi
device list goes through a full bus enumeration).
Check rusb
for that. libusb
itself recommends using hidapi
for HID anyways so I think it's possible to use them in tandem and only refresh hidapi
devices when a libusb
hotplug notification arrives.
I haven't tested this though and I guess it can introduce race conditions if timing is tight? Maybe you can open the libusb
guaranteed-to-be-valid device with wrap_sys_device
instead of refreshing the device list?
I just pushed a branch with a quick implementation on the linux-native
backend only: https://github.com/ruabmbua/hidapi-rs/compare/main...Nemo157:hidapi-rs:monitor-linux-native
Testing it in my app it works perfectly, although as mentioned in the libusb/hidapi#238 there are race conditions between enumerating and setting up the monitor, afaict these are unavoidable.
I'll take a look at the other backends later.
Just pushed another branch adding on the hidraw
backend: https://github.com/ruabmbua/hidapi-rs/compare/main...Nemo157:hidapi-rs:monitor-linux-hidapi
Tested by building a pre-release version of hidapi
with the monitoring changes, using this shell.nix
:
{ pkgs ? import <nixpkgs> {}}:
pkgs.mkShell (with pkgs; {
nativeBuildInputs = [ pkg-config ];
buildInputs = [
udev
libusb1
(hidapi.overrideAttrs rec {
version = "connection-callback";
src = fetchFromGitHub {
owner = "libusb";
repo = "hidapi";
rev = "${version}";
sha256 = "sha256-peHXQbqNWL3XDQdRJ5piWEcglq742rez816lnja6wZA=";
};
})
];
})
And running the example with cargo run --no-default-features --features linux-shared-hidraw --example monitor
. (Could probably update the submodule to that branch and use linux-static-hidraw
instead I guess).
I have a usecase where I need to detect when new matching devices are inserted on the system. Currently I just periodically
.refresh_devices()
and re-iterate the list looking if there are any I haven't seen before, but this means there is a delay between when the device is inserted and the periodic refresh happens. It would be better ifhidapi
could monitor for changes in the device list and emit events as new devices appear (and events as they are removed could be useful too, though I already notice these when theDevice::read
returns an error).I'm not sure if this is something that is supported by the
hidapi
C backends, but it looks like it should be pretty trivial to build in thelinux-native
backend using theudev::MonitorBuilder
, and I will probably prototype it soon and could submit a PR if you'd accept it with just a single backend implementation.