Skip to content

Commit

Permalink
Tiny refactor for USB device IDs
Browse files Browse the repository at this point in the history
Unfortunately, it's impossible to print device manufacturer and product strings during attach/detach: device needs to be opened, and that doesn't work even in attach.
  • Loading branch information
haimgel committed Nov 10, 2024
1 parent a73892f commit fa87a9c
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 10 deletions.
9 changes: 4 additions & 5 deletions src/platform/pnp_detect_libusb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,31 @@
// This code is licensed under MIT license (see LICENSE.txt for details)
//

use crate::usb::{device2str, UsbCallback};
use anyhow::{anyhow, Result};
use rusb::{Context, Device, HotplugBuilder, Registration, UsbContext};

/// Detection of plugged in / removed USB devices: uses "libusb" and should work on Linux
/// and MacOS, but not on Windows: libusb does not support hotplug on Windows.
pub struct PnPDetectLibusb {
callback: Box<dyn UsbCallback + Send>,
callback: Box<dyn crate::usb::UsbCallback + Send>,
}

impl<T: UsbContext> rusb::Hotplug<T> for PnPDetectLibusb {
fn device_arrived(&mut self, device: Device<T>) {
if let Some(str) = device2str(device) {
if let Some(str) = crate::usb::device_id(&device) {
self.callback.device_added(&str)
}
}

fn device_left(&mut self, device: Device<T>) {
if let Some(str) = device2str(device) {
if let Some(str) = crate::usb::device_id(&device) {
self.callback.device_removed(&str)
}
}
}

impl PnPDetectLibusb {
pub fn new(callback: Box<dyn UsbCallback + Send>) -> Box<Self> {
pub fn new(callback: Box<dyn crate::usb::UsbCallback + Send>) -> Box<Self> {
Box::new(PnPDetectLibusb { callback })
}

Expand Down
7 changes: 3 additions & 4 deletions src/platform/pnp_detect_windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use std::ffi::OsStr;
use std::iter::once;
use std::os::windows::ffi::OsStrExt;

use crate::usb::{device2str, UsbCallback};
use anyhow::{anyhow, Result};
use winapi::shared::minwindef::{LPARAM, LRESULT, UINT, WPARAM};
use winapi::shared::ntdef::LPCWSTR;
Expand All @@ -24,12 +23,12 @@ use winapi::um::winuser::{
/// https://github.com/libusb/libusb/issues/86
pub struct PnPDetectWindows {
hwnd: HWND,
callback: Box<dyn UsbCallback>,
callback: Box<dyn crate::usb::UsbCallback>,
current_devices: HashSet<String>,
}

impl PnPDetectWindows {
pub fn new(callback: Box<dyn UsbCallback>) -> Box<Self> {
pub fn new(callback: Box<dyn crate::usb::UsbCallback>) -> Box<Self> {
let mut pnp_detect = Box::new(Self {
callback,
current_devices: Self::read_device_list().unwrap_or_default(),
Expand Down Expand Up @@ -62,7 +61,7 @@ impl PnPDetectWindows {
fn read_device_list() -> Result<HashSet<String>> {
Ok(rusb::devices()?
.iter()
.map(|device| device2str(device).ok_or(anyhow!("Cannot get device Ids")))
.map(|device| crate::usb::device_id(&device).ok_or(anyhow!("Cannot get device Ids")))
.collect::<std::result::Result<_, _>>()?)
}

Expand Down
14 changes: 13 additions & 1 deletion src/usb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,25 @@
//
use rusb::UsbContext;

pub fn device2str<T: UsbContext>(device: rusb::Device<T>) -> Option<String> {
pub fn device_id<T: UsbContext>(device: &rusb::Device<T>) -> Option<String> {
device
.device_descriptor()
.map(|device_desc| format!("{:04x}:{:04x}", device_desc.vendor_id(), device_desc.product_id()))
.ok()
}

// pub fn device_product_name<T: UsbContext>(device: &rusb::Device<T>) -> Option<String> {
// let descriptor = device.device_descriptor().ok()?;
// let handle = device.open().ok()?;
// handle.read_product_string_ascii(&descriptor).ok()
// }
//
// pub fn device_manufacturer_name<T: UsbContext>(device: &rusb::Device<T>) -> Option<String> {
// let descriptor = device.device_descriptor().ok()?;
// let handle = device.open().ok()?;
// handle.read_manufacturer_string_ascii(&descriptor).ok()
// }

pub trait UsbCallback: Send {
fn device_added(&self, device_id: &str);
fn device_removed(&self, device_id: &str);
Expand Down

0 comments on commit fa87a9c

Please sign in to comment.