WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GetSelect4gorbt() == AI_SELECT_4G");
if (GetInit_4gai_task())
{
+#ifdef SUPPORT_AI_SERVICE
uapi_start_AI_asr();
+#endif
}
else
{
WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "停止录音");
if (GetSelect4gorbt() == AI_SELECT_4G) // 选的是4G需要关闭asr
{
+#ifdef SUPPORT_AI_SERVICE
uapi_stop_AI_asr();
+#endif
}
else if (GetSelect4gorbt() == AI_SELECT_BT)
{
if (AiVoiceModel::GetInstance().GetSelect4gorbt() == AI_SELECT_4G)
{
// dinit_ai_task(); // 所有服务都删除重新连一下服务器
- stop_all_websocket_servers();
- destroy_all_websocket_servers();
+#ifdef SUPPORT_AI_SERVICE
+ uapi_stop_all_websocket_servers();
+ uapi_destroy_all_websocket_servers();
+#endif
}
SendMsgToUIService(UI_AI_JUMP_TO_RESPONDERR_VIEW, 0, (void *)str.c_str(), str.length());
if (AiVoiceModel::GetInstance().GetSelect4gorbt() == AI_SELECT_4G)
{
// dinit_ai_task(); // 所有服务都删除重新连一下服务器
- stop_all_websocket_servers();
- destroy_all_websocket_servers();
+#ifdef SUPPORT_AI_SERVICE
+ uapi_stop_all_websocket_servers();
+ uapi_destroy_all_websocket_servers();
+#endif
}
p_AiVoicePresenter->ChangeViewAndLogicOperator(AIVOICE_AIMODE_CONNECTING, AIVOICE_AIMODEL_CONNECT_FAILED_VIEWID);
}
(view_->GetAiVoiceScrollView(AIVOICE_4GSERVICECON_VIEW)->IsVisible()))
{
// dinit_ai_task(); // 所有服务都删除重新连一下服务器
- stop_all_websocket_servers();
- destroy_all_websocket_servers();
+#ifdef SUPPORT_AI_SERVICE
+ uapi_stop_all_websocket_servers();
+ uapi_destroy_all_websocket_servers();
+#endif
p_AiVoicePresenter->ChangeViewAndLogicOperator(AIVOICE_4GSERVICECON_VIEW, AIVOICE_AIMODEL_CONNECT_FAILED_VIEWID);
}
}
#include "aivoice/include/AiVoiceSelectView.h"
#include "graphic_service.h"
#include "websocket_server_manager.h"
+#include "custom_utils.h"
namespace OHOS
{
model->stop_uapi_stop_tts_timer();
remove_4GAI_vote(); // 移除4g投票
- stop_all_websocket_servers();
- destroy_all_websocket_servers();
+#ifdef SUPPORT_AI_SERVICE
+ uapi_stop_all_websocket_servers();
+ uapi_destroy_all_websocket_servers();
+#endif
// dinit_ai_task();
// ai_cleanup_resources();
{
/* -------------------------------------------------------------------------- */
// init_ai_task(AiVoiceModel::GetInstance().GetCurUsing4GAiModelType());
- init_all_websocket_servers();
- start_all_websocket_servers(); // 连接服务器
+#ifdef SUPPORT_AI_SERVICE
+ uapi_init_all_websocket_servers();
+ uapi_start_all_websocket_servers(); // 连接服务器
+#endif
/* -------------------------------------------------------------------------- */
model->start_ai4g_connect_timer();
ChangeViewAndLogicOperator(AIVOICE_STARTCHAT_VIEWID, AIVOICE_4GSERVICECON_VIEW); // LOADING
if (!model->GetInit_4gai_task())
{
// init_ai_task(AiVoiceModel::GetInstance().GetCurUsing4GAiModelType());
- init_all_websocket_servers();
- start_all_websocket_servers(); // 连接服务器
+#ifdef SUPPORT_AI_SERVICE
+ uapi_init_all_websocket_servers();
+ uapi_start_all_websocket_servers(); // 连接服务器
+#endif
model->start_ai4g_connect_timer();
ChangeViewAndLogicOperator(model->GetCurView(), AIVOICE_4GSERVICECON_VIEW); // LOADING
}
{
AiVoiceModel::GetInstance().stop_ai4g_tts_play_timer();
AiVoiceModel::GetInstance().stop_uapi_stop_tts_timer();
- stop_all_websocket_servers();
- destroy_all_websocket_servers();
+#ifdef SUPPORT_AI_SERVICE
+ uapi_stop_all_websocket_servers();
+ uapi_destroy_all_websocket_servers();
+#endif
}
}
ChangeViewAndLogicOperator(it->second.first, it->second.second);
if (model->GetSelect4gorbt() == AI_SELECT_4G)
{
// dinit_ai_task();
- stop_all_websocket_servers();
- destroy_all_websocket_servers();
+#ifdef SUPPORT_AI_SERVICE
+ uapi_stop_all_websocket_servers();
+ uapi_destroy_all_websocket_servers();
+#endif
}
}
ChangeViewAndLogicOperator(it->second.first, it->second.second);
# 'AILPAY_SUPPORT',
'SUPPORT_FACTORY_SERVICE',
# 'MEMORY_CORRUPTION',
+ 'SUPPORT_AI_SERVICE',
],
#添加自定义应用
"transspecard",
"factorytest_service",
# "hid_service",
+
+ #websocket 相关配置
+ "zhihui_websocket",
+ #ai 相关配置
+ "aiMediaService",
+ "aiService",
+ #ai_old相关配置
+ "zhihui_ai_old",
+ #音频相关配置
+ "audio_manager",
+
"producttest",
"ppg_hal",
"mag_service",
return AUDIO_SUCCESS;
}
+int32_t AudioStreamOutFlush(void)
+{
+ int32_t ret = g_streamOut->Flush();
+ if (ret != AUDIO_SUCCESS) {
+ ALOGE("audio stream out Flush failed 0x%x", ret);
+ return AUDIO_ERROR;
+ }
+
+ ALOGD("success");
+ return AUDIO_SUCCESS;
+}
+
int32_t AudioStreamOutStreamWrite(const uint8_t *data, uint32_t size)
{
uint64_t writtenSize = 0;
int32_t AudioStreamOutStop(void)
{
- int32_t ret = g_streamOut->Stop();
+ int32_t ret = g_streamOut->Pause();
if (ret != AUDIO_SUCCESS) {
ALOGE("audio stream out stop failed 0x%x", ret);
return AUDIO_ERROR;
int32_t AudioStreamOutDeinit(void);
+int32_t AudioStreamOutFlush(void);
+
/**
* @brief Sets audio effect algorithm parameters.
*
int32_t AI_SendAudioDataToQueue(const uint8_t* data, uint32_t size);
+/*
+ * @brief 设置AI语音打断标志
+ * @param interrupt 打断标志,true表示需要清空队列并恢复输出流,false表示清除标志
+ * @return 0 成功,-1 失败
+ */
+int32_t AI_SetInterruptFlag(bool interrupt);
+
+/*
+ * @brief 获取AI语音打断标志
+ * @return true 打断标志已设置,false 打断标志未设置或服务未运行
+ */
+bool AI_GetInterruptFlag(void);
+
+/*
+ * @brief 强制清空AI语音队列并恢复输出流
+ * @return 0 成功,-1 失败
+ */
+int32_t AI_ForceInterrupt(void);
+
#ifdef __cplusplus
};
#endif
typedef struct {
AudioSession sessionId;
bool isAIVoiceStopped;
+ bool interruptFlag; // 打断标志,设置时清空队列并重置流
MediaThreadCondHandle cond; // 保留条件变量用于线程同步
MediaThreadIdHandle taskHandle;
char threadName[32]; // 线程名称,用于验证线程ID
MEDIA_INFO_LOG("RunAIVoice: waiting for queue data...");
while (!context->isAIVoiceStopped) {
+// 检查打断标志
+ if (context->interruptFlag) {
+ MEDIA_INFO_LOG("Interrupt flag set, clearing queue and resuming output stream...");
+ // 清除打断标志
+ context->interruptFlag = false;
+
+ MEDIA_INFO_LOG("Interrupt processing completed");
+ }
+
if (context->inputQueue != NULL) {
AIVoiceQueueMessage msg;
osStatus_t status = osMessageQueueGet(context->inputQueue, &msg, NULL, 100); // 100ms超时
return true;
}
+/**
+ * @brief 暂停音频输出流
+ * @return 0 成功,-1 失败
+ */
+static int32_t PauseAudioStreams(void)
+{
+ int32_t ret = 0;
+
+ // 只暂停输出流
+ ret = AudioStreamOutStop();
+ if (ret != 0) {
+ MEDIA_ERR_LOG("audio stream out stop failed: %d", ret);
+ }
+
+ MEDIA_INFO_LOG("Audio output stream paused");
+ return 0;
+}
+
+/**
+ * @brief 清空音频输出流缓冲区
+ * @return 0 成功,-1 失败
+ */
+static int32_t ClearAudioStreams(void)
+{
+ int32_t ret = 0;
+
+ // 只清空输出流缓冲区
+ ret = AudioStreamOutFlush();
+ if (ret != 0) {
+ MEDIA_ERR_LOG("audio stream out flush failed: %d", ret);
+ }
+
+ MEDIA_INFO_LOG("Audio output stream cleared");
+ return 0;
+}
+
+/**
+ * @brief 恢复音频输出流
+ * @return 0 成功,-1 失败
+ */
+static int32_t ResetAudioStreams(void)
+{
+ int32_t ret = 0;
+
+ // 只恢复输出流,不进行销毁重建
+ ret = AudioStreamOutPlay();
+ if (ret != 0) {
+ MEDIA_ERR_LOG("audio stream out resume failed: %d", ret);
+ }
+
+ MEDIA_INFO_LOG("Audio output stream resumed");
+ return 0;
+}
+
+/**
+ * @brief 清空AI语音队列
+ * @param context AI语音上下文
+ * @return 0 成功,-1 失败
+ */
+static int32_t ClearAIVoiceQueue(AIVoiceContext *context)
+{
+ if (context == nullptr || context->inputQueue == NULL) {
+ MEDIA_ERR_LOG("AI voice context or queue is null");
+ return -1;
+ }
+
+ AIVoiceQueueMessage msg;
+ uint32_t clearedCount = 0;
+
+ // 清空队列中的所有消息
+ while (osMessageQueueGet(context->inputQueue, &msg, NULL, 0) == osOK) {
+ if (msg.data != nullptr) {
+ free(msg.data);
+ msg.data = nullptr;
+ }
+ clearedCount++;
+ }
+
+ // 重置队列消息计数
+ context->queueMsgCount = 0;
+
+ MEDIA_INFO_LOG("AI voice queue cleared: %u messages removed", clearedCount);
+ return 0;
+}
+
static void AIVoiceThread(void *priv)
{
return -1;
}
AI_WRITE:
+ if(g_aiVoiceContext->interruptFlag)
+ return -1;
// 获取全局互斥锁(自动初始化)
MediaMutexHandle mutex = GetGlobalMutex();
if (mutex == nullptr) {
// 写入音频数据到输出流
int32_t ret = AudioStreamOutStreamWrite(data, size);
+ usleep(50*size);
if (ret != 0) {
// MEDIA_ERR_LOG("Failed to write audio data to output stream, ret=%d", ret);
- usleep(100000);
// return -1;
+ usleep(10000);
goto AI_WRITE;
}
- MEDIA_INFO_LOG("Successfully wrote %u bytes of audio data to output stream", size);
+ // MEDIA_INFO_LOG("Successfully wrote %u bytes of audio data to output stream", size);
return 0;
}
return 0;
}
+/**
+ * @brief 设置AI语音打断标志
+ * @param interrupt 打断标志,true表示需要清空队列并重置流,false表示清除标志
+ * @return 0 成功,-1 失败
+ */
+int32_t AI_SetInterruptFlag(bool interrupt)
+{
+ MediaMutexHandle mutex = GetGlobalMutex();
+ if (mutex == nullptr) {
+ MEDIA_ERR_LOG("Failed to get global mutex");
+ return -1;
+ }
+
+ MediaMutexLock(mutex);
+ if (g_aiVoiceContext == nullptr) {
+ MEDIA_ERR_LOG("AI voice context is null, please start AI voice first");
+ MediaMutexUnLock(mutex);
+ return -1;
+ }
+
+ g_aiVoiceContext->interruptFlag = interrupt;
+ MEDIA_INFO_LOG("AI voice interrupt flag set: %s", interrupt ? "true" : "false");
+
+ MediaMutexUnLock(mutex);
+ return 0;
+}
+
+/**
+ * @brief 获取AI语音打断标志
+ * @return true 打断标志已设置,false 打断标志未设置或服务未运行
+ */
+bool AI_GetInterruptFlag(void)
+{
+ bool interruptFlag = false;
+
+ MediaMutexHandle mutex = GetGlobalMutex();
+ if (mutex == nullptr) {
+ return false;
+ }
+
+ MediaMutexLock(mutex);
+ if (g_aiVoiceContext != nullptr) {
+ interruptFlag = g_aiVoiceContext->interruptFlag;
+ }
+ MediaMutexUnLock(mutex);
+
+ return interruptFlag;
+}
+
+/**
+ * @brief 强制清空AI语音队列并重置流
+ * @return 0 成功,-1 失败
+ */
+int32_t AI_ForceInterrupt(void)
+{
+ MediaMutexHandle mutex = GetGlobalMutex();
+ if (mutex == nullptr) {
+ MEDIA_ERR_LOG("Failed to get global mutex");
+ return -1;
+ }
+
+ MediaMutexLock(mutex);
+ if (g_aiVoiceContext == nullptr) {
+ MEDIA_ERR_LOG("AI voice context is null, please start AI voice first");
+ MediaMutexUnLock(mutex);
+ return -1;
+ }
+
+ // 设置打断标志
+ g_aiVoiceContext->interruptFlag = true;
+
+ // 立即清空队列
+ ClearAIVoiceQueue(g_aiVoiceContext);
+
+ // 立即暂停和清空输出流
+ PauseAudioStreams();
+ ClearAudioStreams();
+
+ // 立即恢复输出流
+ ResetAudioStreams();
+
+ MEDIA_INFO_LOG("AI voice force interrupt completed");
+
+ MediaMutexUnLock(mutex);
+ return 0;
+}
+
#ifdef __cplusplus
};
#endif
printf("CAT1TEST ATCMD Convert Command Failed\n");
return ERRCODE_FAIL;
}
+#ifdef SUPPORT_AI_SERVICE
init_all_websocket_servers();
start_all_websocket_servers();
+#endif
return 0;
}
printf("CAT1TEST ATCMD Convert Command Failed\n");
return ERRCODE_FAIL;
}
- uapi_start_AI_asr();
+ uapi_start_AI_asr_();
return 0;
}
printf("CAT1TEST ATCMD Convert Command Failed\n");
return ERRCODE_FAIL;
}
- uapi_stop_AI_asr();
+ uapi_stop_AI_asr_();
return 0;
}
extern void msleep(uint32_t ms);
printf("CAT1TEST ATCMD Convert Command Failed\n");
return ERRCODE_FAIL;
}
+#ifdef SUPPORT_AI_SERVICE
stop_all_websocket_servers();
msleep(1000);
destroy_all_websocket_servers();
+#endif
return 0;
}
asr_taskcfg.create_queue_handle = NULL;
asr_taskcfg.attr.name = "asr_server_init";
- asr_taskcfg.attr.priority = (osPriority_t)TASK_PRIORITY_APP;
+ asr_taskcfg.attr.priority = (osPriority_t)16;
asr_taskcfg.attr.stack_size = 0x1000;
asr_taskcfg.func = bk_websocket_asr;
asr_taskcfg.use_mem = USE_EXTEND_MEM;
/* 任务配置结构体 - 使用系统定义的 app_task_definition_t */
/* 常量定义 */
-#define TASK_PRIORITY_APP 24
-#define USE_EXTEND_MEM 1
+// #define TASK_PRIORITY_APP 24
+// #define USE_EXTEND_MEM 1
/* ASR 服务接口函数 */
strncpy(out_put, content_str, copy_size);
out_put[copy_size] = '\0';
}
-
- // 原有的处理逻辑保持不变
- if (event_type == CHAT_EVENT_MIDDLE) {
- char *content_str_chat = (char *)malloc(strlen(content_str) + 1);
- if (content_str_chat != NULL) {
- strcpy(content_str_chat, content_str);
- ble_set_ai_Answer_str(content_str_chat, 2);
- free(content_str_chat);
- }
- } else if (event_type == CHAT_EVENT_END) {
- char end_str_chat[128] = {0};
- memset(end_str_chat, 0, 128);
- memcpy(end_str_chat, content_str, strlen(content_str) < 127 ? strlen(content_str) : 127);
- ble_set_ai_Answer_str(end_str_chat, 2);
- }
}
cJSON_Delete(root);
static char *tts_cached_text = NULL; // 缓存待发送的文本字符串(动态分配)
static int tts_cached_length = 0; // 当前缓存的文本长度
static int tts_cached_capacity = 0; // 当前分配的内存容量
+static bool tts_has_stop_cached = false; // 是否缓存了stop命令
// static bool tts_is_ready = false; // TTS是否准备就绪
/**
tts_cached_length = 0;
}
+ // 检查是否有缓存的stop命令需要发送
+ if (tts_has_stop_cached) {
+ printf("TTS ready, sending cached stop command\n");
+ uapi_stop_tts_type_stop(tts_client);
+ tts_has_stop_cached = false; // 重置标志
+ }
+
// 发送本次携带的内容
if (buf && strlen(buf) > 0) {
printf("TTS ready, sending current text: %s\n", buf);
memset(tts_cached_text, 0, tts_cached_capacity);
}
tts_cached_length = 0;
+ tts_has_stop_cached = false; // 同时清空stop缓存标志
printf("TTS cache cleared\n");
}
+/**
+ * @brief 缓存stop命令
+ * @param tts_client TTS WebSocket客户端
+ * @param ready true: 如果TTS就绪则直接发送stop命令, false: 缓存stop命令等待TTS就绪
+ * @return true 成功,false 失败
+ */
+bool uapi_cache_stop_command(WebSocketClient *tts_client, bool ready)
+{
+ if (ready) {
+ // 如果TTS就绪,直接发送stop命令
+ if (tts_client != NULL) {
+ uapi_stop_tts_type_stop(tts_client);
+ printf("TTS ready, stop command sent directly\n");
+ return true;
+ } else {
+ printf("TTS client is NULL, cannot send stop command\n");
+ return false;
+ }
+ } else {
+ // 如果TTS未就绪,缓存stop命令
+ tts_has_stop_cached = true;
+ printf("TTS not ready, stop command cached\n");
+ return true;
+ }
+}
+
/**
* @brief 初始化TTS缓存内存
* @return true 成功,false 失败
goto cleanup;
}
- if (cJSON_AddNumberToObject(payload, "volume", 80) == NULL) {
+ if (cJSON_AddNumberToObject(payload, "volume", 50) == NULL) {
printf("Failed to add volume field\n");
goto cleanup;
}
*
* // 或者使用全局客户端停止
* uapi_stop_tts_type_stop(g_tts_server->client);
+ *
+ * // 新增功能:智能stop命令处理
+ * // 检查TTS是否就绪
+ * tts_ready_status_t ready_status = uapi_get_tts_ready();
+ * bool is_ready = (ready_status == TTS_READY_SUCCESS_READY);
+ *
+ * // 如果就绪则直接发送stop命令,否则缓存等待就绪
+ * uapi_cache_stop_command(client, is_ready);
+ *
+ * // 或者手动处理文本和stop命令
+ * // 添加文本到缓存(TTS未就绪时)
+ * uapi_tts_process_text(client, "Hello world", false);
+ *
+ * // 当TTS就绪时,清理缓存并发送所有内容(包括stop命令)
+ * uapi_tts_process_text(client, "", true); // 空字符串表示只清理缓存
*/
#ifdef __cplusplus
*/
void uapi_clear_tts_cache(void);
+/**
+ * @brief 缓存stop命令
+ * @param tts_client TTS WebSocket客户端
+ * @param ready true: 如果TTS就绪则直接发送stop命令, false: 缓存stop命令等待TTS就绪
+ * @return true 成功,false 失败
+ */
+bool uapi_cache_stop_command(WebSocketClient *tts_client, bool ready);
+
/**
* @brief 初始化TTS缓存内存
* @return true 成功,false 失败
break;
case ASR_EVENT_TRANSCRIPTION_COMPLETED:
+ g_chat_server->interrupt_flag=0;
ai_chat_send_txt(0, "", g_chat_server->client,true);
asr_is_ready=0;
break;
if (event_data->msg_type == WS_BINARY) {
printf("TTS binary data: %d bytes\n", event_data->data_len);
set_AIStreamend(0);
- // AI_WriteAudioData(event_data->data, event_data->data_len);
AI_SendAudioDataToQueue(event_data->data,event_data->data_len);
- // send_msg_data_into_Ai_msg_queue(event_data->data, event_data->data_len, 200);
} else if (event_data->msg_type == WS_TEXT) {
printf("TTS text data: %s\n", (char *)event_data->data);
tts_event_type_t event = tts_analysis((char *)event_data->data);
case TTS_EVENT_STARTED_SYNTHESIS:
printf("TTS synthesis started successfully\n");
tts_is_ready = TTS_READY_SUCCESS_READY;
+
uapi_tts_process_text(g_tts_server->client,"",(tts_is_ready == TTS_READY_SUCCESS_READY));
break;
case TTS_EVENT_END_SYNTHESIS:
if(tts_is_ready == TTS_READY_NOT_SENT) {
tts_is_ready = TTS_READY_SENT_SUCCESS;
+ g_tts_server->interrupt_flag=0;
uapi_start_tts_type_start(g_tts_server->client);
}
case CHAT_EVENT_END:
printf("Chat event: END - Final content: %s\n", buf);
- uapi_stop_tts_type_stop(g_tts_server->client);
+ ble_set_ai_Answer_str(buf, 2);
+
+ uapi_tts_process_text(g_tts_server->client,buf,(tts_is_ready == TTS_READY_SUCCESS_READY));
+ uapi_cache_stop_command(g_tts_server->client,(tts_is_ready == TTS_READY_SUCCESS_READY));
+
break;
case CHAT_EVENT_ERROR:
// 创建ASR服务器
ws_server_config_t asr_config = ws_server_get_default_config(WS_SERVER_TYPE_ASR);
asr_config.disconnect_strategy = WS_DISCONNECT_RECONNECT; // 设置自动重连
- asr_config.reconnect_interval_ms = 3000; // 3秒重连间隔
+ asr_config.reconnect_interval_ms = 500; // 3秒重连间隔
g_asr_server = ws_server_create(&asr_config, websocket_event_callback, NULL);
if (!g_asr_server) {
printf("Failed to create ASR server\n");
// 创建TTS服务器
ws_server_config_t tts_config = ws_server_get_default_config(WS_SERVER_TYPE_TTS);
tts_config.disconnect_strategy = WS_DISCONNECT_RECONNECT; // 设置自动重连
- tts_config.reconnect_interval_ms = 5000; // 5秒重连间隔
+ tts_config.reconnect_interval_ms = 500; // 5秒重连间隔
g_tts_server = ws_server_create(&tts_config, websocket_event_callback, NULL);
if (!g_tts_server) {
printf("Failed to create TTS server\n");
// 创建Chat服务器
ws_server_config_t chat_config = ws_server_get_default_config(WS_SERVER_TYPE_CHAT);
chat_config.disconnect_strategy = WS_DISCONNECT_RECONNECT; // 设置自动重连
- chat_config.reconnect_interval_ms = 2000; // 2秒重连间隔
+ chat_config.reconnect_interval_ms = 500; // 2秒重连间隔
g_chat_server = ws_server_create(&chat_config, websocket_event_callback, NULL);
if (!g_chat_server) {
printf("Failed to create Chat server\n");
}
-void uapi_start_AI_asr(void)
+void uapi_start_AI_asr_(void)
{
+ if(g_asr_server)
uapi_start_asr_StartTranscription(g_asr_server->client);
+ g_tts_server->interrupt_flag=1;
+ g_chat_server->interrupt_flag=1;
+ AI_ForceInterrupt();
}
-void uapi_stop_AI_asr(void)
+void uapi_stop_AI_asr_(void)
{
+ if(g_asr_server)
uapi_stop_asr_StopTranscription(g_asr_server->client);
}
config.type = type;
config.handshake_timeout_ms = 10000;
config.receive_timeout_ms = 30000;
- config.max_retry_count = 3;
+ config.max_retry_count = 0x1000;
config.buffer_size = 4096;
config.url_callback = NULL;
config.url_user_data = NULL;
handle->is_initialized = 1;
while (!handle->need_stop) {
+ // 检查打断标志,如果设置了则主动重连
+ if (handle->interrupt_flag && !handle->need_stop ) {
+ printf("Interrupt flag set, attempting reconnect...\n");
+ handle->interrupt_flag = 0; // 清除打断标志
+ ws_server_trigger_event(handle, WS_EVENT_RECONNECTING, NULL, 0, WS_TEXT, 0);
+
+ if (ws_server_should_reconnect(handle)) {
+ if (ws_server_attempt_reconnect(handle)) {
+ last_activity = (uint32_t)osKernelGetTickCount();
+ printf("Reconnect successful after interrupt\n");
+ continue;
+ } else {
+ printf("Reconnect failed after interrupt\n");
+ break;
+ }
+ } else {
+ printf("Reconnect not allowed after interrupt\n");
+ break;
+ }
+ }
+
// 检查超时
if ((uint32_t)osKernelGetTickCount() - last_activity > handle->config.receive_timeout_ms) {
printf("Receive timeout, checking reconnect strategy...\n");
// handle->config.receive_timeout_ms);
int len = receive_websocket_message(handle->client,(unsigned char *)handle->recv_buffer,handle->config.buffer_size, &msg_type, handle->config.receive_timeout_ms);
+ if (handle->interrupt_flag && !handle->need_stop ) {
+ printf("Interrupt flag set, attempting reconnect...\n");
+ handle->interrupt_flag = 0; // 清除打断标志
+ ws_server_trigger_event(handle, WS_EVENT_RECONNECTING, NULL, 0, WS_TEXT, 0);
+
+ if (ws_server_should_reconnect(handle)) {
+ if (ws_server_attempt_reconnect(handle)) {
+ last_activity = (uint32_t)osKernelGetTickCount();
+ printf("Reconnect successful after interrupt\n");
+ continue;
+ } else {
+ printf("Reconnect failed after interrupt\n");
+ break;
+ }
+ } else {
+ printf("Reconnect not allowed after interrupt\n");
+ break;
+ }
+ }
+
if (len == -1 || msg_type == WS_CLOSE) {
printf("WebSocket connection closed, checking reconnect strategy...\n");
ws_server_trigger_event(handle, WS_EVENT_DISCONNECTED, NULL, 0, WS_TEXT, 0);
printf("Connecting to: %s\n", url_buf);
// 创建WebSocket客户端
- uint8_t client_count = handle->config.max_retry_count;
+ uint32_t client_count = handle->config.max_retry_count;
while (client_count > 0) {
handle->client = init_websocket_client(url_buf, NULL, 0);
if (handle->client) {
return success;
}
+/**
+ * @brief 设置WebSocket服务器打断标志
+ * @param server_type 服务器类型
+ * @param interrupt 打断标志,1表示需要重连,0表示清除标志
+ * @return errcode_t 错误码
+ */
+errcode_t ws_server_set_interrupt_flag(ws_server_type_t server_type, uint8_t interrupt)
+{
+ if (server_type >= WS_SERVER_TYPE_MAX) {
+ printf("Invalid server type: %d\n", server_type);
+ return ERRCODE_FAIL;
+ }
+
+ ws_server_handle_t *handle = g_thread_handles[server_type];
+ if (!handle) {
+ printf("Server handle not found for type: %d\n", server_type);
+ return ERRCODE_FAIL;
+ }
+
+ handle->interrupt_flag = interrupt;
+ printf("WebSocket server interrupt flag set: type=%d, interrupt=%d\n", server_type, interrupt);
+
+ return ERRCODE_SUCC;
+}
+
+/**
+ * @brief 获取WebSocket服务器打断标志
+ * @param server_type 服务器类型
+ * @return uint8_t 打断标志状态
+ */
+uint8_t ws_server_get_interrupt_flag(ws_server_type_t server_type)
+{
+ if (server_type >= WS_SERVER_TYPE_MAX) {
+ printf("Invalid server type: %d\n", server_type);
+ return 0;
+ }
+
+ ws_server_handle_t *handle = g_thread_handles[server_type];
+ if (!handle) {
+ printf("Server handle not found for type: %d\n", server_type);
+ return 0;
+ }
+
+ return handle->interrupt_flag;
+}
+
#ifdef __cplusplus
}
#endif
uint8_t is_running; // 运行标志
uint8_t need_stop; // 停止标志
uint8_t is_initialized; // 初始化标志
+ uint8_t interrupt_flag; // 打断标志,设置时主动重连
char *recv_buffer; // 接收缓冲区
uint32_t reconnect_count; // 重连次数
uint32_t last_reconnect_time; // 上次重连时间
errcode_t init_all_websocket_servers(void);
-void uapi_start_AI_asr(void);
-void uapi_stop_AI_asr(void);
void stop_all_websocket_servers(void);
+void destroy_all_websocket_servers(void);
+
+
+
bool are_all_services_ready(void);
uint8_t get_asr_is_ready_start_old(void);
-void destroy_all_websocket_servers(void);
+
+
+void uapi_start_AI_asr_(void);
+
+void uapi_stop_AI_asr_(void);
+
+/**
+ * @brief 设置WebSocket服务器打断标志
+ * @param server_type 服务器类型
+ * @param interrupt 打断标志,1表示需要重连,0表示清除标志
+ * @return errcode_t 错误码
+ */
+errcode_t ws_server_set_interrupt_flag(ws_server_type_t server_type, uint8_t interrupt);
+
+/**
+ * @brief 获取WebSocket服务器打断标志
+ * @param server_type 服务器类型
+ * @return uint8_t 打断标志状态
+ */
+uint8_t ws_server_get_interrupt_flag(ws_server_type_t server_type);
#ifdef __cplusplus
#include "custom_utils.h"
+#ifdef SUPPORT_AI_SERVICE
+#include "asr_websocket_server.h"
+#endif
+
+#ifdef SUPPORT_AI_SERVICE
+#include "websocket_server_manager.h"
+#endif
+
#ifdef FD230_650
#include "ui_serviceC.h"
#include "alarm/include/AlarmClockModelC.h"
uapi_check_mic(0);
break;
+case CUSTOM_CMD_MSG_START_AI_ASR:
+#ifdef SUPPORT_AI_SERVICE
+ uapi_start_AI_asr_();
+ PRINT("AI ASR started via custom cmd\n");
+#else
+ PRINT("AI ASR service not supported\n");
+#endif
+ break;
+
+ case CUSTOM_CMD_MSG_STOP_AI_ASR:
+#ifdef SUPPORT_AI_SERVICE
+ uapi_stop_AI_asr_();
+ PRINT("AI ASR stopped via custom cmd\n");
+#else
+ PRINT("AI ASR service not supported\n");
+#endif
+ break;
+
+ case CUSTOM_CMD_MSG_START_ALL_WEBSOCKET_SERVERS:
+#ifdef SUPPORT_AI_SERVICE
+ start_all_websocket_servers();
+ PRINT("All WebSocket servers started via custom cmd\n");
+#else
+ PRINT("WebSocket service not supported\n");
+#endif
+ break;
+
+ case CUSTOM_CMD_MSG_INIT_ALL_WEBSOCKET_SERVERS:
+#ifdef SUPPORT_AI_SERVICE
+ init_all_websocket_servers();
+ PRINT("All WebSocket servers initialized via custom cmd\n");
+#else
+ PRINT("WebSocket service not supported\n");
+#endif
+ break;
+
+ case CUSTOM_CMD_MSG_STOP_ALL_WEBSOCKET_SERVERS:
+#ifdef SUPPORT_AI_SERVICE
+ stop_all_websocket_servers();
+ PRINT("All WebSocket servers stopped via custom cmd\n");
+#else
+ PRINT("WebSocket service not supported\n");
+#endif
+ break;
+
+ case CUSTOM_CMD_MSG_DESTROY_ALL_WEBSOCKET_SERVERS:
+#ifdef SUPPORT_AI_SERVICE
+ destroy_all_websocket_servers();
+ PRINT("All WebSocket servers destroyed via custom cmd\n");
+#else
+ PRINT("WebSocket service not supported\n");
+#endif
+ break;
+
default:
PRINT("Unknown CUSTOM_CMD_MSG cmd 0x%02X \r\n", mail.cmd);
break;
// void custom_cmd_service_service_suspend(void)
// {
// PRINT("custom_cmd_service_service suspend!\r\n");
-// }
\ No newline at end of file
+// }
+
+#ifdef SUPPORT_AI_SERVICE
+/**
+ * @brief 启动AI ASR服务
+ */
+void uapi_start_AI_asr(void)
+{
+ do_custom_cmd_service_check_msg(CUSTOM_CMD_MSG_START_AI_ASR, NULL, 0);
+}
+
+/**
+ * @brief 停止AI ASR服务
+ */
+void uapi_stop_AI_asr(void)
+{
+ do_custom_cmd_service_check_msg(CUSTOM_CMD_MSG_STOP_AI_ASR, NULL, 0);
+}
+
+#ifdef SUPPORT_AI_SERVICE
+/**
+ * @brief 启动所有WebSocket服务器
+ */
+void uapi_start_all_websocket_servers(void)
+{
+ do_custom_cmd_service_check_msg(CUSTOM_CMD_MSG_START_ALL_WEBSOCKET_SERVERS, NULL, 0);
+}
+
+/**
+ * @brief 初始化所有WebSocket服务器
+ */
+void uapi_init_all_websocket_servers(void)
+{
+ do_custom_cmd_service_check_msg(CUSTOM_CMD_MSG_INIT_ALL_WEBSOCKET_SERVERS, NULL, 0);
+}
+
+/**
+ * @brief 停止所有WebSocket服务器
+ */
+void uapi_stop_all_websocket_servers(void)
+{
+ do_custom_cmd_service_check_msg(CUSTOM_CMD_MSG_STOP_ALL_WEBSOCKET_SERVERS, NULL, 0);
+}
+
+/**
+ * @brief 销毁所有WebSocket服务器
+ */
+void uapi_destroy_all_websocket_servers(void)
+{
+ do_custom_cmd_service_check_msg(CUSTOM_CMD_MSG_DESTROY_ALL_WEBSOCKET_SERVERS, NULL, 0);
+}
+#endif
+#endif
\ No newline at end of file
return ERRCODE_SUCC;
}
+/**
+ * @brief 扩展的任务定义结构体,支持传入实例参数
+ */
+/**
+ * @brief 创建带实例参数的自定义线程
+ * @param task_cfg 扩展的任务配置结构体,包含inst_args参数
+ * @return 成功返回ERRCODE_SUCC,失败返回ERRCODE_FAIL
+ */
+errcode_t uapi_create_osThread_custom_with_args(app_task_definition_ext_t *task_cfg)
+{
+ if (task_cfg == NULL) {
+ return ERRCODE_FAIL;
+ }
+
+ /* Create queues before tasks in case they are used during initialisation. */
+ if (task_cfg->create_queue_handle) {
+ task_cfg->create_queue_handle();
+ }
+
+ /* Create tasks */
+ if (task_cfg->use_mem == USE_EXTEND_MEM) {
+ task_cfg->attr.stack_mem = memalign(16, task_cfg->attr.stack_size); // 16字节对齐
+ }
+
+ /* 创建线程,传入inst_args作为参数 */
+ task_cfg->task_handle = osThreadNew(task_cfg->func, task_cfg->inst_args, &(task_cfg->attr));
+ if (task_cfg->task_handle == NULL) {
+ return ERRCODE_FAIL;
+ }
+
+ return ERRCODE_SUCC;
+}
+
errcode_t uapi_terminate_thread(void* thread_id)
{
osStatus_t ret = osThreadTerminate((osThreadId_t)thread_id);
#define CUSTOM_CMD_MSG_CONNECT_AG 0x1F
+#define CUSTOM_CMD_MSG_START_AI_ASR 0x20
+
+#define CUSTOM_CMD_MSG_STOP_AI_ASR 0x21
+
+#define CUSTOM_CMD_MSG_START_ALL_WEBSOCKET_SERVERS 0x22
+
+#define CUSTOM_CMD_MSG_INIT_ALL_WEBSOCKET_SERVERS 0x23
+
+#define CUSTOM_CMD_MSG_STOP_ALL_WEBSOCKET_SERVERS 0x24
+
+#define CUSTOM_CMD_MSG_DESTROY_ALL_WEBSOCKET_SERVERS 0x25
+
typedef enum {
BR_HFP_CONNECT=1,
BR_HFP_DISCONNECT,
errcode_t do_custom_cmd_service_check_msg(int cmd, void *params, int paramlen);
errcode_t do_custom_cmd_service_check_msg_head(int cmd, void *params, int paramlen);
+#ifdef SUPPORT_AI_SERVICE
+void uapi_start_AI_asr(void);
+void uapi_stop_AI_asr(void);
+#endif
+
+#ifdef SUPPORT_AI_SERVICE
+void uapi_start_all_websocket_servers(void);
+void uapi_init_all_websocket_servers(void);
+void uapi_stop_all_websocket_servers(void);
+void uapi_destroy_all_websocket_servers(void);
+#endif
+
/***custom file operate cmd service*/
#define CUSTOM_FILEOPERATE_MSG_TYPE_SPORTDATA_SAVE 0x01 //运动数据
#define CUSTOM_FILEOPERATE_MSG_TYPE_HEARTRATE_SAVE 0x02 //心率数据
void uapi_lcd_backlight_on(uint8_t brightness);
void uapi_lcd_backlight_off(void);
+
+/**
+ * @brief 扩展的任务定义结构体,支持传入实例参数
+ */
+typedef struct {
+ osThreadAttr_t attr; // 线程属性
+ osThreadFunc_t func; // 线程函数
+ uint32_t *task_handle; // 任务句柄
+ CreateQueueFunction_t create_queue_handle; // 队列创建函数
+ uint32_t use_mem; // 内存使用类型
+ void *inst_args; // 实例参数指针
+} app_task_definition_ext_t;
+
+/**
+ * @brief 创建带实例参数的自定义线程
+ * @param task_cfg 扩展的任务配置结构体,包含inst_args参数
+ * @return 成功返回ERRCODE_SUCC,失败返回ERRCODE_FAIL
+ */
+errcode_t uapi_create_osThread_custom_with_args(app_task_definition_ext_t *task_cfg);
+
+
+
#include "custom_utilscpp.h"