Files
STM32F4-Base/Drivers/BSP/NET/net_socket.h

345 lines
11 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* 模块名称Network Socket API
* 模块功能BSD Socket API 兼容接口,提供 TCP/UDP 网络通信功能,
* 底层基于 CH395F 以太网协议栈芯片
* 适用平台STM32F4 系列CH395F 以太网芯片)
* 作者:王建锋
* 创建日期2026-07-18
* 修改记录:
*/
#ifndef __NET_SOCKET_H
#define __NET_SOCKET_H
#ifdef __cplusplus
extern "C" {
#endif
#include "net_types.h"
#include "FreeRTOS.h"
#include "task.h"
/*
* 消息队列类型定义
*/
typedef enum {
NET_MSG_SEND,
NET_MSG_RECV,
NET_MSG_CLOSE,
NET_MSG_CONNECT,
NET_MSG_LISTEN,
NET_MSG_ACCEPT,
} net_msg_type_t;
typedef struct {
net_msg_type_t type; /* 操作类型 */
int sockfd; /* Socket 描述符 */
void *buf; /* 数据缓冲区send/recv */
int len; /* 数据长度/缓冲区大小 */
int flags; /* 接收标志 */
TaskHandle_t caller; /* 调用方任务句柄 */
int result; /* 操作结果 */
/* 连接参数 */
struct net_sockaddr_in addr; /* 连接地址 */
int addrlen; /* 地址长度 */
} net_msg_t;
/*
* 网络初始化接口
*/
/*
* 函数功能:网络子系统初始化(配置 CH395F + 启用多连接模式)
* 入口参数ip - 本地 IP 地址字符串 "192.168.1.100"NULL 使用 DHCP
* mask - 子网掩码字符串 "255.255.255.0"NULL 使用默认
* gateway - 网关地址字符串 "192.168.1.1"NULL 使用默认
* 返回值0 成功,-1 失败
* 限定条件SPI2 已正确初始化
* 函数说明:必须在所有网络操作之前调用
*/
int net_init(const char *ip, const char *mask, const char *gateway);
/*
* 函数功能:轮询所有 Socket 状态(必须在主循环中调用)
* 返回值:有事件发生的 socket 数量
* 限定条件net_init() 已调用
* 函数说明:此函数处理所有 Socket 的中断事件,更新状态,
* 并触发事件回调。在非阻塞模式下必须定期调用。
*/
int net_poll(void);
/*
* 核心 Socket API
*/
/*
* 函数功能:创建 socket
* 入口参数domain - 地址族,仅支持 AF_INET
* type - SOCK_STREAM(TCP) 或 SOCK_DGRAM(UDP)
* protocol - 通常为 0
* 返回值socket 描述符 (0~7),失败返回 -1
* 限定条件net_init() 已调用
* 函数说明:自动分配空闲 Socket 控制块
*/
int net_socket(int domain, int type, int protocol);
/*
* 函数功能:绑定本地地址和端口
* 入口参数sockfd - socket 描述符
* addr - 本地地址结构体指针
* addrlen - 地址结构体长度
* 返回值0 成功,-1 失败
* 限定条件socket 已创建且未绑定
* 函数说明:设置 CH395F 源端口
*/
int net_bind(int sockfd, const struct net_sockaddr *addr, int addrlen);
/*
* 函数功能TCP Server 监听
* 入口参数sockfd - socket 描述符
* 返回值0 成功,-1 失败
* 限定条件socket 已绑定
* 函数说明:内部调用 ch395f_tcp_listen监听 Socket 自身即为数据通道
*/
int net_listen(int sockfd);
/*
* 函数功能TCP Server 接受连接
* 入口参数sockfd - 监听 socket 描述符
* addr - 输出:客户端地址
* addrlen - 输入输出:地址长度
* 返回值:新 socket 描述符,失败返回 -1
* 限定条件socket 正在监听
* 函数说明:在非阻塞模式下,如果没有新连接,返回 -1 并设置
* net_errno 为 NET_ERR_WOULDBLOCK
*/
int net_accept(int sockfd, struct net_sockaddr *addr, int *addrlen);
/*
* 函数功能TCP Client 发起连接
* 入口参数sockfd - socket 描述符
* addr - 服务器地址
* addrlen - 地址长度
* 返回值0 成功,-1 失败
* 限定条件socket 已创建
* 函数说明:连接过程是异步的,需要调用 net_poll() 等待连接完成,
* 或使用 select() 等待可写事件
*/
int net_connect(int sockfd, const struct net_sockaddr *addr, int addrlen);
/*
* 函数功能发送数据TCP
* 入口参数sockfd - socket 描述符
* buf - 数据缓冲区
* len - 数据长度
* flags - 通常为 0
* 返回值:实际发送字节数,失败返回 -1
* 限定条件TCP 连接已建立,指针非空
* 函数说明:阻塞等待发送缓冲区空闲,拷贝数据后触发发送
*/
int net_send(int sockfd, const void *buf, int len, int flags);
/*
* 函数功能接收数据TCP
* 入口参数sockfd - socket 描述符
* buf - 接收缓冲区
* len - 缓冲区大小
* flags - 通常为 0可设置 NET_MSG_DONTWAIT 非阻塞
* 返回值实际接收字节数0=对端关闭,-1=错误
* 限定条件TCP 连接已建立
* 函数说明:在阻塞模式下,如果没有数据,函数会等待;
* 在非阻塞模式下,如果没有数据,返回 -1 并设置
* net_errno 为 NET_ERR_WOULDBLOCK
*/
int net_recv(int sockfd, void *buf, int len, int flags);
/*
* 函数功能:发送 UDP 数据
* 入口参数sockfd - socket 描述符
* buf - 数据缓冲区
* len - 数据长度
* flags - 通常为 0
* dest_addr - 目标地址
* addrlen - 地址长度
* 返回值:实际发送字节数,失败返回 -1
* 限定条件socket 已创建,指针非空
* 函数说明:设置目标地址后调用 CH395F 发送
*/
int net_sendto(int sockfd, const void *buf, int len, int flags,
const struct net_sockaddr *dest_addr, int addrlen);
/*
* 函数功能:接收 UDP 数据
* 入口参数sockfd - socket 描述符
* buf - 接收缓冲区
* len - 缓冲区大小
* flags - 通常为 0
* src_addr - 输出:发送方地址
* addrlen - 输入输出:地址长度
* 返回值:实际接收字节数,失败返回 -1
* 限定条件socket 已创建,指针非空
* 函数说明:读取 CH395F 接收缓冲区,获取对端地址
*/
int net_recvfrom(int sockfd, void *buf, int len, int flags,
struct net_sockaddr *src_addr, int *addrlen);
/*
* 函数功能:关闭 socket
* 入口参数sockfd - socket 描述符
* 返回值0 成功,-1 失败
* 限定条件socket 已打开
* 函数说明:释放 Socket 控制块TCP 先断开连接
*/
int net_close(int sockfd);
/*
* 事件回调 API
*/
/*
* 函数功能:注册事件回调
* 入口参数sockfd - socket 描述符
* cb - 回调函数
* arg - 用户参数
* 返回值0 成功,-1 失败
* 限定条件socket 已创建
* 函数说明:回调在 net_poll 上下文中触发
*/
int net_set_event_cb(int sockfd, net_event_cb_t cb, void *arg);
/*
* 辅助函数
*/
/*
* 函数功能:获取 socket 最后错误码
* 返回值错误码NET_ERR_xxx
*/
int net_get_errno(void);
/*
* 函数功能:将 IP 地址字符串转为网络字节序
* 入口参数cp - 点分十进制字符串 "192.168.1.100"
* 返回值:网络字节序 IP失败返回 0
* 限定条件cp 指针非空
* 函数说明:不支持域名解析
*/
uint32_t net_inet_addr(const char *cp);
/*
* 函数功能:将网络字节序 IP 转为字符串
* 入口参数addr - 网络字节序 IP
* buf - 输出缓冲区(至少 16 字节)
* 返回值buf 指针
* 限定条件buf 指针非空
*/
char *net_inet_ntoa(uint32_t addr, char *buf);
/*
* 函数功能:端口字节序转换(主机序 -> 网络序)
* 入口参数hostshort - 主机序端口
* 返回值:网络序端口
* 限定条件:无
* 函数说明:小端 → 大端
*/
uint16_t net_htons(uint16_t hostshort);
/*
* 函数功能:端口字节序转换(网络序 -> 主机序)
* 入口参数netshort - 网络序端口
* 返回值:主机序端口
* 限定条件:无
* 函数说明:大端 → 小端
*/
uint16_t net_ntohs(uint16_t netshort);
/*
* 函数功能IP 地址字节序转换(主机序 -> 网络序)
* 入口参数hostlong - 主机序 IP
* 返回值:网络序 IP
* 限定条件:无
* 函数说明:小端 → 大端
*/
uint32_t net_htonl(uint32_t hostlong);
/*
* 函数功能IP 地址字节序转换(网络序 -> 主机序)
* 入口参数netlong - 网络序 IP
* 返回值:主机序 IP
* 限定条件:无
* 函数说明:大端 → 小端
*/
uint32_t net_ntohl(uint32_t netlong);
/*
* 函数功能:处理消息队列中的请求(必须在 netTask 主循环中调用)
* 限定条件net_init() 已调用
* 函数说明:处理其他任务通过 net_send/net_recv 等接口发送的请求,
* 在 netTask 上下文中串行化执行所有 CH395F 操作
*/
void net_process_messages(void);
/*
* 函数功能:获取 Socket 控制块指针(内部使用)
* 入口参数sockfd - socket 描述符
* 返回值Socket 控制块指针,失败返回 NULL
*/
net_sock_t *net_get_sock(int sockfd);
/*
* 函数功能:获取 Socket 本地地址IP + Port
* 入口参数sockfd - socket 描述符
* addr - 输出:本地地址
* addrlen - 输入输出:地址结构体长度
* 返回值0 成功,-1 失败
* 限定条件socket 已创建或已绑定
*/
int net_getsockname(int sockfd, struct net_sockaddr *addr, int *addrlen);
/*
* 内部 API需在 netTask 上下文中调用,绕过消息队列)
*/
/*
* 函数功能:发送数据(内部版本,直接操作,不经过消息队列)
* 入口参数p_sock - Socket 控制块指针
* buf - 数据缓冲区
* len - 数据长度
* 返回值:实际发送字节数,失败返回 -1
* 限定条件:必须在 netTask 上下文中调用
*/
int net_send_sock(net_sock_t *p_sock, const void *buf, int len);
/*
* 函数功能:接收数据(内部版本,直接操作,不经过消息队列)
* 入口参数p_sock - Socket 控制块指针
* buf - 接收缓冲区
* len - 缓冲区大小
* flags - 通常为 0可设置 NET_MSG_DONTWAIT
* 返回值实际接收字节数0=对端关闭,-1=错误
* 限定条件:必须在 netTask 上下文中调用
*/
int net_recv_sock(net_sock_t *p_sock, void *buf, int len, int flags);
/*
* 函数功能:关闭 socket内部版本直接操作不经过消息队列
* 入口参数p_sock - Socket 控制块指针
* 返回值0 成功,-1 失败
* 限定条件:必须在 netTask 上下文中调用
*/
int net_close_sock(net_sock_t *p_sock);
/*
* 函数功能:启动 TCP Server 监听(内部版本,直接操作,不经过消息队列)
* 入口参数sockfd - Socket 描述符
* 返回值0 成功,-1 失败
* 限定条件:必须在 netTask 上下文中调用
*/
int net_listen_locked(int sockfd);
#ifdef __cplusplus
}
#endif
#endif /* __NET_SOCKET_H */