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}
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)]
50pub struct DeviceDescriptor {
51 pub usb_version: u16,
52 pub class: u8,
53 pub subclass: u8,
54 pub protocol: u8,
55 pub max_packet_size_0: u8,
56 pub vendor_id: u16,
57 pub product_id: u16,
58 pub device_version: u16,
59 pub manufacturer_string_index: Option<NonZero<u8>>,
60 pub product_string_index: Option<NonZero<u8>>,
61 pub serial_number_string_index: Option<NonZero<u8>>,
62 pub num_configurations: u8,
63}
64
65impl DeviceDescriptor {
66 pub fn parse(data: &[u8]) -> Option<Self> {
67 parser::DeviceDescriptor::new(data).map(Into::into)
68 }
69
70 pub const LEN: usize = 18;
71
72 pub fn class(&self) -> Class {
73 Class::from_class_and_subclass(self.class, self.subclass, self.protocol)
74 }
75}
76
77#[derive(Debug, Clone)]
78pub struct InterfaceDescriptor {
79 pub interface_number: u8,
80 pub alternate_setting: u8,
81 pub class: u8,
82 pub subclass: u8,
83 pub protocol: u8,
84 pub string_index: Option<NonZero<u8>>,
85 pub string: Option<String>,
86 pub num_endpoints: u8,
87 pub endpoints: Vec<EndpointDescriptor>,
88 pub extra: Vec<u8>,
90}
91
92impl InterfaceDescriptor {
93 pub fn class(&self) -> Class {
94 Class::from_class_and_subclass(self.class, self.subclass, self.protocol)
95 }
96}
97
98#[derive(Debug, Copy, Clone, PartialEq, Eq)]
100pub enum EndpointType {
101 Control = 0,
103
104 Isochronous = 1,
106
107 Bulk = 2,
109
110 Interrupt = 3,
112}
113
114#[derive(Debug, Clone)]
115pub struct EndpointDescriptor {
116 pub address: u8,
117 pub max_packet_size: u16,
118 pub transfer_type: EndpointType,
119 pub direction: Direction,
120 pub packets_per_microframe: usize,
121 pub interval: u8,
122}
123
124impl EndpointDescriptor {
125 pub fn dci(&self) -> u8 {
126 let endpoint_number = self.address & 0x0F; (endpoint_number * 2)
130 + match self.transfer_type {
131 EndpointType::Control => 1, _ => {
133 if self.direction == Direction::In {
134 1
135 } else {
136 0
137 }
138 }
139 }
140 }
141}
142
143#[derive(Debug, Clone)]
144pub struct InterfaceDescriptors {
145 pub interface_number: u8,
146 pub alt_settings: Vec<InterfaceDescriptor>,
147}
148
149impl InterfaceDescriptors {
150 pub fn first_alt_setting(&self) -> InterfaceDescriptor {
151 self.alt_settings.first().cloned().unwrap()
152 }
153}
154
155#[derive(Debug, Clone)]
156pub struct ConfigurationDescriptor {
157 pub num_interfaces: u8,
158 pub configuration_value: u8,
159 pub attributes: u8,
160 pub max_power: u8,
161 pub string_index: Option<NonZero<u8>>,
162 pub string: Option<String>,
163 pub interfaces: Vec<InterfaceDescriptors>,
164}
165
166impl ConfigurationDescriptor {
167 pub fn parse(data: &[u8]) -> Option<Self> {
168 parser::ConfigurationDescriptor::new(data).map(Into::into)
169 }
170
171 pub const LEN: usize = 9;
172}
173
174impl From<parser::DeviceDescriptor> for DeviceDescriptor {
175 fn from(desc: parser::DeviceDescriptor) -> Self {
176 DeviceDescriptor {
177 usb_version: desc.usb_version(),
178 class: desc.class(),
179 subclass: desc.subclass(),
180 protocol: desc.protocol(),
181 max_packet_size_0: desc.max_packet_size_0(),
182 vendor_id: desc.vendor_id(),
183 product_id: desc.product_id(),
184 device_version: desc.device_version(),
185 manufacturer_string_index: desc.manufacturer_string_index(),
186 product_string_index: desc.product_string_index(),
187 serial_number_string_index: desc.serial_number_string_index(),
188 num_configurations: desc.num_configurations(),
189 }
190 }
191}
192
193impl From<parser::EndpointDescriptor<'_>> for EndpointDescriptor {
194 fn from(desc: parser::EndpointDescriptor) -> Self {
195 EndpointDescriptor {
196 address: desc.address(),
197 max_packet_size: desc.max_packet_size() as _,
198 direction: desc.direction(),
199 transfer_type: desc.transfer_type(),
200 packets_per_microframe: desc.packets_per_microframe() as usize,
201 interval: desc.interval(),
202 }
203 }
204}
205
206impl From<parser::ConfigurationDescriptor<'_>> for ConfigurationDescriptor {
207 fn from(desc: parser::ConfigurationDescriptor) -> Self {
208 ConfigurationDescriptor {
209 num_interfaces: desc.num_interfaces(),
210 configuration_value: desc.configuration_value(),
211 attributes: desc.attributes(),
212 max_power: desc.max_power(),
213 string_index: desc.string_index(),
214 interfaces: desc.interfaces().map(InterfaceDescriptors::from).collect(),
215 string: None,
216 }
217 }
218}
219
220impl From<parser::InterfaceDescriptor<'_>> for InterfaceDescriptor {
221 fn from(desc: parser::InterfaceDescriptor) -> Self {
222 InterfaceDescriptor {
223 interface_number: desc.interface_number(),
224 alternate_setting: desc.alternate_setting(),
225 class: desc.class(),
226 subclass: desc.subclass(),
227 protocol: desc.protocol(),
228 string_index: desc.string_index(),
229 num_endpoints: desc.num_endpoints(),
230 endpoints: desc.endpoints().map(EndpointDescriptor::from).collect(),
231 string: None,
232 extra: Vec::new(), }
234 }
235}
236
237impl From<parser::InterfaceDescriptors<'_>> for InterfaceDescriptors {
238 fn from(desc: parser::InterfaceDescriptors) -> Self {
239 InterfaceDescriptors {
240 interface_number: desc.interface_number(),
241 alt_settings: desc.alt_settings().map(InterfaceDescriptor::from).collect(),
242 }
243 }
244}