diff --git a/main.c b/main.c index 4583119..1b4d84c 100644 --- a/main.c +++ b/main.c @@ -52,7 +52,7 @@ static void boot_network(void) { printf("[main] NTP sync ok\r\n"); } -static void core0_handle_door_verify(void) { +void core0_handle_door_verify(void) { static uint32_t last_handled_seq = 0; uint32_t seq = door_verify_mailbox.request_seq; diff --git a/serial/commands_backup.c b/serial/commands_backup.c index ea18467..a916453 100644 --- a/serial/commands_backup.c +++ b/serial/commands_backup.c @@ -3,6 +3,7 @@ #include "storage/backup.h" #include "shared/wipe.h" #include "libs/base64/base64.h" +#include "shared/door_verify.h" #include "pico/stdlib.h" #include "pico/time.h" #include @@ -83,6 +84,10 @@ void cmd_import_keys(int argc, char **argv) { absolute_time_t deadline = make_timeout_time_ms(60000); // 60s to paste while (!time_reached(deadline)) { + // Core 0 is the only servicer of keypad door-verify requests; pump it + // each iteration so a long paste never starves the keypad (L9). + core0_handle_door_verify(); + int c = getchar_timeout_us(10000); if (c == PICO_ERROR_TIMEOUT) continue; diff --git a/serial/commands_system.c b/serial/commands_system.c index 4b92f9e..3c4d1e3 100644 --- a/serial/commands_system.c +++ b/serial/commands_system.c @@ -10,6 +10,7 @@ #include "network/ntp.h" #include "storage/backup.h" #include "storage/storage.h" +#include "shared/door_verify.h" #include "shared/totp.h" #include "shared/wipe.h" #include "version.h" @@ -64,11 +65,13 @@ void cmd_status(int argc, char **argv) { printf("ntp: not synced\r\n"); } - // Keys (admin only: key inventory is target-selection data) + // Keys (admin only: key inventory is target-selection data). Declared at + // function scope so the scrub below always runs, even on the non-admin path + // where the array stays zero-initialised. + static key_record_t keys[BACKUP_MAX_KEYS]; if (commands_is_admin()) { - static key_record_t keys[BACKUP_MAX_KEYS]; - int count = storage_key_list(keys, BACKUP_MAX_KEYS); - int enabled = 0, corrupt = 0; + int count = storage_key_list(keys, BACKUP_MAX_KEYS); + int enabled = 0, corrupt = 0; for (int i = 0; i < count; i++) { if (!keys[i].is_checksum_valid) corrupt++; @@ -252,6 +255,10 @@ void cmd_format_storage(int argc, char **argv) { absolute_time_t deadline = make_timeout_time_ms(15000); while (!time_reached(deadline) && len < 7) { + // Core 0 is the only servicer of keypad door-verify requests; pump it + // each iteration so the confirm wait never starves the keypad (L9). + core0_handle_door_verify(); + int c = getchar_timeout_us(0); if (c == PICO_ERROR_TIMEOUT) { sleep_ms(10); diff --git a/shared/door_verify.h b/shared/door_verify.h index 86ca83d..ae4fe9c 100644 --- a/shared/door_verify.h +++ b/shared/door_verify.h @@ -35,4 +35,11 @@ typedef struct { extern door_verify_mailbox_t door_verify_mailbox; +// Core-0 servicer of the mailbox: reads a pending keypad request (if any) and +// writes back the verdict. Non-blocking and single-shot per request. Defined in +// main.c and normally called once per core-0 main-loop iteration; also pumped +// inside core-0 blocking loops (import/format waits) so a paste/confirm can +// never starve the keypad (ISSUES.md L9). +void core0_handle_door_verify(void); + #endif