ln 增加ws对话
authorhcj <1224667075@qq.com>
Fri, 26 Sep 2025 11:02:50 +0000 (19:02 +0800)
committerhcj <1224667075@qq.com>
Fri, 26 Sep 2025 11:02:50 +0000 (19:02 +0800)
code/sdk/zhihui/ai_new/ai_V2.5/ai_v2_5_main.cpp
code/sdk/zhihui/ai_old/asr_websocket_server.cpp
code/sdk/zhihui/ai_old/tts_websocket_server.cpp
code/sdk/zhihui/ai_old/websocket_server_example.cpp
code/sdk/zhihui/leiniao/imsl_ln/CMakeLists.txt
code/sdk/zhihui/leiniao/imsl_ln/ln_api.h
code/sdk/zhihui/leiniao/imsl_ln/ln_api_websocket.c

index fa464e2..323906e 100644 (file)
@@ -323,9 +323,10 @@ int ai_service_start(void)
     ws_call_backs_t callbacks = {
         .message_callback = ai_message_handler,
         .binary_callback = ai_binary_message_handler,
+        .incomplete_callback=NULL,
         .url_callback = ai_url_handler,
         .heartbeat_callback = ai_heartbeat_handler,
-        .event_callback = ai_event_handler
+        .event_callback = ai_event_handler,
     };
     
     // 启动WebSocket服务
index df87624..4f36a6c 100644 (file)
@@ -319,7 +319,7 @@ ASR_START:
 
             } else if (msg_type == WS_BINARY) {
                 printf("ASR binary data received: %d bytes\n", len);
-                send_msg_data_into_Ai_msg_queue((uint8_t *)asr_recv_buf, len, 100);
+                // send_msg_data_into_Ai_msg_queue((uint8_t *)asr_recv_buf, len, 100);
             }
         }
         
index 70c51d0..5cdbe37 100644 (file)
@@ -44,7 +44,6 @@ static uint32_t bk_websocket_tts_tick = 0;
 extern bool read_dev_token(char *data_token);
 // extern void uapi_cat1_keep_wakeup(uint8_t state); // Commented out due to missing implementation
 extern void set_AIStreamend(uint8_t state);
-extern int send_msg_data_into_Ai_msg_queue(void *data, uint16_t len, uint16_t type);
 extern void msleep(uint32_t ms);
 extern int32_t VoiceCallVolteSample(int32_t argc, const char **argv);
 
@@ -891,7 +890,6 @@ TTS_START:
                     set_AIStreamend(0);
                     bk_websocket_tts_tick = (uint32_t)osKernelGetTickCount();
                 }
-                send_msg_data_into_Ai_msg_queue((uint8_t *)tts_recv_buf, len, 200);
                 printf("TTS binary data received: %d bytes\n", len);
                 msleep(1);
             } else if (msg_type == WS_TEXT) {
index 1f620a8..6cf53ab 100644 (file)
@@ -46,7 +46,6 @@ static void (*g_chat_filter_cb)(char *result) = NULL;
 /* 不再使用默认BLE回退,未注册时打印日志 */
 extern void ble_set_ai_Question_str(char *str);
 extern void ble_set_ai_Answer_str(char *str, uint8_t type);
-extern int send_msg_data_into_Ai_msg_queue(void *data, uint16_t len, uint16_t type);
 extern void set_AIStreamend(uint8_t state);
 extern bool uapi_start_tts(void);
 // extern bool ai_chat_send_txt(uint8_t type, char *msg, WebSocketClient *chat_client);
@@ -214,7 +213,6 @@ void handle_asr_data(const ws_event_data_t *event_data)
         }
     } else if (event_data->msg_type == WS_BINARY) {
         printf("ASR binary data: %d bytes\n", event_data->data_len);
-        send_msg_data_into_Ai_msg_queue(event_data->data, event_data->data_len, 100);
     }
 }
 
index 98f893c..9863e37 100644 (file)
@@ -31,7 +31,7 @@ set(PUBLIC_HEADER
     ${ROOT_DIR}/open_source/openharmony/third_party/lwip/lwip_adapter/liteos/src/include
     ${ROOT_DIR}/open_source/openharmony/third_party/cJSON/
     ${ROOT_DIR}/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/websocket/include
-
+    ${ROOT_DIR}/zhihui/websocket/os_ws
 
 )
 
index e86d0b5..11195b4 100644 (file)
@@ -332,6 +332,7 @@ typedef enum {
     WS_CMD_DELETE_EMOJI,             /* 删除表情 (DeleteEmoji) */
     WS_CMD_PING,                     /* 心跳 (Ping) */
     WS_CMD_PONG,                     /* 心跳回应 (Pong) */
+    WS_CMD_VOICE_CHAT_RESPONSE,      /* 语音聊天响应 (VoiceChatResponse) */
     WS_CMD_MAX                       /* 最大命令 */
 } ws_command_t;
 
@@ -343,21 +344,30 @@ typedef struct {
     ws_command_t command;
     char command_str[32];
     char *raw_json;  // 原始JSON字符串,用于需要完整数据的场景
+    
+    // VoiceChatResponse 特定字段
+    char audio_url[512];     // 音频URL
+    char text_content[1024]; // 文本内容
+    bool finished;           // 是否完成
+    char chat_id[64];        // 聊天ID
 } ws_data_msg_t;
 
 /* 消息处理回调函数类型 */
-typedef void (*ws_message_callback_t)(const ws_data_msg_t *data_msg, ws_command_t type);
+typedef void (*ws_message_callback_t_ln)(const ws_data_msg_t *data_msg, ws_command_t type);
 
 /* -------------------------------- 注册进的回调函数 -------------------------------- */
 void ln_ws_process_message(const ws_data_msg_t *data_msg, ws_command_t type);
 /* -------------------------------------------------------------------------- */
 
 /* WebSocket接口函数 */
-int ln_ws_start(ws_message_callback_t callback);
+int ln_ws_start(ws_message_callback_t_ln callback);
 int ln_ws_send_text(const char *text);
+int ln_ws_send_audio_data(const uint8_t *audio_data, uint32_t audio_size, bool finished);
+int ln_ws_start_audio_chat(void);
+int ln_ws_end_audio_chat(void);
+const char* ln_ws_get_current_chat_id(void);
 int ln_ws_stop(void);
-int ln_ws_stop_async(void);
-int ln_ws_force_reconnect(void);
+// int ln_ws_force_reconnect(void);
 int ln_ws_enter_sleep(void);
 int ln_ws_exit_sleep(void);
 
@@ -368,7 +378,7 @@ int ln_ws_get_close_status_public(void);
 void ln_ws_print_status_info(void);
 
 /* 回调函数注册接口 */
-void ln_ws_register_message_callback(ws_message_callback_t callback);
+void ln_ws_register_message_callback(ws_message_callback_t_ln callback);
 
 #ifdef __cplusplus
 }
index 45ec9db..efb7c0b 100644 (file)
@@ -1,5 +1,6 @@
 #include "ln_api.h"
 #include "net_websocket.h"
+#include "haisi_websocket.h"
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
@@ -7,6 +8,7 @@
 #include "custom_utils.h"
 #include "soc_osal.h"
 #include "cmsis_os2.h"
+#include "mbedtls/base64.h"
 
 /*
  * - g_ws_client_fd    当前 WebSocket 客户端fd
  * - g_ws_running      心跳线程运行标志
  */
 
-/* 消息队列相关定义 */
-#define WS_MSG_QUEUE_COUNT 16
-#define WS_MSG_TYPE_SEND_TEXT 0x01
-#define WS_MSG_TYPE_FORCE_RECONNECT 0x02
-#define WS_MSG_TYPE_STOP 0x03
-#define WS_MSG_TYPE_DATA_MESSAGE 0x04
-
 /* 连接状态定义 */
 #define WS_STATE_DISCONNECTED 0  // 未连接
 #define WS_STATE_CONNECTING   1  // 连接中
@@ -34,31 +29,26 @@ typedef enum {
     WS_CLOSE_SUCCESS = 2        // 执行成功
 } ws_close_status_t;
 
-/* WebSocket命令枚举 */
-
 
-
-typedef struct {
-    uint8_t msg_type;
-    uint16_t data_len;
-    ws_data_msg_t data;  // 直接存储数据而不是指针
-} ws_msg_info_t;
-
-
-static int g_ws_client_fd = -1;
 static volatile int g_ws_connected = WS_STATE_DISCONNECTED;
-static uint32_t g_ws_main_thread = 0;
 static volatile int g_ws_running = 0;
 static volatile unsigned int g_ws_reconnect_count = 0; /* 断线后递增,用于URL reconnect参数 */
