crab_usb/host/common/
mod.rs

1use alloc::collections::BTreeMap;
2use alloc::{boxed::Box, string::String, vec::Vec};
3use core::{fmt::Display, ptr::NonNull};
4use log::debug;
5use usb_if::descriptor::Class;
6
7use usb_if::{
8    descriptor::{
9        ConfigurationDescriptor, DeviceDescriptor, EndpointDescriptor, InterfaceDescriptor,
10    },
11    host::{Controller, ResultTransfer, USBError},
12};
13
14use crate::host::xhci::Xhci;
15
16pub struct USBHost {
17    raw: Box<dyn Controller>,
18}
19
20impl USBHost {
21    pub fn from_trait(raw: impl Controller) -> Self {
22        USBHost { raw: Box::new(raw) }
23    }
24
25    pub fn new_xhci(mmio_base: NonNull<u8>) -> Self {
26        let xhci = Xhci::new(mmio_base);
27        Self { raw: xhci }
28    }
29
30    #[cfg(feature = "libusb")]
31    pub fn new_libusb() -> Self {
32        let libusb = crate::host::libusb::Libusb::new();
33        Self {
34            raw: Box::new(libusb),
35        }
36    }
37
38    pub async fn init(&mut self) -> Result<(), USBError> {
39        self.raw.init().await
40    }
41
42    pub async fn device_list(&mut self) -> Result<impl Iterator<Item = DeviceInfo>, USBError> {
43        let devices = self.raw.device_list().await?;
44        let mut device_infos = Vec::with_capacity(devices.len());
45        for device in devices {
46            let device_info = DeviceInfo::from_box(device).await?;
47            device_infos.push(device_info);
48        }
49        Ok(device_infos.into_iter())
50    }
51
52    pub fn handle_event(&mut self) {
53        self.raw.handle_event();
54    }
55}
56
57pub struct DeviceInfo {
58    raw: Box<dyn usb_if::host::DeviceInfo>,
59    pub descriptor: DeviceDescriptor,
60    pub configurations: Vec<ConfigurationDescriptor>,
61}
62
63impl Display for DeviceInfo {
64    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
65        f.debug_struct("DeviceInfo")
66            .field(
67                "id",
68                &alloc::format!(
69                    "{:04x}:{:04x}",
70                    self.descriptor.vendor_id,
71                    self.descriptor.product_id
72                ),
73            )
74            .field("class", &self.class())
75            .finish()
76    }
77}
78
79impl DeviceInfo {
80    async fn from_box(mut raw: Box<dyn usb_if::host::DeviceInfo>) -> Result<Self, USBError> {
81        let desc = raw.descriptor().await?;
82        let mut configurations = Vec::with_capacity(desc.num_configurations as usize);
83        for i in 0..desc.num_configurations {
84            let config_desc = raw.configuration_descriptor(i).await?;
85
86            configurations.push(config_desc);
87        }
88        Ok(DeviceInfo {
89            raw,
90            descriptor: desc,
91            configurations,
92        })
93    }
94
95    pub async fn open(&mut self) -> Result<Device, USBError> {
96        let mut device = self.raw.open().await?;
97
98        let manufacturer_string = match self.descriptor.manufacturer_string_index {
99            Some(index) => device.string_descriptor(index.get(), 0).await?,
100            None => String::new(),
101        };
102
103        let product_string = match self.descriptor.product_string_index {
104            Some(index) => device.string_descriptor(index.get(), 0).await?,
105            None => String::new(),
106        };
107
108        let serial_number_string = match self.descriptor.serial_number_string_index {
109            Some(index) => device.string_descriptor(index.get(), 0).await?,
110            None => String::new(),
111        };
112
113        let mut config_value = device.get_configuration().await?;
114        if config_value == 0 {
115            debug!("Setting configuration 1");
116            device.set_configuration(1).await?; // Reset to configuration 0
117            config_value = 1;
118        }
119        debug!("Current configuration: {config_value}");
120
121        Ok(Device {
122            descriptor: self.descriptor.clone(),
123            configurations: self.configurations.clone(),
124            raw: device,
125            manufacturer_string,
126            product_string,
127            serial_number_string,
128        })
129    }
130
131    pub fn class(&self) -> Class {
132        self.descriptor.class()
133    }
134
135    pub fn vendor_id(&self) -> u16 {
136        self.descriptor.vendor_id
137    }
138
139    pub fn product_id(&self) -> u16 {
140        self.descriptor.product_id
141    }
142
143    pub fn interface_descriptors(&self) -> Vec<usb_if::descriptor::InterfaceDescriptor> {
144        let mut interfaces = BTreeMap::new();
145        for config in &self.configurations {
146            for iface in &config.interfaces {
147                interfaces.insert(iface.interface_number, iface.first_alt_setting());
148            }
149        }
150        interfaces.values().cloned().collect()
151    }
152}
153
154pub struct Device {
155    pub descriptor: usb_if::descriptor::DeviceDescriptor,
156    pub configurations: Vec<usb_if::descriptor::ConfigurationDescriptor>,
157    pub manufacturer_string: String,
158    pub product_string: String,
159    pub serial_number_string: String,
160    raw: Box<dyn usb_if::host::Device>,
161}
162
163impl Display for Device {
164    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
165        f.debug_struct("Device")
166            .field(
167                "id",
168                &alloc::format!(
169                    "{:04x}:{:04x}",
170                    self.descriptor.vendor_id,
171                    self.descriptor.product_id
172                ),
173            )
174            .field("class", &self.class())
175            .field("manufacturer_string", &self.manufacturer_string)
176            .field("product_string", &self.product_string)
177            .field("serial_number_string", &self.serial_number_string)
178            .finish()
179    }
180}
181
182impl Device {
183    pub async fn set_configuration(&mut self, configuration: u8) -> Result<(), USBError> {
184        self.raw.set_configuration(configuration).await
185    }
186
187    pub async fn get_configuration(&mut self) -> Result<u8, USBError> {
188        self.raw.get_configuration().await
189    }
190
191    pub async fn claim_interface(
192        &mut self,
193        interface: u8,
194        alternate: u8,
195    ) -> Result<Interface, USBError> {
196        let mut desc = self.find_interface_desc(interface, alternate)?;
197        desc.string = Some(match desc.string_index {
198            Some(index) => self.raw.string_descriptor(index.get(), 0).await?,
199            None => String::new(),
200        });
201        self.raw
202            .claim_interface(interface, alternate)
203            .await
204            .map(|raw| Interface {
205                descriptor: desc,
206                raw,
207            })
208    }
209
210    fn find_interface_desc(
211        &self,
212        interface: u8,
213        alternate: u8,
214    ) -> Result<InterfaceDescriptor, USBError> {
215        for config in &self.configurations {
216            for iface in &config.interfaces {
217                if iface.interface_number == interface {
218                    for alt in &iface.alt_settings {
219                        if alt.alternate_setting == alternate {
220                            return Ok(alt.clone());
221                        }
222                    }
223                }
224            }
225        }
226        Err(USBError::NotFound)
227    }
228
229    pub async fn current_configuration_descriptor(
230        &mut self,
231    ) -> Result<ConfigurationDescriptor, USBError> {
232        let value = self.raw.get_configuration().await?;
233        if value == 0 {
234            return Err(USBError::NotFound);
235        }
236        for config in &self.configurations {
237            if config.configuration_value == value {
238                return Ok(config.clone());
239            }
240        }
241        Err(USBError::NotFound)
242    }
243
244    pub fn class(&self) -> Class {
245        self.descriptor.class()
246    }
247
248    pub fn vendor_id(&self) -> u16 {
249        self.descriptor.vendor_id
250    }
251
252    pub fn product_id(&self) -> u16 {
253        self.descriptor.product_id
254    }
255}
256
257pub struct Interface {
258    pub descriptor: usb_if::descriptor::InterfaceDescriptor,
259    raw: Box<dyn usb_if::host::Interface>,
260}
261
262impl Display for Interface {
263    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
264        f.debug_struct("Interface")
265            .field("string", self.descriptor.string.as_ref().unwrap())
266            .finish()
267    }
268}
269
270impl Interface {
271    pub fn class(&self) -> Class {
272        self.descriptor.class()
273    }
274
275    pub fn control_in<'a>(
276        &mut self,
277        setup: usb_if::host::ControlSetup,
278        data: &'a mut [u8],
279    ) -> ResultTransfer<'a> {
280        self.raw.control_in(setup, data)
281    }
282
283    pub async fn control_out<'a>(
284        &mut self,
285        setup: usb_if::host::ControlSetup,
286        data: &'a [u8],
287    ) -> usb_if::host::ResultTransfer<'a> {
288        self.raw.control_out(setup, data)
289    }
290
291    pub fn endpoint_bulk_in(&mut self, endpoint: u8) -> Result<EndpointBulkIn, USBError> {
292        let descriptor = self.find_ep_desc(endpoint)?.clone();
293        self.raw
294            .endpoint_bulk_in(endpoint)
295            .map(|raw| EndpointBulkIn { descriptor, raw })
296    }
297
298    pub fn endpoint_bulk_out(&mut self, endpoint: u8) -> Result<EndpointBulkOut, USBError> {
299        let descriptor = self.find_ep_desc(endpoint)?.clone();
300        self.raw
301            .endpoint_bulk_out(endpoint)
302            .map(|raw| EndpointBulkOut { descriptor, raw })
303    }
304
305    pub fn endpoint_interrupt_in(&mut self, endpoint: u8) -> Result<EndpointInterruptIn, USBError> {
306        let descriptor = self.find_ep_desc(endpoint)?.clone();
307        self.raw
308            .endpoint_interrupt_in(endpoint)
309            .map(|raw| EndpointInterruptIn { descriptor, raw })
310    }
311
312    pub fn endpoint_interrupt_out(
313        &mut self,
314        endpoint: u8,
315    ) -> Result<EndpointInterruptOut, USBError> {
316        let descriptor = self.find_ep_desc(endpoint)?.clone();
317        self.raw
318            .endpoint_interrupt_out(endpoint)
319            .map(|raw| EndpointInterruptOut { descriptor, raw })
320    }
321
322    fn find_ep_desc(&self, address: u8) -> Result<&EndpointDescriptor, USBError> {
323        self.descriptor
324            .endpoints
325            .iter()
326            .find(|ep| ep.address == address)
327            .ok_or(USBError::NotFound)
328    }
329}
330
331pub struct EndpointBulkIn {
332    pub descriptor: EndpointDescriptor,
333    raw: Box<dyn usb_if::host::EndpointBulkIn>,
334}
335
336impl EndpointBulkIn {
337    pub fn submit<'a>(&mut self, data: &'a mut [u8]) -> ResultTransfer<'a> {
338        self.raw.submit(data)
339    }
340}
341
342pub struct EndpointBulkOut {
343    pub descriptor: EndpointDescriptor,
344    raw: Box<dyn usb_if::host::EndpointBulkOut>,
345}
346
347impl EndpointBulkOut {
348    pub fn submit<'a>(&mut self, data: &'a [u8]) -> ResultTransfer<'a> {
349        self.raw.submit(data)
350    }
351}
352
353pub struct EndpointInterruptIn {
354    pub descriptor: EndpointDescriptor,
355    raw: Box<dyn usb_if::host::EndpointInterruptIn>,
356}
357
358impl EndpointInterruptIn {
359    pub fn submit<'a>(&mut self, data: &'a mut [u8]) -> ResultTransfer<'a> {
360        self.raw.submit(data)
361    }
362}
363
364pub struct EndpointInterruptOut {
365    pub descriptor: EndpointDescriptor,
366    raw: Box<dyn usb_if::host::EndpointInterruptOut>,
367}
368impl EndpointInterruptOut {
369    pub fn submit<'a>(&mut self, data: &'a [u8]) -> ResultTransfer<'a> {
370        self.raw.submit(data)
371    }
372}