usb_descriptor_decoder/descriptors/
mod.rs

1//TODO: Restruct code!
2use core::ptr;
3
4use desc_configuration::Configuration;
5use desc_device::Device;
6use desc_endpoint::Endpoint;
7use desc_hid::{HIDDescriptorTypes, Hid};
8use desc_interface::{Interface, InterfaceAssociation};
9use desc_str::Str;
10use desc_uvc::{
11    uvc_endpoints::UVCVideoControlInterruptEndpoint,
12    uvc_interfaces::{
13        UVCControlInterface, UVCInterface, UVCInterfaceSubclass, UVCStreamingInterface,
14    },
15    UVCDescriptorTypes,
16};
17use log::trace;
18use num_derive::{FromPrimitive, ToPrimitive};
19use num_traits::FromPrimitive;
20use parser::{Error, ParserMetaData};
21
22pub mod parser;
23pub mod topological_desc;
24
25pub mod desc_configuration;
26pub mod desc_device;
27pub mod desc_endpoint;
28pub mod desc_hid;
29pub mod desc_interface;
30pub mod desc_str;
31pub mod desc_uvc;
32
33#[allow(non_camel_case_types)]
34#[derive(FromPrimitive, ToPrimitive, Copy, Clone, Debug, PartialEq)]
35#[repr(u8)]
36pub enum USBStandardDescriptorTypes {
37    //USB 1.1: 9.4 Standard Device Requests, Table 9-5. Descriptor Types
38    Device = 0x01,
39    Configuration = 0x02,
40    String = 0x03,
41    Interface = 0x04,
42    Endpoint = 0x05,
43    // USB 2.0: 9.4 Standard Device Requests, Table 9-5. Descriptor Types
44    DeviceQualifier = 0x06,
45    OtherSpeedConfiguration = 0x07,
46    InterfacePower1 = 0x08,
47    // USB 3.0+: 9.4 Standard Device Requests, Table 9-5. Descriptor Types
48    OTG = 0x09,
49    Debug = 0x0a,
50    InterfaceAssociation = 0x0b,
51    Bos = 0x0f,
52    DeviceCapability = 0x10,
53    SuperSpeedEndpointCompanion = 0x30,
54    SuperSpeedPlusIsochEndpointCompanion = 0x31,
55}
56
57#[derive(Clone, Debug)]
58pub enum USBDescriptor {
59    Device(Device),
60    Configuration(Configuration),
61    Str(Str),
62    Interface(Interface),
63    InterfaceAssociation(InterfaceAssociation),
64    Endpoint(Endpoint),
65    Hid(Hid),
66    UVCInterface(UVCInterface),
67    UVCClassSpecVideoControlInterruptEndpoint(UVCVideoControlInterruptEndpoint),
68}
69
70impl USBDescriptor {
71    pub(crate) fn from_slice(raw: &[u8], metadata: ParserMetaData) -> Result<Self, Error> {
72        trace!("from slice! meta:{:?}", metadata);
73        assert_eq!(raw.len(), raw[0].into());
74        match Self::from_slice_standard_usb(raw) {
75            Ok(okay) => Ok(okay),
76            Err(_) if let ParserMetaData::HID = metadata => Self::from_slice_hid(raw),
77            Err(_) if let ParserMetaData::UVC(flag) = metadata => Self::from_slice_uvc(raw, flag),
78            Err(any) => panic!("unknown situation {:?},{:?}", any, metadata),
79        }
80    }
81
82    pub(crate) fn from_slice_uvc(raw: &[u8], flag: u8) -> Result<Self, Error> {
83        trace!("from slice uvc!{:?}", raw);
84        match UVCDescriptorTypes::from_u8(raw[1]).unwrap() {
85            UVCDescriptorTypes::UVCClassSpecUnderfined => panic!("underfined!"),
86            UVCDescriptorTypes::UVCClassSpecDevice => todo!(),
87            UVCDescriptorTypes::UVCClassSpecConfiguration => todo!(),
88            UVCDescriptorTypes::UVCClassSpecString => todo!(),
89            UVCDescriptorTypes::UVCClassSpecInterface => {
90                match UVCInterfaceSubclass::from_u8(if flag == 0 { raw[2] } else { flag }).unwrap()
91                {
92                    UVCInterfaceSubclass::UNDEFINED => panic!("impossible!"),
93                    UVCInterfaceSubclass::VIDEOCONTROL => Ok(Self::UVCInterface(
94                        UVCInterface::Control(UVCControlInterface::from_u8_array(raw)),
95                    )),
96                    UVCInterfaceSubclass::VIDEOSTREAMING => Ok(Self::UVCInterface(
97                        UVCInterface::Streaming(UVCStreamingInterface::from_u8_array(raw)),
98                    )),
99                    UVCInterfaceSubclass::VIDEO_INTERFACE_COLLECTION => {
100                        panic!("this subclass only appear in iac, impossible here!");
101                    }
102                }
103            }
104            UVCDescriptorTypes::UVCClassSpecVideoControlInterruptEndpoint => {
105                Ok(Self::UVCClassSpecVideoControlInterruptEndpoint(unsafe {
106                    ptr::read((raw as *const [u8]).cast())
107                }))
108            }
109        }
110    }
111
112    pub(crate) fn from_slice_hid(raw: &[u8]) -> Result<Self, Error> {
113        match HIDDescriptorTypes::from_u8(raw[1]).unwrap() {
114            HIDDescriptorTypes::Hid => {
115                Ok(Self::Hid(unsafe { ptr::read((raw as *const [u8]).cast()) }))
116            }
117            HIDDescriptorTypes::HIDReport => todo!(),
118            HIDDescriptorTypes::HIDPhysical => todo!(),
119        }
120    }
121
122    pub(crate) fn from_slice_standard_usb(raw: &[u8]) -> Result<Self, Error> {
123        trace!(
124            "try to parse slice from standard usb desc! type: {}",
125            raw[1]
126        );
127        match USBStandardDescriptorTypes::from_u8(raw[1]) {
128            Some(t) => {
129                let raw: *const [u8] = raw;
130                match t {
131                    // SAFETY: This operation is safe because the length of `raw` is equivalent to the
132                    // one of the descriptor.
133                    USBStandardDescriptorTypes::Device => {
134                        Ok(Self::Device(unsafe { ptr::read(raw.cast()) }))
135                    }
136                    USBStandardDescriptorTypes::Configuration => {
137                        Ok(Self::Configuration(unsafe { ptr::read(raw.cast()) }))
138                    }
139                    USBStandardDescriptorTypes::String => {
140                        Ok(Self::Str(unsafe { ptr::read(raw.cast()) }))
141                    }
142                    USBStandardDescriptorTypes::Interface => {
143                        Ok(Self::Interface(unsafe { ptr::read(raw.cast()) }))
144                    }
145                    USBStandardDescriptorTypes::Endpoint => {
146                        Ok(Self::Endpoint(unsafe { ptr::read(raw.cast()) }))
147                    }
148                    USBStandardDescriptorTypes::InterfaceAssociation => {
149                        Ok(Self::InterfaceAssociation(unsafe { ptr::read(raw.cast()) }))
150                    }
151                    other => {
152                        unimplemented!("please implement descriptor type:{:?}", other)
153                    }
154                }
155            }
156            None => Err(Error::UnrecognizedType(raw[1])),
157        }
158    }
159}
160
161#[derive(Copy, Clone, FromPrimitive)]
162#[repr(u8)]
163pub enum PortSpeed {
164    FullSpeed = 1,
165    LowSpeed = 2,
166    HighSpeed = 3,
167    SuperSpeed = 4,
168    SuperSpeedPlus = 5,
169}