mirror of
https://github.com/meshtastic/firmware.git
synced 2026-09-21 05:45:27 -04:00
fix(mqtt): rebuild topics in runOnce when the root changes
Replaces the per-call-site reinitTopics() calls. Also keep the device state and node database segments when the EU clamp swaps the region.
This commit is contained in:
1 parent
41fd7c4452
commit
6845b045fe
5 files changed
+13
-23
No files matched your search
@@ -28,9 +28,6 @@
|
||||
#include "mesh/RadioLibInterface.h"
|
||||
#include "modules/AdminModule.h"
|
||||
#include "modules/CannedMessageModule.h"
|
||||
#if !MESHTASTIC_EXCLUDE_MQTT
|
||||
#include "mqtt/MQTT.h"
|
||||
#endif
|
||||
#include "modules/ExternalNotificationModule.h"
|
||||
#include "modules/GeofenceModule.h"
|
||||
#include "modules/KeyVerificationModule.h"
|
||||
@@ -295,10 +292,6 @@ static void applyLoraRegion(meshtastic_Config_LoRaConfig_RegionCode region, bool
|
||||
if (strncmp(moduleConfig.mqtt.root, default_mqtt_root, strlen(default_mqtt_root)) == 0) {
|
||||
snprintf(moduleConfig.mqtt.root, sizeof(moduleConfig.mqtt.root), "%s/%s", default_mqtt_root, myRegion->name);
|
||||
changes |= SEGMENT_MODULECONFIG;
|
||||
#if !MESHTASTIC_EXCLUDE_MQTT
|
||||
if (mqtt)
|
||||
mqtt->reinitTopics();
|
||||
#endif
|
||||
}
|
||||
#if !MESHTASTIC_EXCLUDE_GPS
|
||||
// Enable gps if it was previously disabled due to region not being set
|
||||
|
||||
@@ -1071,10 +1071,6 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c, bool fromOthers)
|
||||
if (strncmp(moduleConfig.mqtt.root, default_mqtt_root, strlen(default_mqtt_root)) == 0) {
|
||||
// Default root is in use, so subscribe to the appropriate MQTT topic for this region
|
||||
snprintf(moduleConfig.mqtt.root, sizeof(moduleConfig.mqtt.root), "%s/%s", default_mqtt_root, myRegion->name);
|
||||
#if !MESHTASTIC_EXCLUDE_MQTT
|
||||
if (mqtt)
|
||||
mqtt->reinitTopics();
|
||||
#endif
|
||||
}
|
||||
changes |= SEGMENT_CONFIG | SEGMENT_MODULECONFIG;
|
||||
} else {
|
||||
@@ -1115,12 +1111,8 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c, bool fromOthers)
|
||||
if (strncmp(moduleConfig.mqtt.root, default_mqtt_root, strlen(default_mqtt_root)) == 0) {
|
||||
// Default root is in use, so subscribe to the appropriate MQTT topic for this region
|
||||
snprintf(moduleConfig.mqtt.root, sizeof(moduleConfig.mqtt.root), "%s/%s", default_mqtt_root, myRegion->name);
|
||||
#if !MESHTASTIC_EXCLUDE_MQTT
|
||||
if (mqtt)
|
||||
mqtt->reinitTopics();
|
||||
#endif
|
||||
}
|
||||
changes = SEGMENT_CONFIG | SEGMENT_MODULECONFIG;
|
||||
changes |= SEGMENT_CONFIG | SEGMENT_MODULECONFIG;
|
||||
}
|
||||
// use_preset and bandwidth are coerced into valid values by the check.
|
||||
}
|
||||
|
||||
@@ -376,6 +376,7 @@ void mqttInit()
|
||||
|
||||
void MQTT::reinitTopics()
|
||||
{
|
||||
topicRoot = moduleConfig.mqtt.root;
|
||||
const std::string root = *moduleConfig.mqtt.root ? moduleConfig.mqtt.root : default_mqtt_root;
|
||||
cryptTopic = root + "/2/e/";
|
||||
mapTopic = root + "/2/map/";
|
||||
@@ -580,6 +581,9 @@ int32_t MQTT::runOnce()
|
||||
{
|
||||
if (!moduleConfig.mqtt.enabled || !(moduleConfig.mqtt.map_reporting_enabled || channels.anyMqttEnabled()))
|
||||
return disable();
|
||||
// A region change rewrites the root at runtime, from several call sites
|
||||
if (topicRoot != moduleConfig.mqtt.root)
|
||||
reinitTopics();
|
||||
bool wantConnection = wantsLink();
|
||||
|
||||
perhapsReportToMap();
|
||||
|
||||
+4
-3
@@ -58,9 +58,6 @@ class MQTT : private concurrency::OSThread
|
||||
bool isUsingDefaultServer() { return isConfiguredForDefaultServer; }
|
||||
bool isUsingDefaultRootTopic() { return isConfiguredForDefaultRootTopic; }
|
||||
|
||||
/// Rebuild topics from moduleConfig.mqtt.root and force a resubscribe.
|
||||
void reinitTopics();
|
||||
|
||||
/// Validate the meshtastic_ModuleConfig_MQTTConfig.
|
||||
static bool isValidConfig(const meshtastic_ModuleConfig_MQTTConfig &config) { return isValidConfig(config, nullptr); }
|
||||
|
||||
@@ -101,6 +98,7 @@ class MQTT : private concurrency::OSThread
|
||||
explicit MQTT(std::unique_ptr<MQTTClient> mqttClient);
|
||||
#endif
|
||||
|
||||
std::string topicRoot; // moduleConfig.mqtt.root the topics below were built from
|
||||
std::string cryptTopic = "/2/e/"; // msh/2/e/CHANNELID/NODEID
|
||||
std::string mapTopic = "/2/map/"; // For protobuf-encoded MapReport messages
|
||||
|
||||
@@ -114,6 +112,9 @@ class MQTT : private concurrency::OSThread
|
||||
*/
|
||||
void reconnect();
|
||||
|
||||
/// Rebuild topics from moduleConfig.mqtt.root and force a resubscribe.
|
||||
void reinitTopics();
|
||||
|
||||
/** Tell the server what subscriptions we want (based on channels.downlink_enabled)
|
||||
*/
|
||||
void sendSubscriptions();
|
||||
|
||||
@@ -1360,8 +1360,9 @@ void test_customMqttRoot(void)
|
||||
[] { return pubsub->subscriptions_.count("custom/2/e/test/+") && pubsub->subscriptions_.count("custom/2/e/PKI/+"); }));
|
||||
}
|
||||
|
||||
// After a LoRa region change, reinitTopics() updates the publish topic and forces
|
||||
// the broker to reconnect with updated subscriptions.
|
||||
// A LoRa region change rewrites moduleConfig.mqtt.root without telling MQTT (AdminModule, MenuHandler,
|
||||
// InkHUD). runOnce() must pick it up, rebuild the topics and resubscribe; otherwise the node keeps
|
||||
// publishing and subscribing under the old region's root until reboot.
|
||||
void test_reinitTopicsUpdatesOnRegionChange(void)
|
||||
{
|
||||
// Start MQTT with a US region root.
|
||||
@@ -1371,11 +1372,10 @@ void test_reinitTopicsUpdatesOnRegionChange(void)
|
||||
TEST_ASSERT_TRUE(loopUntil(
|
||||
[] { return pubsub->subscriptions_.count("msh/US/2/e/test/+") && pubsub->subscriptions_.count("msh/US/2/e/PKI/+"); }));
|
||||
|
||||
// Simulate region change: update the root and call reinitTopics().
|
||||
// Simulate region change: only the root changes, nobody notifies MQTT.
|
||||
strcpy(moduleConfig.mqtt.root, "msh/EU_868");
|
||||
pubsub->subscriptions_.clear();
|
||||
pubsub->published_.clear();
|
||||
mqtt->reinitTopics();
|
||||
|
||||
// Verify that subscriptions are refreshed with the new region prefix.
|
||||
TEST_ASSERT_TRUE(loopUntil([] {
|
||||
|
||||
Reference in new issue
Block a user