/*
 * 模块名称：Network Socket Core
 * 模块功能：BSD Socket API 核心实现，包含 Socket 管理、状态机、消息队列（线程安全）、事件处理、数据收发等功能，底层调用 CH395F 驱动
 * 适用平台：STM32F407ZGTx + CH395F 以太网芯片
 * 作者：王建锋
 * 创建日期：2026-07-18
 * 修改记录：
 *     2026-07-18  王建锋  创建初始版本
 *     2026-07-19  王建锋  添加消息队列线程安全机制，替换 xQueueCreate 为 CubeMX osMessageQueue
 */

#include <string.h>
#include <stdio.h>

#include "FreeRTOS.h"
#include "task.h"
#include "cmsis_os.h"

#include "net_socket.h"
#include "ch395f.h"
#include "main.h"

/*
 * 调试输出配置
 */
#define DBG_TAG "[NET]"
#include "dbg_log.h"

/*
 * 私有宏定义区
 */
#define NET_PHY_CHECK_INTERVAL_MS   5000U  /* PHY 状态定期检查间隔（ms） */

/*
 * 全局变量定义区 - 尽量避免使用全局变量
 */
static net_sock_t s_net_socks[NET_MAX_SOCKETS];  /* Socket 控制块数组 */
static int s_net_errno = 0;                       /* 最后错误码 */
static uint8_t s_net_initialized = 0;             /* 初始化标志 */

/*
 * 消息队列 - 线程安全核心
 * 外部任务通过 net_send/net_recv/net_close 等 API 将请求放入队列，
 * netTask 调用 net_process_messages() 串行处理所有 CH395F 操作
 * 由 CubeMX 在 MX_FREERTOS_Init()（osKernelInitialize 之后）中创建
 */
extern osMessageQueueId_t netMsgQueueHandle;         /* CubeMX 生成的消息队列句柄 */






/*
 * 私有函数声明区
 */

static int alloc_socket(void);
static void handle_connect_event(net_sock_t *p_sock);
static void handle_disconnect_event(net_sock_t *p_sock);
static void handle_recv_event(net_sock_t *p_sock);
static void handle_send_event(net_sock_t *p_sock);
static void handle_timeout_event(net_sock_t *p_sock);
static void fire_event(net_sock_t *p_sock, net_event_t event);
static void parse_ip_string(const char *str, uint8_t *ip_arr);
static int net_send_locked(net_sock_t *p_sock, const void *buf, int len);
static int net_recv_locked(net_sock_t *p_sock, void *buf, int len, int flags);
static int net_close_locked(net_sock_t *p_sock);
static int net_accept_locked(int sockfd, struct net_sockaddr *addr, int *addrlen);

/*
 * 函数功能：网络子系统初始化（配置 CH395F + 启用多连接模式）
 * 入口参数：ip       - IP 地址字符串 "192.168.1.100"，NULL 使用 DHCP 自动获取  const char *
 *           mask     - 子网掩码字符串 "255.255.255.0"，NULL 使用默认值          const char *
 *           gateway  - 网关地址字符串 "192.168.1.1"，NULL 使用默认值            const char *
 * 返回值：0 - 初始化成功  int
 *         -1 - 初始化失败（芯片检测/复位/协议栈初始化失败）                      int
 * 限定条件：SPI2 已正确初始化；netTask 尚未启动
 * 函数说明：1. 检查 CH395F 芯片是否存在并复位
 *           2. 启用 TCP Server 多连接模式（bit1=1），设置 TCP MSS、重传参数、KeepAlive 参数
 *           3. 配置 IP/网关/子网掩码，或启用 DHCP
 *           4. 初始化 CH395F 协议栈并使能 PING 响应
 */
int net_init(const char *ip, const char *mask, const char *gateway) {
    ch395f_status_t ret;

    DBG_INFO("net_init: start");

    /* 清零 Socket 控制块 */
    memset(s_net_socks, 0, sizeof(s_net_socks));
    s_net_errno = 0;
    s_net_initialized = 0;

    DBG_INFO("net_init: queue=%p", (void *)netMsgQueueHandle);

    DBG_INFO("net_init: check_exist...");
    /* 检查 CH395F 芯片 */
    if (ch395f_check_exist() != CH395F_STATUS_OK) {
        DBG_ERROR("net_init: ch395f_check_exist FAILED");
        s_net_errno = NET_ERR;
        return -1;
    }
    DBG_INFO("net_init: reset...");
    /* 复位芯片 */
    ch395f_reset();
    DBG_INFO("net_init: set_fun_para...");

    /* 启用 TCP Server 多连接模式（bit1=1） */
    ch395f_set_fun_para(0x02);
    DBG_INFO("net_init: set_tcp_mss...");

    /* 设置 TCP MSS */
    ch395f_set_tcp_mss(1460);

    /* 设置 TCP 重传参数（必须在 INIT_CH395 之前�?*/
    ch395f_set_retrans_count(8);        /* 重传 8 �?*/
    ch395f_set_retrans_period(500);     /* 每次间隔 500ms，总计 4s 重传窗口 */

    /* 设置 TCP KeepAlive 参数（必须在 INIT_CH395 之前，单�?ms，必须为 500 的倍数，IDLE > INTVL�?*/
    ch395f_set_keepalive_idle(60000);    /* 空闲 60 秒后开始探�?*/
    ch395f_set_keepalive_intvl(5000);    /* �?5 秒探测一�?*/
    ch395f_set_keepalive_cnt(3);         /* 最多探�?3 �?*/

    /* 设置网络参数（必须在 INIT_CH395 之前�?*/
    if (ip != NULL) {
        uint8_t ip_arr[4];
        uint8_t mask_arr[4];
        uint8_t gw_arr[4];

        parse_ip_string(ip, ip_arr);
        parse_ip_string(mask, mask_arr);
        parse_ip_string(gateway, gw_arr);

        ch395f_set_ip_addr(ip_arr);
        ch395f_set_gwip_addr(gw_arr);
        ch395f_set_mask_addr(mask_arr);
    } else {
        /* 启用 DHCP */
        ch395f_set_dhcp(1);
    }

    /* 初始�?CH395F 协议栈（先不配置 buffer，测试默认值是否工作） */
    ret = ch395f_init();
    if (ret != CH395F_STATUS_OK) {
        s_net_errno = NET_ERR;
        return -1;
    }

    /* 使能 PING 响应 */
    ch395f_ping_enable(1);

    s_net_initialized = 1;

    return 0;
}

