feat(control-plane): add network outage voice feedback
This commit is contained in:
@@ -14,6 +14,7 @@ idf_component_register(
|
||||
"src/runtime/control_plane_fortune_service.c"
|
||||
"src/runtime/control_plane_system_events.c"
|
||||
"src/runtime/control_plane_light_standby.c"
|
||||
"src/runtime/control_plane_network_feedback.c"
|
||||
"src/runtime/control_plane_key_input.c"
|
||||
"src/runtime/control_plane_reset_service.c"
|
||||
"src/runtime/control_plane_remote_log_service.c"
|
||||
|
||||
@@ -96,6 +96,11 @@ typedef enum {
|
||||
CONTROL_PLANE_TRANSPORT_LOSS_PROTOCOL_ERROR,
|
||||
} control_plane_transport_loss_reason_t;
|
||||
|
||||
typedef enum {
|
||||
CONTROL_PLANE_NETWORK_ACTION_CONVERSATION = 0,
|
||||
CONTROL_PLANE_NETWORK_ACTION_CLOUD_CHOUQIAN,
|
||||
} control_plane_network_action_t;
|
||||
|
||||
esp_err_t control_plane_multimodal_start(void);
|
||||
esp_err_t control_plane_multimodal_stop(void);
|
||||
bool control_plane_multimodal_is_connected(void);
|
||||
@@ -149,6 +154,16 @@ bool control_plane_ota_business_interactions_allowed(void);
|
||||
bool control_plane_runtime_is_stopping(void);
|
||||
void control_plane_set_runtime_stop_requested(bool stop_requested);
|
||||
|
||||
void control_plane_network_feedback_reset(void);
|
||||
void control_plane_network_feedback_mark_wifi_down(void);
|
||||
void control_plane_network_feedback_mark_wifi_recovered(void);
|
||||
void control_plane_network_feedback_mark_server_down(void);
|
||||
void control_plane_network_feedback_mark_service_ready(void);
|
||||
void control_plane_network_feedback_service(void);
|
||||
esp_err_t control_plane_network_feedback_require_ready(
|
||||
control_plane_network_action_t action);
|
||||
void control_plane_request_wifi_reconnect_now(void);
|
||||
|
||||
esp_err_t control_plane_battery_service_stop(int timeout_ms);
|
||||
void control_plane_battery_service_set_light_standby(bool standby);
|
||||
void control_plane_runtime_diagnostics_set_light_standby(bool standby);
|
||||
|
||||
@@ -690,6 +690,19 @@ esp_err_t control_plane_request_cloud_chouqian(void)
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
portENTER_CRITICAL(&s_multimodal_runtime_lock);
|
||||
bool request_pending = s_cloud_chouqian_pending;
|
||||
portEXIT_CRITICAL(&s_multimodal_runtime_lock);
|
||||
if (request_pending) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
esp_err_t network_err = control_plane_network_feedback_require_ready(
|
||||
CONTROL_PLANE_NETWORK_ACTION_CLOUD_CHOUQIAN);
|
||||
if (network_err != ESP_OK) {
|
||||
return network_err;
|
||||
}
|
||||
|
||||
uint32_t requested_ms = control_plane_now_ms();
|
||||
|
||||
portENTER_CRITICAL(&s_multimodal_runtime_lock);
|
||||
@@ -895,11 +908,13 @@ static void control_plane_multimodal_event_bridge(control_plane_multimodal_event
|
||||
|
||||
switch (event) {
|
||||
case CONTROL_PLANE_MULTIMODAL_EVENT_TRANSPORT_CONNECTED: {
|
||||
control_plane_network_feedback_mark_service_ready();
|
||||
control_plane_schedule_server_success_prompt();
|
||||
break;
|
||||
}
|
||||
|
||||
case CONTROL_PLANE_MULTIMODAL_EVENT_TRANSPORT_DISCONNECTED:
|
||||
control_plane_network_feedback_mark_server_down();
|
||||
control_plane_clear_downstream_stall_recovery();
|
||||
control_plane_clear_cloud_chouqian_pending("transport disconnected");
|
||||
control_plane_multimodal_stop_uplink();
|
||||
@@ -908,6 +923,7 @@ static void control_plane_multimodal_event_bridge(control_plane_multimodal_event
|
||||
break;
|
||||
|
||||
case CONTROL_PLANE_MULTIMODAL_EVENT_TRANSPORT_ERROR:
|
||||
control_plane_network_feedback_mark_server_down();
|
||||
control_plane_clear_downstream_stall_recovery();
|
||||
control_plane_clear_cloud_chouqian_pending("transport error");
|
||||
control_plane_multimodal_stop_uplink();
|
||||
|
||||
@@ -0,0 +1,315 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "control_plane_internal.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "esp_timer.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/portmacro.h"
|
||||
|
||||
#define CONTROL_PLANE_SERVER_DISCONNECT_GRACE_MS 3000U
|
||||
#define CONTROL_PLANE_NETWORK_PROMPT_COOLDOWN_MS 5000U
|
||||
|
||||
#define CONTROL_PLANE_WIFI_INTERRUPTED_PROMPT_FILE \
|
||||
"/littlefs/audio_prompts/network_interrupted_repairing.opus"
|
||||
#define CONTROL_PLANE_WIFI_ACTION_BLOCKED_PROMPT_FILE \
|
||||
"/littlefs/audio_prompts/network_unstable.opus"
|
||||
#define CONTROL_PLANE_SERVER_INTERRUPTED_PROMPT_FILE \
|
||||
"/littlefs/audio_prompts/server_abnormal_interrupted.opus"
|
||||
#define CONTROL_PLANE_SERVER_ACTION_BLOCKED_PROMPT_FILE \
|
||||
"/littlefs/audio_prompts/server_repair_wait_reopen.opus"
|
||||
#define CONTROL_PLANE_NETWORK_RESTORED_PROMPT_FILE \
|
||||
"/littlefs/audio_prompts/signal_restored_business_resume.opus"
|
||||
|
||||
typedef enum {
|
||||
NETWORK_FEEDBACK_STATE_BOOTING = 0,
|
||||
NETWORK_FEEDBACK_STATE_READY,
|
||||
NETWORK_FEEDBACK_STATE_WIFI_DOWN,
|
||||
NETWORK_FEEDBACK_STATE_SERVER_DOWN,
|
||||
} network_feedback_state_t;
|
||||
|
||||
typedef enum {
|
||||
NETWORK_FEEDBACK_PROMPT_NONE = 0,
|
||||
NETWORK_FEEDBACK_PROMPT_WIFI_INTERRUPTED,
|
||||
NETWORK_FEEDBACK_PROMPT_SERVER_INTERRUPTED,
|
||||
NETWORK_FEEDBACK_PROMPT_RESTORED,
|
||||
} network_feedback_prompt_t;
|
||||
|
||||
typedef struct {
|
||||
network_feedback_state_t state;
|
||||
network_feedback_prompt_t pending_prompt;
|
||||
bool service_ever_ready;
|
||||
bool outage_active;
|
||||
bool outage_announced;
|
||||
bool passive_prompt_attempted;
|
||||
bool prompt_in_progress;
|
||||
int64_t server_down_since_us;
|
||||
int64_t last_fault_prompt_us;
|
||||
} network_feedback_runtime_t;
|
||||
|
||||
static const char *TAG = "cp_network_feedback";
|
||||
static network_feedback_runtime_t s_feedback;
|
||||
static portMUX_TYPE s_feedback_lock = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
static int64_t control_plane_network_feedback_now_us(void)
|
||||
{
|
||||
return esp_timer_get_time();
|
||||
}
|
||||
|
||||
static const char *control_plane_network_action_name(control_plane_network_action_t action)
|
||||
{
|
||||
switch (action) {
|
||||
case CONTROL_PLANE_NETWORK_ACTION_CONVERSATION:
|
||||
return "conversation";
|
||||
case CONTROL_PLANE_NETWORK_ACTION_CLOUD_CHOUQIAN:
|
||||
return "cloud_chouqian";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static const char *control_plane_network_prompt_path(network_feedback_prompt_t prompt)
|
||||
{
|
||||
switch (prompt) {
|
||||
case NETWORK_FEEDBACK_PROMPT_WIFI_INTERRUPTED:
|
||||
return CONTROL_PLANE_WIFI_INTERRUPTED_PROMPT_FILE;
|
||||
case NETWORK_FEEDBACK_PROMPT_SERVER_INTERRUPTED:
|
||||
return CONTROL_PLANE_SERVER_INTERRUPTED_PROMPT_FILE;
|
||||
case NETWORK_FEEDBACK_PROMPT_RESTORED:
|
||||
return CONTROL_PLANE_NETWORK_RESTORED_PROMPT_FILE;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void control_plane_network_feedback_begin_outage_locked(void)
|
||||
{
|
||||
if (s_feedback.outage_active) {
|
||||
return;
|
||||
}
|
||||
|
||||
s_feedback.outage_active = true;
|
||||
s_feedback.outage_announced = false;
|
||||
s_feedback.passive_prompt_attempted = false;
|
||||
s_feedback.pending_prompt = NETWORK_FEEDBACK_PROMPT_NONE;
|
||||
}
|
||||
|
||||
static bool control_plane_network_feedback_begin_prompt_locked(int64_t now_us)
|
||||
{
|
||||
if (s_feedback.prompt_in_progress) {
|
||||
return false;
|
||||
}
|
||||
if (s_feedback.last_fault_prompt_us > 0 &&
|
||||
now_us - s_feedback.last_fault_prompt_us <
|
||||
(int64_t)CONTROL_PLANE_NETWORK_PROMPT_COOLDOWN_MS * 1000LL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
s_feedback.prompt_in_progress = true;
|
||||
s_feedback.last_fault_prompt_us = now_us;
|
||||
s_feedback.outage_announced = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void control_plane_network_feedback_end_prompt(void)
|
||||
{
|
||||
portENTER_CRITICAL(&s_feedback_lock);
|
||||
s_feedback.prompt_in_progress = false;
|
||||
portEXIT_CRITICAL(&s_feedback_lock);
|
||||
}
|
||||
|
||||
static esp_err_t control_plane_network_feedback_play(const char *path,
|
||||
const char *reason)
|
||||
{
|
||||
ESP_LOGI(TAG, "Play network prompt: reason=%s path=%s", reason, path);
|
||||
esp_err_t err = domain_runtime_behavior_play_prompt_file(path);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGW(TAG,
|
||||
"Network prompt failed: reason=%s err=%s",
|
||||
reason,
|
||||
esp_err_to_name(err));
|
||||
}
|
||||
control_plane_network_feedback_end_prompt();
|
||||
return err;
|
||||
}
|
||||
|
||||
void control_plane_network_feedback_reset(void)
|
||||
{
|
||||
portENTER_CRITICAL(&s_feedback_lock);
|
||||
s_feedback = (network_feedback_runtime_t){
|
||||
.state = NETWORK_FEEDBACK_STATE_BOOTING,
|
||||
};
|
||||
portEXIT_CRITICAL(&s_feedback_lock);
|
||||
}
|
||||
|
||||
void control_plane_network_feedback_mark_wifi_down(void)
|
||||
{
|
||||
portENTER_CRITICAL(&s_feedback_lock);
|
||||
control_plane_network_feedback_begin_outage_locked();
|
||||
s_feedback.state = NETWORK_FEEDBACK_STATE_WIFI_DOWN;
|
||||
s_feedback.server_down_since_us = 0;
|
||||
if (!s_feedback.outage_announced) {
|
||||
s_feedback.pending_prompt = NETWORK_FEEDBACK_PROMPT_WIFI_INTERRUPTED;
|
||||
s_feedback.passive_prompt_attempted = true;
|
||||
}
|
||||
portEXIT_CRITICAL(&s_feedback_lock);
|
||||
}
|
||||
|
||||
void control_plane_network_feedback_mark_wifi_recovered(void)
|
||||
{
|
||||
int64_t now_us = control_plane_network_feedback_now_us();
|
||||
portENTER_CRITICAL(&s_feedback_lock);
|
||||
if (s_feedback.state == NETWORK_FEEDBACK_STATE_WIFI_DOWN) {
|
||||
s_feedback.state = NETWORK_FEEDBACK_STATE_SERVER_DOWN;
|
||||
s_feedback.server_down_since_us = now_us;
|
||||
s_feedback.pending_prompt = NETWORK_FEEDBACK_PROMPT_NONE;
|
||||
}
|
||||
portEXIT_CRITICAL(&s_feedback_lock);
|
||||
}
|
||||
|
||||
void control_plane_network_feedback_mark_server_down(void)
|
||||
{
|
||||
int64_t now_us = control_plane_network_feedback_now_us();
|
||||
portENTER_CRITICAL(&s_feedback_lock);
|
||||
if (s_feedback.state != NETWORK_FEEDBACK_STATE_WIFI_DOWN) {
|
||||
if (s_feedback.service_ever_ready) {
|
||||
control_plane_network_feedback_begin_outage_locked();
|
||||
}
|
||||
s_feedback.state = NETWORK_FEEDBACK_STATE_SERVER_DOWN;
|
||||
if (s_feedback.server_down_since_us == 0) {
|
||||
s_feedback.server_down_since_us = now_us;
|
||||
}
|
||||
}
|
||||
portEXIT_CRITICAL(&s_feedback_lock);
|
||||
}
|
||||
|
||||
void control_plane_network_feedback_mark_service_ready(void)
|
||||
{
|
||||
portENTER_CRITICAL(&s_feedback_lock);
|
||||
bool should_announce_recovery = s_feedback.service_ever_ready &&
|
||||
s_feedback.outage_active &&
|
||||
s_feedback.outage_announced;
|
||||
s_feedback.service_ever_ready = true;
|
||||
s_feedback.state = NETWORK_FEEDBACK_STATE_READY;
|
||||
s_feedback.outage_active = false;
|
||||
s_feedback.passive_prompt_attempted = false;
|
||||
s_feedback.server_down_since_us = 0;
|
||||
s_feedback.pending_prompt = should_announce_recovery ?
|
||||
NETWORK_FEEDBACK_PROMPT_RESTORED :
|
||||
NETWORK_FEEDBACK_PROMPT_NONE;
|
||||
portEXIT_CRITICAL(&s_feedback_lock);
|
||||
}
|
||||
|
||||
void control_plane_network_feedback_service(void)
|
||||
{
|
||||
if (!control_plane_ota_voice_services_allowed() ||
|
||||
control_plane_is_mini_program_provisioning_running()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int64_t now_us = control_plane_network_feedback_now_us();
|
||||
network_feedback_prompt_t prompt = NETWORK_FEEDBACK_PROMPT_NONE;
|
||||
|
||||
portENTER_CRITICAL(&s_feedback_lock);
|
||||
if (s_feedback.state == NETWORK_FEEDBACK_STATE_SERVER_DOWN &&
|
||||
s_feedback.service_ever_ready &&
|
||||
s_feedback.outage_active &&
|
||||
!s_feedback.outage_announced &&
|
||||
!s_feedback.passive_prompt_attempted &&
|
||||
s_feedback.server_down_since_us > 0 &&
|
||||
now_us - s_feedback.server_down_since_us >=
|
||||
(int64_t)CONTROL_PLANE_SERVER_DISCONNECT_GRACE_MS * 1000LL) {
|
||||
s_feedback.pending_prompt = NETWORK_FEEDBACK_PROMPT_SERVER_INTERRUPTED;
|
||||
s_feedback.passive_prompt_attempted = true;
|
||||
}
|
||||
|
||||
bool fault_prompt_cooling_down =
|
||||
s_feedback.pending_prompt != NETWORK_FEEDBACK_PROMPT_RESTORED &&
|
||||
s_feedback.last_fault_prompt_us > 0 &&
|
||||
now_us - s_feedback.last_fault_prompt_us <
|
||||
(int64_t)CONTROL_PLANE_NETWORK_PROMPT_COOLDOWN_MS * 1000LL;
|
||||
if (s_feedback.pending_prompt != NETWORK_FEEDBACK_PROMPT_NONE &&
|
||||
!s_feedback.prompt_in_progress &&
|
||||
!fault_prompt_cooling_down) {
|
||||
prompt = s_feedback.pending_prompt;
|
||||
s_feedback.pending_prompt = NETWORK_FEEDBACK_PROMPT_NONE;
|
||||
s_feedback.prompt_in_progress = true;
|
||||
if (prompt == NETWORK_FEEDBACK_PROMPT_RESTORED) {
|
||||
s_feedback.outage_announced = false;
|
||||
} else {
|
||||
s_feedback.last_fault_prompt_us = now_us;
|
||||
s_feedback.outage_announced = true;
|
||||
}
|
||||
}
|
||||
portEXIT_CRITICAL(&s_feedback_lock);
|
||||
|
||||
const char *path = control_plane_network_prompt_path(prompt);
|
||||
if (path != NULL) {
|
||||
(void)control_plane_network_feedback_play(path, "state_change");
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t control_plane_network_feedback_require_ready(
|
||||
control_plane_network_action_t action)
|
||||
{
|
||||
bool wifi_connected = control_plane_is_sta_connected();
|
||||
bool server_connected = wifi_connected && control_plane_multimodal_is_connected();
|
||||
if (server_connected) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
portENTER_CRITICAL(&s_feedback_lock);
|
||||
bool confirmed_outage = s_feedback.state == NETWORK_FEEDBACK_STATE_WIFI_DOWN ||
|
||||
s_feedback.state == NETWORK_FEEDBACK_STATE_SERVER_DOWN;
|
||||
portEXIT_CRITICAL(&s_feedback_lock);
|
||||
if (wifi_connected && !confirmed_outage) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
int64_t now_us = control_plane_network_feedback_now_us();
|
||||
bool should_play = false;
|
||||
const char *prompt_path = NULL;
|
||||
|
||||
portENTER_CRITICAL(&s_feedback_lock);
|
||||
control_plane_network_feedback_begin_outage_locked();
|
||||
if (!wifi_connected) {
|
||||
s_feedback.state = NETWORK_FEEDBACK_STATE_WIFI_DOWN;
|
||||
s_feedback.server_down_since_us = 0;
|
||||
prompt_path = CONTROL_PLANE_WIFI_ACTION_BLOCKED_PROMPT_FILE;
|
||||
} else {
|
||||
s_feedback.state = NETWORK_FEEDBACK_STATE_SERVER_DOWN;
|
||||
if (s_feedback.server_down_since_us == 0) {
|
||||
s_feedback.server_down_since_us = now_us;
|
||||
}
|
||||
prompt_path = CONTROL_PLANE_SERVER_ACTION_BLOCKED_PROMPT_FILE;
|
||||
}
|
||||
s_feedback.pending_prompt = NETWORK_FEEDBACK_PROMPT_NONE;
|
||||
s_feedback.passive_prompt_attempted = true;
|
||||
should_play = control_plane_network_feedback_begin_prompt_locked(now_us);
|
||||
portEXIT_CRITICAL(&s_feedback_lock);
|
||||
|
||||
ESP_LOGI(TAG,
|
||||
"Reject network action: action=%s wifi=%d server=%d prompt=%d",
|
||||
control_plane_network_action_name(action),
|
||||
wifi_connected ? 1 : 0,
|
||||
server_connected ? 1 : 0,
|
||||
should_play ? 1 : 0);
|
||||
|
||||
if (should_play) {
|
||||
(void)control_plane_network_feedback_play(prompt_path,
|
||||
control_plane_network_action_name(action));
|
||||
}
|
||||
if (wifi_connected) {
|
||||
(void)control_plane_schedule_websocket_wait_task();
|
||||
} else {
|
||||
control_plane_request_wifi_reconnect_now();
|
||||
}
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
@@ -246,6 +246,7 @@ static QueueHandle_t s_model_cmd_queue;
|
||||
static bool s_model_cmd_queue_with_caps;
|
||||
static TaskHandle_t s_model_cmd_task;
|
||||
static bool s_ws_start_requested;
|
||||
static bool s_wifi_reconnect_now_requested;
|
||||
#if CONFIG_TQ_NETWORK_AUTO_REASSOCIATION_ENABLE
|
||||
static uint32_t s_multimodal_network_failure_count;
|
||||
static bool s_wifi_reassociation_requested;
|
||||
@@ -594,6 +595,26 @@ static void control_plane_notify_wifi_state_task(void)
|
||||
}
|
||||
}
|
||||
|
||||
void control_plane_request_wifi_reconnect_now(void)
|
||||
{
|
||||
portENTER_CRITICAL(&s_runtime_lock);
|
||||
if (!s_runtime_stop_requested) {
|
||||
s_wifi_reconnect_now_requested = true;
|
||||
}
|
||||
portEXIT_CRITICAL(&s_runtime_lock);
|
||||
control_plane_notify_wifi_state_task();
|
||||
}
|
||||
|
||||
static bool control_plane_consume_wifi_reconnect_now_request(void)
|
||||
{
|
||||
bool requested = false;
|
||||
portENTER_CRITICAL(&s_runtime_lock);
|
||||
requested = s_wifi_reconnect_now_requested;
|
||||
s_wifi_reconnect_now_requested = false;
|
||||
portEXIT_CRITICAL(&s_runtime_lock);
|
||||
return requested;
|
||||
}
|
||||
|
||||
static void control_plane_request_ptt_expression(
|
||||
domain_expression_id_t id,
|
||||
domain_expression_trigger_t trigger)
|
||||
@@ -700,6 +721,13 @@ static void control_plane_set_ptt_active_with_trigger(
|
||||
}
|
||||
|
||||
control_plane_local_wake_pause_for_foreground();
|
||||
if (control_plane_network_feedback_require_ready(
|
||||
CONTROL_PLANE_NETWORK_ACTION_CONVERSATION) != ESP_OK) {
|
||||
ESP_LOGI(TAG, "PTT activation rejected while network service is unavailable");
|
||||
control_plane_local_wake_resume_after_foreground();
|
||||
return;
|
||||
}
|
||||
|
||||
ptt_state_t old_state = PTT_STATE_IDLE;
|
||||
ptt_state_t new_state = PTT_STATE_IDLE;
|
||||
uint32_t generation = 0;
|
||||
@@ -1705,6 +1733,7 @@ static bool control_plane_try_start_multimodal_from_state_machine(TickType_t *la
|
||||
#if CONFIG_TQ_NETWORK_AUTO_REASSOCIATION_ENABLE
|
||||
control_plane_record_multimodal_network_result(err);
|
||||
#endif
|
||||
control_plane_network_feedback_mark_server_down();
|
||||
ESP_LOGW(TAG, "Multimodal client start failed: %s", esp_err_to_name(err));
|
||||
return false;
|
||||
}
|
||||
@@ -2082,6 +2111,8 @@ static void control_plane_wifi_state_task(void *arg)
|
||||
|
||||
bool connected = control_plane_is_sta_connected();
|
||||
TickType_t now_tick = xTaskGetTickCount();
|
||||
bool reconnect_now_requested =
|
||||
control_plane_consume_wifi_reconnect_now_request();
|
||||
|
||||
#if CONFIG_TQ_MEMORY_MONITOR_ENABLE
|
||||
control_plane_memory_monitor_sample(now_tick, false);
|
||||
@@ -2099,6 +2130,7 @@ static void control_plane_wifi_state_task(void *arg)
|
||||
|
||||
bool ptt_foreground_disconnect = control_plane_get_ptt_active();
|
||||
bool disconnect_grace_elapsed =
|
||||
reconnect_now_requested ||
|
||||
ptt_foreground_disconnect ||
|
||||
disconnected_expression_active ||
|
||||
(now_tick - disconnect_started_tick) >= disconnect_grace_ticks;
|
||||
@@ -2108,8 +2140,10 @@ static void control_plane_wifi_state_task(void *arg)
|
||||
|
||||
if (!disconnected_expression_active) {
|
||||
ESP_LOGI(TAG, "Wi-Fi STA disconnect persisted; stopping multimodal client");
|
||||
control_plane_network_feedback_mark_wifi_down();
|
||||
(void)control_plane_stop_multimodal_client();
|
||||
control_plane_stop_user_config_server();
|
||||
control_plane_network_feedback_service();
|
||||
}
|
||||
|
||||
bool refresh_due = disconnected_expression_active &&
|
||||
@@ -2139,6 +2173,7 @@ static void control_plane_wifi_state_task(void *arg)
|
||||
ptt_wifi_foreground_attempts <
|
||||
CONTROL_PLANE_PTT_FOREGROUND_RECONNECT_MAX_ATTEMPTS;
|
||||
bool reconnect_due = ptt_foreground ||
|
||||
reconnect_now_requested ||
|
||||
!reconnect_attempted ||
|
||||
(now_tick - last_reconnect_attempt_tick) >= reconnect_delay_ticks;
|
||||
bool provisioning_running =
|
||||
@@ -2226,6 +2261,7 @@ static void control_plane_wifi_state_task(void *arg)
|
||||
|
||||
if (connected && (!was_connected || disconnected_expression_active)) {
|
||||
ESP_LOGI(TAG, "Wi-Fi STA connected; restoring idle expression");
|
||||
control_plane_network_feedback_mark_wifi_recovered();
|
||||
control_plane_start_wall_clock_sync();
|
||||
control_plane_request_wifi_state_expression(DOMAIN_EXPRESSION_IDLE,
|
||||
DOMAIN_EXPRESSION_TRIGGER_WIFI_RECONNECTED,
|
||||
@@ -2280,6 +2316,8 @@ static void control_plane_wifi_state_task(void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
control_plane_network_feedback_service();
|
||||
|
||||
was_connected = connected;
|
||||
}
|
||||
|
||||
@@ -2575,6 +2613,10 @@ esp_err_t control_plane_start_lcd_render_worker(void)
|
||||
esp_err_t control_plane_start_runtime_workers(void)
|
||||
{
|
||||
control_plane_set_runtime_stop_requested(false);
|
||||
control_plane_network_feedback_reset();
|
||||
portENTER_CRITICAL(&s_runtime_lock);
|
||||
s_wifi_reconnect_now_requested = false;
|
||||
portEXIT_CRITICAL(&s_runtime_lock);
|
||||
|
||||
#if CONFIG_TQ_MEMORY_MONITOR_ENABLE
|
||||
memset(&s_memory_monitor, 0, sizeof(s_memory_monitor));
|
||||
@@ -2813,6 +2855,7 @@ void control_plane_stop_runtime_workers(void)
|
||||
control_plane_delete_model_cmd_queue(queue, queue_with_caps);
|
||||
|
||||
(void)control_plane_stop_multimodal_client();
|
||||
control_plane_network_feedback_reset();
|
||||
control_plane_set_runtime_stop_requested(false);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user