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