@@ -293,10 +293,12 @@ impl<T> UsbContext<T, UsbError> for UsbResult<T> {
293293
294294/// This structure represents an enumerated and configured device.
295295#[ derive( Clone , Debug ) ]
296+ // Temporary until we have a more complete stack that uses this field.
297+ #[ allow( dead_code) ]
296298struct DeviceInfo {
297- // Temporary until we have a more complete stack that uses this field.
298- #[ allow( dead_code) ]
299299 dev_desc : Vec < u8 > ,
300+ address : u8 ,
301+ configurations : Vec < Vec < u8 > > ,
300302}
301303
302304struct ControlIn {
@@ -344,20 +346,27 @@ impl QemuHostThread {
344346 const USB_FS_SAFE_PACKET_SIZE : u16 = 8 ;
345347
346348 // Some standard request types.
349+ const USB_REQ_TYPE_OUT : u8 = 0 ;
347350 const USB_REQ_TYPE_IN : u8 = 0x80 ;
348351 const USB_REQ_TYPE_STANDARD : u8 = 0 ;
349352 const USB_REQ_TYPE_DEVICE : u8 = 0 ;
350353
351354 // Some standard USB requests.
355+ const USB_SET_ADDRESS : u8 = 5 ;
352356 const USB_GET_DESCRIPTOR : u8 = 6 ;
357+ const USB_SET_CONFIGURATION : u8 = 9 ;
353358
354359 // Some standard descriptor types.
355360 const USB_DEVICE_DESCRIPTOR : u8 = 1 ;
356- const USB_DEVICE_DESCRIPTOR_LENGTH : usize = 18 ;
361+ const USB_CONFIG_DESCRIPTOR : u8 = 2 ;
357362
358363 // Location of the bMaxPacketSize field in the device descriptor.
359364 const USB_DEV_DESC_MAX_PACKET_SIZE_OFFSET : usize = 7 ;
360365
366+ // How much time to wait after a SET_ADDRESS before moving on
367+ // to the rest of the enumeration sequence.
368+ const SET_ADDRESS_WAIT_DELAY_MS : u64 = 10 ;
369+
361370 fn new (
362371 usbdev : TTYPort ,
363372 channel_send : mpsc:: Sender < HostChannelEvent > ,
@@ -752,31 +761,125 @@ impl QemuHostThread {
752761 req : Self :: USB_GET_DESCRIPTOR ,
753762 value : ( Self :: USB_DEVICE_DESCRIPTOR as u16 ) << 8 ,
754763 index : 0 ,
755- length : Self :: USB_FS_SAFE_PACKET_SIZE . into ( ) , // length
764+ length : Self :: USB_FS_SAFE_PACKET_SIZE . into ( ) ,
756765 max_pkt_size : Self :: USB_FS_SAFE_PACKET_SIZE ,
757766 } )
758767 . maybe_context ( "Failed to send GET_DESC(device, 8 bytes)" ) ?;
759768 let max_packet_size = trunc_dev_desc[ Self :: USB_DEV_DESC_MAX_PACKET_SIZE_OFFSET ] as u16 ;
760769 log:: info!( "USB Host: device report a maximum packet size of {max_packet_size} on EP0" ) ;
761770 // TODO sanity check max packet size
762771
772+ // Assign an address to the device.
773+ // TODO randomize address or assign them by increasing numbers?
774+ let address = 42 ; // Arbitrary number.
775+ self . send_and_wait_control_out ( & ControlOut {
776+ addr : 0 ,
777+ ep : 0 ,
778+ req_type : Self :: USB_REQ_TYPE_OUT
779+ | Self :: USB_REQ_TYPE_STANDARD
780+ | Self :: USB_REQ_TYPE_DEVICE ,
781+ req : Self :: USB_SET_ADDRESS ,
782+ value : address as u16 ,
783+ index : 0 ,
784+ max_pkt_size : max_packet_size,
785+ data : & [ ] ,
786+ } )
787+ . maybe_context ( "Failed to send SET_ADDRESS" ) ?;
788+ log:: info!( "USB Host: device accepted address {address:?}" ) ;
789+
790+ // Give time to the device to update its address.
791+ std:: thread:: sleep ( Duration :: from_millis ( Self :: SET_ADDRESS_WAIT_DELAY_MS ) ) ;
792+
763793 // Retrieve the full device descriptor.
764794 let dev_desc = self
765795 . send_and_wait_control_in ( & ControlIn {
766- addr : 0 ,
796+ addr : address ,
767797 ep : 0 ,
768798 req_type : Self :: USB_REQ_TYPE_IN
769799 | Self :: USB_REQ_TYPE_STANDARD
770800 | Self :: USB_REQ_TYPE_DEVICE ,
771801 req : Self :: USB_GET_DESCRIPTOR ,
772802 value : ( Self :: USB_DEVICE_DESCRIPTOR as u16 ) << 8 ,
773803 index : 0 ,
774- length : Self :: USB_DEVICE_DESCRIPTOR_LENGTH ,
804+ length : size_of :: < desc :: DeviceDescriptor > ( ) ,
775805 max_pkt_size : max_packet_size,
776806 } )
777807 . maybe_context ( "Failed to send GET_DESC(device, all bytes)" ) ?;
808+ // Extract number of configurations.
809+ let num_config = desc:: DeviceDescriptor :: ref_from_bytes ( & dev_desc)
810+ . map_err ( |_err| anyhow ! ( "Cannot parse device descriptor" ) ) ?
811+ . num_config ;
812+
813+ // Retrieve all configurations descriptors.
814+ let mut configurations = Vec :: new ( ) ;
815+ let mut first_config_val = None ;
816+ for config_idx in 0 ..num_config {
817+ // Retrieve just the configuration descriptor first.
818+ let config_desc = self
819+ . send_and_wait_control_in ( & ControlIn {
820+ addr : address,
821+ ep : 0 ,
822+ req_type : Self :: USB_REQ_TYPE_IN
823+ | Self :: USB_REQ_TYPE_STANDARD
824+ | Self :: USB_REQ_TYPE_DEVICE ,
825+ req : Self :: USB_GET_DESCRIPTOR ,
826+ value : ( Self :: USB_CONFIG_DESCRIPTOR as u16 ) << 8 | config_idx as u16 ,
827+ index : 0 ,
828+ length : size_of :: < desc:: ConfigurationDescriptor > ( ) ,
829+ max_pkt_size : max_packet_size,
830+ } )
831+ . maybe_context ( "Failed to send GET_DESC(config desc)" ) ?;
832+ // Parse and extract the size of the full configuration.
833+ let parsed_desc = desc:: ConfigurationDescriptor :: ref_from_bytes ( & config_desc)
834+ . map_err ( |_err| anyhow ! ( "Cannot parse config descriptor" ) ) ?;
835+ let tot_len = parsed_desc. tot_length ;
836+ // Remember the configuration value for later.
837+ if first_config_val. is_none ( ) {
838+ first_config_val = Some ( parsed_desc. config_val ) ;
839+ }
840+ // Retrieve full configuration.
841+ let full_config = self
842+ . send_and_wait_control_in ( & ControlIn {
843+ addr : address,
844+ ep : 0 ,
845+ req_type : Self :: USB_REQ_TYPE_IN
846+ | Self :: USB_REQ_TYPE_STANDARD
847+ | Self :: USB_REQ_TYPE_DEVICE ,
848+ req : Self :: USB_GET_DESCRIPTOR ,
849+ value : ( Self :: USB_CONFIG_DESCRIPTOR as u16 ) << 8 | config_idx as u16 ,
850+ index : 0 ,
851+ length : tot_len. into ( ) ,
852+ max_pkt_size : max_packet_size,
853+ } )
854+ . maybe_context ( "Failed to send GET_DESC(full config)" ) ?;
855+ configurations. push ( full_config) ;
856+ }
778857
779- Ok ( DeviceInfo { dev_desc } )
858+ // Set the first available configuration.
859+ if let Some ( first_config_val) = first_config_val {
860+ self . send_and_wait_control_out ( & ControlOut {
861+ addr : address,
862+ ep : 0 ,
863+ req_type : Self :: USB_REQ_TYPE_OUT
864+ | Self :: USB_REQ_TYPE_STANDARD
865+ | Self :: USB_REQ_TYPE_DEVICE ,
866+ req : Self :: USB_SET_CONFIGURATION ,
867+ value : first_config_val as u16 ,
868+ index : 0 ,
869+ max_pkt_size : max_packet_size,
870+ data : & [ ] ,
871+ } )
872+ . maybe_context ( "Failed to send SET_CONFIGURATION" ) ?;
873+ } else {
874+ log:: error!( "USB host: device has no configurations" )
875+ }
876+ log:: info!( "USB Host: device configured" ) ;
877+
878+ Ok ( DeviceInfo {
879+ dev_desc,
880+ address,
881+ configurations,
882+ } )
780883 }
781884
782885 /// This thread simulates a USB host. It can react to events sent by otlib
@@ -834,7 +937,10 @@ impl QemuHostThread {
834937 log:: info!( "USB Host: device disconnected" ) ;
835938 continue ;
836939 }
837- Err ( err) => return Err ( err) . maybe_context ( "Failed to enumerate device" ) ,
940+ Err ( err) => {
941+ log:: error!( "USB host: failed to enumerate device: {err:?}" ) ;
942+ continue ;
943+ }
838944 Ok ( dev_info) => dev_info,
839945 } ;
840946 log:: info!( "USB Host: device configured: {dev_info:?}" ) ;
0 commit comments