1use alloc::{boxed::Box, string::String, vec::Vec};
2use futures::future::LocalBoxFuture;
3
4use crate::{
5 descriptor::{ConfigurationDescriptor, DeviceDescriptor},
6 err::TransferError,
7 transfer::{Recipient, Request, RequestType, wait::Waiter},
8};
9
10pub trait Controller: Send + 'static {
11 fn init(&mut self) -> LocalBoxFuture<'_, Result<(), USBError>>;
12 fn device_list(&self) -> LocalBoxFuture<'_, Result<Vec<Box<dyn DeviceInfo>>, USBError>>;
13
14 fn handle_event(&mut self);
16}
17
18pub trait DeviceInfo: Send + 'static {
19 fn open(&mut self) -> LocalBoxFuture<'_, Result<Box<dyn Device>, USBError>>;
20 fn descriptor(&self) -> LocalBoxFuture<'_, Result<DeviceDescriptor, USBError>>;
21 fn configuration_descriptor(
22 &mut self,
23 index: u8,
24 ) -> LocalBoxFuture<'_, Result<ConfigurationDescriptor, USBError>>;
25}
26
27pub trait Device: Send + 'static {
28 fn set_configuration(&mut self, configuration: u8) -> LocalBoxFuture<'_, Result<(), USBError>>;
29 fn get_configuration(&mut self) -> LocalBoxFuture<'_, Result<u8, USBError>>;
30 fn claim_interface(
31 &mut self,
32 interface: u8,
33 alternate: u8,
34 ) -> LocalBoxFuture<'_, Result<Box<dyn Interface>, USBError>>;
35
36 fn string_descriptor(
37 &mut self,
38 index: u8,
39 language_id: u16,
40 ) -> LocalBoxFuture<'_, Result<String, USBError>>;
41 fn control_in<'a>(&mut self, setup: ControlSetup, data: &'a mut [u8]) -> ResultTransfer<'a>;
42 fn control_out<'a>(&mut self, setup: ControlSetup, data: &'a [u8]) -> ResultTransfer<'a>;
43}
44
45pub trait Interface: Send + 'static {
46 fn set_alt_setting(&mut self, alt_setting: u8) -> Result<(), USBError>;
47 fn get_alt_setting(&self) -> Result<u8, USBError>;
48 fn control_in<'a>(&mut self, setup: ControlSetup, data: &'a mut [u8]) -> ResultTransfer<'a>;
49 fn control_out<'a>(&mut self, setup: ControlSetup, data: &'a [u8]) -> ResultTransfer<'a>;
50 fn endpoint_bulk_in(&mut self, endpoint: u8) -> Result<Box<dyn EndpointBulkIn>, USBError>;
51 fn endpoint_bulk_out(&mut self, endpoint: u8) -> Result<Box<dyn EndpointBulkOut>, USBError>;
52 fn endpoint_interrupt_in(
53 &mut self,
54 endpoint: u8,
55 ) -> Result<Box<dyn EndpointInterruptIn>, USBError>;
56 fn endpoint_interrupt_out(
57 &mut self,
58 endpoint: u8,
59 ) -> Result<Box<dyn EndpointInterruptOut>, USBError>;
60 fn endpoint_iso_in(&mut self, endpoint: u8) -> Result<Box<dyn EndpintIsoIn>, USBError>;
61 fn endpoint_iso_out(&mut self, endpoint: u8) -> Result<Box<dyn EndpintIsoOut>, USBError>;
62}
63
64pub trait TEndpoint: Send + 'static {}
65
66pub trait EndpointBulkIn: TEndpoint {
67 fn submit<'a>(&mut self, data: &'a mut [u8]) -> ResultTransfer<'a>;
68}
69pub trait EndpointBulkOut: TEndpoint {
70 fn submit<'a>(&mut self, data: &'a [u8]) -> ResultTransfer<'a>;
71}
72
73pub trait EndpointInterruptIn: TEndpoint {
74 fn submit<'a>(&mut self, data: &'a mut [u8]) -> ResultTransfer<'a>;
75}
76
77pub trait EndpointInterruptOut: TEndpoint {
78 fn submit<'a>(&mut self, data: &'a [u8]) -> ResultTransfer<'a>;
79}
80
81pub trait EndpintIsoIn: TEndpoint {
82 fn submit<'a>(&mut self, data: &'a mut [u8], num_iso_packets: usize) -> ResultTransfer<'a>;
83}
84
85pub trait EndpintIsoOut: TEndpoint {
86 fn submit<'a>(&mut self, data: &'a [u8], num_iso_packets: usize) -> ResultTransfer<'a>;
87}
88
89pub type TransferFuture<'a> = Waiter<'a, Result<usize, TransferError>>;
91pub type ResultTransfer<'a> = Result<TransferFuture<'a>, TransferError>;
92
93pub trait Transfer<'a>: Future<Output = Result<usize, TransferError>> + Send + 'a {}
94
95#[derive(thiserror::Error, Debug)]
96pub enum USBError {
97 #[error("Timeout")]
98 Timeout,
99 #[error("No memory available")]
100 NoMemory,
101 #[error("Transfer error: {0}")]
102 TransferError(#[from] TransferError),
103 #[error("Not initialized")]
104 NotInitialized,
105 #[error("Not found")]
106 NotFound,
107 #[error("Slot limit reached")]
108 SlotLimitReached,
109 #[error("Configuration not set")]
110 ConfigurationNotSet,
111 #[error("Other error: {0}")]
112 Other(String),
113}
114
115impl From<Box<dyn core::error::Error>> for USBError {
116 fn from(err: Box<dyn core::error::Error>) -> Self {
117 USBError::Other(alloc::format!("{err}"))
118 }
119}
120
121#[derive(Debug, Clone)]
122pub struct ControlSetup {
123 pub request_type: RequestType,
124 pub recipient: Recipient,
125 pub request: Request,
126 pub value: u16,
127 pub index: u16,
128}