crab_usb/host/common/
mod.rs

1use alloc::{boxed::Box, collections::BTreeMap, string::String, sync::Arc, vec::Vec};
2use core::sync::atomic::AtomicBool;
3use core::{fmt::Display, ptr::NonNull};
4use log::{debug, trace};
5use usb_if::descriptor::{Class, DescriptorType, decode_string_descriptor};
6use usb_if::host::ControlSetup;
7use usb_if::transfer::{Recipient, Request, RequestType};
8
9use usb_if::{
10    descriptor::{
11        ConfigurationDescriptor, DeviceDescriptor, EndpointDescriptor, InterfaceDescriptor,
12    },
13    host::{Controller, ResultTransfer, USBError},
14};
15
16use crate::host::xhci::Xhci;
17
18pub struct EventHandler {
19    ptr: *mut USBHost,
20    running: Arc<AtomicBool>,
21}
22unsafe impl Send for EventHandler {}
23unsafe impl Sync for EventHandler {}
24
25impl EventHandler {
26    pub fn handle_event(&self) -> bool {
27        if !self.running.load(core::sync::atomic::Ordering::Acquire) {
28            return false;
29        }
30        unsafe {
31            (*self.ptr).handle_event();
32        }
33        true
34    }
35}
36
37pub struct USBHost {
38    raw: Box<dyn Controller>,
39    running: Arc<AtomicBool>,
40}
41
42impl USBHost {
43    pub fn from_trait(raw: impl Controller) -> Self {
44        USBHost {
45            raw: Box::new(raw),
46            running: Arc::new(AtomicBool::new(true)),
47        }
48    }
49
50    pub fn new_xhci(mmio_base: NonNull<u8>) -> Self {
51        let xhci = Xhci::new(mmio_base);
52        Self {
53            raw: xhci,
54            running: Arc::new(AtomicBool::new(true)),
55        }
56    }
57
58    #[cfg(feature = "libusb")]
59    pub fn new_libusb() -> Self {
60        let libusb = crate::host::libusb::Libusb::new();
61        Self {
62            raw: Box::new(libusb),
63            running: Arc::new(AtomicBool::new(true)),
64        }
65    }
66
67    pub async fn init(&mut self) -> Result<(), USBError> {
68        self.raw.init().await
69    }
70
71    pub async fn device_list(&mut self) -> Result<impl Iterator<Item = DeviceInfo>, USBError> {
72        let devices = self.raw.device_list().await?;
73        let mut device_infos = Vec::with_capacity(devices.len());
74        for device in devices {
75            let device_info = DeviceInfo::from_box(device).await?;
76            device_infos.push(device_info);
77        }
78        Ok(device_infos.into_iter())
79    }
80
81    fn handle_event(&mut self) {
82        self.raw.handle_event();
83    }
84
85    pub fn event_handler(&mut self) -> EventHandler {
86        EventHandler {
87            ptr: self as *mut USBHost,
88            running: self.running.clone(),
89        }
90    }
91}
92
93impl Drop for USBHost {
94    fn drop(&mut self) {
95        self.running
96            .store(false, core::sync::atomic::Ordering::Release);
97        trace!("USBHost is being dropped, stopping event handler");
98    }
99}
100
101pub struct DeviceInfo {
102    raw: Box<dyn usb_if::host::DeviceInfo>,
103    pub descriptor: DeviceDescriptor,
104    pub configurations: Vec<ConfigurationDescriptor>,
105}
106
107impl Display for DeviceInfo {
108    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
109        f.debug_struct("DeviceInfo")
110            .field(
111                "id",
112                &alloc::format!(
113                    "{:04x}:{:04x}",
114                    self.descriptor.vendor_id,
115                    self.descriptor.product_id
116                ),
117            )
118            .field("class", &self.class())
119            .finish()
120    }
121}
122
123impl DeviceInfo {
124    async fn from_box(mut raw: Box<dyn usb_if::host::DeviceInfo>) -> Result<Self, USBError> {
125        let desc = raw.descriptor().await?;
126        let mut configurations = Vec::with_capacity(desc.num_configurations as usize);
127        for i in 0..desc.num_configurations {
128            let config_desc = raw.configuration_descriptor(i).await?;
129
130            configurations.push(config_desc);
131        }
132        Ok(DeviceInfo {
133            raw,
134            descriptor: desc,
135            configurations,
136        })
137    }
138
139    pub async fn open(&mut self) -> Result<Device, USBError> {
140        let mut device = self.raw.open().await?;
141
142        let manufacturer_string = match self.descriptor.manufacturer_string_index {
143            Some(index) => device.string_descriptor(index.get(), 0).await?,
144            None => String::new(),
145        };
146
147        let product_string = match self.descriptor.product_string_index {
148            Some(index) => device.string_descriptor(index.get(), 0).await?,
149            None => String::new(),
150        };
151
152        let serial_number_string = match self.descriptor.serial_number_string_index {
153            Some(index) => device.string_descriptor(index.get(), 0).await?,
154            None => String::new(),
155        };
156
157        // let mut config_value = device.get_configuration().await?;
158        // if config_value == 0 {
159        //     debug!("Setting configuration 1");
160        //     device.set_configuration(1).await?; // Reset to configuration 0
161        //     config_value = 1;
162        // }
163        // debug!("Current configuration: {config_value}");
164        let mut device = Device {
165            descriptor: self.descriptor.clone(),
166            configurations: Vec::with_capacity(self.configurations.len()),
167            raw: device,
168            manufacturer_string,
169            product_string,
170            serial_number_string,
171        };
172        device.init_configs().await?;
173        Ok(device)
174    }
175
176    pub fn class(&self) -> Class {
177        self.descriptor.class()
178    }
179
180    pub fn vendor_id(&self) -> u16 {
181        self.descriptor.vendor_id
182    }
183
184    pub fn product_id(&self) -> u16 {
185        self.descriptor.product_id
186    }
187
188    pub fn interface_descriptors(&self) -> Vec<usb_if::descriptor::InterfaceDescriptor> {
189        let mut interfaces = BTreeMap::new();
190        for config in &self.configurations {
191            for iface in &config.interfaces {
192                interfaces.insert(iface.interface_number, iface.first_alt_setting());
193            }
194        }
195        interfaces.values().cloned().collect()
196    }
197}
198
199pub struct Device {
200    pub descriptor: usb_if::descriptor::DeviceDescriptor,
201    pub configurations: Vec<ConfigurationDescriptor>,
202    pub manufacturer_string: String,
203    pub product_string: String,
204    pub serial_number_string: String,
205    raw: Box<dyn usb_if::host::Device>,
206}
207
208impl Display for Device {
209    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
210        f.debug_struct("Device")
211            .field(
212                "id",
213                &alloc::format!(
214                    "{:04x}:{:04x}",
215                    self.descriptor.vendor_id,
216                    self.descriptor.product_id
217                ),
218            )
219            .field("class", &self.class())
220            .field("manufacturer_string", &self.manufacturer_string)
221            .field("product_string", &self.product_string)
222            .field("serial_number_string", &self.serial_number_string)
223            .finish()
224    }
225}
226
227impl Device {
228    pub async fn set_configuration(&mut self, configuration: u8) -> Result<(), USBError> {
229        self.raw.set_configuration(configuration).await
230    }
231
232    pub async fn get_configuration(&mut self) -> Result<u8, USBError> {
233        self.raw.get_configuration().await
234    }
235
236    pub async fn claim_interface(
237        &mut self,
238        interface: u8,
239        alternate: u8,
240    ) -> Result<Interface, USBError> {
241        let mut desc = self.find_interface_desc(interface, alternate)?;
242        desc.string = Some(match desc.string_index {
243            Some(index) => self.raw.string_descriptor(index.get(), 0).await?,
244            None => String::new(),
245        });
246        self.raw
247            .claim_interface(interface, alternate)
248            .await
249            .map(|raw| Interface {
250                descriptor: desc,
251                raw,
252            })
253    }
254
255    async fn init_configs(&mut self) -> Result<(), USBError> {
256        if self.configurations.is_empty() {
257            debug!("No configurations found, reading configuration descriptors");
258            for i in 0..self.descriptor.num_configurations {
259                let config_desc = self.read_configuration_descriptor(i).await?;
260                self.configurations.push(config_desc);
261            }
262        }
263        Ok(())
264    }
265
266    fn find_interface_desc(
267        &self,
268        interface: u8,
269        alternate: u8,
270    ) -> Result<InterfaceDescriptor, USBError> {
271        for config in &self.configurations {
272            for iface in &config.interfaces {
273                if iface.interface_number == interface {
274                    for alt in &iface.alt_settings {
275                        if alt.alternate_setting == alternate {
276                            return Ok(alt.clone());
277                        }
278                    }
279                }
280            }
281        }
282        Err(USBError::NotFound)
283    }
284
285    pub async fn current_configuration_descriptor(
286        &mut self,
287    ) -> Result<ConfigurationDescriptor, USBError> {
288        let value = self.raw.get_configuration().await?;
289        if value == 0 {
290            return Err(USBError::NotFound);
291        }
292        for config in &self.configurations {
293            if config.configuration_value == value {
294                return Ok(config.clone());
295            }
296        }
297        Err(USBError::NotFound)
298    }
299
300    pub fn class(&self) -> Class {
301        self.descriptor.class()
302    }
303
304    pub fn vendor_id(&self) -> u16 {
305        self.descriptor.vendor_id
306    }
307
308    pub fn product_id(&self) -> u16 {
309        self.descriptor.product_id
310    }
311
312    pub async fn string_descriptor(
313        &mut self,
314        index: u8,
315        language_id: u16,
316    ) -> Result<String, USBError> {
317        // self.raw.string_descriptor(index, language_id).await
318        let mut data = alloc::vec![0u8; 256];
319        self.get_descriptor(DescriptorType::STRING, index, language_id, &mut data)
320            .await?;
321        let res = decode_string_descriptor(&data).map_err(|e| USBError::Other(e.into()))?;
322        Ok(res)
323    }
324
325    async fn get_descriptor(
326        &mut self,
327        desc_type: DescriptorType,
328        desc_index: u8,
329        language_id: u16,
330        buff: &mut [u8],
331    ) -> Result<(), USBError> {
332        self.raw
333            .control_in(
334                ControlSetup {
335                    request_type: RequestType::Standard,
336                    recipient: Recipient::Device,
337                    request: Request::GetDescriptor,
338                    value: ((desc_type.0 as u16) << 8) | desc_index as u16,
339                    index: language_id,
340                },
341                buff,
342            )?
343            .await?;
344        Ok(())
345    }
346
347    async fn read_configuration_descriptor(
348        &mut self,
349        index: u8,
350    ) -> Result<ConfigurationDescriptor, USBError> {
351        let mut header = alloc::vec![0u8; ConfigurationDescriptor::LEN]; // 配置描述符头部固定为9字节
352        self.get_descriptor(DescriptorType::CONFIGURATION, index, 0, &mut header)
353            .await?;
354
355        let total_length = u16::from_le_bytes(header[2..4].try_into().unwrap()) as usize;
356        // 获取完整的配置描述符(包括接口和端点描述符)
357        let mut full_data = alloc::vec![0u8; total_length];
358        debug!("Reading configuration descriptor for index {index}, total length: {total_length}");
359        self.get_descriptor(DescriptorType::CONFIGURATION, index, 0, &mut full_data)
360            .await?;
361        let parsed_config = ConfigurationDescriptor::parse(&full_data)
362            .ok_or(USBError::Other("config descriptor parse err".into()))?;
363        Ok(parsed_config)
364    }
365}
366
367pub struct Interface {
368    pub descriptor: usb_if::descriptor::InterfaceDescriptor,
369    raw: Box<dyn usb_if::host::Interface>,
370}
371
372impl Display for Interface {
373    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
374        f.debug_struct("Interface")
375            .field("string", self.descriptor.string.as_ref().unwrap())
376            .field("class", &self.class())
377            .finish()
378    }
379}
380
381impl Interface {
382    pub fn set_alt_setting(&mut self, alt_setting: u8) -> Result<(), USBError> {
383        self.raw.set_alt_setting(alt_setting)
384    }
385
386    pub fn class(&self) -> Class {
387        self.descriptor.class()
388    }
389
390    pub fn control_in<'a>(
391        &mut self,
392        setup: usb_if::host::ControlSetup,
393        data: &'a mut [u8],
394    ) -> ResultTransfer<'a> {
395        self.raw.control_in(setup, data)
396    }
397
398    pub async fn control_out<'a>(
399        &mut self,
400        setup: usb_if::host::ControlSetup,
401        data: &'a [u8],
402    ) -> usb_if::host::ResultTransfer<'a> {
403        self.raw.control_out(setup, data)
404    }
405
406    pub fn endpoint_bulk_in(&mut self, endpoint: u8) -> Result<EndpointBulkIn, USBError> {
407        let descriptor = self.find_ep_desc(endpoint)?.clone();
408        self.raw
409            .endpoint_bulk_in(endpoint)
410            .map(|raw| EndpointBulkIn { descriptor, raw })
411    }
412
413    pub fn endpoint_bulk_out(&mut self, endpoint: u8) -> Result<EndpointBulkOut, USBError> {
414        let descriptor = self.find_ep_desc(endpoint)?.clone();
415        self.raw
416            .endpoint_bulk_out(endpoint)
417            .map(|raw| EndpointBulkOut { descriptor, raw })
418    }
419
420    pub fn endpoint_interrupt_in(&mut self, endpoint: u8) -> Result<EndpointInterruptIn, USBError> {
421        let descriptor = self.find_ep_desc(endpoint)?.clone();
422        self.raw
423            .endpoint_interrupt_in(endpoint)
424            .map(|raw| EndpointInterruptIn { descriptor, raw })
425    }
426
427    pub fn endpoint_interrupt_out(
428        &mut self,
429        endpoint: u8,
430    ) -> Result<EndpointInterruptOut, USBError> {
431        let descriptor = self.find_ep_desc(endpoint)?.clone();
432        self.raw
433            .endpoint_interrupt_out(endpoint)
434            .map(|raw| EndpointInterruptOut { descriptor, raw })
435    }
436
437    pub fn endpoint_iso_in(&mut self, endpoint: u8) -> Result<EndpointIsoIn, USBError> {
438        let descriptor = self.find_ep_desc(endpoint)?.clone();
439        self.raw
440            .endpoint_iso_in(endpoint)
441            .map(|raw| EndpointIsoIn { descriptor, raw })
442    }
443
444    pub fn endpoint_iso_out(&mut self, endpoint: u8) -> Result<EndpointIsoOut, USBError> {
445        let descriptor = self.find_ep_desc(endpoint)?.clone();
446        self.raw
447            .endpoint_iso_out(endpoint)
448            .map(|raw| EndpointIsoOut { descriptor, raw })
449    }
450
451    fn find_ep_desc(&self, address: u8) -> Result<&EndpointDescriptor, USBError> {
452        self.descriptor
453            .endpoints
454            .iter()
455            .find(|ep| ep.address == address)
456            .ok_or(USBError::NotFound)
457    }
458}
459
460pub struct EndpointBulkIn {
461    pub descriptor: EndpointDescriptor,
462    raw: Box<dyn usb_if::host::EndpointBulkIn>,
463}
464
465impl EndpointBulkIn {
466    pub fn submit<'a>(&mut self, data: &'a mut [u8]) -> ResultTransfer<'a> {
467        self.raw.submit(data)
468    }
469}
470
471pub struct EndpointBulkOut {
472    pub descriptor: EndpointDescriptor,
473    raw: Box<dyn usb_if::host::EndpointBulkOut>,
474}
475
476impl EndpointBulkOut {
477    pub fn submit<'a>(&mut self, data: &'a [u8]) -> ResultTransfer<'a> {
478        self.raw.submit(data)
479    }
480}
481
482pub struct EndpointInterruptIn {
483    pub descriptor: EndpointDescriptor,
484    raw: Box<dyn usb_if::host::EndpointInterruptIn>,
485}
486
487impl EndpointInterruptIn {
488    pub fn submit<'a>(&mut self, data: &'a mut [u8]) -> ResultTransfer<'a> {
489        self.raw.submit(data)
490    }
491}
492
493pub struct EndpointInterruptOut {
494    pub descriptor: EndpointDescriptor,
495    raw: Box<dyn usb_if::host::EndpointInterruptOut>,
496}
497impl EndpointInterruptOut {
498    pub fn submit<'a>(&mut self, data: &'a [u8]) -> ResultTransfer<'a> {
499        self.raw.submit(data)
500    }
501}
502
503pub struct EndpointIsoIn {
504    pub descriptor: EndpointDescriptor,
505    raw: Box<dyn usb_if::host::EndpintIsoIn>,
506}
507
508impl EndpointIsoIn {
509    pub fn submit<'a>(&mut self, data: &'a mut [u8], num_iso_packets: usize) -> ResultTransfer<'a> {
510        self.raw.submit(data, num_iso_packets)
511    }
512}
513
514pub struct EndpointIsoOut {
515    pub descriptor: EndpointDescriptor,
516    raw: Box<dyn usb_if::host::EndpintIsoOut>,
517}
518
519impl EndpointIsoOut {
520    pub fn submit<'a>(&mut self, data: &'a [u8], num_iso_packets: usize) -> ResultTransfer<'a> {
521        self.raw.submit(data, num_iso_packets)
522    }
523}