-static osMessageQueueId_t g_ws_msg_queue = NULL;
 static ws_message_callback_t g_ws_message_callback = NULL; /* 消息处理回调函数 */
 static volatile ws_close_status_t g_ws_close_status = WS_CLOSE_NOT_EXECUTED; /* WebSocket关闭状态标志位 */
 
+/* Base64数据缓存相关变量 */
+static char *g_base64_cache = NULL;        /* 缓存的Base64数据 */
+static size_t g_base64_cache_size = 0;    /* 缓存大小 */
+static size_t g_base64_cache_capacity = 0; /* 缓存容量 */
+static bool g_base64_in_progress = false;   /* 是否正在进行Base64数据接收 */
+
+/* 回调函数结构体 */
+static ws_call_backs_t g_ws_callbacks = {0};
+
 static void ln_ws_build_url(char *out, size_t out_size);
 int ln_ws_send_ping(void);
 static ws_command_t ln_ws_parse_command_string(const char *command_str);
 static int ln_ws_parse_data_message(const char *json_str, ws_data_msg_t *data_msg);
-static int ln_ws_queue_data_message(const ws_data_msg_t *data_msg);
 static void ln_ws_free_data_message(ws_data_msg_t *data_msg);
 static void ln_ws_default_message_handler(const ws_data_msg_t *data_msg, ws_command_t type);
 static void ln_ws_process_message_with_callback(const ws_data_msg_t *data_msg);
@@ -66,17 +56,15 @@ static int ln_ws_close_with_status(int client_fd);
 static ws_close_status_t ln_ws_get_close_status(void);
 static void ln_ws_reset_close_status(void);
 const char* ln_ws_get_connection_state_string(void);
-/* 队列创建函数 */
-void ln_ws_queue_init(void)
-{
-    printf("[LN][WS] ln_ws_queue_init\n");
-    g_ws_msg_queue = osMessageQueueNew(WS_MSG_QUEUE_COUNT, sizeof(ws_msg_info_t), NULL);
-    if (g_ws_msg_queue == NULL) {
-        printf("[LN][WS] ln_ws_queue_init failed: failed to create message queue\n");
-    } else {
-        printf("[LN][WS] ln_ws_queue_init success: queue created\n");
-    }
-}
+
+/* Base64缓存管理函数 */
+static void ln_ws_base64_cache_init(void);
+static void ln_ws_base64_cache_cleanup(void);
+static int ln_ws_base64_cache_append(const char *data, size_t length);
+static void ln_ws_base64_cache_reset(void);
+static void ln_ws_process_base64_data(const char *base64_data, size_t length);
+static void ln_ws_process_incremental_base64_data(const char *new_data, size_t new_length);
+static void ln_ws_incomplete_callback(const char *raw_data, size_t length, bool isBinary);
 
 /* 握手成功回调:标记连接就绪 */
 static void ln_ws_on_open(int client)
@@ -84,290 +72,112 @@ static void ln_ws_on_open(int client)
     (void)client;
     printf("WebSocketClientConstructor ln_ws_on_open\r\n");
     g_ws_connected = WS_STATE_CONNECTED;
-    ln_ws_reset_close_status(); // 连接成功时重置关闭状态
-    printf("[LN][WS] 连接状态: 连接成功, 关闭状态已重置为 NOT_EXECUTED (%d)\n", g_ws_close_status);
+    printf("[LN][WS] 连接状态: 连接成功\n");
 }
 
