diff --git a/embassy-usb/src/control.rs b/embassy-usb/src/control.rs index 05536dab..567a595a 100644 --- a/embassy-usb/src/control.rs +++ b/embassy-usb/src/control.rs @@ -131,6 +131,13 @@ pub enum OutResponse { Rejected, } +#[derive(Copy, Clone, Eq, PartialEq, Debug)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum InResponse { + Accepted(usize), + Rejected, +} + /// A trait for implementing USB classes. /// /// All methods are optional callbacks that will be called by @@ -171,54 +178,7 @@ pub trait ControlHandler { /// /// * `req` - The request from the SETUP packet. /// * `control` - The control pipe. - fn control_in<'a>(&mut self, req: Request, control: ControlIn<'a>) -> InResponse<'a> { - control.reject() - } -} - -/// Handle for a control IN transfer. When implementing a class, use the methods of this object to -/// response to the transfer with either data or an error (STALL condition). To ignore the request -/// and pass it on to the next class, call [`Self::ignore()`]. -pub struct ControlIn<'a> { - buf: &'a mut [u8], -} - -#[derive(Eq, PartialEq, Debug)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub struct InResponse<'a> { - pub(crate) response: OutResponse, - pub(crate) data: &'a [u8], -} - -impl<'a> InResponse<'a> { - pub fn status(&self) -> OutResponse { - self.response - } -} - -impl<'a> ControlIn<'a> { - pub(crate) fn new(buf: &'a mut [u8]) -> Self { - ControlIn { buf } - } - - /// Accepts the transfer with the supplied buffer. - pub fn accept(self, data: &[u8]) -> InResponse<'a> { - assert!(data.len() < self.buf.len()); - - let buf = &mut self.buf[0..data.len()]; - buf.copy_from_slice(data); - - InResponse { - response: OutResponse::Accepted, - data: buf, - } - } - - /// Rejects the transfer by stalling the pipe. - pub fn reject(self) -> InResponse<'a> { - InResponse { - response: OutResponse::Rejected, - data: &[], - } + fn control_in(&mut self, req: Request, resp: &mut [u8]) -> InResponse { + InResponse::Rejected } } diff --git a/embassy-usb/src/lib.rs b/embassy-usb/src/lib.rs index 8d202402..9ac55db7 100644 --- a/embassy-usb/src/lib.rs +++ b/embassy-usb/src/lib.rs @@ -278,7 +278,6 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { _ => self.control.reject(), }, (RequestType::Class, Recipient::Interface) => { - let mut buf = [0; 128]; let handler = self .interfaces .iter_mut() @@ -286,10 +285,10 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> { .map(|(_, h)| h); match handler { Some(handler) => { - let resp = handler.control_in(req, ControlIn::new(&mut buf)); - match resp.response { - OutResponse::Accepted => self.control.accept_in(resp.data).await, - OutResponse::Rejected => self.control.reject(), + let mut buf = [0; 128]; + match handler.control_in(req, &mut buf) { + InResponse::Accepted(len) => self.control.accept_in(&buf[..len]).await, + InResponse::Rejected => self.control.reject(), } } None => self.control.reject(), diff --git a/examples/nrf/src/bin/usb/cdc_acm.rs b/examples/nrf/src/bin/usb/cdc_acm.rs index 141c6ecd..4be35fd3 100644 --- a/examples/nrf/src/bin/usb/cdc_acm.rs +++ b/examples/nrf/src/bin/usb/cdc_acm.rs @@ -3,7 +3,7 @@ use core::mem::{self, MaybeUninit}; use core::sync::atomic::{AtomicBool, Ordering}; use defmt::info; use embassy::blocking_mutex::CriticalSectionMutex; -use embassy_usb::control::{self, ControlHandler, ControlIn, InResponse, OutResponse, Request}; +use embassy_usb::control::{self, ControlHandler, InResponse, OutResponse, Request}; use embassy_usb::driver::{Endpoint, EndpointIn, EndpointOut, ReadError, WriteError}; use embassy_usb::{driver::Driver, types::*, UsbDeviceBuilder}; @@ -120,20 +120,19 @@ impl ControlHandler for Control { } } - fn control_in<'a>(&mut self, req: Request, control: ControlIn<'a>) -> InResponse<'a> { + fn control_in(&mut self, req: Request, resp: &mut [u8]) -> InResponse { match req.request { // REQ_GET_ENCAPSULATED_COMMAND is not really supported - it will be rejected below. REQ_GET_LINE_CODING if req.length == 7 => { info!("Sending line coding"); let coding = self.shared().line_coding.lock(|x| x.get()); - let mut data = [0; 7]; - data[0..4].copy_from_slice(&coding.data_rate.to_le_bytes()); - data[4] = coding.stop_bits as u8; - data[5] = coding.parity_type as u8; - data[6] = coding.data_bits; - control.accept(&data) + resp[0..4].copy_from_slice(&coding.data_rate.to_le_bytes()); + resp[4] = coding.stop_bits as u8; + resp[5] = coding.parity_type as u8; + resp[6] = coding.data_bits; + InResponse::Accepted(7) } - _ => control.reject(), + _ => InResponse::Rejected, } } }