crab_usb/common/
mod.rs

1use alloc::{boxed::Box, collections::BTreeMap, sync::Arc, vec::Vec};
2use core::{fmt::Display, ptr::NonNull, sync::atomic::AtomicBool};
3use log::trace;
4use usb_if::{
5    descriptor::{Class, ConfigurationDescriptor, DeviceDescriptor, EndpointDescriptor},
6    host::{Controller, ResultTransfer, USBError},
7};
8
9use crate::backend::xhci::Xhci;
10
11mod device;
12pub use device::*;
13
14pub struct EventHandler {
15    ptr: *mut USBHost,
16    running: Arc<AtomicBool>,
17}
18unsafe impl Send for EventHandler {}
19unsafe impl Sync for EventHandler {}
20
21impl EventHandler {
22    pub fn handle_event(&self) -> bool {
23        if !self.running.load(core::sync::atomic::Ordering::Acquire) {
24            return false;
25        }
26        unsafe {
27            (*self.ptr).handle_event();
28        }
29        true
30    }
31}
32
33pub struct USBHost {
34    raw: Box<dyn Controller>,
35    running: Arc<AtomicBool>,
36}
37
38impl USBHost {
39    pub fn from_trait(raw: impl Controller) -> Self {
40        USBHost {
41            raw: Box::new(raw),
42            running: Arc::new(AtomicBool::new(true)),
43        }
44    }
45
46    pub fn new_xhci(mmio_base: NonNull<u8>) -> Self {
47        let xhci = Xhci::new(mmio_base);
48        Self {
49            raw: xhci,
50            running: Arc::new(AtomicBool::new(true)),
51        }
52    }
53
54    #[cfg(feature = "libusb")]
55    pub fn new_libusb() -> Self {
56        let libusb = crate::backend::libusb::Libusb::new();
57        Self {
58            raw: Box::new(libusb),
59            running: Arc::new(AtomicBool::new(true)),
60        }
61    }
62
63    pub async fn init(&mut self) -> Result<(), USBError> {
64        self.raw.init().await
65    }
66
67    pub async fn device_list(&mut self) -> Result<impl Iterator<Item = DeviceInfo>, USBError> {
68        let devices = self.raw.device_list().await?;
69        let mut device_infos = Vec::with_capacity(devices.len());
70        for device in devices {
71            let device_info = DeviceInfo::from_box(device).await?;
72            device_infos.push(device_info);
73        }
74        Ok(device_infos.into_iter())
75    }
76
77    fn handle_event(&mut self) {
78        self.raw.handle_event();
79    }
80
81    pub fn event_handler(&mut self) -> EventHandler {
82        EventHandler {
83            ptr: self as *mut USBHost,
84            running: self.running.clone(),
85        }
86    }
87}
88
89impl Drop for USBHost {
90    fn drop(&mut self) {
91        self.running
92            .store(false, core::sync::atomic::Ordering::Release);
93        trace!("USBHost is being dropped, stopping event handler");
94    }
95}
96
97pub struct DeviceInfo {
98    raw: Box<dyn usb_if::host::DeviceInfo>,
99    pub descriptor: DeviceDescriptor,
100    pub configurations: Vec<ConfigurationDescriptor>,
101}
102
103impl Display for DeviceInfo {
104    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
105        f.debug_struct("DeviceInfo")
106            .field(
107                "id",
108                &alloc::format!(
109                    "{:04x}:{:04x}",
110                    self.descriptor.vendor_id,
111                    self.descriptor.product_id
112                ),
113            )
114            .field("class", &self.class())
115            .finish()
116    }
117}
118
119impl DeviceInfo {
120    async fn from_box(mut raw: Box<dyn usb_if::host::DeviceInfo>) -> Result<Self, USBError> {
121        let desc = raw.descriptor().await?;
122        let mut configurations = Vec::with_capacity(desc.num_configurations as usize);
123        for i in 0..desc.num_configurations {
124            let config_desc = raw.configuration_descriptor(i).await?;
125
126            configurations.push(config_desc);
127        }
128        Ok(DeviceInfo {
129            raw,
130            descriptor: desc,
131            configurations,
132        })
133    }
134
135    pub async fn open(&mut self) -> Result<Device, USBError> {
136        let device = self.raw.open().await?;
137        Device::new(device, self.descriptor.clone()).await
138    }
139
140    pub fn class(&self) -> Class {
141        self.descriptor.class()
142    }
143
144    pub fn vendor_id(&self) -> u16 {
145        self.descriptor.vendor_id
146    }
147
148    pub fn product_id(&self) -> u16 {
149        self.descriptor.product_id
150    }
151
152    pub fn interface_descriptors(&self) -> Vec<usb_if::descriptor::InterfaceDescriptor> {
153        let mut interfaces = BTreeMap::new();
154        for config in &self.configurations {
155            for iface in &config.interfaces {
156                interfaces.insert(iface.interface_number, iface.first_alt_setting());
157            }
158        }
159        interfaces.values().cloned().collect()
160    }
161}
162
163pub struct Interface {
164    pub descriptor: usb_if::descriptor::InterfaceDescriptor,
165    raw: Box<dyn usb_if::host::Interface>,
166}
167
168impl Display for Interface {
169    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
170        f.debug_struct("Interface")
171            .field("string", self.descriptor.string.as_ref().unwrap())
172            .field("class", &self.class())
173            .finish()
174    }
175}
176
177impl Interface {
178    pub fn set_alt_setting(&mut self, alt_setting: u8) -> Result<(), USBError> {
179        self.raw.set_alt_setting(alt_setting)
180    }
181
182    pub fn class(&self) -> Class {
183        self.descriptor.class()
184    }
185
186    pub fn control_in<'a>(
187        &mut self,
188        setup: usb_if::host::ControlSetup,
189        data: &'a mut [u8],
190    ) -> ResultTransfer<'a> {
191        self.raw.control_in(setup, data)
192    }
193
194    pub async fn control_out<'a>(
195        &mut self,
196        setup: usb_if::host::ControlSetup,
197        data: &'a [u8],
198    ) -> usb_if::host::ResultTransfer<'a> {
199        self.raw.control_out(setup, data)
200    }
201
202    pub fn endpoint_bulk_in(&mut self, endpoint: u8) -> Result<EndpointBulkIn, USBError> {
203        let descriptor = self.find_ep_desc(endpoint)?.clone();
204        self.raw
205            .endpoint_bulk_in(endpoint)
206            .map(|raw| EndpointBulkIn { descriptor, raw })
207    }
208
209    pub fn endpoint_bulk_out(&mut self, endpoint: u8) -> Result<EndpointBulkOut, USBError> {
210        let descriptor = self.find_ep_desc(endpoint)?.clone();
211        self.raw
212            .endpoint_bulk_out(endpoint)
213            .map(|raw| EndpointBulkOut { descriptor, raw })
214    }
215
216    pub fn endpoint_interrupt_in(&mut self, endpoint: u8) -> Result<EndpointInterruptIn, USBError> {
217        let descriptor = self.find_ep_desc(endpoint)?.clone();
218        self.raw
219            .endpoint_interrupt_in(endpoint)
220            .map(|raw| EndpointInterruptIn { descriptor, raw })
221    }
222
223    pub fn endpoint_interrupt_out(
224        &mut self,
225        endpoint: u8,
226    ) -> Result<EndpointInterruptOut, USBError> {
227        let descriptor = self.find_ep_desc(endpoint)?.clone();
228        self.raw
229            .endpoint_interrupt_out(endpoint)
230            .map(|raw| EndpointInterruptOut { descriptor, raw })
231    }
232
233    pub fn endpoint_iso_in(&mut self, endpoint: u8) -> Result<EndpointIsoIn, USBError> {
234        let descriptor = self.find_ep_desc(endpoint)?.clone();
235        self.raw
236            .endpoint_iso_in(endpoint)
237            .map(|raw| EndpointIsoIn { descriptor, raw })
238    }
239
240    pub fn endpoint_iso_out(&mut self, endpoint: u8) -> Result<EndpointIsoOut, USBError> {
241        let descriptor = self.find_ep_desc(endpoint)?.clone();
242        self.raw
243            .endpoint_iso_out(endpoint)
244            .map(|raw| EndpointIsoOut { descriptor, raw })
245    }
246
247    fn find_ep_desc(&self, address: u8) -> Result<&EndpointDescriptor, USBError> {
248        self.descriptor
249            .endpoints
250            .iter()
251            .find(|ep| ep.address == address)
252            .ok_or(USBError::NotFound)
253    }
254}
255
256pub struct EndpointBulkIn {
257    pub descriptor: EndpointDescriptor,
258    raw: Box<dyn usb_if::host::EndpointBulkIn>,
259}
260
261impl EndpointBulkIn {
262    pub fn submit<'a>(&mut self, data: &'a mut [u8]) -> ResultTransfer<'a> {
263        self.raw.submit(data)
264    }
265}
266
267pub struct EndpointBulkOut {
268    pub descriptor: EndpointDescriptor,
269    raw: Box<dyn usb_if::host::EndpointBulkOut>,
270}
271
272impl EndpointBulkOut {
273    pub fn submit<'a>(&mut self, data: &'a [u8]) -> ResultTransfer<'a> {
274        self.raw.submit(data)
275    }
276}
277
278pub struct EndpointInterruptIn {
279    pub descriptor: EndpointDescriptor,
280    raw: Box<dyn usb_if::host::EndpointInterruptIn>,
281}
282
283impl EndpointInterruptIn {
284    pub fn submit<'a>(&mut self, data: &'a mut [u8]) -> ResultTransfer<'a> {
285        self.raw.submit(data)
286    }
287}
288
289pub struct EndpointInterruptOut {
290    pub descriptor: EndpointDescriptor,
291    raw: Box<dyn usb_if::host::EndpointInterruptOut>,
292}
293impl EndpointInterruptOut {
294    pub fn submit<'a>(&mut self, data: &'a [u8]) -> ResultTransfer<'a> {
295        self.raw.submit(data)
296    }
297}
298
299pub struct EndpointIsoIn {
300    pub descriptor: EndpointDescriptor,
301    raw: Box<dyn usb_if::host::EndpintIsoIn>,
302}
303
304impl EndpointIsoIn {
305    pub fn submit<'a>(&mut self, data: &'a mut [u8], num_iso_packets: usize) -> ResultTransfer<'a> {
306        self.raw.submit(data, num_iso_packets)
307    }
308}
309
310pub struct EndpointIsoOut {
311    pub descriptor: EndpointDescriptor,
312    raw: Box<dyn usb_if::host::EndpintIsoOut>,
313}
314
315impl EndpointIsoOut {
316    pub fn submit<'a>(&mut self, data: &'a [u8], num_iso_packets: usize) -> ResultTransfer<'a> {
317        self.raw.submit(data, num_iso_packets)
318    }
319}