From a63d46507de7fbb44233ba5557630791f62a985a Mon Sep 17 00:00:00 2001 From: Haobo Gu Date: Thu, 15 Aug 2024 10:58:10 +0800 Subject: [PATCH] feat(usb): add device qualifier descriptor Signed-off-by: Haobo Gu --- embassy-usb/src/descriptor.rs | 21 +++++++++++++++++++++ embassy-usb/src/lib.rs | 4 ++++ 2 files changed, 25 insertions(+) diff --git a/embassy-usb/src/descriptor.rs b/embassy-usb/src/descriptor.rs index eb3d1f53a..f1773fa8a 100644 --- a/embassy-usb/src/descriptor.rs +++ b/embassy-usb/src/descriptor.rs @@ -13,6 +13,8 @@ pub mod descriptor_type { pub const STRING: u8 = 3; pub const INTERFACE: u8 = 4; pub const ENDPOINT: u8 = 5; + pub const DEVICE_QUALIFIER: u8 = 6; + pub const OTHER_SPEED_CONFIGURATION: u8 = 7; pub const IAD: u8 = 11; pub const BOS: u8 = 15; pub const CAPABILITY: u8 = 16; @@ -272,6 +274,25 @@ pub(crate) fn device_descriptor(config: &Config) -> [u8; 18] { ] } +/// Create a new Device Qualifier Descriptor array. +/// +/// All device qualifier descriptors are always 10 bytes, so there's no need for +/// a variable-length buffer or DescriptorWriter. +pub(crate) fn device_qualifier_descriptor(config: &Config) -> [u8; 10] { + [ + 10, // bLength + 0x06, // bDescriptorType + 0x10, + 0x02, // bcdUSB 2.1 + config.device_class, // bDeviceClass + config.device_sub_class, // bDeviceSubClass + config.device_protocol, // bDeviceProtocol + config.max_packet_size_0, // bMaxPacketSize0 + 1, // bNumConfigurations + 0, // Reserved + ] +} + /// A writer for Binary Object Store descriptor. pub struct BosWriter<'a> { pub(crate) writer: DescriptorWriter<'a>, diff --git a/embassy-usb/src/lib.rs b/embassy-usb/src/lib.rs index d58950838..a5478ca0e 100644 --- a/embassy-usb/src/lib.rs +++ b/embassy-usb/src/lib.rs @@ -190,6 +190,7 @@ struct Inner<'d, D: Driver<'d>> { config: Config<'d>, device_descriptor: [u8; 18], + device_qualifier_descriptor: [u8; 10], config_descriptor: &'d [u8], bos_descriptor: &'d [u8], msos_descriptor: crate::msos::MsOsDescriptorSet<'d>, @@ -225,6 +226,7 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { // This prevent further allocation by consuming the driver. let (bus, control) = driver.start(config.max_packet_size_0 as u16); let device_descriptor = descriptor::device_descriptor(&config); + let device_qualifier_descriptor = descriptor::device_qualifier_descriptor(&config); Self { control_buf, @@ -233,6 +235,7 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { bus, config, device_descriptor, + device_qualifier_descriptor, config_descriptor, bos_descriptor, msos_descriptor, @@ -764,6 +767,7 @@ impl<'d, D: Driver<'d>> Inner<'d, D> { } } } + descriptor_type::DEVICE_QUALIFIER => InResponse::Accepted(&self.device_qualifier_descriptor), _ => InResponse::Rejected, } }