#include // SDK #include "cJSON.h" #include "esp_http_server.h" #include "esp_littlefs.h" #include "esp_partition.h" // Project #include "appstate.hpp" #include "types.hpp" #include "utils.hpp" internal esp_err_t api_ota_status_handler(httpd_req_t *req) { httpd_resp_set_type(req, "application/json"); httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); cJSON *root = cJSON_CreateObject(); cJSON_AddNumberToObject(root, "active_slot", g_Active_WWW_Partition); constexpr const char *kPartitions[] = {"www_0", "www_1", "ota_0", "ota_1", "factory"}; constexpr size_t kPartitionCount = ArrayCount(kPartitions); cJSON *parts_arr = cJSON_AddArrayToObject(root, "partitions"); for (size_t i = 0; i < kPartitionCount; i++) { cJSON *p_obj = cJSON_CreateObject(); cJSON_AddStringToObject(p_obj, "label", kPartitions[i]); const esp_partition_t *p = esp_partition_find_first( ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, kPartitions[i]); if (p) { cJSON_AddNumberToObject(p_obj, "size", p->size); size_t total = 0, used = 0; if (esp_littlefs_info(kPartitions[i], &total, &used) == ESP_OK) { cJSON_AddNumberToObject(p_obj, "used", used); cJSON_AddNumberToObject(p_obj, "free", total - used); } else { // Not mounted or not LFS cJSON_AddNumberToObject(p_obj, "used", 0); cJSON_AddNumberToObject(p_obj, "free", p->size); } } cJSON_AddItemToArray(parts_arr, p_obj); } cJSON_AddStringToObject(root, "active_partition", g_Active_WWW_Partition == 0 ? "www_0" : "www_1"); cJSON_AddStringToObject(root, "target_partition", g_Active_WWW_Partition == 0 ? "www_1" : "www_0"); const char *status_info = cJSON_Print(root); httpd_resp_sendstr(req, status_info); free((void *)status_info); cJSON_Delete(root); return ESP_OK; } internal const httpd_uri_t api_ota_status_uri = {.uri = "/api/ota/status", .method = HTTP_GET, .handler = api_ota_status_handler, .user_ctx = NULL};