#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 <stdint.h>
#include <asm/delay.h>
-#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 */
}
// 生成随机的 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';
}
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';
}
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"
"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"
"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);
{
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);
}
// 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
* WebSocket测试程序
* 基于LiteOS-M系统
* 通过AT^TESTWEBSOCKET命令执行测试
- * 支持多线程并发测试同一服务器
*/
#ifdef SUPPORT_WEBSOCKET_TEST
// 测试配置
#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 {
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æµ\8bè¯\95线ç¨\8b[%u]ç»\93æ\9d\9f", thread_id);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocketæ\8e¥æ\94¶çº¿ç¨\8bç»\93æ\9d\9f");
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;
}
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;
}
// 首先停止运行标志
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;
}
// 删除信号量
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;
}
/**
- * æµ\8bè¯\95å®\9aæ\97¶å\99¨å\9b\9eè°\83
+ * æ\89\93å\8d°æµ\8bè¯\95ç»\93æ\9e\9c
*/
-static void test_timer_callback(void *argument)
-{
- (void)argument;
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "测试定时器触发,自动停止测试");
- stop_websocket_test();
-}
-
/**
* 检查内存状态
*/
// 检查内存状态
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);
+ // }
}
/**
*/
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, "========================");
}
/**
return -1;
}
- // 解析参数: AT^TESTWEBSOCKET=<server_addr>,<port>,<thread_count>[,<duration_ms>]
+ // 解析参数: AT^TESTWEBSOCKET=<server_addr>,<port1>
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=<server_addr>,<port>,<thread_count>[,<duration_ms>]");
+ if (sscanf(params, "%63[^,],%hu", server_addr, &port1) != 2) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "参数格式错误,正确格式: AT^TESTWEBSOCKET=<server_addr>,<port1>");
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;
}
*/
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;
}
/**
*/
void websocket_test_init(void)
{
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocket多线程测试模块初始化");
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WebSocket测试模块初始化");
// 注册AT命令处理器
// 注意:这里需要根据实际的AT命令系统进行适配