Skip to content

V2.4.14

Choose a tag to compare

@github-actions github-actions released this 19 May 09:43
· 291 commits to main since this release

Extend the V2.4.13 OTA-teardown pattern to FTPS uploads. Same fix, different trigger — stop MQTT before the upload to free its TLS session state.

Observation

Production logs from both Heltec V2 boards on V2.4.13 (2026-05-19 evening soak) showed the FTPS upload was the dominant heap consumer:

Heltec 4MB unit, cycle #6:
  Pre-upload:  free=68500 min_free=15572 largest=59392
  Post-upload: free=68288 min_free=1112  largest=59392   <-- 14 KB peak dip
Heltec 8MB unit, cycle #30 (FTPS server-side stall):
  Pre-upload:  free=68340 min_free=17080
  → 32 s TLS stall, write got 4096/43186 bytes through
  → PSA preemptive reset
  Post-upload: free=68876 min_free=3600
  → mqtt: errno=11 (EAGAIN), DISCONNECTED
  → 30 min of cascading MQTT handshake failures (-0x2700)

Even on successful uploads the min_free briefly dipped into single-digit-KB territory — one bad allocation away from OOM. On failed uploads (server stall) the MQTT TLS write paths hit EAGAIN as the kernel ran out of buffers, taking MQTT down with the FTPS attempt.

Fix

In log_ftp_loop, right before do_ftp_upload():

bool mqtt_was_running = mqtt_is_initialized();
if (mqtt_was_running) {
    ESP_LOGI(TAG, "FTPS prep: stopping MQTT to free TLS state");
    mqtt_stop();
}
bool ok = do_ftp_upload();

Main loop poll (!mqtt_is_initialized() && n_got_ip > 0 && ntp_time_valid()) re-inits MQTT within ~1 s of FTPS completion.

Expected impact on Heltec V2

  • min_free during FTPS upload: ~1 KB → ~40 KB
  • MQTT keep-alive failures during FTPS: eliminated
  • MQTT cascading reconnect storms after failed FTPS: eliminated

HA / broker behaviour during the FTPS window

mqtt_stop() sends a clean MQTT DISCONNECT packet, so the broker does NOT fire LWT (LWT only fires on abrupt disconnect / keep-alive timeout). The retained "online" availability message stays in place. HA sees the device as online continuously; subscribers just miss state publishes for the 5–30 s upload window (acceptable on a 150 s TX cadence). After upload, mqtt_init() reconnects, publishes "online" again (idempotent — same retained value), and republishes HA Discovery configs (idempotent — broker stores latest retained).

Frequency / retry interaction

FTPS schedule is 15 min by default (configurable). On failure, V2.3.15's 4-retry sequence ~3 min apart applies. Each retry teardown-and-restart-MQTT cycle:

  • ~3-5 s of MQTT publish silence per FTPS attempt
  • Worst case (1 + 4 retries = 5 attempts): 25 s cumulative MQTT silence over 15 min — still well below the 60 s keep-alive

For users who find this objectionable on FeatherS3-D (where the teardown isn't load-bearing), a future tag could heap-gate the teardown. Skipping for now — keeping the code path uniform across boards.

Code changes

  • main/log_ftp.c — #include "mqtt.h"; ~10 LOC teardown block before the do_ftp_upload() call. No other changes.

Recommendation

Safe to flash as a routine OTA update. Behaviour change is localised to FTPS upload start. No NVS / config-form / per-cycle TX path delta.