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 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 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]; 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 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 class(&self) -> Class {
383 self.descriptor.class()
384 }
385
386 pub fn control_in<'a>(
387 &mut self,
388 setup: usb_if::host::ControlSetup,
389 data: &'a mut [u8],
390 ) -> ResultTransfer<'a> {
391 self.raw.control_in(setup, data)
392 }
393
394 pub async fn control_out<'a>(
395 &mut self,
396 setup: usb_if::host::ControlSetup,
397 data: &'a [u8],
398 ) -> usb_if::host::ResultTransfer<'a> {
399 self.raw.control_out(setup, data)
400 }
401
402 pub fn endpoint_bulk_in(&mut self, endpoint: u8) -> Result<EndpointBulkIn, USBError> {
403 let descriptor = self.find_ep_desc(endpoint)?.clone();
404 self.raw
405 .endpoint_bulk_in(endpoint)
406 .map(|raw| EndpointBulkIn { descriptor, raw })
407 }
408
409 pub fn endpoint_bulk_out(&mut self, endpoint: u8) -> Result<EndpointBulkOut, USBError> {
410 let descriptor = self.find_ep_desc(endpoint)?.clone();
411 self.raw
412 .endpoint_bulk_out(endpoint)
413 .map(|raw| EndpointBulkOut { descriptor, raw })
414 }
415
416 pub fn endpoint_interrupt_in(&mut self, endpoint: u8) -> Result<EndpointInterruptIn, USBError> {
417 let descriptor = self.find_ep_desc(endpoint)?.clone();
418 self.raw
419 .endpoint_interrupt_in(endpoint)
420 .map(|raw| EndpointInterruptIn { descriptor, raw })
421 }
422
423 pub fn endpoint_interrupt_out(
424 &mut self,
425 endpoint: u8,
426 ) -> Result<EndpointInterruptOut, USBError> {
427 let descriptor = self.find_ep_desc(endpoint)?.clone();
428 self.raw
429 .endpoint_interrupt_out(endpoint)
430 .map(|raw| EndpointInterruptOut { descriptor, raw })
431 }
432
433 pub fn endpoint_iso_in(&mut self, endpoint: u8) -> Result<EndpointIsoIn, USBError> {
434 let descriptor = self.find_ep_desc(endpoint)?.clone();
435 self.raw
436 .endpoint_iso_in(endpoint)
437 .map(|raw| EndpointIsoIn { descriptor, raw })
438 }
439
440 pub fn endpoint_iso_out(&mut self, endpoint: u8) -> Result<EndpointIsoOut, USBError> {
441 let descriptor = self.find_ep_desc(endpoint)?.clone();
442 self.raw
443 .endpoint_iso_out(endpoint)
444 .map(|raw| EndpointIsoOut { descriptor, raw })
445 }
446
447 fn find_ep_desc(&self, address: u8) -> Result<&EndpointDescriptor, USBError> {
448 self.descriptor
449 .endpoints
450 .iter()
451 .find(|ep| ep.address == address)
452 .ok_or(USBError::NotFound)
453 }
454}
455
456pub struct EndpointBulkIn {
457 pub descriptor: EndpointDescriptor,
458 raw: Box<dyn usb_if::host::EndpointBulkIn>,
459}
460
461impl EndpointBulkIn {
462 pub fn submit<'a>(&mut self, data: &'a mut [u8]) -> ResultTransfer<'a> {
463 self.raw.submit(data)
464 }
465}
466
467pub struct EndpointBulkOut {
468 pub descriptor: EndpointDescriptor,
469 raw: Box<dyn usb_if::host::EndpointBulkOut>,
470}
471
472impl EndpointBulkOut {
473 pub fn submit<'a>(&mut self, data: &'a [u8]) -> ResultTransfer<'a> {
474 self.raw.submit(data)
475 }
476}
477
478pub struct EndpointInterruptIn {
479 pub descriptor: EndpointDescriptor,
480 raw: Box<dyn usb_if::host::EndpointInterruptIn>,
481}
482
483impl EndpointInterruptIn {
484 pub fn submit<'a>(&mut self, data: &'a mut [u8]) -> ResultTransfer<'a> {
485 self.raw.submit(data)
486 }
487}
488
489pub struct EndpointInterruptOut {
490 pub descriptor: EndpointDescriptor,
491 raw: Box<dyn usb_if::host::EndpointInterruptOut>,
492}
493impl EndpointInterruptOut {
494 pub fn submit<'a>(&mut self, data: &'a [u8]) -> ResultTransfer<'a> {
495 self.raw.submit(data)
496 }
497}
498
499pub struct EndpointIsoIn {
500 pub descriptor: EndpointDescriptor,
501 raw: Box<dyn usb_if::host::EndpintIsoIn>,
502}
503
504impl EndpointIsoIn {
505 pub fn submit<'a>(&mut self, data: &'a mut [u8], num_iso_packets: usize) -> ResultTransfer<'a> {
506 self.raw.submit(data, num_iso_packets)
507 }
508}
509
510pub struct EndpointIsoOut {
511 pub descriptor: EndpointDescriptor,
512 raw: Box<dyn usb_if::host::EndpintIsoOut>,
513}
514
515impl EndpointIsoOut {
516 pub fn submit<'a>(&mut self, data: &'a [u8], num_iso_packets: usize) -> ResultTransfer<'a> {
517 self.raw.submit(data, num_iso_packets)
518 }
519}