From bd91ff80eadeb3ab9aa8a0408e7769b354858079 Mon Sep 17 00:00:00 2001 From: agessaman Date: Wed, 19 Aug 2026 08:38:00 -0700 Subject: [PATCH] fix(mqtt): clear a slot that preferences say is disabled on bridge start MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The preset-application loop in begin() only had a positive branch, so when preferences named no preset the slot kept whatever the previous begin() left in RAM. Nothing else resets it: teardownSlot() deliberately preserves enabled and preset so a reconfigure can reuse the mbedTLS context, and the constructor clears them exactly once. A bridge restart could therefore resurrect a broker the operator had disabled and reconnect to it with the old credentials. Config fields only. The client belongs to destroySlotClients() and the token buffer to releaseSlotAuthToken(); clearing either here would strand a pointer esp-mqtt still holds in its config. Note the positive branch re-enabling a slot is correct and unchanged: a slot capped off at startup is disabled in RAM only, with preferences still naming a real preset, and the cap decision has to be re-made on each start. Reachable via WebConfig, where a pending full restart discards the per-slot restart mask, so a batch that disables a slot can end in a restart that never applied the disable. A plain CLI set cannot reach it: restartBridgeSlot() applies the change to the live bridge immediately, keeping RAM and preferences in agreement. Verified on hardware as a non-regression check for that reason — disable, restart, slot stays down; restore, restart, all slots return. --- src/helpers/bridges/MQTTBridge.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/helpers/bridges/MQTTBridge.cpp b/src/helpers/bridges/MQTTBridge.cpp index 6013a4dd7..579242e43 100644 --- a/src/helpers/bridges/MQTTBridge.cpp +++ b/src/helpers/bridges/MQTTBridge.cpp @@ -940,6 +940,21 @@ void MQTTBridge::begin() { _slots[i].enabled = false; } } + } else { + // Prefs say this slot is off. Without this the slot keeps whatever the previous + // begin() left in RAM, so a restart resurrects a broker the operator disabled and + // reconnects to it with the old credentials. teardownSlot() deliberately preserves + // enabled/preset, and the constructor only clears them once, so nothing else does. + // Config fields only: the client belongs to destroySlotClients() and the token + // buffer to releaseSlotAuthToken(), and clearing either here would strand a pointer + // esp-mqtt still holds. + _slots[i].enabled = false; + _slots[i].preset = nullptr; + _slots[i].host[0] = '\0'; + _slots[i].username[0] = '\0'; + _slots[i].password[0] = '\0'; + _slots[i].audience[0] = '\0'; + _slots[i].port = 0; } }