The precompiled IDF 4.4 WebSocket transport (libtcp_transport.a) has an
off-by-one in ws_connect(): when a wss:// endpoint answers the upgrade
request with >=1024 bytes of HTTP response before the blank-line
terminator (typical of a down broker behind a proxy serving a large
error page), it writes a NUL one byte past the 1024-byte ws->buffer.
Heap poisoning catches the clobbered tail canary (0xbaad5678 ->
0xbaad5600) only when the block is freed in ws_destroy() during
esp_mqtt_client_destroy() - i.e. MQTTBridge::end() - so a single down
broker made every deferred 'ota update' panic and reboot at teardown,
before the download started. Decoded from a Heltec V3 crash backtrace
on v1.16.0.11; line numbers match ESP-IDF release/v4.4 exactly.
The transport code ships precompiled, so patch at link time instead:
[esp32_base] wraps esp_transport_ws_init and the wrapper swaps the
fresh buffer for a (WS_BUFFER_SIZE + 1)-byte allocation, making the
out-of-bounds index land on owned memory. The oversized handshake then
fails cleanly instead of corrupting the heap. Pass-through on IDF 5.x,
where upstream already fixed it; delete with the Arduino core 3.x move.
Verified: wrap resolves from ESP32WsTransportFix.cpp.o in the observer
firmware.map; observer, room-server observer and plain repeater ESP32
targets build. RAK_4631_repeater failure is pre-existing (reproduced
on the merge base without these changes).
The unknown-version path kept defaults at boot but any later savePrefs()
(every CLI set command) rewrote /mqtt_prefs as v1 with defaults, destroying
the newer config after a firmware downgrade. Latch _mqtt_prefs_hold when an
unsupported version is seen and refuse to write while it is set — checked
before the NRF52/STM32 open path, which deletes the file first.
Also pin the frozen legacy /mqtt_prefs layouts (472/1464/2904 bytes + 8-byte
header) with static_asserts so every target build re-verifies the deployed
fleet's file offsets, and null-check _obs in AlertReporter::onLoop.
Refactored the handling of observer-related settings by moving them from
NodePrefs to a new MQTTPrefs structure. This change centralizes MQTT,
WiFi, timezone, SNMP, and alert configurations, improving code organization
and maintainability. The new structure allows for better separation of
concerns and prepares the codebase for future enhancements.
Updated the alert PSK implementation to remove base64 support, now requiring a 32-character hex format for private channel secrets. Adjusted related CLI commands, error messages, and internal handling to ensure consistency with the new format. This change enhances clarity and aligns with the mobile app's "Share Channel" output. Relevant updates made across multiple files, including documentation and preference handling.
Modified the sendFlood method in AlertReporter to incorporate path hash size, ensuring compatibility with the repeater's configured path.hash.mode. This change enhances the handling of alert floods by accommodating different regional mesh configurations.
Updated the fault alert functionality to include an optional region name for scoping alert floods, allowing operators to override the default scope. Introduced a list of banned channels (e.g., Public PSK, `#test`, `#bot`) to prevent spamming community channels with alerts. The implementation ensures that alerts are only sent to private PSKs or non-banned hashtags. Relevant changes were made across multiple files, including updates to the CLI for setting and retrieving the new `alert.region` preference.
Implemented a new fault alert system that broadcasts notifications over LoRa when WiFi or MQTT connections are down for a specified duration. The alerts are configurable via CLI commands, allowing operators to set private PSKs or hashtags for alert channels. Default settings for alert thresholds and intervals are established, and the system ensures that alerts do not spam the public channel. Updated relevant files to integrate this feature into the MyMesh implementations and CLI handling.