Skip to content

Commit

Permalink
Linux: Support getting DeviceDescriptor and DeviceInfo from a opened …
Browse files Browse the repository at this point in the history
…device
  • Loading branch information
kirisauce committed Jan 8, 2025
1 parent 91fe523 commit 2c6a6d3
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 2 deletions.
30 changes: 30 additions & 0 deletions src/descriptors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,36 @@ macro_rules! descriptor_fields {
}
}

/// Check whether the buffer contains a valid device descriptor.
/// On success, it will return length of the descriptor, or returns `None`.
pub(crate) fn validate_device_descriptor(buf: &[u8]) -> Option<usize> {
if buf.len() < DESCRIPTOR_LEN_DEVICE as usize {
if buf.len() != 0 {
warn!(
"device descriptor buffer is {} bytes, need {}",
buf.len(),
DESCRIPTOR_LEN_DEVICE
);
}
return None;
}

if buf[0] < DESCRIPTOR_LEN_DEVICE {
warn!("invalid device descriptor bLength");
return None;
}

if buf[1] != DESCRIPTOR_TYPE_DEVICE {
warn!(
"device bDescriptorType is {}, not a device descriptor",
buf[1]
);
return None;
}

return Some(buf[0] as usize);
}

/// Information about a USB device.
#[derive(Clone)]
pub struct DeviceDescriptor<'a>(&'a [u8]);
Expand Down
21 changes: 19 additions & 2 deletions src/device.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::{
descriptors::{
decode_string_descriptor, validate_string_descriptor, ActiveConfigurationError,
Configuration, InterfaceAltSetting, DESCRIPTOR_TYPE_STRING,
decode_string_descriptor, validate_device_descriptor, validate_string_descriptor,
ActiveConfigurationError, Configuration, DeviceDescriptor, InterfaceAltSetting,
DESCRIPTOR_TYPE_STRING,
},
platform,
transfer::{
Expand Down Expand Up @@ -341,6 +342,22 @@ impl Device {
t.submit::<ControlOut>(data);
TransferFuture::new(t)
}

/// Get the device descriptor.
///
/// The only situation when it returns `None` is
/// that the cached descriptors contain no valid device descriptor.
///
/// ### Platform-specific notes
///
/// * This is only supported on Linux at present.
/// * On Linux, this method uses descriptors cached in memory, instead
/// of sending a request to the device for a descriptor.
#[cfg(any(target_os = "linux", target_os = "android"))]
pub fn device_descriptor(&self) -> Option<DeviceDescriptor> {
let buf = self.backend.descriptors();
validate_device_descriptor(&buf).map(|len| DeviceDescriptor::new(&buf[0..len]))
}
}

/// An opened interface of a USB device.
Expand Down
4 changes: 4 additions & 0 deletions src/platform/linux_usbfs/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,10 @@ impl LinuxDevice {
);
return Err(ErrorKind::Other.into());
}

pub(crate) fn descriptors(&self) -> &[u8] {
&self.descriptors
}
}

impl Drop for LinuxDevice {
Expand Down

0 comments on commit 2c6a6d3

Please sign in to comment.