fix(mqtt): clear a slot that preferences say is disabled on bridge start

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.
This commit is contained in:
agessaman committed 2026-08-19 08:38:00 -07:00
1 parent 25d035f80a
commit bd91ff80ea
1 file changed
+15
+15
View File
@@ -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;
}
}