浏览代码

add the first porting for lwip 1.4.1

Bernard Xiong 12 年之前
父节点
当前提交
86fc696957

+ 5 - 0
components/net/SConscript

@@ -1,10 +1,15 @@
 # for network related component
 import os
 Import('RTT_ROOT')
+from building import *
 
 objs = []
 list = os.listdir(os.path.join(RTT_ROOT, 'components', 'net'))
 
+# the default version of LWIP is 1.4.0
+if not GetDepend('RT_USING_LWIP132') and not GetDepend('RT_USING_LWIP141'):
+    AddDepend('RT_USING_LWIP140')
+
 for d in list:
     path = os.path.join(RTT_ROOT, 'components', 'net', d)
     if os.path.isfile(os.path.join(path, 'SConscript')):

+ 87 - 0
components/net/lwip-1.4.1/SConscript

@@ -0,0 +1,87 @@
+Import('RTT_ROOT')
+from building import *
+
+src = Split("""
+src/api/api_lib.c
+src/api/api_msg.c
+src/api/err.c
+src/api/netbuf.c
+src/api/netdb.c
+src/api/netifapi.c
+src/api/sockets.c
+src/api/tcpip.c
+src/arch/sys_arch.c
+src/core/def.c
+src/core/dhcp.c
+src/core/dns.c
+src/core/init.c
+src/core/memp.c
+src/core/netif.c
+src/core/pbuf.c
+src/core/raw.c
+src/core/stats.c
+src/core/sys.c
+src/core/tcp.c
+src/core/tcp_in.c
+src/core/tcp_out.c
+src/core/timers.c
+src/core/udp.c
+src/core/ipv4/autoip.c
+src/core/ipv4/icmp.c
+src/core/ipv4/igmp.c
+src/core/ipv4/inet.c
+src/core/ipv4/inet_chksum.c
+src/core/ipv4/ip.c
+src/core/ipv4/ip_addr.c
+src/core/ipv4/ip_frag.c
+src/netif/etharp.c
+src/netif/ethernetif.c
+src/netif/slipif.c
+""")
+
+snmp_src = Split("""
+src/core/snmp/asn1_dec.c
+src/core/snmp/asn1_enc.c
+src/core/snmp/mib2.c
+src/core/snmp/mib_structs.c
+src/core/snmp/msg_in.c
+src/core/snmp/msg_out.c
+""")
+
+ppp_src = Split("""
+src/netif/ppp/auth.c
+src/netif/ppp/chap.c
+src/netif/ppp/chpms.c
+src/netif/ppp/fsm.c
+src/netif/ppp/ipcp.c
+src/netif/ppp/lcp.c
+src/netif/ppp/magic.c
+src/netif/ppp/md5.c
+src/netif/ppp/pap.c
+src/netif/ppp/ppp.c
+src/netif/ppp/ppp_oe.c
+src/netif/ppp/randm.c
+src/netif/ppp/vj.c
+""")
+
+# The set of source files associated with this SConscript file.
+path = [GetCurrentDir() + '/src',
+    GetCurrentDir() + '/src/include',
+    GetCurrentDir() + '/src/include/ipv4',
+    GetCurrentDir() + '/src/arch/include',
+    GetCurrentDir() + '/src/include/netif']
+
+if GetDepend(['RT_LWIP_SNMP']):
+    src += snmp_src
+
+if GetDepend(['RT_LWIP_PPP']):
+    src += ppp_src
+    path += [GetCurrentDir() + '/src/netif/ppp']
+
+# For testing apps
+if GetDepend(['RT_USING_NETUTILS']):
+    src += Glob('./apps/*.c')
+
+group = DefineGroup('LwIP', src, depend = ['RT_USING_LWIP', 'RT_USING_LWIP141'], CPPPATH = path)
+
+Return('group')

+ 35 - 0
components/net/lwip-1.4.1/src/arch/include/arch/bpstruct.h

@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#if defined(__ICCARM__)
+#pragma pack(1)
+#endif

+ 107 - 0
components/net/lwip-1.4.1/src/arch/include/arch/cc.h

@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2001, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: cc.h,v 1.1.1.1 2004/12/16 14:17:13 bear Exp $
+ */
+#ifndef __ARCH_CC_H__
+#define __ARCH_CC_H__
+
+#include <rthw.h>
+#include <rtthread.h>
+
+typedef rt_uint8_t	u8_t;
+typedef rt_int8_t	s8_t;
+typedef rt_uint16_t	u16_t;
+typedef rt_int16_t	s16_t;
+typedef rt_uint32_t	u32_t;
+typedef rt_int32_t	s32_t;
+typedef rt_uint32_t	mem_ptr_t;
+
+#define U16_F "hu"
+#define S16_F "hd"
+#define X16_F "hx"
+#define U32_F "lu"
+#define S32_F "ld"
+#define X32_F "lx"
+
+#ifdef RT_USING_NEWLIB
+#include <errno.h>
+/* some errno not defined in newlib */
+#define ENSRNOTFOUND 163  /* Domain name not found */
+/* WARNING: ESHUTDOWN also not defined in newlib. We chose
+			180 here because the number "108" which is used
+			in arch.h has been assigned to another error code. */
+#define ESHUTDOWN 180
+#elif RT_USING_MINILIBC
+#include <errno.h>
+#define  EADDRNOTAVAIL  99  /* Cannot assign requested address */
+#else
+#define LWIP_PROVIDE_ERRNO
+#endif
+
+#ifdef RT_USING_MINILIBC
+#include <time.h>
+#define LWIP_TIMEVAL_PRIVATE 0
+#endif
+
+#if defined(__CC_ARM)   /* ARMCC compiler */
+#define PACK_STRUCT_FIELD(x) x
+#define PACK_STRUCT_STRUCT __attribute__ ((__packed__))
+#define PACK_STRUCT_BEGIN
+#define PACK_STRUCT_END
+#elif defined(__IAR_SYSTEMS_ICC__)   /* IAR Compiler */
+#define PACK_STRUCT_BEGIN
+#define PACK_STRUCT_STRUCT
+#define PACK_STRUCT_END
+#define PACK_STRUCT_FIELD(x) x
+#define PACK_STRUCT_USE_INCLUDES
+#elif defined(__GNUC__)     /* GNU GCC Compiler */
+#define PACK_STRUCT_FIELD(x) x
+#define PACK_STRUCT_STRUCT __attribute__((packed))
+#define PACK_STRUCT_BEGIN
+#define PACK_STRUCT_END
+#elif defined(_MSC_VER)
+#define PACK_STRUCT_FIELD(x) x
+#define PACK_STRUCT_STRUCT
+#define PACK_STRUCT_BEGIN
+#define PACK_STRUCT_END
+#endif
+
+void sys_arch_assert(const char* file, int line);
+#define LWIP_PLATFORM_DIAG(x)	do {rt_kprintf x;} while(0)
+#define LWIP_PLATFORM_ASSERT(x) do {rt_kprintf(x); sys_arch_assert(__FILE__, __LINE__);}while(0)
+
+
+#include "string.h"
+
+#endif /* __ARCH_CC_H__ */
+

+ 35 - 0
components/net/lwip-1.4.1/src/arch/include/arch/epstruct.h

@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#if defined(__ICCARM__)
+#pragma pack()
+#endif

+ 52 - 0
components/net/lwip-1.4.1/src/arch/include/arch/perf.h

@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2001, Swedish Institute of Computer Science.
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: perf.h,v 1.1.1.1 2004/12/16 14:17:13 bear Exp $
+ */
+#ifndef __ARCH_PERF_H__
+#define __ARCH_PERF_H__
+
+//#include <sys/times.h>
+
+#define PERF_START    /* null definition */
+#define PERF_STOP(x)  /* null definition */
+
+/*
+void perf_print(unsigned long c1l, unsigned long c1h,
+		unsigned long c2l, unsigned long c2h,
+		char *key);
+
+void perf_print_times(struct tms *start, struct tms *end, char *key);
+
+void perf_init(char *fname);
+*/
+#endif /* __ARCH_PERF_H__ */

+ 63 - 0
components/net/lwip-1.4.1/src/arch/include/arch/sys_arch.h

@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2001, Swedish Institute of Computer Science.
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: sys_arch.h,v 1.3 2005/03/13 16:03:23 bear Exp $
+ */
+#ifndef __ARCH_SYS_ARCH_H__
+#define __ARCH_SYS_ARCH_H__
+
+#include "arch/cc.h"
+
+#include <rtthread.h>
+
+#ifndef BYTE_ORDER
+#define BYTE_ORDER LITTLE_ENDIAN
+#endif
+
+#define SYS_MBOX_NULL RT_NULL
+#define SYS_SEM_NULL  RT_NULL
+
+typedef u32_t sys_prot_t;
+
+#define SYS_MBOX_SIZE 10
+#define SYS_LWIP_TIMER_NAME "timer"
+#define SYS_LWIP_MBOX_NAME "mbox"
+#define SYS_LWIP_SEM_NAME "sem"
+#define SYS_LWIP_MUTEX_NAME "mu"
+
+typedef rt_sem_t sys_sem_t;
+typedef rt_mutex_t sys_mutex_t;
+typedef rt_mailbox_t  sys_mbox_t;
+typedef rt_thread_t sys_thread_t;
+
+
+#endif /* __ARCH_SYS_ARCH_H__ */

