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