Fix: MQTT topic not updated when LoRa region changes#10565
Conversation
When the LoRa region is changed via AdminModule::handleSetConfig, moduleConfig.mqtt.root is updated (e.g. from msh/US to msh/EU_868) but the running MQTT instance kept using the stale topic strings (cryptTopic / jsonTopic / mapTopic) that were set at construction time. Introduce MQTT::reinitTopics() which: - resets the topic strings to their base values and prepends the current moduleConfig.mqtt.root, and - disconnects from the broker so the next reconnect re-subscribes under the new topic prefix. Call reinitTopics() from MQTT's constructor (replacing the inline block) so the logic lives in one place, and call it from AdminModule::handleSetConfig right after moduleConfig.mqtt.root is rewritten on a region change. Add a unit test (test_reinitTopicsUpdatesOnRegionChange) that verifies both the updated subscriptions and the updated publish topic after a simulated region change.
|
@copilot this patch misses the case where the region is changed via menuhandler.cpp |
Fixed in the latest commit — |
There was a problem hiding this comment.
Pull request overview
This PR fixes stale MQTT publish/subscribe topics after a LoRa region change by centralizing topic-prefix (root) handling inside the MQTT singleton and reapplying it whenever moduleConfig.mqtt.root is rewritten (e.g., msh/US → msh/EU_868). This aligns runtime MQTT behavior with the device’s updated region-derived root topic without requiring a reboot.
Changes:
- Added
MQTT::reinitTopics()to rebuildcryptTopic/jsonTopic/mapTopicfrommoduleConfig.mqtt.rootand force a broker disconnect so the next reconnect re-subscribes under the new prefix. - Updated region-change flows (Admin config + on-device menu) to call
mqtt->reinitTopics()immediately after rewritingmoduleConfig.mqtt.root. - Added a unit test validating that
reinitTopics()refreshes subscriptions and the publish topic after a simulated region change.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
src/mqtt/MQTT.h |
Declares MQTT::reinitTopics() as the public entry point for rebuilding topic strings after root changes. |
src/mqtt/MQTT.cpp |
Implements reinitTopics() and uses it in the constructor to avoid duplicated topic-init logic; disconnects to refresh subscriptions on reconnect. |
src/modules/AdminModule.cpp |
Calls mqtt->reinitTopics() after rewriting the default region-derived MQTT root during region changes. |
src/graphics/draw/MenuHandler.cpp |
Adds guarded MQTT include and calls mqtt->reinitTopics() after rewriting the region-derived MQTT root via the device UI. |
test/test_mqtt/MQTT.cpp |
Adds test_reinitTopicsUpdatesOnRegionChange to confirm refreshed subscriptions + corrected publish topic under the new root. |
When MQTT is active and the LoRa region is changed, the running MQTT instance continues publishing and subscribing under the old region's topic prefix (e.g.
msh/US/…after switching away from US), becausemoduleConfig.mqtt.rootwas updated but the topic strings cached in theMQTTobject were not.Changes
src/mqtt/MQTT.h/src/mqtt/MQTT.cpp— IntroduceMQTT::reinitTopics():cryptTopic,jsonTopic,mapTopicto base values and prepends the currentmoduleConfig.mqtt.rootisConfiguredForDefaultRootTopicreinitTopics()instead of duplicating the same inline blocksrc/modules/AdminModule.cpp— Callmqtt->reinitTopics()immediately aftermoduleConfig.mqtt.rootis rewritten on a region change (guarded by!MESHTASTIC_EXCLUDE_MQTT)src/graphics/draw/MenuHandler.cpp— Callmqtt->reinitTopics()immediately aftermoduleConfig.mqtt.rootis rewritten on a region change via the on-device menu (guarded by!MESHTASTIC_EXCLUDE_MQTT); also adds the requiredmqtt/MQTT.hinclude under the same guardtest/test_mqtt/MQTT.cpp— Addtest_reinitTopicsUpdatesOnRegionChange: starts MQTT with rootmsh/US, simulates a region change tomsh/EU_868viareinitTopics(), then asserts both the refreshed subscriptions and the corrected publish topic🤝 Attestations