+ 635 - 0
components/net/lwip-1.4.1/src/arch/sys_arch.c

@@ -0,0 +1,635 @@
+/*
+ * File      : sys_arch.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2012, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2012-12-8      Bernard      add file header
+ *                             export bsd socket symbol for RT-Thread Application Module 
+ */
+
+#include <rtthread.h>
+
+#include "lwip/sys.h"
+#include "lwip/opt.h"
+#include "lwip/stats.h"
+#include "lwip/err.h"
+#include "arch/sys_arch.h"
+#include "lwip/debug.h"
+#include "lwip/netif.h"
+#include "lwip/tcpip.h"
+#include "netif/ethernetif.h"
+#include "lwip/sio.h"
+
+#include <string.h>
+
+static err_t netif_device_init(struct netif *netif)
+{
+    struct eth_device *ethif;
+
+    ethif = (struct eth_device *)netif->state;
+    if (ethif != RT_NULL)
+    {
+        rt_device_t device;
+
+        /* get device object */
+        device = (rt_device_t) ethif;
+        if (rt_device_init(device) != RT_EOK)
+        {
+            return ERR_IF;
+        }
+
+        /* copy device flags to netif flags */
+        netif->flags = ethif->flags;
+
+        return ERR_OK;
+    }
+
+    return ERR_IF;
+}
+
+static void tcpip_init_done_callback(void *arg)
+{
+    rt_device_t device;
+    struct eth_device *ethif;
+    struct ip_addr ipaddr, netmask, gw;
+    struct rt_list_node* node;
+    struct rt_object* object;
+    struct rt_object_information *information;
+
+    extern struct rt_object_information rt_object_container[];
+
+    LWIP_ASSERT("invalid arg.\n",arg);
+
+    IP4_ADDR(&gw, 0,0,0,0);
+    IP4_ADDR(&ipaddr, 0,0,0,0);
+    IP4_ADDR(&netmask, 0,0,0,0);
+
+    /* enter critical */
+    rt_enter_critical();
+
+    /* for each network interfaces */
+    information = &rt_object_container[RT_Object_Class_Device];
+    for (node = information->object_list.next;
+         node != &(information->object_list);
+         node = node->next)
+    {
+        object = rt_list_entry(node, struct rt_object, list);
+        device = (rt_device_t)object;
+        if (device->type == RT_Device_Class_NetIf)
+        {
+            ethif = (struct eth_device *)device;
+
+            /* leave critical */
+            rt_exit_critical();
+
+            netif_add(ethif->netif, &ipaddr, &netmask, &gw,
+                      ethif, netif_device_init, tcpip_input);
+
+            if (netif_default == RT_NULL)
+                netif_set_default(ethif->netif);
+
+#if LWIP_DHCP
+            if (ethif->flags & NETIF_FLAG_DHCP)
+            {
+                /* if this interface uses DHCP, start the DHCP client */
+                dhcp_start(ethif->netif);
+            }
+            else
+#endif
+            {
+                /* set interface up */
+                netif_set_up(ethif->netif);
+            }
+
+#ifdef LWIP_NETIF_LINK_CALLBACK
+            netif_set_link_up(ethif->netif);
+#endif
+
+            /* enter critical */
+            rt_enter_critical();
+        }
+    }
+
+    /* leave critical */
+    rt_exit_critical();
+    rt_sem_release((rt_sem_t)arg);
+}
+
+/**
+ * LwIP system initialization
+ */
+void lwip_system_init(void)
+{
+    rt_err_t rc;
+    struct rt_semaphore done_sem;
+
+    /* set default netif to NULL */
+    netif_default = RT_NULL;
+
+    rc = rt_sem_init(&done_sem, "done", 0, RT_IPC_FLAG_FIFO);
+
+    if (rc != RT_EOK)
+    {
+        LWIP_ASSERT("Failed to create semaphore", 0);
+
+        return;
+    }
+
+    tcpip_init(tcpip_init_done_callback, (void *)&done_sem);
+
+    /* waiting for initialization done */
+    if (rt_sem_take(&done_sem, RT_WAITING_FOREVER) != RT_EOK)
+    {
+        rt_sem_detach(&done_sem);
+
+        return;
+    }
+    rt_sem_detach(&done_sem);
+
+    /* set default ip address */
+#if !LWIP_DHCP
+    if (netif_default != RT_NULL)
+    {
+        struct ip_addr ipaddr, netmask, gw;
+
+        IP4_ADDR(&ipaddr, RT_LWIP_IPADDR0, RT_LWIP_IPADDR1, RT_LWIP_IPADDR2, RT_LWIP_IPADDR3);
+        IP4_ADDR(&gw, RT_LWIP_GWADDR0, RT_LWIP_GWADDR1, RT_LWIP_GWADDR2, RT_LWIP_GWADDR3);
+        IP4_ADDR(&netmask, RT_LWIP_MSKADDR0, RT_LWIP_MSKADDR1, RT_LWIP_MSKADDR2, RT_LWIP_MSKADDR3);
+
+        netifapi_netif_set_addr(netif_default, &ipaddr, &netmask, &gw);
+    }
+#endif
+}
+
+void sys_init(void)
+{
+    /* nothing on RT-Thread porting */
+}
+
+void lwip_sys_init(void)
+{
+    lwip_system_init();
+}
+
+err_t sys_sem_new(sys_sem_t *sem, u8_t count)
+{
+    static unsigned short counter = 0;
+    char tname[RT_NAME_MAX];
+    sys_sem_t tmpsem;
+
+    RT_DEBUG_NOT_IN_INTERRUPT;
+
+    rt_snprintf(tname, RT_NAME_MAX, "%s%d", SYS_LWIP_SEM_NAME, counter);
+    counter ++;
+
+    tmpsem = rt_sem_create(tname, count, RT_IPC_FLAG_FIFO);
+    if (tmpsem == RT_NULL)
+        return ERR_MEM;
+    else
+    {
+        *sem = tmpsem;
+
+        return ERR_OK;
+    }
+}
+
+void sys_sem_free(sys_sem_t *sem)
+{
+    RT_DEBUG_NOT_IN_INTERRUPT;
+    rt_sem_delete(*sem);
+}
+
+void sys_sem_signal(sys_sem_t *sem)
+{
+    rt_sem_release(*sem);
+}
+
+u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
+{
+    rt_err_t ret;
+    s32_t t;
+    u32_t tick;
+
+    RT_DEBUG_NOT_IN_INTERRUPT;
+
+    /* get the begin tick */
+    tick = rt_tick_get();
+    if (timeout == 0)
+        t = RT_WAITING_FOREVER;
+    else
+    {
+        /* convert msecond to os tick */
+        if (timeout < (1000/RT_TICK_PER_SECOND))
+            t = 1;
+        else
+            t = timeout / (1000/RT_TICK_PER_SECOND);
+    }
+
+    ret = rt_sem_take(*sem, t);
+
+    if (ret == -RT_ETIMEOUT)
+        return SYS_ARCH_TIMEOUT;
+    else
+    {
+        if (ret == RT_EOK)
+            ret = 1;
+    }
+
+    /* get elapse msecond */
+    tick = rt_tick_get() - tick;
+
+    /* convert tick to msecond */
+    tick = tick * (1000 / RT_TICK_PER_SECOND);
+    if (tick == 0)
+        tick = 1;
+
+    return tick;
+}
+
+#ifndef sys_sem_valid
+/** Check if a semaphore is valid/allocated:
+ *  return 1 for valid, 0 for invalid
+ */
+int sys_sem_valid(sys_sem_t *sem)
+{
+    return (int)(*sem);
+}
+#endif
+
+#ifndef sys_sem_set_invalid
+/** Set a semaphore invalid so that sys_sem_valid returns 0
+ */
+void sys_sem_set_invalid(sys_sem_t *sem)
+{
+    *sem = RT_NULL;
+}
+#endif
+
+/* ====================== Mutex ====================== */
+
+/** Create a new mutex
+ * @param mutex pointer to the mutex to create
+ * @return a new mutex
+ */
+err_t sys_mutex_new(sys_mutex_t *mutex)
+{
+    static unsigned short counter = 0;
+    char tname[RT_NAME_MAX];
+    sys_mutex_t tmpmutex;
+
+    RT_DEBUG_NOT_IN_INTERRUPT;
+
+    rt_snprintf(tname, RT_NAME_MAX, "%s%d", SYS_LWIP_MUTEX_NAME, counter);
+    counter ++;
+
+    tmpmutex = rt_mutex_create(tname, RT_IPC_FLAG_FIFO);
+    if (tmpmutex == RT_NULL)
+        return ERR_MEM;
+    else
+    {
+        *mutex = tmpmutex;
+
+        return ERR_OK;
+    }
+}
+
+/** Lock a mutex
+ * @param mutex the mutex to lock
+ */
+void sys_mutex_lock(sys_mutex_t *mutex)
+{
+    RT_DEBUG_NOT_IN_INTERRUPT;
+    rt_mutex_take(*mutex, RT_WAITING_FOREVER);
+
+    return;
+}
+
+/** Unlock a mutex
+ * @param mutex the mutex to unlock
+ */
+void sys_mutex_unlock(sys_mutex_t *mutex)
+{
+    rt_mutex_release(*mutex);
+}
+
+/** Delete a semaphore
+ * @param mutex the mutex to delete
+ */
+void sys_mutex_free(sys_mutex_t *mutex)
+{
+    RT_DEBUG_NOT_IN_INTERRUPT;
+
+    rt_mutex_delete(*mutex);
+}
+
+#ifndef sys_mutex_valid
+/** Check if a mutex is valid/allocated:
+ *  return 1 for valid, 0 for invalid
+ */
+int sys_mutex_valid(sys_mutex_t *mutex)
+{
+    return (int)(*mutex);
+}
+#endif
+
+#ifndef sys_mutex_set_invalid
+/** Set a mutex invalid so that sys_mutex_valid returns 0
+ */
+void sys_mutex_set_invalid(sys_mutex_t *mutex)
+{
+    *mutex = RT_NULL;
+}
+#endif
+
+/* ====================== Mailbox ====================== */
+
+err_t sys_mbox_new(sys_mbox_t *mbox, int size)
+{
+    static unsigned short counter = 0;
+    char tname[RT_NAME_MAX];
+    sys_mbox_t tmpmbox;
+
+    RT_DEBUG_NOT_IN_INTERRUPT;
+
+    rt_snprintf(tname, RT_NAME_MAX, "%s%d", SYS_LWIP_MBOX_NAME, counter);
+    counter ++;
+
+    tmpmbox = rt_mb_create(tname, size, RT_IPC_FLAG_FIFO);
+    if (tmpmbox != RT_NULL)
+    {
+        *mbox = tmpmbox;
+
+        return ERR_OK;
+    }
+
+    return ERR_MEM;
+}
+
+void sys_mbox_free(sys_mbox_t *mbox)
+{
+    RT_DEBUG_NOT_IN_INTERRUPT;
+
+    rt_mb_delete(*mbox);
+
+    return;
+}
+
+/** Post a message to an mbox - may not fail
+ * -> blocks if full, only used from tasks not from ISR
+ * @param mbox mbox to posts the message
+ * @param msg message to post (ATTENTION: can be NULL)
+ */
+void sys_mbox_post(sys_mbox_t *mbox, void *msg)
+{
+    RT_DEBUG_NOT_IN_INTERRUPT;
+
+    rt_mb_send_wait(*mbox, (rt_uint32_t)msg, RT_WAITING_FOREVER);
+
+    return;
+}
+
+err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
+{
+    if (rt_mb_send(*mbox, (rt_uint32_t)msg) == RT_EOK)
+        return ERR_OK;
+
+    return ERR_MEM;
+}
+
+/** Wait for a new message to arrive in the mbox
+ * @param mbox mbox to get a message from
+ * @param msg pointer where the message is stored
+ * @param timeout maximum time (in milliseconds) to wait for a message
+ * @return time (in milliseconds) waited for a message, may be 0 if not waited
+           or SYS_ARCH_TIMEOUT on timeout
+ *         The returned time has to be accurate to prevent timer jitter!
+ */
+u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
+{
+    rt_err_t ret;
+    s32_t t;
+    u32_t tick;
+
+    RT_DEBUG_NOT_IN_INTERRUPT;
+
+    /* get the begin tick */
+    tick = rt_tick_get();
+
+    if(timeout == 0)
+        t = RT_WAITING_FOREVER;
+    else
+    {
+        /* convirt msecond to os tick */
+        if (timeout < (1000/RT_TICK_PER_SECOND))
+            t = 1;
+        else
+            t = timeout / (1000/RT_TICK_PER_SECOND);
+    }
+
+    ret = rt_mb_recv(*mbox, (rt_uint32_t *)msg, t);
+
+    if(ret == -RT_ETIMEOUT)
+        return SYS_ARCH_TIMEOUT;
+    else
+    {
+        LWIP_ASSERT("rt_mb_recv returned with error!", ret == RT_EOK);
+    }
+
+    /* get elapse msecond */
+    tick = rt_tick_get() - tick;
+
+    /* convert tick to msecond */
+    tick = tick * (1000 / RT_TICK_PER_SECOND);
+    if (tick == 0)
+        tick = 1;
+
+    return tick;
+}
+
+/** Wait for a new message to arrive in the mbox
+ * @param mbox mbox to get a message from
+ * @param msg pointer where the message is stored
+ * @param timeout maximum time (in milliseconds) to wait for a message
+ * @return 0 (milliseconds) if a message has been received
+ *         or SYS_MBOX_EMPTY if the mailbox is empty
+ */
+u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
+{
+    int ret;
+
+    ret = rt_mb_recv(*mbox, (rt_uint32_t *)msg, 0);
+
+    if(ret == -RT_ETIMEOUT)
+        return SYS_ARCH_TIMEOUT;
+    else
+    {
+        if (ret == RT_EOK) 
+            ret = 1;
+    }
+
+    return ret;
+}
+
+#ifndef sys_mbox_valid
+/** Check if an mbox is valid/allocated:
+ *  return 1 for valid, 0 for invalid
+ */
+int sys_mbox_valid(sys_mbox_t *mbox)
+{
+    return (int)(*mbox);
+}
+#endif
+
+#ifndef sys_mbox_set_invalid
+/** Set an mbox invalid so that sys_mbox_valid returns 0
+ */
+void sys_mbox_set_invalid(sys_mbox_t *mbox)
+{
+    *mbox = RT_NULL;
+}
+#endif
+
+/* ====================== System ====================== */
+
+sys_thread_t sys_thread_new(const char    *name,
+                            lwip_thread_fn thread,
+                            void          *arg,
+                            int            stacksize,
+                            int            prio)
+{
+    rt_thread_t t;
+
+    RT_DEBUG_NOT_IN_INTERRUPT;
+
+    /* create thread */
+    t = rt_thread_create(name, thread, arg, stacksize, prio, 20);
+    RT_ASSERT(t != RT_NULL);
+
+    /* startup thread */
+    rt_thread_startup(t);
+
+    return t;
+}
+
+sys_prot_t sys_arch_protect(void)
+{
+    rt_base_t level;
+
+    /* disable interrupt */
+    level = rt_hw_interrupt_disable();
+
+    return level;
+}
+
+void sys_arch_unprotect(sys_prot_t pval)
+{
+    /* enable interrupt */
+    rt_hw_interrupt_enable(pval);
+
+    return;
+}
+
+void sys_arch_assert(const char *file, int line)
+{
+    rt_kprintf("\nAssertion: %d in %s, thread %s\n",
+               line, file, rt_thread_self()->name);
+    RT_ASSERT(0);
+}
+
+u32_t sys_jiffies(void)
+{
+    return rt_tick_get();
+}
+
+#ifdef RT_LWIP_PPP
+u32_t sio_read(sio_fd_t fd, u8_t *buf, u32_t size)
+{
+    u32_t len;
+
+    RT_ASSERT(fd != RT_NULL);
+
+    len = rt_device_read((rt_device_t)fd, 0, buf, size);
+    if (len <= 0)
+        return 0;
+
+    return len;
+}
+
+u32_t sio_write(sio_fd_t fd, u8_t *buf, u32_t size)
+{
+    RT_ASSERT(fd != RT_NULL);
+
+    return rt_device_write((rt_device_t)fd, 0, buf, size);
+}
+
+void sio_read_abort(sio_fd_t fd)
+{
+    rt_kprintf("read_abort\n");
+}
+
+void ppp_trace(int level, const char *format, ...)
+{
+    va_list args;
+    rt_size_t length;
+    static char rt_log_buf[RT_CONSOLEBUF_SIZE];
+
+    va_start(args, format);
+    length = rt_vsprintf(rt_log_buf, format, args);
+    rt_device_write((rt_device_t)rt_console_get_device(), 0, rt_log_buf, length);
+    va_end(args);
+}
+#endif
+
+/*
+ * export bsd socket symbol for RT-Thread Application Module
+ */
+#if LWIP_SOCKET
+#include <lwip/sockets.h>
+RTM_EXPORT(lwip_accept);
+RTM_EXPORT(lwip_bind);
+RTM_EXPORT(lwip_shutdown);
+RTM_EXPORT(lwip_getpeername);
+RTM_EXPORT(lwip_getsockname);
+RTM_EXPORT(lwip_getsockopt);
+RTM_EXPORT(lwip_setsockopt);
+RTM_EXPORT(lwip_close);
+RTM_EXPORT(lwip_connect);
+RTM_EXPORT(lwip_listen);
+RTM_EXPORT(lwip_recv);
+RTM_EXPORT(lwip_read);
+RTM_EXPORT(lwip_recvfrom);
+RTM_EXPORT(lwip_send);
+RTM_EXPORT(lwip_sendto);
+RTM_EXPORT(lwip_socket);
+RTM_EXPORT(lwip_write);
+RTM_EXPORT(lwip_select);
+RTM_EXPORT(lwip_ioctl);
+RTM_EXPORT(lwip_fcntl);
+
+#if LWIP_DNS
+#include <lwip/netdb.h>
+RTM_EXPORT(lwip_gethostbyname);
+RTM_EXPORT(lwip_gethostbyname_r);
+RTM_EXPORT(lwip_freeaddrinfo);
+RTM_EXPORT(lwip_getaddrinfo);
+#endif
+
+#endif
+
+#if LWIP_DHCP
+#include <lwip/dhcp.h>
+RTM_EXPORT(dhcp_start);
+RTM_EXPORT(dhcp_renew);
+RTM_EXPORT(dhcp_stop);
+#endif
+
+#if LWIP_NETIF_API
+#include <lwip/netifapi.h>
+RTM_EXPORT(netifapi_netif_set_addr);
+#endif