-/*
- * 收到服务器下发的文本消息
- * - 上层可根据业务定义的 JSON 字段进行再分发
- */
-
-//  [LN][WS] on_message: {"deviceId":"860132060562402","timestamp":1758275259,"messageId":"0fb3719adca2472c8f0909d38df87666","command":"Pong"}
-static void ln_ws_on_message(int client, const char *data, size_t length, bool isFinished,bool isBinary)
+/* 消息接收回调函数 */
+static void ln_ws_message_callback(const char *raw_data, uint32_t timestamp)
 {
-    (void)client;
-    (void)isFinished;
-    if (data == NULL || length == 0) return;
+    (void)timestamp;
+    if (raw_data == NULL) return;
+    
+    size_t length = strlen(raw_data);
     char *buf = (char *)malloc(length + 1);
     if (!buf) return;
-    memcpy(buf, data, length);
+    memcpy(buf, raw_data, length);
     buf[length] = '\0';
 
     /* 统一的消息解析处理 */
     printf("WebSocketClientConstructor data\r\n");
     if (length >= 2 && buf[0] == '{' && buf[length - 1] == '}') {
-        // 解析消息并写入队列
+        // 解析消息并直接处理
         ws_data_msg_t data_msg;
         if (ln_ws_parse_data_message(buf, &data_msg) == 0) {
-            ln_ws_queue_data_message(&data_msg);
-            printf("[LN][WS] Message parsed and queued successfully: command=%d (%s)\n", 
+            printf("[LN][WS] Message parsed successfully: command=%d (%s)\n", 
                    data_msg.command, data_msg.command_str);
+            
+            // 直接使用回调函数处理消息
+            ln_ws_process_message_with_callback(&data_msg);
+            
+            // 释放消息内存
+            ln_ws_free_data_message(&data_msg);
         } else {
             printf("[LN][WS] Failed to parse message\n");
         }
     }
+    else
+    {
+        ln_ws_incomplete_callback(raw_data,length,false);
+        printf("[LN][WS] Invalid message\n");
+    }
     printf("[LN][WS] on_message: %s\n", buf);
 
-    /* 透传给接收队列:上层可基于 dispatch_cmd 做进一步处理 */
-    //do_ln_http_server_recv_data(dispatch_cmd, buf, (uint32_t)length);
-    /* 立即在同线程内调上层处理(可选:如担心阻塞可删除此行,仅由接收任务处理) */
-    // ln_ws_process_message(dispatch_cmd, buf);
     free(buf);
 }
 
-/* 出错回调:仅打印,实际重连策略可在上层统一管理 */
-static void ln_ws_on_error(int client, struct WebSocketErrorResult error)
-{
-    (void)client;
-    printf("WebSocketClientConstructor [LN][WS] error: code=%d msg=%s\n", error.errorCode, error.errorMessage);
-}
-
-/* 断开回调:标记为未连接。是否自动重连交由上层决定 */
-static void ln_ws_on_close(int client)
+/* 连接事件回调函数 */
+static void ln_ws_event_callback(ws_event_type_t event_type)
 {
-    printf("WebSocketClientConstructor [LN][WS] ln_ws_on_close %d\r\n",client);
-    
-    // 在断开回调触发时,将关闭状态设置为成功
- 
-    printf("[LN][WS] WebSocket close callback triggered, status set to SUCCESS (%d)\n", g_ws_close_status);
-    
+    switch (event_type) {
+        case WS_EVENT_CONNECTING:
+            printf("[LN][WS] Event: Connecting\n");
+            g_ws_connected = WS_STATE_CONNECTING;
+            break;
+        case WS_EVENT_CONNECTED:
+            printf("[LN][WS] Event: Connected\n");
+            g_ws_connected = WS_STATE_CONNECTED;
+            break;
+        case WS_EVENT_DISCONNECTED:
+            printf("[LN][WS] Event: Disconnected\n");
     g_ws_connected = WS_STATE_DISCONNECTED;
-    printf("[LN][WS] 连接状态: 未连接\n");
-    if(g_ws_client_fd>=0)
-    {
-        // 这里不再调用 ln_ws_close_with_status,因为回调已经触发说明关闭成功
-        if(g_ws_close_status==WS_CLOSE_NOT_EXECUTED)
-        {
-            // int ret = WebSocketClientClose(g_ws_client_fd);
-        
-        }
-        else
-        {
-            g_ws_client_fd=-1;
-        }
-    }
     /* 断开后增加重连计数,由监督线程在下一次连接时携带 */
     if (g_ws_running) {
         if (g_ws_reconnect_count < 0xFFFFFFFFu) {
             g_ws_reconnect_count++;
         }
     }
-}
-
-/*
- * 主线程:负责连接管理、心跳维护和队列消息处理
- * - 监督连接状态,处理重连逻辑
- * - 每30秒发送一次 "ping" 维持链路活性
- * - 处理队列中的消息
- */
-static void ln_ws_main_thread(void *arg)
-{
-    (void)arg;
-    int heartbeat_counter = 0; // 心跳计数器,每30秒发送一次ping
-    ws_msg_info_t msg;
-    uint32_t msgsize =0;
-    while (g_ws_running) {
-        // 处理队列消息(非阻塞)
-        if (osMessageQueueGet(g_ws_msg_queue, &msg, NULL, 1000) == osOK) {
-            printf("[LN][WS] osMessageQueueGet: g_ws_msg_queue\n");
-            switch (msg.msg_type) {
-                case WS_MSG_TYPE_SEND_TEXT:
-                    if (g_ws_connected == WS_STATE_CONNECTED && g_ws_client_fd >= 0) {
-                        // 对于文本消息,我们需要特殊处理,因为现在data是ws_data_msg_t类型
-                        // 这里需要重新设计文本消息的存储方式
-                        printf("[LN][WS] Text message type not supported in new structure\n");
-                    } else {
-                        printf("[LN][WS] Cannot send text, connection state: %d\n", g_ws_connected);
-                    }
-                    break;
-                    
-                case WS_MSG_TYPE_FORCE_RECONNECT:
-                    printf("[LN][WS] Force reconnect requested\n");
-                    if (g_ws_client_fd >= 0) {
-                        printf("[LN][WS] WebSocketClientClose\n");
-                        ln_ws_close_with_status(g_ws_client_fd);
-                        printf("[LN][WS] WebSocketClientClose end\n");
-                    }
-                    g_ws_connected = WS_STATE_DISCONNECTED;
-                    printf("[LN][WS] 连接状态: 未连接(强制重连)\n");
-                    break;
-                    
-                case WS_MSG_TYPE_STOP:
-                    printf("[LN][WS] Stop requested from queue\n");
-                    g_ws_running = 0;
-                    break;
-                    
-                case WS_MSG_TYPE_DATA_MESSAGE:
-                    {
-                        ws_data_msg_t *data_msg = &msg.data;
-                        printf("[LN][WS] Received message: deviceId=%s, timestamp=%u, messageId=%s, command=%d (%s)\n",
-                               data_msg->device_id, data_msg->timestamp, data_msg->message_id, 
-                               data_msg->command, data_msg->command_str);
-                        
-                        // 使用回调函数处理消息
-                        ln_ws_process_message_with_callback(data_msg);
-                        
-                        // 释放消息内存
-                        ln_ws_free_data_message(data_msg);
-                    }
-                    break;
-                    
-                default:
-                    printf("[LN][WS] Unknown message type: %d\n", msg.msg_type);
-                    break;
-            }
-        }
-        else
-        {
-            // printf("osMessageQueueGet timeout or failed\r\n");
-        }
-        
-        // 连接管理部分
-        if (g_ws_connected == WS_STATE_SLEEP) {
-            // 休眠状态:暂停所有操作,只打印状态信息
-            printf("[LN][WS] Sleep mode: pausing all operations\n");
-            usleep(1000 * 1000); // 休眠1秒
-            continue;
-        }
-        
-        if (g_ws_connected == WS_STATE_DISCONNECTED) {
-            if (g_ws_client_fd >= 0) {
-            {
-                if(g_ws_close_status== WS_CLOSE_NOT_EXECUTED)
-                {
-                    printf("[LN][WS] WebSocketClientClose WS_CLOSE_NOT_EXECUTED\n");
-                    ln_ws_close_with_status(g_ws_client_fd);
-                    g_ws_client_fd=-1;
-                    printf("[LN][WS] WebSocketClientClose WS_CLOSE_NOT_EXECUTED end\n");
-
-                }
-            }
-            }
-
-            if (g_ws_client_fd < 0) {
-
-               
-                printf("[LN][WS] 开始创建WebSocket客户端...\n");
-                g_ws_client_fd = WebSocketClientConstructor(ln_ws_on_open, ln_ws_on_message, ln_ws_on_error, ln_ws_on_close);
-                if (g_ws_client_fd < 0) {
-                    printf("[LN][WS] constructor failed: %d\n", g_ws_client_fd);
-                    g_ws_connected = WS_STATE_DISCONNECTED;
-                    printf("[LN][WS] 连接状态: 未连接(创建失败)\n");
-                    /* 失败则短暂休眠后重试创建 */
-                    usleep(2000 * 1000);
-                    continue;
-                }
-            }
-
-            char url[512] = {0};
-            ln_ws_build_url(url, sizeof(url));
-
-            const char *device_id = uapi_ln_get_device_id();
-                    // f"deviceId: {self.device_id}",
-                    //     f"deviceIccid: {self.device_iccid}",
-                    //     f"deviceModel: {Constants.DEVICE_MODEL.value}",
-                    //     f"deviceVersion: {Constants.DEVICE_VERSION.value}"
-
-            printf("[LN][WS] 尝试连接WebSocket: %s\n", url);
-            char header_buf[512]={0};
-            int hdr = snprintf(header_buf, sizeof(header_buf),
-                        "deviceId: %s\r\n",
-                       device_id);
-            int ret = WebSocketClientConnect(g_ws_client_fd, url,header_buf);
-            // int ret = WebSocketClientConnect(g_ws_client_fd,"ws://118.145.158.207:22080/chat/ws?platform=huoshan");
-           
-            if (ret != 0) {
-                printf("[LN][WS] connect failed: %d\n", ret);
-                g_ws_connected = WS_STATE_DISCONNECTED;
-                printf("[LN][WS] 连接状态: 未连接(连接失败)\n");
-                (void)ln_ws_close_with_status(g_ws_client_fd);
-                g_ws_client_fd = -1;
-                /* 指数退避*/
-                unsigned int delay = 1u << (g_ws_reconnect_count > 5 ? 5 : g_ws_reconnect_count);
-                if (delay > 60) delay = 60;
-                for (unsigned int i = 0; i < delay && g_ws_running; i++) {
-                    usleep(1000 * 1000);
-                }
-                continue;
-            }
-            else
-            {
-                g_ws_connected = WS_STATE_CONNECTING;
-            }
-            /* 连接请求已发送,等待握手完成 */
-            printf("[LN][WS] 连接请求已发送,等待握手完成...\n");
-        }
-        
-        // 心跳部分:每30秒发送一次ping
-        if (g_ws_connected == WS_STATE_CONNECTED && g_ws_client_fd >= 0) {
-            heartbeat_counter++;
-            if (heartbeat_counter >= 15) { // 30秒 = 30次 * 1秒
-                (void)ln_ws_send_ping();
-                heartbeat_counter = 0; // 重置计数器
-            }
-        }
-        else
-        {
-           printf("ln ws_state %s\r\n",ln_ws_get_connection_state_string()); 
-        }
-        
-        /* 1秒间隔 */
-        usleep(1000 * 1000);
-    }
-  
-
-    if (g_ws_client_fd >= 0) {
-        ln_ws_close_with_status(g_ws_client_fd);
-    }
-    g_ws_connected = WS_STATE_DISCONNECTED;
-    
-    // 删除消息队列
-    if (g_ws_msg_queue != NULL) {
-
-         ws_msg_info_t msg;
-        while (osMessageQueueGet(g_ws_msg_queue, &msg, NULL, 0) == osOK) {
-            if(msg.data.raw_json)
-            {
-                free(msg.data.raw_json);
-            }
-            
-        }
-        osMessageQueueDelete(g_ws_msg_queue);
-        g_ws_msg_queue = NULL;
+            break;
+        default:
+            printf("[LN][WS] Event: Unknown event type %d\n", event_type);
+            break;
     }
 }
 
-/*
- * 拼接连接URL:环境域名 + 业务必须的查询参数
- * - 认证方式采用“查询参数方式”:至少包含 deviceToken(规范允许)
- * - 兼容性增强:同时附带 deviceId 与 reconnect 计数,方便服务端校验与审计
- * - 如需切换环境,仅修改 base 即可
- */
-static void ln_ws_build_url(char *out, size_t out_size)
+/* URL构建回调函数 */
+static void ln_ws_url_callback(char *url, size_t url_size, char *header_buf, size_t header_size)
 {
     const char *base = "ws://ambybox-api.test.leiniao.com/ambybox-device-api/v1/websocket"; 
     const char *device_id = uapi_ln_get_device_id();
     const char *token = uapi_ln_get_device_token();
     if (!device_id) device_id = "";
     if (!token) token = "";
+    
     /* 仅使用 deviceToken 也可通过;额外带上 deviceId 与 reconnect 便于后端管理 */
-    snprintf(out, out_size, "%s?deviceToken=%s&deviceId=%s&reconnect=%u",
+    snprintf(url, url_size, "%s?deviceToken=%s&deviceId=%s&reconnect=%u",
              base, token, device_id, g_ws_reconnect_count);
+    
+    /* 构建头部信息 */
+    snprintf(header_buf, header_size, "deviceId: %s\r\n", device_id);
 }
+
+/* 心跳处理回调函数 */
+static int ln_ws_heartbeat_callback(void)
+{
+    // 每30秒发送一次心跳
+    static int heartbeat_counter = 0;
+    heartbeat_counter++;
+    if (heartbeat_counter >= 15) { // 30秒 = 30次 * 1秒
+        heartbeat_counter = 0;
+        ln_ws_send_ping();
+        return 1; // 需要发送心跳
+    }
+    return 0; // 不需要发送心跳
+}
+
+
 int ln_ws_send_ping(void)
 {
-    if (g_ws_connected != WS_STATE_CONNECTED || g_ws_client_fd < 0) {
+    if (g_ws_connected != WS_STATE_CONNECTED) {
         printf("[LN][WS] Cannot send ping, connection state: %d\n", g_ws_connected);
         return -1;
     }
@@ -399,9 +209,9 @@ int ln_ws_send_ping(void)
     }
     
     // 发送 JSON 字符串
-    int ret = WebSocketClientSendText(g_ws_client_fd, json_string, strlen(json_string));
+    int ret = uapi_ws_send_text(json_string);
     
-    printf("[LN][WS] Sent ping: %s %d\n", json_string,g_ws_client_fd);
+    printf("[LN][WS] Sent ping: %s\n", json_string);
     
     // 清理内存
     free(json_string);
@@ -411,12 +221,362 @@ int ln_ws_send_ping(void)
 }
 
 
+
+uint16_t send_audio=0;
+
+// 音频聊天相关结构体
+typedef struct {
+    char chat_id[64];           // 聊天ID
+    uint32_t message_counter;   // 消息计数器
+    bool is_active;             // 是否活跃
+} audio_chat_context_t;
+
+// 全局音频聊天上下文
+static audio_chat_context_t g_audio_chat_ctx = {0};
+
+// 音频聊天结束标志
+static bool g_audio_chat_ending = false;
+
+// 函数声明
+static void generate_chat_id(char *chat_id, size_t size);
+static void generate_message_id(char *message_id, size_t size, const char *chat_id, uint32_t counter);
+
+// 生成聊天ID
+static void generate_chat_id(char *chat_id, size_t size)
+{
+    if (!chat_id || size < 16) return;
+    
+    uint32_t timestamp;
+    uapi_get_timestampe_ss(&timestamp);
+    
+    snprintf(chat_id, size, "chat_%u_%u", timestamp, (uint32_t)rand());
+}
+
+// 生成消息ID
+static void generate_message_id(char *message_id, size_t size, const char *chat_id, uint32_t counter)
+{
+    if (!message_id || !chat_id || size < 32) return;
+    
+    snprintf(message_id, size, "%s_msg_%u", chat_id, counter);
+}
+
+// 发送音频数据到WebSocket
+int ln_ws_send_audio_data(const uint8_t *audio_data, uint32_t audio_size, bool finished)
+{
+    // 检查结束标志位,如果设置了结束标志,则finished必须为true
+    if (g_audio_chat_ending && !finished) {
+        printf("[LN][WS] Audio chat is ending, finished must be true\n");
+        return -1;
+    }
+    
+    // 对于正常音频数据,必须有有效的数据
+    if (!finished && (!audio_data || audio_size == 0)) {
+        printf("[LN][WS] Invalid audio data parameters\n");
+        return -1;
+    }
+    
+    if (g_ws_connected != WS_STATE_CONNECTED) {
+        printf("[LN][WS] Cannot send audio data, connection state: %d\n", g_ws_connected);
+        return -1;
+    }
+    
+    // 如果聊天未开始,生成新的聊天ID
+    if (!g_audio_chat_ctx.is_active) {
+        generate_chat_id(g_audio_chat_ctx.chat_id, sizeof(g_audio_chat_ctx.chat_id));
+        g_audio_chat_ctx.message_counter = 0;
+        g_audio_chat_ctx.is_active = true;
+        printf("[LN][WS] New chat started: %s\n", g_audio_chat_ctx.chat_id);
+    }
+    
+    // 增加消息计数器
+    g_audio_chat_ctx.message_counter++;
+    
+    // 生成消息ID
+    char message_id[128];
+    generate_message_id(message_id, sizeof(message_id), g_audio_chat_ctx.chat_id, g_audio_chat_ctx.message_counter);
+    
+    // Base64编码音频数据(如果是结束消息,则使用空字符串)
+    char *audio_base64 = NULL;
+    if (audio_size == 0) {
+        // 结束消息,使用空字符串
+        audio_base64 = (char*)malloc(1);
+        if (!audio_base64) {
+            printf("[LN][WS] Failed to allocate memory for base64 encoding\n");
+            return -1;
+        }
+        audio_base64[0] = '\0';
+    } else {
+        // 正常音频数据,进行Base64编码
+        size_t base64_size =audio_size*2; //((audio_size + 2) / 3) * 4 + 1;
+        audio_base64 = (char*)malloc(base64_size);
+        if (!audio_base64) {
+            printf("[LN][WS] Failed to allocate memory for base64 encoding\n");
+        return -1;
+    }
+    
+        size_t output_len = 0;
+        int ret_encode = mbedtls_base64_encode((unsigned char*)audio_base64, base64_size - 1, &output_len, 
+                                              audio_data, audio_size);
+        if (ret_encode != 0) {
+            printf("[LN][WS] Base64 encoding failed: %d\n", ret_encode);
+            free(audio_base64);
+        return -1;
+        }
+        audio_base64[output_len] = '\0';
+    }
+    
+    // 获取当前时间戳
+    uint32_t timestamp;
+    uapi_get_timestampe_ss(&timestamp);
+    
+    // 创建JSON消息
+    cJSON *json = cJSON_CreateObject();
+    if (!json) {
+        printf("[LN][WS] Failed to create JSON object\n");
+        free(audio_base64);
+        return -1;
+    }
+    
+    // 添加基本字段
+    cJSON_AddStringToObject(json, "deviceId", uapi_ln_get_device_id());
+    cJSON_AddNumberToObject(json, "timestamp", (double)timestamp);
+    cJSON_AddStringToObject(json, "messageId", message_id);
+    cJSON_AddStringToObject(json, "command", "VoiceChatRequest");
+    
+    // 创建data对象
+    cJSON *data_obj = cJSON_CreateObject();
+    if (!data_obj) {
+        printf("[LN][WS] Failed to create data object\n");
+        cJSON_Delete(json);
+        free(audio_base64);
+        return -1;
+    }
+    
+    cJSON_AddStringToObject(data_obj, "audioBase64", audio_base64);
+    cJSON_AddStringToObject(data_obj, "chatId", g_audio_chat_ctx.chat_id);
+    cJSON_AddBoolToObject(data_obj, "finished", finished);
+    
+    cJSON_AddItemToObject(json, "data", data_obj);
+    
+    // 转换为字符串
+    char *json_string = cJSON_Print(json);
+    if (!json_string) {
+        printf("[LN][WS] Failed to print JSON\n");
+        cJSON_Delete(json);
+        free(audio_base64);
+        return -1;
+    }
+    
+    // 发送JSON字符串
+    int ret = uapi_ws_send_text(json_string);
+    
+    printf("[LN][WS] Sent audio data: chatId=%s, messageId=%s, size=%u, finished=%s\n", 
+           g_audio_chat_ctx.chat_id, message_id, audio_size, finished ? "true" : "false");
+    
+    // 清理内存
+    free(json_string);
+    free(audio_base64);
+    cJSON_Delete(json);
+    
+    // 如果音频结束,重置聊天上下文
+    if (finished) {
+        g_audio_chat_ctx.is_active = false;
+        printf("[LN][WS] Chat ended: %s\n", g_audio_chat_ctx.chat_id);
+    }
+    
+    return ret;
+}
+
+// 开始新的音频聊天
+int ln_ws_start_audio_chat(void)
+{
+    if (g_audio_chat_ctx.is_active) {
+        printf("[LN][WS] Audio chat already active: %s\n", g_audio_chat_ctx.chat_id);
+        return 0;
+    }
+    
+    generate_chat_id(g_audio_chat_ctx.chat_id, sizeof(g_audio_chat_ctx.chat_id));
+    g_audio_chat_ctx.message_counter = 0;
+    g_audio_chat_ctx.is_active = true;
+    
+    printf("[LN][WS] Audio chat started: %s\n", g_audio_chat_ctx.chat_id);
+    return 0;
+}
+
+// 结束当前音频聊天
+int ln_ws_end_audio_chat(void)
+{
+    if (!g_audio_chat_ctx.is_active) {
+        printf("[LN][WS] No active audio chat to end\n");
+        return -1;
+    }
+    printf("[LN][WS] Ending audio chat: %s, total messages: %u\n", 
+           g_audio_chat_ctx.chat_id, g_audio_chat_ctx.message_counter);
+    // 设置结束标志,等待下次AIVoiceDataCallback_ln调用时发送结束消息
+    g_audio_chat_ending = true;
+    
+    return 0;
+}
+
+// 获取当前聊天ID
+const char* ln_ws_get_current_chat_id(void)
+{
+    return g_audio_chat_ctx.is_active ? g_audio_chat_ctx.chat_id : NULL;
+}
+
+static void AIVoiceDataCallback_ln(const uint8_t* data, uint32_t size, void* userData)
+{
+    // MEDIA_INFO_LOG("Received audio data: size=%u bytes", size);
+    if( g_audio_chat_ctx.is_active ==true)
+    {
+         if (g_audio_chat_ending) {
+            printf("[LN][WS] Sending audio chat end message\n");
+            // 发送结束消息
+            ln_ws_send_audio_data(data, size, true);
+            // 重置聊天上下文和结束标志
+            g_audio_chat_ctx.is_active = false;
+            g_audio_chat_ending = false;
+        }
+        else
+
+        {
+            // 使用新的音频发送接口
+            ln_ws_send_audio_data(data, size, false);
+        }
+    }
+    
+    // 检查是否设置了结束标志
+   
+}
+
+// "audioBase64":
+
+static void ai_binary_message_handler(const uint8_t *raw_data, uint32_t timestamp, uint16_t data_len)
+{
+    printf("[AI] Received binary message at %u, length: %d bytes\n", timestamp, data_len);
+    
+    if (!raw_data || data_len == 0) {
+        printf("[AI] Invalid binary data parameters\n");
+        return;
+    }
+    
+    const size_t CHUNK_SIZE = 1024; // 1K 分块大小
+    
+    if (data_len <= CHUNK_SIZE) {
+        // 数据小于等于1K,直接发送
+        printf("[AI] Sending data directly (size: %d bytes)\n", data_len);
+        AI_SendAudioDataToQueue(raw_data, data_len);
+    } else {
+        // 数据大于1K,分块发送
+        printf("[AI] Data size %d bytes > %zu bytes, splitting into chunks\n", data_len, CHUNK_SIZE);
+        
+        size_t remaining = data_len;
+        const uint8_t *current_pos = raw_data;
+        int chunk_count = 0;
+        
+        while (remaining > 0) {
+            size_t current_chunk_size = (remaining > CHUNK_SIZE) ? CHUNK_SIZE : remaining;
+            
+            printf("[AI] Sending chunk %d: %zu bytes\n", ++chunk_count, current_chunk_size);
+            AI_SendAudioDataToQueue(current_pos, current_chunk_size);
+            
+            current_pos += current_chunk_size;
+            remaining -= current_chunk_size;
+            
+            // 添加小延迟避免过快发送
+            usleep(1000); // 1ms延迟
+        }
+        
+        printf("[AI] All %d chunks sent successfully\n", chunk_count);
+    }
+}
+
+
+static void ln_ws_incomplete_callback(const char *raw_data, size_t length, bool isBinary)
+{
+    if (!raw_data || length == 0) {
+        return;
+    }
+    
+    printf("[LN][WS] Incomplete message received: length=%zu, isBinary=%s\n", 
+           length, isBinary ? "true" : "false");
+    
+    // 检查是否包含 "audioBase64":" 字符串
+    const char *audioBase64_key = "\"audioBase64\":\"";
+    const char *found = strstr(raw_data, audioBase64_key);
+    
+    if (found) {
+        printf("[LN][WS] Found audioBase64 key in incomplete message\n");
+        
+        // 找到 "audioBase64":" 后面的内容
+        const char *value_start = found + strlen(audioBase64_key);
+        
+        // 找到结束引号
+        const char *value_end = strchr(value_start, '"');
+        
+        if (value_end) {
+            // 找到结束引号,数据完整
+            size_t base64_length = value_end - value_start;
+            printf("[LN][WS] Found complete Base64 data: length=%zu\n", base64_length);
+            
+            // 处理完整的Base64数据
+            ln_ws_process_base64_data(value_start, base64_length);
+            
+            // 重置缓存状态
+            ln_ws_base64_cache_reset();
+            
+        } else {
+            // 没有找到结束引号,数据不完整
+            printf("[LN][WS] No closing quote found, data incomplete\n");
+            
+            // 处理不完整的Base64数据
+            size_t remaining_length = length - (value_start - raw_data);
+            if (remaining_length > 0) {
+                if (!g_base64_in_progress) {
+                    g_base64_in_progress = true;
+                }
+                ln_ws_process_incremental_base64_data(value_start, remaining_length);
+            }
+        }
+    } else {
+        // 没有找到audioBase64关键字
+        if (g_base64_in_progress) {
+            // 如果正在进行Base64数据接收,检查是否包含结束引号
+            const char *end_quote = strchr(raw_data, '"');
+            if (end_quote) {
+                // 找到结束引号,处理到引号位置的数据
+                size_t data_before_quote = end_quote - raw_data;
+                if (data_before_quote > 0) {
+                    printf("[LN][WS] Found end quote, processing data before quote: %zu bytes\n", data_before_quote);
+                    ln_ws_process_incremental_base64_data(raw_data, data_before_quote);
+                }
+                
+                // 处理缓存中剩余的数据(如果有的话)
+                if (g_base64_cache_size > 0) {
+                    printf("[LN][WS] Processing remaining cached data: %zu bytes\n", g_base64_cache_size);
+                    ln_ws_process_base64_data(g_base64_cache, g_base64_cache_size);
+                    ln_ws_base64_cache_reset();
+                }
+                
+                // 结束Base64数据接收
+                g_base64_in_progress = false;
+                printf("[LN][WS] Base64 data reception completed\n");
+            } else {
+                // 没有结束引号,继续处理增量数据
+                printf("[LN][WS] Continuing Base64 data reception, processing incrementally\n");
+                ln_ws_process_incremental_base64_data(raw_data, length);
+            }
+        } else {
+            printf("[LN][WS] No audioBase64 key found in message\n");
+        }
+    }
+}
 /*
  * 启动:开启监督线程与心跳机制(心跳线程首次连接成功后会自然启动)
  * - 若已在运行则直接返回成功
  * - callback: 消息处理回调函数,可以为NULL使用默认处理
  */
-int ln_ws_start(ws_message_callback_t callback)
+int ln_ws_start(ws_message_callback_t_ln callback)
 {
     if (g_ws_running) {
         return 0;
@@ -432,21 +592,24 @@ int ln_ws_start(ws_message_callback_t callback)
     } else {
         printf("[LN][WS] Using default message handler\n");
     }
-    if (!g_ws_main_thread) {
-        app_task_definition_ext_t main_task = {
-            .attr = {
-                .name = "ln_ws_main",
-                .stack_size = 0x2000,
-                .priority = osPriorityNormal
-            },
-            .func = ln_ws_main_thread,
-            .task_handle = &g_ws_main_thread,
-            .create_queue_handle = ln_ws_queue_init,
-            .use_mem = USE_EXTEND_MEM,
-            .inst_args = NULL
-        };
-        (void)uapi_create_osThread_custom_with_args(&main_task);
+    
+    // 设置回调函数结构体
+    g_ws_callbacks.message_callback = ln_ws_message_callback;
+    g_ws_callbacks.event_callback = ln_ws_event_callback;
+    g_ws_callbacks.url_callback = ln_ws_url_callback;
+    g_ws_callbacks.heartbeat_callback = ln_ws_heartbeat_callback;
+    g_ws_callbacks.binary_callback = ai_binary_message_handler; 
+    g_ws_callbacks.incomplete_callback= ln_ws_incomplete_callback;
+    // 启动WebSocket服务
+    int ret = uapi_ws_start(&g_ws_callbacks);
+    if (ret != 0) {
+        printf("[LN][WS] uapi_ws_start failed: %d\n", ret);
+        g_ws_running = 0;
+        return ret;
     }
+    
+    old_Start_AIVoice(AIVoiceDataCallback_ln,NULL,NULL,NULL,false);
+
     cat1_api_keep_wakeup(1);
     cat1_api_wakeup_cat1(1);
 
@@ -457,73 +620,23 @@ int ln_ws_start(ws_message_callback_t callback)
 int ln_ws_send_text(const char *text)
 {
     if (!text) return -1;
-    if (g_ws_connected != WS_STATE_CONNECTED || g_ws_client_fd < 0) {
+    if (g_ws_connected != WS_STATE_CONNECTED) {
         printf("[LN][WS] Cannot send text, connection state: %d\n", g_ws_connected);
         return -1;
     }
-    return WebSocketClientSendText(g_ws_client_fd, text, strlen(text));
-}
-
-/* 通过队列发送文本消息(异步) */
-int ln_ws_send_text_async(const char *text)
-{
-    if (!text || !g_ws_running) return -1;
-    
-    // 由于新的数据结构不支持直接文本消息,这里暂时返回错误
-    // 如果需要支持文本消息,需要重新设计消息类型
-    printf("[LN][WS] Text message not supported in new queue structure\n");
-    return -1;
+    return uapi_ws_send_text(text);
 }
 
-/* 强制重连 */
-int ln_ws_force_reconnect(void)
-{
-    if (!g_ws_running) return -1;
-    
-    ws_msg_info_t msg;
-    msg.msg_type = WS_MSG_TYPE_FORCE_RECONNECT;
-    msg.data_len = 0;
-    msg.data.raw_json = NULL;
-    
-    osStatus_t ret = osMessageQueuePut(g_ws_msg_queue, &msg, 0, 0);
-    return (ret == osOK) ? 0 : -1;
-}
-
-/* 通过队列停止WebSocket服务 */
-int ln_ws_stop_async(void)
-{
-    if (!g_ws_running) return -1;
-    
-    ws_msg_info_t msg;
-    msg.msg_type = WS_MSG_TYPE_STOP;
-    msg.data_len = 0;
-    msg.data.raw_json = NULL;
-    // msg.data = NULL;
-    
-    osStatus_t ret = osMessageQueuePut(g_ws_msg_queue, &msg, 0, 0);
-    return (ret == osOK) ? 0 : -1;
-}
 
 /* 停止:关闭心跳并关闭连接 */
 int ln_ws_stop(void)
 {
     g_ws_running = 0;
-    if (g_ws_main_thread) {
-        osThreadJoin(g_ws_main_thread);
-        g_ws_main_thread = 0;
-    }
-    int ret = 0;
-    if (g_ws_client_fd >= 0) {
-        ret = ln_ws_close_with_status(g_ws_client_fd);
-        g_ws_client_fd = -1;
-    }
+    int ret = uapi_ws_stop();
     g_ws_connected = WS_STATE_DISCONNECTED;
     
-    // 删除消息队列
-    if (g_ws_msg_queue != NULL) {
-        osMessageQueueDelete(g_ws_msg_queue);
-        g_ws_msg_queue = NULL;
-    }
+    // 清理Base64缓存
+    ln_ws_base64_cache_cleanup();
     
     return ret;
 }
@@ -557,7 +670,7 @@ const char* ln_ws_get_connection_state_string(void)
  * @brief 注册消息处理回调函数(公共接口)
  * @param callback 回调函数
  */
-void ln_ws_register_message_callback(ws_message_callback_t callback)
+void ln_ws_register_message_callback(ws_message_callback_t_ln callback)
 {
     g_ws_message_callback = callback;
     if (callback != NULL) {
@@ -604,6 +717,8 @@ static ws_command_t ln_ws_parse_command_string(const char *command_str)
         return WS_CMD_PING;
     } else if (strcmp(command_str, "Pong") == 0) {
         return WS_CMD_PONG;
+    } else if (strcmp(command_str, "VoiceChatResponse") == 0) {
+        return WS_CMD_VOICE_CHAT_RESPONSE;
     } else {
         return WS_CMD_UNKNOWN;
     }
@@ -615,6 +730,13 @@ static ws_command_t ln_ws_parse_command_string(const char *command_str)
  * @param data_msg 输出的消息结构体
  * @return 0成功,-1失败
  */
+
+// {"deviceId":"DEVICE_PC_TEST_001","timestamp":1758880220,
+// "messageId":"d63a0670a3854d709cb95720e1e89f83","command":"VoiceChatResponse","data":
+// {"finished":false,"chatId":"chat_1758880210_2087035594",
+// "data":{"audioUrl":"http://ambybox-api.test.leiniao.com/ambybox-device-api/file/774317549446_20250926175018_1758880218961.mp3",
+// "textContent":"(颔首,夹着烟的手指轻敲桌面)来者何人?"}}}
+
 static int ln_ws_parse_data_message(const char *json_str, ws_data_msg_t *data_msg)
 {
     if (!json_str || !data_msg) {
@@ -676,6 +798,46 @@ static int ln_ws_parse_data_message(const char *json_str, ws_data_msg_t *data_ms
         return -1;
     }
     
+    // 解析VoiceChatResponse特定字段
+    if (data_msg->command == WS_CMD_VOICE_CHAT_RESPONSE) {
+        cJSON *data_obj = cJSON_GetObjectItem(root, "data");
+        if (data_obj && cJSON_IsObject(data_obj)) {
+            // 解析finished字段
+            cJSON *finished = cJSON_GetObjectItem(data_obj, "finished");
+            if (finished && cJSON_IsBool(finished)) {
+                data_msg->finished = cJSON_IsTrue(finished);
+            }
+            
+            // 解析chatId字段
+            cJSON *chat_id = cJSON_GetObjectItem(data_obj, "chatId");
+            if (chat_id && cJSON_IsString(chat_id) && chat_id->valuestring) {
+                strncpy(data_msg->chat_id, chat_id->valuestring, sizeof(data_msg->chat_id) - 1);
+                data_msg->chat_id[sizeof(data_msg->chat_id) - 1] = '\0';
+            }
+            
+            // 解析data.data字段
+            cJSON *data_data = cJSON_GetObjectItem(data_obj, "data");
+            if (data_data && cJSON_IsObject(data_data)) {
+                // 解析audioUrl字段
+                cJSON *audio_url = cJSON_GetObjectItem(data_data, "audioUrl");
+                if (audio_url && cJSON_IsString(audio_url) && audio_url->valuestring) {
+                    strncpy(data_msg->audio_url, audio_url->valuestring, sizeof(data_msg->audio_url) - 1);
+                    data_msg->audio_url[sizeof(data_msg->audio_url) - 1] = '\0';
+                }
+                
+                // 解析textContent字段
+                cJSON *text_content = cJSON_GetObjectItem(data_data, "textContent");
+                if (text_content && cJSON_IsString(text_content) && text_content->valuestring) {
+                    strncpy(data_msg->text_content, text_content->valuestring, sizeof(data_msg->text_content) - 1);
+                    data_msg->text_content[sizeof(data_msg->text_content) - 1] = '\0';
+                }
+            }
+        }
+        
+        printf("[LN][WS] VoiceChatResponse parsed: finished=%s, chatId=%s, audioUrl=%s, textContent=%s\n",
+               data_msg->finished ? "true" : "false", data_msg->chat_id, data_msg->audio_url, data_msg->text_content);
+    }
+    
     // 保存原始JSON字符串
     data_msg->raw_json = (char*)malloc(strlen(json_str) + 1);
     if (data_msg->raw_json) {
@@ -691,35 +853,6 @@ static int ln_ws_parse_data_message(const char *json_str, ws_data_msg_t *data_ms
     return 0;
 }
 
-/**
- * @brief 将消息写入队列
- * @param data_msg 消息结构体指针
- * @return 0成功,-1失败
- */
-static int ln_ws_queue_data_message(const ws_data_msg_t *data_msg)
-{
-    if (!data_msg || !g_ws_running) {
-        printf("[LN][WS] Invalid parameters or WebSocket not running\n");
-        return -1;
-    }
-    
-    ws_msg_info_t msg;
-    msg.msg_type = WS_MSG_TYPE_DATA_MESSAGE;
-    msg.data_len = sizeof(ws_data_msg_t);
-    
-    // 直接复制数据到结构体中
-    memcpy(&msg.data, data_msg, sizeof(ws_data_msg_t));
-    
-    // 写入队列
-    osStatus_t ret = osMessageQueuePut(g_ws_msg_queue, &msg, 0, 0);
-    if (ret != osOK) {
-        printf("[LN][WS] Failed to put data message to queue: %d\n", ret);
-        return -1;
-    }
-    
-    printf("[LN][WS] Data message queued successfully count %d\n", osMessageQueueGetCount(g_ws_msg_queue));
-    return 0;
-}
 
 /**
  * @brief 释放消息结构体内存
@@ -774,6 +907,13 @@ static void ln_ws_default_message_handler(const ws_data_msg_t *data_msg, ws_comm
         case WS_CMD_SCHEDULE_REMINDER_CFG:
             printf("[LN][WS] Default: Processing ScheduleReminderConfig message\n");
             break;
+        case WS_CMD_VOICE_CHAT_RESPONSE:
+            printf("[LN][WS] Default: Processing VoiceChatResponse message\n");
+            printf("[LN][WS] VoiceChatResponse details: finished=%s, chatId=%s\n", 
+                   data_msg->finished ? "true" : "false", data_msg->chat_id);
+            printf("[LN][WS] Audio URL: %s\n", data_msg->audio_url);
+            printf("[LN][WS] Text Content: %s\n", data_msg->text_content);
+            break;
         default:
             printf("[LN][WS] Default: Processing unknown command: %d\n", type);
             break;
@@ -798,126 +938,392 @@ static void ln_ws_process_message_with_callback(const ws_data_msg_t *data_msg)
     }
 }
 
-/* ============================ WebSocket关闭状态管理 ============================ */
+
+/* ============================ 公共接口函数 ============================ */
+
+
 
 /**
- * @brief 带状态跟踪的WebSocket关闭函数
- * @param client_fd WebSocket客户端文件描述符
- * @return WebSocketClientClose的返回值
+ * @brief 进入休眠状态(公共接口)
+ * @return 0成功,-1失败
  */
-static int ln_ws_close_with_status(int client_fd)
+int ln_ws_enter_sleep(void)
 {
-    if (client_fd < 0) {
-        printf("[LN][WS] Invalid client_fd for close operation\n");
-        return -1;
-    }
-    
-    // 设置状态为开始执行
-    g_ws_close_status = WS_CLOSE_STARTING;
-    printf("[LN][WS] WebSocketClientClose starting, fd=%d, status=%d\n", client_fd, g_ws_close_status);
+    printf("[LN][WS] Entering sleep mode\n");
     
-    // 执行关闭操作
-    int ret = WebSocketClientClose(client_fd);
+    if (!g_ws_running) {
+    printf("[LN][WS] WebSocket service not running, cannot enter sleep\n");
+    return -1;
+    }
     
-    // 注意:成功状态由 ln_ws_on_close 回调函数设置,这里只处理失败情况
-    if (ret != 0) {
-        g_ws_close_status = WS_CLOSE_NOT_EXECUTED;
-        printf("[LN][WS] WebSocketClientClose failed, fd=%d, ret=%d, status=%d\n", client_fd, ret, g_ws_close_status);
-    } else {
-        printf("[LN][WS] WebSocketClientClose call returned success, waiting for close callback\n");
+    // 使用新的接口进入休眠
+    int ret = uapi_ws_enter_sleep();
+    if (ret == 0) {
+    g_ws_connected = WS_STATE_SLEEP;
+    printf("[LN][WS] Sleep mode activated, all operations paused\n");
     }
     
     return ret;
 }
 
 /**
- * @brief 获取当前WebSocket关闭状态
- * @return 当前关闭状态
+ * @brief 退出休眠状态(公共接口)
+ * @return 0成功,-1失败
  */
-static ws_close_status_t ln_ws_get_close_status(void)
+int ln_ws_exit_sleep(void)
 {
-    return g_ws_close_status;
+    printf("[LN][WS] Exiting sleep mode\n");
+    
+    if (g_ws_connected != WS_STATE_SLEEP) {
+        printf("[LN][WS] Not in sleep mode, current state: %s\n", ln_ws_get_connection_state_string());
+        return -1;
+    }
+    
+    // 使用新的接口退出休眠
+    int ret = uapi_ws_exit_sleep();
+    if (ret == 0) {
+    g_ws_connected = WS_STATE_DISCONNECTED;
+    printf("[LN][WS] Sleep mode deactivated, resuming normal operations\n");
+    }
+    
+    return ret;
 }
 
+/* ============================ Base64缓存管理函数 ============================ */
+
 /**
- * @brief 重置WebSocket关闭状态
+ * @brief 初始化Base64缓存
  */
-static void ln_ws_reset_close_status(void)
+static void ln_ws_base64_cache_init(void)
 {
-    g_ws_close_status = WS_CLOSE_NOT_EXECUTED;
-    printf("[LN][WS] WebSocket close status reset to NOT_EXECUTED (%d)\n", g_ws_close_status);
+    if (g_base64_cache == NULL) {
+        g_base64_cache_capacity = 4096; // 初始容量4KB
+        g_base64_cache = (char*)malloc(g_base64_cache_capacity);
+        if (g_base64_cache) {
+            g_base64_cache_size = 0;
+            g_base64_in_progress = false;
+            printf("[LN][WS] Base64 cache initialized with capacity: %zu\n", g_base64_cache_capacity);
+        } else {
+            printf("[LN][WS] Failed to initialize Base64 cache\n");
+            g_base64_cache_capacity = 0;
+        }
+    }
 }
 
-/* ============================ 公共接口函数 ============================ */
-
 /**
- * @brief 获取WebSocket关闭状态(公共接口)
- * @return 当前关闭状态
+ * @brief 清理Base64缓存
  */
-int ln_ws_get_close_status_public(void)
+static void ln_ws_base64_cache_cleanup(void)
 {
-    return (int)ln_ws_get_close_status();
+    if (g_base64_cache) {
+        free(g_base64_cache);
+        g_base64_cache = NULL;
+        g_base64_cache_size = 0;
+        g_base64_cache_capacity = 0;
+        g_base64_in_progress = false;
+        printf("[LN][WS] Base64 cache cleaned up\n");
+    }
 }
 
 /**
- * @brief 打印WebSocket状态信息(调试用)
+ * @brief 重置Base64缓存
  */
-void ln_ws_print_status_info(void)
+static void ln_ws_base64_cache_reset(void)
 {
-    printf("[LN][WS] === WebSocket Status Info ===\n");
-    printf("[LN][WS] Connection State: %s (%d)\n", ln_ws_get_connection_state_string(), g_ws_connected);
-    printf("[LN][WS] Close Status: %d (0=NOT_EXECUTED, 1=STARTING, 2=SUCCESS)\n", g_ws_close_status);
-    printf("[LN][WS] Client FD: %d\n", g_ws_client_fd);
-    printf("[LN][WS] Running: %d\n", g_ws_running);
-    printf("[LN][WS] Reconnect Count: %u\n", g_ws_reconnect_count);
-    printf("[LN][WS] ===============================\n");
+    if (g_base64_cache) {
+        g_base64_cache_size = 0;
+        g_base64_in_progress = false;
+        printf("[LN][WS] Base64 cache reset\n");
+    }
 }
 
 /**
- * @brief 进入休眠状态(公共接口)
+ * @brief 向Base64缓存追加数据
+ * @param data 要追加的数据
+ * @param length 数据长度
  * @return 0成功,-1失败
  */
-int ln_ws_enter_sleep(void)
+static int ln_ws_base64_cache_append(const char *data, size_t length)
 {
-    printf("[LN][WS] Entering sleep mode\n");
+    if (!data || length == 0) {
+        return -1;
+    }
     
-    if (!g_ws_running) {
-    printf("[LN][WS] WebSocket service not running, cannot enter sleep\n");
-    return -1;
+    // 确保缓存已初始化
+    if (g_base64_cache == NULL) {
+        ln_ws_base64_cache_init();
+        if (g_base64_cache == NULL) {
+            return -1;
+        }
     }
     
-    // 如果当前有连接,先断开
-    if (g_ws_client_fd >= 0) {
-        printf("[LN][WS] Disconnecting before entering sleep mode\n");
-        ln_ws_close_with_status(g_ws_client_fd);
-            }
+    // 检查是否需要扩容
+    if (g_base64_cache_size + length > g_base64_cache_capacity) {
+        size_t new_capacity = g_base64_cache_capacity * 2;
+        while (new_capacity < g_base64_cache_size + length) {
+            new_capacity *= 2;
+        }
+        
+        char *new_cache = (char*)realloc(g_base64_cache, new_capacity);
+        if (new_cache) {
+            g_base64_cache = new_cache;
+            g_base64_cache_capacity = new_capacity;
+            printf("[LN][WS] Base64 cache expanded to capacity: %zu\n", g_base64_cache_capacity);
+        } else {
+            printf("[LN][WS] Failed to expand Base64 cache\n");
+            return -1;
+        }
+    }
     
-    // 设置状态为休眠
-    g_ws_connected = WS_STATE_SLEEP;
-    printf("[LN][WS] Sleep mode activated, all operations paused\n");
+    // 追加数据
+    memcpy(g_base64_cache + g_base64_cache_size, data, length);
+    g_base64_cache_size += length;
+    g_base64_cache[g_base64_cache_size] = '\0'; // 确保字符串结束
     
+    printf("[LN][WS] Base64 cache appended %zu bytes, total size: %zu\n", length, g_base64_cache_size);
     return 0;
 }
 
 /**
- * @brief 退出休眠状态(公共接口)
- * @return 0成功,-1失败
+ * @brief 处理Base64数据(验证、解码)
+ * @param base64_data Base64数据
+ * @param length 数据长度
  */
-int ln_ws_exit_sleep(void)
+static void ln_ws_process_base64_data(const char *base64_data, size_t length)
 {
-    printf("[LN][WS] Exiting sleep mode\n");
+    if (!base64_data || length == 0) {
+        printf("[LN][WS] Invalid Base64 data parameters\n");
+        return;
+    }
     
-    if (g_ws_connected != WS_STATE_SLEEP) {
-        printf("[LN][WS] Not in sleep mode, current state: %s\n", ln_ws_get_connection_state_string());
-        return -1;
+    printf("[LN][WS] Processing Base64 data: length=%zu\n", length);
+    
+    // 检查Base64长度是否有效(必须是4的倍数)
+    if (length % 4 != 0) {
+        printf("[LN][WS] Invalid Base64 length: %zu (not multiple of 4)\n", length);
+        return;
     }
     
-    // 设置状态为断开,让主线程重新开始连接
-    g_ws_connected = WS_STATE_DISCONNECTED;
-    printf("[LN][WS] Sleep mode deactivated, resuming normal operations\n");
+    // 检查是否包含有效的Base64字符
+    bool valid_base64 = true;
+    for (size_t i = 0; i < length; i++) {
+        char c = base64_data[i];
+        if (!((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || 
+              (c >= '0' && c <= '9') || c == '+' || c == '/' || c == '=')) {
+            valid_base64 = false;
+            break;
+        }
+    }
     
-    return 0;
+    if (!valid_base64) {
+        printf("[LN][WS] Invalid Base64 characters detected\n");
+        return;
+    }
+    
+    printf("[LN][WS] Valid Base64 format detected, attempting decode\n");
+    
+    // 计算解码后的数据长度
+    size_t decoded_length = (length * 3) / 4;
+    
+    // 如果Base64字符串以'='结尾,需要调整长度
+    if (length >= 2 && base64_data[length - 1] == '=') {
+        if (base64_data[length - 2] == '=') {
+            decoded_length -= 2; // 两个填充字符
+        } else {
+            decoded_length -= 1; // 一个填充字符
+        }
+    }
+    
+    printf("[LN][WS] Expected decoded length: %zu\n", decoded_length);
+    
+    // 分配内存进行解码
+    uint8_t *decoded_data = (uint8_t*)malloc(decoded_length);
+    if (decoded_data) {
+        size_t actual_decoded_length = 0;
+        
+        // 创建临时字符串进行解码
+        char *temp_base64 = (char*)malloc(length + 1);
+        if (temp_base64) {
+            memcpy(temp_base64, base64_data, length);
+            temp_base64[length] = '\0';
+            
+            // 执行Base64解码
+            int ret = mbedtls_base64_decode(decoded_data, decoded_length, 
+                                           &actual_decoded_length, 
+                                           (const unsigned char*)temp_base64, 
+                                           length);
+            
+            if (ret == 0) {
+                printf("[LN][WS] Base64 decode successful: %zu bytes decoded\n", actual_decoded_length);
+                
+                // 这里可以处理解码后的音频数据
+                // 例如:调用音频处理回调函数
+                printf("[LN][WS] Decoded audio data: first 16 bytes: ");
+                for (size_t i = 0; i < (actual_decoded_length < 16 ? actual_decoded_length : 16); i++) {
+                    printf("%02X ", decoded_data[i]);
+                }
+                printf("\n");
+                
+                // TODO: 在这里可以调用音频数据处理函数
+               AI_SendAudioDataToQueue(decoded_data, actual_decoded_length);
+                
+            } else {
+                printf("[LN][WS] Base64 decode failed: %d\n", ret);
+            }
+            
+            free(temp_base64);
+        }
+        
+        free(decoded_data);
+    } else {
+        printf("[LN][WS] Failed to allocate memory for decoded data\n");
+    }
+}
+
+/**
+ * @brief 增量处理Base64数据(只缓存多余字符)
+ * @param new_data 新的Base64数据
+ * @param new_length 新数据长度
+ */
+static void ln_ws_process_incremental_base64_data(const char *new_data, size_t new_length)
+{
+    if (!new_data || new_length == 0) {
+        return;
+    }
+    
+    printf("[LN][WS] Processing incremental Base64 data: length=%zu\n", new_length);
+    
+    // 确保缓存已初始化
+    if (g_base64_cache == NULL) {
+        ln_ws_base64_cache_init();
+        if (g_base64_cache == NULL) {
+            return;
+        }
+    }
+    
+    // 将新数据追加到缓存
+    if (ln_ws_base64_cache_append(new_data, new_length) != 0) {
+        printf("[LN][WS] Failed to append data to cache\n");
+        return;
+    }
+    
+    // 计算可以完整解码的数据长度(必须是4的倍数)
+    size_t decodable_length = (g_base64_cache_size / 4) * 4;
+    
+    if (decodable_length > 0) {
+        printf("[LN][WS] Decodable length: %zu, total cache: %zu\n", decodable_length, g_base64_cache_size);
+        
+        // 解码可用的完整数据
+        ln_ws_process_base64_data(g_base64_cache, decodable_length);
+        
+        // 保留多余的字符(不足4个字符的部分)
+        size_t remaining_length = g_base64_cache_size - decodable_length;
+        if (remaining_length > 0) {
+            printf("[LN][WS] Keeping %zu remaining characters in cache\n", remaining_length);
+            
+            // 将剩余字符移到缓存开头
+            memmove(g_base64_cache, g_base64_cache + decodable_length, remaining_length);
+            g_base64_cache_size = remaining_length;
+            g_base64_cache[g_base64_cache_size] = '\0';
+        } else {
+            // 没有剩余字符,重置缓存
+            ln_ws_base64_cache_reset();
+        }
+    } else {
+        printf("[LN][WS] Not enough data for Base64 decode yet: %zu\n", g_base64_cache_size);
+    }
 }
+////////////////////////////////////////////////////////////////////////////
+
+// int uapi_ln_download_mp3_file(const char *url)
+// {
+//     if (!url)
+//     {
+//         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DOWNLOAD] url or save_path is NULL");
+//         return ERRCODE_FAIL;
+//     }
+
+//     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DOWNLOAD] 开始下载: %s -> %s", url);
+
+//     HttpClient client = {0};
+//     HttpClientData client_data = {0};
+//     int ret = -1;
+//     size_t total_written = 0;
+
+
+//     HTTPC_RESULT prep = ln_http_prepare_auto(&client_data, 2048, LN_CLIENT_PREPARE_SIZE * 2);
+//     if (prep != HTTP_SUCCESS)
+//     {
+//         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DOWNLOAD] prepare failed: %d", prep);
+
+//         return ERRCODE_FAIL;
+//     }
+
+//     // 建立连接
+//     ret = HttpClientConn(&client, url);
+//     if (ret != 0)
+//     {
+//         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DOWNLOAD] connection failed, ret=0x%x", ret);
+ 
+//         HttpClientUnprepare(&client_data);
+//         return ERRCODE_FAIL;
+//     }
+
+//     // 发送GET请求
+//     ret = HttpClientSend(&client, url, HTTP_GET, &client_data);
+//     if (ret != 0)
+//     {
+//         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DOWNLOAD] send request failed, ret=0x%x", ret);
+
+//         HttpClientClse(&client);
+//         HttpClientUnprepare(&client_data);
+//         return ERRCODE_FAIL;
+//     }
+
+//     // 接收响应数据
+//     do
+//     {
+//         HTTPC_RESULT recv_res = HttpClientRecvResponse(&client, &client_data);
+//         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DOWNLOAD] recv_res = %d", recv_res);
+//         if (recv_res == HTTP_SUCCESS || recv_res == HTTP_EAGAIN)
+//         {
+//             if (client_data.contentBlockLen > 0)
+//             {
+//                 // size_t written = fwrite(client_data.responseBuf, 1, client_data.contentBlockLen, fd);
+
+//                 WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DOWNLOAD] written = %zu", written);
+//                 if (written != client_data.contentBlockLen)
+//                 {
+//                     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DOWNLOAD] write failed, written=%zu, expected=%d",
+//                                   written, client_data.contentBlockLen);
+//                     HttpClientClse(&client);
+//                     HttpClientUnprepare(&client_data);
+//                     return ERRCODE_FAIL;
+//                 }
+//                 total_written += written;
+//             }
+//         }
+//     } while (client_data.isMore);
 
+//     if (client_data.responseContentLen == 0)
+//     {
+//         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DOWNLOAD] receive length = 0");
+//     }
+//     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DOWNLOAD] responsecode = %d", client.responseCode);
+//     if (total_written == client_data.responseContentLen && client.responseCode == 200 && total_written > 0)
+//     {
+//         ret = ERRCODE_SUCC;
+//         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DOWNLOAD] The file is downloaded successfully and the data is complete!");
+//     }
+//     else
+//     {
+//         ret = ERRCODE_FAIL;
+//         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DOWNLOAD] The file data is incomplete!");
+//     }
 
+//     HttpClientUnprepare(&client_data);
+//     HttpClientClse(&client);
 
+//     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DOWNLOAD] download process finished,ret=%d", ret);
+//     return ret;
+// }
\ No newline at end of file