Skip to content

feat(lockdown): firmware lockdown mode (provision / unlock / lock-now)#5939

Merged
jamesarich merged 4 commits into
mainfrom
lockdown-on-main
Jun 24, 2026
Merged

feat(lockdown): firmware lockdown mode (provision / unlock / lock-now)#5939
jamesarich merged 4 commits into
mainfrom
lockdown-on-main

Conversation

@jamesarich

@jamesarich jamesarich commented Jun 24, 2026

Copy link
Copy Markdown
Collaborator

Why

Adds end-to-end client support for the firmware's hardened LOCKDOWN build: a locked device prompts for a passphrase, optionally auto-replays a stored one, surfaces backoff/lock-reason, and offers Lock Now. Supersedes #5439, which was built on the pre-AIDL architecture and went stale after release/2.8.0 ff-merged onto main. This branch re-applies the same feature, re-resolved against current main (post-AIDL CommandSender/coordinator, takpacket 0.7.0, traffic-mgmt removal, etc.).

🌟 Features

  • LockdownCoordinator owns the lockdown lifecycle: processes LockdownStatus from firmware, drives LockdownState (None/NeedsProvision/Locked/Unlocked/UnlockFailed/UnlockBackoff/Disabled/LockNowAcknowledged), auto-replays cached passphrases.
  • Encrypted passphrase stores: Android EncryptedSharedPreferences (AES-256-GCM); JVM/Desktop PKCS12 + AES-256-GCM.
  • UI: LockdownDialog (provision/unlock/backoff) + LockdownSessionStatus, wired through UIViewModel/RadioConfigViewModelLockdownCoordinator. Region-unset banner gated on sessionAuthorized.