/*
 * 函数功能：轮询 CH395F 中断状态，更新 Socket 连接状态并处理事件
 * 返回值：本次轮询中发生事件的 Socket 数量  int >= 0
 * 限定条件：s_net_initialized == 1；必须在 netTask 上下文中调用
 * 函数说明：1. GPIO 轮询 CH395F INT# 引脚电平（低电平有效），无需 EXTI 中断
 *           2. 读取 GET_GLOB_INT_STATUS_ALL（2 字节版）获取所有 Socket 的中断状态
 *           3. 处理连接/断开/数据接收/发送完成/超时等事件，更新 Socket 状态机
 *           4. RECV 中断为电平触发，每次 net_poll() 只处理一批中断，避免主循环饿死
 */
int net_poll(void) {
    int event_count = 0;
    int i;
    uint16_t int_status;

    if (!s_net_initialized) {
        return 0;
    }

    /*
     * GPIO 轮询模式：仅当 INT# 有效（低电平）时读取中断状态。
     * 读取 GET_GLOB_INT_STATUS_ALL，CH395F 拉高 INT#；若仍有中断则再次拉低。
     */
    do
    {
        if (HAL_GPIO_ReadPin(CH395_INT_GPIO_Port, CH395_INT_Pin) == GPIO_PIN_SET) {
            break;
        }

        int_status = ch395f_get_glob_int_status_all();

        if (int_status == 0) {
            break;
        }

        /* 诊断：每 3 秒打印一次全局中断状态和 Socket 状态。
         * 注意：使用已读取的 int_status，不要再读 GINT（读即清除）。 */
        static uint32_t s_last_diag = 0;
        uint32_t now_diag = HAL_GetTick();
        if ((now_diag - s_last_diag >= 3000) || s_last_diag == 0) {
            s_last_diag = now_diag;
            DBG_INFO("GINT=0x%04X", int_status);
            for (int di = 0; di < NET_MAX_SOCKETS; di++) {
                DBG_INFO("  s%d: in_use=%d state=%d",
                    di, s_net_socks[di].in_use, s_net_socks[di].state);
            }
        }

        if (int_status & CH395F_GINT_STAT_PHY_CHANGE) {
            uint8_t phy = ch395f_get_phy_status();
            DBG_INFO("PHY_CHANGE: 0x%02X", phy);
            if (phy == CH395F_PHY_DISCONN) {
                DBG_ERROR("PHY disconnected, sockets may need recovery");
            }
        }

        /* 处理每个 Socket */
        for (i = 0; i < NET_MAX_SOCKETS; i++) {
            net_sock_t *p_sock = &s_net_socks[i];

            /* 检查该 Socket 是否有中断（全局中断状�?bit4~bit11 对应 socket0~7�?*/
            if (!(int_status & (1U << (i + 4)))) {
                continue;
            }

            /* 读取 Socket 中断状�?*/
            uint8_t sock_int = ch395f_get_sock_int_status(i);

            /* 连接事件 */
            if (sock_int & CH395F_SINT_STAT_CONNECT) {
                handle_connect_event(p_sock);
                event_count++;
            }

            /* 断开事件 */
            if (sock_int & CH395F_SINT_STAT_DISCONNECT) {
                handle_disconnect_event(p_sock);
                event_count++;
            }

            /* 数据接收事件 */
            if (sock_int & CH395F_SINT_STAT_RECV_OK) {
                handle_recv_event(p_sock);
                event_count++;
            }

            /* 发送完成事�?*/
            if (sock_int & CH395F_SINT_STAT_SEND_OK) {
                handle_send_event(p_sock);
                event_count++;
            }

            /* 发送缓冲区空闲 */
            if (sock_int & CH395F_SINT_STAT_SENBUF_FREE) {
                p_sock->send_ready = 1;
            }

            /* 超时事件 */
            if (sock_int & CH395F_SINT_STAT_SOCK_TIMEOUT) {
                handle_timeout_event(p_sock);
                event_count++;
            }
        }

        /*
         * 处理完毕后检查 INT# 是否仍为低电平。如果是，说明在处理期间有新中断产生，需要再次读取。
         * 注意：CH395F 的 RECV 中断是电平触发的（只要接收缓冲区有数据就保持低电平）。
         * 如果不跳出循环，net_poll() 会无限循环处理 RECV 中断，导致主循环中的应用代码（如 echo）永远无法执行。
         * 因此每次 net_poll() 调用只处理一批中断，由主循环负责读取数据。 */
    } while (0);

    /* 2 秒打印一次诊断信息（调试用） */
    {
        static uint32_t s_last_dbg = 0;
        uint32_t now = HAL_GetTick();
        if (now - s_last_dbg >= 2000) {
            s_last_dbg = now;
            uint8_t int_level = (HAL_GPIO_ReadPin(CH395_INT_GPIO_Port, CH395_INT_Pin) == GPIO_PIN_RESET) ? 1 : 0;
            DBG_DEBUG("INT#=%d", int_level);
            for (i = 0; i < NET_MAX_SOCKETS; i++) {
                if (s_net_socks[i].in_use) {
                    uint8_t st[2];
                    ch395f_get_socket_status((uint8_t)i, st);
                    uint16_t rl = ch395f_get_recv_len((uint8_t)i);
                    DBG_DEBUG(" s%d:sw%d/tcp%d rl%d", i, st[0], st[1], rl);
                }
            }
        }
    }

    return event_count;
}

/*
 * 函数功能：处理消息队列中的请求
 * 限定条件：必须在 netTask 上下文中调用（独占 CH395F 和 s_net_socks 访问权）
 * 函数说明：每次调用处理一条消息。处理 send/recv 时内部会调用 net_poll()
 *          等待操作完成。处理完毕后通知调用方任务。
 */
void net_process_messages(void) {
    net_msg_t msg;

    if (netMsgQueueHandle == NULL) {
        return;
    }

    while (osMessageQueueGet(netMsgQueueHandle, &msg, NULL, 0) == osOK) {
        switch (msg.type) {
        case NET_MSG_SEND: {
            net_sock_t *p_sock = net_get_sock(msg.sockfd);
            if (p_sock == NULL || p_sock->state != NET_SOCK_STATE_ESTABLISHED) {
                msg.result = -1;
            } else {
                msg.result = net_send_locked(p_sock, msg.buf, msg.len);
            }
            break;
        }
        case NET_MSG_RECV: {
            net_sock_t *p_sock = net_get_sock(msg.sockfd);
            if (p_sock == NULL) {
                msg.result = -1;
            } else {
                msg.result = net_recv_locked(p_sock, msg.buf, msg.len, msg.flags);
            }
            break;
        }
        case NET_MSG_CLOSE: {
            net_sock_t *p_sock = net_get_sock(msg.sockfd);
            if (p_sock == NULL) {
                msg.result = -1;
            } else {
                msg.result = net_close_locked(p_sock);
            }
            break;
        }
        case NET_MSG_CONNECT: {
            msg.result = net_connect(msg.sockfd,
                                     (const struct net_sockaddr *)&msg.addr,
                                     msg.addrlen);
            break;
        }
        case NET_MSG_LISTEN: {
            msg.result = net_listen_locked(msg.sockfd, msg.flags);
            break;
        }
        case NET_MSG_ACCEPT: {
            struct net_sockaddr *p_addr = (struct net_sockaddr *)msg.buf;
            int addrlen = msg.len;
            int *p_addrlen = (p_addr != NULL && addrlen > 0) ? &addrlen : NULL;
            msg.result = net_accept_locked(msg.sockfd, p_addr, p_addrlen);
            break;
        }
        default:
            msg.result = -1;
            break;
        }

        xTaskNotifyGive(msg.caller);
    }
}

