更新
authorp15692025051 <846603105@qq.com>
Wed, 16 Apr 2025 03:51:01 +0000 (11:51 +0800)
committerp15692025051 <846603105@qq.com>
Wed, 16 Apr 2025 03:51:01 +0000 (11:51 +0800)
2.code/aicos/app/AI_AMP_2_5/AI_AMP_2_5.c
2.code/aicos/app/AI_AMP_2_5/AI_AMP_2_5.h
2.code/aicos/app/AI_AMP_2_5/bk_websocket.c
2.code/aicos/app/AI_AMP_2_5/bk_websocket.h

index 896a6ae..8c9472d 100644 (file)
@@ -222,7 +222,7 @@ static void AI_VC_send_satrt(void)
     cJSON_AddNumberToObject(outbound_cfg, "volume", 100);
     cJSON_AddNumberToObject(outbound_cfg, "speech_rate", 0);
     cJSON_AddNumberToObject(outbound_cfg, "chunk_interval_ms", 100);
-    cJSON_AddStringToObject(outbound_cfg, "voice", "zh_female_linjianvhai_moon_bigtts");
+    cJSON_AddStringToObject(outbound_cfg, "voice", "7468512265134915635");
     cJSON_AddItemToObject(outbound_attributes, "cfg", outbound_cfg);
     cJSON_AddItemToObject(payload, "outbound_attributes", outbound_attributes);
 
@@ -298,7 +298,7 @@ static int websocket_connect_VC(void)
     //连接服务器
     if(AI_client_VC == NULL)
     {
-        AI_client_VC = init_websocket_client("118.145.158.207","/vc/chat?is_auth=0",22086);
+        AI_client_VC = init_websocket_client("ws://118.145.158.207:22086/vc/coze?is_auth=0",NULL);
     }
     //创建发送线程
     if(AI_VC_send_task_id == 0)
@@ -425,8 +425,8 @@ static void AI_VC_send_task(void *thread_input)//websocket 发送线程
                     (WebSocketMessageType)AI_VC_send_queue_data.AIC_WEBSOCKET_OPCODE);
                 if(AI_VC_send_queue_data.AIC_WEBSOCKET_OPCODE ==AIC_WEBSOCKET_OPCODE_TEXT_FRAME )
                     bk_printf("VCVC:send text ret=%d,len=%d,str=%s",ret,AI_VC_send_queue_data.len,AI_VC_send_queue_data.data);
-                // else if(AI_VC_send_queue_data.AIC_WEBSOCKET_OPCODE ==AIC_WEBSOCKET_OPCODE_BINARY_FRAME )
-                //     bk_printf("VCVC:send bin ret=%d,len=%d",ret,AI_VC_send_queue_data.len);
+                else if(AI_VC_send_queue_data.AIC_WEBSOCKET_OPCODE ==AIC_WEBSOCKET_OPCODE_BINARY_FRAME )
+                    bk_printf("VCVC:send bin ret=%d,len=%d",ret,AI_VC_send_queue_data.len);
                 aic_free(AI_VC_send_queue_data.data);
             }else
             {
@@ -439,7 +439,7 @@ static void AI_VC_send_task(void *thread_input)//websocket 发送线程
     }
     
 }
