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 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}