From df171560db2e8602fd358958f5ff3326be9745b5 Mon Sep 17 00:00:00 2001 From: jpirnay Date: Tue, 21 Apr 2026 17:16:19 +0200 Subject: [PATCH] Fix firmware download --- src/activities/settings/OtaUpdateActivity.cpp | 32 +++++++++++++++++++ src/activities/settings/OtaUpdateActivity.h | 1 + src/network/OtaUpdater.cpp | 9 +++++- src/network/OtaUpdater.h | 5 ++- 4 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/activities/settings/OtaUpdateActivity.cpp b/src/activities/settings/OtaUpdateActivity.cpp index 716f8c0f..943abd6e 100644 --- a/src/activities/settings/OtaUpdateActivity.cpp +++ b/src/activities/settings/OtaUpdateActivity.cpp @@ -31,6 +31,7 @@ void OtaUpdateActivity::onWifiSelectionComplete(const bool success) { LOG_DBG("OTA", "Update check failed: %d", res); { RenderLock lock(*this); + failureReason = res; state = FAILED; } return; @@ -126,6 +127,35 @@ void OtaUpdateActivity::render(RenderLock&&) { GUI.drawButtonHints(renderer, labels.btn1, labels.btn2, labels.btn3, labels.btn4); } else if (state == FAILED) { renderer.drawCenteredText(UI_10_FONT_ID, top, tr(STR_UPDATE_FAILED), true, EpdFontFamily::BOLD); + const char* reason = ""; + switch (failureReason) { + case OtaUpdater::HTTP_ERROR: + reason = "Network error (HTTP request failed)"; + break; + case OtaUpdater::JSON_PARSE_ERROR: + reason = "Could not parse release info"; + break; + case OtaUpdater::UPDATE_OLDER_ERROR: + reason = "Available version is not newer"; + break; + case OtaUpdater::OOM_ERROR: + reason = "Out of memory"; + break; + case OtaUpdater::INTERNAL_UPDATE_ERROR: + reason = "Internal update error"; + break; + case OtaUpdater::NO_UPDATE: + reason = "No firmware asset found"; + break; + case OtaUpdater::VALIDATE_FAILED: + reason = "Image validation failed - please flash via USB"; + break; + default: + break; + } + if (reason[0] != '\0') { + renderer.drawCenteredText(SMALL_FONT_ID, top + height + metrics.verticalSpacing, reason); + } const auto labels = mappedInput.mapLabels(tr(STR_BACK), "", "", ""); GUI.drawButtonHints(renderer, labels.btn1, labels.btn2, labels.btn3, labels.btn4); } else if (state == FINISHED) { @@ -151,6 +181,7 @@ void OtaUpdateActivity::loop() { LOG_DBG("OTA", "Update begin failed: %d", beginResult); { RenderLock lock(*this); + failureReason = beginResult; state = FAILED; } requestUpdate(); @@ -205,6 +236,7 @@ void OtaUpdateActivity::loop() { LOG_DBG("OTA", "Update failed: %d", res); { RenderLock lock(*this); + failureReason = res; state = FAILED; } requestUpdate(); diff --git a/src/activities/settings/OtaUpdateActivity.h b/src/activities/settings/OtaUpdateActivity.h index 12afc80d..afd26d2b 100644 --- a/src/activities/settings/OtaUpdateActivity.h +++ b/src/activities/settings/OtaUpdateActivity.h @@ -21,6 +21,7 @@ class OtaUpdateActivity : public Activity { State state = WIFI_SELECTION; unsigned int lastUpdaterPercentage = UNINITIALIZED_PERCENTAGE; OtaUpdater updater; + OtaUpdater::OtaUpdaterError failureReason = OtaUpdater::OK; void onWifiSelectionComplete(bool success); diff --git a/src/network/OtaUpdater.cpp b/src/network/OtaUpdater.cpp index 5f53cbec..cdd1f293 100644 --- a/src/network/OtaUpdater.cpp +++ b/src/network/OtaUpdater.cpp @@ -52,14 +52,18 @@ esp_err_t event_handler(esp_http_client_event_t* event) { } /* namespace */ OtaUpdater::OtaUpdaterError OtaUpdater::checkForUpdate() { + // Reset globals so retries start clean regardless of previous outcome + local_buf = nullptr; + output_len = 0; + JsonDocument filter; esp_err_t esp_err; JsonDocument doc; esp_http_client_config_t client_config = { .url = latestReleaseUrl, - .event_handler = event_handler, .timeout_ms = 10000, + .event_handler = event_handler, /* Default HTTP client buffer size 512 byte only */ .buffer_size = 8192, .buffer_size_tx = 8192, @@ -282,6 +286,9 @@ OtaUpdater::OtaUpdaterError OtaUpdater::performInstallUpdateStep() { if (finish_err != ESP_OK) { LOG_ERR("OTA", "esp_https_ota_finish Failed: %s", esp_err_to_name(finish_err)); cleanupUpdate(); + if (finish_err == ESP_ERR_OTA_VALIDATE_FAILED) { + return VALIDATE_FAILED; + } return INTERNAL_UPDATE_ERROR; } diff --git a/src/network/OtaUpdater.h b/src/network/OtaUpdater.h index e627cf7e..8a24d17b 100644 --- a/src/network/OtaUpdater.h +++ b/src/network/OtaUpdater.h @@ -3,7 +3,9 @@ #include #include -#include "esp_https_ota.h" +// Avoid pulling in esp_https_ota.h here — it transitively includes lwip/sockets.h +// which defines INADDR_NONE as a numeric macro, conflicting with Arduino's IPAddress.h. +typedef void* esp_https_ota_handle_t; class OtaUpdater { bool updateAvailable = false; @@ -27,6 +29,7 @@ class OtaUpdater { OOM_ERROR, UPDATE_CANCELLED, UPDATE_IN_PROGRESS, + VALIDATE_FAILED, }; size_t getOtaSize() const { return otaSize; }