Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 33 additions & 33 deletions src/descriptors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,9 +403,9 @@ pub(crate) fn validate_config_descriptor(buf: &[u8]) -> Option<usize> {

/// Information about a USB configuration with access to all associated interfaces, endpoints, and other descriptors.
#[derive(Clone)]
pub struct Configuration<'a>(&'a [u8]);
pub struct ConfigurationDescriptor<'a>(&'a [u8]);

impl<'a> Configuration<'a> {
impl<'a> ConfigurationDescriptor<'a> {
/// Create a `Configuration` from a buffer containing a series of descriptors.
///
/// You normally obtain a `Configuration` from a [`Device`][crate::Device], but this allows creating
Expand All @@ -415,12 +415,12 @@ impl<'a> Configuration<'a> {
/// * when the buffer is too short for a configuration descriptor
/// * when the bLength and wTotalLength fields are longer than the buffer
/// * when the first descriptor is not a configuration descriptor
pub fn new(buf: &[u8]) -> Configuration {
pub fn new(buf: &[u8]) -> ConfigurationDescriptor {
assert!(buf.len() >= DESCRIPTOR_LEN_CONFIGURATION as usize);
assert!(buf[0] as usize >= DESCRIPTOR_LEN_CONFIGURATION as usize);
assert!(buf[1] == DESCRIPTOR_TYPE_CONFIGURATION);
assert!(buf.len() == u16::from_le_bytes(buf[2..4].try_into().unwrap()) as usize);
Configuration(buf)
ConfigurationDescriptor(buf)
}

/// Get the configuration descriptor followed by all trailing interface and other descriptors.
Expand All @@ -429,14 +429,14 @@ impl<'a> Configuration<'a> {
}

/// Iterate all interfaces and alternate settings settings of this configuration.
pub fn interface_alt_settings(&self) -> impl Iterator<Item = InterfaceAltSetting<'a>> {
pub fn interface_alt_settings(&self) -> impl Iterator<Item = InterfaceDescriptor<'a>> {
self.descriptors()
.split_by_type(DESCRIPTOR_TYPE_INTERFACE, DESCRIPTOR_LEN_INTERFACE)
.map(InterfaceAltSetting)
.map(InterfaceDescriptor)
}

/// Iterate the interfaces of this configuration, grouping together alternate settings of the same interface.
pub fn interfaces(&self) -> impl Iterator<Item = InterfaceGroup<'a>> {
pub fn interfaces(&self) -> impl Iterator<Item = InterfaceDescriptors<'a>> {
let mut interfaces = BTreeMap::new();

for intf in self.interface_alt_settings() {
Expand All @@ -448,15 +448,15 @@ impl<'a> Configuration<'a> {

interfaces
.into_iter()
.map(|(intf_number, interfaces)| InterfaceGroup {
.map(|(intf_number, interfaces)| InterfaceDescriptors {
intf_number,
interfaces,
})
}
}

descriptor_fields! {
impl<'a> Configuration<'a> {
impl<'a> ConfigurationDescriptor<'a> {
/// `bNumInterfaces` descriptor field: Number of interfaces.
#[doc(alias = "bNumInterfaces")]
pub fn num_interfaces at 4 -> u8;
Expand All @@ -481,7 +481,7 @@ descriptor_fields! {
}
}

impl<'a> Configuration<'a> {
impl<'a> ConfigurationDescriptor<'a> {
/// Index of the string descriptor describing this configuration.
#[doc(alias = "iConfiguration")]
pub fn string_index(&self) -> Option<u8> {
Expand All @@ -502,7 +502,7 @@ where
}
}

impl<'a> Debug for Configuration<'a> {
impl<'a> Debug for ConfigurationDescriptor<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Configuration")
.field("configuration_value", &self.configuration_value())
Expand All @@ -520,12 +520,12 @@ impl<'a> Debug for Configuration<'a> {

/// Interface descriptors for alternate settings, grouped by the interface number.
#[derive(Clone)]
pub struct InterfaceGroup<'a> {
pub struct InterfaceDescriptors<'a> {
intf_number: u8,
interfaces: Vec<InterfaceAltSetting<'a>>,
interfaces: Vec<InterfaceDescriptor<'a>>,
}

impl<'a> InterfaceGroup<'a> {
impl<'a> InterfaceDescriptors<'a> {
/// `bInterfaceNumber` descriptor field: Identifier for the interface.
///
/// Pass this to [`Device::claim_interface`][crate::Device::claim_interface] to work with the interface.
Expand All @@ -535,14 +535,14 @@ impl<'a> InterfaceGroup<'a> {
}

/// Iterator over alternate settings of the interface.
pub fn alt_settings(&self) -> impl Iterator<Item = InterfaceAltSetting> {
pub fn alt_settings(&self) -> impl Iterator<Item = InterfaceDescriptor<'a>> + '_ {
self.interfaces.iter().cloned()
}

/// Get the descriptor for the first alt setting.
///
/// There is guaranteed to be at least one alt setting or this would not have been found.
pub fn first_alt_setting(&self) -> InterfaceAltSetting<'a> {
pub fn first_alt_setting(&self) -> InterfaceDescriptor<'a> {
self.interfaces[0].clone()
}
}
Expand All @@ -553,25 +553,25 @@ impl<'a> InterfaceGroup<'a> {
/// an interface. Multiple interface descriptors with the same [`interface_number`][Self::interface_number]
/// but different [`alternate_setting`][Self::alternate_setting] values represent different alternate settings.
#[derive(Clone)]
pub struct InterfaceAltSetting<'a>(&'a [u8]);
pub struct InterfaceDescriptor<'a>(&'a [u8]);

impl<'a> InterfaceAltSetting<'a> {
impl<'a> InterfaceDescriptor<'a> {
/// Get the interface descriptor followed by all trailing endpoint and other
/// descriptors up to the next interface descriptor.
pub fn descriptors(&self) -> Descriptors {
pub fn descriptors(&self) -> Descriptors<'a> {
Descriptors(self.0)
}

/// Get the endpoints of this interface.
pub fn endpoints(&self) -> impl Iterator<Item = Endpoint> {
pub fn endpoints(&self) -> impl Iterator<Item = EndpointDescriptor<'a>> {
self.descriptors()
.split_by_type(DESCRIPTOR_TYPE_ENDPOINT, DESCRIPTOR_LEN_ENDPOINT)
.map(Endpoint)
.map(EndpointDescriptor)
}
}

descriptor_fields! {
impl<'a> InterfaceAltSetting<'a> {
impl<'a> InterfaceDescriptor<'a> {
/// `bInterfaceNumber` descriptor field: Identifier for the interface.
///
/// Pass this to [`Device::claim_interface`][crate::Device::claim_interface] to work with the interface.
Expand Down Expand Up @@ -604,15 +604,15 @@ descriptor_fields! {
}
}

impl<'a> InterfaceAltSetting<'a> {
impl<'a> InterfaceDescriptor<'a> {
/// Index of the string descriptor describing this interface or alternate setting.
#[doc(alias = "iInterface")]
pub fn string_index(&self) -> Option<u8> {
Some(self.string_index_raw()).filter(|&i| i != 0)
}
}

impl<'a> Debug for InterfaceAltSetting<'a> {
impl<'a> Debug for InterfaceDescriptor<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("InterfaceAltSetting")
.field("interface_number", &self.interface_number())
Expand All @@ -628,11 +628,11 @@ impl<'a> Debug for InterfaceAltSetting<'a> {
}

/// Information about a USB endpoint, with access to any associated descriptors.
pub struct Endpoint<'a>(&'a [u8]);
pub struct EndpointDescriptor<'a>(&'a [u8]);

impl<'a> Endpoint<'a> {
impl<'a> EndpointDescriptor<'a> {
/// Get the endpoint descriptor followed by all trailing descriptors up to the next endpoint or interface descriptor.
pub fn descriptors(&self) -> impl Iterator<Item = Descriptor> {
pub fn descriptors(&self) -> impl Iterator<Item = Descriptor<'a>> {
Descriptors(self.0)
}

Expand Down Expand Up @@ -667,7 +667,7 @@ impl<'a> Endpoint<'a> {
}

descriptor_fields! {
impl<'a> Endpoint<'a> {
impl<'a> EndpointDescriptor<'a> {
/// Get the `bEndpointAddress` descriptor field: Endpoint address.
#[doc(alias = "bEndpointAddress")]
pub fn address at 2 -> u8;
Expand All @@ -691,7 +691,7 @@ descriptor_fields! {
}
}

impl<'a> Debug for Endpoint<'a> {
impl<'a> Debug for EndpointDescriptor<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Endpoint")
.field("address", &format_args!("0x{:02X}", self.address()))
Expand Down Expand Up @@ -828,7 +828,7 @@ mod test_concatenated {

#[test]
fn test_empty_config() {
let c = Configuration(&[9, 2, 9, 0, 0, 1, 0, 0, 250]);
let c = ConfigurationDescriptor(&[9, 2, 9, 0, 0, 1, 0, 0, 250]);
assert_eq!(c.num_interfaces(), 0);
assert_eq!(c.configuration_value(), 1);
assert_eq!(c.string_index(), None);
Expand All @@ -837,7 +837,7 @@ fn test_empty_config() {

#[test]
fn test_malformed() {
let c = Configuration(&[9, 2, 0, 0, 0, 1, 0, 0, 2, 5, 250, 0, 0, 0]);
let c = ConfigurationDescriptor(&[9, 2, 0, 0, 0, 1, 0, 0, 2, 5, 250, 0, 0, 0]);
assert!(c.interfaces().next().is_none());
}

Expand All @@ -861,7 +861,7 @@ fn test_linux_root_hub() {
assert_eq!(dev.serial_number_string_index(), Some(1));
assert_eq!(dev.num_configurations(), 1);

let c = Configuration(&[
let c = ConfigurationDescriptor(&[
0x09, 0x02, 0x19, 0x00, 0x01, 0x01, 0x00, 0xe0, 0x00,
0x09, 0x04, 0x00, 0x00, 0x01, 0x09, 0x00, 0x00, 0x00,
0x07, 0x05, 0x81, 0x03, 0x04, 0x00, 0x0c
Expand Down Expand Up @@ -897,7 +897,7 @@ fn test_linux_root_hub() {
#[test]
#[rustfmt::skip]
fn test_dell_webcam() {
let c = Configuration(&[
let c = ConfigurationDescriptor(&[
0x09, 0x02, 0xa3, 0x02, 0x02, 0x01, 0x00, 0x80, 0xfa,

// unknown (skipped)
Expand Down
14 changes: 8 additions & 6 deletions src/device.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{
descriptors::{
decode_string_descriptor, validate_string_descriptor, ActiveConfigurationError,
Configuration, DeviceDescriptor, InterfaceAltSetting, DESCRIPTOR_TYPE_STRING,
ConfigurationDescriptor, DeviceDescriptor, InterfaceDescriptor, DESCRIPTOR_TYPE_STRING,
},
platform,
transfer::{
Expand Down Expand Up @@ -118,7 +118,9 @@ impl Device {
/// This returns cached data and does not perform IO. However, it can fail if the
/// device is unconfigured, or if it can't find a configuration descriptor for
/// the configuration reported as active by the OS.
pub fn active_configuration(&self) -> Result<Configuration, ActiveConfigurationError> {
pub fn active_configuration(
&self,
) -> Result<ConfigurationDescriptor, ActiveConfigurationError> {
let active = self.backend.active_configuration_value();

self.configurations()
Expand All @@ -131,10 +133,10 @@ impl Device {
/// Get an iterator returning information about each configuration of the device.
///
/// This returns cached data and does not perform IO.
pub fn configurations(&self) -> impl Iterator<Item = Configuration> {
pub fn configurations(&self) -> impl Iterator<Item = ConfigurationDescriptor> {
self.backend
.configuration_descriptors()
.map(Configuration::new)
.map(ConfigurationDescriptor::new)
}

/// Set the device configuration.
Expand Down Expand Up @@ -596,14 +598,14 @@ impl Interface {
/// Get the interface descriptors for the alternate settings of this interface.
///
/// This returns cached data and does not perform IO.
pub fn descriptors(&self) -> impl Iterator<Item = InterfaceAltSetting> {
pub fn descriptors(&self) -> impl Iterator<Item = InterfaceDescriptor> {
let active = self.backend.device.active_configuration_value();

let configuration = self
.backend
.device
.configuration_descriptors()
.map(Configuration::new)
.map(ConfigurationDescriptor::new)
.find(|c| c.configuration_value() == active);

configuration
Expand Down
4 changes: 2 additions & 2 deletions src/platform/linux_usbfs/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use super::{
usbfs::{self, Urb},
SysfsPath,
};
use crate::descriptors::{validate_device_descriptor, Configuration, DeviceDescriptor};
use crate::descriptors::{validate_device_descriptor, ConfigurationDescriptor, DeviceDescriptor};
use crate::maybe_future::{blocking::Blocking, MaybeFuture};
use crate::platform::linux_usbfs::events::Watch;
use crate::transfer::{ControlType, Recipient};
Expand Down Expand Up @@ -422,7 +422,7 @@ impl LinuxDevice {
// See: https://github.com/libusb/libusb/blob/467b6a8896daea3d104958bf0887312c5d14d150/libusb/os/linux_usbfs.c#L865
let mut descriptors =
parse_concatenated_config_descriptors(&descriptors[DESCRIPTOR_LEN_DEVICE as usize..])
.map(Configuration::new);
.map(ConfigurationDescriptor::new);

if let Some(config) = descriptors.next() {
return Ok(config.configuration_value());
Expand Down
4 changes: 2 additions & 2 deletions src/platform/windows_winusb/enumeration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use windows_sys::Win32::Devices::{
use crate::{
descriptors::{
decode_string_descriptor, language_id::US_ENGLISH, validate_config_descriptor,
Configuration, DESCRIPTOR_TYPE_CONFIGURATION, DESCRIPTOR_TYPE_STRING,
ConfigurationDescriptor, DESCRIPTOR_TYPE_CONFIGURATION, DESCRIPTOR_TYPE_STRING,
},
maybe_future::{blocking::Blocking, MaybeFuture},
BusInfo, DeviceInfo, Error, InterfaceInfo, UsbControllerType,
Expand Down Expand Up @@ -207,7 +207,7 @@ fn list_interfaces_from_desc(hub_port: &HubPort, active_config: u8) -> Option<Ve
)
.ok()?;
let len = validate_config_descriptor(&buf)?;
let desc = Configuration::new(&buf[..len]);
let desc = ConfigurationDescriptor::new(&buf[..len]);

if desc.configuration_value() != active_config {
return None;
Expand Down
Loading