diff options
Diffstat (limited to 'components/net/sal/impl')
| -rw-r--r-- | components/net/sal/impl/af_inet.h | 38 | ||||
| -rw-r--r-- | components/net/sal/impl/af_inet_at.c | 114 | ||||
| -rw-r--r-- | components/net/sal/impl/af_inet_lwip.c | 337 | ||||
| -rw-r--r-- | components/net/sal/impl/af_inet_winsock.c | 12 | ||||
| -rw-r--r-- | components/net/sal/impl/proto_mbedtls.c | 249 |
5 files changed, 750 insertions, 0 deletions
diff --git a/components/net/sal/impl/af_inet.h b/components/net/sal/impl/af_inet.h new file mode 100644 index 0000000000..421d15bfae --- /dev/null +++ b/components/net/sal/impl/af_inet.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-08-25 ChenYong First version + */ + +#ifndef __AF_INET_H__ +#define __AF_INET_H__ + +#include <rtthread.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef SAL_USING_LWIP + +/* Set lwIP network interface device protocol family information */ +int sal_lwip_netdev_set_pf_info(struct netdev *netdev); + +#endif /* SAL_USING_LWIP */ + +#ifdef SAL_USING_AT + +/* Set AT network interface device protocol family information */ +int sal_at_netdev_set_pf_info(struct netdev *netdev); + +#endif /* SAL_USING_AT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __AF_INET_H__ */ diff --git a/components/net/sal/impl/af_inet_at.c b/components/net/sal/impl/af_inet_at.c new file mode 100644 index 0000000000..07dff0018c --- /dev/null +++ b/components/net/sal/impl/af_inet_at.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-06-06 ChenYong First version + */ + +#include <rtthread.h> + +#include <netdb.h> +#include <sal.h> + +#include <at_socket.h> +#include <af_inet.h> + +#include <netdev.h> + +#ifdef SAL_USING_POSIX +#include <poll.h> +#endif + +#ifdef SAL_USING_AT + +#ifdef SAL_USING_POSIX +static int at_poll(struct dfs_fd *file, struct rt_pollreq *req) +{ + int mask = 0; + struct at_socket *sock; + struct sal_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 + +static const struct sal_socket_ops at_socket_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, +#endif /* SAL_USING_POSIX */ +}; + +static const struct sal_netdb_ops at_netdb_ops = +{ + at_gethostbyname, + NULL, + at_getaddrinfo, + at_freeaddrinfo, +}; + +static const struct sal_proto_family at_inet_family = +{ + AF_AT, + AF_INET, + &at_socket_ops, + &at_netdb_ops, +}; + + +/* Set AT network interface device protocol family information */ +int sal_at_netdev_set_pf_info(struct netdev *netdev) +{ + RT_ASSERT(netdev); + + netdev->sal_user_data = (void *) &at_inet_family; + return 0; +} + +#endif /* SAL_USING_AT */ diff --git a/components/net/sal/impl/af_inet_lwip.c b/components/net/sal/impl/af_inet_lwip.c new file mode 100644 index 0000000000..2cf0958ee4 --- /dev/null +++ b/components/net/sal/impl/af_inet_lwip.c @@ -0,0 +1,337 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-05-17 ChenYong First version + */ + +#include <rtthread.h> + +#include <lwip/sockets.h> +#include <lwip/netdb.h> +#include <lwip/api.h> +#include <lwip/init.h> +#include <lwip/netif.h> + +#ifdef SAL_USING_POSIX +#include <poll.h> +#endif + +#include <sal.h> +#include <af_inet.h> + +#include <netdev.h> + +#if (LWIP_VERSION < 0x2000000) && NETDEV_IPV6 +#error "The lwIP version is not support IPV6, please disable netdev IPV6 configuration " +#elif (LWIP_VERSION > 0x2000000) && (NETDEV_IPV6 != LWIP_IPV6) +#error "IPV6 configuration error, Please check and synchronize netdev and lwip IPV6 configuration." +#endif + +#if LWIP_VERSION < 0x2000000 +#define SELWAIT_T int +#else +#ifndef SELWAIT_T +#define SELWAIT_T u8_t +#endif +#endif + +#ifdef SAL_USING_LWIP + +#ifdef SAL_USING_POSIX + +#if LWIP_VERSION >= 0x20100ff +#include <lwip/priv/sockets_priv.h> +#else /* LWIP_VERSION < 0x20100ff */ +/* + * Re-define lwip socket + * + * NOTE: please make sure the definitions same in lwip::net_socket.c + */ +struct lwip_sock { + /** sockets currently are built on netconns, each socket has one netconn */ + struct netconn *conn; + /** data that was left from the previous read */ + void *lastdata; + /** offset in the data that was left from the previous read */ + u16_t lastoffset; + /** number of times data was received, set by event_callback(), + tested by the receive and select functions */ + s16_t rcvevent; + /** number of times data was ACKed (free send buffer), set by event_callback(), + tested by select */ + u16_t sendevent; + /** error happened for this socket, set by event_callback(), tested by select */ + u16_t errevent; + /** last error that occurred on this socket */ +#if LWIP_VERSION < 0x2000000 + int err; +#else + u8_t err; +#endif + /** counter of how many threads are waiting for this socket using select */ + SELWAIT_T select_waiting; + + rt_wqueue_t wait_head; +}; +#endif /* LWIP_VERSION >= 0x20100ff */ + +extern struct lwip_sock *lwip_tryget_socket(int s); + +static void event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len) +{ + int s; + struct lwip_sock *sock; + uint32_t event = 0; + SYS_ARCH_DECL_PROTECT(lev); + + LWIP_UNUSED_ARG(len); + + /* Get socket */ + if (conn) + { + s = conn->socket; + if (s < 0) + { + /* Data comes in right away after an accept, even though + * the server task might not have created a new socket yet. + * Just count down (or up) if that's the case and we + * will use the data later. Note that only receive events + * can happen before the new socket is set up. */ + SYS_ARCH_PROTECT(lev); + if (conn->socket < 0) + { + if (evt == NETCONN_EVT_RCVPLUS) + { + conn->socket--; + } + SYS_ARCH_UNPROTECT(lev); + return; + } + s = conn->socket; + SYS_ARCH_UNPROTECT(lev); + } + + sock = lwip_tryget_socket(s); + if (!sock) + { + return; + } + } + else + { + return; + } + + SYS_ARCH_PROTECT(lev); + /* Set event as required */ + switch (evt) + { + case NETCONN_EVT_RCVPLUS: + sock->rcvevent++; + break; + case NETCONN_EVT_RCVMINUS: + sock->rcvevent--; + break; + case NETCONN_EVT_SENDPLUS: + sock->sendevent = 1; + break; + case NETCONN_EVT_SENDMINUS: + sock->sendevent = 0; + break; + case NETCONN_EVT_ERROR: + sock->errevent = 1; + break; + default: + LWIP_ASSERT("unknown event", 0); + break; + } + +#if LWIP_VERSION >= 0x20100ff + if ((void*)(sock->lastdata.pbuf) || (sock->rcvevent > 0)) +#else + if ((void*)(sock->lastdata) || (sock->rcvevent > 0)) +#endif + event |= POLLIN; + if (sock->sendevent) + event |= POLLOUT; + if (sock->errevent) + event |= POLLERR; + + SYS_ARCH_UNPROTECT(lev); + + if (event) + { + rt_wqueue_wakeup(&sock->wait_head, (void*) event); + } +} +#endif /* SAL_USING_POSIX */ + +static int inet_socket(int domain, int type, int protocol) +{ +#ifdef SAL_USING_POSIX + int socket; + + socket = lwip_socket(domain, type, protocol); + if (socket >= 0) + { + struct lwip_sock *lwsock; + + lwsock = lwip_tryget_socket(socket); + lwsock->conn->callback = event_callback; + + rt_wqueue_init(&lwsock->wait_head); + } + + return socket; +#else + return lwip_socket(domain, type, protocol); +#endif /* SAL_USING_POSIX */ +} + +static int inet_accept(int socket, struct sockaddr *addr, socklen_t *addrlen) +{ +#ifdef SAL_USING_POSIX + int new_socket; + + new_socket = lwip_accept(socket, addr, addrlen); + if (new_socket >= 0) + { + struct lwip_sock *lwsock; + + lwsock = lwip_tryget_socket(new_socket); + + rt_wqueue_init(&lwsock->wait_head); + } + + return new_socket; +#else + return lwip_accept(socket, addr, addrlen); +#endif /* SAL_USING_POSIX */ +} + +static int inet_getsockname(int socket, struct sockaddr *name, socklen_t *namelen) +{ +#if LWIP_VERSION_MAJOR < 2U + rt_kprintf("ERROR: Your lwIP version is not supported. Please using lwIP 2.0.0+.\n"); + RT_ASSERT(LWIP_VERSION_MAJOR >= 2U); +#endif + + return lwip_getsockname(socket, name, namelen); +} + +int inet_ioctlsocket(int socket, long cmd, void *arg) +{ + switch (cmd) + { + case F_GETFL: + case F_SETFL: + return lwip_fcntl(socket, cmd, (int) arg); + + default: + return lwip_ioctl(socket, cmd, arg); + } +} + +#ifdef SAL_USING_POSIX +static int inet_poll(struct dfs_fd *file, struct rt_pollreq *req) +{ + int mask = 0; + struct lwip_sock *sock; + struct sal_socket *sal_sock; + + sal_sock = sal_get_socket((int) file->data); + if(!sal_sock) + { + return -1; + } + + sock = lwip_tryget_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 LWIP_VERSION >= 0x20100ff + if ((void*)(sock->lastdata.pbuf) || sock->rcvevent) +#else + if ((void*)(sock->lastdata) || sock->rcvevent) +#endif + { + mask |= POLLIN; + } + if (sock->sendevent) + { + mask |= POLLOUT; + } + if (sock->errevent) + { + mask |= POLLERR; + /* clean error event */ + sock->errevent = 0; + } + rt_hw_interrupt_enable(level); + } + + return mask; +} +#endif + +static const struct sal_socket_ops lwip_socket_ops = +{ + inet_socket, + lwip_close, + lwip_bind, + lwip_listen, + lwip_connect, + inet_accept, + (int (*)(int, const void *, size_t, int, const struct sockaddr *, socklen_t))lwip_sendto, + (int (*)(int, void *, size_t, int, struct sockaddr *, socklen_t *))lwip_recvfrom, + lwip_getsockopt, + //TODO fix on 1.4.1 + lwip_setsockopt, + lwip_shutdown, + lwip_getpeername, + inet_getsockname, + inet_ioctlsocket, +#ifdef SAL_USING_POSIX + inet_poll, +#endif +}; + +static const struct sal_netdb_ops lwip_netdb_ops = +{ + lwip_gethostbyname, + lwip_gethostbyname_r, + lwip_getaddrinfo, + lwip_freeaddrinfo, +}; + +static const struct sal_proto_family lwip_inet_family = +{ + AF_INET, +#if LWIP_VERSION > 0x2000000 + AF_INET6, +#else + AF_INET, +#endif + &lwip_socket_ops, + &lwip_netdb_ops, +}; + +/* Set lwIP network interface device protocol family information */ +int sal_lwip_netdev_set_pf_info(struct netdev *netdev) +{ + RT_ASSERT(netdev); + + netdev->sal_user_data = (void *) &lwip_inet_family; + return 0; +} + +#endif /* SAL_USING_LWIP */ diff --git a/components/net/sal/impl/af_inet_winsock.c b/components/net/sal/impl/af_inet_winsock.c new file mode 100644 index 0000000000..f3f103d0ca --- /dev/null +++ b/components/net/sal/impl/af_inet_winsock.c @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ + +#include <winsock.h> + +/* Do NOT include sys/time.h in this file */ diff --git a/components/net/sal/impl/proto_mbedtls.c b/components/net/sal/impl/proto_mbedtls.c new file mode 100644 index 0000000000..338792c948 --- /dev/null +++ b/components/net/sal/impl/proto_mbedtls.c @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-11-12 ChenYong First version + */ + +#include <rtthread.h> + +#ifdef RT_USING_DFS +#include <unistd.h> +#include <sys/stat.h> +#include <sys/statfs.h> +#endif + +#ifdef SAL_USING_TLS +#include <sal_tls.h> +#endif +#include <netdb.h> +#include <sal.h> + +#include <netdev.h> + +#ifdef SAL_USING_TLS + +#if !defined(MBEDTLS_CONFIG_FILE) +#include <mbedtls/config.h> +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include <tls_certificate.h> +#include <tls_client.h> + +#ifndef SAL_MEBDTLS_BUFFER_LEN +#define SAL_MEBDTLS_BUFFER_LEN 1024 +#endif + +static void *mebdtls_socket(int socket) +{ + MbedTLSSession *session = RT_NULL; + char *pers = "mbedtls"; + + if (socket < 0) + { + return RT_NULL; + } + + session = (MbedTLSSession *) tls_calloc(1, sizeof(MbedTLSSession)); + if (session == RT_NULL) + { + return RT_NULL; + } + + session->buffer_len = SAL_MEBDTLS_BUFFER_LEN; + session->buffer = tls_calloc(1, session->buffer_len); + if (session->buffer == RT_NULL) + { + tls_free(session); + session = RT_NULL; + + return RT_NULL; + } + + /* initialize TLS Client sesison */ + if (mbedtls_client_init(session, (void *) pers, rt_strlen(pers)) != RT_EOK) + { + mbedtls_client_close(session); + return RT_NULL; + } + session->server_fd.fd = socket; + + return (void *)session; +} + +int mbedtls_net_send_cb(void *ctx, const unsigned char *buf, size_t len) +{ + struct sal_socket *sock; + int socket, ret; + struct sal_proto_family *pf; + + RT_ASSERT(ctx); + RT_ASSERT(buf); + + socket = ((mbedtls_net_context *) ctx)->fd; + sock = sal_get_socket(socket); + if (sock == RT_NULL) + { + return -1; + } + + pf = (struct sal_proto_family *)sock->netdev->sal_user_data; + + /* Register scoket sendto option to TLS send data callback */ + ret = pf->skt_ops->sendto((int) sock->user_data, (void *)buf, len, 0, RT_NULL, RT_NULL); + if (ret < 0) + { +#ifdef RT_USING_DFS + if ((fcntl(socket, F_GETFL) & O_NONBLOCK) == O_NONBLOCK) + return MBEDTLS_ERR_SSL_WANT_WRITE; +#endif + if (errno == ECONNRESET) + return MBEDTLS_ERR_NET_CONN_RESET; + if ( errno == EINTR) + return MBEDTLS_ERR_SSL_WANT_READ; + + return MBEDTLS_ERR_NET_SEND_FAILED ; + } + + return ret; +} + +int mbedtls_net_recv_cb( void *ctx, unsigned char *buf, size_t len) +{ + struct sal_socket *sock; + struct sal_proto_family *pf; + int socket, ret; + + RT_ASSERT(ctx); + RT_ASSERT(buf); + + socket = ((mbedtls_net_context *) ctx)->fd; + sock = sal_get_socket(socket); + if (sock == RT_NULL) + { + return -1; + } + + pf = (struct sal_proto_family *)sock->netdev->sal_user_data; + + /* Register scoket recvfrom option to TLS recv data callback */ + ret = pf->skt_ops->recvfrom((int) sock->user_data, (void *)buf, len, 0, RT_NULL, RT_NULL); + if (ret < 0) + { +#ifdef RT_USING_DFS + if ((fcntl(socket, F_GETFL) & O_NONBLOCK) == O_NONBLOCK) + return MBEDTLS_ERR_SSL_WANT_WRITE; +#endif + if (errno == ECONNRESET) + return MBEDTLS_ERR_NET_CONN_RESET; + if ( errno == EINTR) + return MBEDTLS_ERR_SSL_WANT_READ; + + return MBEDTLS_ERR_NET_RECV_FAILED ; + } + + return ret; +} + +static int mbedtls_connect(void *sock) +{ + MbedTLSSession *session = RT_NULL; + int ret = 0; + + RT_ASSERT(sock); + + session = (MbedTLSSession *) sock; + + /* Set the SSL Configure infromation */ + ret = mbedtls_client_context(session); + if (ret < 0) + { + goto __exit; + } + + /* Set the underlying BIO callbacks for write, read and read-with-timeout. */ + mbedtls_ssl_set_bio(&session->ssl, &session->server_fd, mbedtls_net_send_cb, mbedtls_net_recv_cb, RT_NULL); + + while ((ret = mbedtls_ssl_handshake(&session->ssl)) != 0) + { + if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) + { + goto __exit; + } + } + + /* Return the result of the certificate verification */ + ret = mbedtls_ssl_get_verify_result(&session->ssl); + if (ret != 0) + { + rt_memset(session->buffer, 0x00, session->buffer_len); + mbedtls_x509_crt_verify_info((char *)session->buffer, session->buffer_len, " ! ", ret); + goto __exit; + } + + return ret; + +__exit: + if (session) + { + mbedtls_client_close(session); + } + + return ret; +} + +static int mbedtls_closesocket(void *sock) +{ + struct sal_socket *ssock; + int socket; + + if (sock == RT_NULL) + { + return 0; + } + + socket = ((MbedTLSSession *) sock)->server_fd.fd; + ssock = sal_get_socket(socket); + if (ssock == RT_NULL) + { + return -1; + } + + /* Close TLS client session, and clean user-data in SAL socket */ + mbedtls_client_close((MbedTLSSession *) sock); + ssock->user_data_tls = RT_NULL; + + return 0; +} + +static const struct sal_proto_tls_ops mbedtls_proto_ops= +{ + RT_NULL, + mebdtls_socket, + mbedtls_connect, + (int (*)(void *sock, const void *data, size_t size)) mbedtls_client_write, + (int (*)(void *sock, void *mem, size_t len)) mbedtls_client_read, + mbedtls_closesocket, +}; + +static const struct sal_proto_tls mbedtls_proto = +{ + "mbedtls", + &mbedtls_proto_ops, +}; + +int sal_mbedtls_proto_init(void) +{ + /* register MbedTLS protocol options to SAL */ + sal_proto_tls_register(&mbedtls_proto); + + return 0; +} +INIT_COMPONENT_EXPORT(sal_mbedtls_proto_init); + +#endif /* SAL_USING_TLS */ |