/*
 * 函数功能：创建 Socket，分配空闲 Socket 控制块并初始化状态
 * 入口参数：domain   - 地址族，仅支持 NET_AF_INET                              int
 *           type     - SOCK_STREAM(TCP) 或 SOCK_DGRAM(UDP)                      int
 *           protocol - 通常为 0                                                int
 * 返回值：Socket 描述符 (0~7)，失败返回 -1                                     int
 * 限定条件：net_init() 已调用成功；s_net_initialized == 1
 * 函数说明：自动分配一个空闲的 Socket 控制块（in_use=0），初始化为 CREATED 状态
 */
int net_socket(int domain, int type, int protocol) {
    int sockfd;
    net_sock_t *p_sock;

    /* 参数检查*/
    if (domain != NET_AF_INET) {
        s_net_errno = NET_ERR_INVAL;
        return -1;
    }

    /* 分配空闲 Socket */
    sockfd = alloc_socket();
    if (sockfd < 0) {
        s_net_errno = NET_ERR_NOMEM;
        return -1;
    }

    p_sock = &s_net_socks[sockfd];
    p_sock->ch395_sock = (uint8_t)sockfd;
    p_sock->type = (uint8_t)type;
    p_sock->state = NET_SOCK_STATE_CREATED;
    p_sock->in_use = 1;
    p_sock->send_ready = 1;

    return sockfd;
}

/*
 * 函数功能：绑定 Socket 到本地 IP 地址和端口号
 * 入口参数：sockfd   - Socket 描述符 (0~7)                                       int
 *           addr     - 本地地址结构体指针                                        const struct net_sockaddr *
 *           addrlen  - 地址结构体长度                                            int >= sizeof(struct net_sockaddr_in)
 * 返回值：0 - 绑定成功                                                          int
 *         -1 - 绑定失败（参数无效、Socket 未使用等）                             int
 * 限定条件：Socket 已通过 net_socket() 创建且未被其他操作占用；net_init() 已调用
 * 函数说明：1. TCP Socket 仅记录本地端口，进入 BOUND 状态等待 listen
 *           2. UDP Socket（SOCK_DGRAM）立即打开 CH395F Socket 并配置为 Server 模式
 *              - Socket 4~7 需显式分配收发缓冲区
 */
int net_bind(int sockfd, const struct net_sockaddr *addr, int addrlen) {
    net_sock_t *p_sock;
    const struct net_sockaddr_in *p_addr_in;

    /* 参数检�?*/
    if (sockfd < 0 || sockfd >= NET_MAX_SOCKETS) {
        s_net_errno = NET_ERR_BADF;
        return -1;
    }

    p_sock = &s_net_socks[sockfd];
    if (!p_sock->in_use) {
        s_net_errno = NET_ERR_BADF;
        return -1;
    }

    if (addr == NULL || addrlen < (int)sizeof(struct net_sockaddr_in)) {
        s_net_errno = NET_ERR_INVAL;
        return -1;
    }

    p_addr_in = (const struct net_sockaddr_in *)addr;

    /* 设置本地端口（转换为主机序） */
    p_sock->local_port = net_ntohs(p_addr_in->sin_port);

    /* UDP (SOCK_DGRAM): 直接在此打开 CH395F Socket */
    if (p_sock->type == NET_SOCK_DGRAM) {
        uint8_t status;

        /* Socket 4-7 默认无收发缓冲，需显式分配 */
        if (sockfd >= 4) {
            ch395f_set_send_buf((uint8_t)sockfd, 28, 2);
            ch395f_set_recv_buf((uint8_t)sockfd, 30, 2);
        }

        ch395f_set_proto_type((uint8_t)sockfd, CH395F_PROTO_TYPE_UDP);
        ch395f_set_sour_port((uint8_t)sockfd, p_sock->local_port);

        /* DesIP=0xFFFFFFFF �?UDP Server 模式（接受任意来源） */
        {
            uint8_t broadcast[4] = {0xFF, 0xFF, 0xFF, 0xFF};
            ch395f_set_des_ip((uint8_t)sockfd, broadcast);
        }
        ch395f_set_des_port((uint8_t)sockfd, 0);

        status = ch395f_open_socket((uint8_t)sockfd);
    if (status != CH395F_ERR_SUCCESS) {
        DBG_ERROR("sock%d open_socket FAIL: status=0x%02X (expected 0x00)", sockfd, status);
        s_net_errno = NET_ERR_BUSY;
        return -1;
    }

        p_sock->state = NET_SOCK_STATE_UDP_OPEN;
    } else {
        p_sock->state = NET_SOCK_STATE_BOUND;
    }

    return 0;
}

/*
 * 函数功能：启动 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) {
    net_sock_t *p_sock = &s_net_socks[sockfd];
    uint8_t status;

    if (!p_sock->in_use || p_sock->type != NET_SOCK_STREAM) {
        s_net_errno = NET_ERR_INVAL;
        return -1;
    }

    if (p_sock->state != NET_SOCK_STATE_BOUND &&
        p_sock->state != NET_SOCK_STATE_CREATED) {
        s_net_errno = NET_ERR_INVAL;
        return -1;
    }

    /* 多连接模式：按 backlog 分配数据 Socket */
    if (backlog > 0) {
        int max_ds = NET_TCP_SERVER_DATA_SOCK_START + backlog;
        if (max_ds > NET_MAX_SOCKETS) {
            max_ds = NET_MAX_SOCKETS;
        }
        for (int ds = NET_TCP_SERVER_DATA_SOCK_START; ds < max_ds; ds++) {
            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);
            ch395f_set_sour_port((uint8_t)ds, p_sock->local_port);
            ch395f_set_proto_type((uint8_t)ds, CH395F_PROTO_TYPE_TCP);
            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;

            p_sock->data_socks[p_sock->data_sock_count++] = ds;
        }
    }

    /* 配置监听 Socket */
    ch395f_set_send_buf((uint8_t)sockfd, 0, 2);
    ch395f_set_recv_buf((uint8_t)sockfd, 2, 2);
    ch395f_set_proto_type(sockfd, CH395F_PROTO_TYPE_TCP);
    ch395f_set_sour_port(sockfd, p_sock->local_port);
    status = ch395f_open_socket(sockfd);

    if (status != CH395F_ERR_SUCCESS) {
        s_net_errno = NET_ERR_BUSY;
        return -1;
    }

    ch395f_tcp_listen(sockfd);

    p_sock->state = NET_SOCK_STATE_LISTENING;
    if (backlog == 0) {
        p_sock->standalone_accept = 1;
    }

    for (int j = 0; j < NET_MAX_SOCKETS; j++) {
        (void)ch395f_get_sock_int_status((uint8_t)j);
    }
    (void)ch395f_get_glob_int_status_all();

    return 0;
}

