Skip to content

Commit

Permalink
sorting all hid devices by their paths (#84)
Browse files Browse the repository at this point in the history
Addresses:
#83 (comment)
carlossless authored Jul 16, 2024
1 parent f082d48 commit f754d06
Showing 1 changed file with 57 additions and 49 deletions.
106 changes: 57 additions & 49 deletions src/isp.rs
Original file line number Diff line number Diff line change
@@ -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<Self, ISPError> {
let devices = Self::find_isp_device(part)?;
@@ -78,42 +90,6 @@ impl ISPDevice {
})
}

/// Prints out all connected HID devices and their paths.
pub fn print_connected_devices() -> Result<(), ISPError> {
let api = ISPDevice::hidapi();

info!("Listing all connected HID devices...");
let mut devices: Vec<_> = api.device_list().collect();

devices.sort_by_key(|d| d.path());

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 hidapi() -> HidApi {
let api = HidApi::new().unwrap();

@@ -125,9 +101,9 @@ impl ISPDevice {

fn open_isp_devices() -> Result<HIDDevices, ISPError> {
let api = Self::hidapi();

let mut devices: Vec<_> = api
.device_list()
let sorted_devices: Vec<_> = api.sorted_device_list();
let isp_devices: Vec<_> = sorted_devices
.into_iter()
.filter(|d| {
#[cfg(not(target_os = "linux"))]
return d.vendor_id() == GAMING_KB_VENDOR_ID
@@ -148,9 +124,7 @@ impl ISPDevice {
})
.collect();

devices.sort_by_key(|d| d.path());

for d in &devices {
for d in &isp_devices {
#[cfg(not(target_os = "linux"))]
debug!(
"Found ISP Device: {:#06x} {:#06x} {:?} {:#06x} {:#06x}",
@@ -169,14 +143,14 @@ impl ISPDevice {
);
}

let device_count = devices.len();
let device_count = isp_devices.len();
if device_count == 0 {
return Err(ISPError::NotFound);
}

#[cfg(not(target_os = "windows"))]
if device_count == 1 {
let request_device = devices.first().unwrap();
let request_device = isp_devices.first().unwrap();
debug!("Request device: {:?}", request_device.path());
return Ok(HIDDevices {
request: api.open_path(request_device.path()).unwrap(),
@@ -189,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 {
@@ -210,8 +184,9 @@ impl ISPDevice {
part.vendor_id, part.product_id
);

let request_device_info = api
.device_list()
let sorted_devices: Vec<_> = api.sorted_device_list();
let request_device_info = sorted_devices
.into_iter()
.filter(|d| {
#[cfg(not(target_os = "linux"))]
return d.vendor_id() == part.vendor_id
@@ -301,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<Vec<u8>, ISPError> {
self.enable_firmware()?;

0 comments on commit f754d06

Please sign in to comment.