+ 35 - 0
components/net/lwip-1.4.1/src/include/netif/ethernetif.h

@@ -0,0 +1,35 @@
+#ifndef __NETIF_ETHERNETIF_H__
+#define __NETIF_ETHERNETIF_H__
+
+#include "lwip/netif.h"
+#include <rtthread.h>
+
+#define NIOCTL_GADDR		0x01
+#define ETHERNET_MTU		1500
+
+struct eth_device
+{
+	/* inherit from rt_device */
+	struct rt_device parent;
+
+	/* network interface for lwip */
+	struct netif *netif;
+	struct rt_semaphore tx_ack;
+
+	rt_uint8_t  flags;
+	rt_uint8_t  link_changed;
+	rt_uint16_t link_status;
+
+	/* eth device interface */
+	struct pbuf* (*eth_rx)(rt_device_t dev);
+	rt_err_t (*eth_tx)(rt_device_t dev, struct pbuf* p);
+};
+
+rt_err_t eth_device_ready(struct eth_device* dev);
+rt_err_t eth_device_init(struct eth_device * dev, char *name);
+rt_err_t eth_device_init_with_flag(struct eth_device *dev, char *name, rt_uint8_t flag);
+rt_err_t eth_device_linkchange(struct eth_device* dev, rt_bool_t up);
+
+void eth_system_device_init(void);
+
+#endif /* __NETIF_ETHERNETIF_H__ */

