1+ use crate :: status_update:: send_status;
12use crate :: transport:: hid:: HIDDevice ;
3+ use crate :: StatusUpdate ;
24
35pub use crate :: transport:: platform:: device:: Device ;
46
@@ -43,7 +45,7 @@ pub struct DeviceSelector {
4345}
4446
4547impl DeviceSelector {
46- pub fn run ( ) -> Self {
48+ pub fn run ( status : Sender < crate :: StatusUpdate > ) -> Self {
4749 let ( selector_send, selector_rec) = channel ( ) ;
4850 // let new_device_callback = Arc::new(new_device_cb);
4951 let runloop = RunLoop :: new ( move |alive| {
@@ -75,6 +77,9 @@ impl DeviceSelector {
7577 break ; // We are done here. The selected device continues without us.
7678 }
7779 DeviceSelectorEvent :: DevicesAdded ( ids) => {
80+ if ids. is_empty ( ) && waiting_for_response. is_empty ( ) && tokens. is_empty ( ) {
81+ send_status ( & status, StatusUpdate :: NoDevicesFound ) ;
82+ }
7883 for id in ids {
7984 debug ! ( "Device added event: {:?}" , id) ;
8085 waiting_for_response. insert ( id) ;
@@ -97,9 +102,15 @@ impl DeviceSelector {
97102 tokens. retain ( |dev_id, _| dev_id != id) ;
98103 if tokens. is_empty ( ) {
99104 blinking = false ;
105+ if waiting_for_response. is_empty ( ) {
106+ send_status ( & status, StatusUpdate :: NoDevicesFound ) ;
107+ }
100108 continue ;
101109 }
102110 }
111+ if waiting_for_response. is_empty ( ) && tokens. is_empty ( ) {
112+ send_status ( & status, StatusUpdate :: NoDevicesFound ) ;
113+ }
103114 // We are already blinking, so no need to run the code below this match
104115 // that figures out if we should blink or not. In fact, currently, we do
105116 // NOT want to run this code again, because if you have 2 blinking tokens
@@ -113,6 +124,9 @@ impl DeviceSelector {
113124 DeviceSelectorEvent :: NotAToken ( ref id) => {
114125 debug ! ( "Device not a token event: {:?}" , id) ;
115126 waiting_for_response. remove ( id) ;
127+ if waiting_for_response. is_empty ( ) && tokens. is_empty ( ) {
128+ send_status ( & status, StatusUpdate :: NoDevicesFound ) ;
129+ }
116130 }
117131 DeviceSelectorEvent :: ImAToken ( ( id, tx) ) => {
118132 let _ = waiting_for_response. remove ( & id) ;
@@ -185,6 +199,7 @@ pub mod tests {
185199 transport:: FidoDevice ,
186200 u2ftypes:: U2FDeviceInfo ,
187201 } ;
202+ use std:: sync:: mpsc:: TryRecvError ;
188203
189204 pub ( crate ) fn gen_info ( id : String ) -> U2FDeviceInfo {
190205 U2FDeviceInfo {
@@ -268,9 +283,10 @@ pub mod tests {
268283 Device :: new( "device selector 4" ) . unwrap( ) ,
269284 ] ;
270285
286+ let ( tx, rx) = channel ( ) ;
271287 // Make those actual tokens. The rest is interpreted as non-u2f-devices
272288 make_device_with_pin ( & mut devices[ 2 ] ) ;
273- let selector = DeviceSelector :: run ( ) ;
289+ let selector = DeviceSelector :: run ( tx ) ;
274290
275291 // Adding all
276292 add_devices ( devices. iter ( ) , & selector) ;
@@ -279,6 +295,7 @@ pub mod tests {
279295 send_no_token ( d, & selector) ;
280296 }
281297 } ) ;
298+ assert_matches ! ( rx. try_recv( ) , Err ( TryRecvError :: Empty ) ) ;
282299
283300 send_i_am_token ( & devices[ 2 ] , & selector) ;
284301
@@ -293,18 +310,24 @@ pub mod tests {
293310 fn test_device_selector_stop ( ) {
294311 let device = Device :: new ( "device selector 1" ) . unwrap ( ) ;
295312
296- let mut selector = DeviceSelector :: run ( ) ;
313+ let ( tx, rx) = channel ( ) ;
314+ let mut selector = DeviceSelector :: run ( tx) ;
297315
298316 // Adding all
299317 selector
300318 . clone_sender ( )
301319 . send ( DeviceSelectorEvent :: DevicesAdded ( vec ! [ device. id( ) ] ) )
302320 . unwrap ( ) ;
321+ assert_matches ! ( rx. try_recv( ) , Err ( TryRecvError :: Empty ) ) ;
303322
304323 selector
305324 . clone_sender ( )
306325 . send ( DeviceSelectorEvent :: NotAToken ( device. id ( ) ) )
307326 . unwrap ( ) ;
327+ assert_matches ! (
328+ rx. recv_timeout( Duration :: from_millis( 500 ) ) ,
329+ Ok ( StatusUpdate :: NoDevicesFound )
330+ ) ;
308331 selector. stop ( ) ;
309332 }
310333
@@ -324,7 +347,8 @@ pub mod tests {
324347 make_device_with_pin ( & mut devices[ 4 ] ) ;
325348 make_device_with_pin ( & mut devices[ 5 ] ) ;
326349
327- let selector = DeviceSelector :: run ( ) ;
350+ let ( tx, rx) = channel ( ) ;
351+ let selector = DeviceSelector :: run ( tx) ;
328352
329353 // Adding all, except the last one (we simulate that this one is not yet plugged in)
330354 add_devices ( devices. iter ( ) . take ( 5 ) , & selector) ;
@@ -356,6 +380,7 @@ pub mod tests {
356380 devices[ 5 ] . receiver. as_ref( ) . unwrap( ) . recv( ) . unwrap( ) ,
357381 DeviceCommand :: Blink
358382 ) ;
383+ assert_matches ! ( rx. try_recv( ) , Err ( TryRecvError :: Empty ) ) ;
359384 }
360385
361386 #[ test]
@@ -376,7 +401,8 @@ pub mod tests {
376401 make_device_simple_u2f ( & mut devices[ 4 ] ) ;
377402 make_device_simple_u2f ( & mut devices[ 5 ] ) ;
378403
379- let selector = DeviceSelector :: run ( ) ;
404+ let ( tx, rx) = channel ( ) ;
405+ let selector = DeviceSelector :: run ( tx) ;
380406
381407 // Adding all, except the last one (we simulate that this one is not yet plugged in)
382408 add_devices ( devices. iter ( ) . take ( 5 ) , & selector) ;
@@ -418,6 +444,7 @@ pub mod tests {
418444 devices[ 6 ] . receiver. as_ref( ) . unwrap( ) . recv( ) . unwrap( ) ,
419445 DeviceCommand :: Blink
420446 ) ;
447+ assert_matches ! ( rx. try_recv( ) , Err ( TryRecvError :: Empty ) ) ;
421448 }
422449
423450 #[ test]
@@ -438,7 +465,8 @@ pub mod tests {
438465 make_device_with_pin ( & mut devices[ 4 ] ) ;
439466 make_device_with_pin ( & mut devices[ 5 ] ) ;
440467
441- let selector = DeviceSelector :: run ( ) ;
468+ let ( tx, rx) = channel ( ) ;
469+ let selector = DeviceSelector :: run ( tx) ;
442470
443471 // Adding all, except the last one (we simulate that this one is not yet plugged in)
444472 add_devices ( devices. iter ( ) , & selector) ;
@@ -457,11 +485,16 @@ pub mod tests {
457485 DeviceCommand :: Blink
458486 ) ;
459487 }
488+ assert_matches ! ( rx. try_recv( ) , Err ( TryRecvError :: Empty ) ) ;
460489
461490 // Remove all tokens
462491 for idx in [ 2 , 4 , 5 ] {
463492 remove_device ( & devices[ idx] , & selector) ;
464493 }
494+ assert_matches ! (
495+ rx. recv_timeout( Duration :: from_millis( 500 ) ) ,
496+ Ok ( StatusUpdate :: NoDevicesFound )
497+ ) ;
465498
466499 // Adding one again
467500 send_i_am_token ( & devices[ 4 ] , & selector) ;
@@ -472,4 +505,56 @@ pub mod tests {
472505 DeviceCommand :: Continue
473506 ) ;
474507 }
508+
509+ #[ test]
510+ fn test_device_selector_no_devices ( ) {
511+ let mut devices = vec ! [
512+ Device :: new( "device selector 1" ) . unwrap( ) ,
513+ Device :: new( "device selector 2" ) . unwrap( ) ,
514+ Device :: new( "device selector 3" ) . unwrap( ) ,
515+ Device :: new( "device selector 4" ) . unwrap( ) ,
516+ ] ;
517+
518+ let ( tx, rx) = channel ( ) ;
519+ // Make those actual tokens. The rest is interpreted as non-u2f-devices
520+ make_device_with_pin ( & mut devices[ 2 ] ) ;
521+ make_device_with_pin ( & mut devices[ 3 ] ) ;
522+ let selector = DeviceSelector :: run ( tx) ;
523+
524+ // Adding no devices first (none are plugged in when we start)
525+ add_devices ( std:: iter:: empty ( ) , & selector) ;
526+ assert_matches ! (
527+ rx. recv_timeout( Duration :: from_millis( 500 ) ) ,
528+ Ok ( StatusUpdate :: NoDevicesFound )
529+ ) ;
530+
531+ // Adding the devices
532+ add_devices ( devices. iter ( ) , & selector) ;
533+ devices. iter_mut ( ) . for_each ( |d| {
534+ if !d. is_u2f ( ) {
535+ send_no_token ( d, & selector) ;
536+ }
537+ } ) ;
538+ assert_matches ! ( rx. try_recv( ) , Err ( TryRecvError :: Empty ) ) ;
539+
540+ send_i_am_token ( & devices[ 2 ] , & selector) ;
541+ send_i_am_token ( & devices[ 3 ] , & selector) ;
542+
543+ assert_eq ! (
544+ devices[ 2 ] . receiver. as_ref( ) . unwrap( ) . recv( ) . unwrap( ) ,
545+ DeviceCommand :: Blink
546+ ) ;
547+ assert_eq ! (
548+ devices[ 3 ] . receiver. as_ref( ) . unwrap( ) . recv( ) . unwrap( ) ,
549+ DeviceCommand :: Blink
550+ ) ;
551+
552+ // Removing all blinking devices
553+ remove_device ( & devices[ 2 ] , & selector) ;
554+ remove_device ( & devices[ 3 ] , & selector) ;
555+ assert_matches ! (
556+ rx. recv_timeout( Duration :: from_millis( 500 ) ) ,
557+ Ok ( StatusUpdate :: NoDevicesFound )
558+ ) ;
559+ }
475560}
0 commit comments