1use alloc::{string::String, vec::Vec};
2use core::num::NonZero;
3
4use crate::transfer::Direction;
5
6mod class_code;
7mod lang_id;
8mod parser;
9
10pub use class_code::*;
11pub use lang_id::*;
12pub use parser::decode_string_descriptor;
13
14#[repr(C)]
15#[derive(Debug, Clone)]
16pub struct DescriptorType(pub u8);
17
18impl DescriptorType {
19 pub const DEVICE: Self = Self(0x01);
20 pub const CONFIGURATION: Self = Self(0x02);
21 pub const STRING: Self = Self(0x03);
22 pub const INTERFACE: Self = Self(0x04);
23 pub const ENDPOINT: Self = Self(0x05);
24 pub const INTERFACE_POWER: Self = Self(0x08);
27 pub const OTG: Self = Self(0x09);
28 pub const DEBUG: Self = Self(0x0A);
29 pub const INTERFACE_ASSOCIATION: Self = Self(0x0B);
30 pub const BOS: Self = Self(0x0F);
31 pub const DEVICE_CAPABILITY: Self = Self(0x10);
32 pub const SUPERSPEED_USB_ENDPOINT_COMPANION: Self = Self(0x30);
33 pub const SUPERSPEEDPLUS_ISOCHRONOUS_ENDPOINT_COMPANION: Self = Self(0x31);
34 pub const HUB: Self = Self(0x29);
35}
36
37impl From<u8> for DescriptorType {
38 fn from(value: u8) -> Self {
39 Self(value)
40 }
41}
42
43impl From<DescriptorType> for u8 {
44 fn from(desc_type: DescriptorType) -> Self {
45 desc_type.0
46 }
47}
48
49#[derive(Debug, Clone, Copy)]
50#[repr(C)]
51pub struct DeviceDescriptorBase {
52 pub length: u8,
53 pub descriptor_type: u8,
54 pub usb_version: u16,
55 pub class: u8,
56 pub subclass: u8,
57 pub protocol: u8,
58 pub max_packet_size_0: u8,
59}
60
61impl DeviceDescriptorBase {
62 pub fn class(&self) -> Class {
63 Class::from_class_and_subclass(self.class, self.subclass, self.protocol)
64 }
65}
66
67#[derive(Debug, Clone)]
68pub struct DeviceDescriptor {
69 pub usb_version: u16,
70 pub class: u8,
71 pub subclass: u8,
72 pub protocol: u8,
73 pub max_packet_size_0: u8,
74 pub vendor_id: u16,
75 pub product_id: u16,
76 pub device_version: u16,
77 pub manufacturer_string_index: Option<NonZero<u8>>,
78 pub product_string_index: Option<NonZero<u8>>,
79 pub serial_number_string_index: Option<NonZero<u8>>,
80 pub num_configurations: u8,
81}
82
83impl DeviceDescriptor {
84 pub fn parse(data: &[u8]) -> Option<Self> {
85 parser::DeviceDescriptor::new(data).map(Into::into)
86 }
87
88 pub const LEN: usize = 18;
89
90 pub fn class(&self) -> Class {
91 Class::from_class_and_subclass(self.class, self.subclass, self.protocol)
92 }
93}
94
95#[derive(Debug, Clone)]
96pub struct InterfaceDescriptor {
97 pub interface_number: u8,
98 pub alternate_setting: u8,
99 pub class: u8,
100 pub subclass: u8,
101 pub protocol: u8,
102 pub string_index: Option<NonZero<u8>>,
103 pub string: Option<String>,
104 pub num_endpoints: u8,
105 pub endpoints: Vec<EndpointDescriptor>,
106}
107
108impl InterfaceDescriptor {
109 pub fn class(&self) -> Class {
110 Class::from_class_and_subclass(self.class, self.subclass, self.protocol)
111 }
112}
113
114#[derive(Debug, Copy, Clone, PartialEq, Eq)]
116pub enum EndpointType {
117 Control = 0,
119
120 Isochronous = 1,
122
123 Bulk = 2,
125
126 Interrupt = 3,
128}
129
130#[derive(Debug, Clone)]
131pub struct EndpointDescriptor {
132 pub address: u8,
133 pub max_packet_size: u16,
134 pub transfer_type: EndpointType,
135 pub direction: Direction,
136 pub packets_per_microframe: usize,
137 pub interval: u8,
138}
139
140impl EndpointDescriptor {
141 pub fn dci(&self) -> u8 {
142 let endpoint_number = self.address & 0x0F; (endpoint_number * 2)
146 + match self.transfer_type {
147 EndpointType::Control => 1, _ => {
149 if self.direction == Direction::In {
150 1
151 } else {
152 0
153 }
154 }
155 }
156 }
157}
158
159#[derive(Debug, Clone)]
160pub struct InterfaceDescriptors {
161 pub interface_number: u8,
162 pub alt_settings: Vec<InterfaceDescriptor>,
163}
164
165impl InterfaceDescriptors {
166 pub fn first_alt_setting(&self) -> InterfaceDescriptor {
167 self.alt_settings.first().cloned().unwrap()
168 }
169}
170
171#[derive(Debug, Clone)]
172pub struct ConfigurationDescriptor {
173 pub num_interfaces: u8,
174 pub configuration_value: u8,
175 pub attributes: u8,
176 pub max_power: u8,
177 pub string_index: Option<NonZero<u8>>,
178 pub string: Option<String>,
179 pub interfaces: Vec<InterfaceDescriptors>,
180 pub raw: Vec<u8>,
181}
182
183impl ConfigurationDescriptor {
184 pub fn parse(data: &[u8]) -> Option<Self> {
185 parser::ConfigurationDescriptor::new(data).map(Into::into)
186 }
187
188 pub const LEN: usize = 9;
189}
190
191impl From<parser::DeviceDescriptor> for DeviceDescriptor {
192 fn from(desc: parser::DeviceDescriptor) -> Self {
193 DeviceDescriptor {
194 usb_version: desc.usb_version(),
195 class: desc.class(),
196 subclass: desc.subclass(),
197 protocol: desc.protocol(),
198 max_packet_size_0: desc.max_packet_size_0(),
199 vendor_id: desc.vendor_id(),
200 product_id: desc.product_id(),
201 device_version: desc.device_version(),
202 manufacturer_string_index: desc.manufacturer_string_index(),
203 product_string_index: desc.product_string_index(),
204 serial_number_string_index: desc.serial_number_string_index(),
205 num_configurations: desc.num_configurations(),
206 }
207 }
208}
209
210impl From<parser::EndpointDescriptor<'_>> for EndpointDescriptor {
211 fn from(desc: parser::EndpointDescriptor) -> Self {
212 EndpointDescriptor {
213 address: desc.address(),
214 max_packet_size: desc.max_packet_size() as _,
215 direction: desc.direction(),
216 transfer_type: desc.transfer_type(),
217 packets_per_microframe: desc.packets_per_microframe() as usize,
218 interval: desc.interval(),
219 }
220 }
221}
222
223impl From<parser::ConfigurationDescriptor<'_>> for ConfigurationDescriptor {
224 fn from(desc: parser::ConfigurationDescriptor) -> Self {
225 ConfigurationDescriptor {
226 num_interfaces: desc.num_interfaces(),
227 configuration_value: desc.configuration_value(),
228 attributes: desc.attributes(),
229 max_power: desc.max_power(),
230 string_index: desc.string_index(),
231 interfaces: desc.interfaces().map(InterfaceDescriptors::from).collect(),
232 string: None,
233 raw: desc.as_bytes().to_vec(),
234 }
235 }
236}
237
238impl From<parser::InterfaceDescriptor<'_>> for InterfaceDescriptor {
239 fn from(desc: parser::InterfaceDescriptor) -> Self {
240 InterfaceDescriptor {
241 interface_number: desc.interface_number(),
242 alternate_setting: desc.alternate_setting(),
243 class: desc.class(),
244 subclass: desc.subclass(),
245 protocol: desc.protocol(),
246 string_index: desc.string_index(),
247 num_endpoints: desc.num_endpoints(),
248 endpoints: desc.endpoints().map(EndpointDescriptor::from).collect(),
249 string: None,
250 }
251 }
252}
253
254impl From<parser::InterfaceDescriptors<'_>> for InterfaceDescriptors {
255 fn from(desc: parser::InterfaceDescriptors) -> Self {
256 InterfaceDescriptors {
257 interface_number: desc.interface_number(),
258 alt_settings: desc.alt_settings().map(InterfaceDescriptor::from).collect(),
259 }
260 }
261}