-static u8 recv_buff[10*1024];
+static u8 recv_buff[20*1024];
 static void AI_VC_read_task(void *thread_input)//websocket 读线程
 {
     int result_val=0;
@@ -726,13 +726,14 @@ static void AI_VC_record_task(void *thread_input)//录音线程
         if(ret<=0)
         {
             bk_printf("AI_VC_record_task continue len = %d,VC_state = %d",ret,VC_state);
+            aos_sleep(1);
             continue;
         }
         if(VC_state == VC_State_None)//开启的时候,先缓存音频
         {
 
             AI_VC_put_record_data(vrecord_buf,ret);
-        }else if(VC_state >= VC_State_Listening && VC_state<VC_State_TTSStart)//正常录音
+        }else if(VC_state >= VC_State_Listening )//正常录音
         {
             char count_t = 200;
             while(count_t--)
@@ -870,7 +871,11 @@ void AI_key_long_press(void)
 {
     bk_printf("AI_key_long_press");
 }
-
+void pwk_key_release(void)
+{
+    bk_printf("pwk_key_release");
+    AI_VC_Close();
+}
 void AI_VC_start(void)
 {
     int ret = 0;
@@ -1011,6 +1016,10 @@ static void AI_AMP_2_5_task(void *thread_input)//做逻辑线程
             case AI_KEY_LONG_PRESS:
                 AI_key_long_press();
                 break;  
+            case PWK_KEY_RELEASE:
+                pwk_key_release();
+                break;  
+                
             case AI_PRINTF:
                 if(AI_AMP_msg.data)
                 uart_write(ai_uart_handle,AI_AMP_msg.data, AI_AMP_msg.len);
index a9a403f..65f84ef 100644 (file)
@@ -12,6 +12,7 @@ typedef enum AI_AMP_MSG
     AI_KEY_PRESS,//AI键按下
     AI_KEY_RELEASE,//AI键释放
     AI_KEY_LONG_PRESS,//AI键长按
+    PWK_KEY_RELEASE,//侧键
     AI_PRINTF,//打印
 } AI_AMP_MSG_Type;
 typedef struct
index 75cc87e..8eb726a 100644 (file)
@@ -63,6 +63,173 @@ void bk_sleep(u32 time)
 {
     aos_sleep(time);
 }
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+// 定义一个结构体来存储解析后的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) {
+        // 若分配失败,输出提示信息
+        bk_printf("Memory allocation failed for error message.\n");
+    }
+
+}
+
+// 解析URL的函数
+BK_URL parse_url(const char *url) {
+    bk_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");
+        aic_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");
+        aic_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");
+        aic_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");
+            aic_free(temp_url_t);
+            return result;
+        }
+        result.port = atoi(colon_port + 1);
+        if (!result.port) {
+            set_url_error(&result, "Invalid port number");
+            aic_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");
+            aic_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;
+    //bk_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");
+            aic_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");
+            aic_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");
+            aic_free(temp_url_t);
+            return result;
+        }
+        result.query = NULL;
+    }
+
+    aic_free(temp_url_t);
+
+    return result;
+}
+
+// 释放URL结构体中分配的内存
+void free_url(BK_URL url) {
+
+    // 释放已分配的内存
+
+    if (url.protocol) {
+        aic_free(url.protocol);
+        url.protocol = NULL;
+    }
+    if (url.host) {
+        aic_free(url.host);
+        url.host = NULL;
+    }
+    if (url.path) {
+        aic_free(url.path);
+        url.path = NULL;
+    }
+    if (url.query) {
+        aic_free(url.query);
+        url.query = NULL;
+    }
+    if (url.error_message) {
+        aic_free(url.error_message);
+        url.error_message = NULL;
+    }
+
+}
+
 // 仿写 htonl 函数
 static uint32_t htonl(uint32_t hostlong) {
     // 检查主机是否为大端字节序
@@ -150,7 +317,7 @@ void generate_accept_key(const char *key, char *accept_key) {
 }
 
 // 发送 WebSocket 握手请求
-int send_handshake(WebSocketClient *client) {
+int send_handshake(WebSocketClient *client,const char *headers) {
     char key[WEBSOCKET_KEY_LEN];
     bk_printf("send_handshake1");
     generate_websocket_key(key);
@@ -159,16 +326,33 @@ int send_handshake(WebSocketClient *client) {
     generate_accept_key(key, accept_key);
     bk_printf("send_handshake2");
     char *request =aic_zalloc(BUFFER_SIZE);
-    snprintf(request, BUFFER_SIZE,
-             "GET %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->host,client->port, accept_key,client->host,client->port);
+    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);
+    }
+    
         bk_printf("send_handshake request:\r\n%s",request);
     if (send(client->sockfd, request, strlen(request), 0) < 0) {
         bk_printf("send handshake failed");
@@ -309,7 +493,7 @@ int  receive_websocket_message(WebSocketClient *client, unsigned char *buf,int l
     }
     if(payload_len>len)
     {
-        bk_printf("receive_websocket_message:len ERROR");
+        bk_printf("receive_websocket_message:len =%d ERROR",payload_len);
         recv(client->sockfd, buf, len, 0);
         return -1;
     }
@@ -384,15 +568,31 @@ int  receive_websocket_message(WebSocketClient *client, unsigned char *buf,int l
 }
 
 // 初始化 WebSocket 客户端
-WebSocketClient *init_websocket_client(const char *host, const char *path, int port) {
+WebSocketClient *init_websocket_client(const char *url, const char *headers) {
     //bk_printf("init_websocket_client 1\n");
     char *buffer = NULL;
-    WebSocketClient *client = aic_zalloc(sizeof(WebSocketClient)) ;
+    WebSocketClient *client  =NULL;
+    BK_URL parsed_url = {0};
+    parsed_url = parse_url(url);//解析url
+    bk_printf("Error: %x", parsed_url);
+    if (parsed_url.error) {
+        bk_printf("Error: %s", parsed_url.error_message);
+        goto client_ERROR;
+    } else {
+        bk_printf("Protocol: %s", parsed_url.protocol);
+        bk_printf("Host: %s", parsed_url.host);
+        bk_printf("Port: %d", parsed_url.port);
+        bk_printf("Path: %s", parsed_url.path);
+        bk_printf("Query: %s", parsed_url.query);
+
+    }
+    client = aic_zalloc(sizeof(WebSocketClient)) ;
     if(!client)
     {
         bk_printf("init_websocket_client alloc error");
-        return NULL;
+        goto client_ERROR;
     }
+
     client->sockfd = socket(AF_INET, SOCK_STREAM, 0);
     if (client->sockfd < 0) {
         bk_printf("socket creation failed");
@@ -402,8 +602,8 @@ WebSocketClient *init_websocket_client(const char *host, const char *path, int p
    // bk_printf("init_websocket_client 3\n");
     struct sockaddr_in server_addr;
     server_addr.sin_family = AF_INET;
-    server_addr.sin_port = htons(port);
-    inet_pton(AF_INET, host, &server_addr.sin_addr);
+    server_addr.sin_port = htons(parsed_url.port);
+    inet_pton(AF_INET, parsed_url.host, &server_addr.sin_addr);
 
     if (connect(client->sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
         bk_printf("connection failed");
@@ -412,10 +612,11 @@ WebSocketClient *init_websocket_client(const char *host, const char *path, int p
     }
 
 
-    strcpy(client->host, host);
-    strcpy(client->path, path);
-    client->port = port;
-    if (send_handshake(client) < 0) {
+    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) { //发送头
         close(client->sockfd);
         goto client_ERROR;
     }
@@ -432,13 +633,14 @@ WebSocketClient *init_websocket_client(const char *host, const char *path, int p
         goto client_ERROR;
     }
     aic_free(buffer);
-
+    free_url(parsed_url);
     return client;
 client_ERROR:
     if(buffer)
         aic_free(buffer);
     if(client)
         aic_free(client);
+    free_url(parsed_url);
     return NULL;
 }
 
@@ -454,7 +656,7 @@ void close_websocket_client(WebSocketClient *client) {
 
 int bk_websocket_demo(void) {
     WebSocketClient *client;
-    client = init_websocket_client("127.0.0.1", "/", 8080) ;
+    client = init_websocket_client("ws://118.145.158.207:22086/vc/coze?is_auth=0",NULL);
     if (client== NULL) {
         return -1;
     }
index b523fd1..5214e65 100644 (file)
@@ -16,12 +16,13 @@ typedef struct {
     int sockfd;
     char host[128];
     char path[128];
+    char query[128];
     int port;
 } WebSocketClient;
 
 
 // 初始化 WebSocket 客户端
-WebSocketClient *init_websocket_client(const char *host, const char *path, int port);
+WebSocketClient *init_websocket_client(const char *url, const char *headers);
 
 // 关闭 WebSocket 客户端
 void close_websocket_client(WebSocketClient *client) ;