@@ -61,7 +61,7 @@ fn check_boot_factory_reset<D, A, B, C>(
6161 fp. empty_template_library ( ) ;
6262 log:: info!( "Factory reset: fingerprint templates cleared" ) ;
6363 {
64- let mut guard = nvs . lock ( ) . expect ( "NVS mutex poisoned" ) ;
64+ let mut guard = config_store :: lock_nvs ( nvs ) ;
6565 for slot in 0u32 ..10 {
6666 let _ = guard. 0 . remove ( & format ! ( "slot_{slot}" ) ) ;
6767 let _ = guard. 0 . remove ( & format ! ( "label_{slot}" ) ) ;
@@ -74,6 +74,59 @@ fn check_boot_factory_reset<D, A, B, C>(
7474 }
7575}
7676
77+ /// Wake the screen if it is off, resetting the inactivity counter.
78+ ///
79+ /// Centralises the repeated "ensure screen is on" pattern used throughout the
80+ /// main event loop (button press, BLE event, fingerprint result, CLI request…).
81+ fn wake_screen_if_off < BL : OutputPin > (
82+ screen_on : & mut bool ,
83+ inactivity_ticks : & mut u32 ,
84+ backlight : & mut PinDriver < ' _ , BL , Output > ,
85+ fp : & mut fingerprint:: FingerprintSensor < ' _ > ,
86+ ) {
87+ * inactivity_ticks = 0 ;
88+ if !* screen_on {
89+ backlight. set_high ( ) . ok ( ) ;
90+ * screen_on = true ;
91+ fp. wake ( ) ;
92+ }
93+ }
94+
95+ /// Restore the main idle screen after any action that temporarily takes over the display.
96+ ///
97+ /// Shows the active-clients count, the pairing PIN, or the "Press B to pair" prompt
98+ /// depending on the current BLE state — the three branches are the same everywhere
99+ /// in the main loop so this helper eliminates 5× copies of the same code.
100+ fn restore_idle_screen < D > (
101+ disp : & mut D ,
102+ sb : & display:: StatusBar < ' _ > ,
103+ connected : u32 ,
104+ pairing_open : bool ,
105+ passkey : u32 ,
106+ ) where
107+ D : embedded_graphics:: draw_target:: DrawTarget < Color = embedded_graphics:: pixelcolor:: Rgb565 > ,
108+ {
109+ if connected > 0 {
110+ display:: show_status ( disp, sb, & format ! ( "ACTIVE CLIENTS: {}" , connected) ) ;
111+ } else if pairing_open {
112+ display:: show_pin ( disp, sb, passkey, connected) ;
113+ } else {
114+ display:: show_status ( disp, sb, "Press B to pair" ) ;
115+ }
116+ }
117+
118+ /// Generate a fresh random passkey, open a 60-second pairing window, and
119+ /// set `pairing_open` + `pairing_auto_close_at` accordingly.
120+ ///
121+ /// Returns the new passkey so the caller can pass it to `show_pin`.
122+ fn open_fresh_pairing_window ( pairing_open : & mut bool , pairing_auto_close_at : & mut u64 ) -> u32 {
123+ let passkey = unsafe { esp_idf_svc:: sys:: esp_random ( ) } % 1_000_000 ;
124+ ble_hid:: open_pairing_window ( passkey) ;
125+ * pairing_open = true ;
126+ * pairing_auto_close_at = unsafe { esp_idf_svc:: sys:: time ( std:: ptr:: null_mut ( ) ) } as u64 + 60 ;
127+ passkey
128+ }
129+
77130#[ allow( clippy:: too_many_arguments) ]
78131pub fn run < D , A , B , C , P , BL , F > (
79132 ble : & ble_hid:: BleHid ,
@@ -173,12 +226,12 @@ where
173226 if ble_hid:: PAIRING_ALLOWED . load ( Ordering :: Relaxed ) {
174227 display:: show_pin ( disp, & sb, passkey, connected) ;
175228 } else if connected > 0 {
176- display:: show_status_mini ( disp, & sb, & format ! ( "ACTIVE CLIENTS: {}" , connected) ) ;
229+ display:: show_status ( disp, & sb, & format ! ( "ACTIVE CLIENTS: {}" , connected) ) ;
177230 } else {
178231 display:: show_status ( disp, & sb, "Press B to pair" ) ;
179232 }
180233 } else if connected > 0 {
181- display:: show_status_mini ( disp, & sb, & format ! ( "ACTIVE CLIENTS: {}" , connected) ) ;
234+ display:: show_status ( disp, & sb, & format ! ( "ACTIVE CLIENTS: {}" , connected) ) ;
182235 } else {
183236 display:: show_status ( disp, & sb, "Press B to pair" ) ;
184237 }
@@ -194,35 +247,21 @@ where
194247 if connected == 0 {
195248 display:: show_status ( disp, & sb, "Press B to pair" ) ;
196249 } else {
197- display:: show_status_mini ( disp, & sb, & format ! ( "ACTIVE CLIENTS: {}" , connected) ) ;
250+ display:: show_status ( disp, & sb, & format ! ( "ACTIVE CLIENTS: {}" , connected) ) ;
198251 }
199252 }
200253 }
201254
202255 // CLI allow_pairing: generate a fresh passkey and open a 60-second window.
203256 if ble_hid:: OPEN_PAIRING_REQUESTED . swap ( false , Ordering :: Relaxed ) {
204- passkey = unsafe { esp_idf_svc:: sys:: esp_random ( ) } % 1_000_000 ;
205- ble_hid:: open_pairing_window ( passkey) ;
206- pairing_open = true ;
207- pairing_auto_close_at =
208- unsafe { esp_idf_svc:: sys:: time ( std:: ptr:: null_mut ( ) ) } as u64 + 60 ;
209- inactivity_ticks = 0 ;
210- if !screen_on {
211- backlight. set_high ( ) . ok ( ) ;
212- screen_on = true ;
213- fp. wake ( ) ;
214- }
257+ passkey = open_fresh_pairing_window ( & mut pairing_open, & mut pairing_auto_close_at) ;
258+ wake_screen_if_off ( & mut screen_on, & mut inactivity_ticks, & mut backlight, fp) ;
215259 display:: show_pin ( disp, & sb, passkey, connected) ;
216260 }
217261
218262 let btn_event = buttons. poll ( ) ;
219263 if btn_event. is_some ( ) || ( !screen_on && buttons. is_any_down ( ) ) {
220- inactivity_ticks = 0 ;
221- if !screen_on {
222- backlight. set_high ( ) . ok ( ) ;
223- screen_on = true ;
224- fp. wake ( ) ;
225- }
264+ wake_screen_if_off ( & mut screen_on, & mut inactivity_ticks, & mut backlight, fp) ;
226265 }
227266 match btn_event {
228267 Some ( ButtonEvent :: ALongPress ) => {
@@ -238,17 +277,7 @@ where
238277 Some ( ButtonEvent :: AShortPress ) => {
239278 if pending_bond_clear {
240279 pending_bond_clear = false ;
241- if connected > 0 {
242- display:: show_status_mini (
243- disp,
244- & sb,
245- & format ! ( "ACTIVE CLIENTS: {}" , connected) ,
246- ) ;
247- } else if pairing_open {
248- display:: show_pin ( disp, & sb, passkey, connected) ;
249- } else {
250- display:: show_status ( disp, & sb, "Press B to pair" ) ;
251- }
280+ restore_idle_screen ( disp, & sb, connected, pairing_open, passkey) ;
252281 }
253282 }
254283 Some ( ButtonEvent :: BLongPress ) => {
@@ -261,21 +290,10 @@ where
261290 ble_hid:: close_pairing_window ( ) ;
262291 pairing_open = false ;
263292 pairing_auto_close_at = 0 ;
264- if connected > 0 {
265- display:: show_status_mini (
266- disp,
267- & sb,
268- & format ! ( "ACTIVE CLIENTS: {}" , connected) ,
269- ) ;
270- } else {
271- display:: show_status ( disp, & sb, "Press B to pair" ) ;
272- }
293+ restore_idle_screen ( disp, & sb, connected, pairing_open, passkey) ;
273294 } else {
274- passkey = unsafe { esp_idf_svc:: sys:: esp_random ( ) } % 1_000_000 ;
275- ble_hid:: open_pairing_window ( passkey) ;
276- pairing_open = true ;
277- pairing_auto_close_at =
278- unsafe { esp_idf_svc:: sys:: time ( std:: ptr:: null_mut ( ) ) } as u64 + 60 ;
295+ passkey =
296+ open_fresh_pairing_window ( & mut pairing_open, & mut pairing_auto_close_at) ;
279297 display:: show_pin ( disp, & sb, passkey, connected) ;
280298 }
281299 }
@@ -312,12 +330,7 @@ where
312330
313331 // CLI-driven enrollment: pick up a pending EnrollRequest from the CLI task.
314332 if let Ok ( request) = enroll_rx. try_recv ( ) {
315- inactivity_ticks = 0 ;
316- if !screen_on {
317- backlight. set_high ( ) . ok ( ) ;
318- screen_on = true ;
319- fp. wake ( ) ;
320- }
333+ wake_screen_if_off ( & mut screen_on, & mut inactivity_ticks, & mut backlight, fp) ;
321334 const PASSES : u8 = 3 ;
322335 display:: show_status_2line ( disp, & sb, "CLI Enroll" , "Place finger" ) ;
323336 if fp. begin_enroll ( request. slot , PASSES ) {
@@ -377,23 +390,12 @@ where
377390 }
378391 fp. reactivate ( ) ;
379392 FreeRtos :: delay_ms ( 2000 ) ;
380- if connected > 0 {
381- display:: show_status_mini ( disp, & sb, & format ! ( "ACTIVE CLIENTS: {}" , connected) ) ;
382- } else if pairing_open {
383- display:: show_pin ( disp, & sb, passkey, connected) ;
384- } else {
385- display:: show_status ( disp, & sb, "Press B to pair" ) ;
386- }
393+ restore_idle_screen ( disp, & sb, connected, pairing_open, passkey) ;
387394 }
388395
389396 // CLI-driven fingerprint verify: pick up a pending VerifyRequest from the CLI task.
390397 if let Ok ( request) = verify_rx. try_recv ( ) {
391- inactivity_ticks = 0 ;
392- if !screen_on {
393- backlight. set_high ( ) . ok ( ) ;
394- screen_on = true ;
395- fp. wake ( ) ;
396- }
398+ wake_screen_if_off ( & mut screen_on, & mut inactivity_ticks, & mut backlight, fp) ;
397399 display:: show_status_2line ( disp, & sb, "CLI Auth" , "Place finger" ) ;
398400 let deadline = std:: time:: Instant :: now ( ) + std:: time:: Duration :: from_secs ( 30 ) ;
399401 let matched = loop {
@@ -413,30 +415,19 @@ where
413415 display:: show_status ( disp, & sb, "Auth Failed" ) ;
414416 }
415417 FreeRtos :: delay_ms ( 1500 ) ;
416- if connected > 0 {
417- display:: show_status_mini ( disp, & sb, & format ! ( "ACTIVE CLIENTS: {}" , connected) ) ;
418- } else if pairing_open {
419- display:: show_pin ( disp, & sb, passkey, connected) ;
420- } else {
421- display:: show_status ( disp, & sb, "Press B to pair" ) ;
422- }
418+ restore_idle_screen ( disp, & sb, connected, pairing_open, passkey) ;
423419 }
424420
425421 // Fingerprint — non-blocking poll; blocks ~20 ms only when a finger is detected.
426422 match fp. poll ( ) {
427423 Some ( fingerprint:: IdentifyResult :: Match ( id) ) => {
428- inactivity_ticks = 0 ;
429- if !screen_on {
430- backlight. set_high ( ) . ok ( ) ;
431- screen_on = true ;
432- fp. wake ( ) ;
433- }
424+ wake_screen_if_off ( & mut screen_on, & mut inactivity_ticks, & mut backlight, fp) ;
434425 display:: show_auth_ok ( disp, & sb, id) ;
435426
436427 let key = format ! ( "slot_{}" , id) ;
437428 let mut buf = [ 0u8 ; 65 ] ;
438429 let totp_result = {
439- let guard = nvs . lock ( ) . expect ( "NVS mutex poisoned" ) ;
430+ let guard = config_store :: lock_nvs ( & nvs ) ;
440431 match guard. 0 . get_str ( & key, & mut buf) {
441432 Ok ( Some ( secret) ) => {
442433 let now =
@@ -472,30 +463,13 @@ where
472463 }
473464
474465 FreeRtos :: delay_ms ( 2000 ) ;
475- if connected > 0 {
476- display:: show_status_mini ( disp, & sb, & format ! ( "ACTIVE CLIENTS: {}" , connected) ) ;
477- } else if pairing_open {
478- display:: show_pin ( disp, & sb, passkey, connected) ;
479- } else {
480- display:: show_status ( disp, & sb, "Press B to pair" ) ;
481- }
466+ restore_idle_screen ( disp, & sb, connected, pairing_open, passkey) ;
482467 }
483468 Some ( fingerprint:: IdentifyResult :: NoMatch ) => {
484- inactivity_ticks = 0 ;
485- if !screen_on {
486- backlight. set_high ( ) . ok ( ) ;
487- screen_on = true ;
488- fp. wake ( ) ;
489- }
469+ wake_screen_if_off ( & mut screen_on, & mut inactivity_ticks, & mut backlight, fp) ;
490470 display:: show_no_match ( disp, & sb) ;
491471 FreeRtos :: delay_ms ( 2000 ) ;
492- if connected > 0 {
493- display:: show_status_mini ( disp, & sb, & format ! ( "ACTIVE CLIENTS: {}" , connected) ) ;
494- } else if pairing_open {
495- display:: show_pin ( disp, & sb, passkey, connected) ;
496- } else {
497- display:: show_status ( disp, & sb, "Press B to pair" ) ;
498- }
472+ restore_idle_screen ( disp, & sb, connected, pairing_open, passkey) ;
499473 }
500474 None => { }
501475 }
0 commit comments