Skip to content

Commit

Permalink
Add location field to UsbPortInf (linux)
Browse files Browse the repository at this point in the history
  • Loading branch information
kindermax committed Nov 30, 2024
1 parent 67ce13e commit 7e079cc
Showing 1 changed file with 21 additions and 1 deletion.
22 changes: 21 additions & 1 deletion src/posix/enumerate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,21 @@ fn udev_restore_spaces(source: String) -> String {
source.replace('_', " ")
}

#[cfg(all(target_os = "linux", not(target_env = "musl"), feature = "libudev"))]
fn device_location(d: &libudev::Device) -> String {
match d.devpath() {
Some(path) => path
.to_str()
.unwrap_or_default()
.split("/")
.take(8)
.last()
.unwrap_or_default()
.to_string(),
None => "".to_string(),
}
}

#[cfg(all(target_os = "linux", not(target_env = "musl"), feature = "libudev"))]
fn port_type(d: &libudev::Device) -> Result<SerialPortType> {
match d.property_value("ID_BUS").and_then(OsStr::to_str) {
Expand All @@ -123,12 +138,14 @@ fn port_type(d: &libudev::Device) -> Result<SerialPortType> {
let product =
udev_property_encoded_or_replaced_as_string(d, "ID_MODEL_ENC", "ID_MODEL")
.or_else(|| udev_property_as_string(d, "ID_MODEL_FROM_DATABASE"));

Ok(SerialPortType::UsbPort(UsbPortInfo {
vid: udev_hex_property_as_int(d, "ID_VENDOR_ID", &u16::from_str_radix)?,
pid: udev_hex_property_as_int(d, "ID_MODEL_ID", &u16::from_str_radix)?,
serial_number,
manufacturer,
product,
location: device_location(d),
#[cfg(feature = "usbportinfo-interface")]
interface: udev_hex_property_as_int(d, "ID_USB_INTERFACE_NUM", &u8::from_str_radix)
.ok(),
Expand All @@ -154,12 +171,14 @@ fn port_type(d: &libudev::Device) -> Result<SerialPortType> {
"ID_USB_MODEL_ENC",
"ID_USB_MODEL",
);

Ok(SerialPortType::UsbPort(UsbPortInfo {
vid: udev_hex_property_as_int(d, "ID_USB_VENDOR_ID", &u16::from_str_radix)?,
pid: udev_hex_property_as_int(d, "ID_USB_MODEL_ID", &u16::from_str_radix)?,
serial_number: udev_property_as_string(d, "ID_USB_SERIAL_SHORT"),
manufacturer,
product,
location: device_location(d),
#[cfg(feature = "usbportinfo-interface")]
interface: udev_hex_property_as_int(
d,
Expand Down Expand Up @@ -252,6 +271,7 @@ fn parse_modalias(moda: &str) -> Option<UsbPortInfo> {
serial_number: None,
manufacturer: None,
product: None,
location: "".to_string(),
// Only attempt to find the interface if the feature is enabled.
#[cfg(feature = "usbportinfo-interface")]
interface: mod_tail.get(pid_start + 4..).and_then(|mod_tail| {
Expand Down Expand Up @@ -349,7 +369,7 @@ fn get_string_property(device_type: io_registry_entry_t, property: &str) -> Resu
/// port numbers, and then formats them in a hierarchical form like “0-1.2.4”.
fn location_to_string(location_id: u32) -> String {
let mut location_id = location_id;
let bus_id = format!("{:02x}", (location_id >> 24) as u8);
let bus_id = format!("{:02x}", (location_id >> 24) as u8);
let mut path = format!("{bus_id}-");
while location_id & 0xf00000 != 0 {
let item = (location_id >> 20) & 0xf;
Expand Down

0 comments on commit 7e079cc

Please sign in to comment.