From 4f132ba46b8fc92dc391eb79b66f4d9503b8dfec Mon Sep 17 00:00:00 2001 From: Karolis Stasaitis Date: Tue, 16 Jul 2024 09:49:35 +0200 Subject: [PATCH] change to hidapi extension, remove cloning --- src/isp.rs | 95 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 50 insertions(+), 45 deletions(-) diff --git a/src/isp.rs b/src/isp.rs index 89f9584..6131cb0 100644 --- a/src/isp.rs +++ b/src/isp.rs @@ -7,7 +7,7 @@ use crate::{part::*, util, VerificationError}; extern crate hidapi; -use hidapi::{HidApi, HidDevice, HidError}; +use hidapi::{DeviceInfo, HidApi, HidDevice, HidError}; const MAX_RETRIES: usize = 10; @@ -67,6 +67,18 @@ struct HIDDevices { data: HidDevice, } +pub trait HidApiExtension { + fn sorted_device_list(&self) -> Vec<&DeviceInfo>; +} + +impl HidApiExtension for HidApi { + fn sorted_device_list(self: &HidApi) -> Vec<&DeviceInfo> { + let mut devices: Vec<_> = self.device_list().collect(); + devices.sort_by_key(|d| d.path()); + devices + } +} + impl ISPDevice { pub fn new(part: Part) -> Result { let devices = Self::find_isp_device(part)?; @@ -78,45 +90,6 @@ impl ISPDevice { }) } - /// Prints out all connected HID devices and their paths. - pub fn print_connected_devices() -> Result<(), ISPError> { - info!("Listing all connected HID devices..."); - let devices: Vec<_> = ISPDevice::sorted_device_list(); - - for d in &devices { - #[cfg(not(target_os = "linux"))] - info!( - "{:}: ID {:04x}:{:04x} manufacturer=\"{:}\" product=\"{:}\" usage_page={:#06x} usage={:#06x}", - d.path().to_str().unwrap(), - d.vendor_id(), - d.product_id(), - d.manufacturer_string().unwrap_or("None"), - d.product_string().unwrap_or("None"), - d.usage_page(), - d.usage() - ); - #[cfg(target_os = "linux")] - info!( - "{:}: ID {:04x}:{:04x} manufacturer=\"{:}\" product=\"{:}\"", - d.path().to_str().unwrap(), - d.vendor_id(), - d.product_id(), - d.manufacturer_string().unwrap_or("None"), - d.product_string().unwrap_or("None") - ); - } - info!("Found {} devices", devices.len()); - - Ok(()) - } - - fn sorted_device_list() -> Vec { - let api = ISPDevice::hidapi(); - let mut devices: Vec<_> = api.device_list().collect(); - devices.sort_by_key(|d| d.path()); - devices.into_iter().cloned().collect() - } - fn hidapi() -> HidApi { let api = HidApi::new().unwrap(); @@ -128,8 +101,7 @@ impl ISPDevice { fn open_isp_devices() -> Result { let api = Self::hidapi(); - - let sorted_devices: Vec<_> = ISPDevice::sorted_device_list(); + let sorted_devices: Vec<_> = api.sorted_device_list(); let isp_devices: Vec<_> = sorted_devices .into_iter() .filter(|d| { @@ -191,8 +163,8 @@ impl ISPDevice { if device_count == 1 { return Err(ISPError::IrregularDeviceCount(device_count)); } else if device_count == 2 { - let request_device = devices[0]; - let data_device = devices[1]; + let request_device = isp_devices[0]; + let data_device = isp_devices[1]; debug!("Request device: {:?}", request_device.path()); debug!("Data device: {:?}", data_device.path()); return Ok(HIDDevices { @@ -212,7 +184,7 @@ impl ISPDevice { part.vendor_id, part.product_id ); - let sorted_devices: Vec<_> = ISPDevice::sorted_device_list(); + let sorted_devices: Vec<_> = api.sorted_device_list(); let request_device_info = sorted_devices .into_iter() .filter(|d| { @@ -304,6 +276,39 @@ impl ISPDevice { Ok(()) } + /// Prints out all connected HID devices and their paths. + pub fn print_connected_devices() -> Result<(), ISPError> { + info!("Listing all connected HID devices..."); + let api = Self::hidapi(); + let devices: Vec<_> = api.sorted_device_list(); + + for d in &devices { + #[cfg(not(target_os = "linux"))] + info!( + "{:}: ID {:04x}:{:04x} manufacturer=\"{:}\" product=\"{:}\" usage_page={:#06x} usage={:#06x}", + d.path().to_str().unwrap(), + d.vendor_id(), + d.product_id(), + d.manufacturer_string().unwrap_or("None"), + d.product_string().unwrap_or("None"), + d.usage_page(), + d.usage() + ); + #[cfg(target_os = "linux")] + info!( + "{:}: ID {:04x}:{:04x} manufacturer=\"{:}\" product=\"{:}\"", + d.path().to_str().unwrap(), + d.vendor_id(), + d.product_id(), + d.manufacturer_string().unwrap_or("None"), + d.product_string().unwrap_or("None") + ); + } + info!("Found {} devices", devices.len()); + + Ok(()) + } + pub fn read_cycle(&self, read_type: ReadType) -> Result, ISPError> { self.enable_firmware()?;