#include "esp_http_client.h" #include "esp_ota_ops.h" #include "esp_system.h" #include "esp_log.h" #include "ota.h" #include "sender_task.h" #include "sampler_task.h" #include "ws.h" #include "heartbeat_task.h" #include "fw_command.h" static TaskHandle_t ota_task_handle = nullptr; static char url_copy[256]; static char sha256[65]; void perform_ota(void* par) { esp_ota_handle_t ota_handle; uint8_t buf[1024]; int read_bytes; const esp_partition_t* partition = nullptr; const char* url = static_cast(par); esp_http_client_config_t config = {}; config.url = url; config.timeout_ms = 5000; config.buffer_size = 1024; esp_http_client_handle_t client = esp_http_client_init(&config); if (esp_http_client_open(client, 0) != ESP_OK) { goto cleanup; } partition = esp_ota_get_next_update_partition(nullptr); if (esp_ota_begin(partition, OTA_SIZE_UNKNOWN, &ota_handle) != ESP_OK) { goto cleanup; } while ((read_bytes = esp_http_client_read(client, (char*)buf, sizeof(buf))) > 0) { if (esp_ota_write(ota_handle, buf, read_bytes) != ESP_OK) { esp_ota_end(ota_handle); goto cleanup; } } if (esp_ota_end(ota_handle) == ESP_OK) { uint8_t hash[32]; if (esp_partition_get_sha256(partition, hash) != ESP_OK) { goto cleanup; } // переводим в hex char hash_str[65]; for (int i = 0; i < 32; i++) { sprintf(&hash_str[i * 2], "%02x", hash[i]); } hash_str[64] = '\0'; // сравнение if (strncmp(hash_str, sha256, 64) != 0) { printf("SHA256 mismatch!\n"); goto cleanup; } esp_ota_set_boot_partition(partition); esp_restart(); } cleanup: esp_http_client_cleanup(client); vTaskDelete(nullptr); ota_task_handle = nullptr; } void ota_task_start(const fw_cmd_t* cmd) { strncpy(url_copy, cmd->url, sizeof(url_copy)); strncpy(sha256, cmd->sha256, sizeof(sha256)); sampler_task_stop(); sender_task_stop(); heartbeat_task_stop(); ws_disconnect(); if (ota_task_handle == nullptr) { xTaskCreate( perform_ota, "ota", 4096, url_copy, 5, &ota_task_handle ); } } void ota_task_stop() { if (ota_task_handle != nullptr) { vTaskDelete(ota_task_handle); ota_task_handle = nullptr; } }