}
printf("send_handshake request:\r\n%s",request);
- //移植建议: 此处调用 tcp_send_data 进行发送, 不必使用 lwip_send,如果新能不行,就改用 tcp_send_data_directly
-
-
- ret = tcp_send_and_wait_response(client->tcp_handle,(uint8_t *)request, strlen(request),(uint8_t *)response, response_len,1000);
- if(ret<0)
- {
- printf("tcp_send_data_directly failed: %d", ret);
+
+ // 发送WebSocket握手请求并等待响应
+ printf("发送WebSocket握手请求...\r\n");
+ ret = tcp_send_and_wait_response(client->tcp_handle, (uint8_t *)request, strlen(request), (uint8_t *)response, response_len, 1000);
+
+ if (ret < 0) {
+ printf("WebSocket握手发送失败: %d\r\n", ret);
ret = -1;
- }
- else
- {
- if(ret<0)
- {
- printf("tcp_recv_data_directly failed");
+ } else {
+ printf("WebSocket握手发送成功,接收到 %d 字节响应\r\n", ret);
+
+ // 检查响应内容
+ if (ret > 0 && response[0] != '\0') {
+ printf("WebSocket握手响应:\r\n%s\r\n", response);
+
+ // 检查是否包含"HTTP/1.1 101"
+ if (strstr(response, "HTTP/1.1 101") != NULL) {
+ printf("WebSocket握手成功!\r\n");
+ client->handshake = 1;
+ } else {
+ printf("WebSocket握手失败:响应不是101状态码\r\n");
+ ret = -1;
+ }
+ } else {
+ printf("WebSocket握手失败:无响应数据\r\n");
ret = -1;
}
- else
- {
- ret = ret;
- printf("tcp_recv_data_directly: %s\r\n", response);
- client->handshake=1;
- }
}
free(request);
- printf("send_handshake3 %d",ret);
+ printf("send_handshake3 返回: %d\r\n", ret);
return ret;
}
// 发送帧
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"offset %d\r\n",offset);
-
- if (tcp_send_data(client->tcp_handle, frame, offset) < 0) {
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"lwip_send message failed\r\n");
+ int ret_tcp_send_data=tcp_send_data(client->tcp_handle, frame, offset);
+ if (ret_tcp_send_data < 0) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"lwip_send message failed %d\r\n",ret_tcp_send_data);
ret = -1;
goto send_websocket_message_ERROR;
}
extern WebSocketClient * get_ws_client_by_handle(void* handle);
WebSocketClient * client = get_ws_client_by_handle(handle);
if (client != NULL) {
-
printf("连接成功,开始WebSocket握手\r\n");
- #if 1
+
+ // 等待连接稳定后再发送握手
+ printf("等待TCP连接稳定...\r\n");
+ msleep(100); // 等待100ms让连接稳定
+
// 发送WebSocket握手请求
char *buffer = (char *)aic_zalloc(BUFFER_SIZE);
if (buffer != NULL) {
- int bytes_received = send_handshake(client, NULL, buffer, BUFFER_SIZE);
- if (bytes_received < 0) {
- printf("WebSocket握手失败\r\n");
- tcp_manager_close(client->tcp_handle);
- } else {
- printf("WebSocket握手发送成功\r\n");
+ int retry_count = 0;
+ const int max_retries = 3;
+
+ while (retry_count < max_retries) {
+ printf("WebSocket握手尝试 #%d...\r\n", retry_count + 1);
+
+ int bytes_received = send_handshake(client, NULL, buffer, BUFFER_SIZE);
+ if (bytes_received < 0) {
+ retry_count++;
+ if (retry_count < max_retries) {
+ printf("WebSocket握手失败,等待重试...\r\n");
+ msleep(500); // 等待500ms后重试
+ continue;
+ } else {
+ printf("WebSocket握手失败,已达到最大重试次数\r\n");
+ tcp_manager_close(client->tcp_handle);
+ }
+ } else {
+ printf("WebSocket握手发送成功\r\n");
+ break;
+ }
}
+
free(buffer);
}
- #else
- client->handshake=1;
- #endif
} else {
printf("未找到对应的WebSocket客户端\r\n");
}
return;
}
- printf("Processed %d bytes of WebSocket data\n", processed);
+ printf("Processed %d bytes %s %s of WebSocket data\n", processed,client->host,client->path);
}
// 初始化 WebSocket 客户端
WebSocketClient *init_websocket_client(const char *url, const char *headers,uint8_t use_dns) {
printf("Query: %s\n", parsed_url.query);
}
client = (WebSocketClient *)aic_zalloc(sizeof(WebSocketClient)) ;
+ memset_s(client,sizeof(WebSocketClient),0,sizeof(WebSocketClient));
if(!client)
{
printf("init_websocket_client alloc error");
int ws_process_received_data(WebSocketClient *client, const uint8_t *data, size_t len)
{
if (!client || !data || len == 0 || !client->parser) {
+ printf("ws_process_received_data: invalid parameters - client=%p, data=%p, len=%zu, parser=%p\n",
+ client, data, len, client->parser);
return -1;
}
ws_parser_t* parser = client->parser;
int processed = 0;
+ printf("ws_process_received_data: processing %zu bytes for client %s:%s\n",
+ len, client->host, client->path);
+
+ // 在解析前打印当前解析器状态
+ printf("ws_process_received_data: parser state before parsing:\n");
+ // ws_parser_debug_state(parser);
+
// 使用新的解析器处理数据
int result = ws_parse_stream(parser, data, len);
+ // 在解析后打印解析器状态
+ printf("ws_process_received_data: parser state after parsing:\n");
+ // ws_parser_debug_state(parser);
+
if (result > 0) {
// 解析完成一个完整的WebSocket帧
const ws_header_t* header = ws_get_header(parser);
- const uint8_t* payload = ws_get_packet(parser);
+ const uint8_t* payload = ws_get_payload(parser); // 使用新函数获取纯载荷数据
+ size_t payload_len = ws_get_payload_length(parser); // 获取载荷长度
+
+ printf("ws_process_received_data: frame complete, total bytes: %d, payload bytes: %zu\n",
+ result, payload_len);
- if (header && payload) {
+ if (header && payload && payload_len > 0) {
printf("WebSocket frame received: opcode=0x%02X, fin=%d, payload_len=%llu\n",
header->opcode, header->fin, header->payload_len);
+ // 打印载荷数据的前几个字节(用于调试)
+ printf("Payload data (first 32 bytes): ");
+ for (size_t i = 0; i < payload_len && i < 32; i++) {
+ printf("%02X ", payload[i]);
+ }
+ if (payload_len > 32) printf("...");
+ printf("\n");
+
// 根据操作码处理不同类型的消息
switch (header->opcode) {
case WS_PING:
printf("Received WebSocket CLOSE\n");
// 调用回调函数处理关闭帧
if (client->packet_callback) {
- client->packet_callback((uint8_t*)payload, header->payload_len, (WebSocketMessageType)WS_CLOSE);
+ client->packet_callback((uint8_t*)payload, payload_len, (WebSocketMessageType)WS_CLOSE);
}
break;
if (client->packet_callback) {
WebSocketMessageType ws_type = (header->opcode == WS_TEXT) ? (WebSocketMessageType)WS_TEXT :
(header->opcode == WS_BINARY) ? (WebSocketMessageType)WS_BINARY : (WebSocketMessageType)WS_CONT;
- client->packet_callback((uint8_t*)payload, header->payload_len, ws_type);
+ client->packet_callback((uint8_t*)payload, payload_len, ws_type);
}
break;
printf("Unknown WebSocket opcode: 0x%02X\n", header->opcode);
break;
}
+
+ // 重要:在数据处理完成后再重置解析器状态
+ // 这样可以确保数据被正确处理后再清理状态
+ printf("ws_process_received_data: data processing complete, resetting parser\n");
+ ws_parser_reset(parser);
+ } else {
+ printf("ws_process_received_data: invalid payload data - header=%p, payload=%p, payload_len=%zu\n",
+ header, payload, payload_len);
+ processed = -1;
}
processed = result;
} else if (result == 0) {
// 数据不完整,继续等待
+ printf("ws_process_received_data: frame incomplete, waiting for more data\n");
processed = len;
} else {
// 解析错误
- printf("WebSocket parsing error\n");
- ws_parser_reset(parser);
+ printf("ws_process_received_data: parsing error, result=%d\n", result);
processed = -1;
}
// 继续执行,处理第一个字节
// 注意:这里故意不break,让代码继续执行
- case WS_STATE_READ_HEADER1:
+ case WS_STATE_READ_HEADER1:{
// 解析第一个头部字节
parser->header.fin = (byte >> 7) & 0x1;
parser->header.rsv1 = (byte >> 6) & 0x1;
parser->state = WS_STATE_READ_HEADER2;
break;
+ }
case WS_STATE_READ_HEADER2: {
// 解析第二个头部字节
parser->header.mask = (byte >> 7) & 0x1;
uint8_t payload_len = byte & 0x7F;
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WS: Parse header2 - MASK:%d, LEN:%d",
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WS: Parse header2 - MASK:%d, LEN:%d",
parser->header.mask, payload_len);
// 保存第二个头部字节到缓存
return -1;
}
- // 累加长度数据
+ // 累加长度数据 - 修复:使用正确的索引计算
static uint8_t len_bytes[8];
- size_t len_pos = 8 - parser->payload_remaining;
+
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WS: Reading payload length byte: 0x%02X, remaining: %zu",
+ byte, parser->payload_remaining);
+
if (parser->header.payload_len == 126) {
- len_bytes[len_pos] = byte;
+ // 16位扩展长度:只需要2个字节
+ // 第一个字节存储在len_bytes[0],第二个字节存储在len_bytes[1]
+ if (parser->payload_remaining == 2) {
+ len_bytes[0] = byte; // 高字节
+ } else if (parser->payload_remaining == 1) {
+ len_bytes[1] = byte; // 低字节
+ }
+
parser->payload_remaining--;
if (parser->payload_remaining == 0) {
- // 计算16位长度
+ // 计算16位长度 - 修复:使用正确的字节顺序
+ // 注意:网络字节序是大端序,第一个字节是高字节
parser->header.payload_len = (len_bytes[0] << 8) | len_bytes[1];
parser->payload_remaining = parser->header.payload_len;
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WS: 16-bit payload length: %d bytes", parser->header.payload_len);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WS: 16-bit payload length: %d bytes (0x%02X%02X)",
+ parser->header.payload_len, len_bytes[0], len_bytes[1]);
// 验证控制帧长度
if (!validate_control_frame_length(parser->header.opcode, parser->header.payload_len)) {
}
// 检查缓存是否足够
- if (parser->buffer_pos + parser->payload_remaining > WS_BUFFER_SIZE) {
+ if (parser->buffer_pos + parser->header.payload_len > WS_BUFFER_SIZE) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "WS: Buffer overflow: current=%zu, adding=%d, max=%d",
+ parser->buffer_pos, parser->header.payload_len, WS_BUFFER_SIZE);
parser->state = WS_STATE_ERROR;
return -1;
}
// 处理掩码
if (parser->header.mask) {
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WS: Moving to READ_MASK state");
parser->state = WS_STATE_READ_MASK;
} else {
if (parser->payload_remaining == 0) {
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WS: Zero payload, moving to COMPLETE state");
parser->state = WS_STATE_COMPLETE;
return 1;
}
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WS: Moving to READ_PAYLOAD state");
parser->state = WS_STATE_READ_PAYLOAD;
}
}
} else if (parser->header.payload_len == 127) {
- len_bytes[len_pos] = byte;
+ // 64位扩展长度:需要8个字节
+ // 使用正确的索引:从0开始,按顺序存储
+ size_t byte_index = 8 - parser->payload_remaining;
+ len_bytes[byte_index] = byte;
+
parser->payload_remaining--;
if (parser->payload_remaining == 0) {
// 检查负载长度是否合理
if (parser->header.payload_len > g_max_payload_len) {
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "WS: 64-bit payload length %llu exceeds maximum %llu",
- (unsigned long long)parser->header.payload_len, (unsigned long long)g_max_payload_len);
+ parser->header.payload_len, (unsigned long long)g_max_payload_len);
parser->state = WS_STATE_ERROR;
return -1;
}
// 检查缓存是否足够
- if (parser->buffer_pos + parser->payload_remaining > WS_BUFFER_SIZE) {
+ if (parser->buffer_pos + parser->header.payload_len > WS_BUFFER_SIZE) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "WS: Buffer overflow: current=%zu, adding=%llu, max=%d",
+ parser->buffer_pos, parser->header.payload_len, WS_BUFFER_SIZE);
parser->state = WS_STATE_ERROR;
return -1;
}
// 处理掩码
if (parser->header.mask) {
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WS: Moving to READ_MASK state");
parser->state = WS_STATE_READ_MASK;
} else {
if (parser->payload_remaining == 0) {
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WS: Zero payload, moving to COMPLETE state");
parser->state = WS_STATE_COMPLETE;
return 1;
}
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WS: Moving to READ_PAYLOAD state");
parser->state = WS_STATE_READ_PAYLOAD;
}
}
break;
case WS_STATE_READ_PAYLOAD: {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WS: Reading payload byte, remaining: %zu, buffer_pos: %zu",
+ parser->payload_remaining, parser->buffer_pos);
+
// 保存负载字节到缓存
if (parser->buffer_pos < WS_BUFFER_SIZE) {
parser->buffer[parser->buffer_pos++] = byte;
} else {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "WS: Buffer overflow in payload reading");
parser->state = WS_STATE_ERROR;
return -1;
}
parser->payload_remaining--;
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "WS: After reading byte, remaining: %zu, buffer_pos: %zu",
+ parser->payload_remaining, parser->buffer_pos);
+
// 所有负载都已读取
if (parser->payload_remaining == 0) {
WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WS: Payload read complete (%llu bytes)",
if (parser->header.mask) {
WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WS: Applying mask to payload data");
size_t payload_start = parser->buffer_pos - parser->header.payload_len;
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WS: Payload start: %zu, payload length: %llu",
+ payload_start, parser->header.payload_len);
apply_mask(parser->buffer + payload_start,
parser->header.payload_len,
parser->header.mask_key,
0);
}
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WS: Frame parsing complete");
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WS: Frame parsing complete, transitioning to COMPLETE state");
parser->state = WS_STATE_COMPLETE;
return 1;
}
return -1;
}
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WS: Parsing stream data (%zu bytes)", len);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WS: Parsing stream data (%zu bytes), current state: %d, buffer_pos: %zu",
+ len, parser->state, parser->buffer_pos);
+
+ // 重要:如果解析器状态为COMPLETE,说明上一个帧已经完成
+ // 新数据应该开始解析新的帧,需要重置解析器状态
+ if (parser->state == WS_STATE_COMPLETE) {
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WS: Parser was in COMPLETE state, resetting for new frame");
+ ws_parser_reset(parser);
+ }
for (size_t i = 0; i < len; i++) {
int result = ws_parse_byte(parser, data[i]);
if (result == 1) {
// 解析完成一个包
int packet_len = parser->buffer_pos;
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WS: Complete frame parsed (%d bytes total)", packet_len);
- ws_parser_reset(parser);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WS: Complete frame parsed (%d bytes total) opcode: %d, payload_len: %llu",
+ packet_len, parser->header.opcode, parser->header.payload_len);
+
+ // 重要:不要在这里重置解析器!
+ // 让上层处理完数据后再调用 ws_parser_reset()
+ // 这样可以确保数据被正确处理后再清理状态
return packet_len;
} else if (result == -1) {
// 解析错误,重置解析器
}
}
- // 未完成解析
- WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WS: Frame parsing incomplete, waiting for more data");
+ // 未完成解析,显示当前状态信息
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WS: Frame parsing incomplete, waiting for more data. State: %d, Buffer: %zu/%zu, Payload remaining: %zu",
+ parser->state, parser->buffer_pos, WS_BUFFER_SIZE, parser->payload_remaining);
return 0;
}
+// 新增:打印解析器详细状态信息(用于调试)
+void ws_parser_debug_state(ws_parser_t* parser) {
+ if (!parser) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "WS: Cannot debug NULL parser");
+ return;
+ }
+
+ const char* state_names[] = {
+ "START", "READ_HEADER1", "READ_HEADER2", "READ_PAYLOAD_LEN",
+ "READ_MASK", "READ_PAYLOAD", "COMPLETE", "ERROR"
+ };
+
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WS: Parser Debug State:");
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, " State: %s (%d)",
+ state_names[parser->state], parser->state);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, " Buffer Position: %zu/%d",
+ parser->buffer_pos, WS_BUFFER_SIZE);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, " Payload Remaining: %zu",
+ parser->payload_remaining);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, " Mask Position: %zu",
+ parser->mask_pos);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, " Header Info:");
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, " FIN: %d", parser->header.fin);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, " Opcode: 0x%02X", parser->header.opcode);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, " Mask: %d", parser->header.mask);
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, " Payload Length: %llu",
+ (unsigned long long)parser->header.payload_len);
+
+ if (parser->header.mask) {
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, " Mask Key: %02X %02X %02X %02X",
+ parser->header.mask_key[0], parser->header.mask_key[1],
+ parser->header.mask_key[2], parser->header.mask_key[3]);
+ }
+
+ // 打印缓冲区前几个字节(用于调试)
+ if (parser->buffer_pos > 0) {
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, " Buffer (first 16 bytes):");
+ for (size_t i = 0; i < parser->buffer_pos && i < 16; i++) {
+ printf("%02X ", parser->buffer[i]);
+ }
+ if (parser->buffer_pos > 16) printf("...");
+ printf("\n");
+ }
+}
+
+// 新增:手动重置解析器状态(供上层调用)
+void ws_parser_manual_reset(ws_parser_t* parser) {
+ if (!parser) {
+ WEARABLE_LOGW(WEARABLE_LOG_MODULE_APP, "WS: Attempt to manually reset NULL parser");
+ return;
+ }
+
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WS: Manual parser reset requested");
+ ws_parser_reset(parser);
+}
+
// 释放解析器资源
void ws_parser_destroy(ws_parser_t* parser) {
if (parser) {
return &parser->header;
}
-// 获取解析出的完整数据包
+// 获取解析出的完整数据包(包含帧头,用于调试)
const uint8_t* ws_get_packet(ws_parser_t* parser) {
if (!parser) return NULL;
return parser->buffer;
}
+// 新增:获取纯载荷数据(不包含帧头)
+const uint8_t* ws_get_payload(ws_parser_t* parser) {
+ if (!parser || parser->state != WS_STATE_COMPLETE) return NULL;
+
+ // 计算载荷数据的起始位置
+ size_t payload_start = 0;
+
+ // 基本头部:2字节
+ payload_start += 2;
+
+ // 扩展长度字段
+ uint8_t payload_len_initial = parser->buffer[1] & 0x7F;
+ if (payload_len_initial == 126) {
+ payload_start += 2; // 16位长度
+ } else if (payload_len_initial == 127) {
+ payload_start += 8; // 64位长度
+ }
+
+ // 掩码密钥(如果存在)
+ if (parser->header.mask) {
+ payload_start += 4;
+ }
+
+ // 确保不越界
+ if (payload_start >= parser->buffer_pos) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "WS: Payload start position %zu exceeds buffer size %zu",
+ payload_start, parser->buffer_pos);
+ return NULL;
+ }
+
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "WS: Payload data starts at offset %zu, length %llu",
+ payload_start, parser->header.payload_len);
+
+ return parser->buffer + payload_start;
+}
+
+// 新增:获取载荷数据长度
+size_t ws_get_payload_length(ws_parser_t* parser) {
+ if (!parser || parser->state != WS_STATE_COMPLETE) return 0;
+ return parser->header.payload_len;
+}
+
// 新增:检查解析器是否处于错误状态
int ws_parser_has_error(ws_parser_t* parser) {
if (!parser) return 1;