From 7ed462a6575cba95e8f07d2d9516d5e7b33d7196 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 9 May 2022 02:11:02 +0200 Subject: usb: simplify control in/out handlng, calling response from a single place. --- embassy-usb/src/control.rs | 29 +++-------------------------- 1 file changed, 3 insertions(+), 26 deletions(-) (limited to 'embassy-usb/src/control.rs') diff --git a/embassy-usb/src/control.rs b/embassy-usb/src/control.rs index ff42f9d78..4fc65b6a5 100644 --- a/embassy-usb/src/control.rs +++ b/embassy-usb/src/control.rs @@ -1,9 +1,7 @@ use core::mem; -use crate::descriptor::DescriptorWriter; -use crate::driver::{self, EndpointError}; - use super::types::*; +use crate::driver::{self, EndpointError}; /// Control request type. #[repr(u8)] @@ -191,16 +189,8 @@ pub trait ControlHandler { } /// Called when a GET_DESCRIPTOR STRING control request is received. - /// - /// Write the response string somewhere (usually to `buf`, but you may use another buffer - /// owned by yourself, or a static buffer), then return it. - fn get_string<'a>( - &'a mut self, - index: StringIndex, - lang_id: u16, - buf: &'a mut [u8], - ) -> Option<&'a str> { - let _ = (index, lang_id, buf); + fn get_string(&mut self, index: StringIndex, lang_id: u16) -> Option<&str> { + let _ = (index, lang_id); None } } @@ -316,19 +306,6 @@ impl ControlPipe { } } - pub(crate) async fn accept_in_writer( - &mut self, - req: Request, - stage: DataInStage, - f: impl FnOnce(&mut DescriptorWriter), - ) { - let mut buf = [0; 256]; - let mut w = DescriptorWriter::new(&mut buf); - f(&mut w); - let pos = w.position().min(usize::from(req.length)); - self.accept_in(&buf[..pos], stage).await - } - pub(crate) fn accept(&mut self, _: StatusStage) { trace!(" control accept"); self.control.accept(); -- cgit From 02ae1138e1b67a18a0fea4f1871751ee1ad858c0 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 9 May 2022 03:25:21 +0200 Subject: usb: merge Control logic into main code. Now that control stuff is called from just one place, there's no need to keep it as a separate struct. --- embassy-usb/src/control.rs | 123 --------------------------------------------- 1 file changed, 123 deletions(-) (limited to 'embassy-usb/src/control.rs') diff --git a/embassy-usb/src/control.rs b/embassy-usb/src/control.rs index 4fc65b6a5..12e5303c3 100644 --- a/embassy-usb/src/control.rs +++ b/embassy-usb/src/control.rs @@ -1,7 +1,6 @@ use core::mem; use super::types::*; -use crate::driver::{self, EndpointError}; /// Control request type. #[repr(u8)] @@ -194,125 +193,3 @@ pub trait ControlHandler { None } } - -/// Typestate representing a ControlPipe in the DATA IN stage -#[derive(Debug)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub(crate) struct DataInStage { - pub(crate) length: usize, -} - -/// Typestate representing a ControlPipe in the DATA OUT stage -#[derive(Debug)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub(crate) struct DataOutStage { - length: usize, -} - -/// Typestate representing a ControlPipe in the STATUS stage -#[derive(Debug)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub(crate) struct StatusStage {} - -#[derive(Debug)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub(crate) enum Setup { - DataIn(Request, DataInStage), - DataOut(Request, DataOutStage), -} - -pub(crate) struct ControlPipe { - control: C, -} - -impl ControlPipe { - pub(crate) fn new(control: C) -> Self { - ControlPipe { control } - } - - pub(crate) async fn setup(&mut self) -> Setup { - let req = self.control.setup().await; - trace!("control request: {:02x}", req); - - match (req.direction, req.length) { - (UsbDirection::Out, n) => Setup::DataOut( - req, - DataOutStage { - length: usize::from(n), - }, - ), - (UsbDirection::In, n) => Setup::DataIn( - req, - DataInStage { - length: usize::from(n), - }, - ), - } - } - - pub(crate) async fn data_out<'a>( - &mut self, - buf: &'a mut [u8], - stage: DataOutStage, - ) -> Result<(&'a [u8], StatusStage), EndpointError> { - if stage.length == 0 { - Ok((&[], StatusStage {})) - } else { - let req_length = stage.length; - let max_packet_size = self.control.max_packet_size(); - let mut total = 0; - - for chunk in buf.chunks_mut(max_packet_size) { - let size = self.control.data_out(chunk).await?; - total += size; - if size < max_packet_size || total == req_length { - break; - } - } - - let res = &buf[0..total]; - #[cfg(feature = "defmt")] - trace!(" control out data: {:02x}", res); - #[cfg(not(feature = "defmt"))] - trace!(" control out data: {:02x?}", res); - - Ok((res, StatusStage {})) - } - } - - pub(crate) async fn accept_in(&mut self, buf: &[u8], stage: DataInStage) { - #[cfg(feature = "defmt")] - trace!(" control in accept {:02x}", buf); - #[cfg(not(feature = "defmt"))] - trace!(" control in accept {:02x?}", buf); - - let req_len = stage.length; - let len = buf.len().min(req_len); - let max_packet_size = self.control.max_packet_size(); - let need_zlp = len != req_len && (len % usize::from(max_packet_size)) == 0; - - let mut chunks = buf[0..len] - .chunks(max_packet_size) - .chain(need_zlp.then(|| -> &[u8] { &[] })); - - while let Some(chunk) = chunks.next() { - match self.control.data_in(chunk, chunks.size_hint().0 == 0).await { - Ok(()) => {} - Err(e) => { - warn!("control accept_in failed: {:?}", e); - return; - } - } - } - } - - pub(crate) fn accept(&mut self, _: StatusStage) { - trace!(" control accept"); - self.control.accept(); - } - - pub(crate) fn reject(&mut self) { - trace!(" control reject"); - self.control.reject(); - } -} -- cgit