增加部分AI接口 1744/target/2 1799/1 1799/head
authorhcj <1224667075@qq.com>
Wed, 28 May 2025 01:51:16 +0000 (09:51 +0800)
committerhcj <1224667075@qq.com>
Wed, 28 May 2025 01:51:16 +0000 (09:51 +0800)
code/sdk/drivers/peripheral/slip/cat1Service/CMakeLists.txt
code/sdk/drivers/peripheral/slip/cat1Service/bk_websocket.h [new file with mode: 0644]
code/sdk/drivers/peripheral/slip/cat1Service/cat1_ws.cpp [new file with mode: 0644]

index d96d053..c7912d5 100644 (file)
@@ -23,6 +23,8 @@ ${CMAKE_CURRENT_SOURCE_DIR}/cat1_server.cpp
 ${CMAKE_CURRENT_SOURCE_DIR}/cat1_tcpServer.cpp
 ${CMAKE_CURRENT_SOURCE_DIR}/cat1_ctl.cpp
 ${CMAKE_CURRENT_SOURCE_DIR}/cat_imei_map.cpp
+${CMAKE_CURRENT_SOURCE_DIR}/cat1_ws.cpp
+
 
 )
 
diff --git a/code/sdk/drivers/peripheral/slip/cat1Service/bk_websocket.h b/code/sdk/drivers/peripheral/slip/cat1Service/bk_websocket.h
new file mode 100644 (file)
index 0000000..5448709
--- /dev/null
@@ -0,0 +1,41 @@
+\r
+#ifndef __BK_WEBSOCKET_H__\r
+#define __BK_WEBSOCKET_H__\r
+// #include "aic_osa.h"\r
+\r
+// WebSocket 消息类型枚举\r
+typedef enum {\r
+    WS_CONT = 0x00,\r
+    WS_TEXT = 0x01,\r
+    WS_BINARY = 0x02,\r
+    WS_CLOSE = 0x8,\r
+    WS_PING = 0x9,\r
+    WS_PONG = 0xa\r
+} WebSocketMessageType;\r
+// WebSocket 客户端结构体\r
+typedef struct {\r
+    int sockfd;\r
+    char host[128];\r
+    char path[128];\r
+    char query[128];\r
+    int port;\r
+} WebSocketClient;\r
+\r
+\r
+// 初始化 WebSocket 客户端\r
+WebSocketClient *init_websocket_client(const char *url, const char *headers);\r
+\r
+// 关闭 WebSocket 客户端\r
+void close_websocket_client(WebSocketClient *client) ;\r
+\r
+// 接收 WebSocket 消息\r
+int  receive_websocket_message(WebSocketClient *client, unsigned char *buf,int len,WebSocketMessageType *code);\r
+\r
+// 发送 WebSocket 消息\r
+int send_websocket_message(WebSocketClient *client, const unsigned char *message, size_t message_len, WebSocketMessageType type) ;\r
+\r
+void send_ai_bin(char *buf,uint32_t len);\r
+\r
+void uapi_start_asr();\r
+\r
+#endif\r
diff --git a/code/sdk/drivers/peripheral/slip/cat1Service/cat1_ws.cpp b/code/sdk/drivers/peripheral/slip/cat1Service/cat1_ws.cpp
new file mode 100644 (file)
index 0000000..606b4e6
--- /dev/null
@@ -0,0 +1,1115 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+
+#include <dirent.h>
+#include "lwip/ip.h"
+#include "lwip/netif.h"
+#include "lwip/init.h"
+#include "lwip/inet_chksum.h"
+
+#include "lwip/err.h"
+#include "lwip/sockets.h"
+#include "lwip/sys.h"
+#include <lwip/netdb.h>
+// #include <netinet/in.h>
+#include "lwip/inet.h"
+#include <stdio.h>
+// #include <string.h>
+// #include <sys/param.h>
+#include <string.h>
+
+#include "../../../../../open_source/openharmony/third_party/cJSON/cJSON.h"
+#include "ConfigModelC.h"
+#include "ConfigModel.h"
+#include "wearable_log.h"
+#include "custom_runtime.h"
+#include "osal_timer.h"
+#include "lwip/apps/sntp.h"
+
+#include <sys/time.h>
+
+#include "bletest.h"
+#include "custom_utils.h"
+#include "custom_runtime.h"
+#include "bleANCS.h"
+#include "cat1_tcpServer.h"
+#include "custom_utils.h"
+#include "broadcast_feature.h"
+#include "cmsis_os2.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+// #include "sock_api/sock_api.h"
+// #include "app_config.h"
+// #include "system/includes.h"
+// #include "wifi/wifi_connect.h"
+// #include "lwip.h"
+#include "lwip/sockets.h"
+#include "lwip/netdb.h"
+#include "cmsis_os2.h"
+// #include <nx_api.h>
+// #include <nx_ip.h>
+// #include <nx_ipv6.h>
+// #include <nx_tcp.h>
+// #include <nx_packet.h>
+// #include <nxd_bsd.h>
+// #include <nx_websocket_client.h>
+
+// #include <aic_init.h>
+// #include <aic_osa.h>
+// #include <aic_errno.h>
+// #include <aic_net_api.h>
+// #include <aic_net_pdp_mgr.h>
+// #include <aic_websocket_client.h>
+// #define printf(const char *format, ...) printf();
+
+// #define printf(fmt, ...)    printf("[bk:%s,%d]"fmt,__func__, __LINE__,##__VA_ARGS__)
+
+// extern void bk_print_hex(uint8_t *data,int data_len);
+#ifdef CONFIG_CRYPTO_MBEDTLS
+#ifdef CONFIG_CRYPTO_MBEDTLS_2
+#include "mbedtls/net.h"
+#else
+#include "mbedtls/net_sockets.h"
+#endif
+#include <mbedtls/ssl.h>
+#include <mbedtls/entropy.h>
+#include <mbedtls/ctr_drbg.h>
+#include <mbedtls/error.h>
+#include <mbedtls/x509_crt.h>
+
+// typedef struct aic_websocket_mbedtls_session {
+//     mbedtls_ssl_context ssl;
+//     mbedtls_entropy_context entropy;
+//     mbedtls_ctr_drbg_context ctr_drbg;
+//     mbedtls_ssl_config conf;
+//     mbedtls_net_context socket_fd;
+//     CHAR status;
+//     ULONG recv_wait_time;
+// } WEBSOCKET_MBEDTLS_SESSION;
+#endif
+
+#include "mbedtls/base64.h"
+#include "mbedtls/sha1.h"
+
+
+#define BUFFER_SIZE 1024
+#define WEBSOCKET_KEY_LEN 24
+#define WEBSOCKET_GUID "1234567890123456"
+
+// #include "fs/fs.h"
+// #include "spiflash.h"
+// #include "app_config.h"
+// #include "asm/sfc_norflash_api.h"
+// #include "event/device_event.h"
+// #include "system/includes.h"
+// #include "net_def.h"
+
+#include "bk_websocket.h"
+
+#include <stdint.h>
+#include <stdint.h>
+
+extern osStatus_t osDelay(uint32_t ticks);
+#define cat1_msleep(ms) osDelay(ms) /* osDelay(1) : 1ms */
+
+void bk_sleep(uint32_t time)
+{
+    cat1_msleep(time);
+}
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+void * aic_zalloc(unsigned int len)
+{
+    return malloc(len);
+}
+
+// free
+
+// 定义一个结构体来存储解析后的URL部分
+typedef struct {
+    char *protocol;
+    char *host;
+    int port;
+    char *path;
+    char *query;
+    int error;
+    char *error_message;
+} BK_URL;
+
+// 自定义的 strdup 函数,添加错误处理
+char* bk_strdup(const char* str) {
+    if (str == NULL) {
+        return NULL;
+    }
+    size_t len = strlen(str) + 1;
+    char* new_str = (char*)aic_zalloc(len);
+    if (new_str == NULL) {
+        return NULL;
+    }
+    return (char*)memcpy(new_str, str, len);
+}
+
+// 设置错误信息
+void set_url_error(BK_URL *url, const char *error_msg) {
+    url->error = 1;
+    url->error_message = bk_strdup(error_msg);
+    if (!url->error_message) {
+        // 若分配失败,输出提示信息
+        printf("Memory allocation failed for error message.\n");
+    }
+
+}
+
+// 解析URL的函数
+BK_URL parse_url(const char *url) {
+    printf("parse_url url=%s.\n",url);
+    BK_URL result = {NULL, NULL, 0, NULL, NULL, 0, NULL};
+    char *temp_url_t = bk_strdup(url);
+    char *temp_url = temp_url_t;
+    if (!temp_url) {
+        set_url_error(&result, "Failed to allocate memory for temp_url");
+        return result;
+    }
+
+    // 解析协议
+    char *colon = strchr(temp_url, ':');
+    if (!colon) {
+        set_url_error(&result, "Invalid URL: No protocol specified");
+        free(temp_url_t);
+        return result;
+    }
+    *colon = '\0';
+    result.protocol = bk_strdup(temp_url);
+    if (!result.protocol) {
+        set_url_error(&result, "Failed to allocate memory for protocol");
+        free(temp_url_t);
+        return result;
+    }
+    temp_url = colon + 3;  // 跳过 "://"
+
+    // 解析主机和端口
+    char *slash = strchr(temp_url, '/');
+    if (!slash) {
+        set_url_error(&result, "Invalid URL: No path specified");
+        free(temp_url_t);
+        return result;
+    }
+    *slash = '\0';
+    char *at = strchr(temp_url, '@');
+    if (at) {
+        temp_url = at + 1;  // 跳过用户名和密码部分
+    }
+    char *colon_port = strchr(temp_url, ':');
+    if (colon_port) {
+        *colon_port = '\0';
+        result.host = bk_strdup(temp_url);
+        if (!result.host) {
+            set_url_error(&result, "Failed to allocate memory for host");
+            free(temp_url_t);
+            return result;
+        }
+        result.port = atoi(colon_port + 1);
+        if (!result.port) {
+            set_url_error(&result, "Invalid port number");
+            free(temp_url_t);
+            return result;
+        }
+    } else {
+        result.host = bk_strdup(temp_url);
+        if (!result.host) {
+            set_url_error(&result, "Failed to allocate memory for host");
+            free(temp_url_t);
+            return result;
+        }
+        if (!strcmp(result.protocol, "http") || !strcmp(result.protocol, "ws")) {
+            result.port = 80;
+        } else if (!strcmp(result.protocol, "https")|| !strcmp(result.protocol, "wss")) {
+            result.port = 443;
+        }
+    }
+    temp_url = slash+1;
+    //printf("parse_url slash=%s\n",temp_url);
+    // 解析路径和查询字符串
+    char *question = strchr(temp_url, '?');
+    if (question) {
+        *question = '\0';
+        result.path = bk_strdup(temp_url);
+        if (!result.path) {
+            set_url_error(&result, "Failed to allocate memory for path");
+            free(temp_url_t);
+            return result;
+        }
+        result.query = bk_strdup(question + 1);
+        if (!result.query) {
+            set_url_error(&result, "Failed to allocate memory for query");
+            free(temp_url_t);
+            return result;
+        }
+    } else {
+        result.path = bk_strdup(temp_url);
+        if (!result.path) {
+            set_url_error(&result, "Failed to allocate memory for path");
+            free(temp_url_t);
+            return result;
+        }
+        result.query = NULL;
+    }
+
+    free(temp_url_t);
+
+    return result;
+}
+
+// 释放URL结构体中分配的内存
+void free_url(BK_URL url) {
+
+    // 释放已分配的内存
+
+    if (url.protocol) {
+        free(url.protocol);
+        url.protocol = NULL;
+    }
+    if (url.host) {
+        free(url.host);
+        url.host = NULL;
+    }
+    if (url.path) {
+        free(url.path);
+        url.path = NULL;
+    }
+    if (url.query) {
+        free(url.query);
+        url.query = NULL;
+    }
+    if (url.error_message) {
+        free(url.error_message);
+        url.error_message = NULL;
+    }
+
+}
+
+// 仿写 htonl 函数
+// static uint32_t htonl(uint32_t hostlong) {
+//     // 检查主机是否为大端字节序
+//     static const union {
+//         uint32_t i;
+//         char c[4];
+//     } test = {0x01000000};
+//     if (test.c[0] == 0x01) {
+//         // 主机是大端字节序,不需要转换
+//         return hostlong;
+//     }
+
+//     // 主机是小端字节序,进行字节序转换
+//     return ((hostlong & 0x000000FF) << 24) |
+//            ((hostlong & 0x0000FF00) << 8) |
+//            ((hostlong & 0x00FF0000) >> 8) |
+//            ((hostlong & 0xFF000000) >> 24);
+// }
+// // 仿写 htonll 函数
+static uint64_t htonll(uint64_t hostlonglong) {
+    // 检查主机是否为大端字节序
+    static const union {
+        uint32_t i;
+        char c[4];
+    } test = {0x01000000};
+    if (test.c[0] == 0x01) {
+        // 主机是大端字节序,不需要转换
+        return hostlonglong;
+    }
+
+    // 将 64 位整数拆分为两个 32 位整数
+    uint32_t high = (hostlonglong >> 32) & 0xFFFFFFFF;
+    uint32_t low = hostlonglong & 0xFFFFFFFF;
+
+    // 分别转换两个 32 位整数的字节序
+    high = htonl(high);
+    low = htonl(low);
+
+    // 合并转换后的两个 32 位整数
+    return ((uint64_t)low << 32) | high;
+}
+// // 仿写 ntohll 函数
+static uint64_t ntohll(uint64_t netlonglong) {
+    // 将 64 位整数拆分为两个 32 位整数
+    uint32_t high = (netlonglong >> 32) & 0xFFFFFFFF;
+    uint32_t low = netlonglong & 0xFFFFFFFF;
+
+    // 分别转换两个 32 位整数的字节序
+    high = ntohl(high);
+    low = ntohl(low);
+
+    // 合并转换后的两个 32 位整数
+    return ((uint64_t)high << 32) | low;
+}
+// 生成随机的 WebSocket 密钥
+void generate_websocket_key(char *key) {
+    static const char charset[] =
+        "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+    for (int i = 0; i < WEBSOCKET_KEY_LEN - 1; ++i) {
+        key[i] = charset[rand() % (sizeof(charset) - 1)];
+    }
+    key[WEBSOCKET_KEY_LEN - 1] = '\0';
+
+    unsigned char encoded[WEBSOCKET_KEY_LEN * 2];
+    size_t olen;
+    mbedtls_base64_encode(encoded, sizeof(encoded), &olen, (const unsigned char *)key, strlen(key));
+    printf("generate_websocket_key %s %d\r\n",encoded ,olen);
+
+    if(olen>=(WEBSOCKET_KEY_LEN-1))
+    olen=WEBSOCKET_KEY_LEN-1;
+
+    strncpy(key, (const char *)encoded, olen);
+
+    key[olen] = '\0';
+}
+
+// 生成 WebSocket 握手响应密钥
+void generate_accept_key(const char *key, char *accept_key) {
+    char combined[128];
+    strcpy(combined, key);
+    strcat(combined, WEBSOCKET_GUID);
+
+    unsigned char sha1_result[20];
+    mbedtls_sha1((const unsigned char *)combined, strlen(combined), sha1_result);
+
+    unsigned char encoded[64];
+    size_t olen;
+    mbedtls_base64_encode(encoded, sizeof(encoded), &olen, sha1_result, 16);//sizeof(sha1_result));
+    strncpy(accept_key, (const char *)encoded, olen);
+    accept_key[olen] = '\0';
+}
+
+// 发送 WebSocket 握手请求
+int send_handshake(WebSocketClient *client,const char *headers) {
+    char key[WEBSOCKET_KEY_LEN];
+    printf("send_handshake1");
+    generate_websocket_key(key);
+    char accept_key[64];
+    int ret = 0;
+    generate_accept_key(key, accept_key);
+    printf("send_handshake2");
+    char *request =( char *)aic_zalloc(BUFFER_SIZE);
+    if(request==NULL)
+    {
+        printf("request aic_zalloc erro");
+        return -1;
+    }
+    
+
+    if(headers!= NULL)
+    {
+        snprintf(request, BUFFER_SIZE,
+            "GET /%s?%s HTTP/1.1\r\n"
+            "Host: %s:%d\r\n"
+            "Upgrade: websocket\r\n"
+            "Connection: Upgrade\r\n"
+            "Sec-WebSocket-Key: %s\r\n"
+            "Sec-WebSocket-Version: 13\r\n"
+            "Origin: http://%s:%d\r\n"
+            "%s\r\n"
+            "\r\n",
+            client->path,client->query  ,client->host,client->port, accept_key,client->host,client->port,headers);
+    }else
+    {
+        snprintf(request, BUFFER_SIZE,
+            "GET /%s?%s HTTP/1.1\r\n"
+            "Host: %s:%d\r\n"
+            "Upgrade: websocket\r\n"
+            "Connection: Upgrade\r\n"
+            "Sec-WebSocket-Key: %s\r\n"
+            "Sec-WebSocket-Version: 13\r\n"
+            "Origin: http://%s:%d\r\n"
+            "\r\n",
+            client->path,client->query , client->host,client->port, accept_key,client->host,client->port);
+    }
+    
+    printf("send_handshake request:\r\n%s",request);
+    if (send(client->sockfd, request, strlen(request), 0) < 0) {
+        printf("send handshake failed");
+        
+        ret = -1;
+    }
+   
+    free(request);
+    printf("send_handshake3 %d",ret);
+    return ret;
+}
+
+
+// 发送 WebSocket 消息
+int send_websocket_message(WebSocketClient *client, const unsigned char *message, size_t message_len, WebSocketMessageType type) {
+    unsigned char *frame=( unsigned char *)aic_zalloc(message_len + 50);
+    int offset = 0;
+    int ret = -1;
+    if(!frame)
+    {
+        printf("send_websocket_message zalloc error");
+        return -1;
+    }
+    // 第一个字节:FIN = 1, 设置 opcode
+    frame[offset++] = 0x80 | type;
+
+    // 第二个字节:设置掩码位和负载长度
+    if (message_len < 126) {
+        frame[offset++] = 0x80 | message_len;
+    } else if (message_len < 65536) {
+        frame[offset++] = 0x80 | 126;
+        uint16_t len = htons((uint16_t)message_len);
+        memcpy(frame + offset, &len, 2);
+        offset += 2;
+    } else {
+        frame[offset++] = 0x80 | 127;
+        uint64_t len = htonll(message_len);
+        memcpy(frame + offset, &len, 8);
+        offset += 8;
+    }
+
+    // 生成掩码密钥
+    unsigned char masking_key[4];
+    for (int i = 0; i < 4; ++i) {
+        masking_key[i] = (unsigned char)rand();
+    }
+    memcpy(frame + offset, masking_key, 4);
+    offset += 4;
+
+    // 掩码处理消息
+    for (size_t i = 0; i < message_len; ++i) {
+        frame[offset + i] = message[i] ^ masking_key[i % 4];
+    }
+    offset += message_len;
+
+    // 发送帧
+    if (send(client->sockfd, frame, offset, 0) < 0) {
+        printf("send message failed");
+        ret =  -1;
+        goto send_websocket_message_ERROR;
+    }
+    ret = 0;
+send_websocket_message_ERROR:
+    free(frame);
+    bk_sleep(message_len/1000+1);
+    return ret;
+}
+
+// 接收 WebSocket 消息,返回读到长度
+int  receive_websocket_message(WebSocketClient *client, unsigned char *buf,int len,WebSocketMessageType *code) {
+    uint32_t timer_ms = (uint32_t)osKernelGetTickCount();
+    //printf("receive_websocket_message 1 timer_ms=%d\n",timer_ms);
+    unsigned char frame[20]={0};
+    unsigned char masking_key[4];
+    unsigned int bytes_received = 0;
+    int recv_len = 0 ;
+    static uint8_t last_byte = 0;
+    // while(1)
+    // {
+    //     recv_len = recv(client->sockfd, frame+bytes_received, 2-bytes_received, 0);
+    //     bytes_received +=recv_len;
+    //     if(bytes_received>=2)
+    //         break;
+    // }
+    while(1)
+    {
+        bytes_received = recv(client->sockfd, frame, 1, 0);
+        if (bytes_received <= 0) {
+            if (bytes_received == 0) {
+                printf("Connection closed by server.\n");
+            } else {
+                printf("receive message failed");
+            }
+            return -1;
+        }
+        if(frame[0]!= 0x80 && frame[0]!= 0x81 && frame[0]!= 0x82 && frame[0]!= 0x88 && frame[0]!= 0x89 && frame[0]!= 0x8A)
+        {
+            printf("receive_websocket_message:hend =0x%X,0x%X ,last_byte =0x%x ERROR!!!!!!!!!",frame[0],frame[1],last_byte);
+
+            if(last_byte!= 0x80 && last_byte!= 0x81 && last_byte!= 0x82 && last_byte!= 0x88 && last_byte!= 0x89 && last_byte!= 0x8A)
+            {
+                printf("receive_websocket_message:hend =0x%X,0x%X ,last_byte =0x%x ERROR222222222!!!!!!!!!",frame[0],frame[1],last_byte);
+                continue;
+            }
+                
+        }else
+        {
+            break;
+        }
+    }
+    timer_ms = (uint32_t)osKernelGetTickCount();
+    //printf("receive_websocket_message 2 timer_ms=%d\n",timer_ms);
+    bytes_received = recv(client->sockfd, frame+1, 1, 0);
+    if (bytes_received <= 0) {
+        if (bytes_received == 0) {
+            printf("Connection closed by server.\n");
+        } else {
+            printf("receive message failed");
+        }
+        return -1;
+    }
+    //unsigned char fin = (frame[0] & 0x80) >> 7;
+    *code = (WebSocketMessageType) (frame[0] & 0x0F);
+    unsigned char mask = (frame[1] & 0x80) >> 7;
+    unsigned int payload_len = frame[1] & 0x7F;
+    
+
+    size_t offset = 2;
+    if (payload_len == 126) {
+        unsigned short extended_payload_len;
+        bytes_received += recv(client->sockfd, frame+offset, 2, 0);
+        memcpy(&extended_payload_len, frame + 2, 2);
+        payload_len = ntohs(extended_payload_len);
+        //printf("receive_websocket_message:payload_len=0x%X",extended_payload_len);
+        offset += 2;
+    } else if (payload_len == 127) {
+        uint64_t extended_payload_len;
+        bytes_received += recv(client->sockfd, frame+offset, 8, 0);
+        memcpy(&extended_payload_len, frame + 2, 8);
+        payload_len = ntohll(extended_payload_len);
+        offset += 8;
+    }
+    if(payload_len>len)
+    {
+        printf("receive_websocket_message:len =%d ERROR",payload_len);
+        recv(client->sockfd, buf, len, 0);
+        return -1;
+    }
+    timer_ms = (uint32_t)osKernelGetTickCount();
+    //printf("receive_websocket_message 3 timer_ms=%d\n",timer_ms);
+    // printf("receive_websocket_message :");
+    // for(int i = 0;i<offset;i++)
+    // {
+    //     printf("%02X",frame[i]);
+    // }
+    // printf("receive_websocket_message:payload_len=%d frame[0]&0x8E=%d",payload_len,frame[0]&0x8E);
+    if (mask) {
+        
+        bytes_received = recv(client->sockfd, frame+offset, 4, 0);
+        memcpy(masking_key, frame + offset, 4);
+        offset += 4;    
+    } 
+    bytes_received = 0;
+    
+    while(1)//读主体内容
+    {
+        //bk_sleep(recv_len/1000+1);
+        recv_len = recv(client->sockfd, buf+bytes_received, payload_len-bytes_received, 0);
+        if(recv_len>0)
+            bytes_received += recv_len;
+        else if(recv_len<0)
+        {
+            printf("receive_websocket_message: recv_len =%d  recv ERROR!!!!!!",recv_len);
+            return -1;
+        }
+        //printf("receive_websocket_message:bytes_received=%d recv_len =%d",bytes_received,recv_len);
+        if(bytes_received >=  payload_len)
+        {
+            //printf("receive_websocket_message:payload_len=%d,bytes_received=%d",payload_len,bytes_received);
+            break;
+        }
+        
+    }
+    if(mask)
+    {
+        for (size_t i = 0; i < payload_len; ++i) {
+            buf[i] = buf[i] ^ masking_key[i % 4];
+        }
+    }
+    
+    // if (*code == WS_TEXT) {
+    //     printf("Received text message: %.*s\n", (int)payload_len, buf);
+    // } else if (*code == WS_BINARY) {
+    //     printf("Received binary message of length %zu\n", payload_len);
+    // }
+
+    if (*code == WS_TEXT)
+    {
+
+    }else if(*code == WS_BINARY)
+    {
+
+    }else if(*code == WS_CLOSE)
+    {
+        payload_len = 0;
+    }else if(*code == WS_PONG)
+    {
+        payload_len = 0;
+    }else if(*code == WS_PING)
+    {
+        send_websocket_message(client,buf,payload_len,WS_PONG);
+        payload_len = 0;
+    }else if(*code == WS_CONT)
+    {
+        payload_len = 0;
+    }
+    last_byte = buf[payload_len-1];
+    timer_ms = (uint32_t)osKernelGetTickCount();
+    //printf("receive_websocket_message 4 timer_ms=%d len = %d\n",timer_ms,payload_len);
+    return payload_len;//parse_frame(buf, bytes_received, buf,code);
+}
+
+// 初始化 WebSocket 客户端
+WebSocketClient *init_websocket_client(const char *url, const char *headers) {
+    //printf("init_websocket_client 1\n");
+    char *buffer = NULL;
+    WebSocketClient *client  =NULL;
+    BK_URL parsed_url = {0};
+    struct sockaddr_in server_addr;
+    ssize_t bytes_received;
+
+    parsed_url = parse_url(url);//解析url
+
+    if (parsed_url.error) {
+        printf("init_websocket_client Error: %s", parsed_url.error_message);
+        goto client_ERROR;
+    } else {
+        printf("Protocol: %s", parsed_url.protocol);
+        printf("Host: %s\n", parsed_url.host);
+        printf("Port: %d\n", parsed_url.port);
+        printf("Path: %s\n", parsed_url.path);
+        printf("Query: %s\n", parsed_url.query);
+
+    }
+    client = (WebSocketClient *)aic_zalloc(sizeof(WebSocketClient)) ;
+    if(!client)
+    {
+        printf("init_websocket_client alloc error");
+        goto client_ERROR;
+    }
+
+    client->sockfd = socket(AF_INET, SOCK_STREAM, 0);
+    if (client->sockfd < 0) {
+        printf("socket creation failed");
+        goto client_ERROR;
+    }
+
+   // printf("init_websocket_client 3\n");
+   
+    server_addr.sin_family = AF_INET;
+
+    server_addr.sin_port = htons(parsed_url.port);
+
+    server_addr.sin_addr.s_addr=inet_addr( parsed_url.host);
+
+    // inet_pton(AF_INET, parsed_url.host, &server_addr.sin_addr);
+
+    if (connect(client->sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
+        printf("init_websocket_client connection failed");
+        close(client->sockfd);
+        goto client_ERROR;
+    }
+     printf("socket creation succ\r\n");
+
+
+    strcpy(client->host, parsed_url.host);
+    strcpy(client->path, parsed_url.path);
+    strcpy(client->query, parsed_url.query);
+    client->port = parsed_url.port;
+    if (send_handshake(client,headers) < 0) { //发送头
+         printf("socket send_handshake client_ERROR");
+        close(client->sockfd);
+        goto client_ERROR;
+    }
+
+    buffer=(char *)aic_zalloc(BUFFER_SIZE);
+    
+    if(buffer==NULL)
+    {
+         printf("aic_zalloc(BUFFER_SIZE);null ");
+          goto client_ERROR;
+    }
+    printf("recv: ???  ");
+
+    bytes_received = recv(client->sockfd, buffer, BUFFER_SIZE - 1, 0);
+
+    printf("recv; ");
+
+    if (bytes_received > 0) {
+        buffer[bytes_received] = '\0';
+        printf("Received handshake response:\n%s\n", buffer);
+    }
+    
+  
+
+    if(strstr(buffer,"HTTP/1.1 101") == NULL)
+    {
+        
+        goto client_ERROR;
+    }
+     printf("init_websocket_client end 1");
+    free(buffer);
+    free_url(parsed_url);
+
+     printf("init_websocket_client end 2");
+    return client;
+client_ERROR:
+    if(buffer)
+        free(buffer);
+    if(client)
+        free(client);
+
+    free_url(parsed_url);
+    
+    return NULL;
+}
+
+// 关闭 WebSocket 客户端
+void close_websocket_client(WebSocketClient *client) {
+    if(client)
+    {
+        printf("close_websocket_client ");
+        close(client->sockfd);
+        free(client);
+    }
+    
+}
+
+char recv_buf[1024]={0};
+WebSocketClient *chat_client;
+
+void send_ai_txt(uint8_t type,char *msg)
+{   
+    cJSON* dataJSON = cJSON_CreateObject();
+    
+    if (dataJSON == NULL) {
+          WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,"Error creating JSON object\n");
+        return;
+    }
+    
+   
+    cJSON_AddStringToObject(dataJSON,"type","chat");
+
+    cJSON_AddStringToObject(dataJSON,"content",msg);
+
+    char *jsonString = cJSON_PrintUnformatted(dataJSON);
+    
+    if (jsonString == NULL) {
+          WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,"Error printing JSON to string\n");
+        cJSON_Delete(dataJSON);
+        return;
+    }
+    
+    uint32_t data_len = strlen(jsonString);
+    cJSON_Delete(dataJSON);
+    
+    if (data_len == 0) {
+          WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,"Error: JSON string length is 0\n");
+        return;
+    }
+    
+    if (send_websocket_message(chat_client,( const unsigned char *)jsonString,strlen(jsonString),WS_TEXT)==0)
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"send_websocket_message succ 0\n");
+ 
+    cJSON_free(jsonString);
+}
+
+
+
+//  {"type":"middle","content":"我是","task_id":"","reasoning_content":""}
+
+bool chat_result_analysis(char *buf)
+{
+     cJSON* root = cJSON_Parse((const char *)buf);
+    if (root == NULL) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"解析失败\n");
+        return false;
+    }
+    char *type_str=NULL;
+    char *content_str=NULL;
+
+    cJSON* type = cJSON_GetObjectItem(root, "type");
+    if (type && cJSON_IsString(type)) {
+          WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,"uid_t: %d\n", uid->valueint);
+         type_str= type->valuestring;
+    }
+    cJSON* content = cJSON_GetObjectItem(root, "content");
+    if (content && cJSON_IsString(content)) {
+          WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,"appid_t: %d\n", appid->valueint);
+        content_str = root->valuestring;
+    }
+   
+    // if(is_end_bool==true)
+    // {
+    //     send_ai_txt(0,result_str);
+    // }
+    cJSON_Delete(root);
+
+    
+}
+
+void bk_websocket_demo(void *data) {
+  
+    while (1)
+    {
+    /* code */
+        chat_client = init_websocket_client("ws://118.145.158.207:22080/chat/ws",NULL);
+        if (chat_client== NULL) {
+            continue ;
+        }
+        // send_ai_txt(1,"你是谁");
+
+        WebSocketMessageType type;
+        while (1)
+        {
+            receive_websocket_message(chat_client,(unsigned char *)recv_buf,1024,&type);
+
+            printf("bk_websocket_demo %s",recv_buf);
+        }
+
+        
+        close_websocket_client(chat_client);
+        chat_client=NULL;
+        continue ;
+    }
+}
+
+
+#include "osal_msgqueue.h"
+#include "thread_init.h"
+#include "soc_osal.h"
+#include "common_def.h"
+#include "los_printf.h"
+
+#define CAT1_SERVICE_TASK_SIZE       (0x1000*2)
+#define CAT1_SERVICE_TASK_PRIO       5
+
+
+errcode_t chat_server_init(void)
+{
+    if(chat_client)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"cat1_tcp_server_init is connet!\r\n");
+        return ERRCODE_FAIL;
+    }
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"cat1_tcp_server_init !\r\n");
+    app_task_definition_t taskcfg={0};
+    taskcfg.create_queue_handle = NULL;
+    taskcfg.attr.name="cat1_service_file";
+    taskcfg.attr.priority = TASK_PRIORITY_APP;
+    taskcfg.attr.stack_size = CAT1_SERVICE_TASK_SIZE;
+    taskcfg.func = bk_websocket_demo;
+    taskcfg.use_mem = USE_EXTEND_MEM;
+  
+    errcode_t ret=uapi_create_osThread_custom(&taskcfg);
+
+
+    if(ret != ERRCODE_SUCC)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"create cat1_service_file failed %d!\r\n",ret);
+        return ERRCODE_FAIL;
+    }
+    return ERRCODE_SUCC;
+}
+
+
+/////////////////////////////////////////////asr///////////////
+
+// http://118.145.158.207:22080ws://amp.raisound.com/asr/ws
+
+char asr_recv_buf[1024]={0};
+WebSocketClient *asr_client;
+
+
+//
+
+void uapi_start_asr()
+{
+    char *jsonString = "{\"header\":{\"event\":\"StartTranscription\",\"trace_id\": \
+     \"3fa6b9e6a30b407ea38ad7ae69e6c291\"},\"payload\":{\"format\":\"MP3\",\"sample_rate\":16000}}";
+
+    if (send_websocket_message(asr_client,( const unsigned char *)jsonString,strlen(jsonString),WS_TEXT)==0)
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"send_websocket_message succ 0\n");
+    else
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"send_websocket_message succ erro\n");
+}
+
+void uapi_stop_asr()
+{
+    char *jsonString ="{\"header\":{\"event\":\"StopTranscription\",\"trace_id\":\"3fa6b9e6a30b407ea38ad7ae69e6c291\"}}";
+
+    if (send_websocket_message(asr_client,( const unsigned char *)jsonString,strlen(jsonString),WS_TEXT)==0)
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"send_websocket_message succ 0\n");
+}
+
+
+
+void send_ai_bin(char *buf,uint32_t len)
+{
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"send_ai_bin 0\n");
+      if (send_websocket_message(asr_client,( const unsigned char *)buf,len,WS_BINARY)==0)
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"send_websocket_message succ 0\n");
+}
+
+void record_test(void)
+{
+    char buf[1024]={0};
+
+    FILE *fp=fopen("/user/aiRecord.sbc","rb+");
+    int read_size;
+
+    uint32_t pack=1024;
+
+    if(fp==NULL)
+    {
+        return;
+    }
+    do
+    {
+        memset_s(buf,1024,0,1024);
+        read_size=fread(buf,1,1024,fp);
+
+        if(read_size!=0)
+        {
+            send_ai_bin(buf,read_size);
+            bk_sleep(10);
+        }
+    
+    } while (read_size==1024);
+    fclose(fp);
+}
+#include "audio_capture_wrapper.h"
+
+// {"status":20000000,"msg":"success","task_id":"80228c9f62821ffe3f867e1a5042d887","event":"TranscriptionStarted","result":null}
+// {"status":20000000,
+// "msg":"success","task_id":"e8274ed1efb60d8146c076a847d7b71a",
+// "event":"SentenceEnd","result":{"result":"你好你好你好你好。",
+// "is_end":true,"sentence_id":"fcb889fe74a0920efe14939de2fd2b1b",
+// "start_time":760,"end_time":2280}} 
+bool aer_result_analysis(char *buf)
+{
+     cJSON* root = cJSON_Parse((const char *)buf);
+    if (root == NULL) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"解析失败\n");
+        return false;
+    }
+    char *result_str=NULL;
+    int start_time_int=0;
+    int end_time_int=0;
+    bool is_end_bool=false;
+    char *event_str=NULL;
+
+    cJSON* event = cJSON_GetObjectItem(root, "event");
+    if (event && cJSON_IsString(event)) {
+        event_str= event->valuestring;
+
+    }
+
+    cJSON* result = cJSON_GetObjectItem(root, "result");
+    if (result && cJSON_IsString(result)) {
+         result_str= result->valuestring;
+    }
+    cJSON* start_time = cJSON_GetObjectItem(root, "start_time");
+    if (start_time && cJSON_IsNumber(start_time)) {
+
+        start_time_int = root->valueint;
+    }
+    cJSON* end_time = cJSON_GetObjectItem(root, "end_time");
+    if (end_time && cJSON_IsNumber(end_time)) {
+        end_time_int = end_time->valueint;
+
+    }
+    
+      cJSON* is_end = cJSON_GetObjectItem(root, "is_end");
+     if (is_end && cJSON_IsBool(is_end)) {
+        is_end_bool = is_end->valueint;
+    }
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"str %s start %d end %d is end\n",result_str,start_time_int,end_time_int,is_end_bool);
+
+    if(is_end_bool==true)
+    {
+        send_ai_txt(0,result_str);
+    }
+    if(strcmp(event_str,"TranscriptionStarted")==0)
+    {
+        streamingRecordAndSend_AI(0);
+    }
+    cJSON_Delete(root);
+
+    
+}
+
+void bk_websocket_asr(void *data) {
+  
+    while (1)
+    {
+        asr_client = init_websocket_client("ws://118.145.158.207:22080/asr/ws",NULL);
+        if (asr_client== NULL) {
+            continue ;
+        }
+
+        WebSocketMessageType type;
+        while (1)
+        {
+            memset_s(asr_recv_buf,1024,0,1024);
+            receive_websocket_message(asr_client,(unsigned char *)asr_recv_buf,1024,&type);
+            // if(type==WS_CONT || 
+            if( type==WS_CLOSE)
+            {
+                break;
+            }
+            aer_result_analysis(asr_recv_buf);
+            printf("bk_websocket_demo %s %d",asr_recv_buf,type);
+        }
+
+        
+        close_websocket_client(asr_client);
+        asr_client=NULL;
+        continue ;
+    }
+    
+   
+}
+
+
+
+
+
+errcode_t asr_server_init(void)
+{
+    if(asr_client)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"cat1_tcp_server_init is connet!\r\n");
+        return ERRCODE_FAIL;
+    }
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"cat1_tcp_server_init !\r\n");
+    app_task_definition_t taskcfg={0};
+    taskcfg.create_queue_handle = NULL;
+    taskcfg.attr.name="cat1_service_file";
+    taskcfg.attr.priority = TASK_PRIORITY_APP;
+    taskcfg.attr.stack_size = CAT1_SERVICE_TASK_SIZE;
+    taskcfg.func = bk_websocket_asr;
+    taskcfg.use_mem = USE_EXTEND_MEM;
+  
+    errcode_t ret=uapi_create_osThread_custom(&taskcfg);
+
+
+    if(ret != ERRCODE_SUCC)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"create cat1_service_file failed %d!\r\n",ret);
+        return ERRCODE_FAIL;
+    }
+    return ERRCODE_SUCC;
+}
+
+
+bool init_ai_task(void)
+{
+    asr_server_init();
+    chat_server_init();
+}
+
+
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
\ No newline at end of file