@@ -313,7 +313,7 @@ void net_process_messages(void) {
break ;
}
case NET_MSG_LISTEN : {
msg . result = net_listen_locked ( msg . sockfd , msg . flags );
msg . result = net_listen_locked ( msg . sockfd ) ;
break ;
}
case NET_MSG_ACCEPT : {
@@ -453,11 +453,10 @@ int net_bind(int sockfd, const struct net_sockaddr *addr, int addrlen) {
/*
* 函数功能:启动 TCP Server 监听(内部版本,必须在 netTask 上下文调用)
* 入口参数: sockfd - Socket 描述符 (0~7) int
* backlog - 数据 Socket 数量( 0=单连接模式) int
* 返回值: 0 - 成功,-1 - 失败 int
* 限定条件: sockfd 已绑定且为 TCP; netTask 上下文
*/
int net_listen_locked ( int sockfd , int backlog ) {
int net_listen_locked ( int sockfd ) {
/* 取监听 Socket 控制块( 直接下标访问, sockfd 已在上层 net_listen 校验过范围) */
net_sock_t * p_sock = & s_net_socks [ sockfd ] ;
/* CH395F 打开 Socket 的返回状态 */
@@ -476,46 +475,10 @@ int net_listen_locked(int sockfd, int backlog) {
return - 1 ;
}
/* 多连接模式( backlog > 0) : 为数据 Socket 分配并初始化 CH395F 资源 */
if ( backlog > 0 ) {
/* 数据 Socket 编号范围:[NET_TCP_SERVER_DATA_SOCK_START, max_ds) */
int max_ds = NET_TCP_SERVER_DATA_SOCK_START + backlog ;
/* 越界保护:不超过 Socket 总数 */
if ( max_ds > NET_MAX_SOCKETS ) {
max_ds = NET_MAX_SOCKETS ;
}
/* 逐个配置数据 Socket, 供后续 accept 时承接新连接 */
for ( int ds = NET_TCP_SERVER_DATA_SOCK_START ; ds < max_ds ; ds + + ) {
/* 以 4 块为单位划出该 Socket 的发送/接收缓冲(发送占前 2 块,接收占后 2 块) */
uint8_t base = ( uint8_t ) ( ds * 4 ) ;
ch395f_set_send_buf ( ( uint8_t ) ds , base , 2 ) ;
ch395f_set_recv_buf ( ( uint8_t ) ds , base + 2 , 2 ) ;
/* 数据 Socket 监听同一本地端口,协议类型为 TCP */
ch395f_set_sour_port ( ( uint8_t ) ds , p_sock - > local_port ) ;
ch395f_set_proto_type ( ( uint8_t ) ds , CH395F_PROTO_TYPE_TCP ) ;
/* 登记数据 Socket 控制块:标记已用、等待连接态、流类型、绑定硬件 Socket 号 */
s_net_socks [ ds ] . in_use = 1 ;
s_net_socks [ ds ] . state = NET_SOCK_STATE_TCP_ACCEPT ;
s_net_socks [ ds ] . type = NET_SOCK_STREAM ;
s_net_socks [ ds ] . ch395_sock = ( uint8_t ) ds ;
s_net_socks [ ds ] . send_ready = 1 ;
/* 记录到监听 Socket 的数据 Socket 列表,供 net_accept_locked 查表 */
p_sock - > data_socks [ p_sock - > data_sock_count + + ] = ds ;
}
}
/*
* 配置 监听 Socket 自身的 缓冲:
* - 单连接模式( backlog==0, 通常用 Socket 0~3) : CH395F 默认缓冲已 互不重叠,无需重设;
* - 多连接模式( Socket 4~7 默认无收发缓冲):显式按 4 块划分发送/接收缓冲。
* 本实现仅支持单连接: 监听 Socket 自身即为数据通道,复用 CH395F 默认收发 缓冲
* ( Socket 0~3 默认缓冲互不重叠),不再为数据 Socket 额外分配。
*/
if ( backlog > 0 ) {
uint8_t base = ( uint8_t ) ( sockfd * 4 ) ;
ch395f_set_send_buf ( ( uint8_t ) sockfd , base , 2 ) ;
ch395f_set_recv_buf ( ( uint8_t ) sockfd , base + 2 , 2 ) ;
}
/* 监听 Socket 协议类型为 TCP, 并绑定本地端口 */
ch395f_set_proto_type ( sockfd , CH395F_PROTO_TYPE_TCP ) ;
ch395f_set_sour_port ( sockfd , p_sock - > local_port ) ;
@@ -533,16 +496,16 @@ int net_listen_locked(int sockfd, int backlog) {
s_net_errno = NET_ERR_BUSY ;
return - 1 ;
}
/* 下发 TCP LISTEN 命令,进入监听状态 */
ch395f_tcp_listen ( sockfd ) ;
status = ch395f_tcp_listen ( sockfd ) ;
if ( status ! = CH395F_ERR_SUCCESS ) {
s_net_errno = NET_ERR_BUSY ;
return - 1 ;
}
/* 监听 Socket 进入 LISTENING 态 */
p_sock - > state = NET_SOCK_STATE_LISTENING ;
/* 单连接模式标记为 standalone_accept : CONNECT 中断直接作用于本 Socket 自身 */
if ( backlog = = 0 ) {
p_sock - > standalone_accept = 1 ;
}
/* 单连接: CONNECT 中断直接作用于本 Socket 自身 */
/*
* 启动监听前清空各 Socket 及全局中断状态寄存器(读即清除),
@@ -559,12 +522,11 @@ int net_listen_locked(int sockfd, int backlog) {
/*
* 函数功能:启动 TCP Server 监听(线程安全版本,通过消息队列委托给 netTask)
* 入口参数: sockfd - Socket 描述符 int
* backlog - 数据 Socket 数量 int
* 返回值: 0 - 成功,-1 - 失败 int
* 限定条件: net_init() + MX_FREERTOS_Init() 已执行;必须在任务上下文中调用
* 函数说明:通过消息队列委托给 netTask, 确保 SPI 串行化
*/
int net_listen ( int sockfd , int backlog ) {
int net_listen ( int sockfd ) {
net_msg_t msg ;
if ( sockfd < 0 | | sockfd > = NET_MAX_SOCKETS ) {
@@ -579,7 +541,6 @@ int net_listen(int sockfd, int backlog) {
msg . type = NET_MSG_LISTEN ;
msg . sockfd = sockfd ;
msg . flags = backlog ;
msg . caller = xTaskGetCurrentTaskHandle ( ) ;
msg . result = - 1 ;
@@ -607,57 +568,37 @@ int net_listen(int sockfd, int backlog) {
* addrlen - 输入输出:地址结构体长度 int *(可为 NULL)
* 返回值:新连接的 Socket 描述符,失败返回 -1 int
* 限定条件: Socket 处于 LISTENING 状态
* 函数说明:先查 data_socks[] 多连接数据 Socket, 再查 standalone_accept 单连接 Socket
* 函数说明:单连接:监听 Socket 自身在 CONNECT 后已转为 ESTABLISHED
*/
static int net_accept_locked ( int sockfd , struct net_sockaddr * addr , int * addrlen ) {
net_sock_t * p_listen_sock ;
int i ;
p_listen_sock = & s_net_socks [ sockfd ] ;
if ( ! p_listen_sock - > in_use ) {
s_net_errno = NET_ERR_INVAL ;
return - 1 ;
}
if ( p_listen_sock - > state ! = NET_SOCK_STATE_LISTENING & &
! ( p_listen_sock - > standalone_accept & & p_listen_sock - > state = = NET_SOCK_STATE_ESTABLISHED ) ) {
s_net_errno = NET_ERR_INVAL ;
return - 1 ;
}
net_poll ( ) ;
/* 多 连接模式:查 data_socks */
for ( i = 0 ; i < p_listen_sock - > data_sock_count ; i + + ) {
int data_sock = p_listen_sock - > data_socks [ i ] ;
net_sock_t * p_data_cb = & s_net_socks [ data_sock ] ;
if ( p_data_cb - > state = = NET_SOCK_STATE_ESTABLISHED ) {
if ( NULL ! = addr & & NULL ! = addrlen ) {
struct net_sockaddr_in * p_addr_in = ( struct net_sockaddr_in * ) addr ;
p_addr_in - > sin_family = NET_AF_INET ;
p_addr_in - > sin_port = net_htons ( p_data_cb - > remote_port ) ;
p_addr_in - > sin_addr . s_addr = p_data_cb - > remote_ip ;
* addrlen = sizeof ( struct net_sockaddr_in ) ;
}
return data_sock ;
}
/* 单 连接:本 Socket 自身在 CONNECT 后已转为 ESTABLISHED,
* 只有处于 ESTABLISHED 才表示有可接受的连接;否则尚无连接 */
if ( p_listen_sock - > state ! = NET_SOCK_STATE_ESTABLISHED ) {
s_ net_errno = NET_ERR_WOULDBLOCK ;
return - 1 ;
}
/* 单连接模式( PASV) : 查 standalone 监听者是否已 ESTABLISHED */
if ( p_listen_sock - > standalone_accept & &
p_listen_sock - > state = = NET_SOCK_STATE_ESTABLISHED ) {
if ( NULL ! = addr & & NULL ! = addrlen ) {
struct net_sockaddr_in * p_addr_in = ( struct net_sockaddr_in * ) addr ;
p_addr_in - > sin_family = NET_AF_INET ;
p_addr_in - > sin_port = net_htons ( p_listen_sock - > remote_port ) ;
p_addr_in - > sin_addr . s_addr = p_listen_sock - > remote_ip ;
* addrlen = sizeof ( struct net_sockaddr_in ) ;
}
return sockfd ;
/* 填充对端地址(若调用方需要) */
if ( NULL ! = addr & & NULL ! = addrlen ) {
struct net_sockaddr_in * p_addr_in = ( struct net_sockaddr_in * ) addr ;
p_addr_in - > sin_family = NET_AF_INET ;
p_addr_in - > sin_port = net_htons ( p_listen_sock - > remote_port ) ;
p_addr_in - > sin_addr . s_addr = p_listen_sock - > remote_ip ;
* addrlen = sizeof ( struct net_sockaddr_in ) ;
}
s_net_errno = NET_ERR_WOULDBLOCK ;
return - 1 ;
/* 单连接:返回的就是监听 Socket 自身(已转为数据通道) */
return sockfd ;
}
/*
@@ -897,9 +838,6 @@ static int net_recv_locked(net_sock_t *p_sock, void *buf, int len, int flags) {
return - 1 ;
}
if ( p_sock - > state = = NET_SOCK_STATE_TCP_ACCEPT ) {
return 0 ;
}
if ( p_sock - > state = = NET_SOCK_STATE_CLOSED ) {
/* 断开前尝试排空 CH395F 接收缓冲区( Trap 13: FIN 可能比数据先到) */
uint16_t rem = ch395f_get_recv_len ( sockfd ) ;
@@ -1485,44 +1423,14 @@ static int alloc_socket(void) {
* 出口参数:无
* 返回值:无
* 限定条件: net_poll() 检测到 CONNECT 中断后调用; netTask 上下文
* 函数说明: 1. 独立监听模式( standalone_accept) :自身转 ESTABLISHED 并读取对端地址
* 2. 多连接监听模式: Socket 0 保持 LISTENING, 由数据 Socket 承接连接
* 3. 多 连接模式自动打开的数据 Socket: 首次 CONNECT 时初始化并置 ESTABLISHED
* 4. TCP Client( CONNECTING) : 连接成功, 读取对端地址并置 ESTABLISHED
* 5. 数据 Socket( TCP_ACCEPT) : 被分配连接, 置 ESTABLISHED
* 6. 连接成功后使能 KeepAlive 并触发 NET_EVENT_CONNECTED 回调
* 函数说明: 1. 单连接 :自身转 ESTABLISHED 并读取对端地址
* 2. TCP Client( CONNECTING) : 连接成功, 读取对端地址并置 ESTABLISHED
* 3. 连接成功后使能 KeepAlive 并触发 NET_EVENT_CONNECTED 回调
*/
static void handle_connect_event ( net_sock_t * p_sock ) {
if ( p_sock - > state = = NET_SOCK_STATE_LISTENING ) {
if ( p_sock - > standalone_accept ) {
/* 独立监听模式( PASV) : 收到 CONNECT 中断 = 自身有连接到达,转为 ESTABLISHED */
DBG_INFO ( " sock%d standalone accept " , p_sock - > ch395_sock ) ;
uint8_t remote [ 6 ] ;
ch395f_get_remot_ipp ( p_sock - > ch395_sock , remote ) ;
memcpy ( p_sock - > remote_ip_arr , remote , 4 ) ;
p_sock - > remote_ip = ( ( uint32_t ) remote [ 0 ] ) |
( ( uint32_t ) remote [ 1 ] < < 8 ) |
( ( uint32_t ) remote [ 2 ] < < 16 ) |
( ( uint32_t ) remote [ 3 ] < < 24 ) ;
p_sock - > remote_port = ( uint16_t ) ( remote [ 4 ] | ( remote [ 5 ] < < 8 ) ) ;
p_sock - > state = NET_SOCK_STATE_ESTABLISHED ;
p_sock - > send_ready = 1 ;
/* 清除残留的 TIMEOUT 中断标志 */
( void ) ch395f_get_sock_int_status ( p_sock - > ch395_sock ) ;
fire_event ( p_sock , NET_EVENT_CONNECTED ) ;
} else {
/* 多连接模式:监听 Socket 收到 CONNECT 中断 = 有新连接被分配到数据 Socket
* Socket 0 自身保持 LISTENING, 不需要改变状态 */
fire_event ( p_sock , NET_EVENT_CONNECTED ) ;
}
}
else if ( ! p_sock - > in_use ) {
/* CH395F 自动打开的数<E79A84> ?Socket( 多连接模式) , 首次收到 CONNECT 中断 */
int sock_idx = ( int ) ( p_sock - s_net_socks ) ;
p_sock - > ch395_sock = ( uint8_t ) sock_idx ;
DBG_INFO ( " sock%d AUTO-OPENED, CONNECTED " , p_sock - > ch395_sock ) ;
/* 单连接:收到 CONNECT 中断 = 自身有连接到达,转为 ESTABLISHED */
DBG_INFO ( " sock%d standalone accept " , p_sock - > ch395_sock ) ;
uint8_t remote [ 6 ] ;
ch395f_get_remot_ipp ( p_sock - > ch395_sock , remote ) ;
memcpy ( p_sock - > remote_ip_arr , remote , 4 ) ;
@@ -1531,15 +1439,14 @@ static void handle_connect_event(net_sock_t *p_sock) {
( ( uint32_t ) remote [ 2 ] < < 16 ) |
( ( uint32_t ) remote [ 3 ] < < 24 ) ;
p_sock - > remote_port = ( uint16_t ) ( remote [ 4 ] | ( remote [ 5 ] < < 8 ) ) ;
p_sock - > in_use = 1 ;
p_sock - > state = NET_SOCK_STATE_ESTABLISHED ;
p_sock - > send_ready = 1 ;
ch395f_set_keepalive_enable ( p_sock - > ch395_sock , 1 ) ;
/* 清除残留的 TIMEOUT 中断标志 */
( void ) ch395f_get_sock_int_status ( p_sock - > ch395_sock ) ;
fire_event ( p_sock , NET_EVENT_CONNECTED ) ;
}
else if ( p_sock - > state = = NET_SOCK_STATE_CONNECTING ) {
} else if ( p_sock - > state = = NET_SOCK_STATE_CONNECTING ) {
/* TCP Client 连接成功 */
uint8_t remote [ 6 ] ;
ch395f_get_remot_ipp ( p_sock - > ch395_sock , remote ) ;
@@ -1553,24 +1460,6 @@ static void handle_connect_event(net_sock_t *p_sock) {
ch395f_set_keepalive_enable ( p_sock - > ch395_sock , 1 ) ;
fire_event ( p_sock , NET_EVENT_CONNECTED ) ;
}
else if ( p_sock - > state = = NET_SOCK_STATE_TCP_ACCEPT ) {
/* 数据 Socket 被分配了连接 */
DBG_INFO ( " data sock%d TCP_ACCEPT -> CONNECTED " , p_sock - > ch395_sock ) ;
uint8_t remote [ 6 ] ;
ch395f_get_remot_ipp ( p_sock - > ch395_sock , remote ) ;
memcpy ( p_sock - > remote_ip_arr , remote , 4 ) ;
p_sock - > remote_ip = ( ( uint32_t ) remote [ 0 ] ) |
( ( uint32_t ) remote [ 1 ] < < 8 ) |
( ( uint32_t ) remote [ 2 ] < < 16 ) |
( ( uint32_t ) remote [ 3 ] < < 24 ) ;
p_sock - > remote_port = ( uint16_t ) ( remote [ 4 ] | ( remote [ 5 ] < < 8 ) ) ;
p_sock - > state = NET_SOCK_STATE_ESTABLISHED ;
p_sock - > send_ready = 1 ;
ch395f_set_keepalive_enable ( p_sock - > ch395_sock , 1 ) ;
fire_event ( p_sock , NET_EVENT_CONNECTED ) ;
}
}
@@ -1582,33 +1471,18 @@ static void handle_connect_event(net_sock_t *p_sock) {
* 返回值:无
* 限定条件: net_poll() 检测到 DISCONNECT 中断后调用; netTask 上下文
* 函数说明: 1. CH395F 在 DISCONNECT 后自动关闭 Socket( FUN_PARA 默认),需重新 OPEN + LISTEN
* 2. 独立监听模式 :置 CLOSED, 交由 net_recv_locked 排空剩余数据后再关
* 3. 多连接数据 Socket: 回到 TCP_ACCEPT 状态等待新连接
* 4. 触发 NET_EVENT_DISCONNECTED 回调
* 2. 单连接 :置 CLOSED, 交由 net_recv_locked 排空剩余数据后再关
* 3. 触发 NET_EVENT_DISCONNECTED 回调
*/
static void handle_disconnect_event ( net_sock_t * p_sock ) {
if ( p_sock - > state = = NET_SOCK_STATE_LISTENING ) {
DBG_ERROR ( " WARNING: listen sock%d got disconnect " , p_sock - > ch395_sock ) ;
}
else if ( p_sock - > state = = NET_SOCK_STATE_ESTABLISHED ) {
if ( p_sock - > standalone_accept ) {
/* 独立监听模式:先不关 CH395F Socket,
* 留给 net_recv_locked 把剩余数据读出来再关 */
DBG_INFO ( " sock%d DISCONNECTED, releasing " , p_sock - > ch395_sock ) ;
p_sock - > state = NET_SOCK_STATE_CLOSED ;
fire_event ( p_sock , NET_EVENT_DISCONNECTED ) ;
} else {
DBG_INFO ( " sock%d DISCONNECTED, back to idle " , p_sock - > ch395_sock ) ;
memset ( p_sock - > remote_ip_arr , 0 , 4 ) ;
p_sock - > remote_port = 0 ;
p_sock - > send_ready = 1 ;
p_sock - > state = NET_SOCK_STATE_TCP_ACCEPT ;
fire_event ( p_sock , NET_EVENT_DISCONNECTED ) ;
}
} else if ( p_sock - > state = = NET_SOCK_STATE_TCP_ACCEPT ) {
memset ( p_sock - > remote_ip_arr , 0 , 4 ) ;
p_sock - > remote_port = 0 ;
p_sock - > send_ready = 1 ;
} else if ( p_sock - > state = = NET_SOCK_STATE_ESTABLISHED ) {
/* 单连接:先不关 CH395F Socket,
* 留给 net_recv_locked 把剩余数据读出来再关,置 CLOSED 等待应用重新监听 */
DBG_INFO ( " sock%d DISCONNECTED, releasing " , p_sock - > ch395_sock ) ;
p_sock - > state = NET_SOCK_STATE_CLOSED ;
fire_event ( p_sock , NET_EVENT_DISCONNECTED ) ;
} else if ( p_sock - > state ! = NET_SOCK_STATE_CLOSED & &
p_sock - > state ! = NET_SOCK_STATE_BOUND & &
p_sock - > state ! = NET_SOCK_STATE_CREATED ) {
@@ -1653,7 +1527,7 @@ static void handle_send_event(net_sock_t *p_sock) {
* 返回值:无
* 限定条件: net_poll() 检测到 SOCK_TIMEOUT 中断后调用; netTask 上下文
* 函数说明: 1. TCP Client( CONNECTING) : 连接超时, 回到 CREATED 状态
* 2. 已建立连接:回到 CLOSED( 独立模式)或 TCP_ACCEPT( 多连接模式 )
* 2. 已建立连接:回到 CLOSED( 单连接 )
* 3. 监听态:异常超时,记录错误日志
* 4. 触发 NET_EVENT_TIMEOUT 回调
*/
@@ -1662,12 +1536,10 @@ static void handle_timeout_event(net_sock_t *p_sock) {
/* TCP Client 连接超时 */
DBG_ERROR ( " sock%d CONNECT TIMEOUT " , p_sock - > ch395_sock ) ;
p_sock - > state = NET_SOCK_STATE_CREATED ;
}
else if ( p_sock - > state = = NET_SOCK_STATE_ESTABLISHED ) {
} else if ( p_sock - > state = = NET_SOCK_STATE_ESTABLISHED ) {
DBG_ERROR ( " sock%d TIMEOUT " , p_sock - > ch395_sock ) ;
p_sock - > state = p_sock - > standalone_accept ? NET_SOCK_STATE_CLOSED : NET_SOCK_STATE_TCP_ACCEPT ;
}
else if ( p_sock - > state = = NET_SOCK_STATE_LISTENING ) {
p_sock - > state = NET_SOCK_STATE_CLOSED ;
} else if ( p_sock - > state = = NET_SOCK_STATE_LISTENING ) {
/* 监听超时(异常情况) */
DBG_ERROR ( " sock%d LISTEN TIMEOUT " , p_sock - > ch395_sock ) ;
}