Rewrite the MQTT region root topic only on the default broker (#11899)

* fix(mqtt): rewrite the region root topic only on the default broker

A region change rewrote any root starting with "msh", on any broker. Custom roots such as msh/home were clobbered, and private brokers had their topics moved even though a regional broker is regional already. An empty root, which MQTT treats as the default, was never updated.

Region changes now go through MQTT::applyRegionRootTopic(), which rewrites the root only on the default broker and only when the root is empty, the default, or a msh/<region> the firmware wrote itself.

* fix(mqtt): parse the broker address before the default-server check

Persist module config only when the root actually changed. Replace a stray NUL byte in the test with the \0 escape.

* fix(mqtt): count the regional roots as the default root topic
This commit is contained in:
Thomas Göttgens authored and GitHub committed 2026-09-18 10:34:53 +00:00
1 parent a5dce941dd
commit c29bd00971
6 files changed
+106 -17

No files matched your search

+10 -10
View File
@@ -1068,11 +1068,11 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c, bool fromOthers)
if (getEffectiveDutyCycle() < 100) {
validatedLora.ignore_mqtt = true; // Ignore MQTT by default if region has a duty cycle limit
}
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);
}
changes |= SEGMENT_CONFIG | SEGMENT_MODULECONFIG;
#if !MESHTASTIC_EXCLUDE_MQTT
if (MQTT::applyRegionRootTopic(myRegion->name))
changes |= SEGMENT_MODULECONFIG;
#endif
changes |= SEGMENT_CONFIG;
} else {
// Region validation has failed, so just copy all of the old config over the new config
validatedLora = oldLoraConfig;
@@ -1108,11 +1108,11 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c, bool fromOthers)
if (getEffectiveDutyCycle() < 100) {
validatedLora.ignore_mqtt = true; // Ignore MQTT by default if region has a duty cycle limit
}
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);
}
changes |= SEGMENT_CONFIG | SEGMENT_MODULECONFIG;
#if !MESHTASTIC_EXCLUDE_MQTT
if (MQTT::applyRegionRootTopic(myRegion->name))
changes |= SEGMENT_MODULECONFIG;
#endif
changes |= SEGMENT_CONFIG;
}
// use_preset and bandwidth are coerced into valid values by the check.
}