#include "fota_manager.h" #include #include "esp_log.h" #include "esp_system.h" #include "esp_ota_ops.h" #include "esp_partition.h" static const char *TAG = "FOTA_MANAGER"; fota_err_t fota_manager_apply(const char *firmware_path) { if (!firmware_path) { ESP_LOGE(TAG, "Firmware path is NULL"); return FOTA_ERR_OPEN; } ESP_LOGI(TAG, "Starting FOTA from file: %s", firmware_path); FILE *fp = fopen(firmware_path, "rb"); if (!fp) { ESP_LOGE(TAG, "Failed to open firmware file: %s", firmware_path); return FOTA_ERR_OPEN; } const esp_partition_t *running = esp_ota_get_running_partition(); if (!running) { ESP_LOGE(TAG, "Failed to get running partition"); fclose(fp); return FOTA_ERR_NO_UPDATE_PART; } ESP_LOGI(TAG, "Running partition: label=%s, addr=0x%lx, size=0x%lx", running->label, (unsigned long)running->address, (unsigned long)running->size); const esp_partition_t *update = esp_ota_get_next_update_partition(NULL); if (!update) { ESP_LOGE(TAG, "Failed to find update partition"); fclose(fp); return FOTA_ERR_NO_UPDATE_PART; } ESP_LOGI(TAG, "Update partition: label=%s, addr=0x%lx, size=0x%lx", update->label, (unsigned long)update->address, (unsigned long)update->size); esp_ota_handle_t ota_handle = 0; esp_err_t err = esp_ota_begin(update, OTA_SIZE_UNKNOWN, &ota_handle); if (err != ESP_OK) { ESP_LOGE(TAG, "esp_ota_begin failed: %s", esp_err_to_name(err)); fclose(fp); return FOTA_ERR_OTA_BEGIN; } uint8_t buffer[4096]; size_t read_bytes = 0; size_t total_written = 0; while ((read_bytes = fread(buffer, 1, sizeof(buffer), fp)) > 0) { err = esp_ota_write(ota_handle, buffer, read_bytes); if (err != ESP_OK) { ESP_LOGE(TAG, "esp_ota_write failed after %u bytes: %s", (unsigned)total_written, esp_err_to_name(err)); esp_ota_end(ota_handle); fclose(fp); return FOTA_ERR_OTA_WRITE; } total_written += read_bytes; } fclose(fp); ESP_LOGI(TAG, "FOTA written %u bytes to partition %s", (unsigned)total_written, update->label); err = esp_ota_end(ota_handle); if (err != ESP_OK) { ESP_LOGE(TAG, "esp_ota_end failed: %s", esp_err_to_name(err)); return FOTA_ERR_OTA_END; } err = esp_ota_set_boot_partition(update); if (err != ESP_OK) { ESP_LOGE(TAG, "esp_ota_set_boot_partition failed: %s", esp_err_to_name(err)); return FOTA_ERR_SET_BOOT; } ESP_LOGI(TAG, "FOTA apply success. Next boot from: label=%s, addr=0x%lx", update->label, (unsigned long)update->address); return FOTA_OK; }