feat(mqtt): clarify custom endpoint requirements in code and documentation

Updated MQTT configuration to succeed when port is defined in mqttN.server but not explicitly set in mqttN.port. Updated documentation to specify that when a full
URL with a scheme is provided, the port setting is optional. Added an
example for local development using a plain WebSocket URL, enhancing
clarity for users configuring custom MQTT brokers.
This commit is contained in:
agessaman committed 2026-07-06 12:34:53 -07:00
1 parent 706d1c7ea2
commit 7e0ffdbea3
2 files changed
+22 -3

No files matched your search

+13 -1
View File
@@ -328,10 +328,11 @@ For community brokers that support the MeshCore JWT auth protocol (same as the b
```bash
set mqtt3.preset custom
set mqtt3.server wss://my-broker.example.com:443/mqtt
set mqtt3.port 443
set mqtt3.audience my-broker.example.com
```
When the server is given as a full URL with a scheme (`mqtt://`, `mqtts://`, `ws://`, `wss://`), `set mqttN.port` is optional — an explicit port in the URL is used as-is, and without one the scheme's default port applies.
When `audience` is set, the device will:
- Connect with username `v1_{PUBLIC_KEY}` and an Ed25519-signed JWT as the password
- Automatically renew tokens before expiry (default 24h lifetime)
@@ -342,6 +343,17 @@ To revert a slot back to username/password auth, clear the audience:
set mqtt3.audience
```
#### Example: Local Development Broker (plain WebSocket, no TLS)
For local development (e.g. a LAN broker without SSL termination), use a full `ws://` URL. Non-TLS transports (`ws://`, `mqtt://`) skip certificate verification entirely:
```bash
set mqtt3.preset custom
set mqtt3.server ws://192.168.1.50:9001/mqtt
set mqtt3.audience my-local-broker
```
The `audience` line is optional — set it if your local broker uses the same JWT auth as the production presets, or use `set mqtt3.username` / `set mqtt3.password` instead.
#### Example: Custom Broker with Custom Topic Template
```bash
set mqtt3.preset custom
+9 -2
View File
@@ -107,13 +107,20 @@ static bool isWiFiConfigValid(const NodePrefs* prefs) {
#ifdef WITH_MQTT_BRIDGE
// A custom slot endpoint is complete if a port is set, or if the host is a
// full URI with a scheme (esp-mqtt applies scheme default ports, and the URI
// builder in setupSlot() preserves any embedded port/path).
static bool customEndpointComplete(const char* host, uint16_t port) {
return host[0] != '\0' && (port != 0 || strstr(host, "://") != nullptr);
}
bool MQTTBridge::isConfigValid(const NodePrefs* prefs) {
if (!prefs || !isWiFiConfigValid(prefs)) return false;
for (int i = 0; i < RUNTIME_MQTT_SLOTS; i++) {
const char* preset_name = prefs->mqtt_slot_preset[i];
if (preset_name[0] == '\0' || strcmp(preset_name, MQTT_PRESET_NONE) == 0) continue;
if (strcmp(preset_name, MQTT_PRESET_CUSTOM) == 0) {
if (prefs->mqtt_slot_host[i][0] != '\0' && prefs->mqtt_slot_port[i] != 0) return true;
if (customEndpointComplete(prefs->mqtt_slot_host[i], prefs->mqtt_slot_port[i])) return true;
} else if (findMQTTPreset(preset_name) != nullptr) {
return true;
}
@@ -1925,7 +1932,7 @@ void MQTTBridge::applySlotPreset(int slot_index, const char* preset_name) {
slot.enabled = true;
slot.preset = nullptr;
// Custom broker settings should already be set via setSlotCustomBroker
if (_initialized && strlen(slot.host) > 0 && slot.port > 0) {
if (_initialized && customEndpointComplete(slot.host, slot.port)) {
setupSlot(slot_index);
}
return;