Skip to content

Commit

Permalink
Replace DeviceInfo::bus_number with bus_id
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinmehall committed Aug 10, 2024
1 parent b8a57a9 commit 0b51e76
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 24 deletions.
2 changes: 1 addition & 1 deletion examples/descriptors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ fn main() {
fn inspect_device(dev: DeviceInfo) {
println!(
"Device {:03}.{:03} ({:04x}:{:04x}) {} {}",
dev.bus_number(),
dev.bus_id(),
dev.device_address(),
dev.vendor_id(),
dev.product_id(),
Expand Down
2 changes: 1 addition & 1 deletion examples/string_descriptors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ fn main() {
fn inspect_device(dev: DeviceInfo) {
println!(
"Device {:03}.{:03} ({:04x}:{:04x}) {} {}",
dev.bus_number(),
dev.bus_id(),
dev.device_address(),
dev.vendor_id(),
dev.product_id(),
Expand Down
24 changes: 18 additions & 6 deletions src/enumeration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ pub struct DeviceInfo {
#[cfg(target_os = "linux")]
pub(crate) path: SysfsPath,

#[cfg(target_os = "linux")]
pub(crate) busnum: u8,

#[cfg(target_os = "windows")]
pub(crate) instance_id: OsString,

Expand All @@ -46,7 +49,7 @@ pub struct DeviceInfo {
#[cfg(target_os = "macos")]
pub(crate) location_id: u32,

pub(crate) bus_number: u8,
pub(crate) bus_id: String,
pub(crate) device_address: u8,
pub(crate) port_chain: Option<Vec<u8>>,

Expand Down Expand Up @@ -80,7 +83,7 @@ impl DeviceInfo {
#[cfg(target_os = "linux")]
{
DeviceId(crate::platform::DeviceId {
bus: self.bus_number,
bus: self.busnum,
addr: self.device_address,
})
}
Expand All @@ -105,6 +108,14 @@ impl DeviceInfo {
&self.path.0
}

/// *(Linux-only)* Bus number.
///
/// On Linux, the `bus_id` is an integer and this provides the value as `u8`.
#[cfg(target_os = "linux")]
pub fn busnum(&self) -> u8 {
self.busnum
}

/// *(Windows-only)* Instance ID path of this device
#[cfg(target_os = "windows")]
pub fn instance_id(&self) -> &OsStr {
Expand Down Expand Up @@ -152,9 +163,9 @@ impl DeviceInfo {
self.registry_id
}

/// Number identifying the bus / host controller where the device is connected.
pub fn bus_number(&self) -> u8 {
self.bus_number
/// Identifier for the bus / host controller where the device is connected.
pub fn bus_id(&self) -> &str {
&self.bus_id
}

/// Number identifying the device within the bus.
Expand Down Expand Up @@ -273,7 +284,7 @@ impl std::fmt::Debug for DeviceInfo {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut s = f.debug_struct("DeviceInfo");

s.field("bus_number", &self.bus_number)
s.field("bus_id", &self.bus_id)
.field("device_address", &self.device_address)
.field("port_chain", &format_args!("{:?}", self.port_chain))
.field("vendor_id", &format_args!("0x{:04X}", self.vendor_id))
Expand All @@ -294,6 +305,7 @@ impl std::fmt::Debug for DeviceInfo {
#[cfg(target_os = "linux")]
{
s.field("sysfs_path", &self.path);
s.field("busnum", &self.busnum);
}

#[cfg(target_os = "windows")]
Expand Down
2 changes: 1 addition & 1 deletion src/platform/linux_usbfs/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub(crate) struct LinuxDevice {

impl LinuxDevice {
pub(crate) fn from_device_info(d: &DeviceInfo) -> Result<Arc<LinuxDevice>, Error> {
let busnum = d.bus_number();
let busnum = d.busnum();
let devnum = d.device_address();
let active_config = d.path.read_attr("bConfigurationValue")?;

Expand Down
5 changes: 3 additions & 2 deletions src/platform/linux_usbfs/enumeration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ pub fn list_devices() -> Result<impl Iterator<Item = DeviceInfo>, Error> {
pub fn probe_device(path: SysfsPath) -> Result<DeviceInfo, SysfsError> {
debug!("Probing device {:?}", path.0);

let bus_number = path.read_attr("busnum")?;
let busnum = path.read_attr("busnum")?;
let device_address = path.read_attr("devnum")?;

let port_chain = path.read_attr::<String>("devpath").ok().and_then(|p| {
Expand All @@ -134,7 +134,8 @@ pub fn probe_device(path: SysfsPath) -> Result<DeviceInfo, SysfsError> {
.collect::<Option<Vec<u8>>>()
});
Ok(DeviceInfo {
bus_number,
busnum,
bus_id: format!("{busnum:03}"),
device_address,
port_chain,
vendor_id: path.read_attr_hex("idVendor")?,
Expand Down
2 changes: 1 addition & 1 deletion src/platform/macos_iokit/enumeration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ pub(crate) fn probe_device(device: IoService) -> Option<DeviceInfo> {
Some(DeviceInfo {
registry_id,
location_id,
bus_number: (location_id >> 24) as u8,
bus_id: format!("{:02x}", (location_id >> 24) as u8),
device_address: get_integer_property(&device, "USB Address")? as u8,
port_chain: Some(parse_location_id(location_id)),
vendor_id: get_integer_property(&device, "idVendor")? as u16,
Expand Down
32 changes: 20 additions & 12 deletions src/platform/windows_winusb/enumeration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::{
use log::debug;
use windows_sys::Win32::Devices::{
Properties::{
DEVPKEY_Device_Address, DEVPKEY_Device_BusNumber, DEVPKEY_Device_BusReportedDeviceDesc,
DEVPKEY_Device_Address, DEVPKEY_Device_BusReportedDeviceDesc,
DEVPKEY_Device_CompatibleIds, DEVPKEY_Device_HardwareIds, DEVPKEY_Device_InstanceId,
DEVPKEY_Device_LocationPaths, DEVPKEY_Device_Parent, DEVPKEY_Device_Service,
},
Expand Down Expand Up @@ -42,7 +42,6 @@ pub fn probe_device(devinst: DevInst) -> Option<DeviceInfo> {
debug!("Probing device {instance_id:?}");

let parent_instance_id = devinst.get_property::<OsString>(DEVPKEY_Device_Parent)?;
let bus_number = devinst.get_property::<u32>(DEVPKEY_Device_BusNumber)? as u8;
let port_number = devinst.get_property::<u32>(DEVPKEY_Device_Address)?;

let hub_port = HubPort::by_child_devinst(devinst).ok()?;
Expand Down Expand Up @@ -98,18 +97,21 @@ pub fn probe_device(devinst: DevInst) -> Option<DeviceInfo> {

interfaces.sort_unstable_by_key(|i| i.interface_number);

let port_chain = devinst
let location_paths = devinst
.get_property::<Vec<OsString>>(DEVPKEY_Device_LocationPaths)
.and_then(|s| s.iter().find_map(|p| parse_location_path(p)));
.unwrap_or_default();

let (bus_id, port_chain) = location_paths.iter().find_map(|p| parse_location_path(p))
.unwrap_or_default();

Some(DeviceInfo {
instance_id,
parent_instance_id,
devinst,
port_number,
port_chain,
port_chain: Some(port_chain),
driver: Some(driver).filter(|s| !s.is_empty()),
bus_number: bus_number as u8,
bus_id,
device_address: info.address,
vendor_id: info.device_desc.idVendor,
product_id: info.device_desc.idProduct,
Expand Down Expand Up @@ -293,8 +295,14 @@ fn test_parse_compatible_id() {
);
}

fn parse_location_path(s: &OsStr) -> Option<Vec<u8>> {
let (_, mut s) = s.to_str()?.split_once("#USBROOT(")?;
fn parse_location_path(s: &OsStr) -> Option<(String, Vec<u8>)> {
let s = s.to_str()?;

let usbroot = "#USBROOT(";
let start_i = s.find(usbroot)?;
let close_i = s[start_i + usbroot.len()..].find(')')?;
let (bus, mut s) = s.split_at(start_i + usbroot.len() + close_i + 1);


let mut path = vec![];

Expand All @@ -304,7 +312,7 @@ fn parse_location_path(s: &OsStr) -> Option<Vec<u8>> {
s = next;
}

Some(path)
Some((bus.to_owned(), path))
}

#[test]
Expand All @@ -313,13 +321,13 @@ fn test_parse_location_path() {
parse_location_path(OsStr::new(
"PCIROOT(0)#PCI(0201)#PCI(0000)#USBROOT(0)#USB(23)#USB(2)#USB(1)#USB(3)#USB(4)"
)),
Some(vec![23, 2, 1, 3, 4])
Some(("PCIROOT(0)#PCI(0201)#PCI(0000)#USBROOT(0)".into(), vec![23, 2, 1, 3, 4]))
);
assert_eq!(
parse_location_path(OsStr::new(
"PCIROOT(0)#PCI(0201)#PCI(0000)#USBROOT(0)#USB(16)"
"PCIROOT(0)#PCI(0201)#PCI(0000)#USBROOT(1)#USB(16)"
)),
Some(vec![16])
Some(("PCIROOT(0)#PCI(0201)#PCI(0000)#USBROOT(1)".into(), vec![16]))
);
assert_eq!(
parse_location_path(OsStr::new(
Expand Down

0 comments on commit 0b51e76

Please sign in to comment.