/
ellersseer
/
MyCheat
Обзор
Документация
Войти
/
ellersseer
/
MyCheat
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
2
CI/CD
Аналитика
Безопасность
master
src/ota_handler.cpp
131 строка
4 KB
Dmitry Zhiltsov
feat(logs): Добавить логи в WEB
20 фев 2026, 20:39
20 фев 2026, 20:39
dae6bcf
Код
Авторство
О чём код?
#include "ota_handler.h" #include "config.h" #include "log_buffer.h" #include <Arduino.h> #include <Update.h> #include "esp_ota_ops.h" #include "nvs.h" // NVS-based OTA state (survives across different firmware builds, // unlike RTC_DATA_ATTR which is address-dependent per binary) static void otaNvsWrite(uint8_t pending, uint8_t attempts) { nvs_handle_t handle; if (nvs_open("ota", NVS_READWRITE, &handle) != ESP_OK) return; nvs_set_u8(handle, "pending", pending); nvs_set_u8(handle, "attempts", attempts); nvs_commit(handle); nvs_close(handle); } static bool otaNvsRead(uint8_t *pending, uint8_t *attempts) { nvs_handle_t handle; if (nvs_open("ota", NVS_READONLY, &handle) != ESP_OK) return false; *pending = 0; *attempts = 0; nvs_get_u8(handle, "pending", pending); nvs_get_u8(handle, "attempts", attempts); nvs_close(handle); return true; } void checkOtaRollback() { uint8_t pending = 0, attempts = 0; if (!otaNvsRead(&pending, &attempts)) return; if (!pending) return; attempts++; otaNvsWrite(1, attempts); if (attempts > 3) { // 3 failed attempts — rollback to the other OTA partition const esp_partition_t *prev = esp_ota_get_next_update_partition(NULL); if (prev) { esp_ota_set_boot_partition(prev); } otaNvsWrite(0, 0); ESP.restart(); // Raw restart OK — no 1-Wire initialized yet } } void confirmOtaIfNeeded() { uint8_t pending = 0, attempts = 0; if (!otaNvsRead(&pending, &attempts)) return; if (!pending) return; esp_ota_mark_app_valid_cancel_rollback(); otaNvsWrite(0, 0); logCapture.println("[OTA] New firmware validated successfully!"); } void setupOtaRoutes(AsyncWebServer *server) { server->on( "/api/ota/upload", HTTP_POST, // onRequest — called after upload is complete [](AsyncWebServerRequest *request) { if (Update.hasError()) { String msg = Update.errorString(); String json = "{\"success\":false,\"error\":\"" + msg + "\"}"; request->send(400, "application/json", json); } else { request->send(200, "application/json", "{\"success\":true}"); // Mark OTA pending in NVS so rollback logic activates on next boot otaNvsWrite(1, 0); delay(500); safeRestart(); } }, // onUpload — called per chunk [](AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final) { if (index == 0) { logCapture.printf("[OTA] Upload start: %s\n", filename.c_str()); // Use content length if available, otherwise UPDATE_SIZE_UNKNOWN size_t contentLength = request->contentLength(); if (!Update.begin(contentLength != 0 ? contentLength : UPDATE_SIZE_UNKNOWN)) { logCapture.printf("[OTA] Begin failed: %s\n", Update.errorString()); } } if (Update.isRunning()) { if (Update.write(data, len) != len) { logCapture.printf("[OTA] Write failed: %s\n", Update.errorString()); } } if (final) { if (Update.end(true)) { logCapture.printf("[OTA] Upload complete: %u bytes\n", index + len); } else { logCapture.printf("[OTA] End failed: %s\n", Update.errorString()); } } }); }