1use crate::bus::{InterfaceNumber, PollResult, StringIndex, UsbBus, UsbBusAllocator};
2use crate::class::{ControlIn, ControlOut, UsbClass};
3use crate::control;
4use crate::control_pipe::ControlPipe;
5use crate::descriptor::{descriptor_type, lang_id::LangID, BosWriter, DescriptorWriter};
6pub use crate::device_builder::{StringDescriptors, UsbDeviceBuilder, UsbVidPid};
7use crate::endpoint::{EndpointAddress, EndpointType};
8use crate::{Result, UsbDirection};
9
10#[repr(u8)]
14#[derive(PartialEq, Eq, Copy, Clone, Debug)]
15#[cfg_attr(feature = "defmt", derive(defmt::Format))]
16pub enum UsbDeviceState {
17 Default,
19
20 Addressed,
22
23 Configured,
25
26 Suspend,
28}
29
30const MAX_ENDPOINTS: usize = 16;
32
33#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
35#[repr(u16)]
36pub enum UsbRev {
37 Usb200 = 0x200,
39 Usb210 = 0x210,
43}
44
45pub struct UsbDevice<'a, B: UsbBus> {
47 bus: &'a B,
48 config: Config<'a>,
49 control: ControlPipe<'a, B>,
50 device_state: UsbDeviceState,
51 remote_wakeup_enabled: bool,
52 self_powered: bool,
53 suspended_device_state: Option<UsbDeviceState>,
54 pending_address: u8,
55}
56
57pub(crate) struct Config<'a> {
58 pub device_class: u8,
59 pub device_sub_class: u8,
60 pub device_protocol: u8,
61 pub max_packet_size_0: u8,
62 pub vendor_id: u16,
63 pub product_id: u16,
64 pub usb_rev: UsbRev,
65 pub device_release: u16,
66 pub string_descriptors: heapless::Vec<StringDescriptors<'a>, 16>,
67 pub self_powered: bool,
68 pub supports_remote_wakeup: bool,
69 pub composite_with_iads: bool,
70 pub max_power: u8,
71}
72
73pub const CONFIGURATION_NONE: u8 = 0;
75
76pub const CONFIGURATION_VALUE: u8 = 1;
78
79pub const DEFAULT_ALTERNATE_SETTING: u8 = 0;
81
82type ClassList<'a, B> = [&'a mut dyn UsbClass<B>];
83
84impl<B: UsbBus> UsbDevice<'_, B> {
85 pub(crate) fn build<'a>(alloc: &'a UsbBusAllocator<B>, config: Config<'a>) -> UsbDevice<'a, B> {
86 let control_out = alloc
87 .alloc(
88 Some(0x00.into()),
89 EndpointType::Control,
90 config.max_packet_size_0 as u16,
91 0,
92 )
93 .expect("failed to alloc control endpoint");
94
95 let control_in = alloc
96 .alloc(
97 Some(0x80.into()),
98 EndpointType::Control,
99 config.max_packet_size_0 as u16,
100 0,
101 )
102 .expect("failed to alloc control endpoint");
103
104 let bus = alloc.freeze();
105
106 UsbDevice {
107 bus,
108 config,
109 control: ControlPipe::new(control_out, control_in),
110 device_state: UsbDeviceState::Default,
111 remote_wakeup_enabled: false,
112 self_powered: false,
113 suspended_device_state: None,
114 pending_address: 0,
115 }
116 }
117
118 pub fn bus(&self) -> &B {
124 self.bus
125 }
126
127 pub fn state(&self) -> UsbDeviceState {
131 self.device_state
132 }
133
134 pub fn remote_wakeup_enabled(&self) -> bool {
136 self.remote_wakeup_enabled
137 }
138
139 pub fn self_powered(&self) -> bool {
141 self.self_powered
142 }
143
144 pub fn set_self_powered(&mut self, is_self_powered: bool) {
146 self.self_powered = is_self_powered;
147 }
148
149 pub fn force_reset(&mut self) -> Result<()> {
155 self.bus.force_reset()
156 }
157
158 pub fn poll(&mut self, classes: &mut ClassList<'_, B>) -> bool {
176 let pr = self.bus.poll();
177
178 if self.device_state == UsbDeviceState::Suspend {
179 match pr {
180 PollResult::Suspend | PollResult::None => {
181 return false;
182 }
183 _ => {
184 self.bus.resume();
185
186 self.device_state = self
187 .suspended_device_state
188 .expect("Unknown state before suspend");
189 self.suspended_device_state = None;
190 }
191 }
192 }
193
194 match pr {
195 PollResult::None => {}
196 PollResult::Reset => self.reset(classes),
197 PollResult::Data {
198 ep_out,
199 ep_in_complete,
200 ep_setup,
201 } => {
202 let mut eps = ep_out | ep_in_complete | ep_setup;
204
205 if (eps & 1) != 0 {
207 usb_debug!(
208 "EP0: setup={}, in_complete={}, out={}",
209 ep_setup & 1,
210 ep_in_complete & 1,
211 ep_out & 1
212 );
213
214 let req = if (ep_setup & 1) != 0 {
215 self.control.handle_setup()
216 } else if (ep_out & 1) != 0 {
217 match self.control.handle_out() {
218 Ok(req) => req,
219 Err(_err) => {
220 usb_debug!("Failed to handle EP0: {:?}", _err);
222 None
223 }
224 }
225 } else {
226 None
227 };
228
229 match req {
230 Some(req) if req.direction == UsbDirection::In => {
231 if let Err(_err) = self.control_in(classes, req) {
232 usb_debug!("Failed to handle input control request: {:?}", _err);
234 }
235 }
236 Some(req) if req.direction == UsbDirection::Out => {
237 if let Err(_err) = self.control_out(classes, req) {
238 usb_debug!("Failed to handle output control request: {:?}", _err);
240 }
241 }
242
243 None if ((ep_in_complete & 1) != 0) => {
244 let completed = match self.control.handle_in_complete() {
250 Ok(completed) => completed,
251 Err(_err) => {
252 usb_debug!(
254 "Failed to process control-input complete: {:?}",
255 _err
256 );
257 false
258 }
259 };
260
261 if !B::QUIRK_SET_ADDRESS_BEFORE_STATUS
262 && completed
263 && self.pending_address != 0
264 {
265 self.bus.set_device_address(self.pending_address);
266 self.pending_address = 0;
267
268 self.device_state = UsbDeviceState::Addressed;
269 }
270 }
271
272 _ => (),
273 };
274
275 eps &= !1;
276 }
277
278 if eps != 0 {
280 let mut bit = 2u16;
281
282 for i in 1..MAX_ENDPOINTS {
283 if (ep_setup & bit) != 0 {
284 for cls in classes.iter_mut() {
285 usb_trace!("Handling EP{}-SETUP", i);
286 cls.endpoint_setup(EndpointAddress::from_parts(
287 i,
288 UsbDirection::Out,
289 ));
290 }
291 } else if (ep_out & bit) != 0 {
292 usb_trace!("Handling EP{}-OUT", i);
293 for cls in classes.iter_mut() {
294 cls.endpoint_out(EndpointAddress::from_parts(i, UsbDirection::Out));
295 }
296 }
297
298 if (ep_in_complete & bit) != 0 {
299 usb_trace!("Handling EP{}-IN", i);
300 for cls in classes.iter_mut() {
301 cls.endpoint_in_complete(EndpointAddress::from_parts(
302 i,
303 UsbDirection::In,
304 ));
305 }
306 }
307
308 eps &= !bit;
309
310 if eps == 0 {
311 break;
313 }
314
315 bit <<= 1;
316 }
317 }
318
319 for cls in classes.iter_mut() {
320 cls.poll();
321 }
322
323 return true;
324 }
325 PollResult::Resume => {}
326 PollResult::Suspend => {
327 usb_debug!("Suspending bus");
328 self.bus.suspend();
329 self.suspended_device_state = Some(self.device_state);
330 self.device_state = UsbDeviceState::Suspend;
331 }
332 }
333
334 false
335 }
336
337 fn control_in(&mut self, classes: &mut ClassList<'_, B>, req: control::Request) -> Result<()> {
338 use crate::control::{Recipient, Request};
339
340 for cls in classes.iter_mut() {
341 cls.control_in(ControlIn::new(&mut self.control, &req));
342
343 if !self.control.waiting_for_response() {
344 return Ok(());
345 }
346 }
347
348 if req.request_type == control::RequestType::Standard {
349 let xfer = ControlIn::new(&mut self.control, &req);
350
351 match (req.recipient, req.request) {
352 (Recipient::Device, Request::GET_STATUS) => {
353 usb_trace!("Processing Device::GetStatus");
354 let status: u16 = if self.self_powered { 0x0001 } else { 0x0000 }
355 | if self.remote_wakeup_enabled {
356 0x0002
357 } else {
358 0x0000
359 };
360
361 xfer.accept_with(&status.to_le_bytes())?;
362 }
363
364 (Recipient::Interface, Request::GET_STATUS) => {
365 usb_trace!("Processing Interface::GetStatus");
366 let status: u16 = 0x0000;
367
368 xfer.accept_with(&status.to_le_bytes())?;
369 }
370
371 (Recipient::Endpoint, Request::GET_STATUS) => {
372 usb_trace!("Processing EP::GetStatus");
373 let ep_addr = ((req.index as u8) & 0x8f).into();
374
375 let status: u16 = if self.bus.is_stalled(ep_addr) {
376 0x0001
377 } else {
378 0x0000
379 };
380
381 xfer.accept_with(&status.to_le_bytes())?;
382 }
383
384 (Recipient::Device, Request::GET_DESCRIPTOR) => {
385 usb_trace!("Processing Device::GetDescriptor");
386 UsbDevice::get_descriptor(&self.config, classes, xfer)?;
387 }
388
389 (Recipient::Device, Request::GET_CONFIGURATION) => {
390 usb_trace!("Processing Device::GetConfiguration");
391 let config = match self.device_state {
392 UsbDeviceState::Configured => CONFIGURATION_VALUE,
393 _ => CONFIGURATION_NONE,
394 };
395
396 xfer.accept_with(&config.to_le_bytes())?;
397 }
398
399 (Recipient::Interface, Request::GET_INTERFACE) => {
400 usb_trace!("Processing Interface::GetInterface");
401 if req.index > core::u8::MAX.into() {
403 return xfer.reject();
404 }
405
406 for cls in classes {
409 if let Some(setting) = cls.get_alt_setting(InterfaceNumber(req.index as u8))
410 {
411 return xfer.accept_with(&setting.to_le_bytes());
412 }
413 }
414
415 xfer.accept_with(&DEFAULT_ALTERNATE_SETTING.to_le_bytes())?;
417 }
418
419 _ => {}
420 };
421 }
422
423 if self.control.waiting_for_response() {
424 usb_debug!("Rejecting control transfer because we were waiting for a response");
425 self.control.reject()?;
426 }
427
428 Ok(())
429 }
430
431 fn control_out(&mut self, classes: &mut ClassList<'_, B>, req: control::Request) -> Result<()> {
432 use crate::control::{Recipient, Request};
433
434 for cls in classes.iter_mut() {
435 cls.control_out(ControlOut::new(&mut self.control, &req));
436
437 if !self.control.waiting_for_response() {
438 return Ok(());
439 }
440 }
441
442 if req.request_type == control::RequestType::Standard {
443 let xfer = ControlOut::new(&mut self.control, &req);
444
445 const CONFIGURATION_NONE_U16: u16 = CONFIGURATION_NONE as u16;
446 const CONFIGURATION_VALUE_U16: u16 = CONFIGURATION_VALUE as u16;
447 const DEFAULT_ALTERNATE_SETTING_U16: u16 = DEFAULT_ALTERNATE_SETTING as u16;
448
449 match (req.recipient, req.request, req.value) {
450 (
451 Recipient::Device,
452 Request::CLEAR_FEATURE,
453 Request::FEATURE_DEVICE_REMOTE_WAKEUP,
454 ) => {
455 usb_debug!("Remote wakeup disabled");
456 self.remote_wakeup_enabled = false;
457 xfer.accept()?;
458 }
459
460 (Recipient::Endpoint, Request::CLEAR_FEATURE, Request::FEATURE_ENDPOINT_HALT) => {
461 usb_debug!("EP{} halt removed", req.index & 0x8f);
462 self.bus
463 .set_stalled(((req.index as u8) & 0x8f).into(), false);
464 xfer.accept()?;
465 }
466
467 (
468 Recipient::Device,
469 Request::SET_FEATURE,
470 Request::FEATURE_DEVICE_REMOTE_WAKEUP,
471 ) => {
472 usb_debug!("Remote wakeup enabled");
473 self.remote_wakeup_enabled = true;
474 xfer.accept()?;
475 }
476
477 (Recipient::Endpoint, Request::SET_FEATURE, Request::FEATURE_ENDPOINT_HALT) => {
478 usb_debug!("EP{} halted", req.index & 0x8f);
479 self.bus
480 .set_stalled(((req.index as u8) & 0x8f).into(), true);
481 xfer.accept()?;
482 }
483
484 (Recipient::Device, Request::SET_ADDRESS, 1..=127) => {
485 usb_debug!("Setting device address to {}", req.value);
486 if B::QUIRK_SET_ADDRESS_BEFORE_STATUS {
487 self.bus.set_device_address(req.value as u8);
488 self.device_state = UsbDeviceState::Addressed;
489 } else {
490 self.pending_address = req.value as u8;
491 }
492 xfer.accept()?;
493 }
494
495 (Recipient::Device, Request::SET_CONFIGURATION, CONFIGURATION_VALUE_U16) => {
496 usb_debug!("Device configured");
497 self.device_state = UsbDeviceState::Configured;
498 xfer.accept()?;
499 }
500
501 (Recipient::Device, Request::SET_CONFIGURATION, CONFIGURATION_NONE_U16) => {
502 usb_debug!("Device deconfigured");
503 match self.device_state {
504 UsbDeviceState::Default => {
505 xfer.accept()?;
506 }
507 _ => {
508 self.device_state = UsbDeviceState::Addressed;
509 xfer.accept()?;
510 }
511 }
512 }
513
514 (Recipient::Interface, Request::SET_INTERFACE, alt_setting) => {
515 if req.index > core::u8::MAX.into() || alt_setting > core::u8::MAX.into() {
517 xfer.reject()?;
518 return Ok(());
519 }
520
521 for cls in classes {
523 if cls.set_alt_setting(InterfaceNumber(req.index as u8), alt_setting as u8)
524 {
525 xfer.accept()?;
526 return Ok(());
527 }
528 }
529
530 if alt_setting == DEFAULT_ALTERNATE_SETTING_U16 {
532 usb_debug!("Accepting unused alternate settings");
533 xfer.accept()?;
534 } else {
535 usb_debug!("Rejecting unused alternate settings");
536 xfer.reject()?;
537 }
538 }
539
540 _ => {
541 xfer.reject()?;
542 return Ok(());
543 }
544 }
545 }
546
547 if self.control.waiting_for_response() {
548 usb_debug!("Rejecting control transfer due to waiting response");
549 self.control.reject()?;
550 }
551
552 Ok(())
553 }
554
555 fn get_descriptor(
556 config: &Config,
557 classes: &mut ClassList<'_, B>,
558 xfer: ControlIn<B>,
559 ) -> Result<()> {
560 let req = *xfer.request();
561
562 let (dtype, index) = req.descriptor_type_index();
563
564 fn accept_writer<B: UsbBus>(
565 xfer: ControlIn<B>,
566 f: impl FnOnce(&mut DescriptorWriter) -> Result<()>,
567 ) -> Result<()> {
568 xfer.accept(|buf| {
569 let mut writer = DescriptorWriter::new(buf);
570 f(&mut writer)?;
571 Ok(writer.position())
572 })?;
573
574 Ok(())
575 }
576
577 match dtype {
578 descriptor_type::BOS if config.usb_rev > UsbRev::Usb200 => accept_writer(xfer, |w| {
579 let mut bw = BosWriter::new(w);
580 bw.bos()?;
581
582 for cls in classes {
583 cls.get_bos_descriptors(&mut bw)?;
584 }
585
586 bw.end_bos();
587
588 Ok(())
589 })?,
590
591 descriptor_type::DEVICE => accept_writer(xfer, |w| w.device(config))?,
592
593 descriptor_type::CONFIGURATION => accept_writer(xfer, |w| {
594 w.configuration(config)?;
595
596 for cls in classes {
597 cls.get_configuration_descriptors(w)?;
598 w.end_class();
599 }
600
601 w.end_configuration();
602
603 Ok(())
604 })?,
605
606 descriptor_type::STRING => match index {
607 0 => {
609 let mut lang_id_bytes = [0u8; 32];
610 for (lang, buf) in config
611 .string_descriptors
612 .iter()
613 .zip(lang_id_bytes.chunks_exact_mut(2))
614 {
615 buf.copy_from_slice(&u16::from(lang.id).to_le_bytes());
616 }
617 accept_writer(xfer, |w| {
618 w.write(
619 descriptor_type::STRING,
620 &lang_id_bytes[..config.string_descriptors.len() * 2],
621 )
622 })?;
623 }
624
625 _ => {
627 let lang_id = LangID::from(req.index);
628
629 let string = match index {
630 1..=3 => {
632 let Some(lang) = config
633 .string_descriptors
634 .iter()
635 .find(|lang| lang.id == lang_id)
636 else {
637 xfer.reject()?;
638 return Ok(());
639 };
640
641 match index {
642 1 => lang.manufacturer,
643 2 => lang.product,
644 3 => lang.serial,
645 _ => unreachable!(),
646 }
647 }
648 _ => {
649 let index = StringIndex::new(index);
650 classes
651 .iter()
652 .find_map(|cls| cls.get_string(index, lang_id))
653 }
654 };
655
656 if let Some(string_descriptor) = string {
657 accept_writer(xfer, |w| w.string(string_descriptor))?;
658 } else {
659 xfer.reject()?;
660 }
661 }
662 },
663
664 _ => {
665 xfer.reject()?;
666 }
667 };
668
669 Ok(())
670 }
671
672 fn reset(&mut self, classes: &mut ClassList<'_, B>) {
673 self.bus.reset();
674
675 self.device_state = UsbDeviceState::Default;
676 self.suspended_device_state = None; self.remote_wakeup_enabled = false;
678 self.pending_address = 0;
679
680 self.control.reset();
681
682 for cls in classes {
683 cls.reset();
684 }
685 }
686}