/*
 * 函数功能：启动 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) {
    net_msg_t msg;

    if (sockfd < 0 || sockfd >= NET_MAX_SOCKETS) {
        s_net_errno = NET_ERR_BADF;
        return -1;
    }

    if (netMsgQueueHandle == NULL) {
        s_net_errno = NET_ERR;
        return -1;
    }

    msg.type = NET_MSG_LISTEN;
    msg.sockfd = sockfd;
    msg.flags = backlog;
    msg.caller = xTaskGetCurrentTaskHandle();
    msg.result = -1;

    if (osMessageQueuePut(netMsgQueueHandle, &msg, 0, osWaitForever) != osOK) {
        s_net_errno = NET_ERR_BUSY;
        return -1;
    }

    ulTaskNotifyTake(pdTRUE, portMAX_DELAY);

    if (msg.result < 0) {
        s_net_errno = NET_ERR;
    }
    return msg.result;
}

/*
 * 函数功能：TCP Server 接受新连接（内部版本，必须在 netTask 上下文调用）
 * 入口参数：sockfd   - 监听 Socket 描述符                                       int
 *           addr     - 输出：客户端地址结构体指针                              struct net_sockaddr *（可为 NULL）
 *           addrlen  - 输入输出：地址结构体长度                                int *（可为 NULL）
 * 返回值：新连接的 Socket 描述符，失败返回 -1                                  int
 * 限定条件：Socket 处于 LISTENING 状态
 * 函数说明：先查 data_socks[] 多连接数据 Socket，再查 standalone_accept 单连接 Socket
 */
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 || p_listen_sock->state != NET_SOCK_STATE_LISTENING) {
        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 (addr != NULL && addrlen != NULL) {
                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;
        }
    }

    /* 单连接模式（PASV）：查 standalone 监听者是否已 ESTABLISHED */
    if (p_listen_sock->standalone_accept &&
        p_listen_sock->state == NET_SOCK_STATE_ESTABLISHED) {
        if (addr != NULL && addrlen != NULL) {
            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;
    }

    s_net_errno = NET_ERR_WOULDBLOCK;
    return -1;
}

/*
 * 函数功能：TCP Server 接受新连接（线程安全版本，通过消息队列委托给 netTask）
 * 入口参数：sockfd   - 监听 Socket 描述符                                       int
 *           addr     - 输出：客户端地址结构体指针                              struct net_sockaddr *（可为 NULL）
 *           addrlen  - 输入输出：地址结构体长度                                int *（可为 NULL）
 * 返回值：新连接的 Socket 描述符，失败返回 -1                                  int
 * 限定条件：Socket 处于 LISTENING 状态；net_init() + MX_FREERTOS_Init() 已执行；非 netTask 上下文
 * 函数说明：将接受请求放入消息队列，阻塞等待 netTask 处理完毕
 */
int net_accept(int sockfd, struct net_sockaddr *addr, int *addrlen) {
    net_msg_t msg;

    if (sockfd < 0 || sockfd >= NET_MAX_SOCKETS) {
        s_net_errno = NET_ERR_BADF;
        return -1;
    }

    if (netMsgQueueHandle == NULL) {
        s_net_errno = NET_ERR;
        return -1;
    }

    msg.type = NET_MSG_ACCEPT;
    msg.sockfd = sockfd;
    msg.buf = (void *)addr;
    msg.len = (addrlen != NULL) ? *addrlen : 0;
    msg.caller = xTaskGetCurrentTaskHandle();
    msg.result = -1;

    if (osMessageQueuePut(netMsgQueueHandle, &msg, 0, osWaitForever) != osOK) {
        s_net_errno = NET_ERR_BUSY;
        return -1;
    }

    ulTaskNotifyTake(pdTRUE, portMAX_DELAY);

    if (addrlen != NULL && addr != NULL) {
        *addrlen = sizeof(struct net_sockaddr_in);
    }

    if (msg.result < 0) {
        s_net_errno = NET_ERR;
    }
    return msg.result;
}

/*
 * 函数功能：TCP Client 发起与服务器的连接
 * 入口参数：sockfd   - Socket 描述符 (0~7)，必须为已创建的 TCP Socket          int
 *           addr     - 服务器地址结构体指针                                    const struct net_sockaddr *
 *           addrlen  - 地址结构体长度                                          int >= sizeof(struct net_sockaddr_in)
 * 返回值：0 - 连接请求发送成功（异步，需等待 ESTABLISHED）                     int
 *         -1 - 连接失败（参数无效、状态错误等）                               int
 * 限定条件：Socket 已通过 net_socket() 创建且 type == NET_SOCK_STREAM；尚未连接
 * 函数说明：设置目标 IP 和端口后打开 CH395F Socket，进入 CONNECTING 状态。连接建立需等待
 *          net_poll() 检测到 CONNECT 事件并将状态更新为 ESTABLISHED
 */
