fix(multimodal): prepare session for cloud fortune draw
This commit is contained in:
@@ -39,11 +39,12 @@
|
||||
#define CONTROL_PLANE_DOWNSTREAM_PLAYBACK_GUARD_MS 220
|
||||
#define CONTROL_PLANE_DOWNSTREAM_STALL_STOP_GRACE_MS 2000
|
||||
#define CONTROL_PLANE_IDLE_TRANSPORT_SHUTDOWN_MS 30000
|
||||
#define CONTROL_PLANE_WATCHDOG_TASK_STACK_SIZE 6144
|
||||
#define CONTROL_PLANE_WATCHDOG_TASK_STACK_SIZE 8192
|
||||
#define CONTROL_PLANE_SERVER_SUCCESS_PROMPT_FILE "/littlefs/audio_prompts/server_connect_success.opus"
|
||||
#define CONTROL_PLANE_CLIENT_LIFECYCLE_WAIT_MS 30000U
|
||||
#define CONTROL_PLANE_SERVER_SUCCESS_PROMPT_RETRY_MS 1000U
|
||||
#define CONTROL_PLANE_SERVER_SUCCESS_PROMPT_MAX_ATTEMPTS 3U
|
||||
#define CONTROL_PLANE_CLOUD_CHOUQIAN_PREPARE_TIMEOUT_MS 10000U
|
||||
|
||||
#ifndef CONFIG_TQ_NETWORK_TASK_CORE
|
||||
#define CONFIG_TQ_NETWORK_TASK_CORE 0
|
||||
@@ -66,6 +67,9 @@ static bool s_server_success_prompt_in_progress;
|
||||
static uint8_t s_server_success_prompt_attempts;
|
||||
static uint32_t s_server_success_prompt_next_attempt_ms;
|
||||
static bool s_cloud_chouqian_pending;
|
||||
static bool s_cloud_chouqian_action_in_progress;
|
||||
static bool s_cloud_chouqian_prompt_sent;
|
||||
static uint32_t s_cloud_chouqian_requested_ms;
|
||||
static bool s_downstream_stall_recovery_pending;
|
||||
static bool s_downstream_stall_stop_sent;
|
||||
static uint32_t s_downstream_stall_recovery_started_ms;
|
||||
@@ -128,6 +132,14 @@ static void set_multimodal_task_handle(TaskHandle_t *slot, TaskHandle_t task)
|
||||
portEXIT_CRITICAL(&s_multimodal_runtime_lock);
|
||||
}
|
||||
|
||||
static void control_plane_wake_multimodal_watchdog(void)
|
||||
{
|
||||
TaskHandle_t task = get_multimodal_task_handle(&s_multimodal_watchdog_task);
|
||||
if (task != NULL) {
|
||||
xTaskNotifyGive(task);
|
||||
}
|
||||
}
|
||||
|
||||
static void clear_multimodal_task_handle_if_match(TaskHandle_t *slot, TaskHandle_t expected_task)
|
||||
{
|
||||
portENTER_CRITICAL(&s_multimodal_runtime_lock);
|
||||
@@ -336,6 +348,9 @@ static void control_plane_clear_cloud_chouqian_pending(const char *reason)
|
||||
portENTER_CRITICAL(&s_multimodal_runtime_lock);
|
||||
was_pending = s_cloud_chouqian_pending;
|
||||
s_cloud_chouqian_pending = false;
|
||||
s_cloud_chouqian_action_in_progress = false;
|
||||
s_cloud_chouqian_prompt_sent = false;
|
||||
s_cloud_chouqian_requested_ms = 0U;
|
||||
portEXIT_CRITICAL(&s_multimodal_runtime_lock);
|
||||
|
||||
if (was_pending) {
|
||||
@@ -438,6 +453,93 @@ static uint32_t control_plane_now_ms(void)
|
||||
return (uint32_t)(xTaskGetTickCount() * portTICK_PERIOD_MS);
|
||||
}
|
||||
|
||||
static void control_plane_try_cloud_chouqian_request(void)
|
||||
{
|
||||
bool pending = false;
|
||||
bool prompt_sent = false;
|
||||
uint32_t requested_ms = 0U;
|
||||
|
||||
portENTER_CRITICAL(&s_multimodal_runtime_lock);
|
||||
pending = s_cloud_chouqian_pending;
|
||||
prompt_sent = s_cloud_chouqian_prompt_sent;
|
||||
requested_ms = s_cloud_chouqian_requested_ms;
|
||||
portEXIT_CRITICAL(&s_multimodal_runtime_lock);
|
||||
|
||||
if (!pending || prompt_sent) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t now_ms = control_plane_now_ms();
|
||||
if ((now_ms - requested_ms) >= CONTROL_PLANE_CLOUD_CHOUQIAN_PREPARE_TIMEOUT_MS) {
|
||||
control_plane_clear_cloud_chouqian_pending("session prepare timeout");
|
||||
return;
|
||||
}
|
||||
|
||||
control_plane_multimodal_runtime_state_t state = {0};
|
||||
esp_err_t state_err = control_plane_multimodal_get_runtime_state(&state);
|
||||
if (state_err != ESP_OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!state.connected) {
|
||||
(void)control_plane_schedule_websocket_wait_task();
|
||||
return;
|
||||
}
|
||||
|
||||
bool should_send_start = !state.has_active_task;
|
||||
bool should_send_prompt = state.has_active_task && state.server_listening;
|
||||
if (!should_send_start && !should_send_prompt) {
|
||||
return;
|
||||
}
|
||||
|
||||
portENTER_CRITICAL(&s_multimodal_runtime_lock);
|
||||
if (!s_cloud_chouqian_pending || s_cloud_chouqian_action_in_progress) {
|
||||
portEXIT_CRITICAL(&s_multimodal_runtime_lock);
|
||||
return;
|
||||
}
|
||||
s_cloud_chouqian_action_in_progress = true;
|
||||
if (should_send_prompt) {
|
||||
s_cloud_chouqian_prompt_sent = true;
|
||||
}
|
||||
portEXIT_CRITICAL(&s_multimodal_runtime_lock);
|
||||
|
||||
if (should_send_start) {
|
||||
esp_err_t start_err = control_plane_multimodal_send_start();
|
||||
|
||||
portENTER_CRITICAL(&s_multimodal_runtime_lock);
|
||||
s_cloud_chouqian_action_in_progress = false;
|
||||
portEXIT_CRITICAL(&s_multimodal_runtime_lock);
|
||||
|
||||
if (start_err == ESP_OK) {
|
||||
ESP_LOGI(TAG, "Cloud chouqian waiting for multimodal session");
|
||||
} else if (start_err != ESP_ERR_INVALID_STATE) {
|
||||
ESP_LOGW(TAG,
|
||||
"Cloud chouqian session start failed: %s",
|
||||
esp_err_to_name(start_err));
|
||||
control_plane_clear_cloud_chouqian_pending("session start failed");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const control_plane_multimodal_respond_request_t request = {
|
||||
.type = CONTROL_PLANE_MULTIMODAL_RESPOND_TYPE_PROMPT,
|
||||
.text = "我要抽签",
|
||||
.parameters_json = NULL,
|
||||
};
|
||||
esp_err_t request_err = control_plane_multimodal_send_request_to_respond(&request);
|
||||
|
||||
portENTER_CRITICAL(&s_multimodal_runtime_lock);
|
||||
s_cloud_chouqian_action_in_progress = false;
|
||||
portEXIT_CRITICAL(&s_multimodal_runtime_lock);
|
||||
|
||||
if (request_err != ESP_OK) {
|
||||
control_plane_clear_cloud_chouqian_pending("request send failed");
|
||||
return;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Cloud chouqian prompt sent");
|
||||
}
|
||||
|
||||
static bool control_plane_is_within_downstream_guard(const control_plane_multimodal_runtime_state_t *state,
|
||||
uint32_t guard_ms)
|
||||
{
|
||||
@@ -549,27 +651,22 @@ esp_err_t control_plane_multimodal_request_to_respond(
|
||||
|
||||
esp_err_t control_plane_request_cloud_chouqian(void)
|
||||
{
|
||||
uint32_t requested_ms = control_plane_now_ms();
|
||||
|
||||
portENTER_CRITICAL(&s_multimodal_runtime_lock);
|
||||
if (s_cloud_chouqian_pending) {
|
||||
portEXIT_CRITICAL(&s_multimodal_runtime_lock);
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
s_cloud_chouqian_pending = true;
|
||||
s_cloud_chouqian_action_in_progress = false;
|
||||
s_cloud_chouqian_prompt_sent = false;
|
||||
s_cloud_chouqian_requested_ms = requested_ms;
|
||||
s_model_command_dispatched = false;
|
||||
portEXIT_CRITICAL(&s_multimodal_runtime_lock);
|
||||
|
||||
const control_plane_multimodal_respond_request_t request = {
|
||||
.type = CONTROL_PLANE_MULTIMODAL_RESPOND_TYPE_PROMPT,
|
||||
.text = "我要抽签",
|
||||
.parameters_json = NULL,
|
||||
};
|
||||
esp_err_t err = control_plane_multimodal_send_request_to_respond(&request);
|
||||
if (err != ESP_OK) {
|
||||
control_plane_clear_cloud_chouqian_pending("request send failed");
|
||||
return err;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Cloud chouqian prompt sent");
|
||||
ESP_LOGI(TAG, "Cloud chouqian request queued");
|
||||
control_plane_wake_multimodal_watchdog();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@@ -613,7 +710,7 @@ static void multimodal_watchdog_task(void *arg)
|
||||
uint32_t idle_transport_started_ms = 0U;
|
||||
|
||||
while (!get_multimodal_stop_flag(&s_multimodal_watchdog_stop_requested)) {
|
||||
vTaskDelay(tick_interval);
|
||||
(void)ulTaskNotifyTake(pdTRUE, tick_interval);
|
||||
|
||||
control_plane_multimodal_runtime_state_t state = {0};
|
||||
if (control_plane_multimodal_get_runtime_state(&state) != ESP_OK) {
|
||||
@@ -622,6 +719,7 @@ static void multimodal_watchdog_task(void *arg)
|
||||
}
|
||||
|
||||
uint32_t now_ms = control_plane_now_ms();
|
||||
control_plane_try_cloud_chouqian_request();
|
||||
control_plane_try_server_success_prompt(&state, now_ms);
|
||||
bool stall_stop_sent = false;
|
||||
uint32_t stall_recovery_started_ms = 0U;
|
||||
@@ -771,9 +869,11 @@ static void control_plane_multimodal_event_bridge(control_plane_multimodal_event
|
||||
break;
|
||||
|
||||
case CONTROL_PLANE_MULTIMODAL_EVENT_TASK_STARTED:
|
||||
control_plane_wake_multimodal_watchdog();
|
||||
break;
|
||||
|
||||
case CONTROL_PLANE_MULTIMODAL_EVENT_SERVER_LISTENING:
|
||||
control_plane_wake_multimodal_watchdog();
|
||||
break;
|
||||
|
||||
case CONTROL_PLANE_MULTIMODAL_EVENT_SERVER_NOT_LISTENING:
|
||||
|
||||
Reference in New Issue
Block a user