#pragma once #include // Firmware update over WiFi (Menu > System > "Check for update") - // checks against the latest version in a private Gitea repository (Releases API) and // installs it on the device directly upon confirmation, without cable/ // web flasher. Blocking, synchronous HTTPS calls - only executed on // explicit button press (no background polling), analogous to // AircraftDetails' model/route queries, just on Core 1 instead of // Core 0, since it reacts directly to user interaction. namespace OtaUpdate { enum class CheckResult { Error, UpToDate, UpdateAvailable }; struct CheckInfo { CheckResult result = CheckResult::Error; // Latest available version WITHOUT "v" prefix (e.g. "3.5.0") - // set for both UpToDate and UpdateAvailable, so // the calling screen can display it in both cases. char latestVersion[16] = {0}; // Direct download link to the firmware.bin of the release - only // set when result == UpdateAvailable. char downloadUrl[192] = {0}; }; // Queries the Gitea Releases API for the latest release, compares // its version number (tag name, "v" prefix is ignored) against // Config::APP_VERSION and looks for the "firmware.bin" attachment in the release. // CheckResult::Error on any error along the way (no WiFi, timeout, // unexpected JSON, no firmware.bin in the release). CheckInfo checkForUpdate(); // Downloads the firmware.bin from 'url' and flashes it (via the // standard Arduino HTTPUpdate library). Intentionally does NOT call // ESP.restart() itself on success - the caller shows a // brief success message first and then restarts itself. onProgress // is called repeatedly during download with 0-100 (percent) // (may be nullptr). Returns false if download or flash // process fails - the device continues running unchanged with // the previous firmware in that case. bool performUpdate(const char* url, void (*onProgress)(uint8_t percent)); }