Skip to content

Commit

Permalink
use sysfs name to get attribute_values
Browse files Browse the repository at this point in the history
  • Loading branch information
tuna-f1sh committed Nov 10, 2023
1 parent 4fa2c19 commit 0362da4
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 17 deletions.
7 changes: 4 additions & 3 deletions src/lsusb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,7 @@ pub mod profiler {
),
driver: None,
syspath: None,
// These are idProduct, idVendor in lsusb - from usb_ids
vendor: usb_ids::Vendor::from_id(device_desc.vendor_id()).map(|v| v.name().to_owned()),
product_name: usb_ids::Device::from_vid_pid(
device_desc.vendor_id(),
Expand Down Expand Up @@ -414,7 +415,7 @@ pub mod profiler {
.or({
#[cfg(all(target_os = "linux", feature = "udev"))]
{
udev::get_udev_attribute(&sp_device.port_path(), "manufacturer")
udev::get_udev_attribute(&sp_device.sysfs_name(), "manufacturer")
}

#[cfg(not(all(target_os = "linux", feature = "udev")))]
Expand All @@ -428,7 +429,7 @@ pub mod profiler {
sp_device.name = match get_product_string(&device_desc, &mut usb_device).or({
#[cfg(all(target_os = "linux", feature = "udev"))]
{
udev::get_udev_attribute(&sp_device.port_path(), "product")
udev::get_udev_attribute(&sp_device.sysfs_name(), "product")
}

#[cfg(not(all(target_os = "linux", feature = "udev")))]
Expand All @@ -451,7 +452,7 @@ pub mod profiler {
sp_device.serial_num = get_serial_string(&device_desc, &mut usb_device).or({
#[cfg(all(target_os = "linux", feature = "udev"))]
{
udev::get_udev_attribute(&sp_device.port_path(), "serial")
udev::get_udev_attribute(&sp_device.sysfs_name(), "serial")
}

#[cfg(not(all(target_os = "linux", feature = "udev")))]
Expand Down
10 changes: 10 additions & 0 deletions src/system_profiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,11 @@ impl DeviceLocation {
pub fn trunk_path(&self) -> String {
get_trunk_path(self.bus, &self.tree_positions)
}

/// Linux sysfs name of [`USBDevice`] similar to `port_path` but root_hubs use the USB controller name instead of port
pub fn sysfs_name(&self) -> String {
get_sysfs_name(self.bus, &self.tree_positions)
}
}

impl<'de> Deserialize<'de> for DeviceLocation {
Expand Down Expand Up @@ -943,6 +948,11 @@ impl USBDevice {
get_dev_path(self.location_id.bus, Some(self.location_id.number))
}

/// Linux sysfs name of [`USBDevice`]
pub fn sysfs_name(&self) -> String {
self.location_id.sysfs_name()
}

/// Trunk device is first in tree
///
/// ```
Expand Down
4 changes: 2 additions & 2 deletions src/udev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ pub fn get_udev_attribute<T: AsRef<std::ffi::OsStr> + std::fmt::Display>(
return None;
}
};
let value = device.attribute_value(attribute).unwrap_or_default();
Some(value.to_str().unwrap_or("").to_string())

device.attribute_value(attribute).map(|s| s.to_str().unwrap_or("").to_string())
}

#[cfg(test)]
Expand Down
45 changes: 33 additions & 12 deletions src/usb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -697,10 +697,10 @@ pub struct USBDeviceExtra {
/// ```
/// use cyme::usb::get_port_path;
///
/// assert_eq!(get_port_path(1, &vec![1, 3, 2]), String::from("1-1.3.2"));
/// assert_eq!(get_port_path(1, &vec![2]), String::from("1-2"));
/// assert_eq!(get_port_path(1, &[1, 3, 2]), String::from("1-1.3.2"));
/// assert_eq!(get_port_path(1, &[2]), String::from("1-2"));
/// // special case for root_hub
/// assert_eq!(get_port_path(2, &vec![]), String::from("2-0"));
/// assert_eq!(get_port_path(2, &[]), String::from("2-0"));
/// ```
///
/// [ref](http://gajjarpremal.blogspot.com/2015/04/sysfs-structures-for-linux-usb.html)
Expand All @@ -710,7 +710,7 @@ pub struct USBDeviceExtra {
/// All the other entries refer to genuine USB devices and their interfaces. The devices are named by a scheme like this:
///
/// bus-port.port.port ...
pub fn get_port_path(bus: u8, ports: &Vec<u8>) -> String {
pub fn get_port_path(bus: u8, ports: &[u8]) -> String {
if ports.len() <= 1 {
get_trunk_path(bus, ports)
} else {
Expand All @@ -722,9 +722,9 @@ pub fn get_port_path(bus: u8, ports: &Vec<u8>) -> String {
/// ```
/// use cyme::usb::get_parent_path;
///
/// assert_eq!(get_parent_path(1, &vec![1, 3, 4, 5]).unwrap(), String::from("1-1.3.4"));
/// assert_eq!(get_parent_path(1, &[1, 3, 4, 5]).unwrap(), String::from("1-1.3.4"));
/// ```
pub fn get_parent_path(bus: u8, ports: &Vec<u8>) -> error::Result<String> {
pub fn get_parent_path(bus: u8, ports: &[u8]) -> error::Result<String> {
if ports.is_empty() {
Err(Error::new(
ErrorKind::InvalidArg,
Expand All @@ -739,11 +739,11 @@ pub fn get_parent_path(bus: u8, ports: &Vec<u8>) -> error::Result<String> {
/// ```
/// use cyme::usb::get_trunk_path;
///
/// assert_eq!(get_trunk_path(1, &vec![1, 3, 5, 6]), String::from("1-1"));
/// assert_eq!(get_trunk_path(1, &[1, 3, 5, 6]), String::from("1-1"));
/// // special case for root_hub
/// assert_eq!(get_trunk_path(1, &vec![]), String::from("1-0"));
/// assert_eq!(get_trunk_path(1, &[]), String::from("1-0"));
/// ```
pub fn get_trunk_path(bus: u8, ports: &Vec<u8>) -> String {
pub fn get_trunk_path(bus: u8, ports: &[u8]) -> String {
if ports.is_empty() {
// special case for root_hub
format!("{:}-{}", bus, 0)
Expand All @@ -757,11 +757,11 @@ pub fn get_trunk_path(bus: u8, ports: &Vec<u8>) -> String {
/// ```
/// use cyme::usb::get_interface_path;
///
/// assert_eq!(get_interface_path(1, &vec![1, 3], 1, 0), String::from("1-1.3:1.0"));
/// assert_eq!(get_interface_path(1, &[1, 3], 1, 0), String::from("1-1.3:1.0"));
/// // bus
/// assert_eq!(get_interface_path(1, &vec![], 1, 0), String::from("1-0:1.0"));
/// assert_eq!(get_interface_path(1, &[], 1, 0), String::from("1-0:1.0"));
/// ```
pub fn get_interface_path(bus: u8, ports: &Vec<u8>, config: u8, interface: u8) -> String {
pub fn get_interface_path(bus: u8, ports: &[u8], config: u8, interface: u8) -> String {
format!("{}:{}.{}", get_port_path(bus, ports), config, interface)
}

Expand All @@ -787,6 +787,27 @@ pub fn get_dev_path(bus: u8, device_no: Option<u8>) -> String {
}
}

/// Builds a replica of sysfs name for reading sysfs_props ala: https://github.com/gregkh/usbutils/blob/master/sysfs.c#L29
///
/// Like `get_port_path` but root_hubs use the USB controller name (usbX) rather than interface
///
/// ```
/// use cyme::usb::get_sysfs_name;
///
/// assert_eq!(get_sysfs_name(1, &vec![1, 3, 2]), String::from("1-1.3.2"));
/// assert_eq!(get_sysfs_name(1, &vec![2]), String::from("1-2"));
/// // special case for root_hub
/// assert_eq!(get_sysfs_name(2, &vec![]), String::from("usb2"));
/// ```
pub fn get_sysfs_name(bus: u8, ports: &[u8]) -> String {
if ports.is_empty() {
// special cae for root_hub
format!("usb{}", bus)
} else {
get_port_path(bus, &ports)
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down

0 comments on commit 0362da4

Please sign in to comment.