@@ -581,6 +581,69 @@ message LockdownAuth {
581581 * the locked state. Always honoured regardless of current lock state.
582582 */
583583 bool lock_now = 4 ;
584+
585+ /*
586+ * Optional per-boot uptime cap on the unlocked session, in seconds.
587+ * 0 = unlimited (token-only enforcement, suitable for unattended
588+ * tower / infrastructure nodes).
589+ *
590+ * When non-zero, the firmware arms an uptime timer at unlock. On
591+ * each expiry, while there is still boot-count budget, the firmware
592+ * decrements the on-flash boot count in place, revokes per-
593+ * connection admin auth (clients must re-authenticate to see
594+ * content), re-engages the screen lock, and re-arms the timer
595+ * without rebooting. Mesh routing keeps running across session
596+ * boundaries; only when the boot-count budget reaches zero does
597+ * the device hard-lock and reboot.
598+ *
599+ * Total exposure ceiling = ((resolved boot count) + 1) * max_session_seconds.
600+ * The +1 accounts for the initial passphrase-unlocked session
601+ * itself, since boots_remaining is the number of subsequent
602+ * session rolls (each consuming one boot from the rollback ledger).
603+ * The resolved boot count is the value the firmware writes into the
604+ * token at unlock time: the client-supplied boots_remaining when
605+ * non-zero, otherwise the firmware default (TOKEN_DEFAULT_BOOTS).
606+ * Note that boots_remaining == 0 in this message means "use firmware
607+ * default", NOT "zero boots" — a client computing the ceiling for
608+ * display should mirror that resolution rather than multiplying the
609+ * raw request value.
610+ *
611+ * The cap is persisted in the token, so it survives token-based
612+ * auto-unlock across reboots. Explicit operator Lock Now still
613+ * deletes the token and forces passphrase re-entry.
614+ *
615+ * Uses millis() (CPU uptime), not wall-clock time, so the cap is
616+ * immune to GPS spoofing, RTC backup-battery removal, and Faraday
617+ * cage isolation — none of those move the uptime counter. The only
618+ * way to reset the session clock is a reboot, which costs a boot
619+ * from the on-flash, HMAC-bound counter.
620+ */
621+ uint32 max_session_seconds = 5 ;
622+
623+ /*
624+ * Disable lockdown mode. Requires a valid passphrase in the same
625+ * message (the device must prove the operator owns it before
626+ * reverting at-rest encryption). On success the firmware decrypts
627+ * every stored config / channel / nodedb file back to plaintext,
628+ * removes the wrapped DEK, unlock token, monotonic-counter, and
629+ * backoff files, and reboots out of lockdown.
630+ *
631+ * This is the inverse of the provision/unlock path: it is how the
632+ * client app's "lockdown mode" toggle returns a device to normal
633+ * operation.
634+ *
635+ * NOT reversed by this operation: APPROTECT. Once the debug port
636+ * lockout has been burned (on silicon where it is effective) it is
637+ * permanent — disabling lockdown decrypts your data and removes the
638+ * access gates, but the SWD/JTAG port stays locked for the life of
639+ * the device (recoverable only via a full chip erase over a debug
640+ * probe, which destroys all data). Clients should make this
641+ * irreversibility clear at the moment lockdown is first enabled.
642+ *
643+ * When true the passphrase field is still required; boots_remaining,
644+ * valid_until_epoch, max_session_seconds, and lock_now are ignored.
645+ */
646+ bool disable = 6 ;
584647}
585648
586649/*
@@ -628,6 +691,12 @@ message HamParameters {
628691 * Optional short name of user
629692 */
630693 string short_name = 4 ;
694+
695+ /*
696+ * Optional long name of user
697+ * Appended to callsign
698+ */
699+ string long_name = 5 ;
631700}
632701
633702/*
0 commit comments