93 lines
2.8 KiB
C
93 lines
2.8 KiB
C
#include "fota_manager.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
#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;
|
|
}
|