[net][sal] Add SAL (socket abstraction layer) framework
This commit is contained in:
parent
4ca1d03bdf
commit
8cda48a132
|
@ -28,7 +28,7 @@ if RT_USING_DFS
|
||||||
|
|
||||||
config RT_USING_DFS_ELMFAT
|
config RT_USING_DFS_ELMFAT
|
||||||
bool "Enable elm-chan fatfs"
|
bool "Enable elm-chan fatfs"
|
||||||
default y
|
default n
|
||||||
help
|
help
|
||||||
FatFs is a generic FAT/exFAT file system module for small embedded systems.
|
FatFs is a generic FAT/exFAT file system module for small embedded systems.
|
||||||
|
|
||||||
|
@ -95,14 +95,6 @@ if RT_USING_DFS
|
||||||
bool "Using devfs for device objects"
|
bool "Using devfs for device objects"
|
||||||
default y
|
default y
|
||||||
|
|
||||||
config RT_USING_DFS_NET
|
|
||||||
bool "Enable BSD socket operated by file system API"
|
|
||||||
select RT_USING_LWIP
|
|
||||||
select RT_USING_POSIX
|
|
||||||
default n
|
|
||||||
help
|
|
||||||
Let BSD socket operated by file system API, such as read/write and involveed in select/poll POSIX APIs.
|
|
||||||
|
|
||||||
config RT_USING_DFS_ROMFS
|
config RT_USING_DFS_ROMFS
|
||||||
bool "Enable ReadOnly file system on flash"
|
bool "Enable ReadOnly file system on flash"
|
||||||
default n
|
default n
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
# RT-Thread building script for component
|
|
||||||
|
|
||||||
from building import *
|
|
||||||
|
|
||||||
cwd = GetCurrentDir()
|
|
||||||
src = Glob('*.c')
|
|
||||||
CPPPATH = [cwd]
|
|
||||||
|
|
||||||
if not GetDepend('HAVE_SYS_SELECT_H'):
|
|
||||||
CPPPATH += [cwd + '/select']
|
|
||||||
|
|
||||||
if not GetDepend('HAVE_SYS_SOCKET_H'):
|
|
||||||
CPPPATH += [cwd + '/socket']
|
|
||||||
|
|
||||||
group = DefineGroup('Filesystem', src, depend = ['RT_USING_DFS', 'RT_USING_DFS_NET'], CPPPATH = CPPPATH)
|
|
||||||
|
|
||||||
Return('group')
|
|
|
@ -1,362 +0,0 @@
|
||||||
/*
|
|
||||||
* File : lwip_sockets.c
|
|
||||||
* This file is part of RT-Thread RTOS
|
|
||||||
* COPYRIGHT (C) 2015, RT-Thread Development Team
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Change Logs:
|
|
||||||
* Date Author Notes
|
|
||||||
* 2015-02-17 Bernard First version
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <dfs.h>
|
|
||||||
#include <dfs_posix.h>
|
|
||||||
#include <dfs_poll.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
|
|
||||||
#include "dfs_net.h"
|
|
||||||
|
|
||||||
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 (sock->lastdata || sock->rcvevent > 0) 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
|
|
||||||
{
|
|
||||||
int new_client = -1;
|
|
||||||
int sock = dfs_net_getsocket(s);
|
|
||||||
|
|
||||||
new_client = lwip_accept(sock, addr, addrlen);
|
|
||||||
if (new_client != -1)
|
|
||||||
{
|
|
||||||
/* this is a new socket, create it in file system fd */
|
|
||||||
int fd;
|
|
||||||
struct dfs_fd *d;
|
|
||||||
struct lwip_sock *lwsock;
|
|
||||||
|
|
||||||
/* allocate a fd */
|
|
||||||
fd = fd_new();
|
|
||||||
if (fd < 0)
|
|
||||||
{
|
|
||||||
rt_set_errno(-ENOMEM);
|
|
||||||
lwip_close(sock);
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
d = fd_get(fd);
|
|
||||||
|
|
||||||
/* this is a socket fd */
|
|
||||||
d->type = FT_SOCKET;
|
|
||||||
d->path = RT_NULL;
|
|
||||||
|
|
||||||
d->fops = dfs_net_get_fops();
|
|
||||||
/* initialize wait head */
|
|
||||||
lwsock = lwip_tryget_socket(new_client);
|
|
||||||
rt_wqueue_init(&(lwsock->wait_head));
|
|
||||||
|
|
||||||
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_client;
|
|
||||||
|
|
||||||
/* release the ref-count of fd */
|
|
||||||
fd_put(d);
|
|
||||||
|
|
||||||
return fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new_client;
|
|
||||||
}
|
|
||||||
RTM_EXPORT(accept);
|
|
||||||
|
|
||||||
int bind(int s, const struct sockaddr *name, socklen_t namelen)
|
|
||||||
{
|
|
||||||
int sock = dfs_net_getsocket(s);
|
|
||||||
|
|
||||||
return lwip_bind(sock, name, namelen);
|
|
||||||
}
|
|
||||||
RTM_EXPORT(bind);
|
|
||||||
|
|
||||||
int shutdown(int s, int how)
|
|
||||||
{
|
|
||||||
int sock;
|
|
||||||
struct dfs_fd *d;
|
|
||||||
|
|
||||||
d = fd_get(s);
|
|
||||||
if (d == RT_NULL)
|
|
||||||
{
|
|
||||||
rt_set_errno(-EBADF);
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sock = dfs_net_getsocket(s);
|
|
||||||
if (lwip_shutdown(sock, how) == 0)
|
|
||||||
{
|
|
||||||
/* socket has been closed, delete it from file system fd */
|
|
||||||
fd_put(d);
|
|
||||||
fd_put(d);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
RTM_EXPORT(shutdown);
|
|
||||||
|
|
||||||
int getpeername(int s, struct sockaddr *name, socklen_t *namelen)
|
|
||||||
{
|
|
||||||
int sock = dfs_net_getsocket(s);
|
|
||||||
|
|
||||||
return lwip_getpeername(sock, name, namelen);
|
|
||||||
}
|
|
||||||
RTM_EXPORT(getpeername);
|
|
||||||
|
|
||||||
int getsockname(int s, struct sockaddr *name, socklen_t *namelen)
|
|
||||||
{
|
|
||||||
int sock = dfs_net_getsocket(s);
|
|
||||||
|
|
||||||
return lwip_getsockname(sock, name, namelen);
|
|
||||||
}
|
|
||||||
RTM_EXPORT(getsockname);
|
|
||||||
|
|
||||||
int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
|
|
||||||
{
|
|
||||||
int sock = dfs_net_getsocket(s);
|
|
||||||
|
|
||||||
return lwip_getsockopt(sock, level, optname, optval, optlen);
|
|
||||||
}
|
|
||||||
RTM_EXPORT(getsockopt);
|
|
||||||
|
|
||||||
int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen)
|
|
||||||
{
|
|
||||||
int sock = dfs_net_getsocket(s);
|
|
||||||
|
|
||||||
#if LWIP_VERSION_MAJOR < 2U
|
|
||||||
#error "Your lwIP version is not supported. Please using lwIP 2.0.0+."
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return lwip_setsockopt(sock, level, optname, optval, optlen);
|
|
||||||
}
|
|
||||||
RTM_EXPORT(setsockopt);
|
|
||||||
|
|
||||||
int connect(int s, const struct sockaddr *name, socklen_t namelen)
|
|
||||||
{
|
|
||||||
int sock = dfs_net_getsocket(s);
|
|
||||||
|
|
||||||
return lwip_connect(sock, name, namelen);
|
|
||||||
}
|
|
||||||
RTM_EXPORT(connect);
|
|
||||||
|
|
||||||
int listen(int s, int backlog)
|
|
||||||
{
|
|
||||||
int sock = dfs_net_getsocket(s);
|
|
||||||
|
|
||||||
return lwip_listen(sock, backlog);
|
|
||||||
}
|
|
||||||
RTM_EXPORT(listen);
|
|
||||||
|
|
||||||
int recv(int s, void *mem, size_t len, int flags)
|
|
||||||
{
|
|
||||||
int sock = dfs_net_getsocket(s);
|
|
||||||
|
|
||||||
return lwip_recv(sock, mem, len, flags);
|
|
||||||
}
|
|
||||||
RTM_EXPORT(recv);
|
|
||||||
|
|
||||||
int recvfrom(int s, void *mem, size_t len, int flags,
|
|
||||||
struct sockaddr *from, socklen_t *fromlen)
|
|
||||||
{
|
|
||||||
int sock = dfs_net_getsocket(s);
|
|
||||||
|
|
||||||
return lwip_recvfrom(sock, mem, len, flags, from, fromlen);
|
|
||||||
}
|
|
||||||
RTM_EXPORT(recvfrom);
|
|
||||||
|
|
||||||
int send(int s, const void *dataptr, size_t size, int flags)
|
|
||||||
{
|
|
||||||
int sock = dfs_net_getsocket(s);
|
|
||||||
|
|
||||||
return lwip_send(sock, dataptr, size, flags);
|
|
||||||
}
|
|
||||||
RTM_EXPORT(send);
|
|
||||||
|
|
||||||
int sendto(int s, const void *dataptr, size_t size, int flags,
|
|
||||||
const struct sockaddr *to, socklen_t tolen)
|
|
||||||
{
|
|
||||||
int sock = dfs_net_getsocket(s);
|
|
||||||
|
|
||||||
return lwip_sendto(sock, dataptr, size, flags, to, tolen);
|
|
||||||
}
|
|
||||||
RTM_EXPORT(sendto);
|
|
||||||
|
|
||||||
int socket(int domain, int type, int protocol)
|
|
||||||
{
|
|
||||||
/* create a BSD socket */
|
|
||||||
int fd;
|
|
||||||
int sock;
|
|
||||||
struct dfs_fd *d;
|
|
||||||
struct lwip_sock *lwsock;
|
|
||||||
|
|
||||||
/* allocate a fd */
|
|
||||||
fd = fd_new();
|
|
||||||
if (fd < 0)
|
|
||||||
{
|
|
||||||
rt_set_errno(-ENOMEM);
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
d = fd_get(fd);
|
|
||||||
|
|
||||||
/* create socket in lwip and then put it to the dfs_fd */
|
|
||||||
sock = lwip_socket(domain, type, protocol);
|
|
||||||
if (sock >= 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 *) sock;
|
|
||||||
|
|
||||||
lwsock = lwip_tryget_socket(sock);
|
|
||||||
rt_wqueue_init(&(lwsock->wait_head));
|
|
||||||
lwsock->conn->callback = event_callback;
|
|
||||||
}
|
|
||||||
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 sock = dfs_net_getsocket(s);
|
|
||||||
struct dfs_fd *d;
|
|
||||||
|
|
||||||
d = fd_get(s);
|
|
||||||
|
|
||||||
/* socket has been closed, delete it from file system fd */
|
|
||||||
fd_put(d);
|
|
||||||
fd_put(d);
|
|
||||||
|
|
||||||
return lwip_close(sock);
|
|
||||||
}
|
|
||||||
RTM_EXPORT(closesocket);
|
|
||||||
|
|
||||||
int ioctlsocket(int s, long cmd, void *arg)
|
|
||||||
{
|
|
||||||
int sock = dfs_net_getsocket(s);
|
|
||||||
|
|
||||||
return lwip_ioctl(sock, cmd, arg);
|
|
||||||
}
|
|
||||||
RTM_EXPORT(ioctlsocket);
|
|
|
@ -1,4 +1,44 @@
|
||||||
menu "Network stack"
|
menu "Network"
|
||||||
|
|
||||||
|
menu "Socket abstraction layer"
|
||||||
|
|
||||||
|
config RT_USING_SAL
|
||||||
|
bool "Enable socket abstraction layer"
|
||||||
|
default n
|
||||||
|
select RT_USING_DFS
|
||||||
|
|
||||||
|
if RT_USING_SAL
|
||||||
|
|
||||||
|
menu "protocol stack implement"
|
||||||
|
|
||||||
|
config SAL_USING_LWIP
|
||||||
|
bool "Support lwIP stack"
|
||||||
|
default y if RT_USING_LWIP
|
||||||
|
default n
|
||||||
|
depends on RT_USING_LWIP
|
||||||
|
|
||||||
|
config SAL_USING_AT
|
||||||
|
bool "Support AT Commands stack"
|
||||||
|
default y if RT_USING_AT_SOCKET
|
||||||
|
default n
|
||||||
|
depends on RT_USING_AT_SOCKET
|
||||||
|
endmenu
|
||||||
|
|
||||||
|
config SAL_USING_POSIX
|
||||||
|
bool "Enable BSD socket operated by file system API"
|
||||||
|
select RT_USING_LIBC
|
||||||
|
select RT_USING_POSIX
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
Let BSD socket operated by file system API, such as read/write and involveed in select/poll POSIX APIs.
|
||||||
|
|
||||||
|
config SAL_PROTO_FAMILIES_NUM
|
||||||
|
int "the number of protocol family"
|
||||||
|
default 4
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
endmenu
|
||||||
|
|
||||||
menu "light weight TCP/IP stack"
|
menu "light weight TCP/IP stack"
|
||||||
config RT_USING_LWIP
|
config RT_USING_LWIP
|
||||||
|
@ -228,7 +268,6 @@ config LWIP_USING_DHCPD
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
|
@ -371,7 +371,7 @@
|
||||||
* LWIP_COMPAT_SOCKETS==1: Enable BSD-style sockets functions names.
|
* LWIP_COMPAT_SOCKETS==1: Enable BSD-style sockets functions names.
|
||||||
* (only used if you use sockets.c)
|
* (only used if you use sockets.c)
|
||||||
*/
|
*/
|
||||||
#ifdef RT_USING_DFS_NET
|
#ifdef SAL_USING_POSIX
|
||||||
#define LWIP_COMPAT_SOCKETS 0
|
#define LWIP_COMPAT_SOCKETS 0
|
||||||
#else
|
#else
|
||||||
#ifndef LWIP_COMPAT_SOCKETS
|
#ifndef LWIP_COMPAT_SOCKETS
|
||||||
|
|
|
@ -67,7 +67,7 @@ path = [GetCurrentDir() + '/src',
|
||||||
GetCurrentDir() + '/src/arch/include',
|
GetCurrentDir() + '/src/arch/include',
|
||||||
GetCurrentDir() + '/src/include/netif']
|
GetCurrentDir() + '/src/include/netif']
|
||||||
|
|
||||||
if not GetDepend('RT_USING_POSIX') or not GetDepend('RT_USING_DFS_NET'):
|
if not GetDepend('RT_USING_POSIX') or not GetDepend('SAL_USING_POSIX'):
|
||||||
path += [GetCurrentDir() + '/src/include/posix']
|
path += [GetCurrentDir() + '/src/include/posix']
|
||||||
|
|
||||||
if GetDepend(['RT_LWIP_SNMP']):
|
if GetDepend(['RT_LWIP_SNMP']):
|
||||||
|
|
|
@ -197,7 +197,7 @@ static void sockaddr_to_ipaddr_port(const struct sockaddr* sockaddr, ip_addr_t*
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
#ifdef RT_USING_DFS_NET
|
#ifdef SAL_USING_POSIX
|
||||||
#include <ipc/waitqueue.h>
|
#include <ipc/waitqueue.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -222,7 +222,7 @@ struct lwip_sock {
|
||||||
/** counter of how many threads are waiting for this socket using select */
|
/** counter of how many threads are waiting for this socket using select */
|
||||||
SELWAIT_T select_waiting;
|
SELWAIT_T select_waiting;
|
||||||
|
|
||||||
#ifdef RT_USING_DFS_NET
|
#ifdef SAL_USING_POSIX
|
||||||
rt_wqueue_t wait_head;
|
rt_wqueue_t wait_head;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
|
@ -405,7 +405,7 @@
|
||||||
* LWIP_COMPAT_SOCKETS==1: Enable BSD-style sockets functions names.
|
* LWIP_COMPAT_SOCKETS==1: Enable BSD-style sockets functions names.
|
||||||
* (only used if you use sockets.c)
|
* (only used if you use sockets.c)
|
||||||
*/
|
*/
|
||||||
#ifdef RT_USING_DFS_NET
|
#ifdef SAL_USING_POSIX
|
||||||
#define LWIP_COMPAT_SOCKETS 0
|
#define LWIP_COMPAT_SOCKETS 0
|
||||||
#else
|
#else
|
||||||
#ifndef LWIP_COMPAT_SOCKETS
|
#ifndef LWIP_COMPAT_SOCKETS
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
# RT-Thread building script for component
|
||||||
|
|
||||||
|
from building import *
|
||||||
|
|
||||||
|
cwd = GetCurrentDir()
|
||||||
|
|
||||||
|
src = Glob('src/*.c')
|
||||||
|
src += Glob('socket/*.c')
|
||||||
|
|
||||||
|
CPPPATH = [cwd + '/include']
|
||||||
|
CPPPATH += [cwd + '/include/dfs_net']
|
||||||
|
CPPPATH += [cwd + '/include/socket']
|
||||||
|
|
||||||
|
if GetDepend('SAL_USING_LWIP'):
|
||||||
|
src += Glob('impl/af_inet_lwip.c')
|
||||||
|
|
||||||
|
if GetDepend('SAL_USING_AT'):
|
||||||
|
src += Glob('impl/af_inet_at.c')
|
||||||
|
|
||||||
|
if GetDepend('SAL_USING_POSIX'):
|
||||||
|
src += Glob('dfs_net/*.c')
|
||||||
|
|
||||||
|
if not GetDepend('HAVE_SYS_SELECT_H'):
|
||||||
|
CPPPATH += [cwd + '/include/dfs_net/sys_select']
|
||||||
|
|
||||||
|
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')
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* File : dfs_net.c
|
* File : dfs_net.c
|
||||||
* This file is part of RT-Thread RTOS
|
* This file is part of RT-Thread RTOS
|
||||||
* COPYRIGHT (C) 2015-2016, RT-Thread Development Team
|
* COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -22,33 +22,29 @@
|
||||||
* 2015-02-17 Bernard First version
|
* 2015-02-17 Bernard First version
|
||||||
* 2016-05-07 Bernard Rename dfs_lwip to dfs_net
|
* 2016-05-07 Bernard Rename dfs_lwip to dfs_net
|
||||||
* 2018-03-09 Bernard Fix the last data issue in poll.
|
* 2018-03-09 Bernard Fix the last data issue in poll.
|
||||||
|
* 2018-05-24 ChenYong Add socket abstraction layer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
|
|
||||||
#include <dfs.h>
|
#include <dfs.h>
|
||||||
#include <dfs_fs.h>
|
#include <dfs_net.h>
|
||||||
#include <dfs_file.h>
|
|
||||||
#include <dfs_posix.h>
|
|
||||||
|
|
||||||
#include <rtdevice.h>
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
|
||||||
#include <dfs_poll.h>
|
|
||||||
#include "dfs_net.h"
|
|
||||||
|
|
||||||
int dfs_net_getsocket(int fd)
|
int dfs_net_getsocket(int fd)
|
||||||
{
|
{
|
||||||
int sock;
|
int socket;
|
||||||
struct dfs_fd *_dfs_fd;
|
struct dfs_fd *_dfs_fd;
|
||||||
|
|
||||||
_dfs_fd = fd_get(fd);
|
_dfs_fd = fd_get(fd);
|
||||||
if (_dfs_fd == NULL) return -1;
|
if (_dfs_fd == NULL) return -1;
|
||||||
|
|
||||||
if (_dfs_fd->type != FT_SOCKET) sock = -1;
|
if (_dfs_fd->type != FT_SOCKET) socket = -1;
|
||||||
else sock = (int)_dfs_fd->data;
|
else socket = (int)_dfs_fd->data;
|
||||||
|
|
||||||
fd_put(_dfs_fd); /* put this dfs fd */
|
fd_put(_dfs_fd); /* put this dfs fd */
|
||||||
return sock;
|
return socket;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dfs_net_ioctl(struct dfs_fd* file, int cmd, void* args)
|
static int dfs_net_ioctl(struct dfs_fd* file, int cmd, void* args)
|
||||||
|
@ -58,69 +54,30 @@ static int dfs_net_ioctl(struct dfs_fd* file, int cmd, void* args)
|
||||||
|
|
||||||
static int dfs_net_read(struct dfs_fd* file, void *buf, size_t count)
|
static int dfs_net_read(struct dfs_fd* file, void *buf, size_t count)
|
||||||
{
|
{
|
||||||
int sock;
|
int socket = (int) file->data;
|
||||||
|
|
||||||
sock = (int)file->data;
|
return sal_recvfrom(socket, buf, count, 0, NULL, NULL);
|
||||||
count = lwip_read(sock, buf, count);
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dfs_net_write(struct dfs_fd *file, const void *buf, size_t count)
|
static int dfs_net_write(struct dfs_fd *file, const void *buf, size_t count)
|
||||||
{
|
{
|
||||||
int sock;
|
int socket = (int) file->data;
|
||||||
|
|
||||||
sock = (int)file->data;
|
return sal_sendto(socket, buf, count, 0, NULL, 0);
|
||||||
count = lwip_write(sock, buf, count);
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dfs_net_close(struct dfs_fd* file)
|
static int dfs_net_close(struct dfs_fd* file)
|
||||||
{
|
{
|
||||||
int sock;
|
int socket = (int) file->data;
|
||||||
int result;
|
|
||||||
|
|
||||||
sock = (int)file->data;
|
return sal_closesocket(socket);
|
||||||
result = lwip_close(sock);
|
|
||||||
|
|
||||||
if (result == 0) return RT_EOK;
|
|
||||||
|
|
||||||
return -result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dfs_net_poll(struct dfs_fd *file, struct rt_pollreq *req)
|
static int dfs_net_poll(struct dfs_fd *file, struct rt_pollreq *req)
|
||||||
{
|
{
|
||||||
int sfd;
|
extern int sal_poll(struct dfs_fd *file, struct rt_pollreq *req);
|
||||||
int mask = 0;
|
|
||||||
struct lwip_sock *sock;
|
|
||||||
|
|
||||||
sfd = (int)file->data;
|
return sal_poll(file, req);
|
||||||
|
|
||||||
sock = lwip_tryget_socket(sfd);
|
|
||||||
if (sock != NULL)
|
|
||||||
{
|
|
||||||
rt_base_t level;
|
|
||||||
|
|
||||||
rt_poll_add(&sock->wait_head, req);
|
|
||||||
|
|
||||||
level = rt_hw_interrupt_disable();
|
|
||||||
if (sock->lastdata || sock->rcvevent)
|
|
||||||
{
|
|
||||||
mask |= POLLIN;
|
|
||||||
}
|
|
||||||
if (sock->sendevent)
|
|
||||||
{
|
|
||||||
mask |= POLLOUT;
|
|
||||||
}
|
|
||||||
if (sock->errevent)
|
|
||||||
{
|
|
||||||
mask |= POLLERR;
|
|
||||||
}
|
|
||||||
rt_hw_interrupt_enable(level);
|
|
||||||
}
|
|
||||||
|
|
||||||
return mask;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct dfs_file_ops _net_fops =
|
const struct dfs_file_ops _net_fops =
|
||||||
|
@ -140,4 +97,3 @@ const struct dfs_file_ops *dfs_net_get_fops(void)
|
||||||
{
|
{
|
||||||
return &_net_fops;
|
return &_net_fops;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
/*
|
||||||
|
* File : af_inet_at.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2018-06-06 ChenYong First version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <sal.h>
|
||||||
|
|
||||||
|
#include <at_socket.h>
|
||||||
|
|
||||||
|
#ifdef SAL_USING_POSIX
|
||||||
|
#include <dfs_poll.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#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 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 sal_socket *socket, int type, int protocol)
|
||||||
|
{
|
||||||
|
RT_ASSERT(socket);
|
||||||
|
|
||||||
|
//TODO Check type & protocol
|
||||||
|
|
||||||
|
socket->ops = &at_inet_stream_ops;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct proto_family at_inet_family_ops = {
|
||||||
|
AF_AT,
|
||||||
|
AF_INET,
|
||||||
|
at_create,
|
||||||
|
at_gethostbyname,
|
||||||
|
NULL,
|
||||||
|
at_freeaddrinfo,
|
||||||
|
at_getaddrinfo,
|
||||||
|
};
|
||||||
|
|
||||||
|
int at_inet_init(void)
|
||||||
|
{
|
||||||
|
sal_proto_family_register(&at_inet_family_ops);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
INIT_COMPONENT_EXPORT(at_inet_init);
|
|
@ -0,0 +1,302 @@
|
||||||
|
/*
|
||||||
|
* File : af_inet_lwip.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* 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>
|
||||||
|
|
||||||
|
#ifdef SAL_USING_POSIX
|
||||||
|
#include <dfs_poll.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <sal.h>
|
||||||
|
|
||||||
|
#if LWIP_VERSION < 0x2000000
|
||||||
|
#define SELWAIT_T int
|
||||||
|
#else
|
||||||
|
#ifndef SELWAIT_T
|
||||||
|
#define SELWAIT_T u8_t
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
#ifdef SAL_USING_POSIX
|
||||||
|
rt_wqueue_t wait_head;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
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 (sock->lastdata || sock->rcvevent > 0)
|
||||||
|
event |= POLLIN;
|
||||||
|
if (sock->sendevent)
|
||||||
|
event |= POLLOUT;
|
||||||
|
if (sock->errevent)
|
||||||
|
event |= POLLERR;
|
||||||
|
|
||||||
|
SYS_ARCH_UNPROTECT(lev);
|
||||||
|
|
||||||
|
if (event)
|
||||||
|
{
|
||||||
|
#ifdef SAL_USING_POSIX
|
||||||
|
rt_wqueue_wakeup(&sock->wait_head, (void*) event);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int inet_socket(int domain, int type, int protocol)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
#ifdef SAL_USING_POSIX
|
||||||
|
rt_wqueue_init(&lwsock->wait_head);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return socket;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int inet_accept(int socket, struct sockaddr *addr, socklen_t *addrlen)
|
||||||
|
{
|
||||||
|
int new_socket;
|
||||||
|
|
||||||
|
new_socket = lwip_accept(socket, addr, addrlen);
|
||||||
|
if (new_socket >= 0)
|
||||||
|
{
|
||||||
|
struct lwip_sock *lwsock;
|
||||||
|
|
||||||
|
lwsock = lwip_tryget_socket(new_socket);
|
||||||
|
|
||||||
|
#ifdef SAL_USING_POSIX
|
||||||
|
rt_wqueue_init(&lwsock->wait_head);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return new_socket;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 (sock->lastdata || sock->rcvevent)
|
||||||
|
{
|
||||||
|
mask |= POLLIN;
|
||||||
|
}
|
||||||
|
if (sock->sendevent)
|
||||||
|
{
|
||||||
|
mask |= POLLOUT;
|
||||||
|
}
|
||||||
|
if (sock->errevent)
|
||||||
|
{
|
||||||
|
mask |= POLLERR;
|
||||||
|
}
|
||||||
|
rt_hw_interrupt_enable(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct proto_ops lwip_inet_stream_ops = {
|
||||||
|
inet_socket,
|
||||||
|
lwip_close,
|
||||||
|
lwip_bind,
|
||||||
|
lwip_listen,
|
||||||
|
lwip_connect,
|
||||||
|
inet_accept,
|
||||||
|
lwip_sendto,
|
||||||
|
lwip_recvfrom,
|
||||||
|
lwip_getsockopt,
|
||||||
|
//TODO fix on 1.4.1
|
||||||
|
lwip_setsockopt,
|
||||||
|
lwip_shutdown,
|
||||||
|
lwip_getpeername,
|
||||||
|
inet_getsockname,
|
||||||
|
lwip_ioctl,
|
||||||
|
inet_poll,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int inet_create(struct sal_socket *socket, int type, int protocol)
|
||||||
|
{
|
||||||
|
RT_ASSERT(socket);
|
||||||
|
|
||||||
|
//TODO Check type & protocol
|
||||||
|
|
||||||
|
socket->ops = &lwip_inet_stream_ops;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct proto_family lwip_inet_family_ops = {
|
||||||
|
AF_INET,
|
||||||
|
AF_INET,
|
||||||
|
inet_create,
|
||||||
|
lwip_gethostbyname,
|
||||||
|
lwip_gethostbyname_r,
|
||||||
|
lwip_freeaddrinfo,
|
||||||
|
lwip_getaddrinfo,
|
||||||
|
};
|
||||||
|
|
||||||
|
int lwip_inet_init(void)
|
||||||
|
{
|
||||||
|
sal_proto_family_register(&lwip_inet_family_ops);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
INIT_COMPONENT_EXPORT(lwip_inet_init);
|
|
@ -30,7 +30,7 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <lwip/sockets.h>
|
#include <dfs_file.h>
|
||||||
|
|
||||||
const struct dfs_file_ops* dfs_net_get_fops(void);
|
const struct dfs_file_ops* dfs_net_get_fops(void);
|
||||||
int dfs_net_getsocket(int fd);
|
int dfs_net_getsocket(int fd);
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* File : select.h
|
* File : select.h
|
||||||
* This file is part of RT-Thread RTOS
|
* This file is part of RT-Thread RTOS
|
||||||
* COPYRIGHT (C) 2015, RT-Thread Development Team
|
* COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
|
@ -0,0 +1,101 @@
|
||||||
|
/*
|
||||||
|
* File : sal.h
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2018-05-17 ChenYong First version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SAL_H__
|
||||||
|
#define SAL_H__
|
||||||
|
|
||||||
|
#include <dfs_file.h>
|
||||||
|
#include <rtdevice.h>
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
#define SAL_SOCKETS_NUM DFS_FD_MAX
|
||||||
|
|
||||||
|
/* 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 proto_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);
|
||||||
|
int (*poll) (struct dfs_fd *file, struct rt_pollreq *req);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sal_socket
|
||||||
|
{
|
||||||
|
uint32_t magic; /* sal socket magic word */
|
||||||
|
|
||||||
|
int socket; /* sal socket descriptor */
|
||||||
|
int domain;
|
||||||
|
int type;
|
||||||
|
int protocol;
|
||||||
|
|
||||||
|
const struct proto_ops *ops; /* socket options */
|
||||||
|
void *user_data; /* specific sal socket data */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct proto_family
|
||||||
|
{
|
||||||
|
int family; /* primary protocol families type*/
|
||||||
|
int sec_family; /* secondary protocol families type*/
|
||||||
|
int (*create)(struct sal_socket *sal_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);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* SAL socket initialization */
|
||||||
|
int sal_init(void);
|
||||||
|
|
||||||
|
int sal_proto_family_register(const struct proto_family *pf);
|
||||||
|
struct sal_socket *sal_get_socket(int sock);
|
||||||
|
|
||||||
|
#endif /* SAL_H__ */
|
|
@ -0,0 +1,138 @@
|
||||||
|
/*
|
||||||
|
* File : sal_ipaddr.h
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2018-05-18 ChenYong First version
|
||||||
|
*/
|
||||||
|
#ifndef SAL_IPADDR_H__
|
||||||
|
#define SAL_IPADDR_H__
|
||||||
|
|
||||||
|
#include "sal_type.h"
|
||||||
|
|
||||||
|
/** IPv4 only: set the IP address given as an u32_t */
|
||||||
|
#define ip4_addr_set_u32(dest_ipaddr, src_u32) ((dest_ipaddr)->addr = (src_u32))
|
||||||
|
/** IPv4 only: get the IP address as an u32_t */
|
||||||
|
#define ip4_addr_get_u32(src_ipaddr) ((src_ipaddr)->addr)
|
||||||
|
|
||||||
|
#define IP4ADDR_STRLEN_MAX 16
|
||||||
|
|
||||||
|
/* These macros should be calculated by the preprocessor and are used
|
||||||
|
with compile-time constants only (so that there is no little-endian
|
||||||
|
overhead at runtime). */
|
||||||
|
#define PP_HTONS(x) ((((x) & 0x00ffUL) << 8) | (((x) & 0xff00UL) >> 8))
|
||||||
|
#define PP_NTOHS(x) PP_HTONS(x)
|
||||||
|
#define PP_HTONL(x) ((((x) & 0x000000ffUL) << 24) | \
|
||||||
|
(((x) & 0x0000ff00UL) << 8) | \
|
||||||
|
(((x) & 0x00ff0000UL) >> 8) | \
|
||||||
|
(((x) & 0xff000000UL) >> 24))
|
||||||
|
#define PP_NTOHL(x) PP_HTONL(x)
|
||||||
|
|
||||||
|
#define htons(x) (u16_t)PP_HTONS(x)
|
||||||
|
#define ntohs(x) (u16_t)PP_NTOHS(x)
|
||||||
|
#define htonl(x) (u32_t)PP_HTONL(x)
|
||||||
|
#define ntohl(x) (u32_t)PP_NTOHL(x)
|
||||||
|
|
||||||
|
/* If your port already typedef's in_addr_t, define IN_ADDR_T_DEFINED
|
||||||
|
to prevent this code from redefining it. */
|
||||||
|
#if !defined(in_addr_t) && !defined(IN_ADDR_T_DEFINED)
|
||||||
|
typedef u32_t in_addr_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct in_addr
|
||||||
|
{
|
||||||
|
in_addr_t s_addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct in6_addr
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
u32_t u32_addr[4];
|
||||||
|
u8_t u8_addr[16];
|
||||||
|
} un;
|
||||||
|
#define s6_addr un.u8_addr
|
||||||
|
};
|
||||||
|
|
||||||
|
enum sal_ip_addr_type
|
||||||
|
{
|
||||||
|
/** IPv4 */
|
||||||
|
IPADDR_TYPE_V4 = 0U,
|
||||||
|
/** IPv6 */
|
||||||
|
IPADDR_TYPE_V6 = 6U,
|
||||||
|
/** IPv4+IPv6 ("dual-stack") */
|
||||||
|
IPADDR_TYPE_ANY = 46U
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct ip4_addr
|
||||||
|
{
|
||||||
|
u32_t addr;
|
||||||
|
} ip4_addr_t;
|
||||||
|
|
||||||
|
typedef struct ip6_addr
|
||||||
|
{
|
||||||
|
u32_t addr[4];
|
||||||
|
} ip6_addr_t;
|
||||||
|
|
||||||
|
typedef struct _ip_addr
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
ip6_addr_t ip6;
|
||||||
|
ip4_addr_t ip4;
|
||||||
|
} u_addr;
|
||||||
|
/** @ref sal_ip_addr_type */
|
||||||
|
u8_t type;
|
||||||
|
} ip_addr_t;
|
||||||
|
|
||||||
|
/** 255.255.255.255 */
|
||||||
|
#define IPADDR_NONE ((u32_t)0xffffffffUL)
|
||||||
|
/** 127.0.0.1 */
|
||||||
|
#define IPADDR_LOOPBACK ((u32_t)0x7f000001UL)
|
||||||
|
/** 0.0.0.0 */
|
||||||
|
#define IPADDR_ANY ((u32_t)0x00000000UL)
|
||||||
|
/** 255.255.255.255 */
|
||||||
|
#define IPADDR_BROADCAST ((u32_t)0xffffffffUL)
|
||||||
|
|
||||||
|
/** 255.255.255.255 */
|
||||||
|
#define INADDR_NONE IPADDR_NONE
|
||||||
|
/** 127.0.0.1 */
|
||||||
|
#define INADDR_LOOPBACK IPADDR_LOOPBACK
|
||||||
|
/** 0.0.0.0 */
|
||||||
|
#define INADDR_ANY IPADDR_ANY
|
||||||
|
/** 255.255.255.255 */
|
||||||
|
#define INADDR_BROADCAST IPADDR_BROADCAST
|
||||||
|
|
||||||
|
#define IPADDR_BROADCAST_STRING "255.255.255.255"
|
||||||
|
|
||||||
|
in_addr_t sal_ipaddr_addr(const char *cp);
|
||||||
|
int sal_ip4addr_aton(const char *cp, ip4_addr_t *addr);
|
||||||
|
char *sal_ip4addr_ntoa(const ip4_addr_t *addr);
|
||||||
|
char *sal_ip4addr_ntoa_r(const ip4_addr_t *addr, char *buf, int buflen);
|
||||||
|
|
||||||
|
#define inet_addr(cp) sal_ipaddr_addr(cp)
|
||||||
|
#define inet_aton(cp,addr) sal_ip4addr_aton(cp,(ip4_addr_t*)addr)
|
||||||
|
#define inet_ntoa(addr) sal_ip4addr_ntoa((const ip4_addr_t*)&(addr))
|
||||||
|
#define inet_ntoa_r(addr, buf, buflen) sal_ip4addr_ntoa_r((const ip4_addr_t*)&(addr), buf, buflen)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* SAL_IPADDR_H__ */
|
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
* File : sal_netdb.h
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2018-05-24 ChenYong First version
|
||||||
|
*/
|
||||||
|
#ifndef SAL_NETDB_H__
|
||||||
|
#define SAL_NETDB_H__
|
||||||
|
|
||||||
|
#include <sal_socket.h>
|
||||||
|
|
||||||
|
#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);
|
||||||
|
|
||||||
|
#endif /* SAL_NETDB_H__ */
|
|
@ -0,0 +1,166 @@
|
||||||
|
/*
|
||||||
|
* File : sal_socket.h
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2018-05-24 ChenYong First version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SAL_SOCKET_H__
|
||||||
|
#define SAL_SOCKET_H__
|
||||||
|
|
||||||
|
#include "sal_ipaddr.h"
|
||||||
|
|
||||||
|
#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 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 AF_MAX (AF_AT + 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_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 */
|
||||||
|
|
||||||
|
struct sockaddr {
|
||||||
|
uint8_t sa_len;
|
||||||
|
sa_family_t sa_family;
|
||||||
|
char sa_data[14];
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 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];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sockaddr_storage {
|
||||||
|
uint8_t s2_len;
|
||||||
|
sa_family_t ss_family;
|
||||||
|
char s2_data1[2];
|
||||||
|
uint32_t s2_data2[3];
|
||||||
|
#if SAL_IPV6
|
||||||
|
u32_t s2_data3[3];
|
||||||
|
#endif /* SAL_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);
|
||||||
|
|
||||||
|
#endif /* SAL_SOCKET_H__ */
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* File : sal_type.h
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2018-05-17 ChenYong First version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SAL_TYPE_H__
|
||||||
|
#define SAL_TYPE_H__
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef int8_t err_t;
|
||||||
|
typedef uint8_t u8_t;
|
||||||
|
typedef int8_t s8_t;
|
||||||
|
typedef uint16_t u16_t;
|
||||||
|
typedef int16_t s16_t;
|
||||||
|
typedef uint32_t u32_t;
|
||||||
|
typedef int32_t s32_t;
|
||||||
|
typedef uintptr_t mem_ptr_t;
|
||||||
|
|
||||||
|
#endif /* SAL_TYPE_H__ */
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* File : inet.h
|
* File : inet.h
|
||||||
* This file is part of RT-Thread RTOS
|
* This file is part of RT-Thread RTOS
|
||||||
* COPYRIGHT (C) 2015, RT-Thread Development Team
|
* COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -25,6 +25,6 @@
|
||||||
#ifndef INET_H__
|
#ifndef INET_H__
|
||||||
#define INET_H__
|
#define INET_H__
|
||||||
|
|
||||||
#include <lwip/inet.h>
|
#include <sal_ipaddr.h>
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* File : netdb.h
|
* File : netdb.h
|
||||||
* This file is part of RT-Thread RTOS
|
* This file is part of RT-Thread RTOS
|
||||||
* COPYRIGHT (C) 2015, RT-Thread Development Team
|
* COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -20,6 +20,7 @@
|
||||||
* Change Logs:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2015-02-17 Bernard First version
|
* 2015-02-17 Bernard First version
|
||||||
|
* 2108-05-24 ChenYong Add socket abstraction layer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef NETDB_H__
|
#ifndef NETDB_H__
|
||||||
|
@ -29,7 +30,7 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <lwip/netdb.h>
|
#include <sal_netdb.h>
|
||||||
|
|
||||||
struct hostent *gethostbyname(const char *name);
|
struct hostent *gethostbyname(const char *name);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* File : in.h
|
* File : in.h
|
||||||
* This file is part of RT-Thread RTOS
|
* This file is part of RT-Thread RTOS
|
||||||
* COPYRIGHT (C) 2015, RT-Thread Development Team
|
* COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
#ifndef IN_H__
|
#ifndef IN_H__
|
||||||
#define IN_H__
|
#define IN_H__
|
||||||
|
|
||||||
#include <lwip/sockets.h>
|
#include <sys/socket.h>
|
||||||
|
|
||||||
#ifndef IN6_IS_ADDR_MULTICAST
|
#ifndef IN6_IS_ADDR_MULTICAST
|
||||||
#define IN6_IS_ADDR_MULTICAST(a) (((uint8_t *) (a))[0] == 0xff)
|
#define IN6_IS_ADDR_MULTICAST(a) (((uint8_t *) (a))[0] == 0xff)
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* File : tcp.h
|
* File : tcp.h
|
||||||
* This file is part of RT-Thread RTOS
|
* This file is part of RT-Thread RTOS
|
||||||
* COPYRIGHT (C) 2015, RT-Thread Development Team
|
* COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -25,6 +25,6 @@
|
||||||
#ifndef TCP_H__
|
#ifndef TCP_H__
|
||||||
#define TCP_H__
|
#define TCP_H__
|
||||||
|
|
||||||
#include <lwip/sockets.h>
|
#include <sys/socket.h>
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* File : udp.h
|
* File : udp.h
|
||||||
* This file is part of RT-Thread RTOS
|
* This file is part of RT-Thread RTOS
|
||||||
* COPYRIGHT (C) 2015, RT-Thread Development Team
|
* COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -25,6 +25,6 @@
|
||||||
#ifndef UDP_H__
|
#ifndef UDP_H__
|
||||||
#define UDP_H__
|
#define UDP_H__
|
||||||
|
|
||||||
#include <lwip/sockets.h>
|
#include <sys/socket.h>
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* File : socket.h
|
* File : socket.h
|
||||||
* This file is part of RT-Thread RTOS
|
* This file is part of RT-Thread RTOS
|
||||||
* COPYRIGHT (C) 2015, RT-Thread Development Team
|
* COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -20,74 +20,18 @@
|
||||||
* Change Logs:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2015-02-17 Bernard First version
|
* 2015-02-17 Bernard First version
|
||||||
|
* 2018-05-17 ChenYong Add socket abstraction layer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SOCKET_H__
|
#ifndef SYS_SOCKET_H_
|
||||||
#define SOCKET_H__
|
#define SYS_SOCKET_H_
|
||||||
|
|
||||||
|
#include <sal_socket.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include <lwip/sockets.h>
|
|
||||||
#include <lwip/api.h>
|
|
||||||
#include <lwip/init.h>
|
|
||||||
|
|
||||||
#include <rtdevice.h>
|
|
||||||
|
|
||||||
#if LWIP_VERSION < 0x2000000
|
|
||||||
typedef uint16_t sa_family_t;
|
|
||||||
typedef uint16_t in_port_t;
|
|
||||||
|
|
||||||
struct sockaddr_storage
|
|
||||||
{
|
|
||||||
sa_family_t ss_family; /* Address family */
|
|
||||||
char ss_data[14]; /* 14-bytes of address data */
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LWIP_VERSION < 0x2000000
|
|
||||||
#define SELWAIT_T int
|
|
||||||
#else
|
|
||||||
#ifndef SELWAIT_T
|
|
||||||
#define SELWAIT_T u8_t
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
};
|
|
||||||
struct lwip_sock *lwip_tryget_socket(int s);
|
|
||||||
|
|
||||||
int accept(int s, struct sockaddr *addr, socklen_t *addrlen);
|
int accept(int s, struct sockaddr *addr, socklen_t *addrlen);
|
||||||
int bind(int s, const struct sockaddr *name, socklen_t namelen);
|
int bind(int s, const struct sockaddr *name, socklen_t namelen);
|
||||||
int shutdown(int s, int how);
|
int shutdown(int s, int how);
|
||||||
|
@ -111,4 +55,4 @@ int ioctlsocket(int s, long cmd, void *arg);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif /* _SYS_SOCKET_H_ */
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* File : netdb.c
|
* File : net_netdb.c
|
||||||
* This file is part of RT-Thread RTOS
|
* This file is part of RT-Thread RTOS
|
||||||
* COPYRIGHT (C) 2015, RT-Thread Development Team
|
* COPYRIGHT (C) 2015, RT-Thread Development Team
|
||||||
*
|
*
|
||||||
|
@ -20,26 +20,28 @@
|
||||||
* Change Logs:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2015-02-17 Bernard First version
|
* 2015-02-17 Bernard First version
|
||||||
|
* 2108-05-24 ChenYong Add socket abstraction layer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "netdb.h"
|
#include <rtthread.h>
|
||||||
#include <lwip/netdb.h>
|
|
||||||
|
#include <netdb.h>
|
||||||
|
|
||||||
struct hostent *gethostbyname(const char *name)
|
struct hostent *gethostbyname(const char *name)
|
||||||
{
|
{
|
||||||
return lwip_gethostbyname(name);
|
return sal_gethostbyname(name);
|
||||||
}
|
}
|
||||||
RTM_EXPORT(gethostbyname);
|
RTM_EXPORT(gethostbyname);
|
||||||
|
|
||||||
int gethostbyname_r(const char *name, struct hostent *ret, char *buf,
|
int gethostbyname_r(const char *name, struct hostent *ret, char *buf,
|
||||||
size_t buflen, struct hostent **result, int *h_errnop)
|
size_t buflen, struct hostent **result, int *h_errnop)
|
||||||
{
|
{
|
||||||
return lwip_gethostbyname_r(name, ret, buf, buflen, result, h_errnop);
|
return sal_gethostbyname_r(name, ret, buf, buflen, result, h_errnop);
|
||||||
}
|
}
|
||||||
|
|
||||||
void freeaddrinfo(struct addrinfo *ai)
|
void freeaddrinfo(struct addrinfo *ai)
|
||||||
{
|
{
|
||||||
lwip_freeaddrinfo(ai);
|
sal_freeaddrinfo(ai);
|
||||||
}
|
}
|
||||||
RTM_EXPORT(freeaddrinfo);
|
RTM_EXPORT(freeaddrinfo);
|
||||||
|
|
||||||
|
@ -48,6 +50,6 @@ int getaddrinfo(const char *nodename,
|
||||||
const struct addrinfo *hints,
|
const struct addrinfo *hints,
|
||||||
struct addrinfo **res)
|
struct addrinfo **res)
|
||||||
{
|
{
|
||||||
return lwip_getaddrinfo(nodename, servname, hints, res);
|
return sal_getaddrinfo(nodename, servname, hints, res);
|
||||||
}
|
}
|
||||||
RTM_EXPORT(getaddrinfo);
|
RTM_EXPORT(getaddrinfo);
|
|
@ -0,0 +1,284 @@
|
||||||
|
/*
|
||||||
|
* File : net_sockets.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2015, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* 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 <dfs_poll.h>
|
||||||
|
#include <dfs_net.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(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 socket;
|
||||||
|
struct dfs_fd *d;
|
||||||
|
|
||||||
|
d = fd_get(s);
|
||||||
|
if (d == NULL)
|
||||||
|
{
|
||||||
|
rt_set_errno(-EBADF);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
socket = dfs_net_getsocket(s);
|
||||||
|
if (sal_shutdown(socket, how) == 0)
|
||||||
|
{
|
||||||
|
/* socket has been closed, delete it from file system fd */
|
||||||
|
fd_put(d);
|
||||||
|
fd_put(d);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
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 socket = dfs_net_getsocket(s);
|
||||||
|
struct dfs_fd *d;
|
||||||
|
|
||||||
|
d = fd_get(s);
|
||||||
|
if(!d)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sal_closesocket(socket) == 0)
|
||||||
|
{
|
||||||
|
/* socket has been closed, delete it from file system fd */
|
||||||
|
fd_put(d);
|
||||||
|
fd_put(d);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
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);
|
|
@ -0,0 +1,271 @@
|
||||||
|
/*
|
||||||
|
* File : sal_ipaddr.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2018-05-18 ChenYong First version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sal_ipaddr.h>
|
||||||
|
#include <rtthread.h>
|
||||||
|
|
||||||
|
/* Here for now until needed in other places in lwIP */
|
||||||
|
#ifndef isprint
|
||||||
|
#define in_range(c, lo, up) ((u8_t)c >= lo && (u8_t)c <= up)
|
||||||
|
#define isprint(c) in_range(c, 0x20, 0x7f)
|
||||||
|
#define isdigit(c) in_range(c, '0', '9')
|
||||||
|
#define isxdigit(c) (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F'))
|
||||||
|
#define islower(c) in_range(c, 'a', 'z')
|
||||||
|
#define isspace(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v')
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether "cp" is a valid ascii representation
|
||||||
|
* of an Internet address and convert to a binary address.
|
||||||
|
* Returns 1 if the address is valid, 0 if not.
|
||||||
|
* This replaces inet_addr, the return value from which
|
||||||
|
* cannot distinguish between failure and a local broadcast address.
|
||||||
|
*
|
||||||
|
* @param cp IP address in ascii representation (e.g. "127.0.0.1")
|
||||||
|
* @param addr pointer to which to save the ip address in network order
|
||||||
|
* @return 1 if cp could be converted to addr, 0 on failure
|
||||||
|
*/
|
||||||
|
int sal_ip4addr_aton(const char *cp, ip4_addr_t *addr)
|
||||||
|
{
|
||||||
|
u32_t val;
|
||||||
|
u8_t base;
|
||||||
|
char c;
|
||||||
|
u32_t parts[4];
|
||||||
|
u32_t *pp = parts;
|
||||||
|
|
||||||
|
c = *cp;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Collect number up to ``.''.
|
||||||
|
* Values are specified as for C:
|
||||||
|
* 0x=hex, 0=octal, 1-9=decimal.
|
||||||
|
*/
|
||||||
|
if (!isdigit(c))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
val = 0;
|
||||||
|
base = 10;
|
||||||
|
if (c == '0')
|
||||||
|
{
|
||||||
|
c = *++cp;
|
||||||
|
if (c == 'x' || c == 'X')
|
||||||
|
{
|
||||||
|
base = 16;
|
||||||
|
c = *++cp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
base = 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (isdigit(c))
|
||||||
|
{
|
||||||
|
val = (val * base) + (u32_t) (c - '0');
|
||||||
|
c = *++cp;
|
||||||
|
}
|
||||||
|
else if (base == 16 && isxdigit(c))
|
||||||
|
{
|
||||||
|
val = (val << 4) | (u32_t) (c + 10 - (islower(c) ? 'a' : 'A'));
|
||||||
|
c = *++cp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (c == '.')
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Internet format:
|
||||||
|
* a.b.c.d
|
||||||
|
* a.b.c (with c treated as 16 bits)
|
||||||
|
* a.b (with b treated as 24 bits)
|
||||||
|
*/
|
||||||
|
if (pp >= parts + 3)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
*pp++ = val;
|
||||||
|
c = *++cp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Check for trailing characters.
|
||||||
|
*/
|
||||||
|
if (c != '\0' && !isspace(c))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Concoct the address according to
|
||||||
|
* the number of parts specified.
|
||||||
|
*/
|
||||||
|
switch (pp - parts + 1)
|
||||||
|
{
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
return 0; /* initial nondigit */
|
||||||
|
|
||||||
|
case 1: /* a -- 32 bits */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2: /* a.b -- 8.24 bits */
|
||||||
|
if (val > 0xffffffUL)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (parts[0] > 0xff)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
val |= parts[0] << 24;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3: /* a.b.c -- 8.8.16 bits */
|
||||||
|
if (val > 0xffff)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ((parts[0] > 0xff) || (parts[1] > 0xff))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
val |= (parts[0] << 24) | (parts[1] << 16);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4: /* a.b.c.d -- 8.8.8.8 bits */
|
||||||
|
if (val > 0xff)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ((parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
RT_ASSERT(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (addr)
|
||||||
|
{
|
||||||
|
ip4_addr_set_u32(addr, htonl(val));
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Same as ipaddr_ntoa, but reentrant since a user-supplied buffer is used.
|
||||||
|
*
|
||||||
|
* @param addr ip address in network order to convert
|
||||||
|
* @param buf target buffer where the string is stored
|
||||||
|
* @param buflen length of buf
|
||||||
|
* @return either pointer to buf which now holds the ASCII
|
||||||
|
* representation of addr or NULL if buf was too small
|
||||||
|
*/
|
||||||
|
char *sal_ip4addr_ntoa_r(const ip4_addr_t *addr, char *buf, int buflen)
|
||||||
|
{
|
||||||
|
u32_t s_addr;
|
||||||
|
char inv[3];
|
||||||
|
char *rp;
|
||||||
|
u8_t *ap;
|
||||||
|
u8_t rem;
|
||||||
|
u8_t n;
|
||||||
|
u8_t i;
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
|
s_addr = ip4_addr_get_u32(addr);
|
||||||
|
|
||||||
|
rp = buf;
|
||||||
|
ap = (u8_t *) &s_addr;
|
||||||
|
for (n = 0; n < 4; n++)
|
||||||
|
{
|
||||||
|
i = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
rem = *ap % (u8_t) 10;
|
||||||
|
*ap /= (u8_t) 10;
|
||||||
|
inv[i++] = (char) ('0' + rem);
|
||||||
|
} while (*ap);
|
||||||
|
while (i--)
|
||||||
|
{
|
||||||
|
if (len++ >= buflen)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
*rp++ = inv[i];
|
||||||
|
}
|
||||||
|
if (len++ >= buflen)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
*rp++ = '.';
|
||||||
|
ap++;
|
||||||
|
}
|
||||||
|
*--rp = 0;
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert numeric IP address into decimal dotted ASCII representation.
|
||||||
|
* returns ptr to static buffer; not reentrant!
|
||||||
|
*
|
||||||
|
* @param addr ip address in network order to convert
|
||||||
|
* @return pointer to a global static (!) buffer that holds the ASCII
|
||||||
|
* representation of addr
|
||||||
|
*/
|
||||||
|
char *sal_ip4addr_ntoa(const ip4_addr_t *addr)
|
||||||
|
{
|
||||||
|
static char str[IP4ADDR_STRLEN_MAX];
|
||||||
|
return sal_ip4addr_ntoa_r(addr, str, IP4ADDR_STRLEN_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ascii internet address interpretation routine.
|
||||||
|
* The value returned is in network order.
|
||||||
|
*
|
||||||
|
* @param cp IP address in ascii representation (e.g. "127.0.0.1")
|
||||||
|
* @return ip address in network order
|
||||||
|
*/
|
||||||
|
in_addr_t sal_ipaddr_addr(const char *cp)
|
||||||
|
{
|
||||||
|
ip4_addr_t val;
|
||||||
|
|
||||||
|
if (sal_ip4addr_aton(cp, &val)) {
|
||||||
|
return ip4_addr_get_u32(&val);
|
||||||
|
}
|
||||||
|
return (IPADDR_NONE);
|
||||||
|
}
|
|
@ -0,0 +1,730 @@
|
||||||
|
/*
|
||||||
|
* File : sal_socket.c
|
||||||
|
* This file is part of RT-Thread RTOS
|
||||||
|
* COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2018-05-23 ChenYong First version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include <rthw.h>
|
||||||
|
|
||||||
|
#include <sal_socket.h>
|
||||||
|
#include <sal_netdb.h>
|
||||||
|
#include <sal.h>
|
||||||
|
|
||||||
|
#define DBG_ENABLE
|
||||||
|
#define DBG_SECTION_NAME "SAL_SOC"
|
||||||
|
#define DBG_LEVEL DBG_INFO
|
||||||
|
#define DBG_COLOR
|
||||||
|
#include <rtdbg.h>
|
||||||
|
|
||||||
|
/* the socket table used to dynamic allocate sockets */
|
||||||
|
struct sal_socket_table
|
||||||
|
{
|
||||||
|
uint32_t max_socket;
|
||||||
|
struct sal_socket **sockets;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The global array of available protocol families */
|
||||||
|
static struct proto_family proto_families[SAL_PROTO_FAMILIES_NUM];
|
||||||
|
/* The global socket table */
|
||||||
|
static struct sal_socket_table socket_table;
|
||||||
|
static struct rt_mutex sal_core_lock;
|
||||||
|
static rt_bool_t init_ok = RT_FALSE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SAL (Socket Abstraction Layer) initialization.
|
||||||
|
*
|
||||||
|
* @return result
|
||||||
|
* >= 0: initialize success
|
||||||
|
*/
|
||||||
|
int sal_init(void)
|
||||||
|
{
|
||||||
|
if(init_ok)
|
||||||
|
{
|
||||||
|
LOG_D("Socket Abstraction Layer is already initialized.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clean sal socket table */
|
||||||
|
memset(&socket_table, 0, sizeof(socket_table));
|
||||||
|
/* create sal socket lock */
|
||||||
|
rt_mutex_init(&sal_core_lock, "sal_lock", RT_IPC_FLAG_FIFO);
|
||||||
|
|
||||||
|
LOG_I("Socket Abstraction Layer initialize success.");
|
||||||
|
init_ok = RT_TRUE;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
INIT_COMPONENT_EXPORT(sal_init);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function will register the current protocol family to the global array of protocol families.
|
||||||
|
*
|
||||||
|
* @param pf protocol families structure
|
||||||
|
*
|
||||||
|
* @return 0 : protocol families structure index
|
||||||
|
* -1 : the global array of available protocol families is full
|
||||||
|
*/
|
||||||
|
int sal_proto_family_register(const struct proto_family *pf)
|
||||||
|
{
|
||||||
|
rt_base_t level;
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
/* disable interrupt */
|
||||||
|
level = rt_hw_interrupt_disable();
|
||||||
|
|
||||||
|
/* find an empty protocol family entry */
|
||||||
|
for(idx = 0; idx < SAL_PROTO_FAMILIES_NUM && proto_families[idx].create; idx++);
|
||||||
|
|
||||||
|
/* can't find an empty protocol family entry */
|
||||||
|
if(idx == SAL_PROTO_FAMILIES_NUM)
|
||||||
|
{
|
||||||
|
/* enable interrupt */
|
||||||
|
rt_hw_interrupt_enable(level);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
proto_families[idx].family = pf->family;
|
||||||
|
proto_families[idx].sec_family = pf->sec_family;
|
||||||
|
proto_families[idx].create = pf->create;
|
||||||
|
|
||||||
|
proto_families[idx].gethostbyname = pf->gethostbyname;
|
||||||
|
proto_families[idx].gethostbyname_r = pf->gethostbyname_r;
|
||||||
|
proto_families[idx].freeaddrinfo = pf->freeaddrinfo;
|
||||||
|
proto_families[idx].getaddrinfo = pf->getaddrinfo;
|
||||||
|
|
||||||
|
/* enable interrupt */
|
||||||
|
rt_hw_interrupt_enable(level);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function will get socket structure by sal socket descriptor
|
||||||
|
*
|
||||||
|
* @param socket sal socket index
|
||||||
|
*
|
||||||
|
* @return socket structure of the current sal socket index
|
||||||
|
*/
|
||||||
|
struct sal_socket *sal_get_socket(int socket)
|
||||||
|
{
|
||||||
|
struct sal_socket_table *st = &socket_table;
|
||||||
|
|
||||||
|
if (socket < 0 || socket >= (int) st->max_socket)
|
||||||
|
{
|
||||||
|
return RT_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
socket = socket - SAL_SOCKET_OFFSET;
|
||||||
|
/* check socket structure valid or not */
|
||||||
|
if (st->sockets[socket]->magic != SAL_SOCKET_MAGIC)
|
||||||
|
{
|
||||||
|
return RT_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return st->sockets[socket];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function will lock sal socket.
|
||||||
|
*
|
||||||
|
* @note please don't invoke it on ISR.
|
||||||
|
*/
|
||||||
|
static void sal_lock(void)
|
||||||
|
{
|
||||||
|
rt_err_t result;
|
||||||
|
|
||||||
|
result = rt_mutex_take(&sal_core_lock, RT_WAITING_FOREVER);
|
||||||
|
if (result != RT_EOK)
|
||||||
|
{
|
||||||
|
RT_ASSERT(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function will lock sal socket.
|
||||||
|
*
|
||||||
|
* @note please don't invoke it on ISR.
|
||||||
|
*/
|
||||||
|
static void sal_unlock(void)
|
||||||
|
{
|
||||||
|
rt_mutex_release(&sal_core_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function will get protocol family structure by family type
|
||||||
|
*
|
||||||
|
* @param family protocol family
|
||||||
|
*
|
||||||
|
* @return protocol family structure address
|
||||||
|
*/
|
||||||
|
static struct proto_family *get_proto_family(int family)
|
||||||
|
{
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
for (idx = 0; idx < SAL_PROTO_FAMILIES_NUM; idx++)
|
||||||
|
{
|
||||||
|
if (proto_families[idx].family == family && proto_families[idx].create)
|
||||||
|
{
|
||||||
|
return &proto_families[idx];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* compare the secondary protocol families when primary protocol families find failed */
|
||||||
|
for (idx = 0; idx < SAL_PROTO_FAMILIES_NUM; idx++)
|
||||||
|
{
|
||||||
|
if (proto_families[idx].sec_family == family && proto_families[idx].create)
|
||||||
|
{
|
||||||
|
return &proto_families[idx];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return RT_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function will initialize socket structure and set socket options
|
||||||
|
*
|
||||||
|
* @param family protocol family
|
||||||
|
* @param type socket type
|
||||||
|
* @param protocol transfer Protocol
|
||||||
|
* @param res socket structure address
|
||||||
|
*
|
||||||
|
* @return 0 : socket initialize success
|
||||||
|
* -1 : input the wrong family
|
||||||
|
* -2 : input the wrong socket type
|
||||||
|
* -3 : get protocol family structure failed
|
||||||
|
* -4 : set socket options failed
|
||||||
|
*/
|
||||||
|
static int socket_init(int family, int type, int protocol, struct sal_socket **res)
|
||||||
|
{
|
||||||
|
struct sal_socket *sock;
|
||||||
|
struct proto_family *pf;
|
||||||
|
|
||||||
|
if (family < 0 || family > AF_MAX)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type < 0 || type > SOCK_MAX)
|
||||||
|
{
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
sock = *res;
|
||||||
|
sock->domain = family;
|
||||||
|
sock->type = type;
|
||||||
|
sock->protocol = protocol;
|
||||||
|
|
||||||
|
/* get socket protocol family structure */
|
||||||
|
if ((pf = get_proto_family(family)) == RT_NULL)
|
||||||
|
{
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* registered the current socket options */
|
||||||
|
if (pf->create(sock, type, protocol) != 0)
|
||||||
|
{
|
||||||
|
return -4;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int socket_alloc(struct sal_socket_table *st, int f_socket)
|
||||||
|
{
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
/* find an empty socket entry */
|
||||||
|
for (idx = f_socket; idx < (int) st->max_socket; idx++)
|
||||||
|
{
|
||||||
|
if (st->sockets[idx] == RT_NULL)
|
||||||
|
break;
|
||||||
|
if (st->sockets[idx]->ops == RT_NULL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allocate a larger sockte container */
|
||||||
|
if (idx == (int) st->max_socket && st->max_socket < SAL_SOCKETS_NUM)
|
||||||
|
{
|
||||||
|
int cnt, index;
|
||||||
|
struct sal_socket **sockets;
|
||||||
|
|
||||||
|
/* increase the number of FD with 4 step length */
|
||||||
|
cnt = st->max_socket + 4;
|
||||||
|
cnt = cnt > SAL_SOCKETS_NUM ? SAL_SOCKETS_NUM : cnt;
|
||||||
|
|
||||||
|
sockets = rt_realloc(st->sockets, cnt * sizeof(struct sal_socket *));
|
||||||
|
if (sockets == RT_NULL)
|
||||||
|
goto __result; /* return st->max_socket */
|
||||||
|
|
||||||
|
/* clean the new allocated fds */
|
||||||
|
for (index = st->max_socket; index < cnt; index++)
|
||||||
|
{
|
||||||
|
sockets[index] = RT_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
st->sockets = sockets;
|
||||||
|
st->max_socket = cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allocate 'struct sal_socket' */
|
||||||
|
if (idx < (int) st->max_socket && st->sockets[idx] == RT_NULL)
|
||||||
|
{
|
||||||
|
st->sockets[idx] = rt_malloc(sizeof(struct sal_socket));
|
||||||
|
if (st->sockets[idx] == RT_NULL)
|
||||||
|
{
|
||||||
|
idx = st->max_socket;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__result:
|
||||||
|
return idx;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function will return a empty sal socket structure address
|
||||||
|
*
|
||||||
|
* @return sal socket structure address
|
||||||
|
*/
|
||||||
|
static int socket_new(void)
|
||||||
|
{
|
||||||
|
struct sal_socket *sock;
|
||||||
|
struct sal_socket_table *st = &socket_table;
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
sal_lock();
|
||||||
|
|
||||||
|
/* find an empty sal socket entry */
|
||||||
|
idx = socket_alloc(st, 0);
|
||||||
|
|
||||||
|
/* can't find an empty sal socket entry */
|
||||||
|
if (idx == (int) st->max_socket)
|
||||||
|
{
|
||||||
|
idx = -(1 + SAL_SOCKET_OFFSET);
|
||||||
|
goto __result;
|
||||||
|
}
|
||||||
|
|
||||||
|
sock = st->sockets[idx];
|
||||||
|
sock->socket = idx + SAL_SOCKET_OFFSET;
|
||||||
|
sock->magic = SAL_SOCKET_MAGIC;
|
||||||
|
|
||||||
|
__result:
|
||||||
|
sal_unlock();
|
||||||
|
return idx + SAL_SOCKET_OFFSET;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sal_accept(int socket, struct sockaddr *addr, socklen_t *addrlen)
|
||||||
|
{
|
||||||
|
int new_socket;
|
||||||
|
struct sal_socket *sock;
|
||||||
|
|
||||||
|
sock = sal_get_socket(socket);
|
||||||
|
if (!sock)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sock->ops->accept == RT_NULL)
|
||||||
|
{
|
||||||
|
return -RT_ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_socket = sock->ops->accept((int) sock->user_data, addr, addrlen);
|
||||||
|
if (new_socket != -1)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
int new_socket;
|
||||||
|
struct sal_socket *new_sock;
|
||||||
|
|
||||||
|
/* allocate a new socket structure and registered socket options */
|
||||||
|
new_socket = socket_new();
|
||||||
|
if (new_socket < 0)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
new_sock = sal_get_socket(new_socket);
|
||||||
|
|
||||||
|
retval = socket_init(sock->domain, sock->type, sock->protocol, &new_sock);
|
||||||
|
if (retval < 0)
|
||||||
|
{
|
||||||
|
LOG_E("New socket registered failed, return error %d.", retval);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* socket struct user_data used to store the acquired new socket */
|
||||||
|
new_sock->user_data = (void *) new_socket;
|
||||||
|
|
||||||
|
return new_sock->socket;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sal_bind(int socket, const struct sockaddr *name, socklen_t namelen)
|
||||||
|
{
|
||||||
|
struct sal_socket *sock;
|
||||||
|
|
||||||
|
sock = sal_get_socket(socket);
|
||||||
|
if (!sock)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sock->ops->bind == RT_NULL)
|
||||||
|
{
|
||||||
|
return -RT_ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sock->ops->bind((int) sock->user_data, name, namelen);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sal_shutdown(int socket, int how)
|
||||||
|
{
|
||||||
|
struct sal_socket *sock;
|
||||||
|
|
||||||
|
sock = sal_get_socket(socket);
|
||||||
|
if (!sock)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sock->ops->shutdown == RT_NULL)
|
||||||
|
{
|
||||||
|
return -RT_ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sock->ops->shutdown((int) sock->user_data, how) == 0)
|
||||||
|
{
|
||||||
|
memset(sock, 0x00, sizeof(struct sal_socket));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sal_getpeername(int socket, struct sockaddr *name, socklen_t *namelen)
|
||||||
|
{
|
||||||
|
struct sal_socket *sock;
|
||||||
|
|
||||||
|
sock = sal_get_socket(socket);
|
||||||
|
if (!sock)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sock->ops->getpeername == RT_NULL)
|
||||||
|
{
|
||||||
|
return -RT_ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sock->ops->getpeername((int) sock->user_data, name, namelen);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sal_getsockname(int socket, struct sockaddr *name, socklen_t *namelen)
|
||||||
|
{
|
||||||
|
struct sal_socket *sock;
|
||||||
|
|
||||||
|
sock = sal_get_socket(socket);
|
||||||
|
if (!sock)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sock->ops->getsockname == RT_NULL)
|
||||||
|
{
|
||||||
|
return -RT_ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sock->ops->getsockname((int) sock->user_data, name, namelen);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sal_getsockopt(int socket, int level, int optname, void *optval, socklen_t *optlen)
|
||||||
|
{
|
||||||
|
struct sal_socket *sock;
|
||||||
|
|
||||||
|
sock = sal_get_socket(socket);
|
||||||
|
if (!sock)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sock->ops->getsockopt == RT_NULL)
|
||||||
|
{
|
||||||
|
return -RT_ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sock->ops->getsockopt((int) sock->user_data, level, optname, optval, optlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sal_setsockopt(int socket, int level, int optname, const void *optval, socklen_t optlen)
|
||||||
|
{
|
||||||
|
struct sal_socket *sock;
|
||||||
|
|
||||||
|
sock = sal_get_socket(socket);
|
||||||
|
if (!sock)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sock->ops->setsockopt == RT_NULL)
|
||||||
|
{
|
||||||
|
return -RT_ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sock->ops->setsockopt((int) sock->user_data, level, optname, optval, optlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sal_connect(int socket, const struct sockaddr *name, socklen_t namelen)
|
||||||
|
{
|
||||||
|
struct sal_socket *sock;
|
||||||
|
|
||||||
|
sock = sal_get_socket(socket);
|
||||||
|
if (!sock)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sock->ops->connect == RT_NULL)
|
||||||
|
{
|
||||||
|
return -RT_ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sock->ops->connect((int) sock->user_data, name, namelen);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sal_listen(int socket, int backlog)
|
||||||
|
{
|
||||||
|
struct sal_socket *sock;
|
||||||
|
|
||||||
|
sock = sal_get_socket(socket);
|
||||||
|
if (!sock)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sock->ops->listen == RT_NULL)
|
||||||
|
{
|
||||||
|
return -RT_ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sock->ops->listen((int) sock->user_data, backlog);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sal_recvfrom(int socket, void *mem, size_t len, int flags,
|
||||||
|
struct sockaddr *from, socklen_t *fromlen)
|
||||||
|
{
|
||||||
|
struct sal_socket *sock;
|
||||||
|
|
||||||
|
sock = sal_get_socket(socket);
|
||||||
|
if (!sock)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sock->ops->recvfrom == RT_NULL)
|
||||||
|
{
|
||||||
|
return -RT_ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sock->ops->recvfrom((int) sock->user_data, mem, len, flags, from, fromlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sal_sendto(int socket, const void *dataptr, size_t size, int flags,
|
||||||
|
const struct sockaddr *to, socklen_t tolen)
|
||||||
|
{
|
||||||
|
struct sal_socket *sock;
|
||||||
|
|
||||||
|
sock = sal_get_socket(socket);
|
||||||
|
if (!sock)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sock->ops->sendto == RT_NULL)
|
||||||
|
{
|
||||||
|
return -RT_ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sock->ops->sendto((int) sock->user_data, dataptr, size, flags, to, tolen);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sal_socket(int domain, int type, int protocol)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
int socket, proto_socket;
|
||||||
|
struct sal_socket *sock;
|
||||||
|
|
||||||
|
/* allocate a new socket and registered socket options */
|
||||||
|
socket = socket_new();
|
||||||
|
if (socket < 0)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
sock = sal_get_socket(socket);
|
||||||
|
|
||||||
|
retval = socket_init(domain, type, protocol, &sock);
|
||||||
|
if (retval < 0)
|
||||||
|
{
|
||||||
|
LOG_E("SAL socket protocol family input failed, return error %d.", retval);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sock->ops->socket == RT_NULL)
|
||||||
|
{
|
||||||
|
return -RT_ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
proto_socket = sock->ops->socket(domain, type, protocol);
|
||||||
|
if (proto_socket >= 0)
|
||||||
|
{
|
||||||
|
sock->user_data = (void *) proto_socket;
|
||||||
|
|
||||||
|
return sock->socket;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sal_closesocket(int socket)
|
||||||
|
{
|
||||||
|
struct sal_socket *sock;
|
||||||
|
|
||||||
|
sock = sal_get_socket(socket);
|
||||||
|
if (!sock)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sock->ops->closesocket == RT_NULL)
|
||||||
|
{
|
||||||
|
return -RT_ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sock->ops->closesocket((int) sock->user_data) == 0)
|
||||||
|
{
|
||||||
|
memset(sock, 0x00, sizeof(struct sal_socket));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sal_ioctlsocket(int socket, long cmd, void *arg)
|
||||||
|
{
|
||||||
|
struct sal_socket *sock;
|
||||||
|
|
||||||
|
sock = sal_get_socket(socket);
|
||||||
|
if (!sock)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sock->ops->ioctlsocket == RT_NULL)
|
||||||
|
{
|
||||||
|
return -RT_ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sock->ops->ioctlsocket((int) sock->user_data, cmd, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sal_poll(struct dfs_fd *file, struct rt_pollreq *req)
|
||||||
|
{
|
||||||
|
struct sal_socket *sock;
|
||||||
|
int socket = (int) file->data;
|
||||||
|
|
||||||
|
sock = sal_get_socket(socket);
|
||||||
|
if (!sock)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sock->ops->poll == RT_NULL)
|
||||||
|
{
|
||||||
|
return -RT_ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sock->ops->poll(file, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct hostent *sal_gethostbyname(const char *name)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < SAL_PROTO_FAMILIES_NUM; ++i)
|
||||||
|
{
|
||||||
|
if (proto_families[i].gethostbyname)
|
||||||
|
{
|
||||||
|
return proto_families[i].gethostbyname(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return RT_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sal_gethostbyname_r(const char *name, struct hostent *ret, char *buf,
|
||||||
|
size_t buflen, struct hostent **result, int *h_errnop)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < SAL_PROTO_FAMILIES_NUM; ++i)
|
||||||
|
{
|
||||||
|
if (proto_families[i].gethostbyname_r)
|
||||||
|
{
|
||||||
|
return proto_families[i].gethostbyname_r(name, ret, buf, buflen, result, h_errnop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sal_freeaddrinfo(struct addrinfo *ai)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < SAL_PROTO_FAMILIES_NUM; ++i)
|
||||||
|
{
|
||||||
|
if (proto_families[i].freeaddrinfo)
|
||||||
|
{
|
||||||
|
proto_families[i].freeaddrinfo(ai);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int sal_getaddrinfo(const char *nodename,
|
||||||
|
const char *servname,
|
||||||
|
const struct addrinfo *hints,
|
||||||
|
struct addrinfo **res)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < SAL_PROTO_FAMILIES_NUM; ++i)
|
||||||
|
{
|
||||||
|
if (proto_families[i].getaddrinfo)
|
||||||
|
{
|
||||||
|
return proto_families[i].getaddrinfo(nodename, servname, hints, res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
|
@ -1,13 +1,13 @@
|
||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
|
||||||
#ifdef RT_USING_DFS_NET
|
#ifdef SAL_USING_POSIX
|
||||||
#include <sys/select.h> // only dfs_net
|
#include <sys/select.h> // only dfs_net
|
||||||
#include <dfs_posix.h>
|
#include <dfs_posix.h>
|
||||||
#else
|
#else
|
||||||
#define read lwip_read
|
#define read lwip_read
|
||||||
#define write lwip_write
|
#define write lwip_write
|
||||||
#endif /* RT_USING_DFS_NET */
|
#endif /* SAL_USING_POSIX */
|
||||||
|
|
||||||
#include "netdb.h"
|
#include "netdb.h"
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#ifdef RT_USING_DFS_NET
|
#ifdef SAL_USING_POSIX
|
||||||
|
|
||||||
#ifdef FD_SETSIZE
|
#ifdef FD_SETSIZE
|
||||||
#undef FD_SETSIZE
|
#undef FD_SETSIZE
|
||||||
|
|
|
@ -29,8 +29,8 @@
|
||||||
#error "POSIX poll/select, stdin need file system(RT_USING_DFS) and device file system(RT_USING_DFS_DEVFS)"
|
#error "POSIX poll/select, stdin need file system(RT_USING_DFS) and device file system(RT_USING_DFS_DEVFS)"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(RT_USING_LWIP) && !defined(RT_USING_DFS_NET)
|
#if defined(RT_USING_LWIP) && !defined(SAL_USING_POSIX)
|
||||||
#error "POSIX poll/select, stdin need file BSD socket API(RT_USING_DFS_NET)"
|
#error "POSIX poll/select, stdin need file BSD socket API(SAL_USING_POSIX)"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(RT_USING_LIBC)
|
#if !defined(RT_USING_LIBC)
|
||||||
|
|
Loading…
Reference in New Issue