aboutsummaryrefslogtreecommitdiff
path: root/embassy-usb/src/lib.rs
diff options
context:
space:
mode:
authorHenrik Alsér <[email protected]>2022-05-12 15:24:46 +0200
committerGitHub <[email protected]>2022-05-12 15:24:46 +0200
commit0be9184efc8f814a19081c2176b8317bd5217f0f (patch)
tree5b9469de15c0a1cc6e106a9a7455602e3bfaad17 /embassy-usb/src/lib.rs
parent1ca5475010a1cae6ebc55a27948ca4320decd5cd (diff)
parent30d4d0e9d78681e16a68ff953c61b96c9863bfc6 (diff)
Merge branch 'embassy-rs:master' into qdec
Diffstat (limited to 'embassy-usb/src/lib.rs')
-rw-r--r--embassy-usb/src/lib.rs335
1 files changed, 199 insertions, 136 deletions
diff --git a/embassy-usb/src/lib.rs b/embassy-usb/src/lib.rs
index 3bfedc048..b135f5eb3 100644
--- a/embassy-usb/src/lib.rs
+++ b/embassy-usb/src/lib.rs
@@ -16,6 +16,7 @@ use embassy::util::{select, Either};
16use heapless::Vec; 16use heapless::Vec;
17 17
18use crate::descriptor_reader::foreach_endpoint; 18use crate::descriptor_reader::foreach_endpoint;
19use crate::driver::ControlPipe;
19 20
20use self::control::*; 21use self::control::*;
21use self::descriptor::*; 22use self::descriptor::*;
@@ -100,15 +101,19 @@ struct Interface<'d> {
100} 101}
101 102
102pub struct UsbDevice<'d, D: Driver<'d>> { 103pub struct UsbDevice<'d, D: Driver<'d>> {
104 control_buf: &'d mut [u8],
105 control: D::ControlPipe,
106 inner: Inner<'d, D>,
107}
108
109struct Inner<'d, D: Driver<'d>> {
103 bus: D::Bus, 110 bus: D::Bus,
104 handler: Option<&'d dyn DeviceStateHandler>, 111 handler: Option<&'d dyn DeviceStateHandler>,
105 control: ControlPipe<D::ControlPipe>,
106 112
107 config: Config<'d>, 113 config: Config<'d>,
108 device_descriptor: &'d [u8], 114 device_descriptor: &'d [u8],
109 config_descriptor: &'d [u8], 115 config_descriptor: &'d [u8],
110 bos_descriptor: &'d [u8], 116 bos_descriptor: &'d [u8],
111 control_buf: &'d mut [u8],
112 117
113 device_state: UsbDeviceState, 118 device_state: UsbDeviceState,
114 suspended: bool, 119 suspended: bool,
@@ -121,7 +126,7 @@ pub struct UsbDevice<'d, D: Driver<'d>> {
121 126
122impl<'d, D: Driver<'d>> UsbDevice<'d, D> { 127impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
123 pub(crate) fn build( 128 pub(crate) fn build(
124 mut driver: D, 129 driver: D,
125 config: Config<'d>, 130 config: Config<'d>,
126 handler: Option<&'d dyn DeviceStateHandler>, 131 handler: Option<&'d dyn DeviceStateHandler>,
127 device_descriptor: &'d [u8], 132 device_descriptor: &'d [u8],
@@ -130,29 +135,28 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
130 interfaces: Vec<Interface<'d>, MAX_INTERFACE_COUNT>, 135 interfaces: Vec<Interface<'d>, MAX_INTERFACE_COUNT>,
131 control_buf: &'d mut [u8], 136 control_buf: &'d mut [u8],
132 ) -> UsbDevice<'d, D> { 137 ) -> UsbDevice<'d, D> {
133 let control = driver 138 // Start the USB bus.
134 .alloc_control_pipe(config.max_packet_size_0 as u16)
135 .expect("failed to alloc control endpoint");
136
137 // Enable the USB bus.
138 // This prevent further allocation by consuming the driver. 139 // This prevent further allocation by consuming the driver.
139 let bus = driver.into_bus(); 140 let (bus, control) = driver.start(config.max_packet_size_0 as u16);
140 141
141 Self { 142 Self {
142 bus,
143 config,
144 handler,
145 control: ControlPipe::new(control),
146 device_descriptor,
147 config_descriptor,
148 bos_descriptor,
149 control_buf, 143 control_buf,
150 device_state: UsbDeviceState::Disabled, 144 control,
151 suspended: false, 145 inner: Inner {
152 remote_wakeup_enabled: false, 146 bus,
153 self_powered: false, 147 config,
154 pending_address: 0, 148 handler,
155 interfaces, 149 device_descriptor,
150 config_descriptor,
151 bos_descriptor,
152
153 device_state: UsbDeviceState::Disabled,
154 suspended: false,
155 remote_wakeup_enabled: false,
156 self_powered: false,
157 pending_address: 0,
158 interfaces,
159 },
156 } 160 }
157 } 161 }
158 162
@@ -176,42 +180,34 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
176 /// before calling any other `UsbDevice` methods to fully reset the 180 /// before calling any other `UsbDevice` methods to fully reset the
177 /// peripheral. 181 /// peripheral.
178 pub async fn run_until_suspend(&mut self) -> () { 182 pub async fn run_until_suspend(&mut self) -> () {
179 if self.device_state == UsbDeviceState::Disabled { 183 if self.inner.device_state == UsbDeviceState::Disabled {
180 self.bus.enable().await; 184 self.inner.bus.enable().await;
181 self.device_state = UsbDeviceState::Default; 185 self.inner.device_state = UsbDeviceState::Default;
182 186
183 if let Some(h) = &self.handler { 187 if let Some(h) = &self.inner.handler {
184 h.enabled(true); 188 h.enabled(true);
185 } 189 }
186 } 190 }
187 191
188 loop { 192 while !self.inner.suspended {
189 let control_fut = self.control.setup(); 193 let control_fut = self.control.setup();
190 let bus_fut = self.bus.poll(); 194 let bus_fut = self.inner.bus.poll();
191 match select(bus_fut, control_fut).await { 195 match select(bus_fut, control_fut).await {
192 Either::First(evt) => { 196 Either::First(evt) => self.inner.handle_bus_event(evt),
193 self.handle_bus_event(evt); 197 Either::Second(req) => self.handle_control(req).await,
194 if self.suspended {
195 return;
196 }
197 }
198 Either::Second(req) => match req {
199 Setup::DataIn(req, stage) => self.handle_control_in(req, stage).await,
200 Setup::DataOut(req, stage) => self.handle_control_out(req, stage).await,
201 },
202 } 198 }
203 } 199 }
204 } 200 }
205 201
206 /// Disables the USB peripheral. 202 /// Disables the USB peripheral.
207 pub async fn disable(&mut self) { 203 pub async fn disable(&mut self) {
208 if self.device_state != UsbDeviceState::Disabled { 204 if self.inner.device_state != UsbDeviceState::Disabled {
209 self.bus.disable().await; 205 self.inner.bus.disable().await;
210 self.device_state = UsbDeviceState::Disabled; 206 self.inner.device_state = UsbDeviceState::Disabled;
211 self.suspended = false; 207 self.inner.suspended = false;
212 self.remote_wakeup_enabled = false; 208 self.inner.remote_wakeup_enabled = false;
213 209
214 if let Some(h) = &self.handler { 210 if let Some(h) = &self.inner.handler {
215 h.enabled(false); 211 h.enabled(false);
216 } 212 }
217 } 213 }
@@ -221,9 +217,9 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
221 /// 217 ///
222 /// This future is cancel-safe. 218 /// This future is cancel-safe.
223 pub async fn wait_resume(&mut self) { 219 pub async fn wait_resume(&mut self) {
224 while self.suspended { 220 while self.inner.suspended {
225 let evt = self.bus.poll().await; 221 let evt = self.inner.bus.poll().await;
226 self.handle_bus_event(evt); 222 self.inner.handle_bus_event(evt);
227 } 223 }
228 } 224 }
229 225
@@ -236,11 +232,11 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
236 /// After dropping the future, [`UsbDevice::disable()`] should be called 232 /// After dropping the future, [`UsbDevice::disable()`] should be called
237 /// before calling any other `UsbDevice` methods to fully reset the peripheral. 233 /// before calling any other `UsbDevice` methods to fully reset the peripheral.
238 pub async fn remote_wakeup(&mut self) -> Result<(), RemoteWakeupError> { 234 pub async fn remote_wakeup(&mut self) -> Result<(), RemoteWakeupError> {
239 if self.suspended && self.remote_wakeup_enabled { 235 if self.inner.suspended && self.inner.remote_wakeup_enabled {
240 self.bus.remote_wakeup().await?; 236 self.inner.bus.remote_wakeup().await?;
241 self.suspended = false; 237 self.inner.suspended = false;
242 238
243 if let Some(h) = &self.handler { 239 if let Some(h) = &self.inner.handler {
244 h.suspended(false); 240 h.suspended(false);
245 } 241 }
246 242
@@ -250,6 +246,88 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
250 } 246 }
251 } 247 }
252 248
249 async fn handle_control(&mut self, req: Request) {
250 trace!("control request: {:02x}", req);
251
252 match req.direction {
253 UsbDirection::In => self.handle_control_in(req).await,
254 UsbDirection::Out => self.handle_control_out(req).await,
255 }
256 }
257
258 async fn handle_control_in(&mut self, req: Request) {
259 let mut resp_length = req.length as usize;
260 let max_packet_size = self.control.max_packet_size();
261
262 // If we don't have an address yet, respond with max 1 packet.
263 // The host doesn't know our EP0 max packet size yet, and might assume
264 // a full-length packet is a short packet, thinking we're done sending data.
265 // See https://github.com/hathach/tinyusb/issues/184
266 const DEVICE_DESCRIPTOR_LEN: usize = 18;
267 if self.inner.pending_address == 0
268 && max_packet_size < DEVICE_DESCRIPTOR_LEN
269 && (max_packet_size as usize) < resp_length
270 {
271 trace!("received control req while not addressed: capping response to 1 packet.");
272 resp_length = max_packet_size;
273 }
274
275 match self.inner.handle_control_in(req, &mut self.control_buf) {
276 InResponse::Accepted(data) => {
277 let len = data.len().min(resp_length);
278 let need_zlp = len != resp_length && (len % usize::from(max_packet_size)) == 0;
279
280 let mut chunks = data[0..len]
281 .chunks(max_packet_size)
282 .chain(need_zlp.then(|| -> &[u8] { &[] }));
283
284 while let Some(chunk) = chunks.next() {
285 match self.control.data_in(chunk, chunks.size_hint().0 == 0).await {
286 Ok(()) => {}
287 Err(e) => {
288 warn!("control accept_in failed: {:?}", e);
289 return;
290 }
291 }
292 }
293 }
294 InResponse::Rejected => self.control.reject(),
295 }
296 }
297
298 async fn handle_control_out(&mut self, req: Request) {
299 let req_length = req.length as usize;
300 let max_packet_size = self.control.max_packet_size();
301 let mut total = 0;
302
303 for chunk in self.control_buf[..req_length].chunks_mut(max_packet_size) {
304 let size = match self.control.data_out(chunk).await {
305 Ok(x) => x,
306 Err(e) => {
307 warn!("usb: failed to read CONTROL OUT data stage: {:?}", e);
308 return;
309 }
310 };
311 total += size;
312 if size < max_packet_size || total == req_length {
313 break;
314 }
315 }
316
317 let data = &self.control_buf[0..total];
318 #[cfg(feature = "defmt")]
319 trace!(" control out data: {:02x}", data);
320 #[cfg(not(feature = "defmt"))]
321 trace!(" control out data: {:02x?}", data);
322
323 match self.inner.handle_control_out(req, data) {
324 OutResponse::Accepted => self.control.accept(),
325 OutResponse::Rejected => self.control.reject(),
326 }
327 }
328}
329
330impl<'d, D: Driver<'d>> Inner<'d, D> {
253 fn handle_bus_event(&mut self, evt: Event) { 331 fn handle_bus_event(&mut self, evt: Event) {
254 match evt { 332 match evt {
255 Event::Reset => { 333 Event::Reset => {
@@ -288,18 +366,10 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
288 } 366 }
289 } 367 }
290 368
291 async fn handle_control_out(&mut self, req: Request, stage: DataOutStage) { 369 fn handle_control_out(&mut self, req: Request, data: &[u8]) -> OutResponse {
292 const CONFIGURATION_NONE_U16: u16 = CONFIGURATION_NONE as u16; 370 const CONFIGURATION_NONE_U16: u16 = CONFIGURATION_NONE as u16;
293 const CONFIGURATION_VALUE_U16: u16 = CONFIGURATION_VALUE as u16; 371 const CONFIGURATION_VALUE_U16: u16 = CONFIGURATION_VALUE as u16;
294 372
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) { 373 match (req.request_type, req.recipient) {
304 (RequestType::Standard, Recipient::Device) => match (req.request, req.value) { 374 (RequestType::Standard, Recipient::Device) => match (req.request, req.value) {
305 (Request::CLEAR_FEATURE, Request::FEATURE_DEVICE_REMOTE_WAKEUP) => { 375 (Request::CLEAR_FEATURE, Request::FEATURE_DEVICE_REMOTE_WAKEUP) => {
@@ -307,14 +377,14 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
307 if let Some(h) = &self.handler { 377 if let Some(h) = &self.handler {
308 h.remote_wakeup_enabled(false); 378 h.remote_wakeup_enabled(false);
309 } 379 }
310 self.control.accept(stage) 380 OutResponse::Accepted
311 } 381 }
312 (Request::SET_FEATURE, Request::FEATURE_DEVICE_REMOTE_WAKEUP) => { 382 (Request::SET_FEATURE, Request::FEATURE_DEVICE_REMOTE_WAKEUP) => {
313 self.remote_wakeup_enabled = true; 383 self.remote_wakeup_enabled = true;
314 if let Some(h) = &self.handler { 384 if let Some(h) = &self.handler {
315 h.remote_wakeup_enabled(true); 385 h.remote_wakeup_enabled(true);
316 } 386 }
317 self.control.accept(stage) 387 OutResponse::Accepted
318 } 388 }
319 (Request::SET_ADDRESS, addr @ 1..=127) => { 389 (Request::SET_ADDRESS, addr @ 1..=127) => {
320 self.pending_address = addr as u8; 390 self.pending_address = addr as u8;
@@ -323,7 +393,7 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
323 if let Some(h) = &self.handler { 393 if let Some(h) = &self.handler {
324 h.addressed(self.pending_address); 394 h.addressed(self.pending_address);
325 } 395 }
326 self.control.accept(stage) 396 OutResponse::Accepted
327 } 397 }
328 (Request::SET_CONFIGURATION, CONFIGURATION_VALUE_U16) => { 398 (Request::SET_CONFIGURATION, CONFIGURATION_VALUE_U16) => {
329 debug!("SET_CONFIGURATION: configured"); 399 debug!("SET_CONFIGURATION: configured");
@@ -344,10 +414,10 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
344 h.configured(true); 414 h.configured(true);
345 } 415 }
346 416
347 self.control.accept(stage) 417 OutResponse::Accepted
348 } 418 }
349 (Request::SET_CONFIGURATION, CONFIGURATION_NONE_U16) => match self.device_state { 419 (Request::SET_CONFIGURATION, CONFIGURATION_NONE_U16) => match self.device_state {
350 UsbDeviceState::Default => self.control.accept(stage), 420 UsbDeviceState::Default => OutResponse::Accepted,
351 _ => { 421 _ => {
352 debug!("SET_CONFIGURATION: unconfigured"); 422 debug!("SET_CONFIGURATION: unconfigured");
353 self.device_state = UsbDeviceState::Addressed; 423 self.device_state = UsbDeviceState::Addressed;
@@ -363,15 +433,15 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
363 h.configured(false); 433 h.configured(false);
364 } 434 }
365 435
366 self.control.accept(stage) 436 OutResponse::Accepted
367 } 437 }
368 }, 438 },
369 _ => self.control.reject(), 439 _ => OutResponse::Rejected,
370 }, 440 },
371 (RequestType::Standard, Recipient::Interface) => { 441 (RequestType::Standard, Recipient::Interface) => {
372 let iface = match self.interfaces.get_mut(req.index as usize) { 442 let iface = match self.interfaces.get_mut(req.index as usize) {
373 Some(iface) => iface, 443 Some(iface) => iface,
374 None => return self.control.reject(), 444 None => return OutResponse::Rejected,
375 }; 445 };
376 446
377 match req.request { 447 match req.request {
@@ -380,7 +450,7 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
380 450
381 if new_altsetting >= iface.num_alt_settings { 451 if new_altsetting >= iface.num_alt_settings {
382 warn!("SET_INTERFACE: trying to select alt setting out of range."); 452 warn!("SET_INTERFACE: trying to select alt setting out of range.");
383 return self.control.reject(); 453 return OutResponse::Rejected;
384 } 454 }
385 455
386 iface.current_alt_setting = new_altsetting; 456 iface.current_alt_setting = new_altsetting;
@@ -402,55 +472,39 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
402 if let Some(handler) = &mut iface.handler { 472 if let Some(handler) = &mut iface.handler {
403 handler.set_alternate_setting(new_altsetting); 473 handler.set_alternate_setting(new_altsetting);
404 } 474 }
405 self.control.accept(stage) 475 OutResponse::Accepted
406 } 476 }
407 _ => self.control.reject(), 477 _ => OutResponse::Rejected,
408 } 478 }
409 } 479 }
410 (RequestType::Standard, Recipient::Endpoint) => match (req.request, req.value) { 480 (RequestType::Standard, Recipient::Endpoint) => match (req.request, req.value) {
411 (Request::SET_FEATURE, Request::FEATURE_ENDPOINT_HALT) => { 481 (Request::SET_FEATURE, Request::FEATURE_ENDPOINT_HALT) => {
412 let ep_addr = ((req.index as u8) & 0x8f).into(); 482 let ep_addr = ((req.index as u8) & 0x8f).into();
413 self.bus.endpoint_set_stalled(ep_addr, true); 483 self.bus.endpoint_set_stalled(ep_addr, true);
414 self.control.accept(stage) 484 OutResponse::Accepted
415 } 485 }
416 (Request::CLEAR_FEATURE, Request::FEATURE_ENDPOINT_HALT) => { 486 (Request::CLEAR_FEATURE, Request::FEATURE_ENDPOINT_HALT) => {
417 let ep_addr = ((req.index as u8) & 0x8f).into(); 487 let ep_addr = ((req.index as u8) & 0x8f).into();
418 self.bus.endpoint_set_stalled(ep_addr, false); 488 self.bus.endpoint_set_stalled(ep_addr, false);
419 self.control.accept(stage) 489 OutResponse::Accepted
420 } 490 }
421 _ => self.control.reject(), 491 _ => OutResponse::Rejected,
422 }, 492 },
423 (RequestType::Class, Recipient::Interface) => { 493 (RequestType::Class, Recipient::Interface) => {
424 let iface = match self.interfaces.get_mut(req.index as usize) { 494 let iface = match self.interfaces.get_mut(req.index as usize) {
425 Some(iface) => iface, 495 Some(iface) => iface,
426 None => return self.control.reject(), 496 None => return OutResponse::Rejected,
427 }; 497 };
428 match &mut iface.handler { 498 match &mut iface.handler {
429 Some(handler) => match handler.control_out(req, data) { 499 Some(handler) => handler.control_out(req, data),
430 OutResponse::Accepted => self.control.accept(stage), 500 None => OutResponse::Rejected,
431 OutResponse::Rejected => self.control.reject(),
432 },
433 None => self.control.reject(),
434 } 501 }
435 } 502 }
436 _ => self.control.reject(), 503 _ => OutResponse::Rejected,
437 } 504 }
438 } 505 }
439 506
440 async fn handle_control_in(&mut self, req: Request, mut stage: DataInStage) { 507 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) { 508 match (req.request_type, req.recipient) {
455 (RequestType::Standard, Recipient::Device) => match req.request { 509 (RequestType::Standard, Recipient::Device) => match req.request {
456 Request::GET_STATUS => { 510 Request::GET_STATUS => {
@@ -461,42 +515,41 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
461 if self.remote_wakeup_enabled { 515 if self.remote_wakeup_enabled {
462 status |= 0x0002; 516 status |= 0x0002;
463 } 517 }
464 self.control.accept_in(&status.to_le_bytes(), stage).await 518 buf[..2].copy_from_slice(&status.to_le_bytes());
519 InResponse::Accepted(&buf[..2])
465 } 520 }
466 Request::GET_DESCRIPTOR => self.handle_get_descriptor(req, stage).await, 521 Request::GET_DESCRIPTOR => self.handle_get_descriptor(req, buf),
467 Request::GET_CONFIGURATION => { 522 Request::GET_CONFIGURATION => {
468 let status = match self.device_state { 523 let status = match self.device_state {
469 UsbDeviceState::Configured => CONFIGURATION_VALUE, 524 UsbDeviceState::Configured => CONFIGURATION_VALUE,
470 _ => CONFIGURATION_NONE, 525 _ => CONFIGURATION_NONE,
471 }; 526 };
472 self.control.accept_in(&status.to_le_bytes(), stage).await 527 buf[0] = status;
528 InResponse::Accepted(&buf[..1])
473 } 529 }
474 _ => self.control.reject(), 530 _ => InResponse::Rejected,
475 }, 531 },
476 (RequestType::Standard, Recipient::Interface) => { 532 (RequestType::Standard, Recipient::Interface) => {
477 let iface = match self.interfaces.get_mut(req.index as usize) { 533 let iface = match self.interfaces.get_mut(req.index as usize) {
478 Some(iface) => iface, 534 Some(iface) => iface,
479 None => return self.control.reject(), 535 None => return InResponse::Rejected,
480 }; 536 };
481 537
482 match req.request { 538 match req.request {
483 Request::GET_STATUS => { 539 Request::GET_STATUS => {
484 let status: u16 = 0; 540 let status: u16 = 0;
485 self.control.accept_in(&status.to_le_bytes(), stage).await 541 buf[..2].copy_from_slice(&status.to_le_bytes());
542 InResponse::Accepted(&buf[..2])
486 } 543 }
487 Request::GET_INTERFACE => { 544 Request::GET_INTERFACE => {
488 self.control 545 buf[0] = iface.current_alt_setting;
489 .accept_in(&[iface.current_alt_setting], stage) 546 InResponse::Accepted(&buf[..1])
490 .await;
491 } 547 }
492 Request::GET_DESCRIPTOR => match &mut iface.handler { 548 Request::GET_DESCRIPTOR => match &mut iface.handler {
493 Some(handler) => match handler.get_descriptor(req, self.control_buf) { 549 Some(handler) => handler.get_descriptor(req, buf),
494 InResponse::Accepted(data) => self.control.accept_in(data, stage).await, 550 None => InResponse::Rejected,
495 InResponse::Rejected => self.control.reject(),
496 },
497 None => self.control.reject(),
498 }, 551 },
499 _ => self.control.reject(), 552 _ => InResponse::Rejected,
500 } 553 }
501 } 554 }
502 (RequestType::Standard, Recipient::Endpoint) => match req.request { 555 (RequestType::Standard, Recipient::Endpoint) => match req.request {
@@ -506,44 +559,40 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
506 if self.bus.endpoint_is_stalled(ep_addr) { 559 if self.bus.endpoint_is_stalled(ep_addr) {
507 status |= 0x0001; 560 status |= 0x0001;
508 } 561 }
509 self.control.accept_in(&status.to_le_bytes(), stage).await 562 buf[..2].copy_from_slice(&status.to_le_bytes());
563 InResponse::Accepted(&buf[..2])
510 } 564 }
511 _ => self.control.reject(), 565 _ => InResponse::Rejected,
512 }, 566 },
513 (RequestType::Class, Recipient::Interface) => { 567 (RequestType::Class, Recipient::Interface) => {
514 let iface = match self.interfaces.get_mut(req.index as usize) { 568 let iface = match self.interfaces.get_mut(req.index as usize) {
515 Some(iface) => iface, 569 Some(iface) => iface,
516 None => return self.control.reject(), 570 None => return InResponse::Rejected,
517 }; 571 };
518 572
519 match &mut iface.handler { 573 match &mut iface.handler {
520 Some(handler) => match handler.control_in(req, self.control_buf) { 574 Some(handler) => handler.control_in(req, buf),
521 InResponse::Accepted(data) => self.control.accept_in(data, stage).await, 575 None => InResponse::Rejected,
522 InResponse::Rejected => self.control.reject(),
523 },
524 None => self.control.reject(),
525 } 576 }
526 } 577 }
527 _ => self.control.reject(), 578 _ => InResponse::Rejected,
528 } 579 }
529 } 580 }
530 581
531 async fn handle_get_descriptor(&mut self, req: Request, stage: DataInStage) { 582 fn handle_get_descriptor<'a>(&'a mut self, req: Request, buf: &'a mut [u8]) -> InResponse<'a> {
532 let (dtype, index) = req.descriptor_type_index(); 583 let (dtype, index) = req.descriptor_type_index();
533 584
534 match dtype { 585 match dtype {
535 descriptor_type::BOS => self.control.accept_in(self.bos_descriptor, stage).await, 586 descriptor_type::BOS => InResponse::Accepted(self.bos_descriptor),
536 descriptor_type::DEVICE => self.control.accept_in(self.device_descriptor, stage).await, 587 descriptor_type::DEVICE => InResponse::Accepted(self.device_descriptor),
537 descriptor_type::CONFIGURATION => { 588 descriptor_type::CONFIGURATION => InResponse::Accepted(self.config_descriptor),
538 self.control.accept_in(self.config_descriptor, stage).await
539 }
540 descriptor_type::STRING => { 589 descriptor_type::STRING => {
541 if index == 0 { 590 if index == 0 {
542 self.control 591 buf[0] = 4; // len
543 .accept_in_writer(req, stage, |w| { 592 buf[1] = descriptor_type::STRING;
544 w.write(descriptor_type::STRING, &lang_id::ENGLISH_US.to_le_bytes()); 593 buf[2] = lang_id::ENGLISH_US as u8;
545 }) 594 buf[3] = (lang_id::ENGLISH_US >> 8) as u8;
546 .await 595 InResponse::Accepted(&buf[..4])
547 } else { 596 } else {
548 let s = match index { 597 let s = match index {
549 STRING_INDEX_MANUFACTURER => self.config.manufacturer, 598 STRING_INDEX_MANUFACTURER => self.config.manufacturer,
@@ -565,7 +614,7 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
565 if let Some(handler) = &mut iface.handler { 614 if let Some(handler) = &mut iface.handler {
566 let index = StringIndex::new(index); 615 let index = StringIndex::new(index);
567 let lang_id = req.index; 616 let lang_id = req.index;
568 handler.get_string(index, lang_id, self.control_buf) 617 handler.get_string(index, lang_id)
569 } else { 618 } else {
570 warn!("String requested to an interface with no handler."); 619 warn!("String requested to an interface with no handler.");
571 None 620 None
@@ -578,15 +627,29 @@ impl<'d, D: Driver<'d>> UsbDevice<'d, D> {
578 }; 627 };
579 628
580 if let Some(s) = s { 629 if let Some(s) = s {
581 self.control 630 if buf.len() < 2 {
582 .accept_in_writer(req, stage, |w| w.string(s)) 631 panic!("control buffer too small");
583 .await 632 }
633
634 buf[1] = descriptor_type::STRING;
635 let mut pos = 2;
636 for c in s.encode_utf16() {
637 if pos >= buf.len() {
638 panic!("control buffer too small");
639 }
640
641 buf[pos..pos + 2].copy_from_slice(&c.to_le_bytes());
642 pos += 2;
643 }
644
645 buf[0] = pos as u8;
646 InResponse::Accepted(&buf[..pos])
584 } else { 647 } else {
585 self.control.reject() 648 InResponse::Rejected
586 } 649 }
587 } 650 }
588 } 651 }
589 _ => self.control.reject(), 652 _ => InResponse::Rejected,
590 } 653 }
591 } 654 }
592} 655}