From: 孙春阳 Date: Sun, 10 Aug 2025 22:13:35 +0000 (+0800) Subject: 恢复cat1_ws. 原始代码,为移植tcp_sample_manager接口做准备。 X-Git-Url: http://git.snicker.com.cn/css/static/gitweb.css?a=commitdiff_plain;h=6ec0db1a2e2649362f8ab1b5ca494cc088c62148;p=mirrors%2FFD230.git 恢复cat1_ws. 原始代码,为移植tcp_sample_manager接口做准备。 --- diff --git a/code/sdk/application/brandy/brandy_standard/thread_pri_init.c b/code/sdk/application/brandy/brandy_standard/thread_pri_init.c index 144ad206a..6d38c3059 100755 --- a/code/sdk/application/brandy/brandy_standard/thread_pri_init.c +++ b/code/sdk/application/brandy/brandy_standard/thread_pri_init.c @@ -498,8 +498,7 @@ uapi_pm_remove_sleep_veto(PM_ID_DEBUG); #endif #ifdef TCP_MANAGER_ENABLED - tcp_manager_test_init(); - PRINT("TCP管理器测试模块初始化完成\n"); + // tcp_manager_test_init(); #endif uapi_custom_cmd_service_init(); diff --git a/code/sdk/drivers/peripheral/slip/cat1Service/bk_websocket.h b/code/sdk/drivers/peripheral/slip/cat1Service/bk_websocket.h index 0ccf6fc3d..a3380a9cb 100644 --- a/code/sdk/drivers/peripheral/slip/cat1Service/bk_websocket.h +++ b/code/sdk/drivers/peripheral/slip/cat1Service/bk_websocket.h @@ -39,18 +39,6 @@ void lwip_close_websocket_client(WebSocketClient *client) ; int receive_websocket_message(WebSocketClient *client, unsigned char *buf,int len,WebSocketMessageType *code); int send_websocket_message(WebSocketClient *client, uint8_t *message, size_t message_len, WebSocketMessageType type) ; -// === IO thread wrappers to ensure all socket operations are executed on a single thread === -// RX callback: invoked in IO thread context when data is read for a session -typedef void (*ws_rx_callback_t)(WebSocketClient *client, const uint8_t *data, int len, WebSocketMessageType type, void *user); - -void ws_io_init(void); -// Basic open (no RX callback; use ws_io_recv instead) -WebSocketClient *ws_io_open(const char *url, const char *headers, uint8_t use_dns); -// Extended open with RX callback (recommended) -WebSocketClient *ws_io_open_ex(const char *url, const char *headers, uint8_t use_dns, ws_rx_callback_t cb, void *user); -int ws_io_send(WebSocketClient *client, uint8_t *message, size_t message_len, WebSocketMessageType type); -int ws_io_recv(WebSocketClient *client, unsigned char *buf, int len, WebSocketMessageType *code); -void ws_io_close(WebSocketClient *client); #ifdef __cplusplus #if __cplusplus diff --git a/code/sdk/drivers/peripheral/slip/cat1Service/cat1_ai_server.cpp b/code/sdk/drivers/peripheral/slip/cat1Service/cat1_ai_server.cpp index cdfe4f5fb..ac17fc3b0 100644 --- a/code/sdk/drivers/peripheral/slip/cat1Service/cat1_ai_server.cpp +++ b/code/sdk/drivers/peripheral/slip/cat1Service/cat1_ai_server.cpp @@ -759,7 +759,7 @@ errcode_t chat_server_init(void) chat_taskcfg.create_queue_handle = NULL; chat_taskcfg.attr.name="chat_server_init"; chat_taskcfg.attr.priority = TASK_PRIORITY_APP; - chat_taskcfg.attr.stack_size = 0x1000; + chat_taskcfg.attr.stack_size = 0x2000; chat_taskcfg.func = bk_websocket_demo; chat_taskcfg.use_mem = USE_EXTEND_MEM; diff --git a/code/sdk/drivers/peripheral/slip/cat1Service/cat1_ws.cpp b/code/sdk/drivers/peripheral/slip/cat1Service/cat1_ws.cpp index d0443eab3..c3bb8444e 100644 --- a/code/sdk/drivers/peripheral/slip/cat1Service/cat1_ws.cpp +++ b/code/sdk/drivers/peripheral/slip/cat1Service/cat1_ws.cpp @@ -110,7 +110,9 @@ extern "C" { #include "mbedtls/sha1.h" - +#define BUFFER_SIZE 1024 +#define WEBSOCKET_KEY_LEN 24 +#define WEBSOCKET_GUID "1234567890123456" // #include "fs/fs.h" // #include "spiflash.h" @@ -126,258 +128,6 @@ extern "C" { #include #include -#include "msgqueue/osal_msgqueue.h" -#include "semaphore/osal_semaphore.h" -#include "bk_websocket.h" - - -#define BUFFER_SIZE 1024 -#define WEBSOCKET_KEY_LEN 25 -#define WEBSOCKET_GUID "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" - -// IO thread and command queue to serialize all socket operations -typedef enum { - WS_CMD_OPEN, - WS_CMD_SEND, - WS_CMD_RECV, - WS_CMD_CLOSE -} ws_cmd_type_t; - -typedef struct { - ws_cmd_type_t cmd; - // input args - const char *url; - const char *headers; - uint8_t use_dns; - WebSocketClient *client; - uint8_t *tx; - size_t tx_len; - WebSocketMessageType tx_type; - unsigned char *rx; - int rx_len; - WebSocketMessageType *rx_type; - // completion - int result_int; - WebSocketClient *result_client; - osal_semaphore sem; // completion semaphore -} ws_cmd_t; - -// Per-session RX callback registration -typedef struct { - WebSocketClient *client; - ws_rx_callback_t rx_cb; - void *user; -} ws_session_t; - -#define WS_MAX_SESSIONS 8 -static ws_session_t g_ws_sessions[WS_MAX_SESSIONS]; - -static unsigned long g_ws_queue_id = 0; -static osThreadId_t g_ws_io_thread = NULL; - -static void ws_cmd_init(ws_cmd_t *cmd) -{ - memset(cmd, 0, sizeof(*cmd)); - (void)osal_sem_init(&cmd->sem, 0); -} - -static void ws_cmd_deinit(ws_cmd_t *cmd) -{ - osal_sem_destroy(&cmd->sem); -} - -static void ws_sessions_init(void) -{ - memset(g_ws_sessions, 0, sizeof(g_ws_sessions)); -} - -static int ws_sessions_add(WebSocketClient *c, ws_rx_callback_t cb, void *user) -{ - for (int i = 0; i < WS_MAX_SESSIONS; ++i) { - if (g_ws_sessions[i].client == NULL) { - g_ws_sessions[i].client = c; - g_ws_sessions[i].rx_cb = cb; - g_ws_sessions[i].user = user; - return 0; - } - } - return -1; -} - -static void ws_sessions_remove(WebSocketClient *c) -{ - for (int i = 0; i < WS_MAX_SESSIONS; ++i) { - if (g_ws_sessions[i].client == c) { - memset(&g_ws_sessions[i], 0, sizeof(g_ws_sessions[i])); - return; - } - } -} - -static ws_session_t *ws_sessions_find(WebSocketClient *c) -{ - for (int i = 0; i < WS_MAX_SESSIONS; ++i) { - if (g_ws_sessions[i].client == c) { - return &g_ws_sessions[i]; - } - } - return NULL; -} - -static void ws_io_thread_entry(void *arg) -{ - (void)arg; - while (1) { - // Process next command if available; else try to poll RX on active sessions - ws_cmd_t *cmd_ptr = NULL; - unsigned int msg_size = sizeof(cmd_ptr); - if (osal_msg_queue_read_copy(g_ws_queue_id, &cmd_ptr, &msg_size, 10) == OSAL_SUCCESS && cmd_ptr != NULL) { - switch (cmd_ptr->cmd) { - case WS_CMD_OPEN: - cmd_ptr->result_client = init_websocket_client(cmd_ptr->url, cmd_ptr->headers, cmd_ptr->use_dns); - cmd_ptr->result_int = (cmd_ptr->result_client != NULL) ? 0 : -1; - break; - case WS_CMD_SEND: - cmd_ptr->result_int = send_websocket_message(cmd_ptr->client, cmd_ptr->tx, cmd_ptr->tx_len, cmd_ptr->tx_type); - break; - case WS_CMD_RECV: - cmd_ptr->result_int = receive_websocket_message(cmd_ptr->client, cmd_ptr->rx, cmd_ptr->rx_len, cmd_ptr->rx_type); - break; - case WS_CMD_CLOSE: - lwip_close_websocket_client(cmd_ptr->client); - ws_sessions_remove(cmd_ptr->client); - cmd_ptr->result_int = 0; - break; - default: - cmd_ptr->result_int = -1; - break; - } - osal_sem_up(&cmd_ptr->sem); - continue; - } - // No command -> build fd_set and wait for readable sockets - fd_set rfds; FD_ZERO(&rfds); - int maxfd = -1; int active = 0; - for (int i = 0; i < WS_MAX_SESSIONS; ++i) { - ws_session_t *s = &g_ws_sessions[i]; - if (s->client == NULL || s->rx_cb == NULL) continue; - FD_SET(s->client->sockfd, &rfds); - if (s->client->sockfd > maxfd) maxfd = s->client->sockfd; - active++; - } - if (active == 0 || maxfd < 0) { - // nothing to poll - continue; - } - struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 20000; // 20ms - int ready = lwip_select(maxfd + 1, &rfds, NULL, NULL, &tv); - if (ready <= 0) { - continue; - } - for (int i = 0; i < WS_MAX_SESSIONS; ++i) { - ws_session_t *s = &g_ws_sessions[i]; - if (s->client == NULL || s->rx_cb == NULL) continue; - if (!FD_ISSET(s->client->sockfd, &rfds)) continue; - WebSocketMessageType type; - uint8_t buf[1024]; - int n = receive_websocket_message(s->client, buf, sizeof(buf), &type); - if (n > 0) { - s->rx_cb(s->client, buf, n, type, s->user); - } - } - } -} - -void ws_io_init(void) -{ - if (g_ws_queue_id == 0) { - (void)osal_msg_queue_create("ws_io_q", 16, &g_ws_queue_id, 0, sizeof(ws_cmd_t *)); - } - if (g_ws_io_thread == NULL) { - osThreadAttr_t attr; memset(&attr, 0, sizeof(attr)); attr.name = "ws_io"; attr.stack_size = 4096; attr.priority = osPriorityNormal; - ws_sessions_init(); - g_ws_io_thread = osThreadNew(ws_io_thread_entry, NULL, &attr); - } -} - -static int ws_enqueue_and_wait(ws_cmd_t *cmd) -{ - ws_cmd_t *ptr = cmd; - if (osal_msg_queue_write_copy(g_ws_queue_id, &ptr, sizeof(ptr), OSAL_MSGQ_WAIT_FOREVER) != OSAL_SUCCESS) { - return -1; - } - (void)osal_sem_down(&cmd->sem); - return 0; -} - -WebSocketClient *ws_io_open(const char *url, const char *headers, uint8_t use_dns) -{ - ws_cmd_t cmd; ws_cmd_init(&cmd); - cmd.cmd = WS_CMD_OPEN; - cmd.url = url; - cmd.headers = headers; - cmd.use_dns = use_dns; - if (ws_enqueue_and_wait(&cmd) != 0) { - ws_cmd_deinit(&cmd); - return NULL; - } - WebSocketClient *cli = cmd.result_client; - ws_cmd_deinit(&cmd); - return cli; -} - -WebSocketClient *ws_io_open_ex(const char *url, const char *headers, uint8_t use_dns, ws_rx_callback_t cb, void *user) -{ - WebSocketClient *cli = ws_io_open(url, headers, use_dns); - if (cli && cb) { - (void)ws_sessions_add(cli, cb, user); - } - return cli; -} - -int ws_io_send(WebSocketClient *client, uint8_t *message, size_t message_len, WebSocketMessageType type) -{ - ws_cmd_t cmd; ws_cmd_init(&cmd); - cmd.cmd = WS_CMD_SEND; - cmd.client = client; - cmd.tx = message; - cmd.tx_len = message_len; - cmd.tx_type = type; - if (ws_enqueue_and_wait(&cmd) != 0) { - ws_cmd_deinit(&cmd); - return -1; - } - int ret = cmd.result_int; - ws_cmd_deinit(&cmd); - return ret; -} - -int ws_io_recv(WebSocketClient *client, unsigned char *buf, int len, WebSocketMessageType *code) -{ - ws_cmd_t cmd; ws_cmd_init(&cmd); - cmd.cmd = WS_CMD_RECV; - cmd.client = client; - cmd.rx = buf; - cmd.rx_len = len; - cmd.rx_type = code; - if (ws_enqueue_and_wait(&cmd) != 0) { - ws_cmd_deinit(&cmd); - return -1; - } - int ret = cmd.result_int; - ws_cmd_deinit(&cmd); - return ret; -} - -void ws_io_close(WebSocketClient *client) -{ - ws_cmd_t cmd; ws_cmd_init(&cmd); - cmd.cmd = WS_CMD_CLOSE; - cmd.client = client; - (void)ws_enqueue_and_wait(&cmd); - ws_cmd_deinit(&cmd); -} - extern osStatus_t osDelay(uint32_t ticks); #define cat1_msleep(ms) LOS_Msleep(ms) /* osDelay(1) : 1ms */ @@ -620,15 +370,23 @@ static uint64_t ntohll(uint64_t netlonglong) { } // 生成随机的 WebSocket 密钥 void generate_websocket_key(char *key) { - unsigned char raw[16]; - for (int i = 0; i < 16; ++i) { - raw[i] = (unsigned char)(rand() & 0xFF); - } - size_t olen = 0; - mbedtls_base64_encode((unsigned char *)key, WEBSOCKET_KEY_LEN, &olen, raw, sizeof(raw)); - if (olen >= WEBSOCKET_KEY_LEN) { - olen = WEBSOCKET_KEY_LEN - 1; + 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'; } @@ -643,7 +401,7 @@ void generate_accept_key(const char *key, char *accept_key) { unsigned char encoded[64]; size_t olen; - mbedtls_base64_encode(encoded, sizeof(encoded), &olen, sha1_result, sizeof(sha1_result)); + mbedtls_base64_encode(encoded, sizeof(encoded), &olen, sha1_result, 16);//sizeof(sha1_result)); strncpy(accept_key, (const char *)encoded, olen); accept_key[olen] = '\0'; } @@ -668,7 +426,7 @@ int send_handshake(WebSocketClient *client,const char *headers) { if(headers!= NULL) { snprintf(request, BUFFER_SIZE, - "GET /%s%s%s HTTP/1.1\r\n" + "GET /%s?%s HTTP/1.1\r\n" "Host: %s:%d\r\n" "Upgrade: websocket\r\n" "Connection: Upgrade\r\n" @@ -677,11 +435,11 @@ int send_handshake(WebSocketClient *client,const char *headers) { "Origin: http://%s:%d\r\n" "%s\r\n" "\r\n", - client->path ? client->path : "", (client->query?"?":""), (client->query?client->query:"") ,client->host,client->port, key,client->host,client->port,headers); + client->path,client->query ,client->host,client->port, accept_key,client->host,client->port,headers); }else { snprintf(request, BUFFER_SIZE, - "GET /%s%s%s HTTP/1.1\r\n" + "GET /%s?%s HTTP/1.1\r\n" "Host: %s:%d\r\n" "Upgrade: websocket\r\n" "Connection: Upgrade\r\n" @@ -689,7 +447,7 @@ int send_handshake(WebSocketClient *client,const char *headers) { "Sec-WebSocket-Version: 13\r\n" "Origin: http://%s:%d\r\n" "\r\n", - client->path ? client->path : "", (client->query?"?":""), (client->query?client->query:"") , client->host,client->port, key,client->host,client->port); + client->path,client->query , client->host,client->port, accept_key,client->host,client->port); } printf("send_handshake request:\r\n%s",request); @@ -961,10 +719,8 @@ static void dns_found(const char* hostname, const ip_addr_t *ipaddr, void *arg) { struct cat1_ws_init_t * ip_sem=(struct cat1_ws_init_t *)arg; - printf("hostname %s\r\n", hostname); - if (ipaddr != NULL) { - memcpy(&(ip_sem->ip), ipaddr, sizeof(*ipaddr)); - } + printf("hostname %s ipaddr%d \r\n",hostname,ipaddr->u_addr.ip4); + memcpy(&(ip_sem->ip),ipaddr,sizeof(ipaddr)); (void)osSemaphoreRelease(ip_sem->dns_done_sem); } @@ -1017,28 +773,20 @@ WebSocketClient *init_websocket_client(const char *url, const char *headers,uint // printf("init_websocket_client 3\n"); if(use_dns) { - // If host is numeric IP, bypass DNS - if (inet_aton(parsed_url.host, &in_addr_t)) { - memcpy(&server_addr.sin_addr, &in_addr_t, sizeof(in_addr_t)); - } else { - ip_sem.dns_done_sem= osSemaphoreNew(1, 0, NULL); - if(ip_sem.dns_done_sem==0) - { - goto client_ERROR; - } + ip_sem.dns_done_sem= osSemaphoreNew(1, 0, NULL); + if(ip_sem.dns_done_sem==0) + { + goto client_ERROR; + } - ret = dns_gethostbyname(parsed_url.host, &ip, dns_found, &ip_sem); - if (ret == ERR_OK) { - memcpy(&server_addr.sin_addr.s_addr, &ip.u_addr.ip4, 4); - } else if (ret == ERR_INPROGRESS) { - osSemaphoreAcquire(ip_sem.dns_done_sem, 1000*30); - memcpy(&server_addr.sin_addr.s_addr, &ip_sem.ip.u_addr.ip4, 4); - } else { - osSemaphoreDelete(ip_sem.dns_done_sem); - goto client_ERROR; - } - osSemaphoreDelete(ip_sem.dns_done_sem); + ret =dns_gethostbyname(parsed_url.host,&ip,dns_found,&ip_sem); + // if(ERR_OK==ret) + { + osSemaphoreAcquire(ip_sem.dns_done_sem, 1000*30); } + osSemaphoreDelete(ip_sem.dns_done_sem); + printf("dns_gethostbyname %d\r\n",ip_sem.ip.u_addr.ip4); + memcpy(&server_addr.sin_addr.s_addr, &ip_sem.ip.u_addr.ip4, 4); } else diff --git a/code/sdk/drivers/peripheral/slip/websocket_test.c b/code/sdk/drivers/peripheral/slip/websocket_test.c index 1fbdec26f..d73e7cea9 100644 --- a/code/sdk/drivers/peripheral/slip/websocket_test.c +++ b/code/sdk/drivers/peripheral/slip/websocket_test.c @@ -2,7 +2,6 @@ * WebSocket测试程序 * 基于LiteOS-M系统 * 通过AT^TESTWEBSOCKET命令执行测试 - * 支持多线程并发测试同一服务器 */ #ifdef SUPPORT_WEBSOCKET_TEST @@ -24,49 +23,23 @@ extern "C" { // 测试配置 #define TEST_DATA_SIZE 228 -#define MAX_TEST_COUNT 100000 +#define MAX_TEST_COUNT 1000 #define THREAD_STACK_SIZE 4096 #define THREAD_PRIORITY 10 -#define MAX_CONCURRENT_THREADS 16 -#define MAX_CONCURRENT_CONNECTIONS 8 - -// Queue message for received frames via IO thread callback -typedef struct { - WebSocketMessageType type; - int len; - uint8_t data[TEST_DATA_SIZE]; - uint32_t thread_id; // 标识来自哪个线程 -} ws_msg_t; - -static osMessageQueueId_t g_ws_rx_queue = NULL; - -// 线程信息结构 -typedef struct { - osThreadId_t thread_id; - uint32_t thread_index; - WebSocketClient *client; - bool active; - uint32_t send_count; - uint32_t recv_count; - uint32_t lost_count; - uint8_t expected_data[TEST_DATA_SIZE]; - uint8_t received_data[TEST_DATA_SIZE]; - osMutexId_t thread_mutex; -} test_thread_info_t; // 全局变量 +static osThreadId_t send_thread_id = NULL; +static osThreadId_t recv_thread_id = NULL; static osMutexId_t test_mutex = NULL; static osSemaphoreId_t test_semaphore = NULL; -static osTimerId_t test_timer = NULL; -static test_thread_info_t test_threads[MAX_CONCURRENT_THREADS] = {0}; -static uint32_t active_thread_count = 0; +static WebSocketClient *test_client = NULL; static bool test_running = false; -static uint32_t total_send_count = 0; -static uint32_t total_recv_count = 0; -static uint32_t total_lost_count = 0; -static uint32_t test_duration_ms = 0; -static uint32_t test_start_time = 0; +static uint32_t send_count = 0; +static uint32_t recv_count = 0; +static uint32_t lost_count = 0; +static uint8_t expected_data[TEST_DATA_SIZE]; +static uint8_t received_data[TEST_DATA_SIZE]; // 测试状态 typedef enum { @@ -79,151 +52,151 @@ typedef enum { static test_state_t test_state = TEST_STATE_IDLE; // 函数声明 -static void websocket_test_thread(void *argument); -static bool init_websocket_test(const char *server_addr, uint16_t port, uint32_t thread_count, uint32_t duration_ms); +static void websocket_send_thread(void *argument); +static void websocket_recv_thread(void *argument); +static bool init_websocket_test(const char *server_addr, uint16_t port); static void cleanup_websocket_test(void); -static bool send_test_data(test_thread_info_t *thread_info, uint8_t data_value); -static bool receive_test_data(test_thread_info_t *thread_info, uint8_t *data_value); +static bool send_test_data(uint8_t data_value); +static bool receive_test_data(uint8_t *data_value); static void print_test_results(void); static void check_memory_status(void); -static void test_timer_callback(void *argument); -static void cleanup_thread_resources(test_thread_info_t *thread_info); - -static void ws_on_rx(WebSocketClient *client, const uint8_t *data, int len, WebSocketMessageType type, void *user) -{ - if (g_ws_rx_queue == NULL || data == NULL || len <= 0 || user == NULL) { - return; - } - - test_thread_info_t *thread_info = (test_thread_info_t *)user; - ws_msg_t msg; - msg.type = type; - msg.len = (len > TEST_DATA_SIZE) ? TEST_DATA_SIZE : len; - msg.thread_id = thread_info->thread_index; - memcpy(msg.data, data, (size_t)msg.len); - - // 快速入队,避免阻塞IO线程 - osStatus_t result = osMessageQueuePut(g_ws_rx_queue, &msg, 0, 0); - if (result != osOK) { - WEARABLE_LOGW(WEARABLE_LOG_MODULE_APP, "接收队列满,丢弃消息"); - } -} /** - * WebSocket测试线程(每个线程独立处理一个连接) + * WebSocket发送线程 */ -static void websocket_test_thread(void *argument) +static void websocket_send_thread(void *argument) { - test_thread_info_t *thread_info = (test_thread_info_t *)argument; - if (!thread_info) { - return; - } - uint8_t data_value = 0; uint32_t send_interval = 100; // 100ms间隔 uint32_t error_count = 0; - uint32_t thread_id = thread_info->thread_index; - WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocket测试线程[%u]启动", thread_id); + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocket发送线程启动"); - while (test_running && thread_info->active) { + while (test_running) { // 检查客户端是否有效 - if (!thread_info->client || thread_info->client->sockfd < 0) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "线程[%u]: 客户端无效", thread_id); + if (!test_client || test_client->sockfd < 0) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "发送线程: 客户端无效"); break; } - // 发送测试数据 - if (send_test_data(thread_info, data_value)) { - thread_info->send_count++; - total_send_count++; - WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "线程[%u]: 发送数据包 %u, 值: %u", - thread_id, thread_info->send_count, data_value); + if (send_test_data(data_value)) { + send_count++; + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "发送数据包 %u, 值: %u", send_count, data_value); data_value = (data_value + 1) % 256; // 0-255循环 error_count = 0; // 重置错误计数 } else { error_count++; - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "线程[%u]: 发送测试数据失败, 错误计数: %u", - thread_id, error_count); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "发送测试数据失败, 错误计数: %u", error_count); // 如果连续失败超过5次,退出循环 if (error_count > 5) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "线程[%u]: 连续失败次数过多,退出", thread_id); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "发送线程: 连续失败次数过多,退出"); break; } } - // 接收测试数据 - uint8_t received_value; - if (receive_test_data(thread_info, &received_value)) { - thread_info->recv_count++; - total_recv_count++; - WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "线程[%u]: 接收数据包 %u, 值: %u", - thread_id, thread_info->recv_count, received_value); + // 检查是否需要停止 + if (!test_running) { + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "发送线程: 收到停止信号"); + break; + } + + osDelay(send_interval); + } + + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocket发送线程结束"); + return; +} + +/** + * WebSocket接收线程 + */ +static void websocket_recv_thread(void *argument) +{ + uint8_t data_value = 0; + uint32_t timeout_count = 0; + uint32_t error_count = 0; + + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocket接收线程启动"); + + while (test_running) { + // 检查客户端是否有效 + if (!test_client || test_client->sockfd < 0) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "接收线程: 客户端无效"); + break; + } + + if (receive_test_data(&data_value)) { + recv_count++; + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "接收数据包 %u, 值: %u", recv_count, data_value); // 检查数据是否正确 bool data_correct = true; for (int i = 0; i < TEST_DATA_SIZE; i++) { - if (thread_info->received_data[i] != received_value) { + if (received_data[i] != data_value) { data_correct = false; break; } } if (!data_correct) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "线程[%u]: 接收数据验证失败", thread_id); - thread_info->lost_count++; - total_lost_count++; + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "接收数据验证失败"); + lost_count++; + } + + timeout_count = 0; + error_count = 0; // 重置错误计数 + } else { + timeout_count++; + error_count++; + if (timeout_count > 10) { // 1秒超时 + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "接收数据超时"); + break; + } + + // 如果连续错误超过20次,退出循环 + if (error_count > 20) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "接收线程: 连续错误次数过多,退出"); + break; } } // 检查是否需要停止 - if (!test_running || !thread_info->active) { - WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "线程[%u]: 收到停止信号", thread_id); + if (!test_running) { + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "接收线程: 收到停止信号"); break; } - osDelay(send_interval); + osDelay(100); } - WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocket测试线程[%u]结束", thread_id); + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocket接收线程结束"); return; } /** * 初始化WebSocket测试 */ -static bool init_websocket_test(const char *server_addr, uint16_t port, uint32_t thread_count, uint32_t duration_ms) +static bool init_websocket_test(const char *server_addr, uint16_t port) { - if (thread_count > MAX_CONCURRENT_THREADS) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "线程数超过最大限制: %u > %u", thread_count, MAX_CONCURRENT_THREADS); - return false; - } + char url[256]; + snprintf(url, sizeof(url), "ws://%s:%d/", server_addr, port); + + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "连接WebSocket服务器: %s", url); - if (thread_count > MAX_CONCURRENT_CONNECTIONS) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "连接数超过最大限制: %u > %u", thread_count, MAX_CONCURRENT_CONNECTIONS); + // 创建WebSocket客户端 + test_client = init_websocket_client(url, NULL, 1); // 启用DNS解析 + if (test_client == NULL) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "WebSocket客户端创建失败"); return false; } - WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "初始化WebSocket测试: %s:%u, 线程数: %u, 持续时间: %u ms", - server_addr, port, thread_count, duration_ms); - - // 初始化单线程IO调度 - ws_io_init(); - - // 创建接收消息队列(供回调快速入队,接收线程取出处理) - if (g_ws_rx_queue == NULL) { - g_ws_rx_queue = osMessageQueueNew(thread_count * 32, sizeof(ws_msg_t), NULL); - if (g_ws_rx_queue == NULL) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "创建接收队列失败"); - return false; - } - } - // 创建互斥锁 test_mutex = osMutexNew(NULL); if (test_mutex == NULL) { WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "互斥锁创建失败"); + lwip_close_websocket_client(test_client); + test_client = NULL; return false; } @@ -232,85 +205,42 @@ static bool init_websocket_test(const char *server_addr, uint16_t port, uint32_t if (test_semaphore == NULL) { WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "信号量创建失败"); osMutexDelete(test_mutex); + lwip_close_websocket_client(test_client); + test_client = NULL; return false; } - // 初始化测试线程信息 - memset(test_threads, 0, sizeof(test_threads)); - active_thread_count = thread_count; - - // 为每个线程创建WebSocket连接 - for (uint32_t i = 0; i < thread_count; i++) { - test_thread_info_t *thread_info = &test_threads[i]; - thread_info->thread_index = i; - thread_info->active = false; - thread_info->send_count = 0; - thread_info->recv_count = 0; - thread_info->lost_count = 0; - - // 创建线程互斥锁 - thread_info->thread_mutex = osMutexNew(NULL); - if (thread_info->thread_mutex == NULL) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "线程[%u]互斥锁创建失败", i); - cleanup_websocket_test(); - return false; - } - - // 创建WebSocket客户端(在IO线程中,并注册回调) - char url[256]; - snprintf(url, sizeof(url), "ws://%s:%u/", server_addr, port); - - WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "线程[%u]: 连接WebSocket服务器: %s", i, url); - - thread_info->client = ws_io_open_ex(url, NULL, ws_on_rx, thread_info); - if (thread_info->client == NULL) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "线程[%u]: WebSocket客户端创建失败", i); - cleanup_websocket_test(); - return false; - } - - // 创建测试线程 - osThreadAttr_t thread_attr = { - .name = "websocket_test", - .stack_size = THREAD_STACK_SIZE, - .priority = osPriorityNormal, - }; - - char thread_name[32]; - snprintf(thread_name, sizeof(thread_name), "ws_test_%u", i); - thread_attr.name = thread_name; - - thread_info->thread_id = osThreadNew(websocket_test_thread, thread_info, &thread_attr); - if (thread_info->thread_id == NULL) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "线程[%u]: 测试线程创建失败", i); - cleanup_websocket_test(); - return false; - } - - thread_info->active = true; - WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "线程[%u]: 初始化完成", i); - } - - // 设置运行标志 + // 设置运行标志(在创建线程之前) test_running = true; test_state = TEST_STATE_RUNNING; - test_duration_ms = duration_ms; - test_start_time = osKernelGetTickCount(); - // 如果指定了持续时间,创建定时器 - if (duration_ms > 0) { - test_timer = osTimerNew(test_timer_callback, osTimerOnce, NULL, NULL); - if (test_timer == NULL) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "测试定时器创建失败"); - cleanup_websocket_test(); - return false; - } - - osTimerStart(test_timer, duration_ms); - WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "测试定时器已启动,%u ms后自动停止", duration_ms); + // 创建发送线程 + osThreadAttr_t send_attr = { + .name = "websocket_send", + .stack_size = THREAD_STACK_SIZE, + .priority = osPriorityNormal, + }; + send_thread_id = osThreadNew(websocket_send_thread, NULL, &send_attr); + if (send_thread_id == NULL) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "发送线程创建失败"); + cleanup_websocket_test(); + return false; + } + + // 创建接收线程 + osThreadAttr_t recv_attr = { + .name = "websocket_recv", + .stack_size = THREAD_STACK_SIZE, + .priority = osPriorityNormal, + }; + recv_thread_id = osThreadNew(websocket_recv_thread, NULL, &recv_attr); + if (recv_thread_id == NULL) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "接收线程创建失败"); + cleanup_websocket_test(); + return false; } - WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocket测试初始化成功,%u个线程已启动", thread_count); + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocket测试初始化成功"); return true; } @@ -324,35 +254,27 @@ static void cleanup_websocket_test(void) // 首先停止运行标志 test_running = false; - // 停止定时器 - if (test_timer) { - osTimerStop(test_timer); - osTimerDelete(test_timer); - test_timer = NULL; - } - // 等待一段时间让线程自然结束 - osDelay(200); - - // 安全地等待所有线程结束 - for (uint32_t i = 0; i < active_thread_count; i++) { - test_thread_info_t *thread_info = &test_threads[i]; - if (thread_info->thread_id && thread_info->active) { - WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "等待线程[%u]结束", i); - osThreadJoin(thread_info->thread_id); - thread_info->thread_id = NULL; - } + osDelay(100); + + // 安全地等待线程结束 + if (send_thread_id) { + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "等待发送线程结束"); + osThreadJoin(send_thread_id); + send_thread_id = NULL; } - // 清理线程资源 - for (uint32_t i = 0; i < active_thread_count; i++) { - cleanup_thread_resources(&test_threads[i]); + if (recv_thread_id) { + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "等待接收线程结束"); + osThreadJoin(recv_thread_id); + recv_thread_id = NULL; } - // 关闭接收队列 - if (g_ws_rx_queue) { - osMessageQueueDelete(g_ws_rx_queue); - g_ws_rx_queue = NULL; + // 关闭WebSocket连接 - 在删除线程相关资源之前 + if (test_client) { + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "关闭WebSocket连接"); + lwip_close_websocket_client(test_client); + test_client = NULL; } // 删除信号量 @@ -361,132 +283,103 @@ static void cleanup_websocket_test(void) test_semaphore = NULL; } - // 删除互斥锁 + // 删除互斥锁 - 最后删除 if (test_mutex) { osMutexDelete(test_mutex); test_mutex = NULL; } - active_thread_count = 0; test_state = TEST_STATE_IDLE; WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocket测试清理完成"); } -/** - * 清理单个线程的资源 - */ -static void cleanup_thread_resources(test_thread_info_t *thread_info) -{ - if (!thread_info) { - return; - } - - // 关闭WebSocket连接 - if (thread_info->client) { - WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "线程[%u]: 关闭WebSocket连接", thread_info->thread_index); - ws_io_close(thread_info->client); - thread_info->client = NULL; - } - - // 删除线程互斥锁 - if (thread_info->thread_mutex) { - osMutexDelete(thread_info->thread_mutex); - thread_info->thread_mutex = NULL; - } - - // 重置线程信息 - thread_info->active = false; - thread_info->send_count = 0; - thread_info->recv_count = 0; - thread_info->lost_count = 0; -} - /** * 发送测试数据 */ -static bool send_test_data(test_thread_info_t *thread_info, uint8_t data_value) +static bool send_test_data(uint8_t data_value) { - if (!thread_info || !thread_info->client || !test_running || !thread_info->active) { + if (!test_client || !test_running) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "发送数据失败: 客户端或运行状态无效"); return false; } // 添加额外的安全检查 - if (thread_info->client->sockfd < 0) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "线程[%u]: 发送数据失败: 无效的socket", thread_info->thread_index); + if (test_client->sockfd < 0) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "发送数据失败: 无效的socket"); return false; } + // 验证测试数据缓冲区 - 数组地址总是为true,不需要检查 + // if (!expected_data) { + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "发送数据失败: 测试数据缓冲区无效"); + // return false; + // } + // 准备测试数据 - memset(thread_info->expected_data, data_value, TEST_DATA_SIZE); + memset(expected_data, data_value, TEST_DATA_SIZE); + + // 添加内存检查 + if (TEST_DATA_SIZE > 65536) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "发送数据失败: 数据大小过大"); + return false; + } + + // 检查内存状态 + check_memory_status(); // 发送数据前增加延迟,避免过于频繁的发送 osDelay(5); - // 发送数据 - 通过IO线程,确保线程安全 - int result = ws_io_send(thread_info->client, thread_info->expected_data, TEST_DATA_SIZE, WS_BINARY); + // 发送数据 + int result = send_websocket_message(test_client, expected_data, TEST_DATA_SIZE, WS_BINARY); if (result != 0) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "线程[%u]: 发送数据失败: %d", thread_info->thread_index, result); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "发送数据失败: %d", result); return false; } + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "发送数据成功: 值=%u, 大小=%d", data_value, TEST_DATA_SIZE); return true; } /** * 接收测试数据 */ -static bool receive_test_data(test_thread_info_t *thread_info, uint8_t *data_value) +static bool receive_test_data(uint8_t *data_value) { - if (!thread_info || !test_running || !thread_info->active || !data_value) { + if (!test_client || !test_running) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "接收数据失败: 客户端或运行状态无效"); return false; } - if (g_ws_rx_queue == NULL) { - return false; - } - - ws_msg_t msg; - uint8_t prio = 0; - osStatus_t st = osMessageQueueGet(g_ws_rx_queue, &msg, &prio, 50); // 减少超时时间,提高响应性 - if (st != osOK) { - return false; // 超时或无数据 - } + WebSocketMessageType type; + int result = receive_websocket_message(test_client, received_data, TEST_DATA_SIZE, &type); - // 检查消息是否属于当前线程 - if (msg.thread_id != thread_info->thread_index) { - // 重新放回队列,让正确的线程处理 - osMessageQueuePut(g_ws_rx_queue, &msg, 0, 0); + if (result <= 0) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "接收数据失败: result=%d", result); return false; } - if (msg.type != WS_BINARY) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "线程[%u]: 接收数据类型错误: type=%d", - thread_info->thread_index, msg.type); + if (type != WS_BINARY) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "接收数据类型错误: type=%d", type); return false; } - if (msg.len != TEST_DATA_SIZE) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "线程[%u]: 接收数据大小错误: %d", - thread_info->thread_index, msg.len); + // 检查数据大小 + if (result != TEST_DATA_SIZE) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "接收数据大小错误: %d", result); return false; } - memcpy(thread_info->received_data, msg.data, TEST_DATA_SIZE); - *data_value = thread_info->received_data[0]; + // 提取数据值 + *data_value = received_data[0]; + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "接收数据成功: 值=%u, 大小=%d", *data_value, result); return true; } /** - * 测试定时器回调 + * 打印测试结果 */ -static void test_timer_callback(void *argument) -{ - (void)argument; - WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "测试定时器触发,自动停止测试"); - stop_websocket_test(); -} - /** * 检查内存状态 */ @@ -495,8 +388,22 @@ static void check_memory_status(void) // 检查内存状态 WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocket: 检查内存状态"); + // 检查内存池状态 - 暂时注释掉,避免编译错误 + // extern void ws_mem_pool_status(void); + // ws_mem_pool_status(); + + // 检查系统内存状态 - 暂时注释掉,避免编译错误 + // extern size_t xPortGetFreeHeapSize(void); + // size_t free_heap = xPortGetFreeHeapSize(); + // WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocket: 系统空闲堆内存: %u 字节", (uint32_t)free_heap); + // 如果内存不足,增加延迟 - osDelay(10); + // if (free_heap < 1024) { + // WEARABLE_LOGW(WEARABLE_LOG_MODULE_APP, "WebSocket: 系统内存不足,增加延迟"); + // osDelay(50); + // } else { + osDelay(10); + // } } /** @@ -504,34 +411,17 @@ static void check_memory_status(void) */ static void print_test_results(void) { - WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "=== WebSocket多线程测试结果 ==="); - WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "活跃线程数: %u", active_thread_count); - WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "总发送数据包数: %u", total_send_count); - WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "总接收数据包数: %u", total_recv_count); - WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "总丢失数据包数: %u", total_lost_count); - - // 打印每个线程的统计信息 - for (uint32_t i = 0; i < active_thread_count; i++) { - test_thread_info_t *thread_info = &test_threads[i]; - if (thread_info->active) { - WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "线程[%u]: 发送=%u, 接收=%u, 丢失=%u", - i, thread_info->send_count, thread_info->recv_count, thread_info->lost_count); - } - } - - if (total_send_count > 0) { - float loss_rate = (float)total_lost_count / total_send_count * 100.0f; - WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "总丢包率: %.2f%%", loss_rate); - } + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "=== WebSocket测试结果 ==="); + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "发送数据包数: %u", send_count); + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "接收数据包数: %u", recv_count); + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "丢失数据包数: %u", lost_count); - // 计算测试持续时间 - if (test_start_time > 0) { - uint32_t test_end_time = osKernelGetTickCount(); - uint32_t actual_duration = test_end_time - test_start_time; - WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "实际测试持续时间: %u ms", actual_duration); + if (send_count > 0) { + float loss_rate = (float)lost_count / send_count * 100.0f; + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "丢包率: %.2f%%", loss_rate); } - WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "================================"); + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "========================"); } /** @@ -543,67 +433,66 @@ int at_test_websocket_handler(const char *cmd, const char *params) return -1; } - // 解析参数: AT^TESTWEBSOCKET=,,[,] + // 解析参数: AT^TESTWEBSOCKET=, char server_addr[64] = {0}; - uint16_t port = 0; - uint32_t thread_count = 1; - uint32_t duration_ms = 0; + uint16_t port1 = 0, port2 = 0; - int parsed = sscanf(params, "%63[^,],%hu,%u,%u", server_addr, &port, &thread_count, &duration_ms); - if (parsed < 3) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "参数格式错误,正确格式: AT^TESTWEBSOCKET=,,[,]"); + if (sscanf(params, "%63[^,],%hu", server_addr, &port1) != 2) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "参数格式错误,正确格式: AT^TESTWEBSOCKET=,"); return -1; } - // 设置默认值 - if (thread_count == 0) thread_count = 1; - if (thread_count > MAX_CONCURRENT_THREADS) { - thread_count = MAX_CONCURRENT_THREADS; - WEARABLE_LOGW(WEARABLE_LOG_MODULE_APP, "线程数超过最大限制,调整为: %u", thread_count); - } - - WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "开始WebSocket多线程测试"); + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "开始WebSocket测试"); WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "服务器地址: %s", server_addr); - WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "端口: %u", port); - WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "线程数: %u", thread_count); - if (duration_ms > 0) { - WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "测试持续时间: %u ms", duration_ms); - } + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "端口1: %u", port1); // 检查当前状态 WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "当前测试状态: %d", test_state); if (test_state != TEST_STATE_IDLE) { WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "测试正在进行中,强制清理并重新开始"); - cleanup_websocket_test(); - total_send_count = 0; - total_recv_count = 0; - total_lost_count = 0; + // 强制清理 + test_running = false; + if (test_client) { + lwip_close_websocket_client(test_client); + test_client = NULL; + } + test_state = TEST_STATE_IDLE; + send_count = 0; + recv_count = 0; + lost_count = 0; } // 初始化测试 - if (!init_websocket_test(server_addr, port, thread_count, duration_ms)) { + if (!init_websocket_test(server_addr, port1)) { WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "WebSocket测试初始化失败"); return -1; } - WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocket多线程测试已启动,使用AT^STOPWEBSOCKET停止测试"); + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocket测试已启动,使用AT^STOPWEBSOCKET停止测试"); return 0; } /** * 手动启动WebSocket测试 */ -int start_websocket_test(const char *server_addr, uint16_t port, uint32_t thread_count, uint32_t duration_ms) +int start_websocket_test(const char *server_addr, uint16_t port, uint32_t duration_ms) { if (test_state != TEST_STATE_IDLE) { WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "测试正在进行中"); return -1; } - if (!init_websocket_test(server_addr, port, thread_count, duration_ms)) { + if (!init_websocket_test(server_addr, port)) { return -1; } + // 如果指定了持续时间,则运行指定时间后自动停止 + if (duration_ms > 0) { + osDelay(duration_ms); + cleanup_websocket_test(); + print_test_results(); + } + return 0; } @@ -634,27 +523,9 @@ int get_websocket_test_state(void) */ void get_websocket_test_stats(uint32_t *send_count_out, uint32_t *recv_count_out, uint32_t *lost_count_out) { - if (send_count_out) *send_count_out = total_send_count; - if (recv_count_out) *recv_count_out = total_recv_count; - if (lost_count_out) *lost_count_out = total_lost_count; -} - -/** - * 获取线程统计信息 - */ -void get_websocket_thread_stats(uint32_t thread_index, uint32_t *send_count_out, uint32_t *recv_count_out, uint32_t *lost_count_out) -{ - if (thread_index >= active_thread_count) { - if (send_count_out) *send_count_out = 0; - if (recv_count_out) *recv_count_out = 0; - if (lost_count_out) *lost_count_out = 0; - return; - } - - test_thread_info_t *thread_info = &test_threads[thread_index]; - if (send_count_out) *send_count_out = thread_info->send_count; - if (recv_count_out) *recv_count_out = thread_info->recv_count; - if (lost_count_out) *lost_count_out = thread_info->lost_count; + if (send_count_out) *send_count_out = send_count; + if (recv_count_out) *recv_count_out = recv_count; + if (lost_count_out) *lost_count_out = lost_count; } /** @@ -662,7 +533,7 @@ void get_websocket_thread_stats(uint32_t thread_index, uint32_t *send_count_out, */ void websocket_test_init(void) { - WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocket多线程测试模块初始化"); + WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocket测试模块初始化"); // 注册AT命令处理器 // 注意:这里需要根据实际的AT命令系统进行适配 diff --git a/code/sdk/drivers/peripheral/slip/websocket_test.h b/code/sdk/drivers/peripheral/slip/websocket_test.h index 20a89cf57..34eaff894 100644 --- a/code/sdk/drivers/peripheral/slip/websocket_test.h +++ b/code/sdk/drivers/peripheral/slip/websocket_test.h @@ -33,7 +33,7 @@ int at_test_websocket_handler(const char *cmd, const char *params); * @param duration_ms 测试持续时间(毫秒) * @return 0表示成功,-1表示失败 */ -int start_websocket_test(const char *server_addr, uint16_t port, uint32_t duration_ms); +int start_websocket_test(const char *server_addr, uint16_t port, uint32_t thread_count, uint32_t duration_ms); /** * 停止WebSocket测试