From 3eacf56e369b5362c83dd1dcf833a95f22700a2e Mon Sep 17 00:00:00 2001 From: agessaman Date: Fri, 27 Mar 2026 15:20:54 -0700 Subject: [PATCH] Update MQTT presets to add 'meshomatic' and enhance error handling in MQTTBridge. Modify custom preset logic to disable slots with no server configured, and improve error logging for connection issues, ensuring clearer diagnostics during MQTT operations. --- src/helpers/MQTTPresets.h | 3 ++- src/helpers/bridges/MQTTBridge.cpp | 23 +++++++++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/helpers/MQTTPresets.h b/src/helpers/MQTTPresets.h index 2b91cbe0b..1a461bd20 100644 --- a/src/helpers/MQTTPresets.h +++ b/src/helpers/MQTTPresets.h @@ -87,7 +87,7 @@ static const char ISRG_ROOT_X1[] PROGMEM = "-----END CERTIFICATE-----\n"; // Number of built-in presets -static const int MQTT_PRESET_COUNT = 6; +static const int MQTT_PRESET_COUNT = 7; // Built-in preset definitions (stored in flash) static const MQTTPresetDef MQTT_PRESETS[MQTT_PRESET_COUNT] = { @@ -96,6 +96,7 @@ static const MQTTPresetDef MQTT_PRESETS[MQTT_PRESET_COUNT] = { { "meshmapper", "wss://mqtt.meshmapper.cc:443/mqtt", "mqtt.meshmapper.cc", ISRG_ROOT_X1, MQTT_AUTH_JWT, MQTT_TOPIC_MESHCORE, 0, true, 55 }, { "meshrank", "mqtts://meshrank.net:8883", nullptr, ISRG_ROOT_X1, MQTT_AUTH_NONE, MQTT_TOPIC_MESHRANK, 0, false, 0 }, { "waev", "wss://mqtt.waev.app:443/mqtt", "mqtt.waev.app", GTS_ROOT_R4, MQTT_AUTH_JWT, MQTT_TOPIC_MESHCORE, 3300, false, 55 }, + { "meshomatic", "wss://us-east.meshomatic.net:443/mqtt", "us-east.meshomatic.net", ISRG_ROOT_X1, MQTT_AUTH_JWT, MQTT_TOPIC_MESHCORE, 0, true, 55 }, { "cascadiamesh", "mqtt://cascadiamesh.ddns.net:1883", nullptr, nullptr, MQTT_AUTH_NONE, MQTT_TOPIC_MESHCORE, 0, true, 0 }, }; diff --git a/src/helpers/bridges/MQTTBridge.cpp b/src/helpers/bridges/MQTTBridge.cpp index 65a12d453..f4e2e5fa8 100644 --- a/src/helpers/bridges/MQTTBridge.cpp +++ b/src/helpers/bridges/MQTTBridge.cpp @@ -327,10 +327,15 @@ void MQTTBridge::begin() { if (preset_name[0] != '\0' && strcmp(preset_name, MQTT_PRESET_NONE) != 0) { if (strcmp(preset_name, MQTT_PRESET_CUSTOM) == 0) { // Custom broker: copy host/port/username/password from prefs - _slots[i].enabled = true; _slots[i].preset = nullptr; strncpy(_slots[i].host, _prefs->mqtt_slot_host[i], sizeof(_slots[i].host) - 1); _slots[i].host[sizeof(_slots[i].host) - 1] = '\0'; + if (strlen(_slots[i].host) == 0) { + MQTT_DEBUG_PRINTLN("MQTT%d: custom preset has no server configured, disabling", i + 1); + _slots[i].enabled = false; + continue; + } + _slots[i].enabled = true; _slots[i].port = _prefs->mqtt_slot_port[i]; strncpy(_slots[i].username, _prefs->mqtt_slot_username[i], sizeof(_slots[i].username) - 1); _slots[i].username[sizeof(_slots[i].username) - 1] = '\0'; @@ -807,7 +812,13 @@ void MQTTBridge::setupSlot(int index) { updateCachedConnectionStatus(); }); slot.client->onError([this, index](esp_mqtt_error_codes error) { - MQTT_DEBUG_PRINTLN("MQTT%d error: %d", index + 1, error.esp_tls_last_esp_err); + if (error.esp_tls_last_esp_err != 0 || error.esp_tls_stack_err != 0 || error.esp_transport_sock_errno != 0) { + MQTT_DEBUG_PRINTLN("MQTT%d error: tls=%d, tls_stack=%d, sock=%d, type=%d", + index + 1, error.esp_tls_last_esp_err, error.esp_tls_stack_err, + error.esp_transport_sock_errno, error.error_type); + } else { + MQTT_DEBUG_PRINTLN("MQTT%d error: type=%d", index + 1, error.error_type); + } }); if (slot.preset) { @@ -850,6 +861,14 @@ void MQTTBridge::setupSlot(int index) { snprintf(slot.broker_uri, sizeof(slot.broker_uri), "%s://%s:%d", proto, slot.host, slot.port); } slot.client->setServer(slot.broker_uri); + + // Custom TLS/WSS slots need the system CA cert bundle for server verification + bool needs_tls = (strncmp(slot.broker_uri, "mqtts://", 8) == 0 || + strncmp(slot.broker_uri, "wss://", 6) == 0); + if (needs_tls) { + slot.client->attachArduinoCACertBundle(true); + } + if (strlen(slot.username) > 0) { slot.client->setCredentials(slot.username, slot.password); }