usb_descriptor_decoder/descriptors/
parser.rs

1use core::ptr;
2
3//
4use alloc::vec::Vec;
5use log::{error, trace};
6use num_traits::FromPrimitive;
7
8use crate::descriptors::USBStandardDescriptorTypes;
9
10use super::{
11    desc_device::StandardUSBDeviceClassCode,
12    desc_interface::{Interface, InterfaceAssociation},
13    desc_uvc::{
14        uvc_interfaces::{
15            UVCInterfaceSubclass, UVCStandardVideoInterfaceClass,
16            UVCStandardVideoInterfaceProtocols,
17        },
18        UVCDescriptorTypes,
19    },
20    topological_desc::{
21        TopologicalUSBDescriptorConfiguration, TopologicalUSBDescriptorDevice,
22        TopologicalUSBDescriptorEndpoint, TopologicalUSBDescriptorFunction,
23        TopologicalUSBDescriptorRoot,
24    },
25    USBDescriptor,
26};
27
28pub struct RawDescriptorParser {
29    device: Vec<u8>,
30    configs: Vec<(Vec<u8>, usize)>,
31    state: ParserStateMachine,
32    result: Option<TopologicalUSBDescriptorDevice>,
33    others: Vec<USBDescriptor>,
34    metadata: ParserMetaData,
35    current: usize,
36    current_len: usize,
37}
38
39#[derive(Debug)]
40pub enum Error {
41    UnrecognizedType(u8),
42    ParseOrderError,
43    EndOfDescriptors,
44    NotReadyToParse,
45    StateSwitch,
46}
47
48#[derive(PartialEq, Debug)]
49enum ParserStateMachine {
50    Device,
51    NotReady,
52    Config(usize),
53    Inetrface(usize, u8),
54    END,
55}
56
57#[derive(Clone, Debug)]
58pub enum ParserMetaData {
59    UVC(u8),
60    HID,
61    Unknown(ParserMetaDataUnknownSituation),
62    NotDetermined,
63}
64
65#[derive(Clone, Debug)]
66pub enum ParserMetaDataUnknownSituation {
67    NoSpecial, //treat as standard usb device
68    ReferIAC,
69    ReferInterface,
70}
71
72impl ParserMetaData {
73    //refer https://www.usb.org/defined-class-codes
74    pub fn determine(class: u8, subclass: u8, protocol: u8) -> Self {
75        trace!("parse metadata! determining");
76        let result = {
77            match (
78                StandardUSBDeviceClassCode::from_u8(class),
79                subclass,
80                protocol,
81            ) {
82                (Some(StandardUSBDeviceClassCode::Miscellaneous), 0x02, 0x01) => {
83                    return Self::Unknown(ParserMetaDataUnknownSituation::ReferIAC)
84                }
85                (Some(StandardUSBDeviceClassCode::HID), _, _) => return Self::HID,
86                (Some(StandardUSBDeviceClassCode::ReferInterfaceDescriptor), _, _) => {
87                    return Self::Unknown(ParserMetaDataUnknownSituation::ReferInterface)
88                }
89                _ => {}
90            }
91
92            if let (
93                    Some(UVCStandardVideoInterfaceClass::CC_Video),
94                    Some(UVCInterfaceSubclass::VIDEO_INTERFACE_COLLECTION),
95                    Some(UVCStandardVideoInterfaceProtocols::PC_PROTOCOL_UNDEFINED),
96                ) = (
97                UVCStandardVideoInterfaceClass::from_u8(class),
98                UVCInterfaceSubclass::from_u8(subclass),
99                UVCStandardVideoInterfaceProtocols::from_u8(protocol),
100            ) { return Self::UVC(0u8) }
101
102            Self::Unknown(ParserMetaDataUnknownSituation::NoSpecial)
103        };
104        trace!("result is {:?}", result);
105
106        result
107    }
108}
109
110impl RawDescriptorParser {
111    pub fn new(raw_device: Vec<u8>) -> Self {
112        let len = raw_device.len();
113        Self {
114            device: raw_device,
115            configs: Vec::new(),
116            state: ParserStateMachine::Device,
117            current: 0,
118            current_len: len,
119            result: None,
120            others: Vec::new(),
121            metadata: ParserMetaData::NotDetermined,
122        }
123    }
124
125    pub fn num_of_configs(&self) -> usize {
126        if self.state != ParserStateMachine::Device {
127            self.result
128                .as_ref()
129                .map(|r| r.data.num_configurations as _)
130                .unwrap()
131        } else {
132            panic!("do not call this method before device has been deserialized!");
133        }
134    }
135
136    pub fn append_config(&mut self, raw_config: Vec<u8>) -> &mut Self {
137        let len = raw_config.len();
138        self.configs.push((raw_config, len));
139        self
140    }
141
142    pub fn summarize(mut self) -> TopologicalUSBDescriptorRoot {
143        while self.single_state_cycle() {}
144        TopologicalUSBDescriptorRoot {
145            device: self.result.unwrap(),
146            others: self.others,
147            metadata: self.metadata,
148        }
149    }
150
151    //return false if reach end, otherwise true
152    pub fn single_state_cycle(&mut self) -> bool {
153        match &self.state {
154            ParserStateMachine::Device => {
155                self.result = self.parse_single_device_descriptor().ok();
156                self.state = ParserStateMachine::NotReady;
157                trace!("state change:{:?}", self.state);
158                self.current = 0;
159                self.current_len = 0;
160                true
161            }
162            ParserStateMachine::Config(index) => {
163                let num_of_configs = self.num_of_configs();
164                let current_index = *index;
165                if current_index >= num_of_configs {
166                    self.state = ParserStateMachine::END;
167                    trace!("state change:{:?}", self.state);
168                    return false;
169                }
170                let topological_usbdescriptor_configuration = self.parse_current_config().unwrap();
171                self.result
172                    .as_mut()
173                    .unwrap()
174                    .child
175                    .push(topological_usbdescriptor_configuration);
176                self.state = ParserStateMachine::Config(current_index + 1);
177                trace!("state change:{:?}", self.state);
178                true
179            }
180            ParserStateMachine::END => panic!("should not call anymore while reaching end"),
181            ParserStateMachine::NotReady => {
182                if let Some(res) = &self.result
183                    && self.configs.len() >= res.data.num_configurations as _
184                {
185                    self.state = ParserStateMachine::Config(0);
186                    trace!("state change:{:?}", self.state);
187                    self.current_len = self.configs[0].1;
188                    true
189                } else {
190                    false
191                }
192            }
193            _ => true,
194        }
195    }
196
197    fn cut_raw_descriptor(&mut self) -> Result<Vec<u8>, Error> {
198        match &self.state {
199            ParserStateMachine::Device => {
200                let len: usize = self.device[self.current].into();
201                let v = self.device[self.current..(self.current + len)].to_vec();
202                self.current += len;
203                Ok(v)
204            }
205            ParserStateMachine::NotReady => Err(Error::NotReadyToParse),
206            ParserStateMachine::Config(cfg_index) | ParserStateMachine::Inetrface(cfg_index, _) => {
207                let len: usize = (self.configs[*cfg_index].0)[self.current].into();
208                let v = (self.configs[*cfg_index].0)[self.current..(self.current + len)].to_vec();
209                self.current += len;
210                Ok(v)
211            }
212            ParserStateMachine::END => Err(Error::EndOfDescriptors),
213        }
214    }
215
216    fn parse_single_device_descriptor(&mut self) -> Result<TopologicalUSBDescriptorDevice, Error> {
217        trace!("parse single device desc!");
218        if let USBDescriptor::Device(dev) = self.parse_any_descriptor()? {
219            if let ParserMetaData::NotDetermined = self.metadata {
220                    self.metadata =
221                        ParserMetaData::determine(dev.class, dev.subclass, dev.protocol);
222                    trace!("determined device type: {:?}", self.metadata)
223                };
224            Ok(TopologicalUSBDescriptorDevice {
225                data: dev,
226                child: Vec::new(),
227            })
228        } else {
229            Err(Error::ParseOrderError)
230        }
231    }
232
233    fn parse_current_config(&mut self) -> Result<TopologicalUSBDescriptorConfiguration, Error> {
234        trace!("parse config desc!");
235        let raw = self.cut_raw_descriptor()?;
236
237        let mut cfg =
238            USBDescriptor::from_slice(&raw, self.metadata.clone()).and_then(|converted| {
239                if let USBDescriptor::Configuration(cfg) = converted {
240                    Ok(TopologicalUSBDescriptorConfiguration {
241                        data: cfg,
242                        child: Vec::new(),
243                    })
244                } else {
245                    Err(Error::ParseOrderError)
246                }
247            })?;
248
249        trace!("max num of interface num:{}", cfg.data.num_interfaces());
250
251        loop {
252            match self.parse_function() {
253                Ok(func) => {
254                    cfg.child.push(func);
255                }
256                Err(Error::EndOfDescriptors) => {
257                    break;
258                }
259                Err(Error::StateSwitch) => {
260                    continue;
261                }
262                Err(other) => return Err(other),
263            }
264        }
265
266        Ok(cfg)
267    }
268
269    fn parse_function(&mut self) -> Result<TopologicalUSBDescriptorFunction, Error> {
270        trace!("parse function desc!");
271
272        if let Some(desc_type) = self.peek_std_desc_type() {
273            match desc_type {
274                USBStandardDescriptorTypes::Interface => {
275                    trace!(
276                        "parse single interface desc! current state:{:?}",
277                        self.state
278                    );
279                    // let collections = TopologicalUSBDescriptorFunction::Interface(vec![]);
280                    let mut interfaces = Vec::new();
281
282                    loop {
283                        trace!("loop! state:{:?}", self.state);
284                        match &self.state {
285                            ParserStateMachine::Config(cfg_id) => {
286                                self.state = ParserStateMachine::Inetrface(
287                                    *cfg_id,
288                                    self.peek_interface().unwrap().interface_number,
289                                );
290                                trace!("state change:{:?}", self.state);
291                            }
292                            ParserStateMachine::Inetrface(cfg_index, current_interface_id) => {
293                                trace!("state interface!");
294                                match &self.peek_interface() {
295                                    Some(next)
296                                        if (next.interface_number) == *current_interface_id =>
297                                    {
298                                        trace!("equal!");
299                                        trace!("current:{:?}", current_interface_id);
300                                        let interface = self.parse_interface().unwrap();
301                                        trace!("got interface {:?}", interface);
302                                        let additional = self.parse_other_descriptors_by_metadata();
303                                        trace!("got additional data {:?}", additional);
304                                        let endpoints = self.parse_endpoints();
305                                        trace!("got endpoints {:?}", endpoints);
306                                        interfaces.push((interface, additional, endpoints))
307                                    }
308                                    Some(next)
309                                        if (next.interface_number) != *current_interface_id =>
310                                    {
311                                        trace!("not equal!");
312                                        self.state = ParserStateMachine::Inetrface(
313                                            *cfg_index,
314                                            next.interface_number,
315                                        );
316                                        trace!("state change:{:?}", self.state);
317                                        break;
318                                    }
319                                    None => {
320                                        trace!("None! wtf?");
321                                        break;
322                                    }
323                                    other => panic!("deserialize error! {:?}", other),
324                                };
325                            }
326                            _ => panic!("impossible situation!"),
327                        }
328                    }
329
330                    Ok(TopologicalUSBDescriptorFunction::Interface(interfaces))
331                }
332                USBStandardDescriptorTypes::InterfaceAssociation => {
333                    trace!("parse InterfaceAssociation desc!");
334                    let interface_association = self.parse_interface_association().unwrap();
335                    // match &self.state {
336                    //     ParserStateMachine::Config(cfg_id) => {
337                    //         self.state = ParserStateMachine::Inetrface(cfg_id.clone(), 0);
338                    //         trace!("state change:{:?}", self.state);
339                    //     }
340                    //     other => panic!("error on switching state! {:?}", other),
341                    // }
342                    let mut interfaces = Vec::new();
343                    for i in 0..interface_association.interface_count {
344                        trace!("parsing {i}th interface!");
345                        //agreement:there is always some interfaces that match the cound behind association
346                        interfaces.push(self.parse_function()?);
347                    }
348                    Ok(TopologicalUSBDescriptorFunction::InterfaceAssociation((
349                        interface_association,
350                        interfaces,
351                    )))
352                }
353                anyother => {
354                    trace!("unrecognize type!");
355                    Err(Error::UnrecognizedType(anyother as u8))
356                }
357            }
358        } else {
359            Err(Error::EndOfDescriptors)
360        }
361    }
362
363    fn parse_any_descriptor(&mut self) -> Result<USBDescriptor, Error> {
364        trace!(
365            "parse any desc at current{}! type:{:?}",
366            self.current,
367            self.peek_std_desc_type()
368        );
369        let raw = self.cut_raw_descriptor()?;
370        USBDescriptor::from_slice(&raw, self.metadata.clone())
371    }
372
373    fn parse_interface_association(&mut self) -> Result<InterfaceAssociation, Error> {
374        match self.parse_any_descriptor()? {
375            USBDescriptor::InterfaceAssociation(interface_association) => {
376                if let ParserMetaData::Unknown(ParserMetaDataUnknownSituation::ReferIAC) =
377                    self.metadata
378                {
379                    self.metadata = ParserMetaData::determine(
380                        interface_association.function_class,
381                        interface_association.function_subclass,
382                        interface_association.function_protocol,
383                    );
384                    trace!("determined currend device type: {:?}", self.metadata);
385                }
386
387                Ok(interface_association)
388            }
389            _ => Err(Error::ParseOrderError),
390        }
391    }
392
393    fn peek_std_desc_type(&self) -> Option<USBStandardDescriptorTypes> {
394        match self.state {
395            ParserStateMachine::Device => {
396                let peeked =
397                    USBStandardDescriptorTypes::from_u8(self.device[self.current + 1]);
398                trace!("peeked type:{:?}", peeked);
399                peeked
400            }
401            ParserStateMachine::Config(index) | ParserStateMachine::Inetrface(index, _) => {
402                let peeked = USBStandardDescriptorTypes::from_u8(
403                    self.configs[index].0[self.current + 1],
404                );
405                trace!("peeked std type:{:?}", peeked);
406                peeked
407            }
408            _ => panic!("impossible!"),
409        }
410    }
411
412    //while call this methods, parser state machine always at "config" state
413    fn peek_uvc_desc_type(&mut self) -> Option<UVCDescriptorTypes> {
414        trace!("peek uvc type!");
415        match self.state {
416            ParserStateMachine::Config(index) | ParserStateMachine::Inetrface(index, _) => {
417                UVCDescriptorTypes::from_u8(self.configs[index].0[self.current + 1])
418            }
419            _ => None,
420        }
421    }
422
423    fn peek_interface(&self) -> Option<Interface> {
424        match self.state {
425            ParserStateMachine::Config(index) | ParserStateMachine::Inetrface(index, _) => {
426                trace!(
427                    "peek at {},value:{}",
428                    self.current,
429                    self.configs[index].0[self.current]
430                );
431
432                if self.peek_std_desc_type() == Some(USBStandardDescriptorTypes::Interface) {
433                    let len = self.configs[index].0[self.current] as usize;
434                    let from = self.current;
435                    let to = from + len - 1;
436                    trace!("len{len},from{from},to{to}");
437                    let raw = (&self.configs[index].0[from..to]) as *const [u8];
438                    let interface = unsafe { ptr::read_volatile(raw as *const Interface) }; //do not cast, in current version rust still had value cache issue
439                    trace!("got:{:?}", interface);
440
441                    return Some(interface);
442                }
443            }
444            _ => {}
445        }
446        None
447    }
448
449    fn parse_interface(&mut self) -> Result<Interface, Error> {
450        trace!("parse interfaces,metadata:{:?}", self.metadata);
451        match self.parse_any_descriptor()? {
452            USBDescriptor::Interface(int) => {
453                match &self.metadata {
454                    ParserMetaData::UVC(_) => {
455                        self.metadata = ParserMetaData::UVC(int.interface_subclass);
456                    }
457                    ParserMetaData::Unknown(ParserMetaDataUnknownSituation::ReferInterface) => {
458                        self.metadata = ParserMetaData::determine(
459                            int.interface_class,
460                            int.interface_subclass,
461                            int.interface_protocol,
462                        );
463
464                        trace!("determined current device type:{:?}", self.metadata);
465                    }
466                    _ => {}
467                }
468                Ok(int)
469            }
470            _ => Err(Error::ParseOrderError),
471        }
472    }
473
474    fn parse_other_descriptors_by_metadata(&mut self) -> Vec<USBDescriptor> {
475        trace!(
476            "parse additional data for interface with metadata:{:?}",
477            self.metadata
478        );
479        let mut vec = Vec::new();
480        loop {
481            match self.peek_std_desc_type() {
482                Some(
483                    USBStandardDescriptorTypes::Endpoint
484                    | USBStandardDescriptorTypes::Interface
485                    | USBStandardDescriptorTypes::InterfaceAssociation,
486                ) => break,
487                Some(_) | None => {
488                    trace!("parse misc desc!");
489                    vec.push(
490                        self.parse_any_descriptor()
491                            .inspect_err(|e| error!("usb descriptor parse failed:{:?}", e))
492                            .unwrap(),
493                    );
494                    continue;
495                }
496            }
497        }
498        vec
499    }
500
501    fn parse_endpoints(&mut self) -> Vec<TopologicalUSBDescriptorEndpoint> {
502        trace!("parse enedpoints, metadata:{:?}", self.metadata);
503        let mut endpoints = Vec::new();
504
505        loop {
506            if let Some(USBStandardDescriptorTypes::Endpoint) = self.peek_std_desc_type() {
507                if let USBDescriptor::Endpoint(endpoint) = self.parse_any_descriptor().unwrap() {
508                    trace!("parsed endpoint:{:?}", endpoint);
509                    endpoints.push(TopologicalUSBDescriptorEndpoint::Standard(endpoint))
510                }
511                continue;
512            }
513
514            if let ParserMetaData::UVC(_) = self.metadata {
515                if let Some(UVCDescriptorTypes::UVCClassSpecVideoControlInterruptEndpoint) =
516                    self.peek_uvc_desc_type()
517                {
518                    trace!("uvc interrupt endpoint!");
519                    match self.parse_any_descriptor().unwrap() {
520                        USBDescriptor::UVCClassSpecVideoControlInterruptEndpoint(ep) => {
521                            trace!("got {:?}", ep);
522                            endpoints.push(TopologicalUSBDescriptorEndpoint::UNVVideoControlInterruptEndpoint(ep));
523                        }
524                        _ => {
525                            panic!("impossible!");
526                        }
527                    }
528                    continue;
529                } else {
530                    trace!("not uvc data!");
531                }
532            }
533
534            break;
535        }
536        endpoints
537    }
538}