1
+ use crate :: status_update:: send_status;
1
2
use crate :: transport:: hid:: HIDDevice ;
3
+ use crate :: StatusUpdate ;
2
4
3
5
pub use crate :: transport:: platform:: device:: Device ;
4
6
@@ -45,7 +47,7 @@ pub struct DeviceSelector {
45
47
}
46
48
47
49
impl DeviceSelector {
48
- pub fn run ( ) -> Self {
50
+ pub fn run ( status : Sender < crate :: StatusUpdate > ) -> Self {
49
51
let ( selector_send, selector_rec) = channel ( ) ;
50
52
// let new_device_callback = Arc::new(new_device_cb);
51
53
let runloop = RunLoop :: new ( move |alive| {
@@ -77,6 +79,9 @@ impl DeviceSelector {
77
79
break ; // We are done here. The selected device continues without us.
78
80
}
79
81
DeviceSelectorEvent :: DevicesAdded ( ids) => {
82
+ if ids. is_empty ( ) && waiting_for_response. is_empty ( ) && tokens. is_empty ( ) {
83
+ send_status ( & status, StatusUpdate :: NoDevicesFound ) ;
84
+ }
80
85
for id in ids {
81
86
debug ! ( "Device added event: {:?}" , id) ;
82
87
waiting_for_response. insert ( id) ;
@@ -99,9 +104,15 @@ impl DeviceSelector {
99
104
tokens. retain ( |dev_id, _| dev_id != id) ;
100
105
if tokens. is_empty ( ) {
101
106
blinking = false ;
107
+ if waiting_for_response. is_empty ( ) {
108
+ send_status ( & status, StatusUpdate :: NoDevicesFound ) ;
109
+ }
102
110
continue ;
103
111
}
104
112
}
113
+ if waiting_for_response. is_empty ( ) && tokens. is_empty ( ) {
114
+ send_status ( & status, StatusUpdate :: NoDevicesFound ) ;
115
+ }
105
116
// We are already blinking, so no need to run the code below this match
106
117
// that figures out if we should blink or not. In fact, currently, we do
107
118
// NOT want to run this code again, because if you have 2 blinking tokens
@@ -115,6 +126,9 @@ impl DeviceSelector {
115
126
DeviceSelectorEvent :: NotAToken ( ref id) => {
116
127
debug ! ( "Device not a token event: {:?}" , id) ;
117
128
waiting_for_response. remove ( id) ;
129
+ if waiting_for_response. is_empty ( ) && tokens. is_empty ( ) {
130
+ send_status ( & status, StatusUpdate :: NoDevicesFound ) ;
131
+ }
118
132
}
119
133
DeviceSelectorEvent :: ImAToken ( ( id, tx) ) => {
120
134
let _ = waiting_for_response. remove ( & id) ;
@@ -187,6 +201,7 @@ pub mod tests {
187
201
transport:: FidoDevice ,
188
202
u2ftypes:: U2FDeviceInfo ,
189
203
} ;
204
+ use std:: sync:: mpsc:: TryRecvError ;
190
205
191
206
fn gen_info ( id : String ) -> U2FDeviceInfo {
192
207
U2FDeviceInfo {
@@ -267,9 +282,10 @@ pub mod tests {
267
282
Device :: new( "device selector 4" ) . unwrap( ) ,
268
283
] ;
269
284
285
+ let ( tx, rx) = channel ( ) ;
270
286
// Make those actual tokens. The rest is interpreted as non-u2f-devices
271
287
make_device_with_pin ( & mut devices[ 2 ] ) ;
272
- let selector = DeviceSelector :: run ( ) ;
288
+ let selector = DeviceSelector :: run ( tx ) ;
273
289
274
290
// Adding all
275
291
add_devices ( devices. iter ( ) , & selector) ;
@@ -278,6 +294,7 @@ pub mod tests {
278
294
send_no_token ( d, & selector) ;
279
295
}
280
296
} ) ;
297
+ assert_matches ! ( rx. try_recv( ) , Err ( TryRecvError :: Empty ) ) ;
281
298
282
299
send_i_am_token ( & devices[ 2 ] , & selector) ;
283
300
@@ -292,18 +309,24 @@ pub mod tests {
292
309
fn test_device_selector_stop ( ) {
293
310
let device = Device :: new ( "device selector 1" ) . unwrap ( ) ;
294
311
295
- let mut selector = DeviceSelector :: run ( ) ;
312
+ let ( tx, rx) = channel ( ) ;
313
+ let mut selector = DeviceSelector :: run ( tx) ;
296
314
297
315
// Adding all
298
316
selector
299
317
. clone_sender ( )
300
318
. send ( DeviceSelectorEvent :: DevicesAdded ( vec ! [ device. id( ) ] ) )
301
319
. unwrap ( ) ;
320
+ assert_matches ! ( rx. try_recv( ) , Err ( TryRecvError :: Empty ) ) ;
302
321
303
322
selector
304
323
. clone_sender ( )
305
324
. send ( DeviceSelectorEvent :: NotAToken ( device. id ( ) ) )
306
325
. unwrap ( ) ;
326
+ assert_matches ! (
327
+ rx. recv_timeout( Duration :: from_millis( 500 ) ) ,
328
+ Ok ( StatusUpdate :: NoDevicesFound )
329
+ ) ;
307
330
selector. stop ( ) ;
308
331
}
309
332
@@ -323,7 +346,8 @@ pub mod tests {
323
346
make_device_with_pin ( & mut devices[ 4 ] ) ;
324
347
make_device_with_pin ( & mut devices[ 5 ] ) ;
325
348
326
- let selector = DeviceSelector :: run ( ) ;
349
+ let ( tx, rx) = channel ( ) ;
350
+ let selector = DeviceSelector :: run ( tx) ;
327
351
328
352
// Adding all, except the last one (we simulate that this one is not yet plugged in)
329
353
add_devices ( devices. iter ( ) . take ( 5 ) , & selector) ;
@@ -355,6 +379,7 @@ pub mod tests {
355
379
devices[ 5 ] . receiver. as_ref( ) . unwrap( ) . recv( ) . unwrap( ) ,
356
380
DeviceCommand :: Blink
357
381
) ;
382
+ assert_matches ! ( rx. try_recv( ) , Err ( TryRecvError :: Empty ) ) ;
358
383
}
359
384
360
385
#[ test]
@@ -375,7 +400,8 @@ pub mod tests {
375
400
make_device_simple_u2f ( & mut devices[ 4 ] ) ;
376
401
make_device_simple_u2f ( & mut devices[ 5 ] ) ;
377
402
378
- let selector = DeviceSelector :: run ( ) ;
403
+ let ( tx, rx) = channel ( ) ;
404
+ let selector = DeviceSelector :: run ( tx) ;
379
405
380
406
// Adding all, except the last one (we simulate that this one is not yet plugged in)
381
407
add_devices ( devices. iter ( ) . take ( 5 ) , & selector) ;
@@ -417,6 +443,7 @@ pub mod tests {
417
443
devices[ 6 ] . receiver. as_ref( ) . unwrap( ) . recv( ) . unwrap( ) ,
418
444
DeviceCommand :: Blink
419
445
) ;
446
+ assert_matches ! ( rx. try_recv( ) , Err ( TryRecvError :: Empty ) ) ;
420
447
}
421
448
422
449
#[ test]
@@ -437,7 +464,8 @@ pub mod tests {
437
464
make_device_with_pin ( & mut devices[ 4 ] ) ;
438
465
make_device_with_pin ( & mut devices[ 5 ] ) ;
439
466
440
- let selector = DeviceSelector :: run ( ) ;
467
+ let ( tx, rx) = channel ( ) ;
468
+ let selector = DeviceSelector :: run ( tx) ;
441
469
442
470
// Adding all, except the last one (we simulate that this one is not yet plugged in)
443
471
add_devices ( devices. iter ( ) , & selector) ;
@@ -456,11 +484,16 @@ pub mod tests {
456
484
DeviceCommand :: Blink
457
485
) ;
458
486
}
487
+ assert_matches ! ( rx. try_recv( ) , Err ( TryRecvError :: Empty ) ) ;
459
488
460
489
// Remove all tokens
461
490
for idx in [ 2 , 4 , 5 ] {
462
491
remove_device ( & devices[ idx] , & selector) ;
463
492
}
493
+ assert_matches ! (
494
+ rx. recv_timeout( Duration :: from_millis( 500 ) ) ,
495
+ Ok ( StatusUpdate :: NoDevicesFound )
496
+ ) ;
464
497
465
498
// Adding one again
466
499
send_i_am_token ( & devices[ 4 ] , & selector) ;
@@ -471,4 +504,56 @@ pub mod tests {
471
504
DeviceCommand :: Continue
472
505
) ;
473
506
}
507
+
508
+ #[ test]
509
+ fn test_device_selector_no_devices ( ) {
510
+ let mut devices = vec ! [
511
+ Device :: new( "device selector 1" ) . unwrap( ) ,
512
+ Device :: new( "device selector 2" ) . unwrap( ) ,
513
+ Device :: new( "device selector 3" ) . unwrap( ) ,
514
+ Device :: new( "device selector 4" ) . unwrap( ) ,
515
+ ] ;
516
+
517
+ let ( tx, rx) = channel ( ) ;
518
+ // Make those actual tokens. The rest is interpreted as non-u2f-devices
519
+ make_device_with_pin ( & mut devices[ 2 ] ) ;
520
+ make_device_with_pin ( & mut devices[ 3 ] ) ;
521
+ let selector = DeviceSelector :: run ( tx) ;
522
+
523
+ // Adding no devices first (none are plugged in when we start)
524
+ add_devices ( std:: iter:: empty ( ) , & selector) ;
525
+ assert_matches ! (
526
+ rx. recv_timeout( Duration :: from_millis( 500 ) ) ,
527
+ Ok ( StatusUpdate :: NoDevicesFound )
528
+ ) ;
529
+
530
+ // Adding the devices
531
+ add_devices ( devices. iter ( ) , & selector) ;
532
+ devices. iter_mut ( ) . for_each ( |d| {
533
+ if !d. is_u2f ( ) {
534
+ send_no_token ( d, & selector) ;
535
+ }
536
+ } ) ;
537
+ assert_matches ! ( rx. try_recv( ) , Err ( TryRecvError :: Empty ) ) ;
538
+
539
+ send_i_am_token ( & devices[ 2 ] , & selector) ;
540
+ send_i_am_token ( & devices[ 3 ] , & selector) ;
541
+
542
+ assert_eq ! (
543
+ devices[ 2 ] . receiver. as_ref( ) . unwrap( ) . recv( ) . unwrap( ) ,
544
+ DeviceCommand :: Blink
545
+ ) ;
546
+ assert_eq ! (
547
+ devices[ 3 ] . receiver. as_ref( ) . unwrap( ) . recv( ) . unwrap( ) ,
548
+ DeviceCommand :: Blink
549
+ ) ;
550
+
551
+ // Removing all blinking devices
552
+ remove_device ( & devices[ 2 ] , & selector) ;
553
+ remove_device ( & devices[ 3 ] , & selector) ;
554
+ assert_matches ! (
555
+ rx. recv_timeout( Duration :: from_millis( 500 ) ) ,
556
+ Ok ( StatusUpdate :: NoDevicesFound )
557
+ ) ;
558
+ }
474
559
}
0 commit comments