espilon-source/espilon_bot/components/mod_ota/cmd_ota.c
Eun0us 6d45770d98 epsilon: merge command system into core + add 5 new modules
Move command registry from components/command/ into components/core/.
New modules: mod_canbus, mod_honeypot, mod_fallback, mod_redteam, mod_ota.
Replace mod_proxy with tun_core (multiplexed SOCKS5 tunnel).
Kconfig extended with per-module settings and async worker config.
2026-02-28 20:07:59 +01:00

160 lines
4.2 KiB
C

/*
* cmd_ota.c
* OTA firmware update commands (HTTPS + cert bundle)
* Compiled as empty when CONFIG_ESPILON_OTA_ENABLED is not set.
*/
#include "sdkconfig.h"
#ifdef CONFIG_ESPILON_OTA_ENABLED
#include <stdio.h>
#include <string.h>
#include "esp_log.h"
#include "esp_system.h"
#include "esp_ota_ops.h"
#include "esp_https_ota.h"
#include "esp_http_client.h"
#include "esp_crt_bundle.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "utils.h"
#define TAG "OTA"
/* ============================================================
* COMMAND: ota_update <url> (async)
* ============================================================ */
static esp_err_t cmd_ota_update(
int argc,
char **argv,
const char *req,
void *ctx
) {
(void)ctx;
const char *url = argv[0];
char buf[256];
snprintf(buf, sizeof(buf), "url=%s", url);
msg_info(TAG, buf, req);
esp_http_client_config_t http_config = {
.url = url,
#ifdef CONFIG_ESPILON_OTA_ALLOW_HTTP
.skip_cert_common_name_check = true,
#else
.crt_bundle_attach = esp_crt_bundle_attach,
#endif
.timeout_ms = 30000,
.keep_alive_enable = true,
};
esp_https_ota_config_t ota_config = {
.http_config = &http_config,
};
esp_https_ota_handle_t ota_handle = NULL;
esp_err_t err = esp_https_ota_begin(&ota_config, &ota_handle);
if (err != ESP_OK) {
snprintf(buf, sizeof(buf), "begin_failed=%s", esp_err_to_name(err));
msg_error(TAG, buf, req);
return err;
}
int total_size = esp_https_ota_get_image_size(ota_handle);
int last_pct = -1;
while (1) {
err = esp_https_ota_perform(ota_handle);
if (err != ESP_ERR_HTTPS_OTA_IN_PROGRESS) break;
if (total_size > 0) {
int bytes_read = esp_https_ota_get_image_len_read(ota_handle);
int pct = (bytes_read * 100) / total_size;
if (pct / 10 != last_pct / 10) {
last_pct = pct;
snprintf(buf, sizeof(buf), "progress=%d%%", pct);
msg_info(TAG, buf, req);
}
}
}
if (err != ESP_OK) {
snprintf(buf, sizeof(buf), "download_failed=%s", esp_err_to_name(err));
msg_error(TAG, buf, req);
esp_https_ota_abort(ota_handle);
return err;
}
err = esp_https_ota_finish(ota_handle);
if (err != ESP_OK) {
if (err == ESP_ERR_OTA_VALIDATE_FAILED) {
msg_error(TAG, "validate_failed=image_corrupted", req);
} else {
snprintf(buf, sizeof(buf), "finish_failed=%s", esp_err_to_name(err));
msg_error(TAG, buf, req);
}
return err;
}
msg_info(TAG, "status=success rebooting=true", req);
vTaskDelay(pdMS_TO_TICKS(500));
esp_restart();
return ESP_OK;
}
/* ============================================================
* COMMAND: ota_status
* ============================================================ */
static esp_err_t cmd_ota_status(
int argc,
char **argv,
const char *req,
void *ctx
) {
(void)argc;
(void)argv;
(void)ctx;
const esp_partition_t *running = esp_ota_get_running_partition();
const esp_partition_t *boot = esp_ota_get_boot_partition();
esp_app_desc_t app_desc;
esp_ota_get_partition_description(running, &app_desc);
char buf[256];
snprintf(buf, sizeof(buf),
"partition=%s boot=%s version=%s idf=%s",
running ? running->label : "?",
boot ? boot->label : "?",
app_desc.version,
app_desc.idf_ver
);
msg_info(TAG, buf, req);
return ESP_OK;
}
/* ============================================================
* COMMAND REGISTRATION
* ============================================================ */
static const command_t ota_cmds[] = {
{ "ota_update", NULL, "OTA update from HTTPS URL", 1, 1, cmd_ota_update, NULL, true },
{ "ota_status", NULL, "Current firmware info", 0, 0, cmd_ota_status, NULL, false },
};
void mod_ota_register_commands(void)
{
ESPILON_LOGI_PURPLE(TAG, "Registering OTA commands");
for (size_t i = 0; i < sizeof(ota_cmds) / sizeof(ota_cmds[0]); i++) {
command_register(&ota_cmds[i]);
}
}
#endif /* CONFIG_ESPILON_OTA_ENABLED */