Files
iot_skeleton/esp32/main/ota.cpp
2026-04-24 16:37:04 +03:00

117 lines
2.5 KiB
C++

#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<const char*>(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;
}
}