From a92aa7202f3bde2128ed4d9a7e93aca2bd3f825f Mon Sep 17 00:00:00 2001 From: hcj <1224667075@qq.com> Date: Wed, 28 May 2025 09:51:16 +0800 Subject: [PATCH] =?utf8?q?=E5=A2=9E=E5=8A=A0=E9=83=A8=E5=88=86AI=E6=8E=A5?= =?utf8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../slip/cat1Service/CMakeLists.txt | 2 + .../slip/cat1Service/bk_websocket.h | 41 + .../peripheral/slip/cat1Service/cat1_ws.cpp | 1115 +++++++++++++++++ 3 files changed, 1158 insertions(+) create mode 100644 code/sdk/drivers/peripheral/slip/cat1Service/bk_websocket.h create mode 100644 code/sdk/drivers/peripheral/slip/cat1Service/cat1_ws.cpp diff --git a/code/sdk/drivers/peripheral/slip/cat1Service/CMakeLists.txt b/code/sdk/drivers/peripheral/slip/cat1Service/CMakeLists.txt index d96d0530d..c7912d588 100644 --- a/code/sdk/drivers/peripheral/slip/cat1Service/CMakeLists.txt +++ b/code/sdk/drivers/peripheral/slip/cat1Service/CMakeLists.txt @@ -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 index 000000000..5448709e1 --- /dev/null +++ b/code/sdk/drivers/peripheral/slip/cat1Service/bk_websocket.h @@ -0,0 +1,41 @@ + +#ifndef __BK_WEBSOCKET_H__ +#define __BK_WEBSOCKET_H__ +// #include "aic_osa.h" + +// WebSocket 消息类型枚举 +typedef enum { + WS_CONT = 0x00, + WS_TEXT = 0x01, + WS_BINARY = 0x02, + WS_CLOSE = 0x8, + WS_PING = 0x9, + WS_PONG = 0xa +} WebSocketMessageType; +// WebSocket 客户端结构体 +typedef struct { + int sockfd; + char host[128]; + char path[128]; + char query[128]; + int port; +} WebSocketClient; + + +// 初始化 WebSocket 客户端 +WebSocketClient *init_websocket_client(const char *url, const char *headers); + +// 关闭 WebSocket 客户端 +void close_websocket_client(WebSocketClient *client) ; + +// 接收 WebSocket 消息 +int receive_websocket_message(WebSocketClient *client, unsigned char *buf,int len,WebSocketMessageType *code); + +// 发送 WebSocket 消息 +int send_websocket_message(WebSocketClient *client, const unsigned char *message, size_t message_len, WebSocketMessageType type) ; + +void send_ai_bin(char *buf,uint32_t len); + +void uapi_start_asr(); + +#endif 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 index 000000000..606b4e6f0 --- /dev/null +++ b/code/sdk/drivers/peripheral/slip/cat1Service/cat1_ws.cpp @@ -0,0 +1,1115 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#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 +// #include +#include "lwip/inet.h" +#include +// #include +// #include +#include + +#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 + +#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 +// #include +// #include +// #include +// #include +// #include +// #include + +// #include +// #include +// #include +// #include +// #include +// #include +// #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 +#include +#include +#include +#include + +// 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 +#include + +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 +#include +#include + +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;isockfd, 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 -- 2.17.1