🛠️ Integration onto current main

  • Lockdown send path builds AdminMessage(lockdown_auth=…) and dispatches via PacketHandler.sendToRadio to self (channel 0, ADMIN_APP, RELIABLE) — the firmware-bootstrap path (pre-session, no passkey).
  • Routes FromRadio.lockdown_status → coordinator; config_completecoordinator.onConfigComplete(); connect/disconnect → coordinator.onConnect()/onDisconnect().
  • Proto pinned to v2.7.26-497cd88-SNAPSHOT (RB snapshot, protobufs UI update, enhancements #959) for max_session_seconds (#916), disable/State.DISABLED (chore(deps): update gradle to v8.7 #929), and the TINY_FAST/TINY_SLOW ModemPreset additions.

🧹 Dependency hygiene

  • core:model excludes takpacket-sdk's transitive protobufs-jvm:2.7.25 so the app's single pinned protobufs is authoritative on every classpath. Without it, the older transitive pin out-ranked the snapshot on the host-test classpath and broke proto ABI (NoSuchMethodError). Drop once takpacket-sdk stops exporting protobufs.

Testing Performed

  • ./gradlew assembleFdroidDebug — SUCCESS against v2.7.26-497cd88-SNAPSHOT.
  • Full suite green across the touched + at-risk modules: :core:data, :core:takserver (123 tests incl. TAKMeshIntegrationTest/TAKPacket.ADAPTER), :core:service, :core:ui, :feature:settings, :feature:connectionszero proto NoSuchMethodError; takpacket 0.7.0 runs cleanly against v2.7.26.

Before merge

  • Swap the v2.7.26-497cd88-SNAPSHOT pin for a tagged protobufs release once one ships with #916/chore(deps): update gradle to v8.7 #929 (reproducible builds), and drop the takpacket exclude once takpacket-sdk no longer exports protobufs.

🤖 Generated with Claude Code

Re-applies the lockdown feature onto main (which absorbed release/2.8.0 +146
commits: takpacket 0.7.0 full-KMP, traffic-mgmt removal #5878, RECONNECTING
progress, MeshConnectionManager test refactor, etc.). Replaces the stale
lockdown-integ branch (built on the old release/2.8.0 line).

Applied as a 3-way patch of the prior re-port; 7 integration points re-resolved
against main's evolution:
- ConnectionsViewModel/Test: main keeps serviceRepository (no ConnectionStateProvider
  split) — just graft lockdownState/sessionAuthorized onto it.
- ServiceRepository: keep both main's RECONNECTING_PROGRESS_TEXT companion and the
  lockdown flows.
- ConnectionsScreen: region banner gated on sessionAuthorized AND main's REPLAY_DEVICE_PREFIX.
- MeshConnectionManagerImpl: keep main's handshakeCompleteLatch reset + lockdownCoordinator.onConnect().
- MeshConnectionManagerImplTest: adopt main's lateinit/setUp pattern + lockdownCoordinator fake.

proto pinned to v2.7.26-497cd88-SNAPSHOT (RB snapshot, #959) for #916/#929 + TINY presets.
takpacket-sdk 0.7.0 (KMP) no longer supplies a conflicting transitive protobufs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions github-actions Bot added the enhancement New feature or request label Jun 24, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📄 Docs staleness check — advisory

This PR modifies user-facing UI source files but does not update any page under docs/en/user/ or docs/en/developer/.

⚠️ Doc changes propagate to 3 consumers: in-app docs browser, Jekyll site (GitHub Pages), and meshtastic.org (Docusaurus sync). Updating a page in docs/en/ automatically flows to all three.

Changed source files:

core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/viewmodel/ConnectionsViewModel.kt
core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/viewmodel/UIViewModel.kt
feature/connections/src/commonMain/kotlin/org/meshtastic/feature/connections/ui/ConnectionsScreen.kt
feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/radio/component/SecurityConfigScreen.kt

What to check:

Changed area Likely doc page
feature/messaging/ docs/en/user/messages-and-channels.md
feature/node/ docs/en/user/nodes.md or docs/en/user/node-metrics.md
feature/map/ docs/en/user/map-and-waypoints.md
feature/connections/ docs/en/user/connections.md
feature/settings/ docs/en/user/settings-radio-user.md or docs/en/user/settings-module-admin.md
feature/firmware/ docs/en/user/firmware.md
feature/intro/ docs/en/user/onboarding.md
feature/discovery/ docs/en/user/discovery.md
feature/docs/ Internal docs infrastructure
core/ui/ docs/en/developer/codebase.md or component-specific user pages

New page checklist (if adding a new doc page):

  1. Create the .md file in docs/en/user/ or docs/en/developer/ with last_updated frontmatter
  2. Register in DocBundleLoader.kt with string resources (in-app browser)
  3. Jekyll and Docusaurus sync pick up new pages automatically — no config change needed

If this PR does not require a doc update (e.g., internal refactor, bug fix, test change), add the skip-docs-check label to dismiss this check.

Cross-platform note: This check is advisory while doc coverage matures. Both Android and Apple repos use the same skip-docs-check label and advisory severity. See meshtastic/design standards for shared conventions.

@github-actions

Copy link
Copy Markdown
Contributor

🖼️ Preview staleness check — advisory

This PR modifies UI composables but does not update any *Previews.kt files.

Previews power screenshot tests and in-app docs screenshots. Keeping them current ensures visual regression coverage stays accurate.

Changed UI files:

feature/connections/src/commonMain/kotlin/org/meshtastic/feature/connections/ui/ConnectionsScreen.kt
feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/radio/component/SecurityConfigScreen.kt

What to check:

Pattern Preview file convention
feature/{name}/…/ui/ or component/ feature/{name}/…/*Previews.kt
core/ui/…/ core/ui/…/ (previews colocated)

Adding previews checklist:

  1. Create or update a *Previews.kt file in the same module with @PreviewLightDark
  2. Add @Suppress("PreviewPublic") if the preview is consumed by screenshot-tests
  3. Add corresponding @PreviewTest function in screenshot-tests/src/screenshotTest/
  4. Run ./gradlew :screenshot-tests:updateDebugScreenshotTest to generate reference images

If this PR does not require preview updates (e.g., logic-only change, non-visual refactor), add the skip-preview-check label to dismiss.

takpacket-sdk 0.7.0 still declares protobufs-jvm:2.7.25 (runtime); it out-ranked the
app's v2.7.26 snapshot pin on the host-test classpath -> proto-ctor NoSuchMethodError
in JVM/host tests. Exclude it so the app's single protobufs version is authoritative.
Verified: full suite incl. :core:takserver green. Drop when takpacket stops exporting protobufs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@jamesarich jamesarich marked this pull request as ready for review June 24, 2026 19:25
@jamesarich jamesarich requested a review from niccellular June 24, 2026 19:26
jamesarich and others added 2 commits June 24, 2026 14:30
# Conflicts:
#	core/data/src/commonTest/kotlin/org/meshtastic/core/data/manager/FromRadioPacketHandlerImplTest.kt
…ondition

The region-warning guard hit 5 && conditions (max 4) after unioning the lockdown
sessionAuthorized gate with main's REPLAY_DEVICE_PREFIX check. Fold the two
device-prefix checks into a named val.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@jamesarich jamesarich added this pull request to the merge queue Jun 24, 2026
Merged via the queue into main with commit df67b3e Jun 24, 2026
22 checks passed
@jamesarich jamesarich deleted the lockdown-on-main branch June 24, 2026 20:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant