feat(architecture): enforce lifecycle orchestration and layered component boundaries

This commit is contained in:
admin
2026-02-26 10:18:19 +08:00
parent 64c2c7d8c2
commit cf1fecb004
32 changed files with 1701 additions and 180 deletions

View File

@@ -0,0 +1,61 @@
#pragma once
#include <stdint.h>
#include "esp_err.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
RUNTIME_DIAG_COUNTER_LIFECYCLE_START_ATTEMPT = 0,
RUNTIME_DIAG_COUNTER_LIFECYCLE_START_SUCCESS,
RUNTIME_DIAG_COUNTER_LIFECYCLE_START_FAILED,
RUNTIME_DIAG_COUNTER_LIFECYCLE_START_RETRY,
RUNTIME_DIAG_COUNTER_LIFECYCLE_STOP_ATTEMPT,
RUNTIME_DIAG_COUNTER_LIFECYCLE_STOP_SUCCESS,
RUNTIME_DIAG_COUNTER_LIFECYCLE_STOP_FAILED,
RUNTIME_DIAG_COUNTER_WIFI_CONNECT_SUCCESS,
RUNTIME_DIAG_COUNTER_WIFI_CONNECT_FAILED,
RUNTIME_DIAG_COUNTER_WIFI_CONNECT_TIMEOUT,
RUNTIME_DIAG_COUNTER_PRINTER_JOB_SUBMITTED,
RUNTIME_DIAG_COUNTER_PRINTER_JOB_SUCCESS,
RUNTIME_DIAG_COUNTER_PRINTER_JOB_FAILED,
RUNTIME_DIAG_COUNTER_PRINTER_JOB_CANCELED,
RUNTIME_DIAG_COUNTER_IMAGE_GENERATE_ATTEMPT,
RUNTIME_DIAG_COUNTER_IMAGE_GENERATE_SUCCESS,
RUNTIME_DIAG_COUNTER_IMAGE_GENERATE_FAILED,
RUNTIME_DIAG_COUNTER_IMAGE_GENERATE_TIMEOUT,
RUNTIME_DIAG_COUNTER_REST_RESPONSES_TOTAL,
RUNTIME_DIAG_COUNTER_REST_ERRORS_TOTAL,
RUNTIME_DIAG_COUNTER_MAX,
} runtime_diag_counter_t;
typedef enum {
RUNTIME_DIAG_GAUGE_LIFECYCLE_STATE = 0,
RUNTIME_DIAG_GAUGE_STATUS_POLL_PAUSE_DEPTH,
RUNTIME_DIAG_GAUGE_PRINTER_QUEUE_DEPTH,
RUNTIME_DIAG_GAUGE_MAX,
} runtime_diag_gauge_t;
typedef struct {
uint64_t counters[RUNTIME_DIAG_COUNTER_MAX];
int32_t gauges[RUNTIME_DIAG_GAUGE_MAX];
int64_t last_error_ms;
esp_err_t last_error_code;
char last_error_source[32];
char last_error_message[96];
} runtime_diag_snapshot_t;
void runtime_diag_counter_add(runtime_diag_counter_t counter, uint32_t delta);
void runtime_diag_set_gauge(runtime_diag_gauge_t gauge, int32_t value);
void runtime_diag_record_error(const char *source, esp_err_t code, const char *message);
void runtime_diag_get_snapshot(runtime_diag_snapshot_t *out_snapshot);
const char *runtime_diag_counter_name(runtime_diag_counter_t counter);
const char *runtime_diag_gauge_name(runtime_diag_gauge_t gauge);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,30 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include "esp_err.h"
uint32_t runtime_policy_wifi_connect_timeout_ms(void);
uint32_t runtime_policy_lifecycle_start_retry_count(void);
uint32_t runtime_policy_lifecycle_retry_backoff_ms(uint32_t attempt);
bool runtime_policy_is_retryable_error(esp_err_t err);
uint32_t runtime_policy_printer_control_lock_timeout_ms(void);
uint32_t runtime_policy_printer_worker_queue_wait_ms(void);
uint32_t runtime_policy_printer_queue_retry_delay_ms(void);
uint32_t runtime_policy_printer_status_poll_interval_ms(void);
uint32_t runtime_policy_printer_stop_timeout_ms(void);
uint32_t runtime_policy_rest_printer_connect_timeout_ms(void);
uint32_t runtime_policy_rest_label_timeout_ms(void);
uint32_t runtime_policy_rest_ota_timeout_ms(void);
uint32_t runtime_policy_image_generation_timeout_default_ms(void);
uint32_t runtime_policy_image_generation_timeout_min_ms(void);
uint32_t runtime_policy_image_generation_timeout_max_ms(void);
uint32_t runtime_policy_image_download_timeout_default_ms(void);
uint32_t runtime_policy_image_download_timeout_min_ms(void);
uint32_t runtime_policy_image_download_timeout_max_ms(void);

View File

@@ -5,6 +5,7 @@
#include "esp_err.h"
esp_err_t wifi_manager_start(void);
esp_err_t wifi_manager_stop(void);
bool wifi_manager_is_ready(void);

View File

@@ -51,6 +51,7 @@ static uint16_t s_mtu = 23;
static bool s_scanning;
static bool s_notify_ready;
static bool s_host_synced;
static bool s_initialized;
static uint16_t uuid16(const ble_uuid_t *uuid) {
if (uuid == NULL || uuid->type != BLE_UUID_TYPE_16) {
@@ -519,6 +520,11 @@ static void nimble_host_task(void *param) {
esp_err_t ble_printer_client_init(ble_frame_rx_cb_t rx_cb) {
s_rx_cb = rx_cb;
if (s_initialized) {
reset_discovery_state();
return ESP_OK;
}
// NimBLE emits very chatty INFO logs during each chunk write.
// Lowering these logs reduces serial I/O overhead and improves runtime smoothness.
esp_log_level_set("NimBLE", ESP_LOG_WARN);
@@ -531,6 +537,8 @@ esp_err_t ble_printer_client_init(ble_frame_rx_cb_t rx_cb) {
s_lock = xSemaphoreCreateMutex();
if (s_lock == NULL) {
vEventGroupDelete(s_evt_group);
s_evt_group = NULL;
return ESP_ERR_NO_MEM;
}
@@ -547,10 +555,15 @@ esp_err_t ble_printer_client_init(ble_frame_rx_cb_t rx_cb) {
nimble_port_freertos_init(nimble_host_task);
reset_discovery_state();
s_initialized = true;
return ESP_OK;
}
esp_err_t ble_printer_client_connect(const char *target_name, uint32_t timeout_ms) {
if (!s_initialized || s_lock == NULL || s_evt_group == NULL) {
return ESP_ERR_INVALID_STATE;
}
s_match_any_compatible = false;
if (target_name != NULL && target_name[0] != '\0') {
if (strcmp(target_name, "*") == 0) {
@@ -626,6 +639,10 @@ esp_err_t ble_printer_client_connect(const char *target_name, uint32_t timeout_m
}
void ble_printer_client_disconnect(void) {
if (!s_initialized || s_lock == NULL) {
return;
}
if (xSemaphoreTake(s_lock, pdMS_TO_TICKS(2000)) != pdTRUE) {
return;
}
@@ -642,6 +659,9 @@ void ble_printer_client_disconnect(void) {
}
bool ble_printer_client_is_connected(void) {
if (!s_initialized) {
return false;
}
return (s_conn_handle != BLE_HS_CONN_HANDLE_NONE) && s_notify_ready;
}

View File

@@ -0,0 +1,136 @@
#include "runtime_diagnostics.h"
#include <stdio.h>
#include <string.h>
#include "esp_timer.h"
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
static SemaphoreHandle_t s_lock;
static runtime_diag_snapshot_t s_snapshot;
static const char *const s_counter_names[RUNTIME_DIAG_COUNTER_MAX] = {
"lifecycle_start_attempt",
"lifecycle_start_success",
"lifecycle_start_failed",
"lifecycle_start_retry",
"lifecycle_stop_attempt",
"lifecycle_stop_success",
"lifecycle_stop_failed",
"wifi_connect_success",
"wifi_connect_failed",
"wifi_connect_timeout",
"printer_job_submitted",
"printer_job_success",
"printer_job_failed",
"printer_job_canceled",
"image_generate_attempt",
"image_generate_success",
"image_generate_failed",
"image_generate_timeout",
"rest_responses_total",
"rest_errors_total",
};
static const char *const s_gauge_names[RUNTIME_DIAG_GAUGE_MAX] = {
"lifecycle_state",
"status_poll_pause_depth",
"printer_queue_depth",
};
static void runtime_diag_ensure_lock(void) {
if (s_lock == NULL) {
s_lock = xSemaphoreCreateMutex();
}
}
void runtime_diag_counter_add(runtime_diag_counter_t counter, uint32_t delta) {
if (counter < 0 || counter >= RUNTIME_DIAG_COUNTER_MAX || delta == 0) {
return;
}
runtime_diag_ensure_lock();
if (s_lock == NULL) {
return;
}
if (xSemaphoreTake(s_lock, pdMS_TO_TICKS(50)) != pdTRUE) {
return;
}
s_snapshot.counters[counter] += delta;
xSemaphoreGive(s_lock);
}
void runtime_diag_set_gauge(runtime_diag_gauge_t gauge, int32_t value) {
if (gauge < 0 || gauge >= RUNTIME_DIAG_GAUGE_MAX) {
return;
}
runtime_diag_ensure_lock();
if (s_lock == NULL) {
return;
}
if (xSemaphoreTake(s_lock, pdMS_TO_TICKS(50)) != pdTRUE) {
return;
}
s_snapshot.gauges[gauge] = value;
xSemaphoreGive(s_lock);
}
void runtime_diag_record_error(const char *source, esp_err_t code, const char *message) {
runtime_diag_ensure_lock();
if (s_lock == NULL) {
return;
}
if (xSemaphoreTake(s_lock, pdMS_TO_TICKS(100)) != pdTRUE) {
return;
}
s_snapshot.last_error_ms = esp_timer_get_time() / 1000;
s_snapshot.last_error_code = code;
strlcpy(s_snapshot.last_error_source,
source != NULL ? source : "unknown",
sizeof(s_snapshot.last_error_source));
strlcpy(s_snapshot.last_error_message,
message != NULL ? message : "unknown",
sizeof(s_snapshot.last_error_message));
xSemaphoreGive(s_lock);
}
void runtime_diag_get_snapshot(runtime_diag_snapshot_t *out_snapshot) {
if (out_snapshot == NULL) {
return;
}
memset(out_snapshot, 0, sizeof(*out_snapshot));
runtime_diag_ensure_lock();
if (s_lock == NULL) {
return;
}
if (xSemaphoreTake(s_lock, pdMS_TO_TICKS(100)) != pdTRUE) {
return;
}
*out_snapshot = s_snapshot;
xSemaphoreGive(s_lock);
}
const char *runtime_diag_counter_name(runtime_diag_counter_t counter) {
if (counter < 0 || counter >= RUNTIME_DIAG_COUNTER_MAX) {
return "unknown";
}
return s_counter_names[counter];
}
const char *runtime_diag_gauge_name(runtime_diag_gauge_t gauge) {
if (gauge < 0 || gauge >= RUNTIME_DIAG_GAUGE_MAX) {
return "unknown";
}
return s_gauge_names[gauge];
}

View File

@@ -0,0 +1,142 @@
#include "runtime_policy.h"
#include <stddef.h>
#ifndef CONFIG_TQ_WIFI_CONNECT_TIMEOUT_MS
#define CONFIG_TQ_WIFI_CONNECT_TIMEOUT_MS 15000
#endif
#ifndef CONFIG_TQ_LIFECYCLE_START_RETRY_COUNT
#define CONFIG_TQ_LIFECYCLE_START_RETRY_COUNT 2
#endif
#ifndef CONFIG_TQ_LIFECYCLE_RETRY_BACKOFF_MS
#define CONFIG_TQ_LIFECYCLE_RETRY_BACKOFF_MS 800
#endif
#ifndef CONFIG_TQ_PRINTER_CONTROL_LOCK_TIMEOUT_MS
#define CONFIG_TQ_PRINTER_CONTROL_LOCK_TIMEOUT_MS 1000
#endif
#ifndef CONFIG_TQ_PRINTER_WORKER_QUEUE_WAIT_MS
#define CONFIG_TQ_PRINTER_WORKER_QUEUE_WAIT_MS 250
#endif
#ifndef CONFIG_TQ_PRINTER_QUEUE_RETRY_DELAY_MS
#define CONFIG_TQ_PRINTER_QUEUE_RETRY_DELAY_MS 20
#endif
#ifndef CONFIG_TQ_PRINTER_STATUS_POLL_INTERVAL_MS
#define CONFIG_TQ_PRINTER_STATUS_POLL_INTERVAL_MS 5000
#endif
#ifndef CONFIG_TQ_PRINTER_STOP_TIMEOUT_MS
#define CONFIG_TQ_PRINTER_STOP_TIMEOUT_MS 8000
#endif
#ifndef CONFIG_TQ_REST_PRINTER_CONNECT_TIMEOUT_MS
#define CONFIG_TQ_REST_PRINTER_CONNECT_TIMEOUT_MS 15000
#endif
#ifndef CONFIG_TQ_REST_LABEL_TIMEOUT_MS
#define CONFIG_TQ_REST_LABEL_TIMEOUT_MS 5000
#endif
#ifndef CONFIG_TQ_REST_OTA_STEP_TIMEOUT_MS
#define CONFIG_TQ_REST_OTA_STEP_TIMEOUT_MS 5000
#endif
#ifndef CONFIG_TQ_Z_IMAGE_TIMEOUT_MS
#define CONFIG_TQ_Z_IMAGE_TIMEOUT_MS 45000
#endif
#ifndef CONFIG_TQ_Z_IMAGE_DOWNLOAD_TIMEOUT_MS
#define CONFIG_TQ_Z_IMAGE_DOWNLOAD_TIMEOUT_MS 15000
#endif
static uint32_t clamp_u32(uint32_t value, uint32_t min_value, uint32_t max_value) {
if (value < min_value) {
return min_value;
}
if (value > max_value) {
return max_value;
}
return value;
}
uint32_t runtime_policy_wifi_connect_timeout_ms(void) {
return clamp_u32(CONFIG_TQ_WIFI_CONNECT_TIMEOUT_MS, 3000, 60000);
}
uint32_t runtime_policy_lifecycle_start_retry_count(void) {
return clamp_u32(CONFIG_TQ_LIFECYCLE_START_RETRY_COUNT, 0, 5);
}
uint32_t runtime_policy_lifecycle_retry_backoff_ms(uint32_t attempt) {
uint32_t base = clamp_u32(CONFIG_TQ_LIFECYCLE_RETRY_BACKOFF_MS, 100, 10000);
if (attempt > 8) {
attempt = 8;
}
uint32_t factor = (1u << attempt);
return clamp_u32(base * factor, 100, 30000);
}
bool runtime_policy_is_retryable_error(esp_err_t err) {
return err == ESP_ERR_TIMEOUT || err == ESP_FAIL || err == ESP_ERR_NO_MEM;
}
uint32_t runtime_policy_printer_control_lock_timeout_ms(void) {
return clamp_u32(CONFIG_TQ_PRINTER_CONTROL_LOCK_TIMEOUT_MS, 100, 5000);
}
uint32_t runtime_policy_printer_worker_queue_wait_ms(void) {
return clamp_u32(CONFIG_TQ_PRINTER_WORKER_QUEUE_WAIT_MS, 50, 2000);
}
uint32_t runtime_policy_printer_queue_retry_delay_ms(void) {
return clamp_u32(CONFIG_TQ_PRINTER_QUEUE_RETRY_DELAY_MS, 5, 500);
}
uint32_t runtime_policy_printer_status_poll_interval_ms(void) {
return clamp_u32(CONFIG_TQ_PRINTER_STATUS_POLL_INTERVAL_MS, 1000, 30000);
}
uint32_t runtime_policy_printer_stop_timeout_ms(void) {
return clamp_u32(CONFIG_TQ_PRINTER_STOP_TIMEOUT_MS, 1000, 30000);
}
uint32_t runtime_policy_rest_printer_connect_timeout_ms(void) {
return clamp_u32(CONFIG_TQ_REST_PRINTER_CONNECT_TIMEOUT_MS, 1000, 60000);
}
uint32_t runtime_policy_rest_label_timeout_ms(void) {
return clamp_u32(CONFIG_TQ_REST_LABEL_TIMEOUT_MS, 500, 30000);
}
uint32_t runtime_policy_rest_ota_timeout_ms(void) {
return clamp_u32(CONFIG_TQ_REST_OTA_STEP_TIMEOUT_MS, 500, 60000);
}
uint32_t runtime_policy_image_generation_timeout_default_ms(void) {
return clamp_u32(CONFIG_TQ_Z_IMAGE_TIMEOUT_MS, 5000, 180000);
}
uint32_t runtime_policy_image_generation_timeout_min_ms(void) {
return 5000;
}
uint32_t runtime_policy_image_generation_timeout_max_ms(void) {
return 180000;
}
uint32_t runtime_policy_image_download_timeout_default_ms(void) {
return clamp_u32(CONFIG_TQ_Z_IMAGE_DOWNLOAD_TIMEOUT_MS, 2000, 120000);
}
uint32_t runtime_policy_image_download_timeout_min_ms(void) {
return 2000;
}
uint32_t runtime_policy_image_download_timeout_max_ms(void) {
return 120000;
}

View File

@@ -7,6 +7,9 @@
#include "esp_log.h"
#include "esp_netif.h"
#include "esp_wifi.h"
#include "esp_wifi_default.h"
#include "runtime_diagnostics.h"
#include "runtime_policy.h"
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
@@ -18,7 +21,10 @@ static const char *TAG = "wifi_manager";
static EventGroupHandle_t s_wifi_event_group;
static int s_retry_num;
static bool s_ready;
static bool s_started;
static esp_netif_t *s_sta_netif;
static esp_event_handler_instance_t s_wifi_event_inst;
static esp_event_handler_instance_t s_ip_event_inst;
static void wifi_manager_apply_sta_throughput_profile(void) {
const uint8_t protocol = WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N;
@@ -49,18 +55,20 @@ static void wifi_event_handler(void *arg,
int32_t event_id,
void *event_data) {
(void)arg;
(void)event_data;
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
esp_wifi_connect();
(void)esp_wifi_connect();
return;
}
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
s_ready = false;
if (s_retry_num < CONFIG_TQ_WIFI_MAXIMUM_RETRY) {
esp_wifi_connect();
(void)esp_wifi_connect();
s_retry_num++;
ESP_LOGW(TAG, "retry to connect to the AP (%d/%d)", s_retry_num, CONFIG_TQ_WIFI_MAXIMUM_RETRY);
} else {
} else if (s_wifi_event_group != NULL) {
xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
}
return;
@@ -70,7 +78,10 @@ static void wifi_event_handler(void *arg,
ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
s_retry_num = 0;
xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
s_ready = true;
if (s_wifi_event_group != NULL) {
xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
}
return;
}
}
@@ -88,9 +99,18 @@ static esp_err_t start_sta_mode(void) {
wifi_config.sta.pmf_cfg.capable = true;
wifi_config.sta.pmf_cfg.required = false;
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());
esp_err_t rc = esp_wifi_set_mode(WIFI_MODE_STA);
if (rc != ESP_OK) {
return rc;
}
rc = esp_wifi_set_config(WIFI_IF_STA, &wifi_config);
if (rc != ESP_OK) {
return rc;
}
rc = esp_wifi_start();
if (rc != ESP_OK && rc != ESP_ERR_INVALID_STATE) {
return rc;
}
ESP_LOGI(TAG, "wifi_init_sta finished");
@@ -98,7 +118,7 @@ static esp_err_t start_sta_mode(void) {
WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
pdFALSE,
pdFALSE,
pdMS_TO_TICKS(15000));
pdMS_TO_TICKS(runtime_policy_wifi_connect_timeout_ms()));
if (bits & WIFI_CONNECTED_BIT) {
ESP_LOGI(TAG, "connected to AP SSID:%s", CONFIG_TQ_WIFI_SSID);
@@ -123,35 +143,157 @@ static esp_err_t start_sta_mode(void) {
}
esp_err_t wifi_manager_start(void) {
s_wifi_event_group = xEventGroupCreate();
if (s_wifi_event_group == NULL) {
return ESP_ERR_NO_MEM;
if (s_started) {
return s_ready ? ESP_OK : ESP_ERR_INVALID_STATE;
}
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
s_retry_num = 0;
s_ready = false;
s_sta_netif = esp_netif_create_default_wifi_sta();
if (s_wifi_event_group == NULL) {
s_wifi_event_group = xEventGroupCreate();
if (s_wifi_event_group == NULL) {
return ESP_ERR_NO_MEM;
}
}
xEventGroupClearBits(s_wifi_event_group, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT);
esp_err_t err = esp_netif_init();
if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) {
runtime_diag_record_error("wifi_start", err, "esp_netif_init failed");
return err;
}
err = esp_event_loop_create_default();
if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) {
runtime_diag_record_error("wifi_start", err, "event loop init failed");
return err;
}
if (s_sta_netif == NULL) {
s_sta_netif = esp_netif_create_default_wifi_sta();
if (s_sta_netif == NULL) {
runtime_diag_record_error("wifi_start", ESP_ERR_NO_MEM, "create sta netif failed");
return ESP_ERR_NO_MEM;
}
}
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
err = esp_wifi_init(&cfg);
if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) {
runtime_diag_record_error("wifi_start", err, "esp_wifi_init failed");
return err;
}
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT,
ESP_EVENT_ANY_ID,
&wifi_event_handler,
NULL));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT,
IP_EVENT_STA_GOT_IP,
&wifi_event_handler,
NULL));
if (s_wifi_event_inst == NULL) {
err = esp_event_handler_instance_register(WIFI_EVENT,
ESP_EVENT_ANY_ID,
&wifi_event_handler,
NULL,
&s_wifi_event_inst);
if (err != ESP_OK) {
runtime_diag_record_error("wifi_start", err, "register WIFI event failed");
return err;
}
}
esp_err_t err = start_sta_mode();
if (err != ESP_OK) {
ESP_LOGE(TAG, "STA-only mode failed to connect (%s)", esp_err_to_name(err));
if (s_ip_event_inst == NULL) {
err = esp_event_handler_instance_register(IP_EVENT,
IP_EVENT_STA_GOT_IP,
&wifi_event_handler,
NULL,
&s_ip_event_inst);
if (err != ESP_OK) {
runtime_diag_record_error("wifi_start", err, "register IP event failed");
return err;
}
}
s_started = true;
err = start_sta_mode();
if (err == ESP_OK) {
runtime_diag_counter_add(RUNTIME_DIAG_COUNTER_WIFI_CONNECT_SUCCESS, 1);
} else {
if (err == ESP_ERR_TIMEOUT) {
runtime_diag_counter_add(RUNTIME_DIAG_COUNTER_WIFI_CONNECT_TIMEOUT, 1);
} else {
runtime_diag_counter_add(RUNTIME_DIAG_COUNTER_WIFI_CONNECT_FAILED, 1);
}
runtime_diag_record_error("wifi_connect", err, "STA connect failed");
}
return err;
}
esp_err_t wifi_manager_stop(void) {
if (!s_started) {
return ESP_OK;
}
esp_err_t first_err = ESP_OK;
s_ready = false;
s_retry_num = 0;
if (s_wifi_event_inst != NULL) {
esp_err_t err = esp_event_handler_instance_unregister(WIFI_EVENT,
ESP_EVENT_ANY_ID,
s_wifi_event_inst);
if (err != ESP_OK && first_err == ESP_OK) {
first_err = err;
}
s_wifi_event_inst = NULL;
}
if (s_ip_event_inst != NULL) {
esp_err_t err = esp_event_handler_instance_unregister(IP_EVENT,
IP_EVENT_STA_GOT_IP,
s_ip_event_inst);
if (err != ESP_OK && first_err == ESP_OK) {
first_err = err;
}
s_ip_event_inst = NULL;
}
esp_err_t err = esp_wifi_disconnect();
if (err != ESP_OK && err != ESP_ERR_WIFI_NOT_STARTED && err != ESP_ERR_WIFI_CONN) {
if (first_err == ESP_OK) {
first_err = err;
}
}
err = esp_wifi_stop();
if (err != ESP_OK && err != ESP_ERR_WIFI_NOT_INIT && err != ESP_ERR_WIFI_NOT_STARTED) {
if (first_err == ESP_OK) {
first_err = err;
}
}
err = esp_wifi_deinit();
if (err != ESP_OK && err != ESP_ERR_WIFI_NOT_INIT) {
if (first_err == ESP_OK) {
first_err = err;
}
}
if (s_sta_netif != NULL) {
esp_netif_destroy_default_wifi(s_sta_netif);
s_sta_netif = NULL;
}
if (s_wifi_event_group != NULL) {
vEventGroupDelete(s_wifi_event_group);
s_wifi_event_group = NULL;
}
s_started = false;
if (first_err != ESP_OK) {
runtime_diag_record_error("wifi_stop", first_err, "wifi stop failed");
}
return first_err;
}
bool wifi_manager_is_ready(void) {
return s_ready;
}