+ 333 - 0
components/net/lwip-1.4.1/src/lwipopts.h

@@ -0,0 +1,333 @@
+#ifndef __LWIPOPTS_H__
+#define __LWIPOPTS_H__
+
+#include <rtconfig.h>
+
+#define ERRNO                       1
+
+#define NO_SYS                      0
+#define LWIP_SOCKET                 1
+#define LWIP_NETCONN                1
+
+#ifdef RT_LWIP_IGMP
+#define LWIP_IGMP                   1
+#else
+#define LWIP_IGMP                   0
+#endif
+
+#ifdef RT_LWIP_ICMP
+#define LWIP_ICMP                   1
+#else
+#define LWIP_ICMP                   0
+#endif
+
+#ifdef RT_LWIP_SNMP
+#define LWIP_SNMP                   1
+#else
+#define LWIP_SNMP                   0
+#endif
+
+#ifdef RT_LWIP_DNS
+#define LWIP_DNS                    1
+#else
+#define LWIP_DNS                    0
+#endif
+
+#define LWIP_HAVE_LOOPIF            0
+
+#define LWIP_PLATFORM_BYTESWAP      0
+#define BYTE_ORDER                  LITTLE_ENDIAN
+
+/* Enable SO_RCVTIMEO processing.   */
+#define LWIP_SO_RCVTIMEO            1
+
+/* #define RT_LWIP_DEBUG */
+
+#ifdef RT_LWIP_DEBUG
+#define LWIP_DEBUG
+#endif
+
+/* ---------- Debug options ---------- */
+#ifdef LWIP_DEBUG
+#define SYS_DEBUG                   LWIP_DBG_OFF
+#define ETHARP_DEBUG                LWIP_DBG_OFF
+#define PPP_DEBUG                   LWIP_DBG_OFF
+#define MEM_DEBUG                   LWIP_DBG_OFF
+#define MEMP_DEBUG                  LWIP_DBG_OFF
+#define PBUF_DEBUG                  LWIP_DBG_OFF
+#define API_LIB_DEBUG               LWIP_DBG_OFF
+#define API_MSG_DEBUG               LWIP_DBG_OFF
+#define TCPIP_DEBUG                 LWIP_DBG_OFF
+#define NETIF_DEBUG                 LWIP_DBG_OFF
+#define SOCKETS_DEBUG               LWIP_DBG_OFF
+#define DNS_DEBUG                   LWIP_DBG_OFF
+#define AUTOIP_DEBUG                LWIP_DBG_OFF
+#define DHCP_DEBUG                  LWIP_DBG_OFF
+#define IP_DEBUG                    LWIP_DBG_OFF
+#define IP_REASS_DEBUG              LWIP_DBG_OFF
+#define ICMP_DEBUG                  LWIP_DBG_OFF
+#define IGMP_DEBUG                  LWIP_DBG_OFF
+#define UDP_DEBUG                   LWIP_DBG_OFF
+#define TCP_DEBUG                   LWIP_DBG_OFF
+#define TCP_INPUT_DEBUG             LWIP_DBG_OFF
+#define TCP_OUTPUT_DEBUG            LWIP_DBG_OFF
+#define TCP_RTO_DEBUG               LWIP_DBG_OFF
+#define TCP_CWND_DEBUG              LWIP_DBG_OFF
+#define TCP_WND_DEBUG               LWIP_DBG_OFF
+#define TCP_FR_DEBUG                LWIP_DBG_OFF
+#define TCP_QLEN_DEBUG              LWIP_DBG_OFF
+#define TCP_RST_DEBUG               LWIP_DBG_OFF
+#endif
+
+#define LWIP_DBG_TYPES_ON           (LWIP_DBG_ON|LWIP_DBG_TRACE|LWIP_DBG_STATE|LWIP_DBG_FRESH|LWIP_DBG_HALT)
+
+/* ---------- Memory options ---------- */
+#ifdef RT_LWIP_ALIGN_SIZE
+#define MEM_ALIGNMENT               RT_LWIP_ALIGN_SIZE
+#else
+#define MEM_ALIGNMENT               4
+#endif
+
+#define MEM_LIBC_MALLOC             1
+#define mem_malloc                  rt_malloc
+#define mem_free                    rt_free
+#define mem_calloc                  rt_calloc
+
+#ifdef RT_LWIP_USING_RT_MEM
+#define MEMP_MEM_MALLOC             1
+#else
+#define MEMP_MEM_MALLOC             0
+#endif
+
+/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
+   sends a lot of data out of ROM (or other static memory), this
+   should be set high. */
+#define MEMP_NUM_PBUF               16
+
+/* the number of UDP protocol control blocks. One per active RAW "connection". */
+#ifdef RT_LWIP_RAW_PCB_NUM
+#define MEMP_NUM_RAW_PCB            RT_LWIP_RAW_PCB_NUM
+#endif
+
+/* the number of UDP protocol control blocks. One per active UDP "connection". */
+#ifdef RT_LWIP_UDP_PCB_NUM
+#define MEMP_NUM_UDP_PCB            RT_LWIP_UDP_PCB_NUM
+#endif
+
+/* the number of simulatenously active TCP connections. */
+#ifdef RT_LWIP_TCP_PCB_NUM
+#define MEMP_NUM_TCP_PCB            RT_LWIP_TCP_PCB_NUM
+#endif
+
+/* the number of simultaneously queued TCP */
+#ifdef RT_LWIP_TCP_SEG_NUM
+#define MEMP_NUM_TCP_SEG            TCP_SND_QUEUELEN
+#endif
+
+/* The following four are used only with the sequential API and can be
+   set to 0 if the application only will use the raw API. */
+/* MEMP_NUM_NETBUF: the number of struct netbufs. */
+#define MEMP_NUM_NETBUF             2
+/* MEMP_NUM_NETCONN: the number of struct netconns. */
+#define MEMP_NUM_NETCONN            4
+/* MEMP_NUM_TCPIP_MSG_*: the number of struct tcpip_msg, which is used
+   for sequential API communication and incoming packets. Used in
+   src/api/tcpip.c. */
+#define MEMP_NUM_TCPIP_MSG_API      16
+#define MEMP_NUM_TCPIP_MSG_INPKT    16
+
+/* ---------- Pbuf options ---------- */
+/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */
+#ifdef RT_LWIP_PBUF_NUM
+#define PBUF_POOL_SIZE              RT_LWIP_PBUF_NUM
+#endif
+
+/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */
+#ifdef RT_LWIP_PBUF_POOL_BUFSIZE
+#define PBUF_POOL_BUFSIZE			 RT_LWIP_PBUF_POOL_BUFSIZE
+#endif
+
+/* PBUF_LINK_HLEN: the number of bytes that should be allocated for a
+   link level header. */
+#define PBUF_LINK_HLEN              16
+
+#ifdef RT_LWIP_ETH_PAD_SIZE
+#define ETH_PAD_SIZE                RT_LWIP_ETH_PAD_SIZE
+#endif
+
+/** SYS_LIGHTWEIGHT_PROT
+ * define SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection
+ * for certain critical regions during buffer allocation, deallocation and memory
+ * allocation and deallocation.
+ */
+#define SYS_LIGHTWEIGHT_PROT        (NO_SYS==0)
+
+/* ---------- TCP options ---------- */
+#ifdef RT_LWIP_TCP
+#define LWIP_TCP                    1
+#else
+#define LWIP_TCP                    0
+#endif
+
+#define TCP_TTL                     255
+
+/* Controls if TCP should queue segments that arrive out of
+   order. Define to 0 if your device is low on memory. */
+#define TCP_QUEUE_OOSEQ             1
+
+/* TCP Maximum segment size. */
+#define TCP_MSS                     1460
+
+/* TCP sender buffer space (bytes). */
+#define TCP_SND_BUF                 (TCP_MSS * 2)
+
+/* TCP sender buffer space (pbufs). This must be at least = 2 *
+   TCP_SND_BUF/TCP_MSS for things to work. */
+#define TCP_SND_QUEUELEN            (4 * TCP_SND_BUF/TCP_MSS)
+
+/* TCP writable space (bytes). This must be less than or equal
+   to TCP_SND_BUF. It is the amount of space which must be
+   available in the tcp snd_buf for select to return writable */
+#define TCP_SNDLOWAT                (TCP_SND_BUF/2)
+#define TCP_SNDQUEUELOWAT           TCP_SND_QUEUELEN/2
+
+/* TCP receive window. */
+#ifdef RT_LWIP_TCP_WND
+#define TCP_WND                     RT_LWIP_TCP_WND
+#else
+#define TCP_WND                     (TCP_MSS * 2)
+#endif
+
+/* Maximum number of retransmissions of data segments. */
+#define TCP_MAXRTX                  12
+
+/* Maximum number of retransmissions of SYN segments. */
+#define TCP_SYNMAXRTX               4
+
+/* tcpip thread options */
+#ifdef RT_LWIP_TCPTHREAD_PRIORITY
+#define TCPIP_MBOX_SIZE             RT_LWIP_TCPTHREAD_MBOX_SIZE
+#define TCPIP_THREAD_PRIO           RT_LWIP_TCPTHREAD_PRIORITY
+#define TCPIP_THREAD_STACKSIZE      RT_LWIP_TCPTHREAD_STACKSIZE
+#else
+#define TCPIP_MBOX_SIZE             8
+#define TCPIP_THREAD_PRIO           128
+#define TCPIP_THREAD_STACKSIZE      4096
+#endif
+#define TCPIP_THREAD_NAME           "tcpip"
+#define DEFAULT_TCP_RECVMBOX_SIZE   10
+
+/* ---------- ARP options ---------- */
+#define LWIP_ARP                    1
+#define ARP_TABLE_SIZE              10
+#define ARP_QUEUEING                1
+
+/* ---------- IP options ---------- */
+/* Define IP_FORWARD to 1 if you wish to have the ability to forward
+   IP packets across network interfaces. If you are going to run lwIP
+   on a device with only one network interface, define this to 0. */
+#define IP_FORWARD                  0
+
+/* IP reassembly and segmentation.These are orthogonal even
+ * if they both deal with IP fragments */
+#define IP_REASSEMBLY               0
+#define IP_REASS_MAX_PBUFS          10
+#define MEMP_NUM_REASSDATA          10
+#define IP_FRAG                     0
+
+/* ---------- ICMP options ---------- */
+#define ICMP_TTL                    255
+
+/* ---------- DHCP options ---------- */
+/* Define LWIP_DHCP to 1 if you want DHCP configuration of
+   interfaces. */
+#ifdef RT_LWIP_DHCP
+#define LWIP_DHCP                   1
+#else
+#define LWIP_DHCP                   0
+#endif
+
+/* 1 if you want to do an ARP check on the offered address
+   (recommended). */
+#define DHCP_DOES_ARP_CHECK         (LWIP_DHCP)
+
+/* ---------- AUTOIP options ------- */
+#define LWIP_AUTOIP                 0
+#define LWIP_DHCP_AUTOIP_COOP       (LWIP_DHCP && LWIP_AUTOIP)
+
+/* ---------- UDP options ---------- */
+#ifdef RT_LWIP_UDP
+#define LWIP_UDP                    1
+#else
+#define LWIP_UDP                    0
+#endif
+
+#define LWIP_UDPLITE                0
+#define UDP_TTL                     255
+#define DEFAULT_UDP_RECVMBOX_SIZE   1
+
+/* ---------- RAW options ---------- */
+#define DEFAULT_RAW_RECVMBOX_SIZE   1
+#define DEFAULT_ACCEPTMBOX_SIZE     10
+
+/* ---------- Statistics options ---------- */
+#ifdef RT_LWIP_STATS
+#define LWIP_STATS                  1
+#define LWIP_STATS_DISPLAY          1
+#else
+#define LWIP_STATS                  0
+#endif
+
+#if LWIP_STATS
+#define LINK_STATS                  1
+#define IP_STATS                    1
+#define ICMP_STATS                  1
+#define IGMP_STATS                  1
+#define IPFRAG_STATS                1
+#define UDP_STATS                   1
+#define TCP_STATS                   1
+#define MEM_STATS                   1
+#define MEMP_STATS                  1
+#define PBUF_STATS                  1
+#define SYS_STATS                   1
+#endif /* LWIP_STATS */
+
+/* ---------- PPP options ---------- */
+#ifdef RT_LWIP_PPP
+#define PPP_SUPPORT                 1      /* Set > 0 for PPP */
+#else
+#define PPP_SUPPORT                 0      /* Set > 0 for PPP */
+#endif
+
+#if PPP_SUPPORT
+#define NUM_PPP                     1      /* Max PPP sessions. */
+
+/* Select modules to enable.  Ideally these would be set in the makefile but
+ * we're limited by the command line length so you need to modify the settings
+ * in this file.
+ */
+#define PPPOE_SUPPORT               0
+#define PPPOS_SUPPORT               1
+
+#define PAP_SUPPORT                 1      /* Set > 0 for PAP. */
+#define CHAP_SUPPORT                1      /* Set > 0 for CHAP. */
+#define MSCHAP_SUPPORT              0      /* Set > 0 for MSCHAP (NOT FUNCTIONAL!) */
+#define CBCP_SUPPORT                0      /* Set > 0 for CBCP (NOT FUNCTIONAL!) */
+#define CCP_SUPPORT                 0      /* Set > 0 for CCP (NOT FUNCTIONAL!) */
+#define VJ_SUPPORT                  1      /* Set > 0 for VJ header compression. */
+#define MD5_SUPPORT                 1      /* Set > 0 for MD5 (see also CHAP) */
+
+#endif /* PPP_SUPPORT */
+
+/* no read/write/close for socket */
+#define LWIP_POSIX_SOCKETS_IO_NAMES 0
+#define LWIP_NETIF_API  1
+
+/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active timeouts. */
+#define MEMP_NUM_SYS_TIMEOUT       (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + PPP_SUPPORT)
+#ifdef LWIP_IGMP
+#include <stdlib.h>
+#define LWIP_RAND                  rand
+#endif
+
+#endif /* __LWIPOPTS_H__ */