int net_connect(int sockfd, const struct net_sockaddr *addr, int addrlen) {
    net_sock_t *p_sock;
    const struct net_sockaddr_in *p_addr_in;
    uint8_t status;

    /* 参数检�?*/
    if (sockfd < 0 || sockfd >= NET_MAX_SOCKETS) {
        s_net_errno = NET_ERR_BADF;
        return -1;
    }

    p_sock = &s_net_socks[sockfd];
    if (!p_sock->in_use || p_sock->type != NET_SOCK_STREAM) {
        s_net_errno = NET_ERR_INVAL;
        return -1;
    }

    if (addr == NULL || addrlen < (int)sizeof(struct net_sockaddr_in)) {
        s_net_errno = NET_ERR_INVAL;
        return -1;
    }

    p_addr_in = (const struct net_sockaddr_in *)addr;

    /* 保存远端地址 */
    p_sock->remote_ip = p_addr_in->sin_addr.s_addr;
    p_sock->remote_port = net_ntohs(p_addr_in->sin_port);

    /* 转换 IP 为数组格式（低字节在前） */
    p_sock->remote_ip_arr[0] = (uint8_t)(p_sock->remote_ip);
    p_sock->remote_ip_arr[1] = (uint8_t)(p_sock->remote_ip >> 8);
    p_sock->remote_ip_arr[2] = (uint8_t)(p_sock->remote_ip >> 16);
    p_sock->remote_ip_arr[3] = (uint8_t)(p_sock->remote_ip >> 24);

    /* 配置 CH395F Socket */
    ch395f_set_proto_type(sockfd, CH395F_PROTO_TYPE_TCP);
    ch395f_set_sour_port(sockfd, p_sock->local_port);
    ch395f_set_des_ip(sockfd, p_sock->remote_ip_arr);
    ch395f_set_des_port(sockfd, p_sock->remote_port);
    status = ch395f_open_socket(sockfd);

    if (status != CH395F_ERR_SUCCESS) {
        s_net_errno = NET_ERR_BUSY;
        return -1;
    }

    /* 发起 TCP 连接 */
    ch395f_tcp_connect(sockfd);
    p_sock->state = NET_SOCK_STATE_CONNECTING;

    return 0;
}

/*
 * 函数功能：发送数据（内部锁定版本，必须在 netTask 上下文调用）
 */
static int net_send_locked(net_sock_t *p_sock, const void *buf, int len) {
    int sent = 0;
    uint32_t tick_start;
    int sockfd = (int)(p_sock - s_net_socks);

    if (buf == NULL || len <= 0) {
        s_net_errno = NET_ERR_INVAL;
        return -1;
    }

    if (p_sock->state != NET_SOCK_STATE_ESTABLISHED) {
        s_net_errno = NET_ERR_NOTCONN;
        return -1;
    }

    tick_start = HAL_GetTick();

    while (sent < len) {
        int chunk = len - sent;
        if (chunk > NET_SEND_BUF_SIZE) {
            chunk = NET_SEND_BUF_SIZE;
        }

        if (!p_sock->send_ready) {
            if (NET_SEND_TIMEOUT_MS > 0 &&
                (HAL_GetTick() - tick_start) >= NET_SEND_TIMEOUT_MS) {
                s_net_errno = NET_ERR_TIMEDOUT;
                break;
            }
            net_poll();
            continue;
        }

        ch395f_write_send_buf(sockfd, (uint8_t *)buf + sent, (uint16_t)chunk);
        p_sock->send_ready = 0;
        sent += chunk;
        p_sock->send_bytes += (uint32_t)chunk;

        tick_start = HAL_GetTick();
        while (!p_sock->send_ready) {
            net_poll();
            if (NET_SEND_TIMEOUT_MS > 0 &&
                (HAL_GetTick() - tick_start) >= NET_SEND_TIMEOUT_MS) {
                break;
            }
        }
    }

    return sent;
}

/*
 * 函数功能：接收数据（内部锁定版本，必须在 netTask 上下文调用）
 */
static int net_recv_locked(net_sock_t *p_sock, void *buf, int len, int flags) {
    uint16_t recv_len;
    uint32_t tick_start;
    int sockfd = (int)(p_sock - s_net_socks);

    if (buf == NULL || len <= 0) {
        s_net_errno = NET_ERR_INVAL;
        return -1;
    }

    tick_start = HAL_GetTick();

    while (1) {
        net_poll();

        recv_len = ch395f_get_recv_len(sockfd);
        if (recv_len > 0) {
            int read_len = (recv_len > (uint16_t)len) ? len : (int)recv_len;
            ch395f_read_recv_buf(sockfd, (uint8_t *)buf, (uint16_t)read_len);
            p_sock->recv_bytes += (uint32_t)read_len;
            return read_len;
        }

        if (flags & NET_MSG_DONTWAIT) {
            s_net_errno = NET_ERR_WOULDBLOCK;
            return -1;
        }

        if (NET_RECV_TIMEOUT_MS > 0 &&
            (HAL_GetTick() - tick_start) >= NET_RECV_TIMEOUT_MS) {
            s_net_errno = NET_ERR_TIMEDOUT;
            return -1;
        }

        if (p_sock->state == NET_SOCK_STATE_TCP_ACCEPT) {
            return 0;
        }
    }
}

/*
 * 函数功能：关闭 socket（内部锁定版本，必须在 netTask 上下文调用）
 */
static int net_close_locked(net_sock_t *p_sock) {
    int sockfd = (int)(p_sock - s_net_socks);

    ch395f_close_socket(sockfd);
    memset(p_sock, 0, sizeof(net_sock_t));

    return 0;
}

/*
 * 函数功能：发送数据（线程安全版本，通过消息队列委托给 netTask）
 * 入口参数：sockfd - Socket 描述符                                                  int >= 0 && < NET_MAX_SOCKETS
 *           buf    - 待发送数据缓冲区指针                                            const void *
 *           len    - 数据长度                                                        int > 0
 *           flags  - 标志位，通常为 0                                                int
 * 返回值：实际发送字节数                                                            int >= 0 || -1
 *         -1       - 发送失败（参数无效、队列满等）                                int
 * 限定条件：Socket 处于 ESTABLISHED 状态；net_init() + MX_FREERTOS_Init() 已执行；非 netTask 上下文
 * 函数说明：将发送请求放入消息队列，阻塞等待 netTask 处理完毕并返回结果。netTask 内请使用 net_send_sock()
 */
int net_send(int sockfd, const void *buf, int len, int flags) {
    (void)flags;
    net_msg_t msg;

    if (sockfd < 0 || sockfd >= NET_MAX_SOCKETS) {
        s_net_errno = NET_ERR_BADF;
        return -1;
    }

    if (netMsgQueueHandle == NULL) {
        s_net_errno = NET_ERR;
        return -1;
    }

    msg.type = NET_MSG_SEND;
    msg.sockfd = sockfd;
    msg.buf = (void *)buf;
    msg.len = len;
    msg.flags = 0;
    msg.caller = xTaskGetCurrentTaskHandle();
    msg.result = -1;

    if (osMessageQueuePut(netMsgQueueHandle, &msg, 0, osWaitForever) != osOK) {
        s_net_errno = NET_ERR_BUSY;
        return -1;
    }

    ulTaskNotifyTake(pdTRUE, portMAX_DELAY);

    if (msg.result < 0) {
        s_net_errno = NET_ERR;
    }
    return msg.result;
}

