--- /dev/null
+#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