aboutsummaryrefslogtreecommitdiff
path: root/embassy-usb
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2022-05-09 02:11:02 +0200
committerDario Nieuwenhuis <[email protected]>2022-05-09 02:11:02 +0200
commit7ed462a6575cba95e8f07d2d9516d5e7b33d7196 (patch)
treeae0e68faea70a907bfb4488876ee179068f38f64 /embassy-usb
parent2e104170de36295243608fbbebebdc6f52e8f8d0 (diff)
usb: simplify control in/out handlng, calling response from a single place.
Diffstat (limited to 'embassy-usb')
-rw-r--r--embassy-usb/src/control.rs29
-rw-r--r--embassy-usb/src/descriptor.rs1
-rw-r--r--embassy-usb/src/lib.rs270
3 files changed, 152 insertions, 148 deletions
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 @@
1use core::mem; 1use core::mem;
2 2
3use crate::descriptor::DescriptorWriter;
4use crate::driver::{self, EndpointError};
5
6use super::types::*; 3use super::types::*;
4use crate::driver::{self, EndpointError};
7 5
8/// Control request type. 6/// Control request type.
9#[repr(u8)] 7#[repr(u8)]
@@ -191,16 +189,8 @@ pub trait ControlHandler {
191 } 189 }
192 190
193 /// Called when a GET_DESCRIPTOR STRING control request is received. 191 /// Called when a GET_DESCRIPTOR STRING control request is received.
194 /// 192 fn get_string(&mut self, index: StringIndex, lang_id: u16) -> Option<&str> {
195 /// Write the response string somewhere (usually to `buf`, but you may use another buffer 193 let _ = (index, lang_id);
196 /// owned by yourself, or a static buffer), then return it.
197 fn get_string<'a>(
198 &'a mut self,
199 index: StringIndex,
200 lang_id: u16,
201 buf: &'a mut [u8],
202 ) -> Option<&'a str> {
203 let _ = (index, lang_id, buf);
204 None 194 None
205 } 195 }
206} 196}
@@ -316,19 +306,6 @@ impl<C: driver::ControlPipe> ControlPipe<C> {
316 } 306 }
317 } 307 }
318 308
319 pub(crate) async fn accept_in_writer(
320 &mut self,
321 req: Request,
322 stage: DataInStage,
323 f: impl FnOnce(&mut DescriptorWriter),
324 ) {
325 let mut buf = [0; 256];
326 let mut w = DescriptorWriter::new(&mut buf);
327 f(&mut w);
328 let pos = w.position().min(usize::from(req.length));
329 self.accept_in(&buf[..pos], stage).await
330 }
331
332 pub(crate) fn accept(&mut self, _: StatusStage) { 309 pub(crate) fn accept(&mut self, _: StatusStage) {
333 trace!(" control accept"); 310 trace!(" control accept");
334 self.control.accept(); 311 self.control.accept();
diff --git a/embassy-usb/src/descriptor.rs b/embassy-usb/src/descriptor.rs
index dce326780..7f23fd921 100644
--- a/embassy-usb/src/descriptor.rs
+++ b/embassy-usb/src/descriptor.rs
@@ -244,6 +244,7 @@ impl<'a> DescriptorWriter<'a> {
244 } 244 }
245 245
246 /// Writes a string descriptor. 246 /// Writes a string descriptor.
247 #[allow(unused)]
247 pub(crate) fn string(&mut self, string: &str) { 248 pub(crate) fn string(&mut self, string: &str) {
248 let mut pos = self.position; 249 let mut pos = self.position;
249 250
diff --git a/embassy-usb/src/lib.rs b/embassy-usb/src/lib.rs
index 3bfedc048..690305885 100644
--- a/embassy-usb/src/lib.rs
+++ b/embassy-usb/src/lib.rs
@@ -100,15 +100,19 @@ struct Interface<'d> {
100} 100}
101 101
102pub struct UsbDevice<'d, D: Driver<'d>> { 102pub struct UsbDevice<'d, D: Driver<'d>> {
103 control_buf: &'d mut [u8],
104 control: ControlPipe<D::ControlPipe>,
105 inner: Inner<'d, D>,
106}
107
108struct Inner<'d, D: Driver<'d>> {
103 bus: D::Bus, 109 bus: D::Bus,
104 handler: Option<&'d dyn DeviceStateHandler>, 110 handler: Option<&'d dyn DeviceStateHandler>,
105 control: ControlPipe<D::ControlPipe>,
106 111
107 config: Config<'d>, 112 config: Config<'d>,
108 device_descriptor: &'d [u8], 113 device_descriptor: &'d [u8],
109 config_descriptor: &'d [u8], 114 config_descriptor: &'d [u8],
110 bos_descriptor: &'d [u8], 115 bos_descriptor: &'d [u8],
111 control_buf: &'d mut [u8],
112 116
113 device_state: UsbDeviceState, 117 device_state: UsbDeviceState,
114 suspended: bool, 118 suspended: bool,
@@ -139,20 +143,23 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
139 let bus = driver.into_bus(); 143 let bus = driver.into_bus();
140 144
141 Self { 145 Self {
142 bus,
143 config,
144 handler,
145 control: ControlPipe::new(control),
146 device_descriptor,
147 config_descriptor,
148 bos_descriptor,
149 control_buf, 146 control_buf,
150 device_state: UsbDeviceState::Disabled, 147 control: ControlPipe::new(control),
151 suspended: false, 148 inner: Inner {
152 remote_wakeup_enabled: false, 149 bus,
153 self_powered: false, 150 config,
154 pending_address: 0, 151 handler,
155 interfaces, 152 device_descriptor,
153 config_descriptor,
154 bos_descriptor,
155
156 device_state: UsbDeviceState::Disabled,
157 suspended: false,
158 remote_wakeup_enabled: false,
159 self_powered: false,
160 pending_address: 0,
161 interfaces,
162 },
156 } 163 }
157 } 164 }
158 165
@@ -176,28 +183,60 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
176 /// before calling any other `UsbDevice` methods to fully reset the 183 /// before calling any other `UsbDevice` methods to fully reset the
177 /// peripheral. 184 /// peripheral.
178 pub async fn run_until_suspend(&mut self) -> () { 185 pub async fn run_until_suspend(&mut self) -> () {
179 if self.device_state == UsbDeviceState::Disabled { 186 if self.inner.device_state == UsbDeviceState::Disabled {
180 self.bus.enable().await; 187 self.inner.bus.enable().await;
181 self.device_state = UsbDeviceState::Default; 188 self.inner.device_state = UsbDeviceState::Default;
182 189
183 if let Some(h) = &self.handler { 190 if let Some(h) = &self.inner.handler {
184 h.enabled(true); 191 h.enabled(true);
185 } 192 }
186 } 193 }
187 194
188 loop { 195 loop {
189 let control_fut = self.control.setup(); 196 let control_fut = self.control.setup();
190 let bus_fut = self.bus.poll(); 197 let bus_fut = self.inner.bus.poll();
191 match select(bus_fut, control_fut).await { 198 match select(bus_fut, control_fut).await {
192 Either::First(evt) => { 199 Either::First(evt) => {
193 self.handle_bus_event(evt); 200 self.inner.handle_bus_event(evt);
194 if self.suspended { 201 if self.inner.suspended {
195 return; 202 return;
196 } 203 }
197 } 204 }
198 Either::Second(req) => match req { 205 Either::Second(req) => match req {
199 Setup::DataIn(req, stage) => self.handle_control_in(req, stage).await, 206 Setup::DataIn(req, mut stage) => {
200 Setup::DataOut(req, stage) => self.handle_control_out(req, stage).await, 207 // If we don't have an address yet, respond with max 1 packet.
208 // The host doesn't know our EP0 max packet size yet, and might assume
209 // a full-length packet is a short packet, thinking we're done sending data.
210 // See https://github.com/hathach/tinyusb/issues/184
211 const DEVICE_DESCRIPTOR_LEN: u8 = 18;
212 if self.inner.pending_address == 0
213 && self.inner.config.max_packet_size_0 < DEVICE_DESCRIPTOR_LEN
214 && (self.inner.config.max_packet_size_0 as usize) < stage.length
215 {
216 trace!("received control req while not addressed: capping response to 1 packet.");
217 stage.length = self.inner.config.max_packet_size_0 as _;
218 }
219
220 match self.inner.handle_control_in(req, &mut self.control_buf) {
221 InResponse::Accepted(data) => self.control.accept_in(data, stage).await,
222 InResponse::Rejected => self.control.reject(),
223 }
224 }
225 Setup::DataOut(req, stage) => {
226 let (data, stage) =
227 match self.control.data_out(self.control_buf, stage).await {
228 Ok(data) => data,
229 Err(_) => {
230 warn!("usb: failed to read CONTROL OUT data stage.");
231 return;
232 }
233 };
234
235 match self.inner.handle_control_out(req, data) {
236 OutResponse::Accepted => self.control.accept(stage),
237 OutResponse::Rejected => self.control.reject(),
238 }
239 }
201 }, 240 },
202 } 241 }
203 } 242 }
@@ -205,13 +244,13 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
205 244
206 /// Disables the USB peripheral. 245 /// Disables the USB peripheral.
207 pub async fn disable(&mut self) { 246 pub async fn disable(&mut self) {
208 if self.device_state != UsbDeviceState::Disabled { 247 if self.inner.device_state != UsbDeviceState::Disabled {
209 self.bus.disable().await; 248 self.inner.bus.disable().await;
210 self.device_state = UsbDeviceState::Disabled; 249 self.inner.device_state = UsbDeviceState::Disabled;
211 self.suspended = false; 250 self.inner.suspended = false;
212 self.remote_wakeup_enabled = false; 251 self.inner.remote_wakeup_enabled = false;
213 252
214 if let Some(h) = &self.handler { 253 if let Some(h) = &self.inner.handler {
215 h.enabled(false); 254 h.enabled(false);
216 } 255 }
217 } 256 }
@@ -221,9 +260,9 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
221 /// 260 ///
222 /// This future is cancel-safe. 261 /// This future is cancel-safe.
223 pub async fn wait_resume(&mut self) { 262 pub async fn wait_resume(&mut self) {
224 while self.suspended { 263 while self.inner.suspended {
225 let evt = self.bus.poll().await; 264 let evt = self.inner.bus.poll().await;
226 self.handle_bus_event(evt); 265 self.inner.handle_bus_event(evt);
227 } 266 }
228 } 267 }
229 268
@@ -236,11 +275,11 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
236 /// After dropping the future, [`UsbDevice::disable()`] should be called 275 /// After dropping the future, [`UsbDevice::disable()`] should be called
237 /// before calling any other `UsbDevice` methods to fully reset the peripheral. 276 /// before calling any other `UsbDevice` methods to fully reset the peripheral.
238 pub async fn remote_wakeup(&mut self) -> Result<(), RemoteWakeupError> { 277 pub async fn remote_wakeup(&mut self) -> Result<(), RemoteWakeupError> {
239 if self.suspended && self.remote_wakeup_enabled { 278 if self.inner.suspended && self.inner.remote_wakeup_enabled {
240 self.bus.remote_wakeup().await?; 279 self.inner.bus.remote_wakeup().await?;
241 self.suspended = false; 280 self.inner.suspended = false;
242 281
243 if let Some(h) = &self.handler { 282 if let Some(h) = &self.inner.handler {
244 h.suspended(false); 283 h.suspended(false);
245 } 284 }
246 285
@@ -249,7 +288,9 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
249 Err(RemoteWakeupError::InvalidState) 288 Err(RemoteWakeupError::InvalidState)
250 } 289 }
251 } 290 }
291}
252 292
293impl<'d, D: Driver<'d>> Inner<'d, D> {
253 fn handle_bus_event(&mut self, evt: Event) { 294 fn handle_bus_event(&mut self, evt: Event) {
254 match evt { 295 match evt {
255 Event::Reset => { 296 Event::Reset => {
@@ -288,18 +329,10 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
288 } 329 }
289 } 330 }
290 331
291 async fn handle_control_out(&mut self, req: Request, stage: DataOutStage) { 332 fn handle_control_out(&mut self, req: Request, data: &[u8]) -> OutResponse {
292 const CONFIGURATION_NONE_U16: u16 = CONFIGURATION_NONE as u16; 333 const CONFIGURATION_NONE_U16: u16 = CONFIGURATION_NONE as u16;
293 const CONFIGURATION_VALUE_U16: u16 = CONFIGURATION_VALUE as u16; 334 const CONFIGURATION_VALUE_U16: u16 = CONFIGURATION_VALUE as u16;
294 335
295 let (data, stage) = match self.control.data_out(self.control_buf, stage).await {
296 Ok(data) => data,
297 Err(_) => {
298 warn!("usb: failed to read CONTROL OUT data stage.");
299 return;
300 }
301 };
302
303 match (req.request_type, req.recipient) { 336 match (req.request_type, req.recipient) {
304 (RequestType::Standard, Recipient::Device) => match (req.request, req.value) { 337 (RequestType::Standard, Recipient::Device) => match (req.request, req.value) {
305 (Request::CLEAR_FEATURE, Request::FEATURE_DEVICE_REMOTE_WAKEUP) => { 338 (Request::CLEAR_FEATURE, Request::FEATURE_DEVICE_REMOTE_WAKEUP) => {
@@ -307,14 +340,14 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
307 if let Some(h) = &self.handler { 340 if let Some(h) = &self.handler {
308 h.remote_wakeup_enabled(false); 341 h.remote_wakeup_enabled(false);
309 } 342 }
310 self.control.accept(stage) 343 OutResponse::Accepted
311 } 344 }
312 (Request::SET_FEATURE, Request::FEATURE_DEVICE_REMOTE_WAKEUP) => { 345 (Request::SET_FEATURE, Request::FEATURE_DEVICE_REMOTE_WAKEUP) => {
313 self.remote_wakeup_enabled = true; 346 self.remote_wakeup_enabled = true;
314 if let Some(h) = &self.handler { 347 if let Some(h) = &self.handler {
315 h.remote_wakeup_enabled(true); 348 h.remote_wakeup_enabled(true);
316 } 349 }
317 self.control.accept(stage) 350 OutResponse::Accepted
318 } 351 }
319 (Request::SET_ADDRESS, addr @ 1..=127) => { 352 (Request::SET_ADDRESS, addr @ 1..=127) => {
320 self.pending_address = addr as u8; 353 self.pending_address = addr as u8;
@@ -323,7 +356,7 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
323 if let Some(h) = &self.handler { 356 if let Some(h) = &self.handler {
324 h.addressed(self.pending_address); 357 h.addressed(self.pending_address);
325 } 358 }
326 self.control.accept(stage) 359 OutResponse::Accepted
327 } 360 }
328 (Request::SET_CONFIGURATION, CONFIGURATION_VALUE_U16) => { 361 (Request::SET_CONFIGURATION, CONFIGURATION_VALUE_U16) => {
329 debug!("SET_CONFIGURATION: configured"); 362 debug!("SET_CONFIGURATION: configured");
@@ -344,10 +377,10 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
344 h.configured(true); 377 h.configured(true);
345 } 378 }
346 379
347 self.control.accept(stage) 380 OutResponse::Accepted
348 } 381 }
349 (Request::SET_CONFIGURATION, CONFIGURATION_NONE_U16) => match self.device_state { 382 (Request::SET_CONFIGURATION, CONFIGURATION_NONE_U16) => match self.device_state {
350 UsbDeviceState::Default => self.control.accept(stage), 383 UsbDeviceState::Default => OutResponse::Accepted,
351 _ => { 384 _ => {
352 debug!("SET_CONFIGURATION: unconfigured"); 385 debug!("SET_CONFIGURATION: unconfigured");
353 self.device_state = UsbDeviceState::Addressed; 386 self.device_state = UsbDeviceState::Addressed;
@@ -363,15 +396,15 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
363 h.configured(false); 396 h.configured(false);
364 } 397 }
365 398
366 self.control.accept(stage) 399 OutResponse::Accepted
367 } 400 }
368 }, 401 },
369 _ => self.control.reject(), 402 _ => OutResponse::Rejected,
370 }, 403 },
371 (RequestType::Standard, Recipient::Interface) => { 404 (RequestType::Standard, Recipient::Interface) => {
372 let iface = match self.interfaces.get_mut(req.index as usize) { 405 let iface = match self.interfaces.get_mut(req.index as usize) {
373 Some(iface) => iface, 406 Some(iface) => iface,
374 None => return self.control.reject(), 407 None => return OutResponse::Rejected,
375 }; 408 };
376 409
377 match req.request { 410 match req.request {
@@ -380,7 +413,7 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
380 413
381 if new_altsetting >= iface.num_alt_settings { 414 if new_altsetting >= iface.num_alt_settings {
382 warn!("SET_INTERFACE: trying to select alt setting out of range."); 415 warn!("SET_INTERFACE: trying to select alt setting out of range.");
383 return self.control.reject(); 416 return OutResponse::Rejected;
384 } 417 }
385 418
386 iface.current_alt_setting = new_altsetting; 419 iface.current_alt_setting = new_altsetting;
@@ -402,55 +435,39 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
402 if let Some(handler) = &mut iface.handler { 435 if let Some(handler) = &mut iface.handler {
403 handler.set_alternate_setting(new_altsetting); 436 handler.set_alternate_setting(new_altsetting);
404 } 437 }
405 self.control.accept(stage) 438 OutResponse::Accepted
406 } 439 }
407 _ => self.control.reject(), 440 _ => OutResponse::Rejected,
408 } 441 }
409 } 442 }
410 (RequestType::Standard, Recipient::Endpoint) => match (req.request, req.value) { 443 (RequestType::Standard, Recipient::Endpoint) => match (req.request, req.value) {
411 (Request::SET_FEATURE, Request::FEATURE_ENDPOINT_HALT) => { 444 (Request::SET_FEATURE, Request::FEATURE_ENDPOINT_HALT) => {
412 let ep_addr = ((req.index as u8) & 0x8f).into(); 445 let ep_addr = ((req.index as u8) & 0x8f).into();
413 self.bus.endpoint_set_stalled(ep_addr, true); 446 self.bus.endpoint_set_stalled(ep_addr, true);
414 self.control.accept(stage) 447 OutResponse::Accepted
415 } 448 }
416 (Request::CLEAR_FEATURE, Request::FEATURE_ENDPOINT_HALT) => { 449 (Request::CLEAR_FEATURE, Request::FEATURE_ENDPOINT_HALT) => {
417 let ep_addr = ((req.index as u8) & 0x8f).into(); 450 let ep_addr = ((req.index as u8) & 0x8f).into();
418 self.bus.endpoint_set_stalled(ep_addr, false); 451 self.bus.endpoint_set_stalled(ep_addr, false);
419 self.control.accept(stage) 452 OutResponse::Accepted
420 } 453 }
421 _ => self.control.reject(), 454 _ => OutResponse::Rejected,
422 }, 455 },
423 (RequestType::Class, Recipient::Interface) => { 456 (RequestType::Class, Recipient::Interface) => {
424 let iface = match self.interfaces.get_mut(req.index as usize) { 457 let iface = match self.interfaces.get_mut(req.index as usize) {
425 Some(iface) => iface, 458 Some(iface) => iface,
426 None => return self.control.reject(), 459 None => return OutResponse::Rejected,
427 }; 460 };
428 match &mut iface.handler { 461 match &mut iface.handler {
429 Some(handler) => match handler.control_out(req, data) { 462 Some(handler) => handler.control_out(req, data),
430 OutResponse::Accepted => self.control.accept(stage), 463 None => OutResponse::Rejected,
431 OutResponse::Rejected => self.control.reject(),
432 },
433 None => self.control.reject(),
434 } 464 }
435 } 465 }
436 _ => self.control.reject(), 466 _ => OutResponse::Rejected,
437 } 467 }
438 } 468 }
439 469
440 async fn handle_control_in(&mut self, req: Request, mut stage: DataInStage) { 470 fn handle_control_in<'a>(&'a mut self, req: Request, buf: &'a mut [u8]) -> InResponse<'a> {
441 // If we don't have an address yet, respond with max 1 packet.
442 // The host doesn't know our EP0 max packet size yet, and might assume
443 // a full-length packet is a short packet, thinking we're done sending data.
444 // See https://github.com/hathach/tinyusb/issues/184
445 const DEVICE_DESCRIPTOR_LEN: u8 = 18;
446 if self.pending_address == 0
447 && self.config.max_packet_size_0 < DEVICE_DESCRIPTOR_LEN
448 && (self.config.max_packet_size_0 as usize) < stage.length
449 {
450 trace!("received control req while not addressed: capping response to 1 packet.");
451 stage.length = self.config.max_packet_size_0 as _;
452 }
453
454 match (req.request_type, req.recipient) { 471 match (req.request_type, req.recipient) {
455 (RequestType::Standard, Recipient::Device) => match req.request { 472 (RequestType::Standard, Recipient::Device) => match req.request {
456 Request::GET_STATUS => { 473 Request::GET_STATUS => {
@@ -461,42 +478,41 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
461 if self.remote_wakeup_enabled { 478 if self.remote_wakeup_enabled {
462 status |= 0x0002; 479 status |= 0x0002;
463 } 480 }
464 self.control.accept_in(&status.to_le_bytes(), stage).await 481 buf[..2].copy_from_slice(&status.to_le_bytes());
482 InResponse::Accepted(&buf[..2])
465 } 483 }
466 Request::GET_DESCRIPTOR => self.handle_get_descriptor(req, stage).await, 484 Request::GET_DESCRIPTOR => self.handle_get_descriptor(req, buf),
467 Request::GET_CONFIGURATION => { 485 Request::GET_CONFIGURATION => {
468 let status = match self.device_state { 486 let status = match self.device_state {
469 UsbDeviceState::Configured => CONFIGURATION_VALUE, 487 UsbDeviceState::Configured => CONFIGURATION_VALUE,
470 _ => CONFIGURATION_NONE, 488 _ => CONFIGURATION_NONE,
471 }; 489 };
472 self.control.accept_in(&status.to_le_bytes(), stage).await 490 buf[0] = status;
491 InResponse::Accepted(&buf[..1])
473 } 492 }
474 _ => self.control.reject(), 493 _ => InResponse::Rejected,
475 }, 494 },
476 (RequestType::Standard, Recipient::Interface) => { 495 (RequestType::Standard, Recipient::Interface) => {
477 let iface = match self.interfaces.get_mut(req.index as usize) { 496 let iface = match self.interfaces.get_mut(req.index as usize) {
478 Some(iface) => iface, 497 Some(iface) => iface,
479 None => return self.control.reject(), 498 None => return InResponse::Rejected,
480 }; 499 };
481 500
482 match req.request { 501 match req.request {
483 Request::GET_STATUS => { 502 Request::GET_STATUS => {
484 let status: u16 = 0; 503 let status: u16 = 0;
485 self.control.accept_in(&status.to_le_bytes(), stage).await 504 buf[..2].copy_from_slice(&status.to_le_bytes());
505 InResponse::Accepted(&buf[..2])
486 } 506 }
487 Request::GET_INTERFACE => { 507 Request::GET_INTERFACE => {
488 self.control 508 buf[0] = iface.current_alt_setting;
489 .accept_in(&[iface.current_alt_setting], stage) 509 InResponse::Accepted(&buf[..1])
490 .await;
491 } 510 }
492 Request::GET_DESCRIPTOR => match &mut iface.handler { 511 Request::GET_DESCRIPTOR => match &mut iface.handler {
493 Some(handler) => match handler.get_descriptor(req, self.control_buf) { 512 Some(handler) => handler.get_descriptor(req, buf),
494 InResponse::Accepted(data) => self.control.accept_in(data, stage).await, 513 None => InResponse::Rejected,
495 InResponse::Rejected => self.control.reject(),
496 },
497 None => self.control.reject(),
498 }, 514 },
499 _ => self.control.reject(), 515 _ => InResponse::Rejected,
500 } 516 }
501 } 517 }
502 (RequestType::Standard, Recipient::Endpoint) => match req.request { 518 (RequestType::Standard, Recipient::Endpoint) => match req.request {
@@ -506,44 +522,40 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
506 if self.bus.endpoint_is_stalled(ep_addr) { 522 if self.bus.endpoint_is_stalled(ep_addr) {
507 status |= 0x0001; 523 status |= 0x0001;
508 } 524 }
509 self.control.accept_in(&status.to_le_bytes(), stage).await 525 buf[..2].copy_from_slice(&status.to_le_bytes());
526 InResponse::Accepted(&buf[..2])
510 } 527 }
511 _ => self.control.reject(), 528 _ => InResponse::Rejected,
512 }, 529 },
513 (RequestType::Class, Recipient::Interface) => { 530 (RequestType::Class, Recipient::Interface) => {
514 let iface = match self.interfaces.get_mut(req.index as usize) { 531 let iface = match self.interfaces.get_mut(req.index as usize) {
515 Some(iface) => iface, 532 Some(iface) => iface,
516 None => return self.control.reject(), 533 None => return InResponse::Rejected,
517 }; 534 };
518 535
519 match &mut iface.handler { 536 match &mut iface.handler {
520 Some(handler) => match handler.control_in(req, self.control_buf) { 537 Some(handler) => handler.control_in(req, buf),
521 InResponse::Accepted(data) => self.control.accept_in(data, stage).await, 538 None => InResponse::Rejected,
522 InResponse::Rejected => self.control.reject(),
523 },
524 None => self.control.reject(),
525 } 539 }
526 } 540 }
527 _ => self.control.reject(), 541 _ => InResponse::Rejected,
528 } 542 }
529 } 543 }
530 544
531 async fn handle_get_descriptor(&mut self, req: Request, stage: DataInStage) { 545 fn handle_get_descriptor<'a>(&'a mut self, req: Request, buf: &'a mut [u8]) -> InResponse<'a> {
532 let (dtype, index) = req.descriptor_type_index(); 546 let (dtype, index) = req.descriptor_type_index();
533 547
534 match dtype { 548 match dtype {
535 descriptor_type::BOS => self.control.accept_in(self.bos_descriptor, stage).await, 549 descriptor_type::BOS => InResponse::Accepted(self.bos_descriptor),
536 descriptor_type::DEVICE => self.control.accept_in(self.device_descriptor, stage).await, 550 descriptor_type::DEVICE => InResponse::Accepted(self.device_descriptor),
537 descriptor_type::CONFIGURATION => { 551 descriptor_type::CONFIGURATION => InResponse::Accepted(self.config_descriptor),
538 self.control.accept_in(self.config_descriptor, stage).await
539 }
540 descriptor_type::STRING => { 552 descriptor_type::STRING => {
541 if index == 0 { 553 if index == 0 {
542 self.control 554 buf[0] = 4; // len
543 .accept_in_writer(req, stage, |w| { 555 buf[1] = descriptor_type::STRING;
544 w.write(descriptor_type::STRING, &lang_id::ENGLISH_US.to_le_bytes()); 556 buf[2] = lang_id::ENGLISH_US as u8;
545 }) 557 buf[3] = (lang_id::ENGLISH_US >> 8) as u8;
546 .await 558 InResponse::Accepted(&buf[..4])
547 } else { 559 } else {
548 let s = match index { 560 let s = match index {
549 STRING_INDEX_MANUFACTURER => self.config.manufacturer, 561 STRING_INDEX_MANUFACTURER => self.config.manufacturer,
@@ -565,7 +577,7 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
565 if let Some(handler) = &mut iface.handler { 577 if let Some(handler) = &mut iface.handler {
566 let index = StringIndex::new(index); 578 let index = StringIndex::new(index);
567 let lang_id = req.index; 579 let lang_id = req.index;
568 handler.get_string(index, lang_id, self.control_buf) 580 handler.get_string(index, lang_id)
569 } else { 581 } else {
570 warn!("String requested to an interface with no handler."); 582 warn!("String requested to an interface with no handler.");
571 None 583 None
@@ -578,15 +590,29 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
578 }; 590 };
579 591
580 if let Some(s) = s { 592 if let Some(s) = s {
581 self.control 593 if buf.len() < 2 {
582 .accept_in_writer(req, stage, |w| w.string(s)) 594 panic!("control buffer too small");
583 .await 595 }
596
597 buf[1] = descriptor_type::STRING;
598 let mut pos = 2;
599 for c in s.encode_utf16() {
600 if pos >= buf.len() {
601 panic!("control buffer too small");
602 }
603
604 buf[pos..pos + 2].copy_from_slice(&c.to_le_bytes());
605 pos += 2;
606 }
607
608 buf[0] = pos as u8;
609 InResponse::Accepted(&buf[..pos])
584 } else { 610 } else {
585 self.control.reject() 611 InResponse::Rejected
586 } 612 }
587 } 613 }
588 } 614 }
589 _ => self.control.reject(), 615 _ => InResponse::Rejected,
590 } 616 }
591 } 617 }
592} 618}