From 4a6fe4e2be812fe5b04ecbc581874f667b91e5ed Mon Sep 17 00:00:00 2001 From: agessaman Date: Sun, 19 Jul 2026 08:02:29 -0700 Subject: [PATCH] fix(mqtt): use ASCII hyphens in serial log strings UTF-8 em-dashes (U+2014) inside MQTT_DEBUG_PRINTLN / CLI reply strings render as mojibake ("aEUR"-style, e.g. cooperative stop garbles) on consoles that don't decode UTF-8. Replace the em-dashes in printed strings with ASCII '-'. Comments are intentionally left unchanged (they never reach the console; rewriting them would be needless churn in a merge-sensitive file). Verified on V3: the stop message now emits pure ASCII -- zero non-ASCII bytes in the boot+stop console capture. --- src/helpers/CommonCLI_Observer.cpp | 2 +- src/helpers/bridges/MQTTBridge.cpp | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/helpers/CommonCLI_Observer.cpp b/src/helpers/CommonCLI_Observer.cpp index 4023413b..8e7c5426 100644 --- a/src/helpers/CommonCLI_Observer.cpp +++ b/src/helpers/CommonCLI_Observer.cpp @@ -785,7 +785,7 @@ bool CommonCLI::handleObserverGetCmd(uint32_t sender_timestamp, const char* conf if (_mqtt_prefs.mqtt_slot_audience[slot][0] != '\0') { sprintf(reply, "> %s", _mqtt_prefs.mqtt_slot_audience[slot]); } else { - strcpy(reply, "> (not set — custom slots use username/password auth)"); + strcpy(reply, "> (not set - custom slots use username/password auth)"); } } else if (memcmp(subcmd, "diag", 4) == 0) { MQTTBridge::formatSlotDiagReply(reply, 160, slot); diff --git a/src/helpers/bridges/MQTTBridge.cpp b/src/helpers/bridges/MQTTBridge.cpp index 4bc30664..4a9f1120 100644 --- a/src/helpers/bridges/MQTTBridge.cpp +++ b/src/helpers/bridges/MQTTBridge.cpp @@ -661,7 +661,7 @@ void MQTTBridge::begin() { // would re-run allocation and re-create the task, leaking the previous // queue/task. Guard here instead of relying on caller discipline. if (_initialized) { - MQTT_DEBUG_PRINTLN("MQTT Bridge already running — begin() ignored"); + MQTT_DEBUG_PRINTLN("MQTT Bridge already running - begin() ignored"); return; } @@ -910,7 +910,7 @@ void MQTTBridge::end() { // Idempotent stop: nothing to tear down if we never started (or already stopped). if (!_initialized) { - MQTT_DEBUG_PRINTLN("MQTT Bridge already stopped — end() ignored"); + MQTT_DEBUG_PRINTLN("MQTT Bridge already stopped - end() ignored"); return; } @@ -966,7 +966,7 @@ void MQTTBridge::end() { _initialized = false; _slots_setup_done = false; // Reset so deferred setup runs again on next begin() MQTT_DEBUG_PRINTLN("MQTT Bridge stopped (%s)", - _lifecycle.stopTimedOut() ? "forced/timeout — OTA blocked" : "clean"); + _lifecycle.stopTimedOut() ? "forced/timeout - OTA blocked" : "clean"); } // --------------------------------------------------------------------------- @@ -1148,7 +1148,7 @@ void MQTTBridge::mqttTaskLoop() { // this teardown has completed, then self-terminate via the mqttTask() // trampoline (vTaskDelete(nullptr)). if (_stop_requested) { - MQTT_DEBUG_PRINTLN("MQTT task: cooperative stop — tearing down clients on Core 0"); + MQTT_DEBUG_PRINTLN("MQTT task: cooperative stop - tearing down clients on Core 0"); for (int i = 0; i < RUNTIME_MQTT_SLOTS; i++) { teardownSlot(i); } @@ -1256,7 +1256,7 @@ void MQTTBridge::mqttTaskLoop() { } char reason[80]; if (!isSlotReady(i, reason, sizeof(reason))) { - MQTT_DEBUG_PRINTLN("MQTT%d not ready — run '%s' to connect", i + 1, reason); + MQTT_DEBUG_PRINTLN("MQTT%d not ready - run '%s' to connect", i + 1, reason); continue; } setupSlot(i); @@ -1498,7 +1498,7 @@ void MQTTBridge::setupSlot(int index) { // Persistent client is expected to have been allocated by initSlotClients(). // If it hasn't, we can't proceed — bail loudly rather than silently leaking. if (slot.client == nullptr) { - MQTT_DEBUG_PRINTLN("MQTT%d: setupSlot before initSlotClients() — skipping", index + 1); + MQTT_DEBUG_PRINTLN("MQTT%d: setupSlot before initSlotClients() - skipping", index + 1); return; } @@ -2270,7 +2270,7 @@ void MQTTBridge::applySlotPreset(int slot_index, const char* preset_name) { if (_initialized) { char reason[80]; if (!isSlotReady(slot_index, reason, sizeof(reason))) { - MQTT_DEBUG_PRINTLN("MQTT%d (%s) not ready — run '%s' to connect", slot_index + 1, preset_name, reason); + MQTT_DEBUG_PRINTLN("MQTT%d (%s) not ready - run '%s' to connect", slot_index + 1, preset_name, reason); return; } setupSlot(slot_index); @@ -2301,7 +2301,7 @@ void MQTTBridge::checkConfigurationMismatch() { if (_obs->mqtt_packets_enabled && !_obs->mqtt_rx_enabled && _obs->mqtt_tx_enabled == 0) { unsigned long now = millis(); if (_last_config_warning == 0 || (now - _last_config_warning > CONFIG_WARNING_INTERVAL)) { - MQTT_DEBUG_PRINTLN("MQTT: Both mqtt.rx and mqtt.tx are off — no packets will be published. Run 'set mqtt.rx on' or 'set mqtt.tx on' to fix."); + MQTT_DEBUG_PRINTLN("MQTT: Both mqtt.rx and mqtt.tx are off - no packets will be published. Run 'set mqtt.rx on' or 'set mqtt.tx on' to fix."); _last_config_warning = now; } } else {