usb_if/descriptor/
mod.rs

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    // Reserved 6
26    // Reserved 7
27    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    /// 类特定描述符数据(如 UVC 的格式和帧描述符)
89    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/// Endpoint type.
99#[derive(Debug, Copy, Clone, PartialEq, Eq)]
100pub enum EndpointType {
101    /// Control endpoint.
102    Control = 0,
103
104    /// Isochronous endpoint.
105    Isochronous = 1,
106
107    /// Bulk endpoint.
108    Bulk = 2,
109
110    /// Interrupt endpoint.
111    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        // DCI = (endpoint_number * 2) + direction
127        // Control endpoint always has DCI 1
128        let endpoint_number = self.address & 0x0F; // Extract endpoint number (low 4 bits)
129        (endpoint_number * 2)
130            + match self.transfer_type {
131                EndpointType::Control => 1, // Control endpoint always has DCI 1
132                _ => {
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(), // parser 模式不提取 extra 数据
233        }
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}