+ 501 - 251
components/net/lwip-1.4.1/src/netif/ethernetif.c

@@ -1,14 +1,27 @@
-/**
- * @file
- * Ethernet Interface Skeleton
+/*
+ * File      : ethernetif.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
  *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-07-07     Bernard      fix send mail to mailbox issue.
+ * 2011-07-30     mbbill       port lwIP 1.4.0 to RT-Thread
+ * 2012-04-10     Bernard      add more compatible with RT-Thread.
+ * 2012-11-12     Bernard      The network interface can be initialized
+ *                             after lwIP initialization.
+ * 2013-02-28     aozima       fixed list_tcps bug: ipaddr_ntoa isn't reentrant.
  */
 
 /*
  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved. 
- * 
- * Redistribution and use in source and binary forms, with or without modification, 
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *
  * 1. Redistributions of source code must retain the above copyright notice,
@@ -17,301 +30,538 @@
  *    this list of conditions and the following disclaimer in the documentation
  *    and/or other materials provided with the distribution.
  * 3. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission. 
+ *    derived from this software without specific prior written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
- * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
  * OF SUCH DAMAGE.
  *
  * This file is part of the lwIP TCP/IP stack.
- * 
+ *
  * Author: Adam Dunkels <adam@sics.se>
  *
  */
 
