Skip to content

feat(mqtt): add phone-local MQTT proxy cutoff control#5823

Merged
jamesarich merged 1 commit into
mainfrom
claude/stupefied-wright-d241bd
Jun 17, 2026
Merged

feat(mqtt): add phone-local MQTT proxy cutoff control#5823
jamesarich merged 1 commit into
mainfrom
claude/stupefied-wright-d241bd

Conversation

@jamesarich

Copy link
Copy Markdown
Collaborator

When a device is set to the root topic, MQTT traffic can saturate the BLE link and the MCU on nRF devices — where the phone acts as the MQTT proxy — leaving the device unresponsive to phone requests. This adds a phone-local control that cuts the proxy firehose immediately, without the slow read-modify-write-readback cycle on the device's MQTT config.

Resolves #5800

🌟 New Features

  • "MQTT proxy on this phone" switch on the MQTT settings screen (just below the live status row). Toggling it off stops the phone-side proxy immediately; toggling it on resumes proxying using the device's current MQTT config.
  • The control acts purely on the phone-side proxy lifecycle via MqttManager and issues no device config reads or writes — so recovery is instant even when the BLE link is congested.
  • A summary string makes the semantics explicit: it relays/cuts traffic on this phone and does not change the device's MQTT setting.

🛠️ Refactoring & Architecture

  • MqttManager now exposes proxyActive: StateFlow<Boolean> reflecting the phone-side proxy lifecycle (backed by the existing internal state in MqttManagerImpl, renamed to _proxyActive).
  • RadioConfigViewModel surfaces mqttProxyActive and adds setMqttProxyActive(active), which calls MqttManager.stop() / startProxy(...) directly. On re-enable it reads the device's current (already-loaded) MQTT config rather than fetching it, and never writes config back.
  • The switch is gated so off→on is only offered when the device config permits proxying (mqtt.enabled && proxy_to_client_enabled), while staying live whenever the proxy is actually running so it can always be turned off.

Testing Performed

Added unit tests in RadioConfigViewModelTest:

  • setMqttProxyActive false stops the proxy without touching device config — verifies MqttManager.stop() is called and no setModuleConfig write is issued.
  • setMqttProxyActive true restarts proxy using current device module config — verifies startProxy(true, true) from the loaded config, with no config write.
  • setMqttProxyActive true is a no-op start when device MQTT is disabled — verifies it delegates with both flags false (the manager's own guard then does nothing).

Full baseline verification run locally and green: spotlessApply spotlessCheck detekt assembleDebug test allTests kmpSmokeCompile.

@github-actions github-actions Bot added the enhancement New feature or request label Jun 17, 2026
@github-actions

github-actions Bot commented Jun 17, 2026

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:

feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/radio/component/MQTTConfigItemList.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

github-actions Bot commented Jun 17, 2026

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/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/radio/component/MQTTConfigItemList.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.

@jamesarich jamesarich force-pushed the claude/stupefied-wright-d241bd branch from 5227b2e to 3d66abc Compare June 17, 2026 00:34
@jamesarich jamesarich marked this pull request as ready for review June 17, 2026 00:48
@jamesarich jamesarich added this to the 2.8.0 milestone Jun 17, 2026
Adds a "MQTT proxy on this phone" switch to the MQTT settings screen that
stops/starts the phone-side MQTT proxy directly via MqttManager, without the
slow read-modify-write-readback round-trip on the device's MQTT config. On nRF
devices (where the phone is the MQTT proxy) a root-topic firehose can saturate
the BLE link and MCU; this lets the user cut it immediately.

- Expose MqttManager.proxyActive: StateFlow<Boolean> (phone-side lifecycle).
- RadioConfigViewModel.setMqttProxyActive() stops/(re)starts the proxy using
  the device's current MQTT config, issuing no device config writes.
- Switch is gated so off->on is only offered when the device config permits
  proxying, while staying live whenever the proxy is running.

Fixes #5800

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@jamesarich jamesarich force-pushed the claude/stupefied-wright-d241bd branch from 3d66abc to 6cda11e Compare June 17, 2026 02:00
@jamesarich jamesarich enabled auto-merge June 17, 2026 02:00
@jamesarich jamesarich added this pull request to the merge queue Jun 17, 2026
Merged via the queue into main with commit c347903 Jun 17, 2026
18 checks passed
@jamesarich jamesarich deleted the claude/stupefied-wright-d241bd branch June 17, 2026 02:12
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.

[Feature Request]: ability to disable MQTT from the phone without reading the phone setting first

1 participant