/*
 * 函数功能：接收数据（线程安全版本，通过消息队列委托给 netTask）
 * 入口参数：sockfd - Socket 描述符                                                  int >= 0 && < NET_MAX_SOCKETS
 *           buf    - 接收缓冲区指针                                                  void *
 *           len    - 缓冲区大小                                                      int > 0
 *           flags  - 标志位，0=阻塞，NET_MSG_DONTWAIT=非阻塞                        int
 * 返回值：实际接收字节数                                                            int >= 0 || 0 || -1
 *         0        - 对端关闭连接                                                   int
 *         -1       - 接收失败（参数无效、队列满等）                               int
 * 限定条件：Socket 处于 ESTABLISHED 状态；net_init() + MX_FREERTOS_Init() 已执行；非 netTask 上下文
 * 函数说明：将接收请求放入消息队列，阻塞等待 netTask 处理完毕并返回结果。netTask 内请使用 net_recv_sock()
 */
int net_recv(int sockfd, void *buf, int len, int flags) {
    net_msg_t msg;

    if (sockfd < 0 || sockfd >= NET_MAX_SOCKETS) {
        s_net_errno = NET_ERR_BADF;
        return -1;
    }

    if (netMsgQueueHandle == NULL) {
        s_net_errno = NET_ERR;
        return -1;
    }

    msg.type = NET_MSG_RECV;
    msg.sockfd = sockfd;
    msg.buf = buf;
    msg.len = len;
    msg.flags = flags;
    msg.caller = xTaskGetCurrentTaskHandle();
    msg.result = -1;

    if (osMessageQueuePut(netMsgQueueHandle, &msg, 0, osWaitForever) != osOK) {
        s_net_errno = NET_ERR_BUSY;
        return -1;
    }

    ulTaskNotifyTake(pdTRUE, portMAX_DELAY);

    if (msg.result < 0) {
        s_net_errno = NET_ERR;
    }
    return msg.result;
}

/*
 * 函数功能：关闭 Socket（线程安全版本，通过消息队列委托给 netTask）
 * 入口参数：sockfd - Socket 描述符                                                  int >= 0 && < NET_MAX_SOCKETS
 * 返回值：0 - 关闭成功                                                            int
 *         -1       - 关闭失败                                                     int
 * 限定条件：Socket 已创建且处于非 CLOSED 状态；net_init() + MX_FREERTOS_Init() 已执行；非 netTask 上下文
 * 函数说明：将关闭请求放入消息队列，阻塞等待 netTask 处理完毕。TCP Socket 先断开连接再释放控制块。
 *          netTask 内请使用 net_close_sock()
 */
int net_close(int sockfd) {
    net_msg_t msg;

    if (sockfd < 0 || sockfd >= NET_MAX_SOCKETS) {
        s_net_errno = NET_ERR_BADF;
        return -1;
    }

    if (netMsgQueueHandle == NULL) {
        s_net_errno = NET_ERR;
        return -1;
    }

    msg.type = NET_MSG_CLOSE;
    msg.sockfd = sockfd;
    msg.caller = xTaskGetCurrentTaskHandle();
    msg.result = -1;

    if (osMessageQueuePut(netMsgQueueHandle, &msg, 0, osWaitForever) != osOK) {
        s_net_errno = NET_ERR_BUSY;
        return -1;
    }

    ulTaskNotifyTake(pdTRUE, portMAX_DELAY);

    if (msg.result < 0) {
        s_net_errno = NET_ERR;
    }
    return msg.result;
}
/*
 * 函数功能：发送 UDP 数据报（含目标地址）
 * 入口参数：sockfd     - Socket 描述符                                                  int >= 0 && < NET_MAX_SOCKETS
 *           buf        - 待发送数据缓冲区指针                                            const void *
 *           len        - 数据长度                                                        int > 0
 *           flags      - 标志位，通常为 0                                                int
 *           dest_addr  - 目标地址结构体指针                                              const struct net_sockaddr *
 *           addrlen    - 目标地址结构体长度                                              int >= sizeof(struct net_sockaddr_in)
 * 返回值：实际发送字节数                                                              int > 0 || -1
 *         -1          - 发送失败                                                      int
 * 限定条件：Socket 已创建且为 UDP 类型（SOCK_DGRAM）；net_init() 已调用
 */
int net_sendto(int sockfd, const void *buf, int len, int flags,
               const struct net_sockaddr *dest_addr, int addrlen) {
    net_sock_t *p_sock;
    const struct net_sockaddr_in *p_addr_in;
    int sent = 0;
    uint32_t tick_start;

    /* 参数检�?*/
    if (sockfd < 0 || sockfd >= NET_MAX_SOCKETS) {
        s_net_errno = NET_ERR_BADF;
        return -1;
    }

    p_sock = &s_net_socks[sockfd];
    if (!p_sock->in_use) {
        s_net_errno = NET_ERR_BADF;
        return -1;
    }

    if (buf == NULL || len <= 0) {
        s_net_errno = NET_ERR_INVAL;
        return -1;
    }

    /* UDP 模式：设置目标地址 */
    if (dest_addr != NULL && addrlen >= (int)sizeof(struct net_sockaddr_in)) {
        p_addr_in = (const struct net_sockaddr_in *)dest_addr;

        /* 转换 IP 为数组格�?*/
        uint8_t ip_arr[4];
        uint32_t ip = p_addr_in->sin_addr.s_addr;
        ip_arr[0] = (uint8_t)(ip);
        ip_arr[1] = (uint8_t)(ip >> 8);
        ip_arr[2] = (uint8_t)(ip >> 16);
        ip_arr[3] = (uint8_t)(ip >> 24);

        ch395f_set_des_ip(sockfd, ip_arr);
        ch395f_set_des_port(sockfd, net_ntohs(p_addr_in->sin_port));
    }

    tick_start = HAL_GetTick();

    /* 发送数�?*/
    while (sent < len) {
        int chunk = len - sent;
        if (chunk > NET_SEND_BUF_SIZE) {
            chunk = NET_SEND_BUF_SIZE;
        }

        /* 检查发送缓冲区 */
        if (!p_sock->send_ready) {
            if (NET_SEND_TIMEOUT_MS > 0 &&
                (HAL_GetTick() - tick_start) >= NET_SEND_TIMEOUT_MS) {
                s_net_errno = NET_ERR_TIMEDOUT;
                break;
            }
            net_poll();
            continue;
        }

        ch395f_write_send_buf(sockfd, (uint8_t *)buf + sent, (uint16_t)chunk);
        p_sock->send_ready = 0;
        sent += chunk;
        p_sock->send_bytes += (uint32_t)chunk;

        /* 等待发送完�?*/
        tick_start = HAL_GetTick();
        while (!p_sock->send_ready) {
            net_poll();
            if (NET_SEND_TIMEOUT_MS > 0 &&
                (HAL_GetTick() - tick_start) >= NET_SEND_TIMEOUT_MS) {
                break;
            }
        }
    }

    return sent;
}
/*
 * 函数功能：接收 UDP 数据报（含源地址）
 * 入口参数：sockfd   - Socket 描述符                                                  int >= 0 && < NET_MAX_SOCKETS
 *           buf      - 接收缓冲区指针                                                  void *
 *           len      - 缓冲区大小                                                      int > 0
 *           flags    - 标志位，通常为 0                                                int
 *           src_addr - 输出：发送方地址结构体指针                                      struct net_sockaddr *（可为 NULL）
 *           addrlen  - 输入输出：源地址长度                                            int *（可为 NULL）
 * 返回值：实际接收字节数                                                              int >= 0 || -1
 *         -1          - 接收失败                                                    int
 * 限定条件：Socket 已创建且为 UDP 类型（SOCK_DGRAM）；net_init() 已调用；有数据可用
 */
