@@ -35,8 +35,6 @@ pub struct CredentialService {
3535 usb_state : AsyncArc < AsyncMutex < UsbState > > ,
3636 usb_uv_handler : UsbUvHandler ,
3737
38- internal_hid_devices : Vec < HidDevice > ,
39- chosen_hid_device : Option < HidDevice > ,
4038 internal_device_credentials : Vec < CredentialMetadata > ,
4139 internal_device_state : InternalDeviceState ,
4240 internal_pin_attempts_left : u32 ,
@@ -83,15 +81,13 @@ impl CredentialService {
8381 usb_state : usb_state. clone ( ) ,
8482 usb_uv_handler : UsbUvHandler :: new ( ) ,
8583
86- internal_hid_devices : Vec :: new ( ) ,
8784 internal_device_credentials,
8885 internal_device_state : InternalDeviceState :: Idle ,
8986 internal_pin_attempts_left : 5 ,
9087 internal_pin_unlock_time : None ,
9188
9289 cred_request,
9390 cred_response,
94- chosen_hid_device : None ,
9591 }
9692 }
9793
@@ -101,28 +97,25 @@ impl CredentialService {
10197
10298 pub ( crate ) async fn poll_device_discovery_usb ( & mut self ) -> Result < UsbState , String > {
10399 debug ! ( "polling for USB status" ) ;
104- let prev_usb_state = * self . usb_state . lock ( ) . await ;
100+ let prev_usb_state = self . usb_state . lock ( ) . await . clone ( ) ;
105101 let next_usb_state = match prev_usb_state {
106102 UsbState :: Idle | UsbState :: Waiting => {
107- self . internal_hid_devices =
108- libwebauthn:: transport:: hid:: list_devices ( ) . await . unwrap ( ) ;
109- if self . internal_hid_devices . is_empty ( ) {
103+ let mut hid_devices = libwebauthn:: transport:: hid:: list_devices ( ) . await . unwrap ( ) ;
104+ if hid_devices. is_empty ( ) {
110105 let state = UsbState :: Waiting ;
111- * self . usb_state . lock ( ) . await = state;
106+ * self . usb_state . lock ( ) . await = state. clone ( ) ;
112107 return Ok ( state) ;
113- } else if self . internal_hid_devices . len ( ) == 1 {
114- self . chosen_hid_device = Some ( self . internal_hid_devices . swap_remove ( 0 ) ) ;
115- Ok ( UsbState :: Connected )
108+ } else if hid_devices. len ( ) == 1 {
109+ Ok ( UsbState :: Connected ( hid_devices. swap_remove ( 0 ) ) )
116110 } else {
117- Ok ( UsbState :: SelectingDevice )
111+ Ok ( UsbState :: SelectingDevice ( hid_devices ) )
118112 }
119113 }
120- UsbState :: SelectingDevice => {
121- let ( blinking_tx, mut blinking_rx) = tokio:: sync:: mpsc:: channel :: < Option < HidDevice > > (
122- self . internal_hid_devices . len ( ) ,
123- ) ;
124- let mut expected_answers = self . internal_hid_devices . len ( ) ;
125- for mut device in self . internal_hid_devices . drain ( ..) {
114+ UsbState :: SelectingDevice ( hid_devices) => {
115+ let ( blinking_tx, mut blinking_rx) =
116+ tokio:: sync:: mpsc:: channel :: < Option < HidDevice > > ( hid_devices. len ( ) ) ;
117+ let mut expected_answers = hid_devices. len ( ) ;
118+ for mut device in hid_devices {
126119 let tx = blinking_tx. clone ( ) ;
127120 tokio ( ) . spawn ( async move {
128121 let ( mut channel, _state_rx) = device. channel ( ) . await . unwrap ( ) ;
@@ -145,8 +138,7 @@ impl CredentialService {
145138 expected_answers -= 1 ;
146139 match msg {
147140 Some ( device) => {
148- self . chosen_hid_device = Some ( device) ;
149- state = UsbState :: Connected ;
141+ state = UsbState :: Connected ( device) ;
150142 break ;
151143 }
152144 None => {
@@ -160,13 +152,11 @@ impl CredentialService {
160152 }
161153 Ok ( state)
162154 }
163- UsbState :: Connected => {
155+ UsbState :: Connected ( mut device ) => {
164156 let handler = self . usb_uv_handler . clone ( ) ;
165157 let cred_request = self . cred_request . clone ( ) ;
166158 let signal_tx = self . usb_uv_handler . signal_tx . clone ( ) ;
167159 let pin_rx = self . usb_uv_handler . pin_rx . clone ( ) ;
168- let mut device = self . chosen_hid_device . take ( ) . unwrap ( ) ;
169- self . internal_hid_devices . clear ( ) ;
170160 tokio ( ) . spawn ( async move {
171161 let ( mut channel, state_rx) = device. channel ( ) . await . unwrap ( ) ;
172162 tokio ( ) . spawn ( async move {
@@ -447,7 +437,7 @@ impl CredentialService {
447437 }
448438}
449439
450- #[ derive( Copy , Clone , Debug , Default , PartialEq ) ]
440+ #[ derive( Clone , Debug , Default ) ]
451441pub enum UsbState {
452442 /// Not polling for FIDO USB device.
453443 #[ default]
@@ -457,7 +447,7 @@ pub enum UsbState {
457447 Waiting ,
458448
459449 /// USB device connected, prompt user to tap
460- Connected ,
450+ Connected ( HidDevice ) ,
461451
462452 /// The device needs the PIN to be entered.
463453 NeedsPin {
@@ -480,7 +470,7 @@ pub enum UsbState {
480470
481471 // When we encounter multiple devices, we let all of them blink and continue
482472 // with the one that was tapped.
483- SelectingDevice ,
473+ SelectingDevice ( Vec < HidDevice > ) ,
484474}
485475
486476#[ derive( Clone , Debug , Default , PartialEq ) ]
0 commit comments