Browse Source

[net][sal] Add SAL (socket abstraction layer) framework

chenyong 7 years ago
parent
commit
8cda48a132
32 changed files with 2378 additions and 544 deletions
  1. 1 9
      components/dfs/Kconfig
  2. 0 17
      components/dfs/filesystems/net/SConscript
  3. 0 362
      components/dfs/filesystems/net/net_sockets.c
  4. 41 2
      components/net/Kconfig
  5. 1 1
      components/net/lwip-1.4.1/src/lwipopts.h
  6. 1 1
      components/net/lwip-2.0.2/SConscript
  7. 2 2
      components/net/lwip-2.0.2/src/api/sockets.c
  8. 1 1
      components/net/lwip-2.0.2/src/lwipopts.h
  9. 31 0
      components/net/sal_socket/SConscript
  10. 18 62
      components/net/sal_socket/dfs_net/dfs_net.c
  11. 125 0
      components/net/sal_socket/impl/af_inet_at.c
  12. 302 0
      components/net/sal_socket/impl/af_inet_lwip.c
  13. 1 1
      components/net/sal_socket/include/dfs_net/dfs_net.h
  14. 1 1
      components/net/sal_socket/include/dfs_net/sys_select/sys/select.h
  15. 101 0
      components/net/sal_socket/include/sal.h
  16. 138 0
      components/net/sal_socket/include/sal_ipaddr.h
  17. 91 0
      components/net/sal_socket/include/sal_netdb.h
  18. 166 0
      components/net/sal_socket/include/sal_socket.h
  19. 40 0
      components/net/sal_socket/include/sal_type.h
  20. 2 2
      components/net/sal_socket/include/socket/arpa/inet.h
  21. 3 2
      components/net/sal_socket/include/socket/netdb.h
  22. 2 2
      components/net/sal_socket/include/socket/netinet/in.h
  23. 2 2
      components/net/sal_socket/include/socket/netinet/tcp.h
  24. 2 2
      components/net/sal_socket/include/socket/netinet/udp.h
  25. 7 63
      components/net/sal_socket/include/socket/sys_socket/sys/socket.h
  26. 9 7
      components/net/sal_socket/socket/net_netdb.c
  27. 284 0
      components/net/sal_socket/socket/net_sockets.c
  28. 271 0
      components/net/sal_socket/src/sal_ipaddr.c
  29. 730 0
      components/net/sal_socket/src/sal_socket.c
  30. 2 2
      examples/network/chargen.c
  31. 1 1
      include/libc/libc_fdset.h
  32. 2 2
      include/rtdebug.h

+ 1 - 9
components/dfs/Kconfig

@@ -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

+ 0 - 17
components/dfs/filesystems/net/SConscript

@@ -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')

+ 0 - 362
components/dfs/filesystems/net/net_sockets.c

@@ -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);

+ 41 - 2
components/net/Kconfig

@@ -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
@@ -227,7 +267,6 @@ config LWIP_USING_DHCPD
                 default 1.1.1.1
                 default 1.1.1.1
         endif
         endif
     endif
     endif
-    
 
 
 endif
 endif
 
 

+ 1 - 1
components/net/lwip-1.4.1/src/lwipopts.h

@@ -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

+ 1 - 1
components/net/lwip-2.0.2/SConscript

@@ -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']):

+ 2 - 2
components/net/lwip-2.0.2/src/api/sockets.c

@@ -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
 };
 };

+ 1 - 1
components/net/lwip-2.0.2/src/lwipopts.h

@@ -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

+ 31 - 0
components/net/sal_socket/SConscript

@@ -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')

+ 18 - 62
components/dfs/filesystems/net/dfs_net.c → components/net/sal_socket/dfs_net/dfs_net.c

@@ -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_file.h>
-#include <dfs_posix.h>
+#include <dfs_net.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;
-    else sock = (int)_dfs_fd->data;
+    if (_dfs_fd->type != FT_SOCKET) socket = -1;
+    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;
-
-    sock = (int)file->data;
-    count = lwip_read(sock, buf, count);
+    int socket = (int) file->data;
 
 
-    return count;
+    return sal_recvfrom(socket, buf, count, 0, NULL, NULL);
 }
 }
 
 
 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;
