@@ -2,7 +2,10 @@ use core::{mem::MaybeUninit, num::NonZero};
22
33use futures:: FutureExt ;
44use 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
710pub 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
128189impl 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 ] ;
0 commit comments