int net_recvfrom(int sockfd, void *buf, int len, int flags,
                 struct net_sockaddr *src_addr, int *addrlen) {
    net_sock_t *p_sock;
    uint16_t recv_len;
    uint32_t tick_start;

    /* 参数检�?*/
    if (sockfd < 0 || sockfd >= NET_MAX_SOCKETS) {
        s_net_errno = NET_ERR_BADF;
        return -1;
    }

    p_sock = &s_net_socks[sockfd];
    if (!p_sock->in_use) {
        s_net_errno = NET_ERR_BADF;
        return -1;
    }

    if (buf == NULL || len <= 0) {
        s_net_errno = NET_ERR_INVAL;
        return -1;
    }

    tick_start = HAL_GetTick();

    while (1) {
        net_poll();

        recv_len = ch395f_get_recv_len(sockfd);
        if (recv_len > 0) {
            /* UDP Server 模式：前 8 字节为固定格式（IP + 端口 + 长度�?*/
            if (p_sock->type == NET_SOCK_DGRAM && recv_len >= 8) {
                uint8_t header[8];
                ch395f_read_recv_buf(sockfd, header, 8);
                recv_len -= 8;

                /* 填充来源地址 */
                if (src_addr != NULL && addrlen != NULL &&
                    *addrlen >= (int)sizeof(struct net_sockaddr_in)) {
                    struct net_sockaddr_in *p_addr_in = (struct net_sockaddr_in *)src_addr;
                    p_addr_in->sin_family = NET_AF_INET;
                    /* CH395F UDP �? [0-1] reserved  [2-3] src_port(LE)  [4-7] src_ip */
                    p_addr_in->sin_port = net_htons((uint16_t)(header[2] | (header[3] << 8)));
                    p_addr_in->sin_addr.s_addr = ((uint32_t)header[4]) |
                                               ((uint32_t)header[5] << 8) |
                                               ((uint32_t)header[6] << 16) |
                                               ((uint32_t)header[7] << 24);
                    *addrlen = sizeof(struct net_sockaddr_in);
                }
            }

            /* 读取数据 */
            if (recv_len > 0) {
                int read_len = (recv_len > (uint16_t)len) ? len : (int)recv_len;
                ch395f_read_recv_buf(sockfd, (uint8_t *)buf, (uint16_t)read_len);
                p_sock->recv_bytes += (uint32_t)read_len;
                return read_len;
            }
        }

        /* 非阻塞模式检�?*/
        if (flags & NET_MSG_DONTWAIT) {
            s_net_errno = NET_ERR_WOULDBLOCK;
            return -1;
        }

        /* 超时检�?*/
        if (NET_RECV_TIMEOUT_MS > 0 &&
            (HAL_GetTick() - tick_start) >= NET_RECV_TIMEOUT_MS) {
            s_net_errno = NET_ERR_TIMEDOUT;
            return -1;
        }
    }
}

/*
 * 函数功能：发送数据（内部版本，绕过消息队列，供 netTask 直接使用）
 */
int net_send_sock(net_sock_t *p_sock, const void *buf, int len) {
    if (p_sock == NULL) {
        s_net_errno = NET_ERR_BADF;
        return -1;
    }
    return net_send_locked(p_sock, buf, len);
}
/*
 * 函数功能：接收数据（内部版本，绕过消息队列，供 netTask 直接使用）
 * 入口参数：p_sock - Socket 控制块指针                                             net_sock_t *
 *           buf    - 接收缓冲区指针                                                  void *
 *           len    - 缓冲区大小                                                      int > 0
 *           flags  - 标志位，NET_MSG_DONTWAIT=非阻塞                                 int
 * 返回值：实际接收字节数                                                            int >= 0 || 0 || -1
 *         0        - 对端关闭连接                                                   int
 *         -1       - 接收失败                                                      int
 * 限定条件：必须在 netTask 上下文中调用；p_sock->in_use == 1
 * 函数说明：直接操作 Socket 控制块，不经过消息队列。避免 netTask 向自身发送消息造成死锁
 */
int net_recv_sock(net_sock_t *p_sock, void *buf, int len, int flags) {
    if (p_sock == NULL) {
        s_net_errno = NET_ERR_BADF;
        return -1;
    }
    return net_recv_locked(p_sock, buf, len, flags);
}
/*
 * 函数功能：关闭 Socket（内部版本，绕过消息队列，供 netTask 直接使用）
 * 入口参数：p_sock - Socket 控制块指针                                             net_sock_t *
 * 返回值：0 - 关闭成功                                                            int
 *         -1       - 关闭失败                                                     int
 * 限定条件：必须在 netTask 上下文中调用；p_sock->in_use == 1
 * 函数说明：直接操作 Socket 控制块，不经过消息队列。TCP Socket 先断开连接再释放控制块
 */
int net_close_sock(net_sock_t *p_sock) {
    if (p_sock == NULL) {
        s_net_errno = NET_ERR_BADF;
        return -1;
    }
    return net_close_locked(p_sock);
}
/*
 * 函数功能：注册 Socket 事件回调函数
 * 入口参数：sockfd - Socket 描述符                                                  int >= 0 && < NET_MAX_SOCKETS
 *           cb     - 回调函数指针                                                    net_event_cb_t（可为 NULL 取消注册）
 *           arg    - 用户自定义参数指针                                              void *
 * 返回值：0 - 注册成功                                                            int
 *         -1       - 注册失败                                                     int
 * 限定条件：Socket 已创建且 in_use == 1；net_init() 已调用
 */