-    
-    sock = (int)file->data;
-    count = lwip_write(sock, buf, count);
+    int socket = (int) file->data;
 
 
-    return count;
+    return sal_sendto(socket, buf, count, 0, NULL, 0);
 }
 }
 
 
 static int dfs_net_close(struct dfs_fd* file)
 static int dfs_net_close(struct dfs_fd* file)
 {
 {
-    int sock;
-    int result;
-    
-    sock = (int)file->data;
-    result = lwip_close(sock);
-    
-    if (result == 0) return RT_EOK;
-    
-    return -result;
+    int socket = (int) file->data;
+
+    return sal_closesocket(socket);
 }
 }
 
 
 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;
-    int mask = 0;
-    struct lwip_sock *sock;
-
-    sfd = (int)file->data;
-
-    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;
+    extern int sal_poll(struct dfs_fd *file, struct rt_pollreq *req);
+
+    return sal_poll(file, req);
 }
 }
 
 
 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;
 }
 }
-

+ 125 - 0
components/net/sal_socket/impl/af_inet_at.c

@@ -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);

+ 302 - 0
components/net/sal_socket/impl/af_inet_lwip.c

@@ -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);

+ 1 - 1
components/dfs/filesystems/net/dfs_net.h → components/net/sal_socket/include/dfs_net/dfs_net.h

@@ -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 - 1
components/dfs/filesystems/net/select/sys/select.h → components/net/sal_socket/include/dfs_net/sys_select/sys/select.h

@@ -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

+ 101 - 0
components/net/sal_socket/include/sal.h

@@ -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__ */

+ 138 - 0
components/net/sal_socket/include/sal_ipaddr.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__ */

+ 91 - 0
components/net/sal_socket/include/sal_netdb.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__ */

+ 166 - 0
components/net/sal_socket/include/sal_socket.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__ */

+ 40 - 0
components/net/sal_socket/include/sal_type.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__ */

+ 2 - 2
components/dfs/filesystems/net/arpa/inet.h → components/net/sal_socket/include/socket/arpa/inet.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

+ 3 - 2
components/dfs/filesystems/net/netdb.h → components/net/sal_socket/include/socket/netdb.h

@@ -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);
 
 

+ 2 - 2
components/dfs/filesystems/net/netinet/in.h → components/net/sal_socket/include/socket/netinet/in.h

@@ -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)

+ 2 - 2
components/dfs/filesystems/net/netinet/tcp.h → components/net/sal_socket/include/socket/netinet/tcp.h

@@ -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

+ 2 - 2
components/dfs/filesystems/net/netinet/udp.h → components/net/sal_socket/include/socket/netinet/udp.h

@@ -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

+ 7 - 63
components/dfs/filesystems/net/socket/sys/socket.h → components/net/sal_socket/include/socket/sys_socket/sys/socket.h

@@ -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__
-#define SOCKET_H__
+#ifndef SYS_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_ */

+ 9 - 7
components/dfs/filesystems/net/net_netdb.c → components/net/sal_socket/socket/net_netdb.c

@@ -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 <lwip/netdb.h>
+#include <rtthread.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);

+ 284 - 0
components/net/sal_socket/socket/net_sockets.c

@@ -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);

+ 271 - 0
components/net/sal_socket/src/sal_ipaddr.c

@@ -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);
+}

+ 730 - 0
components/net/sal_socket/src/sal_socket.c

@@ -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;
+}

+ 2 - 2
examples/network/chargen.c

@@ -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"
 
 

+ 1 - 1
include/libc/libc_fdset.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

+ 2 - 2
include/rtdebug.h

@@ -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)
-#error "POSIX poll/select, stdin need file BSD socket API(RT_USING_DFS_NET)"
+#if defined(RT_USING_LWIP) && !defined(SAL_USING_POSIX)
+#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)