impl Debug for descriptors

This commit is contained in:
Kevin Mehall 2023-12-16 23:05:03 -07:00
parent 424e0b4d92
commit de7881821c
3 changed files with 56 additions and 28 deletions

View file

@ -20,35 +20,19 @@ fn inspect_device(dev: DeviceInfo) {
let dev = match dev.open() { let dev = match dev.open() {
Ok(dev) => dev, Ok(dev) => dev,
Err(e) => { Err(e) => {
println!(" Failed to open device: {}", e); println!("Failed to open device: {}", e);
return; return;
} }
}; };
match dev.active_configuration() { match dev.active_configuration() {
Ok(config) => println!(" Active configuration is {}", config.configuration_value()), Ok(config) => println!("Active configuration is {}", config.configuration_value()),
Err(e) => println!("Unknown active configuration: {e}"), Err(e) => println!("Unknown active configuration: {e}"),
} }
for config in dev.configurations() { for config in dev.configurations() {
println!(" Configuration {}", config.configuration_value()); println!("{config:#?}");
for intf in config.interfaces() {
for alt in intf.alt_settings() {
println!(
" Interface {}, alt setting {}",
alt.interface_number(),
alt.alternate_setting()
);
for ep in alt.endpoints() {
println!(
" Endpoint {:02x} {:?} {:?}",
ep.address(),
ep.transfer_type(),
ep.direction()
);
}
}
}
} }
println!(""); println!("");
println!("");
} }

View file

@ -5,12 +5,7 @@ use libfuzzer_sys::fuzz_target;
fuzz_target!(|data: &[u8]| { fuzz_target!(|data: &[u8]| {
for config in nusb::descriptors::fuzz_parse_concatenated_config_descriptors(data) { for config in nusb::descriptors::fuzz_parse_concatenated_config_descriptors(data) {
let config = nusb::descriptors::Configuration::new(config); let config = nusb::descriptors::Configuration::new(config);
for interface in config.interfaces() { let s = format!("{config:?}");
for alt in interface.alt_settings() { std::hint::black_box(s);
for endpoint in alt.endpoints() {
std::hint::black_box(endpoint);
}
}
}
} }
}); });

View file

@ -2,7 +2,7 @@
//! //!
//! Descriptors are blocks of data that describe the functionality of a USB device. //! Descriptors are blocks of data that describe the functionality of a USB device.
use std::{collections::BTreeMap, fmt::Display, io::ErrorKind, iter, ops::Deref}; use std::{collections::BTreeMap, fmt::{Display, Debug}, io::ErrorKind, iter, ops::Deref};
use log::warn; use log::warn;
@ -285,6 +285,27 @@ impl<'a> Configuration<'a> {
} }
} }
struct DebugEntries<F>(F);
impl<F, I> Debug for DebugEntries<F> where F: Fn() -> I, I: Iterator, I::Item: Debug {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_list().entries(self.0()).finish()
}
}
impl<'a> Debug for Configuration<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Configuration")
.field("configuration_value", &self.configuration_value())
.field("num_interfaces", &self.num_interfaces())
.field("attributes", &self.attributes())
.field("max_power", &self.max_power())
.field("string_index", &self.string_index())
.field("interface_alt_settings", &DebugEntries(|| self.interface_alt_settings()))
.finish()
}
}
/// Interface descriptors for alternate settings, grouped by the interface number. /// Interface descriptors for alternate settings, grouped by the interface number.
#[derive(Clone)] #[derive(Clone)]
pub struct InterfaceGroup<'a> { pub struct InterfaceGroup<'a> {
@ -371,6 +392,21 @@ impl<'a> InterfaceAltSetting<'a> {
} }
} }
impl<'a> Debug for InterfaceAltSetting<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("InterfaceAltSetting")
.field("interface_number", &self.interface_number())
.field("alternate_setting", &self.alternate_setting())
.field("num_endpoints", &self.num_endpoints())
.field("class", &self.class())
.field("subclass", &self.subclass())
.field("protocol", &self.protocol())
.field("string_index", &self.string_index())
.field("endpoints", &DebugEntries(|| self.endpoints()))
.finish()
}
}
/// Information about a USB endpoint, with access to any associated descriptors. /// Information about a USB endpoint, with access to any associated descriptors.
pub struct Endpoint<'a>(&'a [u8]); pub struct Endpoint<'a>(&'a [u8]);
@ -435,6 +471,19 @@ descriptor_fields! {
} }
} }
impl<'a> Debug for Endpoint<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Endpoint")
.field("address", &format_args!("0x{:02X}", self.address()))
.field("direction", &self.direction())
.field("transfer_type", &self.transfer_type())
.field("max_packet_size", &self.max_packet_size())
.field("packets_per_microframe", &self.packets_per_microframe())
.field("interval", &self.interval())
.finish()
}
}
/// Error from [`crate::Device::active_configuration`] /// Error from [`crate::Device::active_configuration`]
#[derive(Copy, Clone, Debug, PartialEq, Eq)] #[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct ActiveConfigurationError { pub struct ActiveConfigurationError {