usb_descriptor_decoder/descriptors/
mod.rs1use 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 Device = 0x01,
39 Configuration = 0x02,
40 String = 0x03,
41 Interface = 0x04,
42 Endpoint = 0x05,
43 DeviceQualifier = 0x06,
45 OtherSpeedConfiguration = 0x07,
46 InterfacePower1 = 0x08,
47 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 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}