|
|
|
@@ -16,7 +16,11 @@
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
|
|
#include "domain.h"
|
|
|
|
|
#include "esp_app_desc.h"
|
|
|
|
|
#include "esp_core_dump.h"
|
|
|
|
|
#include "esp_heap_caps.h"
|
|
|
|
|
#include "esp_log.h"
|
|
|
|
|
#include "esp_system.h"
|
|
|
|
|
#include "esp_timer.h"
|
|
|
|
|
#include "freertos/FreeRTOS.h"
|
|
|
|
|
#include "freertos/task.h"
|
|
|
|
@@ -76,7 +80,7 @@
|
|
|
|
|
|
|
|
|
|
#define REMOTE_LOG_TASK_STACK_SIZE (1024 * 8)
|
|
|
|
|
#define REMOTE_LOG_TASK_PRIORITY 3
|
|
|
|
|
#define REMOTE_LOG_DIR "/littlefs/remote_logs"
|
|
|
|
|
#define REMOTE_LOG_DIR "/logfs/remote_logs"
|
|
|
|
|
#define REMOTE_LOG_FILE_PREFIX "log_"
|
|
|
|
|
#define REMOTE_LOG_FILE_SUFFIX ".jsonl"
|
|
|
|
|
#define REMOTE_LOG_PATH_MAX 96
|
|
|
|
@@ -104,6 +108,16 @@ static volatile bool s_stop_requested;
|
|
|
|
|
static portMUX_TYPE s_lock = portMUX_INITIALIZER_UNLOCKED;
|
|
|
|
|
static vprintf_like_t s_original_vprintf;
|
|
|
|
|
static bool s_hook_installed;
|
|
|
|
|
static uint32_t s_successful_uploads;
|
|
|
|
|
static uint32_t s_failed_uploads;
|
|
|
|
|
static int s_last_http_status = -1;
|
|
|
|
|
static esp_err_t s_last_upload_err = ESP_ERR_NOT_FOUND;
|
|
|
|
|
static int64_t s_last_upload_ms;
|
|
|
|
|
static int64_t s_last_success_ms;
|
|
|
|
|
static bool s_coredump_present;
|
|
|
|
|
static bool s_coredump_reported;
|
|
|
|
|
static size_t s_coredump_addr;
|
|
|
|
|
static size_t s_coredump_size;
|
|
|
|
|
|
|
|
|
|
static bool remote_log_path_active(void)
|
|
|
|
|
{
|
|
|
|
@@ -230,6 +244,15 @@ static bool dequeue_entry(remote_log_entry_t *out_entry)
|
|
|
|
|
return ok;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static size_t snapshot_queue_count(void)
|
|
|
|
|
{
|
|
|
|
|
size_t count = 0U;
|
|
|
|
|
portENTER_CRITICAL(&s_lock);
|
|
|
|
|
count = s_queue_count;
|
|
|
|
|
portEXIT_CRITICAL(&s_lock);
|
|
|
|
|
return count;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static uint32_t snapshot_and_clear_dropped_count(void)
|
|
|
|
|
{
|
|
|
|
|
uint32_t dropped = 0;
|
|
|
|
@@ -451,6 +474,12 @@ static size_t collect_files(uint32_t *out_sequences, size_t capacity)
|
|
|
|
|
return count;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static size_t count_pending_files(void)
|
|
|
|
|
{
|
|
|
|
|
uint32_t sequences[CONFIG_TQ_REMOTE_LOG_MAX_FILES + 8] = {0};
|
|
|
|
|
return collect_files(sequences, sizeof(sequences) / sizeof(sequences[0]));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void trim_old_files(void)
|
|
|
|
|
{
|
|
|
|
|
uint32_t sequences[CONFIG_TQ_REMOTE_LOG_MAX_FILES + 8] = {0};
|
|
|
|
@@ -541,6 +570,102 @@ static bool realtime_path_busy(void)
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const char *reset_reason_name(esp_reset_reason_t reason)
|
|
|
|
|
{
|
|
|
|
|
switch (reason) {
|
|
|
|
|
case ESP_RST_POWERON:
|
|
|
|
|
return "poweron";
|
|
|
|
|
case ESP_RST_EXT:
|
|
|
|
|
return "external";
|
|
|
|
|
case ESP_RST_SW:
|
|
|
|
|
return "software";
|
|
|
|
|
case ESP_RST_PANIC:
|
|
|
|
|
return "panic";
|
|
|
|
|
case ESP_RST_INT_WDT:
|
|
|
|
|
return "interrupt_wdt";
|
|
|
|
|
case ESP_RST_TASK_WDT:
|
|
|
|
|
return "task_wdt";
|
|
|
|
|
case ESP_RST_WDT:
|
|
|
|
|
return "other_wdt";
|
|
|
|
|
case ESP_RST_DEEPSLEEP:
|
|
|
|
|
return "deepsleep";
|
|
|
|
|
case ESP_RST_BROWNOUT:
|
|
|
|
|
return "brownout";
|
|
|
|
|
case ESP_RST_SDIO:
|
|
|
|
|
return "sdio";
|
|
|
|
|
default:
|
|
|
|
|
return "unknown";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static esp_err_t append_device_state(char *body, size_t body_len, size_t *offset)
|
|
|
|
|
{
|
|
|
|
|
if (body == NULL || offset == NULL || *offset >= body_len) {
|
|
|
|
|
return ESP_ERR_INVALID_ARG;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const esp_app_desc_t *app = esp_app_get_description();
|
|
|
|
|
esp_reset_reason_t reset_reason = esp_reset_reason();
|
|
|
|
|
control_plane_multimodal_runtime_state_t mm = {0};
|
|
|
|
|
bool have_mm = (control_plane_multimodal_get_runtime_state(&mm) == ESP_OK);
|
|
|
|
|
|
|
|
|
|
int written = snprintf(body + *offset,
|
|
|
|
|
body_len - *offset,
|
|
|
|
|
",\"device_state\":{"
|
|
|
|
|
"\"reset_reason\":\"%s\","
|
|
|
|
|
"\"reset_reason_code\":%d,"
|
|
|
|
|
"\"firmware_version\":\"",
|
|
|
|
|
reset_reason_name(reset_reason),
|
|
|
|
|
(int)reset_reason);
|
|
|
|
|
if (written < 0 || (size_t)written >= body_len - *offset) {
|
|
|
|
|
return ESP_ERR_INVALID_SIZE;
|
|
|
|
|
}
|
|
|
|
|
*offset += (size_t)written;
|
|
|
|
|
json_append_escaped(body, body_len, offset, app != NULL ? app->version : "");
|
|
|
|
|
written = snprintf(body + *offset,
|
|
|
|
|
body_len - *offset,
|
|
|
|
|
"\",\"project_name\":\"");
|
|
|
|
|
if (written < 0 || (size_t)written >= body_len - *offset) {
|
|
|
|
|
return ESP_ERR_INVALID_SIZE;
|
|
|
|
|
}
|
|
|
|
|
*offset += (size_t)written;
|
|
|
|
|
json_append_escaped(body, body_len, offset, app != NULL ? app->project_name : "");
|
|
|
|
|
written = snprintf(body + *offset,
|
|
|
|
|
body_len - *offset,
|
|
|
|
|
"\",\"free_heap\":%lu,"
|
|
|
|
|
"\"minimum_free_heap\":%lu,"
|
|
|
|
|
"\"free_internal\":%lu,"
|
|
|
|
|
"\"largest_internal\":%lu,"
|
|
|
|
|
"\"free_spiram\":%lu,"
|
|
|
|
|
"\"largest_spiram\":%lu,"
|
|
|
|
|
"\"task_count\":%lu,"
|
|
|
|
|
"\"multimodal_connected\":%s,"
|
|
|
|
|
"\"multimodal_active_task\":%s,"
|
|
|
|
|
"\"multimodal_client_speech_active\":%s,"
|
|
|
|
|
"\"multimodal_remote_responding\":%s,"
|
|
|
|
|
"\"coredump_present\":%s,"
|
|
|
|
|
"\"coredump_size\":%lu"
|
|
|
|
|
"}",
|
|
|
|
|
(unsigned long)esp_get_free_heap_size(),
|
|
|
|
|
(unsigned long)esp_get_minimum_free_heap_size(),
|
|
|
|
|
(unsigned long)heap_caps_get_free_size(MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT),
|
|
|
|
|
(unsigned long)heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT),
|
|
|
|
|
(unsigned long)heap_caps_get_free_size(MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT),
|
|
|
|
|
(unsigned long)heap_caps_get_largest_free_block(MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT),
|
|
|
|
|
(unsigned long)uxTaskGetNumberOfTasks(),
|
|
|
|
|
(have_mm && mm.connected) ? "true" : "false",
|
|
|
|
|
(have_mm && mm.has_active_task) ? "true" : "false",
|
|
|
|
|
(have_mm && mm.client_speech_active) ? "true" : "false",
|
|
|
|
|
(have_mm && mm.remote_responding) ? "true" : "false",
|
|
|
|
|
s_coredump_present ? "true" : "false",
|
|
|
|
|
(unsigned long)s_coredump_size);
|
|
|
|
|
if (written < 0 || (size_t)written >= body_len - *offset) {
|
|
|
|
|
return ESP_ERR_INVALID_SIZE;
|
|
|
|
|
}
|
|
|
|
|
*offset += (size_t)written;
|
|
|
|
|
return ESP_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static esp_err_t build_upload_body(uint32_t sequence,
|
|
|
|
|
uint32_t dropped_count,
|
|
|
|
|
char *body,
|
|
|
|
@@ -616,7 +741,16 @@ static esp_err_t build_upload_body(uint32_t sequence,
|
|
|
|
|
}
|
|
|
|
|
fclose(file);
|
|
|
|
|
|
|
|
|
|
written = snprintf(body + offset, body_len - offset, "]}");
|
|
|
|
|
written = snprintf(body + offset, body_len - offset, "]");
|
|
|
|
|
if (written < 0 || (size_t)written >= body_len - offset) {
|
|
|
|
|
return ESP_ERR_INVALID_SIZE;
|
|
|
|
|
}
|
|
|
|
|
offset += (size_t)written;
|
|
|
|
|
esp_err_t state_err = append_device_state(body, body_len, &offset);
|
|
|
|
|
if (state_err != ESP_OK) {
|
|
|
|
|
return state_err;
|
|
|
|
|
}
|
|
|
|
|
written = snprintf(body + offset, body_len - offset, "}");
|
|
|
|
|
if (written < 0 || (size_t)written >= body_len - offset) {
|
|
|
|
|
return ESP_ERR_INVALID_SIZE;
|
|
|
|
|
}
|
|
|
|
@@ -669,11 +803,16 @@ static bool upload_one_file(uint32_t sequence)
|
|
|
|
|
|
|
|
|
|
free(body);
|
|
|
|
|
free(response);
|
|
|
|
|
s_last_upload_ms = esp_timer_get_time() / 1000;
|
|
|
|
|
s_last_upload_err = err;
|
|
|
|
|
s_last_http_status = status;
|
|
|
|
|
|
|
|
|
|
if (err == ESP_OK && (status == 200 || status == 202 || status == 204)) {
|
|
|
|
|
char path[REMOTE_LOG_PATH_MAX] = {0};
|
|
|
|
|
make_log_path(sequence, path, sizeof(path));
|
|
|
|
|
(void)unlink(path);
|
|
|
|
|
s_successful_uploads++;
|
|
|
|
|
s_last_success_ms = s_last_upload_ms;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -682,10 +821,12 @@ static bool upload_one_file(uint32_t sequence)
|
|
|
|
|
make_log_path(sequence, path, sizeof(path));
|
|
|
|
|
(void)unlink(path);
|
|
|
|
|
restore_dropped_count(dropped);
|
|
|
|
|
s_failed_uploads++;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
restore_dropped_count(dropped);
|
|
|
|
|
s_failed_uploads++;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -703,6 +844,144 @@ static bool upload_pending_files(void)
|
|
|
|
|
return upload_one_file(sequences[0]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void detect_coredump(void)
|
|
|
|
|
{
|
|
|
|
|
size_t addr = 0U;
|
|
|
|
|
size_t size = 0U;
|
|
|
|
|
esp_err_t err = esp_core_dump_image_get(&addr, &size);
|
|
|
|
|
if (err == ESP_OK && size > 0U) {
|
|
|
|
|
s_coredump_present = true;
|
|
|
|
|
s_coredump_addr = addr;
|
|
|
|
|
s_coredump_size = size;
|
|
|
|
|
} else {
|
|
|
|
|
s_coredump_present = false;
|
|
|
|
|
s_coredump_addr = 0U;
|
|
|
|
|
s_coredump_size = 0U;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static esp_err_t build_coredump_report_body(char *body, size_t body_len)
|
|
|
|
|
{
|
|
|
|
|
if (body == NULL || body_len == 0U) {
|
|
|
|
|
return ESP_ERR_INVALID_ARG;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char device_id[64] = {0};
|
|
|
|
|
char serial_number[64] = {0};
|
|
|
|
|
domain_runtime_read_device_identity(device_id, sizeof(device_id), serial_number, sizeof(serial_number));
|
|
|
|
|
|
|
|
|
|
char panic_reason[192] = {0};
|
|
|
|
|
#if CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH && CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF
|
|
|
|
|
(void)esp_core_dump_get_panic_reason(panic_reason, sizeof(panic_reason));
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
size_t offset = 0U;
|
|
|
|
|
int written = snprintf(body,
|
|
|
|
|
body_len,
|
|
|
|
|
"{\"schema\":\"tq.coredump.report.v1\",\"device_id\":\"");
|
|
|
|
|
if (written < 0 || (size_t)written >= body_len) {
|
|
|
|
|
return ESP_ERR_INVALID_SIZE;
|
|
|
|
|
}
|
|
|
|
|
offset = (size_t)written;
|
|
|
|
|
json_append_escaped(body, body_len, &offset, device_id);
|
|
|
|
|
written = snprintf(body + offset, body_len - offset, "\",\"serial_number\":\"");
|
|
|
|
|
if (written < 0 || (size_t)written >= body_len - offset) {
|
|
|
|
|
return ESP_ERR_INVALID_SIZE;
|
|
|
|
|
}
|
|
|
|
|
offset += (size_t)written;
|
|
|
|
|
json_append_escaped(body, body_len, &offset, serial_number);
|
|
|
|
|
written = snprintf(body + offset,
|
|
|
|
|
body_len - offset,
|
|
|
|
|
"\",\"sent_at_ms\":%lld,\"coredump_addr\":%lu,\"coredump_size\":%lu,\"panic_reason\":\"",
|
|
|
|
|
(long long)(esp_timer_get_time() / 1000),
|
|
|
|
|
(unsigned long)s_coredump_addr,
|
|
|
|
|
(unsigned long)s_coredump_size);
|
|
|
|
|
if (written < 0 || (size_t)written >= body_len - offset) {
|
|
|
|
|
return ESP_ERR_INVALID_SIZE;
|
|
|
|
|
}
|
|
|
|
|
offset += (size_t)written;
|
|
|
|
|
json_append_escaped(body, body_len, &offset, panic_reason);
|
|
|
|
|
written = snprintf(body + offset, body_len - offset, "\"");
|
|
|
|
|
if (written < 0 || (size_t)written >= body_len - offset) {
|
|
|
|
|
return ESP_ERR_INVALID_SIZE;
|
|
|
|
|
}
|
|
|
|
|
offset += (size_t)written;
|
|
|
|
|
esp_err_t state_err = append_device_state(body, body_len, &offset);
|
|
|
|
|
if (state_err != ESP_OK) {
|
|
|
|
|
return state_err;
|
|
|
|
|
}
|
|
|
|
|
written = snprintf(body + offset, body_len - offset, "}");
|
|
|
|
|
if (written < 0 || (size_t)written >= body_len - offset) {
|
|
|
|
|
return ESP_ERR_INVALID_SIZE;
|
|
|
|
|
}
|
|
|
|
|
return ESP_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool upload_coredump_report(void)
|
|
|
|
|
{
|
|
|
|
|
if (!s_coredump_present || s_coredump_reported ||
|
|
|
|
|
!control_plane_is_sta_connected() || realtime_path_busy()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *body = (char *)malloc(2048);
|
|
|
|
|
char *response = (char *)malloc(REMOTE_LOG_RESPONSE_MAX);
|
|
|
|
|
if (body == NULL || response == NULL) {
|
|
|
|
|
free(body);
|
|
|
|
|
free(response);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
esp_err_t err = build_coredump_report_body(body, 2048);
|
|
|
|
|
if (err != ESP_OK) {
|
|
|
|
|
free(body);
|
|
|
|
|
free(response);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int status = -1;
|
|
|
|
|
size_t response_len = 0U;
|
|
|
|
|
err = domain_runtime_post_json(CONFIG_TQ_REMOTE_LOG_ENDPOINT,
|
|
|
|
|
body,
|
|
|
|
|
NULL,
|
|
|
|
|
CONFIG_TQ_REMOTE_LOG_AUTH_TOKEN,
|
|
|
|
|
CONFIG_TQ_REMOTE_LOG_UPLOAD_TIMEOUT_MS,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
response,
|
|
|
|
|
REMOTE_LOG_RESPONSE_MAX,
|
|
|
|
|
&response_len,
|
|
|
|
|
&status);
|
|
|
|
|
free(body);
|
|
|
|
|
free(response);
|
|
|
|
|
|
|
|
|
|
s_last_upload_ms = esp_timer_get_time() / 1000;
|
|
|
|
|
s_last_upload_err = err;
|
|
|
|
|
s_last_http_status = status;
|
|
|
|
|
if (err == ESP_OK && (status == 200 || status == 202 || status == 204)) {
|
|
|
|
|
s_successful_uploads++;
|
|
|
|
|
s_last_success_ms = s_last_upload_ms;
|
|
|
|
|
s_coredump_reported = true;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
s_failed_uploads++;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void log_startup_self_check(void)
|
|
|
|
|
{
|
|
|
|
|
ESP_LOGW("remote_log",
|
|
|
|
|
"enabled endpoint=%s dir=%s pending_files=%u queue=%u max_files=%u file_max=%u coredump_present=%d coredump_size=%u",
|
|
|
|
|
CONFIG_TQ_REMOTE_LOG_ENDPOINT,
|
|
|
|
|
REMOTE_LOG_DIR,
|
|
|
|
|
(unsigned)count_pending_files(),
|
|
|
|
|
(unsigned)CONFIG_TQ_REMOTE_LOG_QUEUE_LEN,
|
|
|
|
|
(unsigned)CONFIG_TQ_REMOTE_LOG_MAX_FILES,
|
|
|
|
|
(unsigned)CONFIG_TQ_REMOTE_LOG_FILE_MAX_BYTES,
|
|
|
|
|
s_coredump_present,
|
|
|
|
|
(unsigned)s_coredump_size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void install_hook(void)
|
|
|
|
|
{
|
|
|
|
|
if (s_hook_installed) {
|
|
|
|
@@ -726,7 +1005,7 @@ static void remote_log_task(void *arg)
|
|
|
|
|
{
|
|
|
|
|
(void)arg;
|
|
|
|
|
|
|
|
|
|
esp_err_t mount_err = domain_runtime_mount_littlefs();
|
|
|
|
|
esp_err_t mount_err = domain_runtime_mount_logfs();
|
|
|
|
|
if (mount_err != ESP_OK) {
|
|
|
|
|
s_remote_log_task = NULL;
|
|
|
|
|
vTaskDelete(NULL);
|
|
|
|
@@ -734,8 +1013,10 @@ static void remote_log_task(void *arg)
|
|
|
|
|
}
|
|
|
|
|
(void)make_log_dir();
|
|
|
|
|
s_file_sequence = find_next_file_sequence();
|
|
|
|
|
detect_coredump();
|
|
|
|
|
|
|
|
|
|
install_hook();
|
|
|
|
|
log_startup_self_check();
|
|
|
|
|
|
|
|
|
|
TickType_t last_flush = xTaskGetTickCount();
|
|
|
|
|
uint32_t backoff_ms = 0U;
|
|
|
|
@@ -750,6 +1031,7 @@ static void remote_log_task(void *arg)
|
|
|
|
|
|
|
|
|
|
if (backoff_ms == 0U || now >= next_upload_tick) {
|
|
|
|
|
drain_memory_queue_to_flash();
|
|
|
|
|
(void)upload_coredump_report();
|
|
|
|
|
bool ok = upload_pending_files();
|
|
|
|
|
if (ok) {
|
|
|
|
|
backoff_ms = 0U;
|
|
|
|
@@ -792,6 +1074,81 @@ esp_err_t control_plane_remote_log_start(void)
|
|
|
|
|
return created == pdPASS ? ESP_OK : ESP_ERR_NO_MEM;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
esp_err_t control_plane_remote_log_flush_now(void)
|
|
|
|
|
{
|
|
|
|
|
if (s_remote_log_task == NULL) {
|
|
|
|
|
return ESP_ERR_INVALID_STATE;
|
|
|
|
|
}
|
|
|
|
|
drain_memory_queue_to_flash();
|
|
|
|
|
if (!control_plane_is_sta_connected()) {
|
|
|
|
|
return ESP_ERR_INVALID_STATE;
|
|
|
|
|
}
|
|
|
|
|
(void)upload_coredump_report();
|
|
|
|
|
return upload_pending_files() ? ESP_OK : ESP_FAIL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
esp_err_t control_plane_remote_log_clear(void)
|
|
|
|
|
{
|
|
|
|
|
portENTER_CRITICAL(&s_lock);
|
|
|
|
|
s_queue_read = 0U;
|
|
|
|
|
s_queue_count = 0U;
|
|
|
|
|
s_dropped_count = 0U;
|
|
|
|
|
portEXIT_CRITICAL(&s_lock);
|
|
|
|
|
|
|
|
|
|
uint32_t sequences[CONFIG_TQ_REMOTE_LOG_MAX_FILES + 8] = {0};
|
|
|
|
|
size_t count = collect_files(sequences, sizeof(sequences) / sizeof(sequences[0]));
|
|
|
|
|
for (size_t i = 0; i < count; ++i) {
|
|
|
|
|
char path[REMOTE_LOG_PATH_MAX] = {0};
|
|
|
|
|
make_log_path(sequences[i], path, sizeof(path));
|
|
|
|
|
(void)unlink(path);
|
|
|
|
|
}
|
|
|
|
|
return ESP_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
esp_err_t control_plane_remote_log_format_status(char *out, size_t out_len)
|
|
|
|
|
{
|
|
|
|
|
if (out == NULL || out_len == 0U) {
|
|
|
|
|
return ESP_ERR_INVALID_ARG;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t dropped = 0U;
|
|
|
|
|
portENTER_CRITICAL(&s_lock);
|
|
|
|
|
dropped = s_dropped_count;
|
|
|
|
|
portEXIT_CRITICAL(&s_lock);
|
|
|
|
|
|
|
|
|
|
int written = snprintf(out,
|
|
|
|
|
out_len,
|
|
|
|
|
"{\"enabled\":true,\"running\":%s,\"hook_installed\":%s,"
|
|
|
|
|
"\"endpoint\":\"%s\",\"dir\":\"%s\",\"queue_count\":%u,"
|
|
|
|
|
"\"queue_capacity\":%u,\"pending_files\":%u,"
|
|
|
|
|
"\"max_files\":%u,\"file_max_bytes\":%u,"
|
|
|
|
|
"\"dropped_count\":%lu,\"successful_uploads\":%lu,"
|
|
|
|
|
"\"failed_uploads\":%lu,\"last_http_status\":%d,"
|
|
|
|
|
"\"last_upload_err\":%d,\"last_upload_ms\":%lld,"
|
|
|
|
|
"\"last_success_ms\":%lld,\"coredump_present\":%s,"
|
|
|
|
|
"\"coredump_reported\":%s,\"coredump_size\":%lu}",
|
|
|
|
|
s_remote_log_task != NULL ? "true" : "false",
|
|
|
|
|
s_hook_installed ? "true" : "false",
|
|
|
|
|
CONFIG_TQ_REMOTE_LOG_ENDPOINT,
|
|
|
|
|
REMOTE_LOG_DIR,
|
|
|
|
|
(unsigned)snapshot_queue_count(),
|
|
|
|
|
(unsigned)CONFIG_TQ_REMOTE_LOG_QUEUE_LEN,
|
|
|
|
|
(unsigned)count_pending_files(),
|
|
|
|
|
(unsigned)CONFIG_TQ_REMOTE_LOG_MAX_FILES,
|
|
|
|
|
(unsigned)CONFIG_TQ_REMOTE_LOG_FILE_MAX_BYTES,
|
|
|
|
|
(unsigned long)dropped,
|
|
|
|
|
(unsigned long)s_successful_uploads,
|
|
|
|
|
(unsigned long)s_failed_uploads,
|
|
|
|
|
s_last_http_status,
|
|
|
|
|
(int)s_last_upload_err,
|
|
|
|
|
(long long)s_last_upload_ms,
|
|
|
|
|
(long long)s_last_success_ms,
|
|
|
|
|
s_coredump_present ? "true" : "false",
|
|
|
|
|
s_coredump_reported ? "true" : "false",
|
|
|
|
|
(unsigned long)s_coredump_size);
|
|
|
|
|
return (written > 0 && (size_t)written < out_len) ? ESP_OK : ESP_ERR_INVALID_SIZE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void control_plane_remote_log_stop(int timeout_ms)
|
|
|
|
|
{
|
|
|
|
|
if (s_remote_log_task == NULL) {
|
|
|
|
@@ -821,4 +1178,23 @@ void control_plane_remote_log_stop(int timeout_ms)
|
|
|
|
|
{
|
|
|
|
|
(void)timeout_ms;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
esp_err_t control_plane_remote_log_flush_now(void)
|
|
|
|
|
{
|
|
|
|
|
return ESP_ERR_NOT_SUPPORTED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
esp_err_t control_plane_remote_log_clear(void)
|
|
|
|
|
{
|
|
|
|
|
return ESP_ERR_NOT_SUPPORTED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
esp_err_t control_plane_remote_log_format_status(char *out, size_t out_len)
|
|
|
|
|
{
|
|
|
|
|
if (out == NULL || out_len == 0U) {
|
|
|
|
|
return ESP_ERR_INVALID_ARG;
|
|
|
|
|
}
|
|
|
|
|
int written = snprintf(out, out_len, "{\"enabled\":false}");
|
|
|
|
|
return (written > 0 && (size_t)written < out_len) ? ESP_OK : ESP_ERR_INVALID_SIZE;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|