init project

Signed-off-by: a1012112796 <1012112796@qq.com>
This commit is contained in:
2022-09-26 15:31:48 +08:00
commit 02210074ec
2260 changed files with 1056951 additions and 0 deletions
+42
View File
@@ -0,0 +1,42 @@
menuconfig RT_USING_SAL
bool "SAL: socket abstraction layer"
select RT_USING_NETDEV
select RT_USING_SYSTEM_WORKQUEUE
default n
if RT_USING_SAL
config SAL_INTERNET_CHECK
bool "Enable the ability that check internet status"
default y
help
The ability that check internet status is provided by RT-Thread.
menu "Docking with protocol stacks"
config SAL_USING_LWIP
bool "Docking with lwIP stack"
default n
config SAL_USING_AT
bool "Docking with AT commands stack"
default n
config SAL_USING_TLS
bool "Docking with MbedTLS protocol"
default n
endmenu
config SAL_USING_POSIX
bool
depends on DFS_USING_POSIX
default y
help
Enable BSD socket operated by file system API
Let BSD socket operated by file system API, such as read/write and involveed in select/poll POSIX APIs.
config SAL_SOCKETS_NUM
int "the maximum number of sockets"
depends on !SAL_USING_POSIX
default 16
endif
+35
View File
@@ -0,0 +1,35 @@
# RT-Thread building script for component
from building import *
cwd = GetCurrentDir()
src = Glob('src/*.c')
src += ['socket/net_netdb.c']
CPPPATH = [cwd + '/include']
CPPPATH += [cwd + '/include/socket']
if GetDepend('SAL_USING_LWIP') or GetDepend('SAL_USING_AT'):
CPPPATH += [cwd + '/impl']
if GetDepend('SAL_USING_LWIP'):
src += ['impl/af_inet_lwip.c']
if GetDepend('SAL_USING_AT'):
src += ['impl/af_inet_at.c']
if GetDepend('SAL_USING_TLS'):
src += ['impl/proto_mbedtls.c']
if GetDepend('SAL_USING_POSIX'):
CPPPATH += [cwd + '/include/dfs_net']
src += ['socket/net_sockets.c']
src += Glob('dfs_net/*.c')
if not GetDepend('HAVE_SYS_SOCKET_H'):
CPPPATH += [cwd + '/include/socket/sys_socket']
group = DefineGroup('SAL', src, depend = ['RT_USING_SAL'], CPPPATH = CPPPATH)
Return('group')
@@ -0,0 +1,87 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2015-02-17 Bernard First version
* 2016-05-07 Bernard Rename dfs_lwip to dfs_net
* 2018-03-09 Bernard Fix the last data issue in poll.
* 2018-05-24 ChenYong Add socket abstraction layer
*/
#include <rtthread.h>
#include <dfs.h>
#include <dfs_net.h>
#include <sys/socket.h>
int dfs_net_getsocket(int fd)
{
int socket;
struct dfs_fd *_dfs_fd;
_dfs_fd = fd_get(fd);
if (_dfs_fd == NULL) return -1;
if (_dfs_fd->type != FT_SOCKET) socket = -1;
else socket = (int)_dfs_fd->data;
fd_put(_dfs_fd); /* put this dfs fd */
return socket;
}
static int dfs_net_ioctl(struct dfs_fd* file, int cmd, void* args)
{
int socket = (int) file->data;
return sal_ioctlsocket(socket, cmd, args);
}
static int dfs_net_read(struct dfs_fd* file, void *buf, size_t count)
{
int socket = (int) file->data;
return sal_recvfrom(socket, buf, count, 0, NULL, NULL);
}
static int dfs_net_write(struct dfs_fd *file, const void *buf, size_t count)
{
int socket = (int) file->data;
return sal_sendto(socket, buf, count, 0, NULL, 0);
}
static int dfs_net_close(struct dfs_fd* file)
{
int socket = (int) file->data;
return sal_closesocket(socket);
}
static int dfs_net_poll(struct dfs_fd *file, struct rt_pollreq *req)
{
extern int sal_poll(struct dfs_fd *file, struct rt_pollreq *req);
return sal_poll(file, req);
}
const struct dfs_file_ops _net_fops =
{
NULL, /* open */
dfs_net_close,
dfs_net_ioctl,
dfs_net_read,
dfs_net_write,
NULL,
NULL, /* lseek */
NULL, /* getdents */
dfs_net_poll,
};
const struct dfs_file_ops *dfs_net_get_fops(void)
{
return &_net_fops;
}
@@ -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__ */
@@ -0,0 +1,122 @@
/*
* 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_low_lvl.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,
#ifdef AT_USING_SOCKET_SERVER
at_listen,
#else
NULL,
#endif
at_connect,
#ifdef AT_USING_SOCKET_SERVER
at_accept,
#else
NULL,
#endif
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 */
@@ -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_low_lvl.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 */
@@ -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_low_lvl.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 */
@@ -0,0 +1,29 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2015-02-17 Bernard First version
* 2016-05-05 Bernard rename dfs_lwip to dfs_net.
*/
#ifndef DFS_NET_H__
#define DFS_NET_H__
#include <dfs_file.h>
#ifdef __cplusplus
extern "C" {
#endif
const struct dfs_file_ops* dfs_net_get_fops(void);
int dfs_net_getsocket(int fd);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,116 @@
/*
* 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
* 2022-05-15 Meco Man rename sal.h as sal_low_lvl.h to avoid conflicts
* with Microsoft Visual Studio header file
*/
#ifndef SAL_LOW_LEVEL_H__
#define SAL_LOW_LEVEL_H__
#include <rtdevice.h>
#ifdef SAL_USING_POSIX
#include <dfs_file.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(socklen_t) && !defined(SOCKLEN_T_DEFINED)
typedef uint32_t socklen_t;
#endif
/* SAL socket magic word */
#define SAL_SOCKET_MAGIC 0x5A10
/* The maximum number of sockets structure */
#ifndef SAL_SOCKETS_NUM
#define SAL_SOCKETS_NUM DFS_FD_MAX
#endif
/* The maximum number of protocol families */
#ifndef SAL_PROTO_FAMILIES_NUM
#define SAL_PROTO_FAMILIES_NUM 4
#endif
/* SAL socket offset */
#ifndef SAL_SOCKET_OFFSET
#define SAL_SOCKET_OFFSET 0
#endif
struct sal_socket
{
uint32_t magic; /* SAL socket magic word */
int socket; /* SAL socket descriptor */
int domain;
int type;
int protocol;
struct netdev *netdev; /* SAL network interface device */
void *user_data; /* user-specific data */
#ifdef SAL_USING_TLS
void *user_data_tls; /* user-specific TLS data */
#endif
};
/* network interface socket opreations */
struct sal_socket_ops
{
int (*socket) (int domain, int type, int protocol);
int (*closesocket)(int s);
int (*bind) (int s, const struct sockaddr *name, socklen_t namelen);
int (*listen) (int s, int backlog);
int (*connect) (int s, const struct sockaddr *name, socklen_t namelen);
int (*accept) (int s, struct sockaddr *addr, socklen_t *addrlen);
int (*sendto) (int s, const void *data, size_t size, int flags, const struct sockaddr *to, socklen_t tolen);
int (*recvfrom) (int s, void *mem, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen);
int (*getsockopt) (int s, int level, int optname, void *optval, socklen_t *optlen);
int (*setsockopt) (int s, int level, int optname, const void *optval, socklen_t optlen);
int (*shutdown) (int s, int how);
int (*getpeername)(int s, struct sockaddr *name, socklen_t *namelen);
int (*getsockname)(int s, struct sockaddr *name, socklen_t *namelen);
int (*ioctlsocket)(int s, long cmd, void *arg);
#ifdef SAL_USING_POSIX
int (*poll) (struct dfs_fd *file, struct rt_pollreq *req);
#endif
};
/* sal network database name resolving */
struct sal_netdb_ops
{
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);
int (*getaddrinfo) (const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res);
void (*freeaddrinfo) (struct addrinfo *ai);
};
struct sal_proto_family
{
int family; /* primary protocol families type */
int sec_family; /* secondary protocol families type */
const struct sal_socket_ops *skt_ops; /* socket opreations */
const struct sal_netdb_ops *netdb_ops; /* network database opreations */
};
/* SAL(Socket Abstraction Layer) initialize */
int sal_init(void);
/* Get SAL socket object by socket descriptor */
struct sal_socket *sal_get_socket(int sock);
/* check SAL socket netweork interface device internet status */
int sal_check_netdev_internet_up(struct netdev *netdev);
#ifdef __cplusplus
}
#endif
#endif /* SAL_H__ */
@@ -0,0 +1,86 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-05-24 ChenYong First version
*/
#ifndef SAL_NETDB_H__
#define SAL_NETDB_H__
#include <stddef.h>
#include "sal_socket.h"
#ifdef __cplusplus
extern "C" {
#endif
#define EAI_NONAME 200
#define EAI_SERVICE 201
#define EAI_FAIL 202
#define EAI_MEMORY 203
#define EAI_FAMILY 204
#define HOST_NOT_FOUND 210
#define NO_DATA 211
#define NO_RECOVERY 212
#define TRY_AGAIN 213
#define AI_PASSIVE 0x01
#define AI_CANONNAME 0x02
#define AI_NUMERICHOST 0x04
#define AI_NUMERICSERV 0x08
#define AI_V4MAPPED 0x10
#define AI_ALL 0x20
#define AI_ADDRCONFIG 0x40
/* input flags for structure addrinfo */
#define AI_PASSIVE 0x01
#define AI_CANONNAME 0x02
#define AI_NUMERICHOST 0x04
#define AI_NUMERICSERV 0x08
#define AI_V4MAPPED 0x10
#define AI_ALL 0x20
#define AI_ADDRCONFIG 0x40
#define DNS_MAX_NAME_LENGTH 256
struct hostent {
char *h_name; /* Official name of the host. */
char **h_aliases; /* A pointer to an array of pointers to alternative host names,
terminated by a null pointer. */
int h_addrtype; /* Address type. */
int h_length; /* The length, in bytes, of the address. */
char **h_addr_list; /* A pointer to an array of pointers to network addresses (in
network byte order) for the host, terminated by a null pointer. */
#define h_addr h_addr_list[0] /* for backward compatibility */
};
struct addrinfo {
int ai_flags; /* Input flags. */
int ai_family; /* Address family of socket. */
int ai_socktype; /* Socket type. */
int ai_protocol; /* Protocol of socket. */
socklen_t ai_addrlen; /* Length of socket address. */
struct sockaddr *ai_addr; /* Socket address of socket. */
char *ai_canonname; /* Canonical name of service location. */
struct addrinfo *ai_next; /* Pointer to next in list. */
};
struct hostent *sal_gethostbyname(const char *name);
int sal_gethostbyname_r(const char *name, struct hostent *ret, char *buf,
size_t buflen, struct hostent **result, int *h_errnop);
void sal_freeaddrinfo(struct addrinfo *ai);
int sal_getaddrinfo(const char *nodename,
const char *servname,
const struct addrinfo *hints,
struct addrinfo **res);
#ifdef __cplusplus
}
#endif
#endif /* SAL_NETDB_H__ */
@@ -0,0 +1,218 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-05-24 ChenYong First version
*/
#ifndef SAL_SOCKET_H__
#define SAL_SOCKET_H__
#include <stddef.h>
#include <arpa/inet.h>
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(socklen_t) && !defined(SOCKLEN_T_DEFINED)
typedef uint32_t socklen_t;
#endif
#if !defined(sa_family_t) && !defined(SA_FAMILY_T_DEFINED)
typedef uint8_t sa_family_t;
#endif
/* If your port already typedef's in_port_t, define IN_PORT_T_DEFINED
to prevent this code from redefining it. */
#if !defined(in_port_t) && !defined(IN_PORT_T_DEFINED)
typedef uint16_t in_port_t;
#endif
/* Socket protocol types (TCP/UDP/RAW) */
#define SOCK_STREAM 1
#define SOCK_DGRAM 2
#define SOCK_RAW 3
#define SOCK_MAX (SOCK_RAW + 1)
/* Option flags per-socket. These must match the SOF_ flags in ip.h (checked in init.c) */
#define SO_REUSEADDR 0x0004 /* Allow local address reuse */
#define SO_KEEPALIVE 0x0008 /* keep connections alive */
#define SO_BROADCAST 0x0020 /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */
/* Additional options, not kept in so_options */
#define SO_DEBUG 0x0001 /* Unimplemented: turn on debugging info recording */
#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
#define SO_DONTROUTE 0x0010 /* Unimplemented: just use interface addresses */
#define SO_USELOOPBACK 0x0040 /* Unimplemented: bypass hardware when possible */
#define SO_LINGER 0x0080 /* linger on close if data present */
#define SO_DONTLINGER ((int)(~SO_LINGER))
#define SO_OOBINLINE 0x0100 /* Unimplemented: leave received OOB data in line */
#define SO_REUSEPORT 0x0200 /* Unimplemented: allow local address & port reuse */
#define SO_SNDBUF 0x1001 /* Unimplemented: send buffer size */
#define SO_RCVBUF 0x1002 /* receive buffer size */
#define SO_SNDLOWAT 0x1003 /* Unimplemented: send low-water mark */
#define SO_RCVLOWAT 0x1004 /* Unimplemented: receive low-water mark */
#define SO_SNDTIMEO 0x1005 /* send timeout */
#define SO_RCVTIMEO 0x1006 /* receive timeout */
#define SO_ERROR 0x1007 /* get error status and clear */
#define SO_TYPE 0x1008 /* get socket type */
#define SO_CONTIMEO 0x1009 /* Unimplemented: connect timeout */
#define SO_NO_CHECK 0x100a /* don't create UDP checksum */
/* Level number for (get/set)sockopt() to apply to socket itself */
#define SOL_SOCKET 0xfff /* options for socket level */
#define AF_UNSPEC 0
#define AF_INET 2
#define AF_INET6 10
#define AF_CAN 29 /* Controller Area Network */
#define AF_AT 45 /* AT socket */
#define AF_WIZ 46 /* WIZnet socket */
#define PF_INET AF_INET
#define PF_INET6 AF_INET6
#define PF_UNSPEC AF_UNSPEC
#define PF_CAN AF_CAN
#define PF_AT AF_AT
#define PF_WIZ AF_WIZ
#define AF_MAX (AF_WIZ + 1) /* For now.. */
#define IPPROTO_IP 0
#define IPPROTO_ICMP 1
#define IPPROTO_TCP 6
#define IPPROTO_UDP 17
#define IPPROTO_IPV6 41
#define IPPROTO_ICMPV6 58
#define IPPROTO_UDPLITE 136
#define IPPROTO_RAW 255
/* Flags we can use with send and recv */
#define MSG_PEEK 0x01 /* Peeks at an incoming message */
#define MSG_WAITALL 0x02 /* Unimplemented: Requests that the function block until the full amount of data requested can be returned */
#define MSG_OOB 0x04 /* Unimplemented: Requests out-of-band data. The significance and semantics of out-of-band data are protocol-specific */
#define MSG_DONTWAIT 0x08 /* Nonblocking i/o for this operation only */
#define MSG_MORE 0x10 /* Sender will send more */
/* Options for level IPPROTO_IP */
#define IP_TOS 1
#define IP_TTL 2
/* Options for level IPPROTO_TCP */
#define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */
#define TCP_KEEPALIVE 0x02 /* send KEEPALIVE probes when idle for pcb->keep_idle milliseconds */
#define TCP_KEEPIDLE 0x03 /* set pcb->keep_idle - Same as TCP_KEEPALIVE, but use seconds for get/setsockopt */
#define TCP_KEEPINTVL 0x04 /* set pcb->keep_intvl - Use seconds for get/setsockopt */
#define TCP_KEEPCNT 0x05 /* set pcb->keep_cnt - Use number of probes sent for get/setsockopt */
/* Options and types related to multicast membership */
#define IP_ADD_MEMBERSHIP 3
#define IP_DROP_MEMBERSHIP 4
/* Options and types for UDP multicast traffic handling */
#define IP_MULTICAST_TTL 5
#define IP_MULTICAST_IF 6
#define IP_MULTICAST_LOOP 7
typedef struct ip_mreq
{
struct in_addr imr_multiaddr; /* IP multicast address of group */
struct in_addr imr_interface; /* local IP address of interface */
} ip_mreq;
/* The Type of Service provides an indication of the abstract parameters of the quality of service desired */
#define IPTOS_TOS_MASK 0x1E
#define IPTOS_TOS(tos) ((tos) & IPTOS_TOS_MASK)
#define IPTOS_LOWDELAY 0x10
#define IPTOS_THROUGHPUT 0x08
#define IPTOS_RELIABILITY 0x04
#define IPTOS_LOWCOST 0x02
#define IPTOS_MINCOST IPTOS_LOWCOST
/* The Network Control precedence designation is intended to be used within a network only */
#define IPTOS_PREC_MASK 0xe0
#define IPTOS_PREC(tos) ((tos) & IPTOS_PREC_MASK)
#define IPTOS_PREC_NETCONTROL 0xe0
#define IPTOS_PREC_INTERNETCONTROL 0xc0
#define IPTOS_PREC_CRITIC_ECP 0xa0
#define IPTOS_PREC_FLASHOVERRIDE 0x80
#define IPTOS_PREC_FLASH 0x60
#define IPTOS_PREC_IMMEDIATE 0x40
#define IPTOS_PREC_PRIORITY 0x20
#define IPTOS_PREC_ROUTINE 0x00
/* Options for shatdown type */
#ifndef SHUT_RD
#define SHUT_RD 0
#define SHUT_WR 1
#define SHUT_RDWR 2
#endif
struct sockaddr
{
uint8_t sa_len;
sa_family_t sa_family;
char sa_data[14];
};
#if NETDEV_IPV4
/* members are in network byte order */
struct sockaddr_in
{
uint8_t sin_len;
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
#define SIN_ZERO_LEN 8
char sin_zero[SIN_ZERO_LEN];
};
#endif /* NETDEV_IPV4 */
#if NETDEV_IPV6
struct sockaddr_in6
{
uint8_t sin6_len; /* length of this structure */
sa_family_t sin6_family; /* AF_INET6 */
in_port_t sin6_port; /* Transport layer port # */
uint32_t sin6_flowinfo; /* IPv6 flow information */
struct in6_addr sin6_addr; /* IPv6 address */
uint32_t sin6_scope_id; /* Set of interfaces for scope */
};
#endif /* NETDEV_IPV6 */
struct sockaddr_storage
{
uint8_t s2_len;
sa_family_t ss_family;
char s2_data1[2];
uint32_t s2_data2[3];
#if NETDEV_IPV6
uint32_t s2_data3[3];
#endif /* NETDEV_IPV6 */
};
int sal_accept(int socket, struct sockaddr *addr, socklen_t *addrlen);
int sal_bind(int socket, const struct sockaddr *name, socklen_t namelen);
int sal_shutdown(int socket, int how);
int sal_getpeername (int socket, struct sockaddr *name, socklen_t *namelen);
int sal_getsockname (int socket, struct sockaddr *name, socklen_t *namelen);
int sal_getsockopt (int socket, int level, int optname, void *optval, socklen_t *optlen);
int sal_setsockopt (int socket, int level, int optname, const void *optval, socklen_t optlen);
int sal_connect(int socket, const struct sockaddr *name, socklen_t namelen);
int sal_listen(int socket, int backlog);
int sal_recvfrom(int socket, void *mem, size_t len, int flags,
struct sockaddr *from, socklen_t *fromlen);
int sal_sendto(int socket, const void *dataptr, size_t size, int flags,
const struct sockaddr *to, socklen_t tolen);
int sal_socket(int domain, int type, int protocol);
int sal_closesocket(int socket);
int sal_ioctlsocket(int socket, long cmd, void *arg);
#ifdef __cplusplus
}
#endif
#endif /* SAL_SOCKET_H__ */
@@ -0,0 +1,68 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-11-10 ChenYong First version
*/
#ifndef __SAL_TLS_H__
#define __SAL_TLS_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <rtthread.h>
/* Protocol level for TLS.
* Here, the same socket protocol level for TLS as in Linux was used.
*/
#define SOL_TLS 282
/* Socket options for TLS */
/* Socket option to select TLS credentials to use. */
#define TLS_CRET_LIST 1
/* Socket option to set select ciphersuites to use. */
#define TLS_CIPHERSUITE_LIST 2
/* Socket option to set peer verification level for TLS connection. */
#define TLS_PEER_VERIFY 3
/* Socket option to set role for DTLS connection. */
#define TLS_DTLS_ROLE 4
/* Protocol numbers for TLS protocols */
#define PROTOCOL_TLS 256
#define PROTOCOL_DTLS 257
struct sal_proto_tls_ops
{
int (*init)(void);
void* (*socket)(int socket);
int (*connect)(void *sock);
int (*send)(void *sock, const void *data, size_t size);
int (*recv)(void *sock, void *mem, size_t len);
int (*closesocket)(void *sock);
int (*set_cret_list)(void *sock, const void *cert, size_t size); /* Set TLS credentials */
int (*set_ciphersurite)(void *sock, const void* ciphersurite, size_t size); /* Set select ciphersuites */
int (*set_peer_verify)(void *sock, const void* peer_verify, size_t size); /* Set peer verification */
int (*set_dtls_role)(void *sock, const void *dtls_role, size_t size); /* Set role for DTLS */
};
struct sal_proto_tls
{
char name[RT_NAME_MAX]; /* TLS protocol name */
const struct sal_proto_tls_ops *ops; /* SAL TLS protocol options */
};
/* SAL TLS protocol register */
int sal_proto_tls_register(const struct sal_proto_tls *pt);
#ifdef __cplusplus
}
#endif
#endif /* __SAL_TLS_H__ */
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2015-02-17 Bernard First version
* 2018-05-24 ChenYong Add socket abstraction layer
*/
#ifndef NETDB_H__
#define NETDB_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
#include <sal_netdb.h>
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);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,20 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2015-02-17 Bernard First version
*/
#ifndef IN_H__
#define IN_H__
#include <sys/socket.h>
#ifndef IN6_IS_ADDR_MULTICAST
#define IN6_IS_ADDR_MULTICAST(a) (((uint8_t *) (a))[0] == 0xff)
#endif
#endif
@@ -0,0 +1,16 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2015-02-17 Bernard First version
*/
#ifndef TCP_H__
#define TCP_H__
#include <sys/socket.h>
#endif
@@ -0,0 +1,16 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2015-02-17 Bernard First version
*/
#ifndef UDP_H__
#define UDP_H__
#include <sys/socket.h>
#endif
@@ -0,0 +1,67 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2015-02-17 Bernard First version
* 2018-05-17 ChenYong Add socket abstraction layer
*/
#ifndef SYS_SOCKET_H_
#define SYS_SOCKET_H_
#include <rtthread.h>
#include <sal_socket.h>
#ifdef SAL_USING_TLS
#include <sal_tls.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifdef SAL_USING_POSIX
int accept(int s, struct sockaddr *addr, socklen_t *addrlen);
int bind(int s, const struct sockaddr *name, socklen_t namelen);
int shutdown(int s, int how);
int getpeername(int s, struct sockaddr *name, socklen_t *namelen);
int getsockname(int s, struct sockaddr *name, socklen_t *namelen);
int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen);
int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen);
int connect(int s, const struct sockaddr *name, socklen_t namelen);
int listen(int s, int backlog);
int recv(int s, void *mem, size_t len, int flags);
int recvfrom(int s, void *mem, size_t len, int flags,
struct sockaddr *from, socklen_t *fromlen);
int send(int s, const void *dataptr, size_t size, int flags);
int sendto(int s, const void *dataptr, size_t size, int flags,
const struct sockaddr *to, socklen_t tolen);
int socket(int domain, int type, int protocol);
int closesocket(int s);
int ioctlsocket(int s, long cmd, void *arg);
#else
#define accept(s, addr, addrlen) sal_accept(s, addr, addrlen)
#define bind(s, name, namelen) sal_bind(s, name, namelen)
#define shutdown(s, how) sal_shutdown(s, how)
#define getpeername(s, name, namelen) sal_getpeername(s, name, namelen)
#define getsockname(s, name, namelen) sal_getsockname(s, name, namelen)
#define getsockopt(s, level, optname, optval, optlen) sal_getsockopt(s, level, optname, optval, optlen)
#define setsockopt(s, level, optname, optval, optlen) sal_setsockopt(s, level, optname, optval, optlen)
#define connect(s, name, namelen) sal_connect(s, name, namelen)
#define listen(s, backlog) sal_listen(s, backlog)
#define recv(s, mem, len, flags) sal_recvfrom(s, mem, len, flags, NULL, NULL)
#define recvfrom(s, mem, len, flags, from, fromlen) sal_recvfrom(s, mem, len, flags, from, fromlen)
#define send(s, dataptr, size, flags) sal_sendto(s, dataptr, size, flags, NULL, NULL)
#define sendto(s, dataptr, size, flags, to, tolen) sal_sendto(s, dataptr, size, flags, to, tolen)
#define socket(domain, type, protocol) sal_socket(domain, type, protocol)
#define closesocket(s) sal_closesocket(s)
#define ioctlsocket(s, cmd, arg) sal_ioctlsocket(s, cmd, arg)
#endif /* SAL_USING_POSIX */
#ifdef __cplusplus
}
#endif
#endif /* _SYS_SOCKET_H_ */
@@ -0,0 +1,43 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2015-02-17 Bernard First version
* 2108-05-24 ChenYong Add socket abstraction layer
*/
#include <stddef.h>
#include <rtthread.h>
#include <netdb.h>
struct hostent *gethostbyname(const char *name)
{
return sal_gethostbyname(name);
}
RTM_EXPORT(gethostbyname);
int gethostbyname_r(const char *name, struct hostent *ret, char *buf,
size_t buflen, struct hostent **result, int *h_errnop)
{
return sal_gethostbyname_r(name, ret, buf, buflen, result, h_errnop);
}
RTM_EXPORT(gethostbyname_r);
void freeaddrinfo(struct addrinfo *ai)
{
sal_freeaddrinfo(ai);
}
RTM_EXPORT(freeaddrinfo);
int getaddrinfo(const char *nodename,
const char *servname,
const struct addrinfo *hints,
struct addrinfo **res)
{
return sal_getaddrinfo(nodename, servname, hints, res);
}
RTM_EXPORT(getaddrinfo);
@@ -0,0 +1,293 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2015-02-17 Bernard First version
* 2018-05-17 ChenYong Add socket abstraction layer
*/
#include <dfs.h>
#include <dfs_file.h>
#include <poll.h>
#include <dfs_net.h>
#include <sys/errno.h>
#include <sys/socket.h>
int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
{
int new_socket = -1;
int socket = dfs_net_getsocket(s);
new_socket = sal_accept(socket, addr, addrlen);
if (new_socket != -1)
{
/* this is a new socket, create it in file system fd */
int fd;
struct dfs_fd *d;
/* allocate a fd */
fd = fd_new();
if (fd < 0)
{
rt_set_errno(-ENOMEM);
sal_closesocket(new_socket);
return -1;
}
d = fd_get(fd);
if(d)
{
/* this is a socket fd */
d->type = FT_SOCKET;
d->path = NULL;
d->fops = dfs_net_get_fops();
d->flags = O_RDWR; /* set flags as read and write */
d->size = 0;
d->pos = 0;
/* set socket to the data of dfs_fd */
d->data = (void *) new_socket;
/* release the ref-count of fd */
fd_put(d);
return fd;
}
rt_set_errno(-ENOMEM);
sal_closesocket(new_socket);
return -1;
}
return -1;
}
RTM_EXPORT(accept);
int bind(int s, const struct sockaddr *name, socklen_t namelen)
{
int socket = dfs_net_getsocket(s);
return sal_bind(socket, name, namelen);
}
RTM_EXPORT(bind);
int shutdown(int s, int how)
{
int error = 0;
int socket = -1;
struct dfs_fd *d;
socket = dfs_net_getsocket(s);
if (socket < 0)
{
rt_set_errno(-ENOTSOCK);
return -1;
}
d = fd_get(s);
if (d == NULL)
{
rt_set_errno(-EBADF);
return -1;
}
if (sal_shutdown(socket, how) == 0)
{
error = 0;
}
else
{
rt_set_errno(-ENOTSOCK);
error = -1;
}
fd_put(d);
return error;
}
RTM_EXPORT(shutdown);
int getpeername(int s, struct sockaddr *name, socklen_t *namelen)
{
int socket = dfs_net_getsocket(s);
return sal_getpeername(socket, name, namelen);
}
RTM_EXPORT(getpeername);
int getsockname(int s, struct sockaddr *name, socklen_t *namelen)
{
int socket = dfs_net_getsocket(s);
return sal_getsockname(socket, name, namelen);
}
RTM_EXPORT(getsockname);
int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
{
int socket = dfs_net_getsocket(s);
return sal_getsockopt(socket, level, optname, optval, optlen);
}
RTM_EXPORT(getsockopt);
int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen)
{
int socket = dfs_net_getsocket(s);
return sal_setsockopt(socket, level, optname, optval, optlen);
}
RTM_EXPORT(setsockopt);
int connect(int s, const struct sockaddr *name, socklen_t namelen)
{
int socket = dfs_net_getsocket(s);
return sal_connect(socket, name, namelen);
}
RTM_EXPORT(connect);
int listen(int s, int backlog)
{
int socket = dfs_net_getsocket(s);
return sal_listen(socket, backlog);
}
RTM_EXPORT(listen);
int recv(int s, void *mem, size_t len, int flags)
{
int socket = dfs_net_getsocket(s);
return sal_recvfrom(socket, mem, len, flags, NULL, NULL);
}
RTM_EXPORT(recv);
int recvfrom(int s, void *mem, size_t len, int flags,
struct sockaddr *from, socklen_t *fromlen)
{
int socket = dfs_net_getsocket(s);
return sal_recvfrom(socket, mem, len, flags, from, fromlen);
}
RTM_EXPORT(recvfrom);
int send(int s, const void *dataptr, size_t size, int flags)
{
int socket = dfs_net_getsocket(s);
return sal_sendto(socket, dataptr, size, flags, NULL, 0);
}
RTM_EXPORT(send);
int sendto(int s, const void *dataptr, size_t size, int flags,
const struct sockaddr *to, socklen_t tolen)
{
int socket = dfs_net_getsocket(s);
return sal_sendto(socket, dataptr, size, flags, to, tolen);
}
RTM_EXPORT(sendto);
int socket(int domain, int type, int protocol)
{
/* create a BSD socket */
int fd;
int socket;
struct dfs_fd *d;
/* allocate a fd */
fd = fd_new();
if (fd < 0)
{
rt_set_errno(-ENOMEM);
return -1;
}
d = fd_get(fd);
/* create socket and then put it to the dfs_fd */
socket = sal_socket(domain, type, protocol);
if (socket >= 0)
{
/* this is a socket fd */
d->type = FT_SOCKET;
d->path = NULL;
d->fops = dfs_net_get_fops();
d->flags = O_RDWR; /* set flags as read and write */
d->size = 0;
d->pos = 0;
/* set socket to the data of dfs_fd */
d->data = (void *) socket;
}
else
{
/* release fd */
fd_put(d);
fd_put(d);
rt_set_errno(-ENOMEM);
return -1;
}
/* release the ref-count of fd */
fd_put(d);
return fd;
}
RTM_EXPORT(socket);
int closesocket(int s)
{
int error = 0;
int socket = -1;
struct dfs_fd *d;
socket = dfs_net_getsocket(s);
if (socket < 0)
{
rt_set_errno(-ENOTSOCK);
return -1;
}
d = fd_get(s);
if (d == RT_NULL)
{
rt_set_errno(-EBADF);
return -1;
}
if (sal_closesocket(socket) == 0)
{
error = 0;
}
else
{
rt_set_errno(-ENOTSOCK);
error = -1;
}
/* socket has been closed, delete it from file system fd */
fd_put(d);
fd_put(d);
return error;
}
RTM_EXPORT(closesocket);
int ioctlsocket(int s, long cmd, void *arg)
{
int socket = dfs_net_getsocket(s);
return sal_ioctlsocket(socket, cmd, arg);
}
RTM_EXPORT(ioctlsocket);
File diff suppressed because it is too large Load Diff