网络协议栈接入方式
网络协议栈或网络功能实现的接入,主要是对协议簇结构体的初始化和注册处理,并且添加到 SAL 组件中协议簇列表中,协议簇结构体定义如下:
- struct proto_family
- {
- int family; /* primary protocol families type*/
- int sec_family; /* secondary protocol families type*/
- int (*create)(struct socket *socket, int type, int protocol); /* register socket options */
- struct hostent* (*gethostbyname) (const char *name);
- int (*gethostbyname_r)(const char *name, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop);
- void (*freeaddrinfo) (struct addrinfo *ai);
- int (*getaddrinfo) (const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res);
- };
- family: 每个协议栈支持的主协议簇类型,例如 lwIP 的为 AF_INET ,AT Socket 为 AF_AT。
- sec_family:每个协议栈支持的次协议簇类型,用于支持单个协议栈或网络实现时,匹配软件包中其他类型的协议簇类型。
- create: 主要是对 socket 相关执行函数的注册,例如 connect、close 等函数的,将当前协议栈的执行函数注册进创建的 SAL 组件中 socket 结构体中。
- 其他函数: 为套接字无关执行函数,用于匹配每个协议栈或网络实现中的执行函数。
以下为 AT Socket 网络实现的接入注册流程,开发者可参考实现其他的协议栈或网络实现的接入:
- #include <netdb.h>
- #include <sal.h> /* SAL 组件结构体存放头文件 */
- #include <at_socket.h> /* AT Socket 相关头文件 */
- #ifdef RT_USING_DFS_NET
- #include <dfs_poll.h> /* poll 函数实现相关头文件 */
- #endif
- #ifdef RT_USING_DFS_NET
- /* 自定义的 poll 执行函数,用于 poll 中处理接收的事件 */
- static int at_poll(struct dfs_fd *file, struct rt_pollreq *req)
- {
- int mask = 0;
- struct at_socket *sock;
- struct socket *sal_sock;
- sal_sock = sal_get_socket((int) file->data);
- if(!sal_sock)
- {
- return -1;
- }
- sock = at_get_socket((int)sal_sock->user_data);
- if (sock != NULL)
- {
- rt_base_t level;
- rt_poll_add(&sock->wait_head, req);
- level = rt_hw_interrupt_disable();
- if (sock->rcvevent)
- {
- mask |= POLLIN;
- }
- if (sock->sendevent)
- {
- mask |= POLLOUT;
- }
- if (sock->errevent)
- {
- mask |= POLLERR;
- }
- rt_hw_interrupt_enable(level);
- }
- return mask;
- }
- #endif
- /* 定义和赋值 Socket 执行函数,每个创建的新 Socket 套接字存在该执行函数存放与 Socket 结构体中,当执行相关函数是调用 */
- static const struct proto_ops at_inet_stream_ops =
- {
- at_socket,
- at_closesocket,
- at_bind,
- NULL,
- at_connect,
- NULL,
- at_sendto,
- at_recvfrom,
- at_getsockopt,
- at_setsockopt,
- at_shutdown,
- NULL,
- NULL,
- NULL,
- #ifdef SAL_USING_POSIX
- at_poll,
- #else
- NULL,
- #endif /* SAL_USING_POSIX */
- };
- static int at_create(struct socket *socket, int type, int protocol)
- {
- RT_ASSERT(socket);
- /* 协议簇结构体中 create 函数的实现,用于注册上面定义的 ops 执行函数到 socket 结构体中 */
- socket->ops = &at_inet_stream_ops;
- return 0;
- }
- static const struct proto_family at_inet_family_ops = {
- AF_AT,
- AF_INET,
- at_create,
- /* Socket 套接字无关函数,由协议簇结构体注册 */
- at_gethostbyname,
- NULL,
- at_freeaddrinfo,
- at_getaddrinfo,
- };
- int at_inet_init(void)
- {
- /* 注册协议簇结构体到协议簇列表,开发者通过 socket 函数传入的 family 类型匹配对应使用的协议簇类型 */
- sal_proto_family_register(&at_inet_family_ops);
- return 0;
- }
- /* 自动初始化函数 */
- INIT_COMPONENT_EXPORT(at_inet_init);