-/*
- * This file is a skeleton for developing Ethernet network interface
- * drivers for lwIP. Add code to the low_level functions and do a
- * search-and-replace for the word "ethernetif" to replace it with
- * something that better describes your network interface.
- */
+#include <rtthread.h>
 
 #include "lwip/opt.h"
-
-#if 0 /* don't build, this is only a skeleton, see previous comment */
-
+#include "lwip/debug.h"
 #include "lwip/def.h"
 #include "lwip/mem.h"
 #include "lwip/pbuf.h"
-#include <lwip/stats.h>
-#include <lwip/snmp.h>
+#include "lwip/sys.h"
+#include "lwip/netif.h"
+#include "lwip/stats.h"
+#include "lwip/tcpip.h"
+
 #include "netif/etharp.h"
-#include "netif/ppp_oe.h"
+#include "netif/ethernetif.h"
 
-/* Define those to better describe your network interface. */
-#define IFNAME0 'e'
-#define IFNAME1 'n'
+#define netifapi_netif_set_link_up(n)      netifapi_netif_common(n, netif_set_link_up, NULL)
+#define netifapi_netif_set_link_down(n)    netifapi_netif_common(n, netif_set_link_down, NULL)
 
 /**
- * Helper struct to hold private data used to operate your ethernet interface.
- * Keeping the ethernet address of the MAC in this struct is not necessary
- * as it is already kept in the struct netif.
- * But this is only an example, anyway...
+ * Tx message structure for Ethernet interface
  */
-struct ethernetif {
-  struct eth_addr *ethaddr;
-  /* Add whatever per-interface state that is needed here. */
+struct eth_tx_msg
+{
+    struct netif 	*netif;
+    struct pbuf 	*buf;
 };
 
-/* Forward declarations. */
-static void  ethernetif_input(struct netif *netif);
+static struct rt_mailbox eth_tx_thread_mb;
+static struct rt_thread eth_tx_thread;
+#ifndef RT_LWIP_ETHTHREAD_PRIORITY
+static char eth_tx_thread_mb_pool[32 * 4];
+static char eth_tx_thread_stack[512];
+#else
+static char eth_tx_thread_mb_pool[RT_LWIP_ETHTHREAD_MBOX_SIZE * 4];
+static char eth_tx_thread_stack[RT_LWIP_ETHTHREAD_STACKSIZE];
+#endif
 
-/**
- * In this function, the hardware should be initialized.
- * Called from ethernetif_init().
- *
- * @param netif the already initialized lwip network interface structure
- *        for this ethernetif
- */
-static void
-low_level_init(struct netif *netif)
+static struct rt_mailbox eth_rx_thread_mb;
+static struct rt_thread eth_rx_thread;
+#ifndef RT_LWIP_ETHTHREAD_PRIORITY
+#define RT_ETHERNETIF_THREAD_PREORITY	0x90
+static char eth_rx_thread_mb_pool[48 * 4];
+static char eth_rx_thread_stack[1024];
+#else
+#define RT_ETHERNETIF_THREAD_PREORITY	RT_LWIP_ETHTHREAD_PRIORITY
+static char eth_rx_thread_mb_pool[RT_LWIP_ETHTHREAD_MBOX_SIZE * 4];
+static char eth_rx_thread_stack[RT_LWIP_ETHTHREAD_STACKSIZE];
+#endif
+
+static err_t ethernetif_linkoutput(struct netif *netif, struct pbuf *p)
 {
-  struct ethernetif *ethernetif = netif->state;
-  
-  /* set MAC hardware address length */
-  netif->hwaddr_len = ETHARP_HWADDR_LEN;
-
-  /* set MAC hardware address */
-  netif->hwaddr[0] = ;
-  ...
-  netif->hwaddr[5] = ;
-
-  /* maximum transfer unit */
-  netif->mtu = 1500;
-  
-  /* device capabilities */
-  /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
-  netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
- 
-  /* Do whatever else is needed to initialize interface. */  
-}
+    struct eth_tx_msg msg;
+    struct eth_device* enetif;
+
+    enetif = (struct eth_device*)netif->state;
+
+    /* send a message to eth tx thread */
+    msg.netif = netif;
+    msg.buf   = p;
+    if (rt_mb_send(&eth_tx_thread_mb, (rt_uint32_t) &msg) == RT_EOK)
+    {
+        /* waiting for ack */
+        rt_sem_take(&(enetif->tx_ack), RT_WAITING_FOREVER);
+    }
 
-/**
- * This function should do the actual transmission of the packet. The packet is
- * contained in the pbuf that is passed to the function. This pbuf
- * might be chained.
- *
- * @param netif the lwip network interface structure for this ethernetif
- * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
- * @return ERR_OK if the packet could be sent
- *         an err_t value if the packet couldn't be sent
- *
- * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
- *       strange results. You might consider waiting for space in the DMA queue
- *       to become availale since the stack doesn't retry to send a packet
- *       dropped because of memory failure (except for the TCP timers).
- */
+    return ERR_OK;
+}
 
-static err_t
-low_level_output(struct netif *netif, struct pbuf *p)
+static err_t eth_netif_device_init(struct netif *netif)
 {
-  struct ethernetif *ethernetif = netif->state;
-  struct pbuf *q;
+    struct eth_device *ethif;
+
+    ethif = (struct eth_device*)netif->state;
+    if (ethif != RT_NULL)
+    {
+        rt_device_t device;
+
+        /* get device object */
+        device = (rt_device_t) ethif;
+        if (rt_device_init(device) != RT_EOK)
+        {
+            return ERR_IF;
+        }
+
+        /* copy device flags to netif flags */
+        netif->flags = ethif->flags;
+
+        /* set default netif */
+        if (netif_default == RT_NULL)
+            netif_set_default(ethif->netif);
+
+#if LWIP_DHCP
+        if (ethif->flags & NETIF_FLAG_DHCP)
+        {
+            /* if this interface uses DHCP, start the DHCP client */
+            dhcp_start(ethif->netif);
+        }
+        else
+#endif
+        {
+            /* set interface up */
+            netif_set_up(ethif->netif);
+        }
 
-  initiate transfer();
-  
-#if ETH_PAD_SIZE
-  pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
+#ifdef LWIP_NETIF_LINK_CALLBACK
+        netif_set_link_up(ethif->netif);
 #endif
 
-  for(q = p; q != NULL; q = q->next) {
-    /* Send the data from the pbuf to the interface, one pbuf at a
-       time. The size of the data in each pbuf is kept in the ->len
-       variable. */
-    send data from(q->payload, q->len);
-  }
+        return ERR_OK;
+    }
+
+    return ERR_IF;
+}
 
-  signal that packet should be sent();
+/* Keep old drivers compatible in RT-Thread */
+rt_err_t eth_device_init_with_flag(struct eth_device *dev, char *name, rt_uint8_t flags)
+{
+    struct netif* netif;
 
-#if ETH_PAD_SIZE
-  pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
+    netif = (struct netif*) rt_malloc (sizeof(struct netif));
+    if (netif == RT_NULL)
+    {
+        rt_kprintf("malloc netif failed\n");
+        return -RT_ERROR;
+    }
+    rt_memset(netif, 0, sizeof(struct netif));
+
+    /* set netif */
+    dev->netif = netif;
+    /* device flags, which will be set to netif flags when initializing */
+    dev->flags = flags;
+    /* link changed status of device */
+    dev->link_changed = 0x00;
+    dev->parent.type = RT_Device_Class_NetIf;
+    /* register to RT-Thread device manager */
+    rt_device_register(&(dev->parent), name, RT_DEVICE_FLAG_RDWR);
+    rt_sem_init(&(dev->tx_ack), name, 0, RT_IPC_FLAG_FIFO);
+
+    /* set name */
+    netif->name[0] = name[0];
+    netif->name[1] = name[1];
+
+    /* set hw address to 6 */
+    netif->hwaddr_len 	= 6;
+    /* maximum transfer unit */
+    netif->mtu			= ETHERNET_MTU;
+
+    /* get hardware MAC address */
+    rt_device_control(&(dev->parent), NIOCTL_GADDR, netif->hwaddr);
+
+    /* set output */
+    netif->output		= etharp_output;
+    netif->linkoutput	= ethernetif_linkoutput;
+
+    /* if tcp thread has been started up, we add this netif to the system */
+    if (rt_thread_find("tcpip") != RT_NULL)
+    {
+        struct ip_addr ipaddr, netmask, gw;
+
+#if !LWIP_DHCP
+        IP4_ADDR(&ipaddr, RT_LWIP_IPADDR0, RT_LWIP_IPADDR1, RT_LWIP_IPADDR2, RT_LWIP_IPADDR3);
+        IP4_ADDR(&gw, RT_LWIP_GWADDR0, RT_LWIP_GWADDR1, RT_LWIP_GWADDR2, RT_LWIP_GWADDR3);
+        IP4_ADDR(&netmask, RT_LWIP_MSKADDR0, RT_LWIP_MSKADDR1, RT_LWIP_MSKADDR2, RT_LWIP_MSKADDR3);
+#else
+        IP4_ADDR(&ipaddr, 0, 0, 0, 0);
+        IP4_ADDR(&gw, 0, 0, 0, 0);
+        IP4_ADDR(&netmask, 0, 0, 0, 0);
 #endif
-  
-  LINK_STATS_INC(link.xmit);
 
-  return ERR_OK;
+        netifapi_netif_add(netif, &ipaddr, &netmask, &gw, dev, eth_netif_device_init, tcpip_input);
+    }
+
+    return RT_EOK;
 }
 