int net_set_event_cb(int sockfd, net_event_cb_t cb, void *arg) {
    net_sock_t *p_sock;

    /* 参数检�?*/
    if (sockfd < 0 || sockfd >= NET_MAX_SOCKETS) {
        s_net_errno = NET_ERR_BADF;
        return -1;
    }

    p_sock = &s_net_socks[sockfd];
    if (!p_sock->in_use) {
        s_net_errno = NET_ERR_BADF;
        return -1;
    }

    p_sock->event_cb = cb;
    p_sock->event_arg = arg;

    return 0;
}
/*
 * 函数功能：获取 Socket 最后一次操作返回的错误码
 * 返回值：当前错误码值（NET_OK=0, NET_ERR_xxx=-N）                                int
 * 限定条件：无
 * 函数说明：每次 net_*() API 调用失败后，错误码被设置。调用成功时不自动清零
 */

int net_get_errno(void) {
    return s_net_errno;
}

/*
 * 函数功能：将 IP 地址字符串转为网络字节序
 */
uint32_t net_inet_addr(const char *cp) {
    uint32_t addr = 0;
    uint32_t val;
    int i;

    if (cp == NULL) {
        return 0;
    }

    for (i = 0; i < 4; i++) {
        val = 0;
        while (*cp >= '0' && *cp <= '9') {
            val = val * 10 + (*cp - '0');
            cp++;
        }
        addr |= (val << (i * 8));
        if (*cp == '.') {
            cp++;
        }
    }

    return NET_htonl(addr);
}

/*
 * 函数功能：将网络字节�?IP 转为字符�? */
char *net_inet_ntoa(uint32_t addr, char *buf) {
    uint32_t naddr = NET_ntohl(addr);

    if (buf == NULL) {
        return NULL;
    }

    sprintf(buf, "%lu.%lu.%lu.%lu",
            (unsigned long)(naddr & 0xFF),
            (unsigned long)((naddr >> 8) & 0xFF),
            (unsigned long)((naddr >> 16) & 0xFF),
            (unsigned long)((naddr >> 24) & 0xFF));

    return buf;
}

/*
 * 函数功能：端口字节序转换（主机序 -> 网络序）
 */
uint16_t net_htons(uint16_t hostshort) {
    return NET_htons(hostshort);
}

/*
 * 函数功能：端口字节序转换（网络序 -> 主机序）
 */
uint16_t net_ntohs(uint16_t netshort) {
    return NET_ntohs(netshort);
}

/*
 * 函数功能：IP 地址字节序转换（主机�?-> 网络序）
 */
uint32_t net_htonl(uint32_t hostlong) {
    return NET_htonl(hostlong);
}

/*
 * 函数功能：IP 地址字节序转换（网络�?-> 主机序）
 */
uint32_t net_ntohl(uint32_t netlong) {
    return NET_ntohl(netlong);
}

/*
 * 私有函数实现�? */

/*
 * 函数功能：分配空�?Socket
 * 返回值：Socket 索引，失败返�?-1
 */
static int alloc_socket(void) {
    int i;

    for (i = 0; i < NET_MAX_SOCKETS; i++) {
        if (!s_net_socks[i].in_use) {
            return i;
        }
    }

    return -1;
}

/*
 * 函数功能：处理连接事�? */
static void handle_connect_event(net_sock_t *p_sock) {
    if (p_sock->state == NET_SOCK_STATE_LISTENING) {
        /* 多连接模式：监听 Socket 收到 CONNECT 中断 = 有新连接被分配到数据 Socket
         * Socket 0 自身保持 LISTENING，不需要改变状�?*/
        fire_event(p_sock, NET_EVENT_CONNECTED);
    }
    else if (!p_sock->in_use) {
        /* CH395F 自动打开的数�?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);
        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->in_use = 1;
        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);
    }
    else if (p_sock->state == NET_SOCK_STATE_CONNECTING) {
        /* TCP Client 连接成功 */
        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;

        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);
    }
}

/*
 * 函数功能：处理断开事件
 * 函数说明：CH395F �?DISCONNECT 中断后自动关�?Socket（默�?FUN_PARA_FLAG_SOCKET_CLOSE=0），
 *          必须重新 OPEN_SOCKET + TCP_LISTEN 才能接受新连�? */
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) {
        /* CH395F 自动关闭�?Socket，恢复为未使用状�?*/
        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 {
        /* 未预期的断开 */
        DBG_ERROR("sock%d disconnect in state %d", p_sock->ch395_sock, p_sock->state);
        fire_event(p_sock, NET_EVENT_DISCONNECTED);
    }
}

/*
 * 函数功能：处理数据接收事�? */
static void handle_recv_event(net_sock_t *p_sock) {
    uint16_t recv_len = ch395f_get_recv_len(p_sock->ch395_sock);

    if (recv_len > 0) {
        fire_event(p_sock, NET_EVENT_DATA_RECEIVED);
    }
}

/*
 * 函数功能：处理发送完成事�? */
static void handle_send_event(net_sock_t *p_sock) {
    fire_event(p_sock, NET_EVENT_SEND_COMPLETE);
}

/*
 * 函数功能：处理超时事�? * 函数说明：CH395F �?TIMEOUT 中断后同样自动关�?Socket�? *          需要重新打开并恢复监�? */
static void handle_timeout_event(net_sock_t *p_sock) {
    if (p_sock->state == NET_SOCK_STATE_CONNECTING) {
        /* 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) {
        /* 多连接模式：数据 Socket 超时，恢复为 TCP_ACCEPT 等待新连�?*/
        DBG_INFO("sock%d TIMEOUT, back to ACCEPT", 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;
    }
    else if (p_sock->state == NET_SOCK_STATE_LISTENING) {
        /* 监听超时（异常情况） */
        DBG_ERROR("sock%d LISTEN TIMEOUT", p_sock->ch395_sock);
    }

    fire_event(p_sock, NET_EVENT_TIMEOUT);
}

/*
 * 函数功能：触发事件回�? */
static void fire_event(net_sock_t *p_sock, net_event_t event) {
    if (p_sock->event_cb != NULL) {
        p_sock->event_cb(p_sock->ch395_sock, event, p_sock->event_arg);
    }
}

/*
 * 函数功能：解�?IP 地址字符串为数组
 */
static void parse_ip_string(const char *str, uint8_t *ip_arr) {
    uint32_t val;
    int i;

    if (str == NULL || ip_arr == NULL) {
        return;
    }

    for (i = 0; i < 4; i++) {
        val = 0;
        while (*str >= '0' && *str <= '9') {
            val = val * 10 + (*str - '0');
            str++;
        }
        ip_arr[i] = (uint8_t)val;
        if (*str == '.') {
            str++;
        }
    }
}

/*
 * 函数功能：获�?Socket 控制块指针（内部使用�? */
net_sock_t *net_get_sock(int sockfd) {
    if (sockfd < 0 || sockfd >= NET_MAX_SOCKETS) {
        return NULL;
    }

    if (!s_net_socks[sockfd].in_use) {
        return NULL;
    }

    return &s_net_socks[sockfd];
}
