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);
|
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) {
|
static char *json_get_data_str(const char *json) {
|
||||||
char *data = (char *)malloc(TCP_JSON_MAX_FRAME);
|
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';
|
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) {
|
static uint32_t json_get_uint_field(const char *json, const char *key) {
|
||||||
reset_tmp();
|
reset_tmp();
|
||||||
simple_parse_json(json, key, g_tmp_value);
|
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) {
|
void tcp_json_handle_sock_int(uint8_t socketid, uint8_t intstat) {
|
||||||
// === Listen socket events ===
|
// === RECV: Always process for the client socket (handles listen==client overlap) ===
|
||||||
if (socketid == g_json_socket_listen) {
|
if (socketid == g_json_socket_client && (intstat & SINT_STAT_RECV)) {
|
||||||
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
|
|
||||||
uint32_t recv_len = WCHNET_SocketRecvLen(socketid, NULL);
|
uint32_t recv_len = WCHNET_SocketRecvLen(socketid, NULL);
|
||||||
if (recv_len > 0) {
|
if (recv_len > 0) {
|
||||||
uint16_t space = TCP_JSON_RECV_BUF_LEN - g_json_recv_len;
|
uint16_t space = TCP_JSON_RECV_BUF_LEN - g_json_recv_len;
|
||||||
if (recv_len > space) recv_len = space;
|
if (recv_len > space) recv_len = space;
|
||||||
uint32_t rd_len = recv_len;
|
uint32_t rd_len = recv_len;
|
||||||
// Read into a temp buffer first, then append to frame buffer
|
|
||||||
uint8_t tmp_buf[RECE_BUF_LEN];
|
uint8_t tmp_buf[RECE_BUF_LEN];
|
||||||
WCHNET_SocketRecv(socketid, tmp_buf, &rd_len);
|
WCHNET_SocketRecv(socketid, tmp_buf, &rd_len);
|
||||||
memcpy(g_json_recv_buf + g_json_recv_len, tmp_buf, (uint16_t)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;
|
g_json_recv_len += (uint16_t)rd_len;
|
||||||
|
|
||||||
// Process complete frames
|
|
||||||
char frame[TCP_JSON_MAX_FRAME];
|
char frame[TCP_JSON_MAX_FRAME];
|
||||||
while (json_extract_frame(g_json_recv_buf, &g_json_recv_len, frame, sizeof(frame))) {
|
while (json_extract_frame(g_json_recv_buf, &g_json_recv_len, frame, sizeof(frame))) {
|
||||||
PRINT("JSON recv: %s\n", frame);
|
PRINT("JSON recv: %s\n", frame);
|
||||||
json_process_frame(socketid, frame);
|
json_process_frame(socketid, frame);
|
||||||
|
|
||||||
// Reset auth timer on activity
|
|
||||||
if (g_json_auth_state == JSON_STATE_WAIT_AUTH) {
|
if (g_json_auth_state == JSON_STATE_WAIT_AUTH) {
|
||||||
g_json_auth_timer = mstick();
|
g_json_auth_timer = mstick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buffer overflow protection
|
|
||||||
if (g_json_recv_len >= TCP_JSON_MAX_FRAME) {
|
if (g_json_recv_len >= TCP_JSON_MAX_FRAME) {
|
||||||
PRINT("JSON: frame overflow, discarding buffer\n");
|
PRINT("JSON: frame overflow, discarding buffer\n");
|
||||||
g_json_recv_len = 0;
|
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) {
|
if (intstat & SINT_STAT_CONNECT) {
|
||||||
PRINT("JSON: Client socket connected (id=%d)\n", socketid);
|
PRINT("JSON: Client socket connected (id=%d)\n", socketid);
|
||||||
g_json_auth_state = JSON_STATE_WAIT_AUTH;
|
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_auth_timer = mstick();
|
||||||
g_json_recv_len = 0;
|
g_json_recv_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (intstat & SINT_STAT_DISCONNECT) {
|
if (intstat & SINT_STAT_DISCONNECT) {
|
||||||
PRINT("JSON: Client disconnected (id=%d)\n", socketid);
|
PRINT("JSON: Client disconnected (id=%d)\n", socketid);
|
||||||
g_json_socket_client = 0xFF;
|
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_pwd_retry = 0;
|
||||||
g_json_recv_len = 0;
|
g_json_recv_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (intstat & SINT_STAT_TIM_OUT) {
|
if (intstat & SINT_STAT_TIM_OUT) {
|
||||||
PRINT("JSON: Client timeout (id=%d)\n", socketid);
|
PRINT("JSON: Client timeout (id=%d)\n", socketid);
|
||||||
g_json_socket_client = 0xFF;
|
g_json_socket_client = 0xFF;
|
||||||
@@ -718,16 +702,15 @@ void tcp_json_handle_sock_int(uint8_t socketid, uint8_t intstat) {
|
|||||||
return;
|
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) {
|
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_socket_client = socketid;
|
||||||
g_json_auth_state = JSON_STATE_WAIT_AUTH;
|
g_json_auth_state = JSON_STATE_WAIT_AUTH;
|
||||||
g_json_pwd_retry = 0;
|
g_json_pwd_retry = 0;
|
||||||
g_json_auth_timer = mstick();
|
g_json_auth_timer = mstick();
|
||||||
g_json_recv_len = 0;
|
g_json_recv_len = 0;
|
||||||
memset(g_json_recv_buf, 0, sizeof(g_json_recv_buf));
|
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