Skip to content

Commit 7f1fa47

Browse files
committed
update
1 parent 0712236 commit 7f1fa47

13 files changed

Lines changed: 222 additions & 82 deletions

File tree

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#![cfg(test)]
22

3-
use crab_usb::USBHost;
3+
use crab_usb::{BaseClass, DeviceInfo, USBHost};
4+
use log::info;
45

56
#[tokio::test]
67
async fn test() {
@@ -10,13 +11,34 @@ async fn test() {
1011
.init();
1112

1213
let mut host = USBHost::new_libusb();
13-
let mut ls = host.device_list().await.unwrap();
14+
let ls = host.device_list().await.unwrap();
15+
16+
let mut info: Option<DeviceInfo> = None;
1417

1518
for device in ls {
1619
println!("Device: {:?}", device.descriptor().await.unwrap());
1720

1821
for iface in device.interface_descriptors() {
1922
println!(" Interface: {iface:?}",);
23+
24+
if iface.class == BaseClass::VIDEO {
25+
info = Some(device);
26+
break;
27+
}
2028
}
2129
}
30+
31+
let mut info = info.unwrap();
32+
33+
let mut device = info.open().await.unwrap();
34+
info!("Opened device: {device}");
35+
36+
let config = device.current_configuration_descriptor().await.unwrap();
37+
38+
for iface in &config.interfaces {
39+
let interface = device
40+
.claim_interface(iface.interface_number, 0)
41+
.await
42+
.unwrap();
43+
}
2244
}

usb-host/src/host/common/mod.rs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
use alloc::collections::BTreeMap;
12
use alloc::{boxed::Box, string::String, vec::Vec};
23
use core::{fmt::Display, ptr::NonNull};
3-
use std::collections::BTreeMap;
4+
use log::debug;
45

56
use usb_if::{
67
descriptor::{
@@ -37,7 +38,7 @@ impl USBHost {
3738
self.raw.init().await
3839
}
3940

40-
pub async fn device_list(&self) -> Result<impl Iterator<Item = DeviceInfo>, USBError> {
41+
pub async fn device_list(&mut self) -> Result<impl Iterator<Item = DeviceInfo>, USBError> {
4142
let devices = self.raw.device_list().await?;
4243
let mut device_infos = Vec::with_capacity(devices.len());
4344
for device in devices {
@@ -76,7 +77,6 @@ impl DeviceInfo {
7677

7778
pub async fn open(&mut self) -> Result<Device, USBError> {
7879
let mut device = self.raw.open().await?;
79-
device.set_configuration(1).await?; // Default to configuration 1
8080

8181
let manufacturer_string = match self.descriptor.manufacturer_string_index {
8282
Some(index) => device.string_descriptor(index.get(), 0).await?,
@@ -93,6 +93,14 @@ impl DeviceInfo {
9393
None => String::new(),
9494
};
9595

96+
let mut config_value = device.get_configuration().await?;
97+
if config_value == 0 {
98+
debug!("Setting configuration 1");
99+
device.set_configuration(1).await?; // Reset to configuration 0
100+
config_value = 1;
101+
}
102+
debug!("Current configuration: {config_value}");
103+
96104
Ok(Device {
97105
descriptor: self.descriptor.clone(),
98106
configurations: self.configurations.clone(),
@@ -183,6 +191,21 @@ impl Device {
183191
}
184192
Err(USBError::NotFound)
185193
}
194+
195+
pub async fn current_configuration_descriptor(
196+
&mut self,
197+
) -> Result<ConfigurationDescriptor, USBError> {
198+
let value = self.raw.get_configuration().await?;
199+
if value == 0 {
200+
return Err(USBError::NotFound);
201+
}
202+
for config in &self.configurations {
203+
if config.configuration_value == value {
204+
return Ok(config.clone());
205+
}
206+
}
207+
Err(USBError::NotFound)
208+
}
186209
}
187210

188211
pub struct Interface {

usb-host/src/host/libusb/device.rs

Lines changed: 107 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ use core::{mem::MaybeUninit, num::NonZero};
22

33
use futures::FutureExt;
44
use libusb1_sys::*;
5-
use usb_if::descriptor::{ConfigurationDescriptor, DeviceDescriptor, InterfaceDescriptor, InterfaceDescriptors};
5+
use log::debug;
6+
use usb_if::descriptor::{
7+
ConfigurationDescriptor, DeviceDescriptor, InterfaceDescriptor, InterfaceDescriptors,
8+
};
69

710
pub struct DeviceInfo {
811
pub(crate) raw: *mut libusb_device,
@@ -37,9 +40,10 @@ impl usb_if::host::DeviceInfo for DeviceInfo {
3740
Result<Box<dyn usb_if::host::Device>, usb_if::host::USBError>,
3841
> {
3942
async move {
43+
let desc = self.descriptor().await?;
44+
4045
let mut handle = std::ptr::null_mut();
4146
usb!(libusb_open(self.raw, &mut handle))?;
42-
let desc = self.descriptor().await?;
4347
let device = Device::new(handle, desc);
4448

4549
Ok(Box::new(device) as Box<dyn usb_if::host::Device>)
@@ -85,7 +89,72 @@ impl usb_if::host::DeviceInfo for DeviceInfo {
8589
let mut interfaces = Vec::with_capacity(interface_num);
8690

8791
for iface_num in 0..interface_num {
88-
92+
let iface_desc = unsafe { &*desc.interface.add(iface_num) };
93+
let alt_setting_num = iface_desc.num_altsetting as usize;
94+
let mut alt_settings = Vec::with_capacity(alt_setting_num);
95+
96+
for alt_idx in 0..alt_setting_num {
97+
let alt_desc = unsafe { &*iface_desc.altsetting.add(alt_idx) };
98+
let endpoint_num = alt_desc.bNumEndpoints as usize;
99+
let mut endpoints = Vec::with_capacity(endpoint_num);
100+
101+
for ep_idx in 0..endpoint_num {
102+
let ep_desc = unsafe { &*alt_desc.endpoint.add(ep_idx) };
103+
let direction = if ep_desc.bEndpointAddress & 0x80 != 0 {
104+
usb_if::transfer::Direction::In
105+
} else {
106+
usb_if::transfer::Direction::Out
107+
};
108+
109+
let transfer_type = match ep_desc.bmAttributes & 0x03 {
110+
0 => usb_if::descriptor::EndpointType::Control,
111+
1 => usb_if::descriptor::EndpointType::Isochronous,
112+
2 => usb_if::descriptor::EndpointType::Bulk,
113+
3 => usb_if::descriptor::EndpointType::Interrupt,
114+
_ => unreachable!(),
115+
};
116+
117+
let packets_per_microframe = match transfer_type {
118+
usb_if::descriptor::EndpointType::Isochronous
119+
| usb_if::descriptor::EndpointType::Interrupt => {
120+
(((ep_desc.wMaxPacketSize >> 11) & 0x03) + 1) as usize
121+
}
122+
_ => 1,
123+
};
124+
125+
endpoints.push(usb_if::descriptor::EndpointDescriptor {
126+
address: ep_desc.bEndpointAddress & 0x0F,
127+
max_packet_size: ep_desc.wMaxPacketSize & 0x7FF,
128+
transfer_type,
129+
direction,
130+
packets_per_microframe,
131+
interval: ep_desc.bInterval,
132+
});
133+
}
134+
135+
alt_settings.push(InterfaceDescriptor {
136+
interface_number: alt_desc.bInterfaceNumber,
137+
alternate_setting: alt_desc.bAlternateSetting,
138+
class: alt_desc.bInterfaceClass.into(),
139+
subclass: alt_desc.bInterfaceSubClass.into(),
140+
protocol: alt_desc.bInterfaceProtocol,
141+
string_index: NonZero::new(alt_desc.iInterface),
142+
string: None,
143+
num_endpoints: alt_desc.bNumEndpoints,
144+
endpoints,
145+
});
146+
}
147+
148+
interfaces.push(InterfaceDescriptors {
149+
interface_number: unsafe {
150+
if !iface_desc.altsetting.is_null() {
151+
(*iface_desc.altsetting).bInterfaceNumber
152+
} else {
153+
iface_num as u8
154+
}
155+
},
156+
alt_settings,
157+
});
89158
}
90159

91160
let out = ConfigurationDescriptor {
@@ -115,14 +184,6 @@ impl Device {
115184
pub(crate) fn new(raw: *mut libusb_device_handle, desc: DeviceDescriptor) -> Self {
116185
Self { raw, desc }
117186
}
118-
119-
pub fn raw(&self) -> *mut libusb_device_handle {
120-
self.raw
121-
}
122-
123-
pub fn descriptor(&self) -> &DeviceDescriptor {
124-
&self.desc
125-
}
126187
}
127188

128189
impl Drop for Device {
@@ -138,13 +199,22 @@ impl usb_if::host::Device for Device {
138199
&mut self,
139200
configuration: u8,
140201
) -> futures::future::LocalBoxFuture<'_, Result<(), usb_if::host::USBError>> {
141-
todo!()
202+
async move {
203+
usb!(libusb_set_configuration(self.raw, configuration as _))?;
204+
Ok(())
205+
}
206+
.boxed_local()
142207
}
143208

144209
fn get_configuration(
145210
&mut self,
146211
) -> futures::future::LocalBoxFuture<'_, Result<u8, usb_if::host::USBError>> {
147-
todo!()
212+
async move {
213+
let mut config = 0;
214+
usb!(libusb_get_configuration(self.raw, &mut config))?;
215+
Ok(config as _)
216+
}
217+
.boxed_local()
148218
}
149219

150220
fn claim_interface(
@@ -155,13 +225,35 @@ impl usb_if::host::Device for Device {
155225
'_,
156226
Result<Box<dyn usb_if::host::Interface>, usb_if::host::USBError>,
157227
> {
158-
todo!()
228+
async move {
229+
let res = usb!(libusb_kernel_driver_active(self.raw, interface as _))?;
230+
231+
if res == 1 {
232+
usb!(libusb_detach_kernel_driver(self.raw, interface as _))?;
233+
debug!("Kernel driver detached for interface {interface}");
234+
}
235+
236+
usb!(libusb_claim_interface(self.raw, interface as _))?;
237+
238+
debug!("Interface {interface} claimed successfully");
239+
if alternate != 0 {
240+
usb!(libusb_set_interface_alt_setting(
241+
self.raw,
242+
interface as _,
243+
alternate as _,
244+
))?;
245+
debug!("Interface {interface} set to alternate setting {alternate} successfully");
246+
}
247+
248+
todo!()
249+
}
250+
.boxed_local()
159251
}
160252

161253
fn string_descriptor(
162254
&mut self,
163255
index: u8,
164-
language_id: u16,
256+
_language_id: u16,
165257
) -> futures::future::LocalBoxFuture<'_, Result<String, usb_if::host::USBError>> {
166258
async move {
167259
let mut buf = vec![0u8; 256];

usb-host/src/host/libusb/endpoint.rs

Whitespace-only changes.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
use libusb1_sys::*;
2+
3+
pub struct InterfaceImpl {
4+
raw: *mut libusb_interface,
5+
}

usb-host/src/host/libusb/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ macro_rules! usb {
1515

1616
mod context;
1717
mod device;
18+
mod endpoint;
19+
mod interface;
1820

1921
#[macro_use]
2022
pub(crate) mod err;
@@ -59,3 +61,9 @@ impl Libusb {
5961
}
6062
}
6163
}
64+
65+
impl Default for Libusb {
66+
fn default() -> Self {
67+
Self::new()
68+
}
69+
}

usb-host/src/host/xhci/device.rs

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,12 @@ pub struct Device {
4343
}
4444

4545
pub struct DeviceInfo {
46-
device_desc: DeviceDescriptor,
4746
device: Option<Device>,
4847
}
4948

5049
impl DeviceInfo {
5150
pub(crate) fn new(device: Device) -> Self {
52-
let device_desc = device.desc.clone().unwrap();
5351
Self {
54-
device_desc,
5552
device: Some(device),
5653
}
5754
}
@@ -73,7 +70,7 @@ impl usb_if::host::DeviceInfo for DeviceInfo {
7370
fn descriptor(
7471
&self,
7572
) -> futures::future::LocalBoxFuture<'_, Result<DeviceDescriptor, USBError>> {
76-
async { Ok(self.device_desc.clone()) }.boxed_local()
73+
async { Ok(self.device.as_ref().unwrap().desc.clone().unwrap()) }.boxed_local()
7774
}
7875

7976
fn configuration_descriptor(
@@ -166,12 +163,6 @@ impl usb_if::host::Device for Device {
166163
.boxed_local()
167164
}
168165

169-
// fn configuration_descriptor(
170-
// &mut self,
171-
// ) -> futures::future::LocalBoxFuture<'_, Result<Vec<ConfigurationDescriptor>, USBError>> {
172-
// async { Ok(self.config_desc.to_vec()) }.boxed_local()
173-
// }
174-
175166
fn string_descriptor(
176167
&mut self,
177168
index: u8,
@@ -223,14 +214,13 @@ impl Device {
223214

224215
trace!("Max packet size: {max_packet_size}");
225216
self.set_ep_packet_size(Dci::CTRL, max_packet_size).await?;
226-
227-
// let desc = self.descriptor().await?;
228-
// for i in 0..desc.num_configurations {
229-
// let config = self.read_configuration_descriptor(i).await?;
230-
// let parsed_config = ConfigurationDescriptor::parse(&config)
231-
// .ok_or(USBError::Other("config descriptor parse err".into()))?;
232-
// self.config_desc.push(parsed_config);
233-
// }
217+
let desc = self.descriptor().await?;
218+
for i in 0..desc.num_configurations {
219+
let config = self.read_configuration_descriptor(i).await?;
220+
let parsed_config = ConfigurationDescriptor::parse(&config)
221+
.ok_or(USBError::Other("config descriptor parse err".into()))?;
222+
self.config_desc.push(parsed_config);
223+
}
234224

235225
Ok(())
236226
}

usb-host/src/host/xhci/root.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -491,10 +491,7 @@ impl RootHub {
491491
let ctx = root.dev_list.new_ctx(slot_id, is_64)?;
492492
let device = Device::new(slot_id, self, ctx, (port_idx + 1).into())?;
493493
device.ctrl_ep.listen(&mut root);
494-
// {
495-
// let ep = device.ctrl_ep.lock();
496-
// root.litsen_transfer(&ep.ring);
497-
// }
494+
498495
device
499496
};
500497

usb-host/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
extern crate alloc;
55

66
use core::time::Duration;
7+
pub use usb_if::descriptor::*;
8+
pub use usb_if::err::*;
9+
pub use usb_if::transfer::*;
710

811
#[macro_use]
912
mod _macros;
@@ -13,7 +16,6 @@ mod host;
1316

1417
pub use futures::future::BoxFuture;
1518
pub use host::*;
16-
use usb_if::transfer::wait;
1719

1820
pub trait Kernel {
1921
fn sleep<'a>(duration: Duration) -> BoxFuture<'a, ()>;

0 commit comments

Comments
 (0)