#include <sys/time.h>
#include <time.h>
+#include "cmsis_os2.h"
+
#include "bletest.h"
#include "custom_utils.h"
#include "custom_runtime.h"
#include "dev_authentication.h"
#include "bk_websocket.h"
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "cmsis_os2.h"
+#include "bk_websocket.h"
+
+#include <stdint.h>
+#include <stdint.h>
+#include <asm/delay.h>
+#include "bts_br_gap.h"
+
+
// 内存管理和错误处理优化
#define AI_SAFE_MALLOC(size) ({ \
void* ptr = malloc(size); \
// 超时和重试配置
#define AI_CONNECT_TIMEOUT_MS 30000 // 30秒连接超时
-#define AI_RECEIVE_TIMEOUT_MS 60000 // 10秒接收超时
+#define AI_RECEIVE_TIMEOUT_MS 10000 // 10秒接收超时
#define AI_MAX_RETRY_COUNT 3 // 最大重试次数
#define AI_QUEUE_CHECK_INTERVAL 1000 // 队列检查间隔(ms)
}
}
+/**
+ * @brief 处理WebSocket连接失败的统一函数
+ * @param client_type 客户端类型字符串
+ * @param retry_count 当前重试次数
+ * @param max_retries 最大重试次数
+ * @return true 如果应该继续重试,false 如果应该停止重试
+ */
+static bool handle_websocket_connection_failure(const char* client_type, uint8_t retry_count, uint8_t max_retries) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "%s WebSocket connection failed, retries left: %d", client_type, max_retries - retry_count);
+
+ if (retry_count >= max_retries) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "%s WebSocket connection failed after %d retries, giving up", client_type, max_retries);
+ return false; // 停止重试
+ }
+
+ // 等待一段时间后重试
+ msleep(1000);
+ return true; // 继续重试
+}
+
+/**
+ * @brief 检查WebSocket客户端连接状态
+ * @param client WebSocket客户端指针
+ * @param client_type 客户端类型字符串
+ * @return true 如果连接正常,false 如果连接失败
+ */
+static bool check_websocket_client_status(WebSocketClient* client, const char* client_type) {
+ if (client == NULL) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "%s WebSocket client is NULL", client_type);
+ return false;
+ }
+
+ if (client->tcp_handle == NULL) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "%s WebSocket TCP handle is NULL", client_type);
+ return false;
+ }
+
+ if (client->parser == NULL) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "%s WebSocket parser is NULL", client_type);
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * @brief 将TCP连接状态转换为字符串
+ * @param state TCP连接状态
+ * @return 状态字符串
+ */
+static const char* tcp_state_to_string(tcp_connection_state_t state) {
+ switch (state) {
+ case TCP_STATE_DISCONNECTED: return "DISCONNECTED";
+ case TCP_STATE_CONNECTING: return "CONNECTING";
+ case TCP_STATE_CONNECTED: return "CONNECTED";
+ case TCP_STATE_CLOSING: return "CLOSING";
+ case TCP_STATE_ERROR: return "ERROR";
+ default: return "UNKNOWN";
+ }
+}
+
+/**
+ * @brief 等待TCP连接建立确认
+ * @param client WebSocket客户端指针
+ * @param client_type 客户端类型字符串
+ * @param timeout_ms 超时时间(毫秒)
+ * @return true 如果连接成功,false 如果连接失败或超时
+ */
+static bool wait_for_tcp_connection(WebSocketClient* client, const char* client_type, uint32_t timeout_ms) {
+ if (!client || !client->tcp_handle) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "%s WebSocket client or TCP handle is NULL", client_type);
+ return false;
+ }
+
+ uint32_t start_time = (uint32_t)osKernelGetTickCount();
+ uint32_t check_interval = 100; // 每100ms检查一次
+
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "%s 等待TCP连接建立确认...", client_type);
+
+ while ((uint32_t)osKernelGetTickCount() - start_time < timeout_ms) {
+ // 检查TCP连接状态
+ tcp_connection_state_t state = tcp_get_connection_state(client->tcp_handle);
+
+ if (state == TCP_STATE_CONNECTED) {
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "%s TCP连接已建立", client_type);
+ return true;
+ }
+
+ if (state == TCP_STATE_ERROR || state == TCP_STATE_DISCONNECTED) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "%s TCP连接失败或已断开,状态: %s", client_type, tcp_state_to_string(state));
+ return false;
+ }
+
+ // 如果还在连接中,继续等待
+ if (state == TCP_STATE_CONNECTING) {
+ msleep(check_interval);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "%s 等待TCP连接... (%d ms)",
+ client_type, (uint32_t)osKernelGetTickCount() - start_time);
+ continue;
+ }
+
+ // 其他状态也继续等待
+ msleep(check_interval);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "%s TCP状态: %s, 等待中... (%d ms)",
+ client_type, tcp_state_to_string(state), (uint32_t)osKernelGetTickCount() - start_time);
+ }
+
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "%s TCP连接确认超时 (%d ms)", client_type, timeout_ms);
+ return false;
+}
+
// 线程安全保护
#define AI_LOCK() do { \
if (g_ai_mutex) { \
} \
} while(0)
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-#include "cmsis_os2.h"
-#include "bk_websocket.h"
-#include <stdint.h>
-#include <stdint.h>
-#include <asm/delay.h>
-#include "bts_br_gap.h"
#define AI_RESULT_STR_LEN 512
static int receive_websocket_message_from_queue(ws_message_queue_t* queue, uint8_t* buffer, uint16_t buffer_size, WebSocketMessageType* type, uint32_t timeout_ms)
{
if (!queue || !buffer || !type) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "!queue || !buffer || !type");
return -1;
}
if (is_raisound_url) {
chat_client = init_websocket_client(url_buf, NULL, 1);
- chat_client->msg_queue = &chat_msg_queue;
- chat_client->packet_callback = chat_on_ws_packet_callback;
+ if (chat_client != NULL) {
+ chat_client->msg_queue = &chat_msg_queue;
+ chat_client->packet_callback = chat_on_ws_packet_callback;
+ }
} else {
#ifdef SUPPORT_CHINA_MOBILE_AI_REGULATION
chat_client = init_websocket_client(url_buf, NULL, 0);
- chat_client->msg_queue = &chat_msg_queue;
- chat_client->packet_callback = chat_on_ws_packet_callback;
+ if (chat_client != NULL) {
+ chat_client->msg_queue = &chat_msg_queue;
+ chat_client->packet_callback = chat_on_ws_packet_callback;
+ }
#else
const char* base_url = "ws://118.145.158.207:22080/chat/ws";
char full_url[512] = {0};
break;
}
chat_client = init_websocket_client(full_url, NULL, 0);
- chat_client->msg_queue = &chat_msg_queue;
- chat_client->packet_callback = chat_on_ws_packet_callback;
+ if (chat_client != NULL) {
+ chat_client->msg_queue = &chat_msg_queue;
+ chat_client->packet_callback = chat_on_ws_packet_callback;
+ }
#endif
}
if (chat_client == NULL) {
client_count--;
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "WebSocket connection failed, retries left: %d", client_count);
-
+
// 检查超时
if ((uint32_t)osKernelGetTickCount() - connect_start > AI_CONNECT_TIMEOUT_MS) {
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Connection timeout");
msleep(1000);
continue;
} else {
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocket connection established");
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocket connection established");
break;
}
}
goto cleanup_and_exit;
}
- while (chat_client->handshake==0 )
- {
+ // 在握手前先确认TCP连接状态
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "Chat WebSocket: 开始TCP连接确认...");
+
+ // 先检查当前连接状态
+ tcp_connection_state_t current_state = tcp_get_connection_state(chat_client->tcp_handle);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "Chat WebSocket: 当前TCP连接状态: %s", tcp_state_to_string(current_state));
+
+ if (!wait_for_tcp_connection(chat_client, "Chat", 15000)) { // 15秒TCP连接确认超时
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Chat WebSocket: TCP连接确认失败,退出线程");
+ lwip_close_websocket_client(chat_client);
+ chat_client = NULL;
+ goto cleanup_and_exit;
+ }
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "Chat WebSocket: TCP连接确认成功,开始握手等待");
+
+ // 等待WebSocket握手完成,增加超时机制
+ uint32_t handshake_start_time = (uint32_t)osKernelGetTickCount();
+ const uint32_t handshake_timeout_ms = 10000; // 30秒超时
+
+ while (chat_client->handshake == 0) {
+ // 检查是否超时
+ if ((uint32_t)osKernelGetTickCount() - handshake_start_time > handshake_timeout_ms) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "WebSocket握手超时 (%d ms),重新连接", handshake_timeout_ms);
+ lwip_close_websocket_client(chat_client);
+ chat_client = NULL;
+ goto cleanup_and_exit;
+ }
+
msleep(1000);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "等待WebSocket握手完成... (%d ms)",
+ (uint32_t)osKernelGetTickCount() - handshake_start_time);
}
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocket握手完成,耗时 %d ms",
+ (uint32_t)osKernelGetTickCount() - handshake_start_time);
+
// 设置socket超时
// struct timeval timeout;
// timeout.tv_sec = AI_RECEIVE_TIMEOUT_MS / 1000;
if (g_test_server_index == 1) {
asr_client = init_websocket_client("ws://118.145.158.207:22080/asr/ws", NULL, 0);
- asr_client->msg_queue = &asr_msg_queue;
- asr_client->packet_callback = asr_on_ws_packet_callback;
+ if (asr_client != NULL) {
+ asr_client->msg_queue = &asr_msg_queue;
+ asr_client->packet_callback = asr_on_ws_packet_callback;
+ }
} else if (g_test_server_index == 2) {
asr_client = init_websocket_client("ws://110.42.224.129:8910/asr/ws", NULL, 0);
- asr_client->msg_queue = &asr_msg_queue;
- asr_client->packet_callback = asr_on_ws_packet_callback;
+ if (asr_client != NULL) {
+ asr_client->msg_queue = &asr_msg_queue;
+ asr_client->packet_callback = asr_on_ws_packet_callback;
+ }
} else {
if (is_raisound_url) {
asr_client = init_websocket_client(url_buf, NULL, 1);
- asr_client->msg_queue = &asr_msg_queue;
- asr_client->packet_callback = asr_on_ws_packet_callback;
+ if (asr_client != NULL) {
+ asr_client->msg_queue = &asr_msg_queue;
+ asr_client->packet_callback = asr_on_ws_packet_callback;
+ }
} else {
asr_client = init_websocket_client("ws://118.145.158.207:22080/asr/ws", NULL, 0);
- asr_client->msg_queue = &asr_msg_queue;
- asr_client->packet_callback = asr_on_ws_packet_callback;
+ if (asr_client != NULL) {
+ asr_client->msg_queue = &asr_msg_queue;
+ asr_client->packet_callback = asr_on_ws_packet_callback;
+ }
}
}
if (asr_client == NULL) {
client_count--;
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ASR WebSocket connection failed, retries left: %d", client_count);
-
+
// 检查超时
if ((uint32_t)osKernelGetTickCount() - connect_start > AI_CONNECT_TIMEOUT_MS) {
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ASR connection timeout");
break;
}
- msleep(1000);
+msleep(1000);
continue;
} else {
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "ASR WebSocket connection established");
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "ASR WebSocket connection established");
break;
}
}
goto asr_cleanup_and_exit;
}
- while (asr_client->handshake==0)
- {
+ // 在握手前先确认TCP连接状态
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "ASR WebSocket: 开始TCP连接确认...");
+
+ // 先检查当前连接状态
+ tcp_connection_state_t current_state = tcp_get_connection_state(asr_client->tcp_handle);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "ASR WebSocket: 当前TCP连接状态: %s", tcp_state_to_string(current_state));
+
+ if (!wait_for_tcp_connection(asr_client, "ASR", 15000)) { // 15秒TCP连接确认超时
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ASR WebSocket: TCP连接确认失败,退出线程");
+ lwip_close_websocket_client(asr_client);
+ asr_client = NULL;
+ goto asr_cleanup_and_exit;
+ }
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "ASR WebSocket: TCP连接确认成功,开始握手等待");
+
+ // 等待ASR WebSocket握手完成,增加超时机制
+ uint32_t asr_handshake_start_time = (uint32_t)osKernelGetTickCount();
+ const uint32_t asr_handshake_timeout_ms = 10000; // 30秒超时
+
+ while (asr_client->handshake == 0) {
+ // 检查是否超时
+ if ((uint32_t)osKernelGetTickCount() - asr_handshake_start_time > asr_handshake_timeout_ms) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ASR WebSocket握手超时 (%d ms),重新连接", asr_handshake_timeout_ms);
+ lwip_close_websocket_client(asr_client);
+ asr_client = NULL;
+ goto asr_cleanup_and_exit;
+ }
+
msleep(1000);
+WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "等待ASR WebSocket握手完成... (%d ms)",
+ (uint32_t)osKernelGetTickCount() - asr_handshake_start_time);
}
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "ASR WebSocket握手完成,耗时 %d ms",
+ (uint32_t)osKernelGetTickCount() - asr_handshake_start_time);
+
uapi_cat1_keep_wakeup(1);
server_state = 0x01 ^ server_state;
if (is_raisound_url == 1) {
tts_client = init_websocket_client(url_buf, NULL, 1);
- tts_client->msg_queue = &tts_msg_queue;
- tts_client->packet_callback = tts_on_ws_packet_callback;
+ if (tts_client != NULL) {
+ tts_client->msg_queue = &tts_msg_queue;
+ tts_client->packet_callback = tts_on_ws_packet_callback;
+ }
} else {
- tts_client = init_websocket_client("ws://118.145.158.207:22080/tts/stream?audio_buffer_size=1024", NULL, 0);
- tts_client->msg_queue = &tts_msg_queue;
- tts_client->packet_callback = tts_on_ws_packet_callback;
+ tts_client = init_websocket_client("ws://118.145.158.207:22080/tts/stream?audio_buffer_size=512", NULL, 0);
+ if (tts_client != NULL) {
+ tts_client->msg_queue = &tts_msg_queue;
+ tts_client->packet_callback = tts_on_ws_packet_callback;
+ }
}
if (tts_client == NULL) {
client_count--;
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TTS WebSocket connection failed, retries left: %d", client_count);
-
+
// 检查超时
if ((uint32_t)osKernelGetTickCount() - connect_start > AI_CONNECT_TIMEOUT_MS) {
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TTS connection timeout");
break;
}
- msleep(1000);
continue;
} else {
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "TTS WebSocket connection established");
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "TTS WebSocket connection established");
break;
}
}
goto tts_cleanup_and_exit;
}
- while (tts_client->handshake==0)
- {
+ // 在握手前先确认TCP连接状态
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "TTS WebSocket: 开始TCP连接确认...");
+
+ // 先检查当前连接状态
+ tcp_connection_state_t current_state = tcp_get_connection_state(tts_client->tcp_handle);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "TTS WebSocket: 当前TCP连接状态: %s", tcp_state_to_string(current_state));
+
+ if (!wait_for_tcp_connection(tts_client, "TTS", 15000)) { // 15秒TCP连接确认超时
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TTS WebSocket: TCP连接确认失败,退出线程");
+ lwip_close_websocket_client(tts_client);
+ tts_client = NULL;
+ goto tts_cleanup_and_exit;
+ }
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "TTS WebSocket: TCP连接确认成功,开始握手等待");
+
+ // 等待TTS WebSocket握手完成,增加超时机制
+ uint32_t tts_handshake_start_time = (uint32_t)osKernelGetTickCount();
+ const uint32_t tts_handshake_timeout_ms = 10; // 30秒超时
+
+ while (tts_client->handshake == 0) {
+ // 检查是否超时
+ if ((uint32_t)osKernelGetTickCount() - tts_handshake_start_time > tts_handshake_timeout_ms) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TTS WebSocket握手超时 (%d ms),重新连接", tts_handshake_timeout_ms);
+ lwip_close_websocket_client(tts_client);
+ tts_client = NULL;
+ goto tts_cleanup_and_exit;
+ }
+
msleep(1000);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "等待TTS WebSocket握手完成... (%d ms)",
+ (uint32_t)osKernelGetTickCount() - tts_handshake_start_time);
}
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "TTS WebSocket握手完成,耗时 %d ms",
+ (uint32_t)osKernelGetTickCount() - tts_handshake_start_time);
+
server_state = 0x04 ^ server_state;
tts_break = 0;
if (is_raisound_url == 1) {
voice_chat_client = init_websocket_client(url_buf, NULL, 1);
- // voice_chat_client->msg_queue = &voice_msg_queue;
+ if (voice_chat_client != NULL) {
+ // voice_chat_client->msg_queue = &voice_msg_queue;
+ }
} else {
voice_chat_client = init_websocket_client("ws://118.145.158.207:22080/voice-chat/v2/ws?platform=huoshan", NULL, 0);
- // voice_chat_client->msg_queue = &voice_msg_queue;
+ if (voice_chat_client != NULL) {
+ // voice_chat_client->msg_queue = &voice_msg_queue;
+ }
}
if (voice_chat_client == NULL) {
client_count--;
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Voice chat WebSocket connection failed, retries left: %d", client_count);
+
+ // 使用统一的错误处理函数
+ if (!handle_websocket_connection_failure("Voice chat", AI_MAX_RETRY_COUNT - client_count, AI_MAX_RETRY_COUNT)) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Voice chat WebSocket connection failed after all retries");
+ break;
+ }
// 检查超时
if ((uint32_t)osKernelGetTickCount() - connect_start > AI_CONNECT_TIMEOUT_MS) {
break;
}
- msleep(1000);
continue;
} else {
WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "Voice chat WebSocket connection established");