-/**
- * Should allocate a pbuf and transfer the bytes of the incoming
- * packet from the interface into the pbuf.
- *
- * @param netif the lwip network interface structure for this ethernetif
- * @return a pbuf filled with the received packet (including MAC header)
- *         NULL on memory error
- */
-static struct pbuf *
-low_level_input(struct netif *netif)
+rt_err_t eth_device_init(struct eth_device * dev, char *name)
 {
-  struct ethernetif *ethernetif = netif->state;
-  struct pbuf *p, *q;
-  u16_t len;
+    rt_uint8_t flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
 
-  /* Obtain the size of the packet and put it into the "len"
-     variable. */
-  len = ;
+#if LWIP_DHCP
+    /* DHCP support */
+    flags |= NETIF_FLAG_DHCP;
+#endif
 
-#if ETH_PAD_SIZE
-  len += ETH_PAD_SIZE; /* allow room for Ethernet padding */
+#if LWIP_IGMP
+    /* IGMP support */
+    flags |= NETIF_FLAG_IGMP;
 #endif
 
-  /* We allocate a pbuf chain of pbufs from the pool. */
-  p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
-  
-  if (p != NULL) {
+    return eth_device_init_with_flag(dev, name, flags);
+}
 
-#if ETH_PAD_SIZE
-    pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
-#endif
+rt_err_t eth_device_ready(struct eth_device* dev)
+{
+    if (dev->netif)
+        /* post message to Ethernet thread */
+        return rt_mb_send(&eth_rx_thread_mb, (rt_uint32_t)dev);
+    else
+        return ERR_OK; /* netif is not initialized yet, just return. */
+}
+
+rt_err_t eth_device_linkchange(struct eth_device* dev, rt_bool_t up)
+{
+    rt_uint32_t level;
+
+    RT_ASSERT(dev != RT_NULL);
+
+    level = rt_hw_interrupt_disable();
+    dev->link_changed = 0x01;
+    if (up == RT_TRUE)
+        dev->link_status = 0x01;
+    else
+        dev->link_status = 0x00;
+    rt_hw_interrupt_enable(level);
+
+    /* post message to ethernet thread */
+    return rt_mb_send(&eth_rx_thread_mb, (rt_uint32_t)dev);
+}
 
-    /* We iterate over the pbuf chain until we have read the entire
-     * packet into the pbuf. */
-    for(q = p; q != NULL; q = q->next) {
-      /* Read enough bytes to fill this pbuf in the chain. The
-       * available data in the pbuf is given by the q->len
-       * variable.
-       * This does not necessarily have to be a memcpy, you can also preallocate
-       * pbufs for a DMA-enabled MAC and after receiving truncate it to the
-       * actually received size. In this case, ensure the tot_len member of the
-       * pbuf is the sum of the chained pbuf len members.
-       */
-      read data into(q->payload, q->len);
+/* Ethernet Tx Thread */
+static void eth_tx_thread_entry(void* parameter)
+{
+    struct eth_tx_msg* msg;
+
+    while (1)
+    {
+        if (rt_mb_recv(&eth_tx_thread_mb, (rt_uint32_t*)&msg, RT_WAITING_FOREVER) == RT_EOK)
+        {
+            struct eth_device* enetif;
+
+            RT_ASSERT(msg->netif != RT_NULL);
+            RT_ASSERT(msg->buf   != RT_NULL);
+
+            enetif = (struct eth_device*)msg->netif->state;
+            if (enetif != RT_NULL)
+            {
+                /* call driver's interface */
+                if (enetif->eth_tx(&(enetif->parent), msg->buf) != RT_EOK)
+                {
+                    rt_kprintf("transmit eth packet failed\n");
+                }
+            }
+
+            /* send ACK */
+            rt_sem_release(&(enetif->tx_ack));
+        }
     }
-    acknowledge that packet has been read();
+}
 
-#if ETH_PAD_SIZE
-    pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
-#endif
+/* Ethernet Rx Thread */
+static void eth_rx_thread_entry(void* parameter)
+{
+    struct eth_device* device;
+
+    while (1)
+    {
+        if (rt_mb_recv(&eth_rx_thread_mb, (rt_uint32_t*)&device, RT_WAITING_FOREVER) == RT_EOK)
+        {
+            struct pbuf *p;
+
+            /* check link status */
+            if (device->link_changed)
+            {
+                int status;
+                rt_uint32_t level;
+
+                level = rt_hw_interrupt_disable();
+                status = device->link_status;
+                device->link_changed = 0x00;
+                rt_hw_interrupt_enable(level);
+
+                if (status)
+                    netifapi_netif_set_link_up(device->netif);
+                else
+                    netifapi_netif_set_link_down(device->netif);
+            }
+
+            /* receive all of buffer */
+            while (1)
+            {
+                p = device->eth_rx(&(device->parent));
+                if (p != RT_NULL)
+                {
+                    /* notify to upper layer */
+                    if( device->netif->input(p, device->netif) != ERR_OK )
+                    {
+                        LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: Input error\n"));
+                        pbuf_free(p);
+                        p = NULL;
+                    }
+                }
+                else break;
+            }
+        }
+        else
+        {
+            LWIP_ASSERT("Should not happen!\n",0);
+        }
+    }
+}
 
-    LINK_STATS_INC(link.recv);
-  } else {
-    drop packet();
-    LINK_STATS_INC(link.memerr);
-    LINK_STATS_INC(link.drop);
-  }
+void eth_system_device_init()
+{
+    rt_err_t result = RT_EOK;
+
+    /* initialize Rx thread.
+     * initialize mailbox and create Ethernet Rx thread */
+    result = rt_mb_init(&eth_rx_thread_mb, "erxmb",
+                        &eth_rx_thread_mb_pool[0], sizeof(eth_rx_thread_mb_pool)/4,
+                        RT_IPC_FLAG_FIFO);
+    RT_ASSERT(result == RT_EOK);
+
+    result = rt_thread_init(&eth_rx_thread, "erx", eth_rx_thread_entry, RT_NULL,
+                            &eth_rx_thread_stack[0], sizeof(eth_rx_thread_stack),
+                            RT_LWIP_ETHTHREAD_PRIORITY, 16);
+    RT_ASSERT(result == RT_EOK);
+    result = rt_thread_startup(&eth_rx_thread);
+    RT_ASSERT(result == RT_EOK);
+
+    /* initialize Tx thread */
+    /* initialize mailbox and create Ethernet Tx thread */
+    result = rt_mb_init(&eth_tx_thread_mb, "etxmb",
+                        &eth_tx_thread_mb_pool[0], sizeof(eth_tx_thread_mb_pool)/4,
+                        RT_IPC_FLAG_FIFO);
+    RT_ASSERT(result == RT_EOK);
+
+    result = rt_thread_init(&eth_tx_thread, "etx", eth_tx_thread_entry, RT_NULL,
+                            &eth_tx_thread_stack[0], sizeof(eth_tx_thread_stack),
+                            RT_ETHERNETIF_THREAD_PREORITY, 16);
+    RT_ASSERT(result == RT_EOK);
+
+    result = rt_thread_startup(&eth_tx_thread);
+    RT_ASSERT(result == RT_EOK);
+}
+
+#ifdef RT_USING_FINSH
+#include <finsh.h>
+void set_if(char* netif_name, char* ip_addr, char* gw_addr, char* nm_addr)
+{
+    struct ip_addr *ip;
+    struct ip_addr addr;
+    struct netif * netif = netif_list;
+
+    if(strlen(netif_name) > sizeof(netif->name))
+    {
+        rt_kprintf("network interface name too long!\r\n");
+        return;
+    }
 
-  return p;  
+    while(netif != RT_NULL)
+    {
+        if(strncmp(netif_name, netif->name, sizeof(netif->name)) == 0)
+            break;
+
+        netif = netif->next;
+        if( netif == RT_NULL )
+        {
+            rt_kprintf("network interface: %s not found!\r\n", netif_name);
+            return;
+        }
+    }
+
+    ip = (struct ip_addr *)&addr;
+
+    /* set ip address */
+    if ((ip_addr != RT_NULL) && ipaddr_aton(ip_addr, &addr))
+    {
+        netif_set_ipaddr(netif, ip);
+    }
+
+    /* set gateway address */
+    if ((gw_addr != RT_NULL) && ipaddr_aton(gw_addr, &addr))
+    {
+        netif_set_gw(netif, ip);
+    }
+
+    /* set netmask address */
+    if ((nm_addr != RT_NULL) && ipaddr_aton(nm_addr, &addr))
+    {
+        netif_set_netmask(netif, ip);
+    }
 }
+FINSH_FUNCTION_EXPORT(set_if, set network interface address);
 
-/**
- * This function should be called when a packet is ready to be read
- * from the interface. It uses the function low_level_input() that
- * should handle the actual reception of bytes from the network
- * interface. Then the type of the received packet is determined and
- * the appropriate input function is called.
- *
- * @param netif the lwip network interface structure for this ethernetif
- */
-static void
-ethernetif_input(struct netif *netif)
+#if LWIP_DNS
+#include <lwip/dns.h>
+void set_dns(char* dns_server)
 {
-  struct ethernetif *ethernetif;
-  struct eth_hdr *ethhdr;
-  struct pbuf *p;
-
-  ethernetif = netif->state;
-
-  /* move received packet into a new pbuf */
-  p = low_level_input(netif);
-  /* no packet could be read, silently ignore this */
-  if (p == NULL) return;
-  /* points to packet payload, which starts with an Ethernet header */
-  ethhdr = p->payload;
-
-  switch (htons(ethhdr->type)) {
-  /* IP or ARP packet? */
-  case ETHTYPE_IP:
-  case ETHTYPE_ARP:
-#if PPPOE_SUPPORT
-  /* PPPoE packet? */
-  case ETHTYPE_PPPOEDISC:
-  case ETHTYPE_PPPOE:
-#endif /* PPPOE_SUPPORT */
-    /* full packet send to tcpip_thread to process */
-    if (netif->input(p, netif)!=ERR_OK)
-     { LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
-       pbuf_free(p);
-       p = NULL;
-     }
-    break;
-
-  default:
-    pbuf_free(p);
-    p = NULL;
-    break;
-  }
+    struct ip_addr addr;
+
+    if ((dns_server != RT_NULL) && ipaddr_aton(dns_server, &addr))
+    {
+        dns_setserver(0, &addr);
+    }
 }
+FINSH_FUNCTION_EXPORT(set_dns, set DNS server address);
+#endif
 
-/**
- * Should be called at the beginning of the program to set up the
- * network interface. It calls the function low_level_init() to do the
- * actual setup of the hardware.
- *
- * This function should be passed as a parameter to netif_add().
- *
- * @param netif the lwip network interface structure for this ethernetif
- * @return ERR_OK if the loopif is initialized
- *         ERR_MEM if private data couldn't be allocated
- *         any other err_t on error
- */
-err_t
-ethernetif_init(struct netif *netif)
+void list_if(void)
+{
+    rt_ubase_t index;
+    struct netif * netif;
+
+    rt_enter_critical();
+
+    netif = netif_list;
+
+    while( netif != RT_NULL )
+    {
+        rt_kprintf("network interface: %c%c%s\n",
+                   netif->name[0],
+                   netif->name[1],
+                   (netif == netif_default)?" (Default)":"");
+        rt_kprintf("MTU: %d\n", netif->mtu);
+        rt_kprintf("MAC: ");
+        for (index = 0; index < netif->hwaddr_len; index ++)
+            rt_kprintf("%02x ", netif->hwaddr[index]);
+        rt_kprintf("\nFLAGS:");
+        if (netif->flags & NETIF_FLAG_UP) rt_kprintf(" UP");
+        else rt_kprintf(" DOWN");
+        if (netif->flags & NETIF_FLAG_LINK_UP) rt_kprintf(" LINK_UP");
+        else rt_kprintf(" LINK_DOWN");
+        if (netif->flags & NETIF_FLAG_DHCP) rt_kprintf(" DHCP");
+        if (netif->flags & NETIF_FLAG_POINTTOPOINT) rt_kprintf(" PPP");
+        if (netif->flags & NETIF_FLAG_ETHARP) rt_kprintf(" ETHARP");
+        if (netif->flags & NETIF_FLAG_IGMP) rt_kprintf(" IGMP");
+        rt_kprintf("\n");
+        rt_kprintf("ip address: %s\n", ipaddr_ntoa(&(netif->ip_addr)));
+        rt_kprintf("gw address: %s\n", ipaddr_ntoa(&(netif->gw)));
+        rt_kprintf("net mask  : %s\n", ipaddr_ntoa(&(netif->netmask)));
+        rt_kprintf("\r\n");
+
+        netif = netif->next;
+    }
+
+#if LWIP_DNS
+    {
+        struct ip_addr ip_addr;
+
+        for(index=0; index<DNS_MAX_SERVERS; index++)
+        {
+            ip_addr = dns_getserver(index);
+            rt_kprintf("dns server #%d: %s\n", index, ipaddr_ntoa(&(ip_addr)));
+        }
+    }
+#endif /**< #if LWIP_DNS */
+
+    rt_exit_critical();
+}
+FINSH_FUNCTION_EXPORT(list_if, list network interface information);
+
+#if LWIP_TCP
+#include <lwip/tcp.h>
+#include <lwip/tcp_impl.h>
+
+void list_tcps(void)
 {
-  struct ethernetif *ethernetif;
-
-  LWIP_ASSERT("netif != NULL", (netif != NULL));
-    
-  ethernetif = mem_malloc(sizeof(struct ethernetif));
-  if (ethernetif == NULL) {
-    LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n"));
-    return ERR_MEM;
-  }
-
-#if LWIP_NETIF_HOSTNAME
-  /* Initialize interface hostname */
-  netif->hostname = "lwip";
-#endif /* LWIP_NETIF_HOSTNAME */
-
-  /*
-   * Initialize the snmp variables and counters inside the struct netif.
-   * The last argument should be replaced with your link speed, in units
-   * of bits per second.
-   */
-  NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS);
-
-  netif->state = ethernetif;
-  netif->name[0] = IFNAME0;
-  netif->name[1] = IFNAME1;
-  /* We directly use etharp_output() here to save a function call.
-   * You can instead declare your own function an call etharp_output()
-   * from it if you have to do some checks before sending (e.g. if link
-   * is available...) */
-  netif->output = etharp_output;
-  netif->linkoutput = low_level_output;
-  
-  ethernetif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]);
-  
-  /* initialize the hardware */
-  low_level_init(netif);
-
-  return ERR_OK;
+    rt_uint32_t num = 0;
+    struct tcp_pcb *pcb;
+    char local_ip_str[16];
+    char remote_ip_str[16];
+
+    extern struct tcp_pcb *tcp_active_pcbs;
+    extern union tcp_listen_pcbs_t tcp_listen_pcbs;
+    extern struct tcp_pcb *tcp_tw_pcbs;
+    extern const char *tcp_state_str[];
+
+    rt_enter_critical();
+    rt_kprintf("Active PCB states:\n");
+    for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next)
+    {
+        strcpy(local_ip_str, ipaddr_ntoa(&(pcb->local_ip)));
+        strcpy(remote_ip_str, ipaddr_ntoa(&(pcb->remote_ip)));
+
+        rt_kprintf("#%d %s:%d <==> %s:%d snd_nxt 0x%08X rcv_nxt 0x%08X ",
+                   num++,
+                   local_ip_str,
+                   pcb->local_port,
+                   remote_ip_str,
+                   pcb->remote_port,
+                   pcb->snd_nxt,
+                   pcb->rcv_nxt);
+        rt_kprintf("state: %s\n", tcp_state_str[pcb->state]);
+    }
+
+    rt_kprintf("Listen PCB states:\n");
+    num = 0;
+    for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next)
+    {
+        rt_kprintf("#%d local port %d ", num++, pcb->local_port);
+        rt_kprintf("state: %s\n", tcp_state_str[pcb->state]);
+    }
+
+    rt_kprintf("TIME-WAIT PCB states:\n");
+    num = 0;
+    for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next)
+    {
+        strcpy(local_ip_str, ipaddr_ntoa(&(pcb->local_ip)));
+        strcpy(remote_ip_str, ipaddr_ntoa(&(pcb->remote_ip)));
+
+        rt_kprintf("#%d %s:%d <==> %s:%d snd_nxt 0x%08X rcv_nxt 0x%08X ",
+                   num++,
+                   local_ip_str,
+                   pcb->local_port,
+                   remote_ip_str,
+                   pcb->remote_port,
+                   pcb->snd_nxt,
+                   pcb->rcv_nxt);
+        rt_kprintf("state: %s\n", tcp_state_str[pcb->state]);
+    }
+    rt_exit_critical();
 }
+FINSH_FUNCTION_EXPORT(list_tcps, list all of tcp connections);
+#endif
 
-#endif /* 0 */
+#endif

+ 1 - 1
components/net/lwip/SConscript

@@ -82,6 +82,6 @@ if GetDepend(['RT_LWIP_PPP']):
 if GetDepend(['RT_USING_NETUTILS']):
     src += Glob('./apps/*.c')
 
-group = DefineGroup('LwIP', src, depend = ['RT_USING_LWIP'], CPPPATH = path)
+group = DefineGroup('LwIP', src, depend = ['RT_USING_LWIP', 'RT_USING_LWIP140'], CPPPATH = path)
 
 Return('group')