#include "web_server_pages.h" #include "esp_log.h" #include "esp_ota_ops.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include static const char *TAG = "SYS_WEB_OTA"; static void reboot_task(void *arg) { (void)arg; vTaskDelay(pdMS_TO_TICKS(1000)); esp_restart(); } static const char OTA_HTML[] = "" "" "ABrobot OTA Firmware Update" "" "
" "
" "
" "
" "
ESP32-C3 Firmware Update
" "
" " " "
" "
" "
Over-The-Air FlasherOTA 2.0 Engine
" "
" " " "
" "
⚡
" "
Click or Drag & Drop Firmware Image (.bin)
" "
Select the compiled application binary file to flash to ESP32-C3
" "
" "
" "
" " firmware.bin" " 0 KB" "
" " " "
" "
" "
" " Uploading binary..." " 0 KB / 0 KB" "
" "
" "
" "
0%
" "
" "
" " " "
" "
" "
" "
" "
OTA Safety Checklist
" "
" "
Dual PartitionSafe rollback on boot failure
" "
Flash VerificationSHA-256 & image headers verified
" "
Power NoticeDo not remove power during flash
" "
Auto RestartReboots automatically after install
" "
" "
" "
" ""; static esp_err_t ota_get(httpd_req_t *request) { httpd_resp_set_type(request, "text/html"); return httpd_resp_send(request, OTA_HTML, HTTPD_RESP_USE_STRLEN); } static esp_err_t ota_post(httpd_req_t *request) { const esp_partition_t *partition = esp_ota_get_next_update_partition(NULL); if (!partition || request->content_len == 0 || request->content_len > partition->size) return httpd_resp_send_err(request, HTTPD_400_BAD_REQUEST, "Firmware image is too large or unavailable"); esp_ota_handle_t handle; esp_err_t err = esp_ota_begin(partition, request->content_len, &handle); if (err != ESP_OK) return httpd_resp_send_err(request, HTTPD_500_INTERNAL_SERVER_ERROR, "Could not begin firmware update"); uint8_t *buffer = malloc(4096); if (!buffer) { esp_ota_abort(handle); return httpd_resp_send_err(request, HTTPD_500_INTERNAL_SERVER_ERROR, "Not enough memory"); } size_t remaining = request->content_len; while (remaining) { size_t requested = remaining < 4096 ? remaining : 4096; int received = httpd_req_recv(request, (char *)buffer, requested); if (received <= 0 || esp_ota_write(handle, buffer, received) != ESP_OK) { free(buffer); esp_ota_abort(handle); return httpd_resp_send_err(request, HTTPD_400_BAD_REQUEST, "Firmware upload failed"); } remaining -= (size_t)received; } free(buffer); err = esp_ota_end(handle); if (err == ESP_OK) err = esp_ota_set_boot_partition(partition); if (err != ESP_OK) return httpd_resp_send_err(request, HTTPD_400_BAD_REQUEST, "Invalid firmware image"); httpd_resp_sendstr(request, "Firmware update installed. Rebooting."); ESP_LOGI(TAG, "OTA image installed to %s; rebooting", partition->label); xTaskCreate(reboot_task, "ota_reboot", 2048, NULL, 5, NULL); return ESP_OK; } void web_server_register_ota_page(httpd_handle_t server) { const httpd_uri_t page = {.uri = "/ota", .method = HTTP_GET, .handler = ota_get}; const httpd_uri_t upload = {.uri = "/ota", .method = HTTP_POST, .handler = ota_post}; httpd_register_uri_handler(server, &page); httpd_register_uri_handler(server, &upload); }