fix: tcp_json_handle_sock_int RECV 被 listen socket 分支拦截导致收不到鉴权数据
- RECV 处理移到函数最前面,优先于 listen socket 检查 - listen socket 分支增加 socketid!=g_json_socket_client 保护, 防止 listen 与 accepted client 为同一 socket ID 时 RECV 事件被 listen 分支 return 拦截 - WCHNET 某些版本可能将 TCP_LISTEN 和已 accept 的连接 共用同一 socket ID,此时旧代码在 listen 检查处直接 return 导致后续 client RECV 处理永远不被执行
This commit is contained in:
@@ -85,9 +85,6 @@ static uint32_t json_get_msg_id(const char *json) {
|
||||
return (uint32_t)strtoul(g_tmp_value, NULL, 10);
|
||||
}
|
||||
|
||||
static void json_get_cmd(const char *json, char *out, int out_len) {
|
||||
json_get_str_field(json, "\"cmd\"", out, out_len);
|
||||
}
|
||||
|
||||
static char *json_get_data_str(const char *json) {
|
||||
char *data = (char *)malloc(TCP_JSON_MAX_FRAME);
|
||||
@@ -114,6 +111,10 @@ static void json_get_str_field(const char *json, const char *key, char *out, int
|
||||
out[copy_len] = '\0';
|
||||
}
|
||||
|
||||
static void json_get_cmd(const char *json, char *out, int out_len) {
|
||||
json_get_str_field(json, "\"cmd\"", out, out_len);
|
||||
}
|
||||
|
||||
static uint32_t json_get_uint_field(const char *json, const char *key) {
|
||||
reset_tmp();
|
||||
simple_parse_json(json, key, g_tmp_value);
|
||||
@@ -623,67 +624,26 @@ void tcp_json_srv_init(void) {
|
||||
}
|
||||
|
||||
void tcp_json_handle_sock_int(uint8_t socketid, uint8_t intstat) {
|
||||
// === Listen socket events ===
|
||||
if (socketid == g_json_socket_listen) {
|
||||
if (intstat & SINT_STAT_CONNECT) {
|
||||
// A client connected — the accepted socket gets its own CONNECT event
|
||||
// We handle the accept in the "newly accepted" path below
|
||||
PRINT("JSON: Listen socket got CONNECT\n");
|
||||
}
|
||||
if (intstat & SINT_STAT_DISCONNECT) {
|
||||
PRINT("JSON: Listen socket disconnect (unexpected)\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// === Newly accepted client (CONNECT on unknown socket) ===
|
||||
if ((intstat & SINT_STAT_CONNECT) && socketid != g_json_socket_client
|
||||
&& socketid != SocketId_TCP && socketid != SocketId_UDP) {
|
||||
// This is the newly accepted JSON client connection
|
||||
g_json_socket_client = socketid;
|
||||
g_json_auth_state = JSON_STATE_WAIT_AUTH;
|
||||
g_json_pwd_retry = 0;
|
||||
g_json_auth_timer = mstick();
|
||||
g_json_recv_len = 0;
|
||||
memset(g_json_recv_buf, 0, sizeof(g_json_recv_buf));
|
||||
|
||||
// CRITICAL: Set up receive buffer for the accepted TCP socket
|
||||
// Use a SEPARATE buffer for WCHNET — not g_json_recv_buf
|
||||
// WCHNET_SocketRecv copies FROM this buffer, so it must not overlap
|
||||
WCHNET_ModifyRecvBuf(socketid, (uint32_t)g_json_wchnet_buf, RECE_BUF_LEN);
|
||||
|
||||
PRINT("JSON: Client accepted on socket %d, recv buf configured\n", socketid);
|
||||
return;
|
||||
}
|
||||
|
||||
// === Client socket events ===
|
||||
if (socketid == g_json_socket_client) {
|
||||
if (intstat & SINT_STAT_RECV) {
|
||||
// Read data from WCHNET's buffer into our frame accumulator
|
||||
// === RECV: Always process for the client socket (handles listen==client overlap) ===
|
||||
if (socketid == g_json_socket_client && (intstat & SINT_STAT_RECV)) {
|
||||
uint32_t recv_len = WCHNET_SocketRecvLen(socketid, NULL);
|
||||
if (recv_len > 0) {
|
||||
uint16_t space = TCP_JSON_RECV_BUF_LEN - g_json_recv_len;
|
||||
if (recv_len > space) recv_len = space;
|
||||
uint32_t rd_len = recv_len;
|
||||
// Read into a temp buffer first, then append to frame buffer
|
||||
uint8_t tmp_buf[RECE_BUF_LEN];
|
||||
WCHNET_SocketRecv(socketid, tmp_buf, &rd_len);
|
||||
memcpy(g_json_recv_buf + g_json_recv_len, tmp_buf, (uint16_t)rd_len);
|
||||
g_json_recv_len += (uint16_t)rd_len;
|
||||
|
||||
// Process complete frames
|
||||
char frame[TCP_JSON_MAX_FRAME];
|
||||
while (json_extract_frame(g_json_recv_buf, &g_json_recv_len, frame, sizeof(frame))) {
|
||||
PRINT("JSON recv: %s\n", frame);
|
||||
json_process_frame(socketid, frame);
|
||||
|
||||
// Reset auth timer on activity
|
||||
if (g_json_auth_state == JSON_STATE_WAIT_AUTH) {
|
||||
g_json_auth_timer = mstick();
|
||||
}
|
||||
}
|
||||
|
||||
// Buffer overflow protection
|
||||
if (g_json_recv_len >= TCP_JSON_MAX_FRAME) {
|
||||
PRINT("JSON: frame overflow, discarding buffer\n");
|
||||
g_json_recv_len = 0;
|
||||
@@ -692,6 +652,32 @@ void tcp_json_handle_sock_int(uint8_t socketid, uint8_t intstat) {
|
||||
}
|
||||
}
|
||||
|
||||
// === Listen socket events (log only, no action needed) ===
|
||||
if (socketid == g_json_socket_listen && socketid != g_json_socket_client) {
|
||||
if (intstat & SINT_STAT_CONNECT) {
|
||||
PRINT("JSON: Listen socket got CONNECT\n");
|
||||
}
|
||||
if (intstat & SINT_STAT_DISCONNECT) {
|
||||
PRINT("JSON: Listen socket disconnect (unexpected)\n");
|
||||
}
|
||||
}
|
||||
|
||||
// === Newly accepted client (CONNECT on unknown socket) ===
|
||||
if ((intstat & SINT_STAT_CONNECT) && socketid != g_json_socket_client
|
||||
&& socketid != SocketId_TCP && socketid != SocketId_UDP) {
|
||||
g_json_socket_client = socketid;
|
||||
g_json_auth_state = JSON_STATE_WAIT_AUTH;
|
||||
g_json_pwd_retry = 0;
|
||||
g_json_auth_timer = mstick();
|
||||
g_json_recv_len = 0;
|
||||
memset(g_json_recv_buf, 0, sizeof(g_json_recv_buf));
|
||||
WCHNET_ModifyRecvBuf(socketid, (uint32_t)g_json_wchnet_buf, RECE_BUF_LEN);
|
||||
PRINT("JSON: Client accepted on socket %d, recv buf configured\n", socketid);
|
||||
return;
|
||||
}
|
||||
|
||||
// === Client socket events (non-RECV: CONNECT, DISCONNECT, TIMEOUT) ===
|
||||
if (socketid == g_json_socket_client) {
|
||||
if (intstat & SINT_STAT_CONNECT) {
|
||||
PRINT("JSON: Client socket connected (id=%d)\n", socketid);
|
||||
g_json_auth_state = JSON_STATE_WAIT_AUTH;
|
||||
@@ -699,7 +685,6 @@ void tcp_json_handle_sock_int(uint8_t socketid, uint8_t intstat) {
|
||||
g_json_auth_timer = mstick();
|
||||
g_json_recv_len = 0;
|
||||
}
|
||||
|
||||
if (intstat & SINT_STAT_DISCONNECT) {
|
||||
PRINT("JSON: Client disconnected (id=%d)\n", socketid);
|
||||
g_json_socket_client = 0xFF;
|
||||
@@ -707,7 +692,6 @@ void tcp_json_handle_sock_int(uint8_t socketid, uint8_t intstat) {
|
||||
g_json_pwd_retry = 0;
|
||||
g_json_recv_len = 0;
|
||||
}
|
||||
|
||||
if (intstat & SINT_STAT_TIM_OUT) {
|
||||
PRINT("JSON: Client timeout (id=%d)\n", socketid);
|
||||
g_json_socket_client = 0xFF;
|
||||
@@ -718,16 +702,15 @@ void tcp_json_handle_sock_int(uint8_t socketid, uint8_t intstat) {
|
||||
return;
|
||||
}
|
||||
|
||||
// === New socket connecting? (WCHNET assigns TCP PCB after listen accept) ===
|
||||
// === Fallback: connect on a socket we haven't tracked yet ===
|
||||
if (intstat & SINT_STAT_CONNECT && g_json_socket_client == 0xFF && socketid != g_json_socket_listen) {
|
||||
// This might be the newly accepted JSON client connection
|
||||
g_json_socket_client = socketid;
|
||||
g_json_auth_state = JSON_STATE_WAIT_AUTH;
|
||||
g_json_pwd_retry = 0;
|
||||
g_json_auth_timer = mstick();
|
||||
g_json_recv_len = 0;
|
||||
memset(g_json_recv_buf, 0, sizeof(g_json_recv_buf));
|
||||
PRINT("JSON: Client accepted on socket %d\n", socketid);
|
||||
PRINT("JSON: Client accepted on socket %d (fallback)\n", socketid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user