Add usb version to device info (#123)

Introduced a new `usb_version` field to represent the encoded USB specification version (`bcdUSB`) in DeviceInfo struct. This change includes updates to data structure, a new accessor method, and enhanced debug formatting to display the `usb_version` field.
This commit is contained in:
pgorgon-hem 2025-04-02 03:32:10 +02:00 committed by GitHub
parent a243514f58
commit f10a5f2c22
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 23 additions and 3 deletions

View file

@ -60,6 +60,7 @@ pub struct DeviceInfo {
pub(crate) product_id: u16,
pub(crate) device_version: u16,
pub(crate) usb_version: u16,
pub(crate) class: u8,
pub(crate) subclass: u8,
pub(crate) protocol: u8,
@ -200,6 +201,12 @@ impl DeviceInfo {
self.device_version
}
/// Encoded version of the USB specification, from the `bcdUSB` device descriptor field.
#[doc(alias = "bcdUSB")]
pub fn usb_version(&self) -> u16 {
self.usb_version
}
/// Code identifying the standard device class, from the `bDeviceClass` device descriptor field.
///
/// `0x00`: specified at the interface level.\
@ -296,6 +303,7 @@ impl std::fmt::Debug for DeviceInfo {
"device_version",
&format_args!("0x{:04X}", self.device_version),
)
.field("usb_version", &format_args!("0x{:04X}", self.usb_version))
.field("class", &format_args!("0x{:02X}", self.class))
.field("subclass", &format_args!("0x{:02X}", self.subclass))
.field("protocol", &format_args!("0x{:02X}", self.protocol))

View file

@ -1,12 +1,11 @@
use log::debug;
use log::warn;
use std::fs;
use std::io;
use std::num::ParseIntError;
use std::path::PathBuf;
use std::str::FromStr;
use log::debug;
use log::warn;
use crate::enumeration::InterfaceInfo;
use crate::maybe_future::{MaybeFuture, Ready};
use crate::{BusInfo, DeviceInfo, Error, Speed, UsbControllerType};
@ -74,6 +73,16 @@ impl SysfsPath {
self.parse_attr(attr, |s| T::from_hex_str(s.strip_prefix("0x").unwrap_or(s)))
}
fn read_version_attr(&self, attr: &str) -> Result<u16, SysfsError> {
// in sysfs bcdUSB is parsed to `x.yz`, so we have to parse it back. It should be coded in bcd, so we can treat parts as hex.
self.parse_attr(attr, |s| {
s.to_owned()
.split('.')
.map(|x| u16::from_hex_str(x))
.fold(Ok::<u16, ParseIntError>(0), |a, b| Ok((a? << 8) + b?))
})
}
pub(crate) fn readlink_attr_filename(&self, attr: &str) -> Result<String, SysfsError> {
self.readlink_attr(attr).map(|p| {
p.file_name()
@ -214,6 +223,7 @@ pub fn probe_device(path: SysfsPath) -> Result<DeviceInfo, SysfsError> {
vendor_id: path.read_attr_hex("idVendor")?,
product_id: path.read_attr_hex("idProduct")?,
device_version: path.read_attr_hex("bcdDevice")?,
usb_version: path.read_version_attr("version")?,
class: path.read_attr_hex("bDeviceClass")?,
subclass: path.read_attr_hex("bDeviceSubClass")?,
protocol: path.read_attr_hex("bDeviceProtocol")?,

View file

@ -124,6 +124,7 @@ pub(crate) fn probe_device(device: IoService) -> Option<DeviceInfo> {
vendor_id: get_integer_property(&device, "idVendor")? as u16,
product_id: get_integer_property(&device, "idProduct")? as u16,
device_version: get_integer_property(&device, "bcdDevice")? as u16,
usb_version: get_integer_property(&device, "bcdUSB")? as u16,
class: get_integer_property(&device, "bDeviceClass")? as u8,
subclass: get_integer_property(&device, "bDeviceSubClass")? as u8,
protocol: get_integer_property(&device, "bDeviceProtocol")? as u8,

View file

@ -142,6 +142,7 @@ pub fn probe_device(devinst: DevInst) -> Option<DeviceInfo> {
vendor_id: info.device_desc.idVendor,
product_id: info.device_desc.idProduct,
device_version: info.device_desc.bcdDevice,
usb_version: info.device_desc.bcdUSB,
class: info.device_desc.bDeviceClass,
subclass: info.device_desc.bDeviceSubClass,
protocol: info.device_desc.bDeviceProtocol,