embassy_usb/
lib.rs

1#![no_std]
2#![doc = include_str!("../README.md")]
3#![warn(missing_docs)]
4
5// This mod MUST go first, so that the others see its macros.
6pub(crate) mod fmt;
7
8pub use embassy_usb_driver as driver;
9
10mod builder;
11pub mod class;
12pub mod control;
13pub mod descriptor;
14mod descriptor_reader;
15pub mod msos;
16pub mod types;
17
18mod config {
19    #![allow(unused)]
20    include!(concat!(env!("OUT_DIR"), "/config.rs"));
21}
22
23use embassy_futures::select::{select, Either};
24use heapless::Vec;
25
26pub use crate::builder::{Builder, Config, FunctionBuilder, InterfaceAltBuilder, InterfaceBuilder, UsbVersion};
27use crate::config::{MAX_HANDLER_COUNT, MAX_INTERFACE_COUNT};
28use crate::control::{InResponse, OutResponse, Recipient, Request, RequestType};
29use crate::descriptor::{descriptor_type, lang_id};
30use crate::descriptor_reader::foreach_endpoint;
31use crate::driver::{Bus, ControlPipe, Direction, Driver, EndpointAddress, Event};
32use crate::types::{InterfaceNumber, StringIndex};
33
34/// The global state of the USB device.
35///
36/// In general class traffic is only possible in the `Configured` state.
37#[repr(u8)]
38#[derive(PartialEq, Eq, Copy, Clone, Debug)]
39#[cfg_attr(feature = "defmt", derive(defmt::Format))]
40pub enum UsbDeviceState {
41    /// The USB device has no power.
42    Unpowered,
43
44    /// The USB device is disabled.
45    Disabled,
46
47    /// The USB device has just been enabled or reset.
48    Default,
49
50    /// The USB device has received an address from the host.
51    Addressed,
52
53    /// The USB device has been configured and is fully functional.
54    Configured,
55}
56
57/// Error returned by [`UsbDevice::remote_wakeup`].
58#[derive(PartialEq, Eq, Copy, Clone, Debug)]
59#[cfg_attr(feature = "defmt", derive(defmt::Format))]
60pub enum RemoteWakeupError {
61    /// The USB device is not suspended, or remote wakeup was not enabled.
62    InvalidState,
63    /// The underlying driver doesn't support remote wakeup.
64    Unsupported,
65}
66
67impl From<driver::Unsupported> for RemoteWakeupError {
68    fn from(_: driver::Unsupported) -> Self {
69        RemoteWakeupError::Unsupported
70    }
71}
72
73/// The bConfiguration value for the not configured state.
74pub const CONFIGURATION_NONE: u8 = 0;
75
76/// The bConfiguration value for the single configuration supported by this device.
77pub const CONFIGURATION_VALUE: u8 = 1;
78
79const STRING_INDEX_MANUFACTURER: u8 = 1;
80const STRING_INDEX_PRODUCT: u8 = 2;
81const STRING_INDEX_SERIAL_NUMBER: u8 = 3;
82const STRING_INDEX_CUSTOM_START: u8 = 4;
83
84/// Handler for device events and control requests.
85///
86/// All methods are optional callbacks that will be called by
87/// [`UsbDevice::run()`](crate::UsbDevice::run)
88pub trait Handler {
89    /// Called when the USB device has been enabled or disabled.
90    fn enabled(&mut self, _enabled: bool) {}
91
92    /// Called after a USB reset after the bus reset sequence is complete.
93    fn reset(&mut self) {}
94
95    /// Called when the host has set the address of the device to `addr`.
96    fn addressed(&mut self, _addr: u8) {}
97
98    /// Called when the host has enabled or disabled the configuration of the device.
99    fn configured(&mut self, _configured: bool) {}
100
101    /// Called when the bus has entered or exited the suspend state.
102    fn suspended(&mut self, _suspended: bool) {}
103
104    /// Called when remote wakeup feature is enabled or disabled.
105    fn remote_wakeup_enabled(&mut self, _enabled: bool) {}
106
107    /// Called when a "set alternate setting" control request is done on the interface.
108    fn set_alternate_setting(&mut self, iface: InterfaceNumber, alternate_setting: u8) {
109        let _ = iface;
110        let _ = alternate_setting;
111    }
112
113    /// Called when a control request is received with direction HostToDevice.
114    ///
115    /// # Arguments
116    ///
117    /// * `req` - The request from the SETUP packet.
118    /// * `data` - The data from the request.
119    ///
120    /// # Returns
121    ///
122    /// If you didn't handle this request (for example if it's for the wrong interface), return
123    /// `None`. In this case, the USB stack will continue calling the other handlers, to see
124    /// if another handles it.
125    ///
126    /// If you did, return `Some` with either `Accepted` or `Rejected`. This will make the USB stack
127    /// respond to the control request, and stop calling other handlers.
128    fn control_out(&mut self, req: Request, data: &[u8]) -> Option<OutResponse> {
129        let _ = (req, data);
130        None
131    }
132
133    /// Called when a control request is received with direction DeviceToHost.
134    ///
135    /// You should write the response somewhere (usually to `buf`, but you may use another buffer
136    /// owned by yourself, or a static buffer), then return `InResponse::Accepted(data)`.
137    ///
138    /// # Arguments
139    ///
140    /// * `req` - The request from the SETUP packet.
141    ///
142    /// # Returns
143    ///
144    /// If you didn't handle this request (for example if it's for the wrong interface), return
145    /// `None`. In this case, the USB stack will continue calling the other handlers, to see
146    /// if another handles it.
147    ///
148    /// If you did, return `Some` with either `Accepted` or `Rejected`. This will make the USB stack
149    /// respond to the control request, and stop calling other handlers.
150    fn control_in<'a>(&'a mut self, req: Request, buf: &'a mut [u8]) -> Option<InResponse<'a>> {
151        let _ = (req, buf);
152        None
153    }
154
155    /// Called when a GET_DESCRIPTOR STRING control request is received.
156    fn get_string(&mut self, index: StringIndex, lang_id: u16) -> Option<&str> {
157        let _ = (index, lang_id);
158        None
159    }
160}
161
162struct Interface {
163    current_alt_setting: u8,
164    num_alt_settings: u8,
165}
166
167/// A report of the used size of the runtime allocated buffers
168#[derive(PartialEq, Eq, Copy, Clone, Debug)]
169#[cfg_attr(feature = "defmt", derive(defmt::Format))]
170pub struct UsbBufferReport {
171    /// Number of config descriptor bytes used
172    pub config_descriptor_used: usize,
173    /// Number of bos descriptor bytes used
174    pub bos_descriptor_used: usize,
175    /// Number of msos descriptor bytes used
176    pub msos_descriptor_used: usize,
177    /// Size of the control buffer
178    pub control_buffer_size: usize,
179}
180
181/// Main struct for the USB device stack.
182pub struct UsbDevice<'d, D: Driver<'d>> {
183    control_buf: &'d mut [u8],
184    control: D::ControlPipe,
185    inner: Inner<'d, D>,
186}
187
188struct Inner<'d, D: Driver<'d>> {
189    bus: D::Bus,
190
191    config: Config<'d>,
192    device_descriptor: [u8; 18],
193    device_qualifier_descriptor: [u8; 10],
194    config_descriptor: &'d [u8],
195    bos_descriptor: &'d [u8],
196    msos_descriptor: crate::msos::MsOsDescriptorSet<'d>,
197
198    device_state: UsbDeviceState,
199    suspended: bool,
200    remote_wakeup_enabled: bool,
201    self_powered: bool,
202
203    /// Our device address, or 0 if none.
204    address: u8,
205    /// SET_ADDRESS requests have special handling depending on the driver.
206    /// This flag indicates that requests must be handled by `ControlPipe::accept_set_address()`
207    /// instead of regular `accept()`.
208    set_address_pending: bool,
209
210    interfaces: Vec<Interface, MAX_INTERFACE_COUNT>,
211    handlers: Vec<&'d mut dyn Handler, MAX_HANDLER_COUNT>,
212}
213
214impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
215    pub(crate) fn build(
216        driver: D,
217        config: Config<'d>,
218        handlers: Vec<&'d mut dyn Handler, MAX_HANDLER_COUNT>,
219        config_descriptor: &'d [u8],
220        bos_descriptor: &'d [u8],
221        msos_descriptor: crate::msos::MsOsDescriptorSet<'d>,
222        interfaces: Vec<Interface, MAX_INTERFACE_COUNT>,
223        control_buf: &'d mut [u8],
224    ) -> UsbDevice<'d, D> {
225        // Start the USB bus.
226        // This prevent further allocation by consuming the driver.
227        let (bus, control) = driver.start(config.max_packet_size_0 as u16);
228        let device_descriptor = descriptor::device_descriptor(&config);
229        let device_qualifier_descriptor = descriptor::device_qualifier_descriptor(&config);
230
231        Self {
232            control_buf,
233            control,
234            inner: Inner {
235                bus,
236                config,
237                device_descriptor,
238                device_qualifier_descriptor,
239                config_descriptor,
240                bos_descriptor,
241                msos_descriptor,
242
243                device_state: UsbDeviceState::Unpowered,
244                suspended: false,
245                remote_wakeup_enabled: false,
246                self_powered: false,
247                address: 0,
248                set_address_pending: false,
249                interfaces,
250                handlers,
251            },
252        }
253    }
254
255    /// Returns a report of the consumed buffers
256    ///
257    /// Useful for tuning buffer sizes for actual usage
258    pub fn buffer_usage(&self) -> UsbBufferReport {
259        UsbBufferReport {
260            config_descriptor_used: self.inner.config_descriptor.len(),
261            bos_descriptor_used: self.inner.bos_descriptor.len(),
262            msos_descriptor_used: self.inner.msos_descriptor.len(),
263            control_buffer_size: self.control_buf.len(),
264        }
265    }
266
267    /// Runs the `UsbDevice` forever.
268    ///
269    /// This future may leave the bus in an invalid state if it is dropped.
270    /// After dropping the future, [`UsbDevice::disable()`] should be called
271    /// before calling any other `UsbDevice` methods to fully reset the
272    /// peripheral.
273    pub async fn run(&mut self) -> ! {
274        loop {
275            self.run_until_suspend().await;
276            self.wait_resume().await;
277        }
278    }
279
280    /// Runs the `UsbDevice` until the bus is suspended.
281    ///
282    /// This future may leave the bus in an invalid state if it is dropped.
283    /// After dropping the future, [`UsbDevice::disable()`] should be called
284    /// before calling any other `UsbDevice` methods to fully reset the
285    /// peripheral.
286    pub async fn run_until_suspend(&mut self) {
287        while !self.inner.suspended {
288            let control_fut = self.control.setup();
289            let bus_fut = self.inner.bus.poll();
290            match select(bus_fut, control_fut).await {
291                Either::First(evt) => self.inner.handle_bus_event(evt).await,
292                Either::Second(req) => self.handle_control(req).await,
293            }
294        }
295    }
296
297    /// Disables the USB peripheral.
298    pub async fn disable(&mut self) {
299        if self.inner.device_state != UsbDeviceState::Disabled {
300            self.inner.bus.disable().await;
301            self.inner.device_state = UsbDeviceState::Disabled;
302            self.inner.suspended = false;
303            self.inner.remote_wakeup_enabled = false;
304
305            for h in &mut self.inner.handlers {
306                h.enabled(false);
307            }
308        }
309    }
310
311    /// Waits for a resume condition on the USB bus.
312    ///
313    /// This future is cancel-safe.
314    pub async fn wait_resume(&mut self) {
315        while self.inner.suspended {
316            let evt = self.inner.bus.poll().await;
317            self.inner.handle_bus_event(evt).await;
318        }
319    }
320
321    /// Initiates a device remote wakeup on the USB bus.
322    ///
323    /// If the bus is not suspended or remote wakeup is not enabled, an error
324    /// will be returned.
325    ///
326    /// This future may leave the bus in an inconsistent state if dropped.
327    /// After dropping the future, [`UsbDevice::disable()`] should be called
328    /// before calling any other `UsbDevice` methods to fully reset the peripheral.
329    pub async fn remote_wakeup(&mut self) -> Result<(), RemoteWakeupError> {
330        if self.inner.suspended && self.inner.remote_wakeup_enabled {
331            self.inner.bus.remote_wakeup().await?;
332            self.inner.suspended = false;
333
334            for h in &mut self.inner.handlers {
335                h.suspended(false);
336            }
337
338            Ok(())
339        } else {
340            Err(RemoteWakeupError::InvalidState)
341        }
342    }
343
344    async fn handle_control(&mut self, req: [u8; 8]) {
345        let req = Request::parse(&req);
346
347        trace!("control request: {:?}", req);
348
349        match req.direction {
350            Direction::In => self.handle_control_in(req).await,
351            Direction::Out => self.handle_control_out(req).await,
352        }
353    }
354
355    async fn handle_control_in(&mut self, req: Request) {
356        const DEVICE_DESCRIPTOR_LEN: usize = 18;
357
358        let mut resp_length = req.length as usize;
359        let max_packet_size = self.control.max_packet_size();
360
361        // If we don't have an address yet, respond with max 1 packet.
362        // The host doesn't know our EP0 max packet size yet, and might assume
363        // a full-length packet is a short packet, thinking we're done sending data.
364        // See https://github.com/hathach/tinyusb/issues/184
365        if self.inner.address == 0 && max_packet_size < DEVICE_DESCRIPTOR_LEN && max_packet_size < resp_length {
366            trace!("received control req while not addressed: capping response to 1 packet.");
367            resp_length = max_packet_size;
368        }
369
370        match self.inner.handle_control_in(req, self.control_buf) {
371            InResponse::Accepted(data) => {
372                let len = data.len().min(resp_length);
373                let need_zlp = len != resp_length && (len % max_packet_size) == 0;
374
375                let chunks = data[0..len]
376                    .chunks(max_packet_size)
377                    .chain(need_zlp.then(|| -> &[u8] { &[] }));
378
379                for (first, last, chunk) in first_last(chunks) {
380                    match self.control.data_in(chunk, first, last).await {
381                        Ok(()) => {}
382                        Err(e) => {
383                            warn!("control accept_in failed: {:?}", e);
384                            return;
385                        }
386                    }
387                }
388            }
389            InResponse::Rejected => self.control.reject().await,
390        }
391    }
392
393    async fn handle_control_out(&mut self, req: Request) {
394        let req_length = req.length as usize;
395        let max_packet_size = self.control.max_packet_size();
396        let mut total = 0;
397
398        if req_length > self.control_buf.len() {
399            warn!(
400                "got CONTROL OUT with length {} higher than the control_buf len {}, rejecting.",
401                req_length,
402                self.control_buf.len()
403            );
404            self.control.reject().await;
405            return;
406        }
407
408        let chunks = self.control_buf[..req_length].chunks_mut(max_packet_size);
409        for (first, last, chunk) in first_last(chunks) {
410            let size = match self.control.data_out(chunk, first, last).await {
411                Ok(x) => x,
412                Err(e) => {
413                    warn!("usb: failed to read CONTROL OUT data stage: {:?}", e);
414                    return;
415                }
416            };
417            total += size;
418            if size < max_packet_size || total == req_length {
419                break;
420            }
421        }
422
423        let data = &self.control_buf[0..total];
424        #[cfg(feature = "defmt")]
425        trace!("  control out data: {:02x}", data);
426        #[cfg(not(feature = "defmt"))]
427        trace!("  control out data: {:02x?}", data);
428
429        match self.inner.handle_control_out(req, data) {
430            OutResponse::Accepted => {
431                if self.inner.set_address_pending {
432                    self.control.accept_set_address(self.inner.address).await;
433                    self.inner.set_address_pending = false;
434                } else {
435                    self.control.accept().await;
436                }
437            }
438            OutResponse::Rejected => self.control.reject().await,
439        }
440    }
441}
442
443impl<'d, D: Driver<'d>> Inner<'d, D> {
444    async fn handle_bus_event(&mut self, evt: Event) {
445        match evt {
446            Event::Reset => {
447                trace!("usb: reset");
448                self.device_state = UsbDeviceState::Default;
449                self.suspended = false;
450                self.remote_wakeup_enabled = false;
451                self.address = 0;
452
453                for h in &mut self.handlers {
454                    h.reset();
455                }
456
457                for (i, iface) in self.interfaces.iter_mut().enumerate() {
458                    iface.current_alt_setting = 0;
459
460                    for h in &mut self.handlers {
461                        h.set_alternate_setting(InterfaceNumber::new(i as _), 0);
462                    }
463                }
464            }
465            Event::Resume => {
466                trace!("usb: resume");
467                self.suspended = false;
468                for h in &mut self.handlers {
469                    h.suspended(false);
470                }
471            }
472            Event::Suspend => {
473                trace!("usb: suspend");
474                self.suspended = true;
475                for h in &mut self.handlers {
476                    h.suspended(true);
477                }
478            }
479            Event::PowerDetected => {
480                trace!("usb: power detected");
481                self.bus.enable().await;
482                self.device_state = UsbDeviceState::Default;
483
484                for h in &mut self.handlers {
485                    h.enabled(true);
486                }
487            }
488            Event::PowerRemoved => {
489                trace!("usb: power removed");
490                self.bus.disable().await;
491                self.device_state = UsbDeviceState::Unpowered;
492
493                for h in &mut self.handlers {
494                    h.enabled(false);
495                }
496            }
497        }
498    }
499
500    fn handle_control_out(&mut self, req: Request, data: &[u8]) -> OutResponse {
501        const CONFIGURATION_NONE_U16: u16 = CONFIGURATION_NONE as u16;
502        const CONFIGURATION_VALUE_U16: u16 = CONFIGURATION_VALUE as u16;
503
504        match (req.request_type, req.recipient) {
505            (RequestType::Standard, Recipient::Device) => match (req.request, req.value) {
506                (Request::CLEAR_FEATURE, Request::FEATURE_DEVICE_REMOTE_WAKEUP) => {
507                    self.remote_wakeup_enabled = false;
508                    for h in &mut self.handlers {
509                        h.remote_wakeup_enabled(false);
510                    }
511                    OutResponse::Accepted
512                }
513                (Request::SET_FEATURE, Request::FEATURE_DEVICE_REMOTE_WAKEUP) => {
514                    self.remote_wakeup_enabled = true;
515                    for h in &mut self.handlers {
516                        h.remote_wakeup_enabled(true);
517                    }
518                    OutResponse::Accepted
519                }
520                (Request::SET_ADDRESS, addr @ 1..=127) => {
521                    self.address = addr as u8;
522                    self.set_address_pending = true;
523                    self.device_state = UsbDeviceState::Addressed;
524                    for h in &mut self.handlers {
525                        h.addressed(self.address);
526                    }
527                    OutResponse::Accepted
528                }
529                (Request::SET_CONFIGURATION, CONFIGURATION_VALUE_U16) => {
530                    debug!("SET_CONFIGURATION: configured");
531                    self.device_state = UsbDeviceState::Configured;
532
533                    // Enable all endpoints of selected alt settings.
534                    foreach_endpoint(self.config_descriptor, |ep| {
535                        let iface = &self.interfaces[ep.interface.0 as usize];
536                        self.bus
537                            .endpoint_set_enabled(ep.ep_address, iface.current_alt_setting == ep.interface_alt);
538                    })
539                    .unwrap();
540
541                    // Notify handlers.
542                    for h in &mut self.handlers {
543                        h.configured(true);
544                    }
545
546                    OutResponse::Accepted
547                }
548                (Request::SET_CONFIGURATION, CONFIGURATION_NONE_U16) => {
549                    if self.device_state != UsbDeviceState::Default {
550                        debug!("SET_CONFIGURATION: unconfigured");
551                        self.device_state = UsbDeviceState::Addressed;
552
553                        // Disable all endpoints.
554                        foreach_endpoint(self.config_descriptor, |ep| {
555                            self.bus.endpoint_set_enabled(ep.ep_address, false);
556                        })
557                        .unwrap();
558
559                        // Notify handlers.
560                        for h in &mut self.handlers {
561                            h.configured(false);
562                        }
563                    }
564                    OutResponse::Accepted
565                }
566                _ => OutResponse::Rejected,
567            },
568            (RequestType::Standard, Recipient::Interface) => {
569                let iface_num = InterfaceNumber::new(req.index as _);
570                let Some(iface) = self.interfaces.get_mut(iface_num.0 as usize) else {
571                    return OutResponse::Rejected;
572                };
573
574                match req.request {
575                    Request::SET_INTERFACE => {
576                        let new_altsetting = req.value as u8;
577
578                        if new_altsetting >= iface.num_alt_settings {
579                            warn!("SET_INTERFACE: trying to select alt setting out of range.");
580                            return OutResponse::Rejected;
581                        }
582
583                        iface.current_alt_setting = new_altsetting;
584
585                        // Enable/disable EPs of this interface as needed.
586                        foreach_endpoint(self.config_descriptor, |ep| {
587                            if ep.interface == iface_num {
588                                self.bus
589                                    .endpoint_set_enabled(ep.ep_address, iface.current_alt_setting == ep.interface_alt);
590                            }
591                        })
592                        .unwrap();
593
594                        // TODO check it is valid (not out of range)
595
596                        for h in &mut self.handlers {
597                            h.set_alternate_setting(iface_num, new_altsetting);
598                        }
599                        OutResponse::Accepted
600                    }
601                    _ => OutResponse::Rejected,
602                }
603            }
604            (RequestType::Standard, Recipient::Endpoint) => match (req.request, req.value) {
605                (Request::SET_FEATURE, Request::FEATURE_ENDPOINT_HALT) => {
606                    let ep_addr = ((req.index as u8) & 0x8f).into();
607                    self.bus.endpoint_set_stalled(ep_addr, true);
608                    OutResponse::Accepted
609                }
610                (Request::CLEAR_FEATURE, Request::FEATURE_ENDPOINT_HALT) => {
611                    let ep_addr = ((req.index as u8) & 0x8f).into();
612                    self.bus.endpoint_set_stalled(ep_addr, false);
613                    OutResponse::Accepted
614                }
615                _ => OutResponse::Rejected,
616            },
617            _ => self.handle_control_out_delegated(req, data),
618        }
619    }
620
621    fn handle_control_in<'a>(&'a mut self, req: Request, buf: &'a mut [u8]) -> InResponse<'a> {
622        match (req.request_type, req.recipient) {
623            (RequestType::Standard, Recipient::Device) => match req.request {
624                Request::GET_STATUS => {
625                    let mut status: u16 = 0x0000;
626                    if self.self_powered {
627                        status |= 0x0001;
628                    }
629                    if self.remote_wakeup_enabled {
630                        status |= 0x0002;
631                    }
632                    buf[..2].copy_from_slice(&status.to_le_bytes());
633                    InResponse::Accepted(&buf[..2])
634                }
635                Request::GET_DESCRIPTOR => self.handle_get_descriptor(req, buf),
636                Request::GET_CONFIGURATION => {
637                    let status = match self.device_state {
638                        UsbDeviceState::Configured => CONFIGURATION_VALUE,
639                        _ => CONFIGURATION_NONE,
640                    };
641                    buf[0] = status;
642                    InResponse::Accepted(&buf[..1])
643                }
644                _ => InResponse::Rejected,
645            },
646            (RequestType::Standard, Recipient::Interface) => {
647                let Some(iface) = self.interfaces.get_mut(req.index as usize) else {
648                    return InResponse::Rejected;
649                };
650
651                match req.request {
652                    Request::GET_STATUS => {
653                        let status: u16 = 0;
654                        buf[..2].copy_from_slice(&status.to_le_bytes());
655                        InResponse::Accepted(&buf[..2])
656                    }
657                    Request::GET_INTERFACE => {
658                        buf[0] = iface.current_alt_setting;
659                        InResponse::Accepted(&buf[..1])
660                    }
661                    _ => self.handle_control_in_delegated(req, buf),
662                }
663            }
664            (RequestType::Standard, Recipient::Endpoint) => match req.request {
665                Request::GET_STATUS => {
666                    let ep_addr: EndpointAddress = ((req.index as u8) & 0x8f).into();
667                    let mut status: u16 = 0x0000;
668                    if self.bus.endpoint_is_stalled(ep_addr) {
669                        status |= 0x0001;
670                    }
671                    buf[..2].copy_from_slice(&status.to_le_bytes());
672                    InResponse::Accepted(&buf[..2])
673                }
674                _ => InResponse::Rejected,
675            },
676
677            (RequestType::Vendor, Recipient::Device) => {
678                if !self.msos_descriptor.is_empty()
679                    && req.request == self.msos_descriptor.vendor_code()
680                    && req.index == 7
681                {
682                    // Index 7 retrieves the MS OS Descriptor Set
683                    InResponse::Accepted(self.msos_descriptor.descriptor())
684                } else {
685                    self.handle_control_in_delegated(req, buf)
686                }
687            }
688            _ => self.handle_control_in_delegated(req, buf),
689        }
690    }
691
692    fn handle_control_out_delegated(&mut self, req: Request, data: &[u8]) -> OutResponse {
693        for h in &mut self.handlers {
694            if let Some(res) = h.control_out(req, data) {
695                return res;
696            }
697        }
698        OutResponse::Rejected
699    }
700
701    fn handle_control_in_delegated<'a>(&'a mut self, req: Request, buf: &'a mut [u8]) -> InResponse<'a> {
702        unsafe fn extend_lifetime<'y>(r: InResponse<'_>) -> InResponse<'y> {
703            core::mem::transmute(r)
704        }
705
706        for h in &mut self.handlers {
707            if let Some(res) = h.control_in(req, buf) {
708                // safety: the borrow checker isn't smart enough to know this pattern (returning a
709                // borrowed value from inside the loop) is sound. Workaround by unsafely extending lifetime.
710                // Also, Polonius (the WIP new borrow checker) does accept it.
711
712                return unsafe { extend_lifetime(res) };
713            }
714        }
715        InResponse::Rejected
716    }
717
718    fn handle_get_descriptor<'a>(&'a mut self, req: Request, buf: &'a mut [u8]) -> InResponse<'a> {
719        let (dtype, index) = req.descriptor_type_index();
720
721        match dtype {
722            descriptor_type::BOS => InResponse::Accepted(self.bos_descriptor),
723            descriptor_type::DEVICE => InResponse::Accepted(&self.device_descriptor),
724            descriptor_type::CONFIGURATION => InResponse::Accepted(self.config_descriptor),
725            descriptor_type::STRING => {
726                if index == 0 {
727                    buf[0] = 4; // len
728                    buf[1] = descriptor_type::STRING;
729                    buf[2] = lang_id::ENGLISH_US as u8;
730                    buf[3] = (lang_id::ENGLISH_US >> 8) as u8;
731                    InResponse::Accepted(&buf[..4])
732                } else {
733                    let s = match index {
734                        STRING_INDEX_MANUFACTURER => self.config.manufacturer,
735                        STRING_INDEX_PRODUCT => self.config.product,
736                        STRING_INDEX_SERIAL_NUMBER => self.config.serial_number,
737                        _ => {
738                            let mut s = None;
739                            for handler in &mut self.handlers {
740                                let index = StringIndex::new(index);
741                                let lang_id = req.index;
742                                if let Some(res) = handler.get_string(index, lang_id) {
743                                    s = Some(res);
744                                    break;
745                                }
746                            }
747                            s
748                        }
749                    };
750
751                    if let Some(s) = s {
752                        assert!(buf.len() >= 2, "control buffer too small");
753
754                        buf[1] = descriptor_type::STRING;
755                        let mut pos = 2;
756                        for c in s.encode_utf16() {
757                            assert!(pos + 2 < buf.len(), "control buffer too small");
758
759                            buf[pos..pos + 2].copy_from_slice(&c.to_le_bytes());
760                            pos += 2;
761                        }
762
763                        buf[0] = pos as u8;
764                        InResponse::Accepted(&buf[..pos])
765                    } else {
766                        InResponse::Rejected
767                    }
768                }
769            }
770            descriptor_type::DEVICE_QUALIFIER => InResponse::Accepted(&self.device_qualifier_descriptor),
771            _ => InResponse::Rejected,
772        }
773    }
774}
775
776fn first_last<T: Iterator>(iter: T) -> impl Iterator<Item = (bool, bool, T::Item)> {
777    let mut iter = iter.peekable();
778    let mut first = true;
779    core::iter::from_fn(move || {
780        let val = iter.next()?;
781        let is_first = first;
782        first = false;
783        let is_last = iter.peek().is_none();
784        Some((is_first, is_last, val))
785    })
786}