usb: unify ControlHandler+DeviceStateHandler, route all control requests to all handlers.

- Allows classes to handle vendor requests.
- Allows classes to use a single handler for multiple interfaces.
- Allows classes to access the other events (previously only `reset` was available).
This commit is contained in:
Dario Nieuwenhuis
2023-02-07 22:49:14 +01:00
parent 1d841cc8ac
commit 3af991ab63
31 changed files with 381 additions and 338 deletions

View File

@@ -1,12 +1,12 @@
use heapless::Vec;
use crate::control::ControlHandler;
use crate::config::*;
use crate::descriptor::{BosWriter, DescriptorWriter};
use crate::driver::{Driver, Endpoint, EndpointType};
#[cfg(feature = "msos-descriptor")]
use crate::msos::{DeviceLevelDescriptor, FunctionLevelDescriptor, MsOsDescriptorWriter};
use crate::types::*;
use crate::{DeviceStateHandler, Interface, UsbDevice, MAX_INTERFACE_COUNT, STRING_INDEX_CUSTOM_START};
use crate::{Handler, Interface, UsbDevice, MAX_INTERFACE_COUNT, STRING_INDEX_CUSTOM_START};
#[derive(Debug, Copy, Clone)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
@@ -122,8 +122,8 @@ impl<'a> Config<'a> {
/// [`UsbDevice`] builder.
pub struct Builder<'d, D: Driver<'d>> {
config: Config<'d>,
handler: Option<&'d dyn DeviceStateHandler>,
interfaces: Vec<Interface<'d>, MAX_INTERFACE_COUNT>,
handlers: Vec<&'d mut dyn Handler, MAX_HANDLER_COUNT>,
interfaces: Vec<Interface, MAX_INTERFACE_COUNT>,
control_buf: &'d mut [u8],
driver: D,
@@ -151,7 +151,6 @@ impl<'d, D: Driver<'d>> Builder<'d, D> {
bos_descriptor_buf: &'d mut [u8],
#[cfg(feature = "msos-descriptor")] msos_descriptor_buf: &'d mut [u8],
control_buf: &'d mut [u8],
handler: Option<&'d dyn DeviceStateHandler>,
) -> Self {
// Magic values specified in USB-IF ECN on IADs.
if config.composite_with_iads
@@ -179,9 +178,9 @@ impl<'d, D: Driver<'d>> Builder<'d, D> {
Builder {
driver,
handler,
config,
interfaces: Vec::new(),
handlers: Vec::new(),
control_buf,
next_string_index: STRING_INDEX_CUSTOM_START,
@@ -205,7 +204,7 @@ impl<'d, D: Driver<'d>> Builder<'d, D> {
UsbDevice::build(
self.driver,
self.config,
self.handler,
self.handlers,
self.device_descriptor.into_buf(),
self.config_descriptor.into_buf(),
self.bos_descriptor.writer.into_buf(),
@@ -248,6 +247,26 @@ impl<'d, D: Driver<'d>> Builder<'d, D> {
}
}
/// Add a Handler.
///
/// The Handler is called on some USB bus events, and to handle all control requests not already
/// handled by the USB stack.
pub fn handler(&mut self, handler: &'d mut dyn Handler) {
if self.handlers.push(handler).is_err() {
panic!(
"embassy-usb: handler list full. Increase the `max_handler_count` compile-time setting. Current value: {}",
MAX_HANDLER_COUNT
)
}
}
/// Allocates a new string index.
pub fn string(&mut self) -> StringIndex {
let index = self.next_string_index;
self.next_string_index += 1;
StringIndex::new(index)
}
#[cfg(feature = "msos-descriptor")]
/// Add an MS OS 2.0 Descriptor Set.
///
@@ -301,10 +320,8 @@ impl<'a, 'd, D: Driver<'d>> FunctionBuilder<'a, 'd, D> {
let number = self.builder.interfaces.len() as _;
let iface = Interface {
handler: None,
current_alt_setting: 0,
num_alt_settings: 0,
num_strings: 0,
};
if self.builder.interfaces.push(iface).is_err() {
@@ -350,17 +367,9 @@ impl<'a, 'd, D: Driver<'d>> InterfaceBuilder<'a, 'd, D> {
self.interface_number
}
pub fn handler(&mut self, handler: &'d mut dyn ControlHandler) {
self.builder.interfaces[self.interface_number.0 as usize].handler = Some(handler);
}
/// Allocates a new string index.
pub fn string(&mut self) -> StringIndex {
let index = self.builder.next_string_index;
self.builder.next_string_index += 1;
self.builder.interfaces[self.interface_number.0 as usize].num_strings += 1;
StringIndex::new(index)
self.builder.string()
}
/// Add an alternate setting to the interface and write its descriptor.