diff options
| author | Dario Nieuwenhuis <[email protected]> | 2022-03-28 03:34:24 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2022-04-06 05:38:11 +0200 |
| commit | e99a3a1da42649bb9ad9a64508d14d6461be331d (patch) | |
| tree | eb28a76b0d0d08710ce1a44de58fd9a92209fee6 /embassy-usb/src/control.rs | |
| parent | bfce731982af1f053b1b727e49e920fc496a9546 (diff) | |
usb: simplify buffer handling for Control IN transfers.
Diffstat (limited to 'embassy-usb/src/control.rs')
| -rw-r--r-- | embassy-usb/src/control.rs | 58 |
1 files changed, 9 insertions, 49 deletions
diff --git a/embassy-usb/src/control.rs b/embassy-usb/src/control.rs index 05536dab2..567a595a1 100644 --- a/embassy-usb/src/control.rs +++ b/embassy-usb/src/control.rs | |||
| @@ -131,6 +131,13 @@ pub enum OutResponse { | |||
| 131 | Rejected, | 131 | Rejected, |
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | #[derive(Copy, Clone, Eq, PartialEq, Debug)] | ||
| 135 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 136 | pub enum InResponse { | ||
| 137 | Accepted(usize), | ||
| 138 | Rejected, | ||
| 139 | } | ||
| 140 | |||
| 134 | /// A trait for implementing USB classes. | 141 | /// A trait for implementing USB classes. |
| 135 | /// | 142 | /// |
| 136 | /// All methods are optional callbacks that will be called by | 143 | /// All methods are optional callbacks that will be called by |
| @@ -171,54 +178,7 @@ pub trait ControlHandler { | |||
| 171 | /// | 178 | /// |
| 172 | /// * `req` - The request from the SETUP packet. | 179 | /// * `req` - The request from the SETUP packet. |
| 173 | /// * `control` - The control pipe. | 180 | /// * `control` - The control pipe. |
| 174 | fn control_in<'a>(&mut self, req: Request, control: ControlIn<'a>) -> InResponse<'a> { | 181 | fn control_in(&mut self, req: Request, resp: &mut [u8]) -> InResponse { |
| 175 | control.reject() | 182 | InResponse::Rejected |
| 176 | } | ||
| 177 | } | ||
| 178 | |||
| 179 | /// Handle for a control IN transfer. When implementing a class, use the methods of this object to | ||
| 180 | /// response to the transfer with either data or an error (STALL condition). To ignore the request | ||
| 181 | /// and pass it on to the next class, call [`Self::ignore()`]. | ||
| 182 | pub struct ControlIn<'a> { | ||
| 183 | buf: &'a mut [u8], | ||
| 184 | } | ||
| 185 | |||
| 186 | #[derive(Eq, PartialEq, Debug)] | ||
| 187 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 188 | pub struct InResponse<'a> { | ||
| 189 | pub(crate) response: OutResponse, | ||
| 190 | pub(crate) data: &'a [u8], | ||
| 191 | } | ||
| 192 | |||
| 193 | impl<'a> InResponse<'a> { | ||
| 194 | pub fn status(&self) -> OutResponse { | ||
| 195 | self.response | ||
| 196 | } | ||
| 197 | } | ||
| 198 | |||
| 199 | impl<'a> ControlIn<'a> { | ||
| 200 | pub(crate) fn new(buf: &'a mut [u8]) -> Self { | ||
| 201 | ControlIn { buf } | ||
| 202 | } | ||
| 203 | |||
| 204 | /// Accepts the transfer with the supplied buffer. | ||
| 205 | pub fn accept(self, data: &[u8]) -> InResponse<'a> { | ||
| 206 | assert!(data.len() < self.buf.len()); | ||
| 207 | |||
| 208 | let buf = &mut self.buf[0..data.len()]; | ||
| 209 | buf.copy_from_slice(data); | ||
| 210 | |||
| 211 | InResponse { | ||
| 212 | response: OutResponse::Accepted, | ||
| 213 | data: buf, | ||
| 214 | } | ||
| 215 | } | ||
| 216 | |||
| 217 | /// Rejects the transfer by stalling the pipe. | ||
| 218 | pub fn reject(self) -> InResponse<'a> { | ||
| 219 | InResponse { | ||
| 220 | response: OutResponse::Rejected, | ||
| 221 | data: &[], | ||
| 222 | } | ||
| 223 | } | 183 | } |
| 224 | } | 184 | } |
