4

I'm examining rust to see if it suits my project requirements. One of my requirements is to watch for a USB insertion and removal which is identified by product id and vendor id. I found two crates libusb-rs and rusb. Both provide the following usage example:

fn main() {
    for device in rusb::devices().unwrap().iter() {
        let device_desc = device.device_descriptor().unwrap();

        println!("Bus {:03} Device {:03} ID {:04x}:{:04x}",
            device.bus_number(),
            device.address(),
            device_desc.vendor_id(),
            device_desc.product_id());
    }
}

This code iterates through all the system USB devices and list their properties. To watch for USB insertion and removal I can run the code every 500ms and check if the target USB is there or if it is removed. The thing is this method seems like a workaround to me and i think there should be some OS events that rust can hook to and makes USB detection more reliable and efficient. So what is the best way to do it in rust?

pouya
  • 3,400
  • 6
  • 38
  • 53
  • I'm not familiar with USB stuff, but sounds like you want [`register_callback`](https://docs.rs/rusb/0.8.0/rusb/trait.UsbContext.html#method.register_callback)? – loganfsmyth May 27 '21 at 20:19
  • The `rusb` crate offers such an example ([examples/hotplug.rs](https://github.com/a1ien/rusb/blob/fdf16f49cd7920f20d324caa2118f7d89e16354f/examples/hotplug.rs)), but if I recall correctly I had to listen for the events on a separate thread and it didn't work on Windows. Which operating systems does it need to work for? – Jason May 27 '21 at 20:42
  • @Jason I'm on linux – pouya May 28 '21 at 06:12

1 Answers1

1

So libusb itself has a traditional hotplug "API": https://libusb.sourceforge.io/api-1.0/libusb_hotplug.html

And while there is a libusb crate in Rust: https://docs.rs/libusb/latest/libusb/

I don't see that it supports this API unfortunately. The only other option I can think of is constantly polling the DeviceList object: https://docs.rs/libusb/latest/libusb/struct.DeviceList.html

And then seeing if it's length has changed since the last iteration.

Here's how to get the Device List

    let lusb_context = libusb::Context::new().unwrap();
    let connected_usb_devices = lusb_context.devices().unwrap();
Raleigh L.
  • 599
  • 2
  • 13
  • 18