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