1#![allow(missing_docs)]
3
4use embassy_usb_driver::host::HostError;
5use embassy_usb_driver::{Direction, EndpointInfo, EndpointType};
6
7pub mod descriptor_type {
9 pub const DEVICE: u8 = 0x01;
10 pub const CONFIGURATION: u8 = 0x02;
11 pub const INTERFACE: u8 = 0x04;
12 pub const ENDPOINT: u8 = 0x05;
13
14 pub const INTERFACE_ASSOCIATION: u8 = 0x0B;
15 pub const CS_INTERFACE: u8 = 0x24;
16 pub const CS_ENDPOINT: u8 = 0x25;
17}
18
19pub type StringIndex = u8;
20
21pub(crate) const DEFAULT_MAX_DESCRIPTOR_SIZE: usize = 512;
23
24#[derive(Debug)]
25#[cfg_attr(feature = "defmt", derive(defmt::Format))]
26pub enum DescriptorError {
27 BadDescriptorType,
28 UnexpectedEndOfBuffer,
29}
30
31#[derive(Debug)]
33#[cfg_attr(feature = "defmt", derive(defmt::Format))]
34pub enum VisitError<E> {
35 BadDescriptor,
37 Visitor(E),
39}
40
41pub trait USBDescriptor {
43 const SIZE: usize;
44 const DESC_TYPE: u8;
45 type Error;
46 fn try_from_bytes(bytes: &[u8]) -> Result<Self, Self::Error>
47 where
48 Self: Sized;
49}
50
51#[derive(Debug)]
53pub struct DeviceDescriptorPartial {
54 _padding: [u8; 7],
55 pub max_packet_size0: u8,
56}
57
58impl USBDescriptor for DeviceDescriptorPartial {
59 const SIZE: usize = 8;
60 const DESC_TYPE: u8 = descriptor_type::DEVICE;
61 type Error = ();
62
63 fn try_from_bytes(bytes: &[u8]) -> Result<Self, Self::Error> {
64 if bytes.len() < Self::SIZE || bytes[1] != Self::DESC_TYPE {
65 return Err(());
66 }
67 Ok(Self {
68 _padding: [0; 7],
69 max_packet_size0: bytes[7],
70 })
71 }
72}
73
74#[derive(Copy, Clone, Debug)]
76#[cfg_attr(feature = "defmt", derive(defmt::Format))]
77pub struct DeviceDescriptor {
78 pub len: u8,
79 pub descriptor_type: u8,
80 pub bcd_usb: u16,
81 pub device_class: u8,
82 pub device_subclass: u8,
83 pub device_protocol: u8,
84 pub max_packet_size0: u8,
85 pub vendor_id: u16,
86 pub product_id: u16,
87 pub bcd_device: u16,
88 pub manufacturer: StringIndex,
89 pub product: StringIndex,
90 pub serial_number: StringIndex,
91 pub num_configurations: u8,
92}
93
94impl USBDescriptor for DeviceDescriptor {
95 const SIZE: usize = 18;
96 const DESC_TYPE: u8 = descriptor_type::DEVICE;
97 type Error = ();
98
99 fn try_from_bytes(bytes: &[u8]) -> Result<Self, Self::Error> {
100 if bytes.len() < Self::SIZE || bytes[1] != Self::DESC_TYPE {
101 return Err(());
102 }
103 Ok(Self {
104 len: bytes[0],
105 descriptor_type: bytes[1],
106 bcd_usb: u16::from_le_bytes([bytes[2], bytes[3]]),
107 device_class: bytes[4],
108 device_subclass: bytes[5],
109 device_protocol: bytes[6],
110 max_packet_size0: bytes[7],
111 vendor_id: u16::from_le_bytes([bytes[8], bytes[9]]),
112 product_id: u16::from_le_bytes([bytes[10], bytes[11]]),
113 bcd_device: u16::from_le_bytes([bytes[12], bytes[13]]),
114 manufacturer: bytes[14],
115 product: bytes[15],
116 serial_number: bytes[16],
117 num_configurations: bytes[17],
118 })
119 }
120}
121
122#[derive(Copy, Clone, Debug)]
124#[cfg_attr(feature = "defmt", derive(defmt::Format))]
125pub struct ConfigurationDescriptor<'a> {
126 pub len: u8,
127 pub descriptor_type: u8,
128 pub total_len: u16,
129 pub num_interfaces: u8,
130 pub configuration_value: u8,
131 pub configuration_name: StringIndex,
132 pub attributes: u8,
133 pub max_power: u8,
134 pub buffer: &'a [u8],
136}
137
138impl USBDescriptor for ConfigurationDescriptor<'_> {
139 const SIZE: usize = 9;
140 const DESC_TYPE: u8 = descriptor_type::CONFIGURATION;
141 type Error = ();
142
143 fn try_from_bytes(bytes: &[u8]) -> Result<Self, Self::Error> {
144 if bytes.len() < Self::SIZE || bytes[1] != Self::DESC_TYPE {
145 return Err(());
146 }
147 Ok(Self {
148 len: bytes[0],
149 descriptor_type: bytes[1],
150 total_len: u16::from_le_bytes([bytes[2], bytes[3]]),
151 num_interfaces: bytes[4],
152 configuration_value: bytes[5],
153 configuration_name: bytes[6],
154 attributes: bytes[7],
155 max_power: bytes[8],
156 buffer: &[],
157 })
158 }
159}
160
161impl<'a> ConfigurationDescriptor<'a> {
162 pub fn try_from_slice(buf: &'a [u8]) -> Result<Self, HostError> {
164 if buf.len() < Self::SIZE || buf[1] != Self::DESC_TYPE {
165 return Err(HostError::InvalidDescriptor);
166 }
167 let total_length = u16::from_le_bytes([buf[2], buf[3]]);
168 Ok(Self {
169 len: buf[0],
170 descriptor_type: buf[1],
171 total_len: total_length,
172 num_interfaces: buf[4],
173 configuration_value: buf[5],
174 configuration_name: buf[6],
175 attributes: buf[7],
176 max_power: buf[8],
177 buffer: &buf[buf[0] as usize..total_length as usize],
178 })
179 }
180
181 pub fn iter_descriptors(&self) -> RawDescriptorIterator<'a> {
183 RawDescriptorIterator {
184 buf: self.buffer,
185 offset: 0,
186 }
187 }
188
189 pub fn iter_interface(&self) -> InterfaceIterator<'_> {
191 let first_interface_offset = self
192 .iter_descriptors()
193 .find_map(|(offset, bytes)| {
194 if bytes[1] == descriptor_type::INTERFACE {
195 Some(offset)
196 } else {
197 None
198 }
199 })
200 .unwrap_or(0);
201 InterfaceIterator {
202 offset: first_interface_offset,
203 cfg_desc: self,
204 }
205 }
206
207 pub fn visit_descriptors<V: DescriptorVisitor<'a>>(&self, visitor: &mut V) -> Result<(), VisitError<V::Error>> {
210 if !visitor.on_configuration(self) {
211 return Ok(());
212 }
213 let mut current_iface: Option<InterfaceDescriptor<'a>> = None;
214 for (_, bytes) in self.iter_descriptors() {
215 if bytes.len() < 2 {
216 continue;
217 }
218 match bytes[1] {
219 descriptor_type::INTERFACE => {
220 let iface = InterfaceDescriptor::try_from_bytes(bytes).map_err(|_| VisitError::BadDescriptor)?;
221 current_iface = Some(iface);
222 if !visitor.on_interface(&iface) {
223 return Ok(());
224 }
225 }
226 descriptor_type::ENDPOINT => {
227 let ep = EndpointDescriptor::try_from_bytes(bytes).map_err(|_| VisitError::BadDescriptor)?;
228 if let Some(iface) = current_iface.as_ref() {
229 if !visitor.on_endpoint(iface, &ep) {
230 return Ok(());
231 }
232 }
233 }
234 _ => {
235 if !visitor
236 .on_other(current_iface.as_ref(), bytes)
237 .map_err(VisitError::Visitor)?
238 {
239 return Ok(());
240 }
241 }
242 }
243 }
244 Ok(())
245 }
246}
247
248pub trait DescriptorVisitor<'a> {
252 type Error;
253
254 fn on_configuration(&mut self, _c: &ConfigurationDescriptor<'a>) -> bool {
256 true
257 }
258
259 fn on_interface(&mut self, _i: &InterfaceDescriptor<'a>) -> bool {
261 true
262 }
263
264 fn on_endpoint(&mut self, _iface: &InterfaceDescriptor<'a>, _e: &EndpointDescriptor) -> bool {
266 true
267 }
268
269 fn on_other(&mut self, _iface: Option<&InterfaceDescriptor<'a>>, _raw: &[u8]) -> Result<bool, Self::Error> {
273 Ok(true)
274 }
275}
276
277pub struct ShowDescriptors;
279
280impl<'a> DescriptorVisitor<'a> for ShowDescriptors {
281 type Error = core::convert::Infallible;
282
283 fn on_configuration(&mut self, c: &ConfigurationDescriptor) -> bool {
284 debug!("{:?}", c);
285 true
286 }
287 fn on_interface(&mut self, i: &InterfaceDescriptor) -> bool {
288 debug!(" {:?}", i);
289 true
290 }
291 fn on_endpoint(&mut self, _i: &InterfaceDescriptor, e: &EndpointDescriptor) -> bool {
292 debug!(" {:?}", e);
293 true
294 }
295 fn on_other(&mut self, _i: Option<&InterfaceDescriptor>, d: &[u8]) -> Result<bool, Self::Error> {
296 let dlen = d[0];
297 let dtype = d[1];
298 let domain = match dtype & 0x60 {
299 0x00 => "standard",
300 0x20 => "class",
301 0x40 => "vendor",
302 _ => "reserved",
303 };
304 debug!(" {} type 0x{:02X} len {}", domain, dtype, dlen);
305 Ok(true)
306 }
307}
308
309#[derive(Copy, Clone, Debug)]
311#[cfg_attr(feature = "defmt", derive(defmt::Format))]
312pub struct InterfaceDescriptor<'a> {
313 pub len: u8,
314 pub descriptor_type: u8,
315 pub interface_number: u8,
316 pub alternate_setting: u8,
317 pub num_endpoints: u8,
318 pub interface_class: u8,
319 pub interface_subclass: u8,
320 pub interface_protocol: u8,
321 pub interface_name: StringIndex,
322 pub buffer: &'a [u8],
324}
325
326impl<'a> InterfaceDescriptor<'a> {
327 const SIZE: usize = 9;
328 const DESC_TYPE: u8 = descriptor_type::INTERFACE;
329
330 pub(crate) fn try_from_bytes(bytes: &'a [u8]) -> Result<Self, ()> {
331 if bytes.len() < Self::SIZE || bytes[1] != Self::DESC_TYPE {
332 return Err(());
333 }
334 let endpoints = &bytes[bytes[0] as usize..];
335 let mut raw = RawDescriptorIterator {
336 buf: endpoints,
337 offset: 0,
338 };
339 let next_iface_index = raw
340 .find_map(|(index, v)| v.get(1).is_some_and(|v| *v == Self::DESC_TYPE).then_some(index))
341 .unwrap_or(endpoints.len());
342 Ok(Self {
343 len: bytes[0],
344 descriptor_type: bytes[1],
345 interface_number: bytes[2],
346 alternate_setting: bytes[3],
347 num_endpoints: bytes[4],
348 interface_class: bytes[5],
349 interface_subclass: bytes[6],
350 interface_protocol: bytes[7],
351 interface_name: bytes[8],
352 buffer: &endpoints[..next_iface_index],
353 })
354 }
355
356 pub fn iter_descriptors(&self) -> RawDescriptorIterator<'_> {
358 RawDescriptorIterator {
359 buf: self.buffer,
360 offset: 0,
361 }
362 }
363
364 pub fn iter_endpoints(&'a self) -> EndpointIterator<'a> {
366 EndpointIterator {
367 index: 0,
368 buffer_idx: 0,
369 iface_desc: self,
370 }
371 }
372}
373
374pub struct InterfaceIterator<'a> {
376 offset: usize,
377 cfg_desc: &'a ConfigurationDescriptor<'a>,
378}
379
380impl<'a> Iterator for InterfaceIterator<'a> {
381 type Item = InterfaceDescriptor<'a>;
382
383 fn next(&mut self) -> Option<Self::Item> {
384 if self.offset >= self.cfg_desc.buffer.len() {
385 return None;
386 }
387 let remaining = &self.cfg_desc.buffer[self.offset..];
388 let iface = InterfaceDescriptor::try_from_bytes(remaining).ok()?;
389 self.offset += iface.len as usize + iface.buffer.len();
390 Some(iface)
391 }
392}
393
394pub struct RawDescriptorIterator<'a> {
396 buf: &'a [u8],
397 offset: usize,
398}
399
400impl<'a> Iterator for RawDescriptorIterator<'a> {
401 type Item = (usize, &'a [u8]);
402
403 fn next(&mut self) -> Option<Self::Item> {
404 if self.offset >= self.buf.len() {
405 return None;
406 }
407 let pre = self.offset;
408 let len = self.buf[pre] as usize;
409 if len == 0 {
410 return None;
411 }
412 self.offset += len;
413 if self.offset > self.buf.len() {
414 return None;
415 }
416 Some((pre, &self.buf[pre..self.offset]))
417 }
418}
419
420pub struct EndpointIterator<'a> {
422 buffer_idx: usize,
423 index: usize,
424 iface_desc: &'a InterfaceDescriptor<'a>,
425}
426
427impl Iterator for EndpointIterator<'_> {
428 type Item = EndpointDescriptor;
429
430 fn next(&mut self) -> Option<Self::Item> {
431 if self.index >= self.iface_desc.num_endpoints as usize {
432 return None;
433 }
434 while self.buffer_idx + 7 <= self.iface_desc.buffer.len() {
435 let working = &self.iface_desc.buffer[self.buffer_idx..];
436 self.buffer_idx += working[0] as usize;
437 if let Ok(d) = EndpointDescriptor::try_from_bytes(working) {
438 self.index += 1;
439 return Some(d);
440 }
441 }
442 None
443 }
444}
445
446#[derive(Copy, Clone, Debug, PartialEq)]
448#[cfg_attr(feature = "defmt", derive(defmt::Format))]
449pub struct EndpointDescriptor {
450 pub len: u8,
451 pub descriptor_type: u8,
452 pub endpoint_address: u8,
453 pub attributes: u8,
454 pub max_packet_size: u16,
455 pub interval: u8,
456}
457
458impl EndpointDescriptor {
459 pub fn ep_dir(&self) -> Direction {
461 match self.endpoint_address & 0x80 {
462 0x00 => Direction::Out,
463 _ => Direction::In,
464 }
465 }
466
467 pub fn ep_type(&self) -> EndpointType {
469 match self.attributes & 0x03 {
470 0 => EndpointType::Control,
471 1 => EndpointType::Isochronous,
472 2 => EndpointType::Bulk,
473 _ => EndpointType::Interrupt,
474 }
475 }
476
477 pub fn ep_number(&self) -> u8 {
479 self.endpoint_address & 0x0F
480 }
481
482 pub fn is_in(&self) -> bool {
484 (self.endpoint_address & 0x80) != 0
485 }
486
487 pub fn transfer_type(&self) -> u8 {
489 self.attributes & 0x03
490 }
491}
492
493impl USBDescriptor for EndpointDescriptor {
494 const SIZE: usize = 7;
495 const DESC_TYPE: u8 = descriptor_type::ENDPOINT;
496 type Error = DescriptorError;
497
498 fn try_from_bytes(bytes: &[u8]) -> Result<Self, Self::Error> {
499 if bytes.len() < Self::SIZE || bytes.len() < bytes[0] as usize {
500 return Err(DescriptorError::UnexpectedEndOfBuffer);
501 }
502 if bytes[1] != Self::DESC_TYPE {
503 return Err(DescriptorError::BadDescriptorType);
504 }
505 Ok(Self {
506 len: bytes[0],
507 descriptor_type: bytes[1],
508 endpoint_address: bytes[2],
509 attributes: bytes[3],
510 max_packet_size: u16::from_le_bytes([bytes[4], bytes[5]]),
511 interval: bytes[6],
512 })
513 }
514}
515
516impl From<EndpointDescriptor> for EndpointInfo {
517 fn from(value: EndpointDescriptor) -> Self {
518 EndpointInfo {
519 addr: value.endpoint_address.into(),
520 ep_type: value.ep_type(),
521 max_packet_size: value.max_packet_size,
522 interval_ms: value.interval,
523 }
524 }
525}
526
527#[cfg(test)]
528mod test {
529 use heapless::Vec;
530
531 use super::{ConfigurationDescriptor, DescriptorVisitor, EndpointDescriptor, InterfaceDescriptor};
532 use crate::descriptor::ShowDescriptors;
533
534 struct TestInterface<'a> {
535 interface: InterfaceDescriptor<'a>,
536 endpoints: Vec<EndpointDescriptor, 4>,
537 }
538
539 const MAX_INTERFACES: usize = 4;
540 const MAX_DESCRIPTOR_SIZE: usize = 256;
541 const MAX_OTHERS: usize = 8;
542
543 struct TestVisitor<'a> {
544 configuration: Option<ConfigurationDescriptor<'a>>,
545 interfaces: Vec<TestInterface<'a>, MAX_INTERFACES>,
546 others: Vec<Vec<u8, MAX_DESCRIPTOR_SIZE>, MAX_OTHERS>,
547 }
548
549 impl<'a> Default for TestVisitor<'a> {
550 fn default() -> Self {
551 Self {
552 configuration: None,
553 interfaces: Vec::new(),
554 others: Vec::new(),
555 }
556 }
557 }
558
559 impl<'a> DescriptorVisitor<'a> for TestVisitor<'a> {
560 type Error = core::convert::Infallible;
561
562 fn on_configuration(&mut self, c: &ConfigurationDescriptor<'a>) -> bool {
563 assert!(self.configuration.is_none());
564 self.configuration = Some(*c);
565 true
566 }
567
568 fn on_interface(&mut self, i: &InterfaceDescriptor<'a>) -> bool {
569 assert!(self.configuration.is_some());
570 let _ = self.interfaces.push(TestInterface {
571 interface: *i,
572 endpoints: Vec::new(),
573 });
574 true
575 }
576
577 fn on_endpoint(&mut self, _iface: &InterfaceDescriptor<'a>, e: &EndpointDescriptor) -> bool {
578 assert!(!self.interfaces.is_empty());
579 let _ = self.interfaces.last_mut().unwrap().endpoints.push(*e);
580 true
581 }
582
583 fn on_other(&mut self, _iface: Option<&InterfaceDescriptor<'a>>, d: &[u8]) -> Result<bool, Self::Error> {
584 assert!(self.configuration.is_some());
585 let _ = self.others.push(Vec::from_slice(d).unwrap_or_default());
586 Ok(true)
587 }
588 }
589
590 #[test]
591 fn test_parse_extended_endpoint_descriptor() {
592 let desc_bytes = [
593 9, 2, 76, 0, 2, 1, 0, 160, 101, 8, 11, 0, 1, 3, 0, 0, 0, 9, 4, 0, 0, 1, 3, 1, 1, 0, 9, 33, 16, 1, 0, 1, 34,
594 63, 0, 9, 5, 129, 3, 8, 0, 1, 99, 99, 9, 4, 1, 0, 2, 3, 1, 0, 0, 9, 33, 16, 1, 0, 1, 34, 39, 0, 7, 5, 131,
595 3, 64, 0, 1, 7, 5, 3, 3, 64, 0, 1,
596 ];
597
598 let cfg = ConfigurationDescriptor::try_from_slice(desc_bytes.as_slice()).unwrap();
599 assert_eq!(cfg.num_interfaces, 2);
600
601 let interface0 = cfg.iter_interface().next().unwrap();
602 assert_eq!(interface0.interface_number, 0);
603 assert_eq!(interface0.num_endpoints, 1);
604
605 let endpoints: Vec<EndpointDescriptor, 2> = interface0.iter_endpoints().collect();
606 assert_eq!(endpoints.len(), 1);
607 assert_eq!(endpoints[0].endpoint_address, 0x81);
608 assert_eq!(endpoints[0].max_packet_size, 8);
609
610 let interface1 = cfg.iter_interface().nth(1).unwrap();
611 assert_eq!(interface1.interface_number, 1);
612 assert_eq!(interface1.num_endpoints, 2);
613
614 let endpoints: Vec<EndpointDescriptor, 2> = interface1.iter_endpoints().collect();
615 assert_eq!(endpoints.len(), 2);
616 }
617
618 #[test]
619 fn test_parse_interface_descriptor() {
620 let desc_bytes = [
621 9, 2, 66, 0, 2, 1, 0, 160, 101, 9, 4, 0, 0, 1, 3, 1, 1, 0, 9, 33, 16, 1, 0, 1, 34, 63, 0, 7, 5, 129, 3, 8,
622 0, 1, 9, 4, 1, 0, 2, 3, 1, 0, 0, 9, 33, 16, 1, 0, 1, 34, 39, 0, 7, 5, 131, 3, 64, 0, 1, 7, 5, 3, 3, 64, 0,
623 1,
624 ];
625
626 let cfg = ConfigurationDescriptor::try_from_slice(desc_bytes.as_slice()).unwrap();
627 assert_eq!(cfg.num_interfaces, 2);
628
629 let interface0 = cfg.iter_interface().next().unwrap();
630 assert_eq!(interface0.interface_number, 0);
631
632 let interface0_buffer_ref = [9u8, 33, 16, 1, 0, 1, 34, 63, 0, 7, 5, 129, 3, 8, 0, 1];
633 assert_eq!(interface0.buffer.len(), interface0_buffer_ref.len());
634
635 let interface1 = cfg.iter_interface().nth(1).unwrap();
636 assert_eq!(interface1.interface_number, 1);
637
638 let interface1_buffer_ref = [
639 9u8, 33, 16, 1, 0, 1, 34, 39, 0, 7, 5, 131, 3, 64, 0, 1, 7, 5, 3, 3, 64, 0, 1,
640 ];
641 assert_eq!(interface1.buffer.len(), interface1_buffer_ref.len());
642 }
643
644 #[test]
645 fn test_parse_visit_midi_descriptor() {
646 let _ = env_logger::builder().is_test(true).try_init();
647
648 let desc_bytes = [
649 9, 2, 101, 0, 2, 1, 0, 128, 50, 9, 4, 0, 0, 0, 1, 1, 0, 0, 9, 36, 1, 0, 1, 9, 0, 1, 1, 9, 4, 1, 0, 2, 1, 3,
650 0, 0, 7, 36, 1, 0, 1, 65, 0, 6, 36, 2, 1, 1, 0, 6, 36, 2, 2, 2, 0, 9, 36, 3, 1, 3, 1, 2, 1, 0, 9, 36, 3, 2,
651 4, 1, 1, 1, 0, 9, 5, 2, 2, 32, 0, 0, 0, 0, 5, 37, 1, 1, 1, 9, 5, 129, 2, 32, 0, 0, 0, 0, 5, 37, 1, 1, 3,
652 ];
653
654 let cfg = ConfigurationDescriptor::try_from_slice(desc_bytes.as_slice()).unwrap();
655 assert_eq!(cfg.num_interfaces, 2);
656
657 let mut v = TestVisitor::default();
658 cfg.visit_descriptors(&mut v).unwrap();
659
660 assert!(v.configuration.is_some());
661 assert_eq!(cfg.num_interfaces, 2);
662 assert_eq!(v.interfaces.len(), 2);
663 assert_eq!(v.interfaces[0].interface.interface_class, 1);
664 assert_eq!(v.interfaces[0].endpoints.len(), 0);
665 assert_eq!(v.interfaces[1].endpoints.len(), 2);
666 assert_eq!(v.interfaces[1].endpoints[0].attributes, 2);
667 assert_eq!(v.interfaces[1].endpoints[0].endpoint_address, 0x02);
668 assert_eq!(v.interfaces[1].endpoints[1].endpoint_address, 0x81);
669 assert_eq!(v.others.len(), 8);
670
671 let mut sv = ShowDescriptors {};
672 cfg.visit_descriptors(&mut sv).unwrap();
673 }
674}