diff --git a/Drivers/BSP/NET/net_socket.c b/Drivers/BSP/NET/net_socket.c index e736f5b9..ea0ef756 100644 --- a/Drivers/BSP/NET/net_socket.c +++ b/Drivers/BSP/NET/net_socket.c @@ -3308,6 +3308,9 @@ static void handle_connect_event(net_sock_t *p_sock) { * ESTABLISHED 之后立刻做:否则抢先 relisten 后到新连接的窗口内 * recv 仍会误得 EOF(把新客户端踢开) */ p_sock->session_dead = 0U; + /* F-NET-17 M3 前置:清可疑电平——探针(LISTENING 期)残留计数会带进新会话, + * 不补此清零则 M3 矛盾判据首轮即被旁路(T6 实测 grep:connect 原不清此字段) */ + p_sock->lost_conn_seen = 0U; /* 新开 Socket 发送缓冲按空闲计 */ p_sock->send_ready = 1; @@ -3345,6 +3348,8 @@ static void handle_connect_event(net_sock_t *p_sock) { /* N-32(P1):新会话开始 —— 清"上一条会话已结束"电平(同 LISTENING * 分支:必须在转 ESTABLISHED 后立刻做,防抢先 relisten 窗口误 EOF) */ p_sock->session_dead = 0U; + /* F-NET-17 M3 前置:清可疑电平(同 LISTENING 分支) */ + p_sock->lost_conn_seen = 0U; /* 使能 KeepAlive(客户端连接保活) */ ch395f_set_keepalive_enable(p_sock->ch395_sock, 1); @@ -3413,6 +3418,32 @@ static void handle_disconnect_event(net_sock_t *p_sock) { /* 直接返回(中断已读清,不会重复上报) */ return; } + /* F-NET-17 M3(N34 实验 2026-10-13):矛盾态可疑门——芯片 Socket 仍 OPEN(0x05) + * 而 TCP 槽 0x00 且本层 ESTABLISHED = 逻辑矛盾(活连接应 0x04):陈旧 DISCONNECT + * (拆链完成滞后锁存,Trap 14)与"真断开恰被旧拆链覆写槽"在 D20 上不可分辨 + * (结构性失明,F-NET-15 Q1)。处置:不吃边沿,置可疑电平返回,交对账① + * (ESTABLISHED + 芯片 TCP==CLOSED,:588-589)电平去抖再入本函数(去抖 2×200ms + * + 冷却,实测延迟 ~1.2s):flag==1 旁路本门 → 正常释放;连接真活则租约内 + * 会话正常完成(风暴链掐断,E9a n30 0/50 实证)。 + * 零额外 SPI 于常规路径(st[] 已读;recv_len 仅可疑分支多读一条)。 + * ⚠ E9a/E9b 实测两轮收窄:①必须含 recv_bytes==0——已读数据的会话遇 + * 0x05/0x00 多为真死(探针控制通道教训);②必须含芯片 RX>0——延迟保护的 + * 本质是"在途投递不可毁"(closed-with-data 救回同源红线:RX 有数据=消费者 + * 资产)。@0ms 快复连(连上即关、零数据,E9b :21 46/50 教训)RX 空 → 立即 + * 释放,误杀也无数据损失,后到数据由救回路径接住。边界:滞后锁存杀 + * "已读数据或 RX 空"会话的形态不在本门保护域(E8 窗口未出现该受害形态)。 + * 零误伤:健康 FIN=0x07、静默回收=0x00/0x00 均不命中(E5 20/20 样本) */ + if ((st[0] == CH395F_SOCKET_OPEN) && (st[1] == CH395F_TCP_CLOSED) && + (p_sock->lost_conn_seen == 0U) && (p_sock->recv_bytes == 0U) && + (ch395f_get_recv_len((uint8_t)sockfd) > 0U)) { + /* 置可疑电平(复用探针字段,零 RAM;connect/relisten 清零) */ + p_sock->lost_conn_seen = 1U; + /* 留痕(INFO 级:这是预期自愈路径,非错误,勿污染 [ERR] 台架判据) */ + DBG_INFO("sock%d suspect DISCONNECT on live conn (chip 0x%02X/0x%02X), defer to reconcile", + sockfd, st[0], st[1]); + /* 不释放、不登记沉降、不动 session_dead——保留 400ms 租约窗口 */ + return; + } /* 单连接:先不关 CH395F Socket, * 留给 net_recv_locked 把剩余数据读出来再关,置 CLOSED 等待应用重新监听 */ DBG_INFO("sock%d DISCONNECTED, releasing (chip st=0x%02X/0x%02X)",