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