summaryrefslogtreecommitdiff
path: root/components/net
diff options
context:
space:
mode:
authorBernard Xiong <[email protected]>2013-01-08 18:13:32 -0800
committerBernard Xiong <[email protected]>2013-01-08 18:13:32 -0800
commitaccace98e05eda28c116eb04502eb92d01b6ef1e (patch)
tree4a425c96e0be3980779c8205c7c3fe2f1a144630 /components/net
parent1fab41d48a490f6483582147500d43f4ca889a8e (diff)
parent02b8e9366f362926799bfaecc0891830ba62f646 (diff)
Merge pull request #8 from mbbill/correct_crlf
Correct crlf
Diffstat (limited to 'components/net')
-rw-r--r--components/net/SConscript26
-rw-r--r--components/net/lwip-1.3.2/SConscript174
-rw-r--r--components/net/lwip-1.3.2/src/api/api_msg.c2496
-rw-r--r--components/net/lwip-1.3.2/src/arch/include/arch/bpstruct.h70
-rw-r--r--components/net/lwip-1.3.2/src/arch/include/arch/cc.h8
-rw-r--r--components/net/lwip-1.3.2/src/arch/include/arch/cpu.h84
-rw-r--r--components/net/lwip-1.3.2/src/arch/include/arch/epstruct.h70
-rw-r--r--components/net/lwip-1.3.2/src/arch/include/arch/init.h88
-rw-r--r--components/net/lwip-1.3.2/src/arch/include/arch/lib.h82
-rw-r--r--components/net/lwip-1.3.2/src/arch/include/arch/perf.h104
-rw-r--r--components/net/lwip-1.3.2/src/arch/include/arch/sys_arch.h114
-rw-r--r--components/net/lwip-1.3.2/src/arch/include/arch/sys_arch_init.h16
-rw-r--r--components/net/lwip-1.3.2/src/arch/sys_arch.c472
-rw-r--r--components/net/lwip-1.3.2/src/core/memp.c82
-rw-r--r--components/net/lwip-1.3.2/src/include/netif/ethernetif.h70
-rw-r--r--components/net/lwip-1.3.2/src/lwipopts.h10
-rw-r--r--components/net/lwip-1.3.2/src/netif/ethernetif.c898
-rw-r--r--components/net/lwip/src/arch/include/arch/bpstruct.h70
-rw-r--r--components/net/lwip/src/arch/include/arch/epstruct.h70
-rw-r--r--components/net/uip/apps/hello-world/hello-world.c230
-rw-r--r--components/net/uip/apps/hello-world/hello-world.h106
-rw-r--r--components/net/uip/apps/telnetd/uip_shell.c246
-rw-r--r--components/net/uip/rt-thread/clock-arch.c100
-rw-r--r--components/net/uip/rt-thread/clock-arch.h80
-rw-r--r--components/net/uip/rt-thread/readme.txt22
-rw-r--r--components/net/uip/rt-thread/uIPmain.c254
-rw-r--r--components/net/uip/rt-thread/uip-conf.h334
-rw-r--r--components/net/uip/rt-thread/uip_addr.h14
-rw-r--r--components/net/uip/rt-thread/uip_arch.c286
-rw-r--r--components/net/uip/rt-thread/uip_eth.h70
-rw-r--r--components/net/uip/rt-thread/uip_etharp.c114
-rw-r--r--components/net/uip/rt-thread/uip_etharp.h30
-rw-r--r--components/net/uip/rt-thread/uip_ethernetif.c626
-rw-r--r--components/net/uip/rt-thread/uip_ethernetif.h62
-rw-r--r--components/net/uip/rt-thread/uip_ipaddr.h38
-rw-r--r--components/net/uip/rt-thread/uip_netif.c106
-rw-r--r--components/net/uip/rt-thread/uip_netif.h538
-rw-r--r--components/net/uip/rt-thread/uip_pbuf.c98
-rw-r--r--components/net/uip/rt-thread/uip_pbuf.h174
-rw-r--r--components/net/uip/rt-thread/uip_tcpip.c80
-rw-r--r--components/net/uip/uip/psock.c676
-rw-r--r--components/net/uip/uip/uip.c3806
-rw-r--r--components/net/uip/uip/uip.h3204
-rw-r--r--components/net/uip/uip/uip_timer.c394
-rw-r--r--components/net/uip/uip/uip_timer.h172
45 files changed, 8432 insertions, 8432 deletions
diff --git a/components/net/SConscript b/components/net/SConscript
index 1a2485b8aa..87943f32ae 100644
--- a/components/net/SConscript
+++ b/components/net/SConscript
@@ -1,13 +1,13 @@
-# for network related component
-import os
-Import('RTT_ROOT')
-
-objs = []
-list = os.listdir(os.path.join(RTT_ROOT, 'components', 'net'))
-
-for d in list:
- path = os.path.join(RTT_ROOT, 'components', 'net', d)
- if os.path.isfile(os.path.join(path, 'SConscript')):
- objs = objs + SConscript(os.path.join(d, 'SConscript'))
-
-Return('objs')
+# for network related component
+import os
+Import('RTT_ROOT')
+
+objs = []
+list = os.listdir(os.path.join(RTT_ROOT, 'components', 'net'))
+
+for d in list:
+ path = os.path.join(RTT_ROOT, 'components', 'net', d)
+ if os.path.isfile(os.path.join(path, 'SConscript')):
+ objs = objs + SConscript(os.path.join(d, 'SConscript'))
+
+Return('objs')
diff --git a/components/net/lwip-1.3.2/SConscript b/components/net/lwip-1.3.2/SConscript
index d74b3451e9..2cef59e3d8 100644
--- a/components/net/lwip-1.3.2/SConscript
+++ b/components/net/lwip-1.3.2/SConscript
@@ -1,87 +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/arch/sys_arch_init.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/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/loopif.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_LWIP132'], CPPPATH = path)
-
-Return('group')
+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/arch/sys_arch_init.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/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/loopif.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_LWIP132'], CPPPATH = path)
+
+Return('group')
diff --git a/components/net/lwip-1.3.2/src/api/api_msg.c b/components/net/lwip-1.3.2/src/api/api_msg.c
index a4e44c7a9e..c2ff5ee5e8 100644
--- a/components/net/lwip-1.3.2/src/api/api_msg.c
+++ b/components/net/lwip-1.3.2/src/api/api_msg.c
@@ -1,1248 +1,1248 @@
-/**
- * @file
- * Sequential API Internal module
- *
- */
-
-/*
- * Copyright (c) 2001-2004 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 <[email protected]>
- *
- */
-
-#include "lwip/opt.h"
-
-#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */
-
-#include "lwip/api_msg.h"
-
-#include "lwip/ip.h"
-#include "lwip/udp.h"
-#include "lwip/tcp.h"
-#include "lwip/raw.h"
-
-#include "lwip/memp.h"
-#include "lwip/tcpip.h"
-#include "lwip/igmp.h"
-#include "lwip/dns.h"
-
-#include <string.h>
-
-/* forward declarations */
-#if LWIP_TCP
-static err_t do_writemore(struct netconn *conn);
-static void do_close_internal(struct netconn *conn);
-#endif
-
-#if LWIP_RAW
-/**
- * Receive callback function for RAW netconns.
- * Doesn't 'eat' the packet, only references it and sends it to
- * conn->recvmbox
- *
- * @see raw.h (struct raw_pcb.recv) for parameters and return value
- */
-static u8_t
-recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p,
- struct ip_addr *addr)
-{
- struct pbuf *q;
- struct netbuf *buf;
- struct netconn *conn;
-#if LWIP_SO_RCVBUF
- int recv_avail;
-#endif /* LWIP_SO_RCVBUF */
-
- LWIP_UNUSED_ARG(addr);
- conn = arg;
-
-#if LWIP_SO_RCVBUF
- SYS_ARCH_GET(conn->recv_avail, recv_avail);
- if ((conn != NULL) && (conn->recvmbox != SYS_MBOX_NULL) &&
- ((recv_avail + (int)(p->tot_len)) <= conn->recv_bufsize)) {
-#else /* LWIP_SO_RCVBUF */
- if ((conn != NULL) && (conn->recvmbox != SYS_MBOX_NULL)) {
-#endif /* LWIP_SO_RCVBUF */
- /* copy the whole packet into new pbufs */
- q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);
- if(q != NULL) {
- if (pbuf_copy(q, p) != ERR_OK) {
- pbuf_free(q);
- q = NULL;
- }
- }
-
- if(q != NULL) {
- buf = memp_malloc(MEMP_NETBUF);
- if (buf == NULL) {
- pbuf_free(q);
- return 0;
- }
-
- buf->p = q;
- buf->ptr = q;
- buf->addr = &(((struct ip_hdr*)(q->payload))->src);
- buf->port = pcb->protocol;
-
- if (sys_mbox_trypost(conn->recvmbox, buf) != ERR_OK) {
- netbuf_delete(buf);
- return 0;
- } else {
- SYS_ARCH_INC(conn->recv_avail, q->tot_len);
- /* Register event with callback */
- API_EVENT(conn, NETCONN_EVT_RCVPLUS, q->tot_len);
- }
- }
- }
-
- return 0; /* do not eat the packet */
-}
-#endif /* LWIP_RAW*/
-
-#if LWIP_UDP
-/**
- * Receive callback function for UDP netconns.
- * Posts the packet to conn->recvmbox or deletes it on memory error.
- *
- * @see udp.h (struct udp_pcb.recv) for parameters
- */
-static void
-recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
- struct ip_addr *addr, u16_t port)
-{
- struct netbuf *buf;
- struct netconn *conn;
-#if LWIP_SO_RCVBUF
- int recv_avail;
-#endif /* LWIP_SO_RCVBUF */
-
- LWIP_UNUSED_ARG(pcb); /* only used for asserts... */
- LWIP_ASSERT("recv_udp must have a pcb argument", pcb != NULL);
- LWIP_ASSERT("recv_udp must have an argument", arg != NULL);
- conn = arg;
- LWIP_ASSERT("recv_udp: recv for wrong pcb!", conn->pcb.udp == pcb);
-
-#if LWIP_SO_RCVBUF
- SYS_ARCH_GET(conn->recv_avail, recv_avail);
- if ((conn == NULL) || (conn->recvmbox == SYS_MBOX_NULL) ||
- ((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize)) {
-#else /* LWIP_SO_RCVBUF */
- if ((conn == NULL) || (conn->recvmbox == SYS_MBOX_NULL)) {
-#endif /* LWIP_SO_RCVBUF */
- pbuf_free(p);
- return;
- }
-
- buf = memp_malloc(MEMP_NETBUF);
- if (buf == NULL) {
- pbuf_free(p);
- return;
- } else {
- buf->p = p;
- buf->ptr = p;
- buf->addr = addr;
- buf->port = port;
-#if LWIP_NETBUF_RECVINFO
- {
- const struct ip_hdr* iphdr = ip_current_header();
- /* get the UDP header - always in the first pbuf, ensured by udp_input */
- const struct udp_hdr* udphdr = (void*)(((char*)iphdr) + IPH_LEN(iphdr));
- buf->toaddr = (struct ip_addr*)&iphdr->dest;
- buf->toport = udphdr->dest;
- }
-#endif /* LWIP_NETBUF_RECVINFO */
- }
-
- if (sys_mbox_trypost(conn->recvmbox, buf) != ERR_OK) {
- netbuf_delete(buf);
- return;
- } else {
- SYS_ARCH_INC(conn->recv_avail, p->tot_len);
- /* Register event with callback */
- API_EVENT(conn, NETCONN_EVT_RCVPLUS, p->tot_len);
- }
-}
-#endif /* LWIP_UDP */
-
-#if LWIP_TCP
-/**
- * Receive callback function for TCP netconns.
- * Posts the packet to conn->recvmbox, but doesn't delete it on errors.
- *
- * @see tcp.h (struct tcp_pcb.recv) for parameters and return value
- */
-static err_t
-recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
-{
- struct netconn *conn;
- u16_t len;
-
- LWIP_UNUSED_ARG(pcb);
- LWIP_ASSERT("recv_tcp must have a pcb argument", pcb != NULL);
- LWIP_ASSERT("recv_tcp must have an argument", arg != NULL);
- conn = arg;
- LWIP_ASSERT("recv_tcp: recv for wrong pcb!", conn->pcb.tcp == pcb);
-
- if ((conn == NULL) || (conn->recvmbox == SYS_MBOX_NULL)) {
- return ERR_VAL;
- }
-
- conn->err = err;
- if (p != NULL) {
- len = p->tot_len;
- SYS_ARCH_INC(conn->recv_avail, len);
- } else {
- len = 0;
- }
-
- if (sys_mbox_trypost(conn->recvmbox, p) != ERR_OK) {
- return ERR_MEM;
- } else {
- /* Register event with callback */
- API_EVENT(conn, NETCONN_EVT_RCVPLUS, len);
- }
-
- return ERR_OK;
-}
-
-/**
- * Poll callback function for TCP netconns.
- * Wakes up an application thread that waits for a connection to close
- * or data to be sent. The application thread then takes the
- * appropriate action to go on.
- *
- * Signals the conn->sem.
- * netconn_close waits for conn->sem if closing failed.
- *
- * @see tcp.h (struct tcp_pcb.poll) for parameters and return value
- */
-static err_t
-poll_tcp(void *arg, struct tcp_pcb *pcb)
-{
- struct netconn *conn = arg;
-
- LWIP_UNUSED_ARG(pcb);
- LWIP_ASSERT("conn != NULL", (conn != NULL));
-
- if (conn->state == NETCONN_WRITE) {
- do_writemore(conn);
- } else if (conn->state == NETCONN_CLOSE) {
- do_close_internal(conn);
- }
-
- return ERR_OK;
-}
-
-/**
- * Sent callback function for TCP netconns.
- * Signals the conn->sem and calls API_EVENT.
- * netconn_write waits for conn->sem if send buffer is low.
- *
- * @see tcp.h (struct tcp_pcb.sent) for parameters and return value
- */
-static err_t
-sent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len)
-{
- struct netconn *conn = arg;
-
- LWIP_UNUSED_ARG(pcb);
- LWIP_ASSERT("conn != NULL", (conn != NULL));
-
- if (conn->state == NETCONN_WRITE) {
- LWIP_ASSERT("conn->pcb.tcp != NULL", conn->pcb.tcp != NULL);
- do_writemore(conn);
- } else if (conn->state == NETCONN_CLOSE) {
- do_close_internal(conn);
- }
-
- if (conn) {
- if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT)) {
- API_EVENT(conn, NETCONN_EVT_SENDPLUS, len);
- }
- }
-
- return ERR_OK;
-}
-
-/**
- * Error callback function for TCP netconns.
- * Signals conn->sem, posts to all conn mboxes and calls API_EVENT.
- * The application thread has then to decide what to do.
- *
- * @see tcp.h (struct tcp_pcb.err) for parameters
- */
-static void
-err_tcp(void *arg, err_t err)
-{
- struct netconn *conn;
-
- conn = arg;
- LWIP_ASSERT("conn != NULL", (conn != NULL));
-
- conn->pcb.tcp = NULL;
-
- conn->err = err;
- if (conn->recvmbox != SYS_MBOX_NULL) {
- /* Register event with callback */
- API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
- sys_mbox_post(conn->recvmbox, NULL);
- }
- if (conn->op_completed != SYS_SEM_NULL && conn->state == NETCONN_CONNECT) {
- conn->state = NETCONN_NONE;
- sys_sem_signal(conn->op_completed);
- }
- if (conn->acceptmbox != SYS_MBOX_NULL) {
- /* Register event with callback */
- API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
- sys_mbox_post(conn->acceptmbox, NULL);
- }
- if ((conn->state == NETCONN_WRITE) || (conn->state == NETCONN_CLOSE)) {
- /* calling do_writemore/do_close_internal is not necessary
- since the pcb has already been deleted! */
- conn->state = NETCONN_NONE;
- /* wake up the waiting task */
- sys_sem_signal(conn->op_completed);
- }
-}
-
-/**
- * Setup a tcp_pcb with the correct callback function pointers
- * and their arguments.
- *
- * @param conn the TCP netconn to setup
- */
-static void
-setup_tcp(struct netconn *conn)
-{
- struct tcp_pcb *pcb;
-
- pcb = conn->pcb.tcp;
- tcp_arg(pcb, conn);
- tcp_recv(pcb, recv_tcp);
- tcp_sent(pcb, sent_tcp);
- tcp_poll(pcb, poll_tcp, 4);
- tcp_err(pcb, err_tcp);
-}
-
-/**
- * Accept callback function for TCP netconns.
- * Allocates a new netconn and posts that to conn->acceptmbox.
- *
- * @see tcp.h (struct tcp_pcb_listen.accept) for parameters and return value
- */
-static err_t
-accept_function(void *arg, struct tcp_pcb *newpcb, err_t err)
-{
- struct netconn *newconn;
- struct netconn *conn;
-
-#if API_MSG_DEBUG
-#if TCP_DEBUG
- tcp_debug_print_state(newpcb->state);
-#endif /* TCP_DEBUG */
-#endif /* API_MSG_DEBUG */
- conn = (struct netconn *)arg;
-
- /* check whether acceptmbox is valid */
- if (conn->acceptmbox == SYS_MBOX_NULL)
- {
- LWIP_DEBUGF(API_MSG_DEBUG, ("accept_function: acceptmbox already deleted\n"));
- return ERR_VAL;
- }
-
- /* We have to set the callback here even though
- * the new socket is unknown. conn->socket is marked as -1. */
- newconn = netconn_alloc(conn->type, conn->callback);
- if (newconn == NULL) {
- return ERR_MEM;
- }
- newconn->pcb.tcp = newpcb;
- setup_tcp(newconn);
- newconn->err = err;
-
- if (sys_mbox_trypost(conn->acceptmbox, newconn) != ERR_OK) {
- /* When returning != ERR_OK, the connection is aborted in tcp_process(),
- so do nothing here! */
- newconn->pcb.tcp = NULL;
- netconn_free(newconn);
- return ERR_MEM;
- } else {
- /* Register event with callback */
- API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
- }
-
- return ERR_OK;
-}
-#endif /* LWIP_TCP */
-
-/**
- * Create a new pcb of a specific type.
- * Called from do_newconn().
- *
- * @param msg the api_msg_msg describing the connection type
- * @return msg->conn->err, but the return value is currently ignored
- */
-static err_t
-pcb_new(struct api_msg_msg *msg)
-{
- msg->conn->err = ERR_OK;
-
- LWIP_ASSERT("pcb_new: pcb already allocated", msg->conn->pcb.tcp == NULL);
-
- /* Allocate a PCB for this connection */
- switch(NETCONNTYPE_GROUP(msg->conn->type)) {
-#if LWIP_RAW
- case NETCONN_RAW:
- msg->conn->pcb.raw = raw_new(msg->msg.n.proto);
- if(msg->conn->pcb.raw == NULL) {
- msg->conn->err = ERR_MEM;
- break;
- }
- raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn);
- break;
-#endif /* LWIP_RAW */
-#if LWIP_UDP
- case NETCONN_UDP:
- msg->conn->pcb.udp = udp_new();
- if(msg->conn->pcb.udp == NULL) {
- msg->conn->err = ERR_MEM;
- break;
- }
-#if LWIP_UDPLITE
- if (msg->conn->type==NETCONN_UDPLITE) {
- udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE);
- }
-#endif /* LWIP_UDPLITE */
- if (msg->conn->type==NETCONN_UDPNOCHKSUM) {
- udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM);
- }
- udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
- break;
-#endif /* LWIP_UDP */
-#if LWIP_TCP
- case NETCONN_TCP:
- msg->conn->pcb.tcp = tcp_new();
- if(msg->conn->pcb.tcp == NULL) {
- msg->conn->err = ERR_MEM;
- break;
- }
- setup_tcp(msg->conn);
- break;
-#endif /* LWIP_TCP */
- default:
- /* Unsupported netconn type, e.g. protocol disabled */
- msg->conn->err = ERR_VAL;
- break;
- }
-
- return msg->conn->err;
-}
-
-/**
- * Create a new pcb of a specific type inside a netconn.
- * Called from netconn_new_with_proto_and_callback.
- *
- * @param msg the api_msg_msg describing the connection type
- */
-void
-do_newconn(struct api_msg_msg *msg)
-{
- if(msg->conn->pcb.tcp == NULL) {
- pcb_new(msg);
- }
- /* Else? This "new" connection already has a PCB allocated. */
- /* Is this an error condition? Should it be deleted? */
- /* We currently just are happy and return. */
-
- TCPIP_APIMSG_ACK(msg);
-}
-
-/**
- * Create a new netconn (of a specific type) that has a callback function.
- * The corresponding pcb is NOT created!
- *
- * @param t the type of 'connection' to create (@see enum netconn_type)
- * @param proto the IP protocol for RAW IP pcbs
- * @param callback a function to call on status changes (RX available, TX'ed)
- * @return a newly allocated struct netconn or
- * NULL on memory error
- */
-struct netconn*
-netconn_alloc(enum netconn_type t, netconn_callback callback)
-{
- struct netconn *conn;
- int size;
-
- conn = memp_malloc(MEMP_NETCONN);
- if (conn == NULL) {
- return NULL;
- }
-
- conn->err = ERR_OK;
- conn->type = t;
- conn->pcb.tcp = NULL;
-
-#if (DEFAULT_RAW_RECVMBOX_SIZE == DEFAULT_UDP_RECVMBOX_SIZE) && \
- (DEFAULT_RAW_RECVMBOX_SIZE == DEFAULT_TCP_RECVMBOX_SIZE)
- size = DEFAULT_RAW_RECVMBOX_SIZE;
-#else
- size = 0; /* skip warning */
- switch(NETCONNTYPE_GROUP(t)) {
-#if LWIP_RAW
- case NETCONN_RAW:
- size = DEFAULT_RAW_RECVMBOX_SIZE;
- break;
-#endif /* LWIP_RAW */
-#if LWIP_UDP
- case NETCONN_UDP:
- size = DEFAULT_UDP_RECVMBOX_SIZE;
- break;
-#endif /* LWIP_UDP */
-#if LWIP_TCP
- case NETCONN_TCP:
- size = DEFAULT_TCP_RECVMBOX_SIZE;
- break;
-#endif /* LWIP_TCP */
- default:
- LWIP_ASSERT("netconn_alloc: undefined netconn_type", 0);
- break;
- }
-#endif
-
- if ((conn->op_completed = sys_sem_new(0)) == SYS_SEM_NULL) {
- memp_free(MEMP_NETCONN, conn);
- return NULL;
- }
- if ((conn->recvmbox = sys_mbox_new(size)) == SYS_MBOX_NULL) {
- sys_sem_free(conn->op_completed);
- memp_free(MEMP_NETCONN, conn);
- return NULL;
- }
-
- conn->acceptmbox = SYS_MBOX_NULL;
- conn->state = NETCONN_NONE;
- /* initialize socket to -1 since 0 is a valid socket */
- conn->socket = -1;
- conn->callback = callback;
- conn->recv_avail = 0;
-#if LWIP_TCP
- conn->write_msg = NULL;
- conn->write_offset = 0;
-#if LWIP_TCPIP_CORE_LOCKING
- conn->write_delayed = 0;
-#endif /* LWIP_TCPIP_CORE_LOCKING */
-#endif /* LWIP_TCP */
-#if LWIP_SO_RCVTIMEO
- conn->recv_timeout = 0;
-#endif /* LWIP_SO_RCVTIMEO */
-#if LWIP_SO_RCVBUF
- conn->recv_bufsize = RECV_BUFSIZE_DEFAULT;
-#endif /* LWIP_SO_RCVBUF */
- return conn;
-}
-
-/**
- * Delete a netconn and all its resources.
- * The pcb is NOT freed (since we might not be in the right thread context do this).
- *
- * @param conn the netconn to free
- */
-void
-netconn_free(struct netconn *conn)
-{
- void *mem;
- LWIP_ASSERT("PCB must be deallocated outside this function", conn->pcb.tcp == NULL);
-
- /* Drain the recvmbox. */
- if (conn->recvmbox != SYS_MBOX_NULL) {
- while (sys_mbox_tryfetch(conn->recvmbox, &mem) != SYS_MBOX_EMPTY) {
- if (conn->type == NETCONN_TCP) {
- if(mem != NULL) {
- pbuf_free((struct pbuf *)mem);
- }
- } else {
- netbuf_delete((struct netbuf *)mem);
- }
- }
- sys_mbox_free(conn->recvmbox);
- conn->recvmbox = SYS_MBOX_NULL;
- }
-
- /* Drain the acceptmbox. */
- if (conn->acceptmbox != SYS_MBOX_NULL) {
- while (sys_mbox_tryfetch(conn->acceptmbox, &mem) != SYS_MBOX_EMPTY) {
- netconn_delete((struct netconn *)mem);
- }
- sys_mbox_free(conn->acceptmbox);
- conn->acceptmbox = SYS_MBOX_NULL;
- }
-
- sys_sem_free(conn->op_completed);
- conn->op_completed = SYS_SEM_NULL;
-
- memp_free(MEMP_NETCONN, conn);
-}
-
-#if LWIP_TCP
-/**
- * Internal helper function to close a TCP netconn: since this sometimes
- * doesn't work at the first attempt, this function is called from multiple
- * places.
- *
- * @param conn the TCP netconn to close
- */
-static void
-do_close_internal(struct netconn *conn)
-{
- err_t err;
-
- LWIP_ASSERT("invalid conn", (conn != NULL));
- LWIP_ASSERT("this is for tcp netconns only", (conn->type == NETCONN_TCP));
- LWIP_ASSERT("conn must be in state NETCONN_CLOSE", (conn->state == NETCONN_CLOSE));
- LWIP_ASSERT("pcb already closed", (conn->pcb.tcp != NULL));
-
- /* Set back some callback pointers */
- tcp_arg(conn->pcb.tcp, NULL);
- if (conn->pcb.tcp->state == LISTEN) {
- tcp_accept(conn->pcb.tcp, NULL);
- } else {
- tcp_recv(conn->pcb.tcp, NULL);
- tcp_accept(conn->pcb.tcp, NULL);
- /* some callbacks have to be reset if tcp_close is not successful */
- tcp_sent(conn->pcb.tcp, NULL);
- tcp_poll(conn->pcb.tcp, NULL, 4);
- tcp_err(conn->pcb.tcp, NULL);
- }
- /* Try to close the connection */
- err = tcp_close(conn->pcb.tcp);
- if (err == ERR_OK) {
- /* Closing succeeded */
- conn->state = NETCONN_NONE;
- /* Set back some callback pointers as conn is going away */
- conn->pcb.tcp = NULL;
- conn->err = ERR_OK;
- /* Trigger select() in socket layer. This send should something else so the
- errorfd is set, not the read and write fd! */
- API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
- API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
- /* wake up the application task */
- sys_sem_signal(conn->op_completed);
- } else {
- /* Closing failed, restore some of the callbacks */
- /* Closing of listen pcb will never fail! */
- LWIP_ASSERT("Closing a listen pcb may not fail!", (conn->pcb.tcp->state != LISTEN));
- tcp_sent(conn->pcb.tcp, sent_tcp);
- tcp_poll(conn->pcb.tcp, poll_tcp, 4);
- tcp_err(conn->pcb.tcp, err_tcp);
- tcp_arg(conn->pcb.tcp, conn);
- }
- /* If closing didn't succeed, we get called again either
- from poll_tcp or from sent_tcp */
-}
-#endif /* LWIP_TCP */
-
-/**
- * Delete the pcb inside a netconn.
- * Called from netconn_delete.
- *
- * @param msg the api_msg_msg pointing to the connection
- */
-void
-do_delconn(struct api_msg_msg *msg)
-{
- if (msg->conn->pcb.tcp != NULL) {
- switch (NETCONNTYPE_GROUP(msg->conn->type)) {
-#if LWIP_RAW
- case NETCONN_RAW:
- raw_remove(msg->conn->pcb.raw);
- break;
-#endif /* LWIP_RAW */
-#if LWIP_UDP
- case NETCONN_UDP:
- msg->conn->pcb.udp->recv_arg = NULL;
- udp_remove(msg->conn->pcb.udp);
- break;
-#endif /* LWIP_UDP */
-#if LWIP_TCP
- case NETCONN_TCP:
- msg->conn->state = NETCONN_CLOSE;
- do_close_internal(msg->conn);
- /* API_EVENT is called inside do_close_internal, before releasing
- the application thread, so we can return at this point! */
- return;
-#endif /* LWIP_TCP */
- default:
- break;
- }
- }
- /* tcp netconns don't come here! */
-
- /* Trigger select() in socket layer. This send should something else so the
- errorfd is set, not the read and write fd! */
- API_EVENT(msg->conn, NETCONN_EVT_RCVPLUS, 0);
- API_EVENT(msg->conn, NETCONN_EVT_SENDPLUS, 0);
-
- if (msg->conn->op_completed != SYS_SEM_NULL) {
- sys_sem_signal(msg->conn->op_completed);
- }
-}
-
-/**
- * Bind a pcb contained in a netconn
- * Called from netconn_bind.
- *
- * @param msg the api_msg_msg pointing to the connection and containing
- * the IP address and port to bind to
- */
-void
-do_bind(struct api_msg_msg *msg)
-{
- if (!ERR_IS_FATAL(msg->conn->err)) {
- if (msg->conn->pcb.tcp != NULL) {
- switch (NETCONNTYPE_GROUP(msg->conn->type)) {
-#if LWIP_RAW
- case NETCONN_RAW:
- msg->conn->err = raw_bind(msg->conn->pcb.raw, msg->msg.bc.ipaddr);
- break;
-#endif /* LWIP_RAW */
-#if LWIP_UDP
- case NETCONN_UDP:
- msg->conn->err = udp_bind(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port);
- break;
-#endif /* LWIP_UDP */
-#if LWIP_TCP
- case NETCONN_TCP:
- msg->conn->err = tcp_bind(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, msg->msg.bc.port);
- break;
-#endif /* LWIP_TCP */
- default:
- break;
- }
- } else {
- /* msg->conn->pcb is NULL */
- msg->conn->err = ERR_VAL;
- }
- }
- TCPIP_APIMSG_ACK(msg);
-}
-
-#if LWIP_TCP
-/**
- * TCP callback function if a connection (opened by tcp_connect/do_connect) has
- * been established (or reset by the remote host).
- *
- * @see tcp.h (struct tcp_pcb.connected) for parameters and return values
- */
-static err_t
-do_connected(void *arg, struct tcp_pcb *pcb, err_t err)
-{
- struct netconn *conn;
-
- LWIP_UNUSED_ARG(pcb);
-
- conn = arg;
-
- if (conn == NULL) {
- return ERR_VAL;
- }
-
- conn->err = err;
- if ((conn->type == NETCONN_TCP) && (err == ERR_OK)) {
- setup_tcp(conn);
- }
- conn->state = NETCONN_NONE;
- sys_sem_signal(conn->op_completed);
- return ERR_OK;
-}
-#endif /* LWIP_TCP */
-
-/**
- * Connect a pcb contained inside a netconn
- * Called from netconn_connect.
- *
- * @param msg the api_msg_msg pointing to the connection and containing
- * the IP address and port to connect to
- */
-void
-do_connect(struct api_msg_msg *msg)
-{
- if (msg->conn->pcb.tcp == NULL) {
- sys_sem_signal(msg->conn->op_completed);
- return;
- }
-
- switch (NETCONNTYPE_GROUP(msg->conn->type)) {
-#if LWIP_RAW
- case NETCONN_RAW:
- msg->conn->err = raw_connect(msg->conn->pcb.raw, msg->msg.bc.ipaddr);
- sys_sem_signal(msg->conn->op_completed);
- break;
-#endif /* LWIP_RAW */
-#if LWIP_UDP
- case NETCONN_UDP:
- msg->conn->err = udp_connect(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port);
- sys_sem_signal(msg->conn->op_completed);
- break;
-#endif /* LWIP_UDP */
-#if LWIP_TCP
- case NETCONN_TCP:
- msg->conn->state = NETCONN_CONNECT;
- setup_tcp(msg->conn);
- msg->conn->err = tcp_connect(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, msg->msg.bc.port,
- do_connected);
- /* sys_sem_signal() is called from do_connected (or err_tcp()),
- * when the connection is established! */
- break;
-#endif /* LWIP_TCP */
- default:
- LWIP_ERROR("Invalid netconn type", 0, do{ msg->conn->err = ERR_VAL;
- sys_sem_signal(msg->conn->op_completed); }while(0));
- break;
- }
-}
-
-/**
- * Connect a pcb contained inside a netconn
- * Only used for UDP netconns.
- * Called from netconn_disconnect.
- *
- * @param msg the api_msg_msg pointing to the connection to disconnect
- */
-void
-do_disconnect(struct api_msg_msg *msg)
-{
-#if LWIP_UDP
- if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) {
- udp_disconnect(msg->conn->pcb.udp);
- }
-#endif /* LWIP_UDP */
- TCPIP_APIMSG_ACK(msg);
-}
-
-/**
- * Set a TCP pcb contained in a netconn into listen mode
- * Called from netconn_listen.
- *
- * @param msg the api_msg_msg pointing to the connection
- */
-void
-do_listen(struct api_msg_msg *msg)
-{
-#if LWIP_TCP
- if (!ERR_IS_FATAL(msg->conn->err)) {
- if (msg->conn->pcb.tcp != NULL) {
- if (msg->conn->type == NETCONN_TCP) {
- if (msg->conn->pcb.tcp->state == CLOSED) {
-#if TCP_LISTEN_BACKLOG
- struct tcp_pcb* lpcb = tcp_listen_with_backlog(msg->conn->pcb.tcp, msg->msg.lb.backlog);
-#else /* TCP_LISTEN_BACKLOG */
- struct tcp_pcb* lpcb = tcp_listen(msg->conn->pcb.tcp);
-#endif /* TCP_LISTEN_BACKLOG */
- if (lpcb == NULL) {
- msg->conn->err = ERR_MEM;
- } else {
- /* delete the recvmbox and allocate the acceptmbox */
- if (msg->conn->recvmbox != SYS_MBOX_NULL) {
- /** @todo: should we drain the recvmbox here? */
- sys_mbox_free(msg->conn->recvmbox);
- msg->conn->recvmbox = SYS_MBOX_NULL;
- }
- if (msg->conn->acceptmbox == SYS_MBOX_NULL) {
- if ((msg->conn->acceptmbox = sys_mbox_new(DEFAULT_ACCEPTMBOX_SIZE)) == SYS_MBOX_NULL) {
- msg->conn->err = ERR_MEM;
- }
- }
- if (msg->conn->err == ERR_OK) {
- msg->conn->state = NETCONN_LISTEN;
- msg->conn->pcb.tcp = lpcb;
- tcp_arg(msg->conn->pcb.tcp, msg->conn);
- tcp_accept(msg->conn->pcb.tcp, accept_function);
- }
- }
- } else {
- msg->conn->err = ERR_CONN;
- }
- }
- }
- }
-#endif /* LWIP_TCP */
- TCPIP_APIMSG_ACK(msg);
-}
-
-/**
- * Send some data on a RAW or UDP pcb contained in a netconn
- * Called from netconn_send
- *
- * @param msg the api_msg_msg pointing to the connection
- */
-void
-do_send(struct api_msg_msg *msg)
-{
- if (!ERR_IS_FATAL(msg->conn->err)) {
- if (msg->conn->pcb.tcp != NULL) {
- switch (NETCONNTYPE_GROUP(msg->conn->type)) {
-#if LWIP_RAW
- case NETCONN_RAW:
- if (msg->msg.b->addr == NULL) {
- msg->conn->err = raw_send(msg->conn->pcb.raw, msg->msg.b->p);
- } else {
- msg->conn->err = raw_sendto(msg->conn->pcb.raw, msg->msg.b->p, msg->msg.b->addr);
- }
- break;
-#endif
-#if LWIP_UDP
- case NETCONN_UDP:
- if (msg->msg.b->addr == NULL) {
- msg->conn->err = udp_send(msg->conn->pcb.udp, msg->msg.b->p);
- } else {
- msg->conn->err = udp_sendto(msg->conn->pcb.udp, msg->msg.b->p, msg->msg.b->addr, msg->msg.b->port);
- }
- break;
-#endif /* LWIP_UDP */
- default:
- break;
- }
- }
- }
- TCPIP_APIMSG_ACK(msg);
-}
-
-/**
- * Indicate data has been received from a TCP pcb contained in a netconn
- * Called from netconn_recv
- *
- * @param msg the api_msg_msg pointing to the connection
- */
-void
-do_recv(struct api_msg_msg *msg)
-{
-#if LWIP_TCP
- if (!ERR_IS_FATAL(msg->conn->err)) {
- if (msg->conn->pcb.tcp != NULL) {
- if (msg->conn->type == NETCONN_TCP) {
-#if TCP_LISTEN_BACKLOG
- if (msg->conn->pcb.tcp->state == LISTEN) {
- tcp_accepted(msg->conn->pcb.tcp);
- } else
-#endif /* TCP_LISTEN_BACKLOG */
- {
- tcp_recved(msg->conn->pcb.tcp, msg->msg.r.len);
- }
- }
- }
- }
-#endif /* LWIP_TCP */
- TCPIP_APIMSG_ACK(msg);
-}
-
-#if LWIP_TCP
-/**
- * See if more data needs to be written from a previous call to netconn_write.
- * Called initially from do_write. If the first call can't send all data
- * (because of low memory or empty send-buffer), this function is called again
- * from sent_tcp() or poll_tcp() to send more data. If all data is sent, the
- * blocking application thread (waiting in netconn_write) is released.
- *
- * @param conn netconn (that is currently in state NETCONN_WRITE) to process
- * @return ERR_OK
- * ERR_MEM if LWIP_TCPIP_CORE_LOCKING=1 and sending hasn't yet finished
- */
-static err_t
-do_writemore(struct netconn *conn)
-{
- err_t err;
- void *dataptr;
- u16_t len, available;
- u8_t write_finished = 0;
- size_t diff;
-
- LWIP_ASSERT("conn->state == NETCONN_WRITE", (conn->state == NETCONN_WRITE));
-
- dataptr = (u8_t*)conn->write_msg->msg.w.dataptr + conn->write_offset;
- diff = conn->write_msg->msg.w.len - conn->write_offset;
- if (diff > 0xffffUL) { /* max_u16_t */
- len = 0xffff;
-#if LWIP_TCPIP_CORE_LOCKING
- conn->write_delayed = 1;
-#endif
- } else {
- len = (u16_t)diff;
- }
- available = tcp_sndbuf(conn->pcb.tcp);
- if (available < len) {
- /* don't try to write more than sendbuf */
- len = available;
-#if LWIP_TCPIP_CORE_LOCKING
- conn->write_delayed = 1;
-#endif
- }
-
- err = tcp_write(conn->pcb.tcp, dataptr, len, conn->write_msg->msg.w.apiflags);
- LWIP_ASSERT("do_writemore: invalid length!", ((conn->write_offset + len) <= conn->write_msg->msg.w.len));
- if (err == ERR_OK) {
- conn->write_offset += len;
- if (conn->write_offset == conn->write_msg->msg.w.len) {
- /* everything was written */
- write_finished = 1;
- conn->write_msg = NULL;
- conn->write_offset = 0;
- /* API_EVENT might call tcp_tmr, so reset conn->state now */
- conn->state = NETCONN_NONE;
- }
- err = tcp_output_nagle(conn->pcb.tcp);
- conn->err = err;
- if ((err == ERR_OK) && (tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT)) {
- API_EVENT(conn, NETCONN_EVT_SENDMINUS, len);
- }
- } else if (err == ERR_MEM) {
- /* If ERR_MEM, we wait for sent_tcp or poll_tcp to be called
- we do NOT return to the application thread, since ERR_MEM is
- only a temporary error! */
-
- /* tcp_enqueue returned ERR_MEM, try tcp_output anyway */
- err = tcp_output(conn->pcb.tcp);
-
-#if LWIP_TCPIP_CORE_LOCKING
- conn->write_delayed = 1;
-#endif
- } else {
- /* On errors != ERR_MEM, we don't try writing any more but return
- the error to the application thread. */
- conn->err = err;
- write_finished = 1;
- }
-
- if (write_finished) {
- /* everything was written: set back connection state
- and back to application task */
- conn->state = NETCONN_NONE;
-#if LWIP_TCPIP_CORE_LOCKING
- if (conn->write_delayed != 0)
-#endif
- {
- sys_sem_signal(conn->op_completed);
- }
- }
-#if LWIP_TCPIP_CORE_LOCKING
- else
- return ERR_MEM;
-#endif
- return ERR_OK;
-}
-#endif /* LWIP_TCP */
-
-/**
- * Send some data on a TCP pcb contained in a netconn
- * Called from netconn_write
- *
- * @param msg the api_msg_msg pointing to the connection
- */
-void
-do_write(struct api_msg_msg *msg)
-{
- if (!ERR_IS_FATAL(msg->conn->err)) {
- if ((msg->conn->pcb.tcp != NULL) && (msg->conn->type == NETCONN_TCP)) {
-#if LWIP_TCP
- msg->conn->state = NETCONN_WRITE;
- /* set all the variables used by do_writemore */
- LWIP_ASSERT("already writing", msg->conn->write_msg == NULL &&
- msg->conn->write_offset == 0);
- msg->conn->write_msg = msg;
- msg->conn->write_offset = 0;
-#if LWIP_TCPIP_CORE_LOCKING
- msg->conn->write_delayed = 0;
- if (do_writemore(msg->conn) != ERR_OK) {
- LWIP_ASSERT("state!", msg->conn->state == NETCONN_WRITE);
- UNLOCK_TCPIP_CORE();
- sys_arch_sem_wait(msg->conn->op_completed, 0);
- LOCK_TCPIP_CORE();
- LWIP_ASSERT("state!", msg->conn->state == NETCONN_NONE);
- }
-#else
- do_writemore(msg->conn);
-#endif
- /* for both cases: if do_writemore was called, don't ACK the APIMSG! */
- return;
-#endif /* LWIP_TCP */
-#if (LWIP_UDP || LWIP_RAW)
- } else {
- msg->conn->err = ERR_VAL;
-#endif /* (LWIP_UDP || LWIP_RAW) */
- }
- }
- TCPIP_APIMSG_ACK(msg);
-}
-
-/**
- * Return a connection's local or remote address
- * Called from netconn_getaddr
- *
- * @param msg the api_msg_msg pointing to the connection
- */
-void
-do_getaddr(struct api_msg_msg *msg)
-{
- if (msg->conn->pcb.ip != NULL) {
- *(msg->msg.ad.ipaddr) = (msg->msg.ad.local?msg->conn->pcb.ip->local_ip:msg->conn->pcb.ip->remote_ip);
-
- switch (NETCONNTYPE_GROUP(msg->conn->type)) {
-#if LWIP_RAW
- case NETCONN_RAW:
- if (msg->msg.ad.local) {
- *(msg->msg.ad.port) = msg->conn->pcb.raw->protocol;
- } else {
- /* return an error as connecting is only a helper for upper layers */
- msg->conn->err = ERR_CONN;
- }
- break;
-#endif /* LWIP_RAW */
-#if LWIP_UDP
- case NETCONN_UDP:
- if (msg->msg.ad.local) {
- *(msg->msg.ad.port) = msg->conn->pcb.udp->local_port;
- } else {
- if ((msg->conn->pcb.udp->flags & UDP_FLAGS_CONNECTED) == 0) {
- msg->conn->err = ERR_CONN;
- } else {
- *(msg->msg.ad.port) = msg->conn->pcb.udp->remote_port;
- }
- }
- break;
-#endif /* LWIP_UDP */
-#if LWIP_TCP
- case NETCONN_TCP:
- *(msg->msg.ad.port) = (msg->msg.ad.local?msg->conn->pcb.tcp->local_port:msg->conn->pcb.tcp->remote_port);
- break;
-#endif /* LWIP_TCP */
- }
- } else {
- msg->conn->err = ERR_CONN;
- }
- TCPIP_APIMSG_ACK(msg);
-}
-
-/**
- * Close a TCP pcb contained in a netconn
- * Called from netconn_close
- *
- * @param msg the api_msg_msg pointing to the connection
- */
-void
-do_close(struct api_msg_msg *msg)
-{
-#if LWIP_TCP
- if ((msg->conn->pcb.tcp != NULL) && (msg->conn->type == NETCONN_TCP)) {
- msg->conn->state = NETCONN_CLOSE;
- do_close_internal(msg->conn);
- /* for tcp netconns, do_close_internal ACKs the message */
- } else
-#endif /* LWIP_TCP */
- {
- msg->conn->err = ERR_VAL;
- sys_sem_signal(msg->conn->op_completed);
- }
-}
-
-#if LWIP_IGMP
-/**
- * Join multicast groups for UDP netconns.
- * Called from netconn_join_leave_group
- *
- * @param msg the api_msg_msg pointing to the connection
- */
-void
-do_join_leave_group(struct api_msg_msg *msg)
-{
- if (!ERR_IS_FATAL(msg->conn->err)) {
- if (msg->conn->pcb.tcp != NULL) {
- if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) {
-#if LWIP_UDP
- if (msg->msg.jl.join_or_leave == NETCONN_JOIN) {
- msg->conn->err = igmp_joingroup(msg->msg.jl.interface, msg->msg.jl.multiaddr);
- } else {
- msg->conn->err = igmp_leavegroup(msg->msg.jl.interface, msg->msg.jl.multiaddr);
- }
-#endif /* LWIP_UDP */
-#if (LWIP_TCP || LWIP_RAW)
- } else {
- msg->conn->err = ERR_VAL;
-#endif /* (LWIP_TCP || LWIP_RAW) */
- }
- }
- }
- TCPIP_APIMSG_ACK(msg);
-}
-#endif /* LWIP_IGMP */
-
-#if LWIP_DNS
-/**
- * Callback function that is called when DNS name is resolved
- * (or on timeout). A waiting application thread is waked up by
- * signaling the semaphore.
- */
-static void
-do_dns_found(const char *name, struct ip_addr *ipaddr, void *arg)
-{
- struct dns_api_msg *msg = (struct dns_api_msg*)arg;
-
- LWIP_ASSERT("DNS response for wrong host name", strcmp(msg->name, name) == 0);
-
- if (ipaddr == NULL) {
- /* timeout or memory error */
- *msg->err = ERR_VAL;
- } else {
- /* address was resolved */
- *msg->err = ERR_OK;
- *msg->addr = *ipaddr;
- }
- /* wake up the application task waiting in netconn_gethostbyname */
- sys_sem_signal(msg->sem);
-}
-
-/**
- * Execute a DNS query
- * Called from netconn_gethostbyname
- *
- * @param arg the dns_api_msg pointing to the query
- */
-void
-do_gethostbyname(void *arg)
-{
- struct dns_api_msg *msg = (struct dns_api_msg*)arg;
-
- *msg->err = dns_gethostbyname(msg->name, msg->addr, do_dns_found, msg);
- if (*msg->err != ERR_INPROGRESS) {
- /* on error or immediate success, wake up the application
- * task waiting in netconn_gethostbyname */
- sys_sem_signal(msg->sem);
- }
-}
-#endif /* LWIP_DNS */
-
-#endif /* LWIP_NETCONN */
+/**
+ * @file
+ * Sequential API Internal module
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2004 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 <[email protected]>
+ *
+ */
+
+#include "lwip/opt.h"
+
+#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/api_msg.h"
+
+#include "lwip/ip.h"
+#include "lwip/udp.h"
+#include "lwip/tcp.h"
+#include "lwip/raw.h"
+
+#include "lwip/memp.h"
+#include "lwip/tcpip.h"
+#include "lwip/igmp.h"
+#include "lwip/dns.h"
+
+#include <string.h>
+
+/* forward declarations */
+#if LWIP_TCP
+static err_t do_writemore(struct netconn *conn);
+static void do_close_internal(struct netconn *conn);
+#endif
+
+#if LWIP_RAW
+/**
+ * Receive callback function for RAW netconns.
+ * Doesn't 'eat' the packet, only references it and sends it to
+ * conn->recvmbox
+ *
+ * @see raw.h (struct raw_pcb.recv) for parameters and return value
+ */
+static u8_t
+recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p,
+ struct ip_addr *addr)
+{
+ struct pbuf *q;
+ struct netbuf *buf;
+ struct netconn *conn;
+#if LWIP_SO_RCVBUF
+ int recv_avail;
+#endif /* LWIP_SO_RCVBUF */
+
+ LWIP_UNUSED_ARG(addr);
+ conn = arg;
+
+#if LWIP_SO_RCVBUF
+ SYS_ARCH_GET(conn->recv_avail, recv_avail);
+ if ((conn != NULL) && (conn->recvmbox != SYS_MBOX_NULL) &&
+ ((recv_avail + (int)(p->tot_len)) <= conn->recv_bufsize)) {
+#else /* LWIP_SO_RCVBUF */
+ if ((conn != NULL) && (conn->recvmbox != SYS_MBOX_NULL)) {
+#endif /* LWIP_SO_RCVBUF */
+ /* copy the whole packet into new pbufs */
+ q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);
+ if(q != NULL) {
+ if (pbuf_copy(q, p) != ERR_OK) {
+ pbuf_free(q);
+ q = NULL;
+ }
+ }
+
+ if(q != NULL) {
+ buf = memp_malloc(MEMP_NETBUF);
+ if (buf == NULL) {
+ pbuf_free(q);
+ return 0;
+ }
+
+ buf->p = q;
+ buf->ptr = q;
+ buf->addr = &(((struct ip_hdr*)(q->payload))->src);
+ buf->port = pcb->protocol;
+
+ if (sys_mbox_trypost(conn->recvmbox, buf) != ERR_OK) {
+ netbuf_delete(buf);
+ return 0;
+ } else {
+ SYS_ARCH_INC(conn->recv_avail, q->tot_len);
+ /* Register event with callback */
+ API_EVENT(conn, NETCONN_EVT_RCVPLUS, q->tot_len);
+ }
+ }
+ }
+
+ return 0; /* do not eat the packet */
+}
+#endif /* LWIP_RAW*/
+
+#if LWIP_UDP
+/**
+ * Receive callback function for UDP netconns.
+ * Posts the packet to conn->recvmbox or deletes it on memory error.
+ *
+ * @see udp.h (struct udp_pcb.recv) for parameters
+ */
+static void
+recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
+ struct ip_addr *addr, u16_t port)
+{
+ struct netbuf *buf;
+ struct netconn *conn;
+#if LWIP_SO_RCVBUF
+ int recv_avail;
+#endif /* LWIP_SO_RCVBUF */
+
+ LWIP_UNUSED_ARG(pcb); /* only used for asserts... */
+ LWIP_ASSERT("recv_udp must have a pcb argument", pcb != NULL);
+ LWIP_ASSERT("recv_udp must have an argument", arg != NULL);
+ conn = arg;
+ LWIP_ASSERT("recv_udp: recv for wrong pcb!", conn->pcb.udp == pcb);
+
+#if LWIP_SO_RCVBUF
+ SYS_ARCH_GET(conn->recv_avail, recv_avail);
+ if ((conn == NULL) || (conn->recvmbox == SYS_MBOX_NULL) ||
+ ((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize)) {
+#else /* LWIP_SO_RCVBUF */
+ if ((conn == NULL) || (conn->recvmbox == SYS_MBOX_NULL)) {
+#endif /* LWIP_SO_RCVBUF */
+ pbuf_free(p);
+ return;
+ }
+
+ buf = memp_malloc(MEMP_NETBUF);
+ if (buf == NULL) {
+ pbuf_free(p);
+ return;
+ } else {
+ buf->p = p;
+ buf->ptr = p;
+ buf->addr = addr;
+ buf->port = port;
+#if LWIP_NETBUF_RECVINFO
+ {
+ const struct ip_hdr* iphdr = ip_current_header();
+ /* get the UDP header - always in the first pbuf, ensured by udp_input */
+ const struct udp_hdr* udphdr = (void*)(((char*)iphdr) + IPH_LEN(iphdr));
+ buf->toaddr = (struct ip_addr*)&iphdr->dest;
+ buf->toport = udphdr->dest;
+ }
+#endif /* LWIP_NETBUF_RECVINFO */
+ }
+
+ if (sys_mbox_trypost(conn->recvmbox, buf) != ERR_OK) {
+ netbuf_delete(buf);
+ return;
+ } else {
+ SYS_ARCH_INC(conn->recv_avail, p->tot_len);
+ /* Register event with callback */
+ API_EVENT(conn, NETCONN_EVT_RCVPLUS, p->tot_len);
+ }
+}
+#endif /* LWIP_UDP */
+
+#if LWIP_TCP
+/**
+ * Receive callback function for TCP netconns.
+ * Posts the packet to conn->recvmbox, but doesn't delete it on errors.
+ *
+ * @see tcp.h (struct tcp_pcb.recv) for parameters and return value
+ */
+static err_t
+recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
+{
+ struct netconn *conn;
+ u16_t len;
+
+ LWIP_UNUSED_ARG(pcb);
+ LWIP_ASSERT("recv_tcp must have a pcb argument", pcb != NULL);
+ LWIP_ASSERT("recv_tcp must have an argument", arg != NULL);
+ conn = arg;
+ LWIP_ASSERT("recv_tcp: recv for wrong pcb!", conn->pcb.tcp == pcb);
+
+ if ((conn == NULL) || (conn->recvmbox == SYS_MBOX_NULL)) {
+ return ERR_VAL;
+ }
+
+ conn->err = err;
+ if (p != NULL) {
+ len = p->tot_len;
+ SYS_ARCH_INC(conn->recv_avail, len);
+ } else {
+ len = 0;
+ }
+
+ if (sys_mbox_trypost(conn->recvmbox, p) != ERR_OK) {
+ return ERR_MEM;
+ } else {
+ /* Register event with callback */
+ API_EVENT(conn, NETCONN_EVT_RCVPLUS, len);
+ }
+
+ return ERR_OK;
+}
+
+/**
+ * Poll callback function for TCP netconns.
+ * Wakes up an application thread that waits for a connection to close
+ * or data to be sent. The application thread then takes the
+ * appropriate action to go on.
+ *
+ * Signals the conn->sem.
+ * netconn_close waits for conn->sem if closing failed.
+ *
+ * @see tcp.h (struct tcp_pcb.poll) for parameters and return value
+ */
+static err_t
+poll_tcp(void *arg, struct tcp_pcb *pcb)
+{
+ struct netconn *conn = arg;
+
+ LWIP_UNUSED_ARG(pcb);
+ LWIP_ASSERT("conn != NULL", (conn != NULL));
+
+ if (conn->state == NETCONN_WRITE) {
+ do_writemore(conn);
+ } else if (conn->state == NETCONN_CLOSE) {
+ do_close_internal(conn);
+ }
+
+ return ERR_OK;
+}
+
+/**
+ * Sent callback function for TCP netconns.
+ * Signals the conn->sem and calls API_EVENT.
+ * netconn_write waits for conn->sem if send buffer is low.
+ *
+ * @see tcp.h (struct tcp_pcb.sent) for parameters and return value
+ */
+static err_t
+sent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len)
+{
+ struct netconn *conn = arg;
+
+ LWIP_UNUSED_ARG(pcb);
+ LWIP_ASSERT("conn != NULL", (conn != NULL));
+
+ if (conn->state == NETCONN_WRITE) {
+ LWIP_ASSERT("conn->pcb.tcp != NULL", conn->pcb.tcp != NULL);
+ do_writemore(conn);
+ } else if (conn->state == NETCONN_CLOSE) {
+ do_close_internal(conn);
+ }
+
+ if (conn) {
+ if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT)) {
+ API_EVENT(conn, NETCONN_EVT_SENDPLUS, len);
+ }
+ }
+
+ return ERR_OK;
+}
+
+/**
+ * Error callback function for TCP netconns.
+ * Signals conn->sem, posts to all conn mboxes and calls API_EVENT.
+ * The application thread has then to decide what to do.
+ *
+ * @see tcp.h (struct tcp_pcb.err) for parameters
+ */
+static void
+err_tcp(void *arg, err_t err)
+{
+ struct netconn *conn;
+
+ conn = arg;
+ LWIP_ASSERT("conn != NULL", (conn != NULL));
+
+ conn->pcb.tcp = NULL;
+
+ conn->err = err;
+ if (conn->recvmbox != SYS_MBOX_NULL) {
+ /* Register event with callback */
+ API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
+ sys_mbox_post(conn->recvmbox, NULL);
+ }
+ if (conn->op_completed != SYS_SEM_NULL && conn->state == NETCONN_CONNECT) {
+ conn->state = NETCONN_NONE;
+ sys_sem_signal(conn->op_completed);
+ }
+ if (conn->acceptmbox != SYS_MBOX_NULL) {
+ /* Register event with callback */
+ API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
+ sys_mbox_post(conn->acceptmbox, NULL);
+ }
+ if ((conn->state == NETCONN_WRITE) || (conn->state == NETCONN_CLOSE)) {
+ /* calling do_writemore/do_close_internal is not necessary
+ since the pcb has already been deleted! */
+ conn->state = NETCONN_NONE;
+ /* wake up the waiting task */
+ sys_sem_signal(conn->op_completed);
+ }
+}
+
+/**
+ * Setup a tcp_pcb with the correct callback function pointers
+ * and their arguments.
+ *
+ * @param conn the TCP netconn to setup
+ */
+static void
+setup_tcp(struct netconn *conn)
+{
+ struct tcp_pcb *pcb;
+
+ pcb = conn->pcb.tcp;
+ tcp_arg(pcb, conn);
+ tcp_recv(pcb, recv_tcp);
+ tcp_sent(pcb, sent_tcp);
+ tcp_poll(pcb, poll_tcp, 4);
+ tcp_err(pcb, err_tcp);
+}
+
+/**
+ * Accept callback function for TCP netconns.
+ * Allocates a new netconn and posts that to conn->acceptmbox.
+ *
+ * @see tcp.h (struct tcp_pcb_listen.accept) for parameters and return value
+ */
+static err_t
+accept_function(void *arg, struct tcp_pcb *newpcb, err_t err)
+{
+ struct netconn *newconn;
+ struct netconn *conn;
+
+#if API_MSG_DEBUG
+#if TCP_DEBUG
+ tcp_debug_print_state(newpcb->state);
+#endif /* TCP_DEBUG */
+#endif /* API_MSG_DEBUG */
+ conn = (struct netconn *)arg;
+
+ /* check whether acceptmbox is valid */
+ if (conn->acceptmbox == SYS_MBOX_NULL)
+ {
+ LWIP_DEBUGF(API_MSG_DEBUG, ("accept_function: acceptmbox already deleted\n"));
+ return ERR_VAL;
+ }
+
+ /* We have to set the callback here even though
+ * the new socket is unknown. conn->socket is marked as -1. */
+ newconn = netconn_alloc(conn->type, conn->callback);
+ if (newconn == NULL) {
+ return ERR_MEM;
+ }
+ newconn->pcb.tcp = newpcb;
+ setup_tcp(newconn);
+ newconn->err = err;
+
+ if (sys_mbox_trypost(conn->acceptmbox, newconn) != ERR_OK) {
+ /* When returning != ERR_OK, the connection is aborted in tcp_process(),
+ so do nothing here! */
+ newconn->pcb.tcp = NULL;
+ netconn_free(newconn);
+ return ERR_MEM;
+ } else {
+ /* Register event with callback */
+ API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
+ }
+
+ return ERR_OK;
+}
+#endif /* LWIP_TCP */
+
+/**
+ * Create a new pcb of a specific type.
+ * Called from do_newconn().
+ *
+ * @param msg the api_msg_msg describing the connection type
+ * @return msg->conn->err, but the return value is currently ignored
+ */
+static err_t
+pcb_new(struct api_msg_msg *msg)
+{
+ msg->conn->err = ERR_OK;
+
+ LWIP_ASSERT("pcb_new: pcb already allocated", msg->conn->pcb.tcp == NULL);
+
+ /* Allocate a PCB for this connection */
+ switch(NETCONNTYPE_GROUP(msg->conn->type)) {
+#if LWIP_RAW
+ case NETCONN_RAW:
+ msg->conn->pcb.raw = raw_new(msg->msg.n.proto);
+ if(msg->conn->pcb.raw == NULL) {
+ msg->conn->err = ERR_MEM;
+ break;
+ }
+ raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn);
+ break;
+#endif /* LWIP_RAW */
+#if LWIP_UDP
+ case NETCONN_UDP:
+ msg->conn->pcb.udp = udp_new();
+ if(msg->conn->pcb.udp == NULL) {
+ msg->conn->err = ERR_MEM;
+ break;
+ }
+#if LWIP_UDPLITE
+ if (msg->conn->type==NETCONN_UDPLITE) {
+ udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE);
+ }
+#endif /* LWIP_UDPLITE */
+ if (msg->conn->type==NETCONN_UDPNOCHKSUM) {
+ udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM);
+ }
+ udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
+ break;
+#endif /* LWIP_UDP */
+#if LWIP_TCP
+ case NETCONN_TCP:
+ msg->conn->pcb.tcp = tcp_new();
+ if(msg->conn->pcb.tcp == NULL) {
+ msg->conn->err = ERR_MEM;
+ break;
+ }
+ setup_tcp(msg->conn);
+ break;
+#endif /* LWIP_TCP */
+ default:
+ /* Unsupported netconn type, e.g. protocol disabled */
+ msg->conn->err = ERR_VAL;
+ break;
+ }
+
+ return msg->conn->err;
+}
+
+/**
+ * Create a new pcb of a specific type inside a netconn.
+ * Called from netconn_new_with_proto_and_callback.
+ *
+ * @param msg the api_msg_msg describing the connection type
+ */
+void
+do_newconn(struct api_msg_msg *msg)
+{
+ if(msg->conn->pcb.tcp == NULL) {
+ pcb_new(msg);
+ }
+ /* Else? This "new" connection already has a PCB allocated. */
+ /* Is this an error condition? Should it be deleted? */
+ /* We currently just are happy and return. */
+
+ TCPIP_APIMSG_ACK(msg);
+}
+
+/**
+ * Create a new netconn (of a specific type) that has a callback function.
+ * The corresponding pcb is NOT created!
+ *
+ * @param t the type of 'connection' to create (@see enum netconn_type)
+ * @param proto the IP protocol for RAW IP pcbs
+ * @param callback a function to call on status changes (RX available, TX'ed)
+ * @return a newly allocated struct netconn or
+ * NULL on memory error
+ */
+struct netconn*
+netconn_alloc(enum netconn_type t, netconn_callback callback)
+{
+ struct netconn *conn;
+ int size;
+
+ conn = memp_malloc(MEMP_NETCONN);
+ if (conn == NULL) {
+ return NULL;
+ }
+
+ conn->err = ERR_OK;
+ conn->type = t;
+ conn->pcb.tcp = NULL;
+
+#if (DEFAULT_RAW_RECVMBOX_SIZE == DEFAULT_UDP_RECVMBOX_SIZE) && \
+ (DEFAULT_RAW_RECVMBOX_SIZE == DEFAULT_TCP_RECVMBOX_SIZE)
+ size = DEFAULT_RAW_RECVMBOX_SIZE;
+#else
+ size = 0; /* skip warning */
+ switch(NETCONNTYPE_GROUP(t)) {
+#if LWIP_RAW
+ case NETCONN_RAW:
+ size = DEFAULT_RAW_RECVMBOX_SIZE;
+ break;
+#endif /* LWIP_RAW */
+#if LWIP_UDP
+ case NETCONN_UDP:
+ size = DEFAULT_UDP_RECVMBOX_SIZE;
+ break;
+#endif /* LWIP_UDP */
+#if LWIP_TCP
+ case NETCONN_TCP:
+ size = DEFAULT_TCP_RECVMBOX_SIZE;
+ break;
+#endif /* LWIP_TCP */
+ default:
+ LWIP_ASSERT("netconn_alloc: undefined netconn_type", 0);
+ break;
+ }
+#endif
+
+ if ((conn->op_completed = sys_sem_new(0)) == SYS_SEM_NULL) {
+ memp_free(MEMP_NETCONN, conn);
+ return NULL;
+ }
+ if ((conn->recvmbox = sys_mbox_new(size)) == SYS_MBOX_NULL) {
+ sys_sem_free(conn->op_completed);
+ memp_free(MEMP_NETCONN, conn);
+ return NULL;
+ }
+
+ conn->acceptmbox = SYS_MBOX_NULL;
+ conn->state = NETCONN_NONE;
+ /* initialize socket to -1 since 0 is a valid socket */
+ conn->socket = -1;
+ conn->callback = callback;
+ conn->recv_avail = 0;
+#if LWIP_TCP
+ conn->write_msg = NULL;
+ conn->write_offset = 0;
+#if LWIP_TCPIP_CORE_LOCKING
+ conn->write_delayed = 0;
+#endif /* LWIP_TCPIP_CORE_LOCKING */
+#endif /* LWIP_TCP */
+#if LWIP_SO_RCVTIMEO
+ conn->recv_timeout = 0;
+#endif /* LWIP_SO_RCVTIMEO */
+#if LWIP_SO_RCVBUF
+ conn->recv_bufsize = RECV_BUFSIZE_DEFAULT;
+#endif /* LWIP_SO_RCVBUF */
+ return conn;
+}
+
+/**
+ * Delete a netconn and all its resources.
+ * The pcb is NOT freed (since we might not be in the right thread context do this).
+ *
+ * @param conn the netconn to free
+ */
+void
+netconn_free(struct netconn *conn)
+{
+ void *mem;
+ LWIP_ASSERT("PCB must be deallocated outside this function", conn->pcb.tcp == NULL);
+
+ /* Drain the recvmbox. */
+ if (conn->recvmbox != SYS_MBOX_NULL) {
+ while (sys_mbox_tryfetch(conn->recvmbox, &mem) != SYS_MBOX_EMPTY) {
+ if (conn->type == NETCONN_TCP) {
+ if(mem != NULL) {
+ pbuf_free((struct pbuf *)mem);
+ }
+ } else {
+ netbuf_delete((struct netbuf *)mem);
+ }
+ }
+ sys_mbox_free(conn->recvmbox);
+ conn->recvmbox = SYS_MBOX_NULL;
+ }
+
+ /* Drain the acceptmbox. */
+ if (conn->acceptmbox != SYS_MBOX_NULL) {
+ while (sys_mbox_tryfetch(conn->acceptmbox, &mem) != SYS_MBOX_EMPTY) {
+ netconn_delete((struct netconn *)mem);
+ }
+ sys_mbox_free(conn->acceptmbox);
+ conn->acceptmbox = SYS_MBOX_NULL;
+ }
+
+ sys_sem_free(conn->op_completed);
+ conn->op_completed = SYS_SEM_NULL;
+
+ memp_free(MEMP_NETCONN, conn);
+}
+
+#if LWIP_TCP
+/**
+ * Internal helper function to close a TCP netconn: since this sometimes
+ * doesn't work at the first attempt, this function is called from multiple
+ * places.
+ *
+ * @param conn the TCP netconn to close
+ */
+static void
+do_close_internal(struct netconn *conn)
+{
+ err_t err;
+
+ LWIP_ASSERT("invalid conn", (conn != NULL));
+ LWIP_ASSERT("this is for tcp netconns only", (conn->type == NETCONN_TCP));
+ LWIP_ASSERT("conn must be in state NETCONN_CLOSE", (conn->state == NETCONN_CLOSE));
+ LWIP_ASSERT("pcb already closed", (conn->pcb.tcp != NULL));
+
+ /* Set back some callback pointers */
+ tcp_arg(conn->pcb.tcp, NULL);
+ if (conn->pcb.tcp->state == LISTEN) {
+ tcp_accept(conn->pcb.tcp, NULL);
+ } else {
+ tcp_recv(conn->pcb.tcp, NULL);
+ tcp_accept(conn->pcb.tcp, NULL);
+ /* some callbacks have to be reset if tcp_close is not successful */
+ tcp_sent(conn->pcb.tcp, NULL);
+ tcp_poll(conn->pcb.tcp, NULL, 4);
+ tcp_err(conn->pcb.tcp, NULL);
+ }
+ /* Try to close the connection */
+ err = tcp_close(conn->pcb.tcp);
+ if (err == ERR_OK) {
+ /* Closing succeeded */
+ conn->state = NETCONN_NONE;
+ /* Set back some callback pointers as conn is going away */
+ conn->pcb.tcp = NULL;
+ conn->err = ERR_OK;
+ /* Trigger select() in socket layer. This send should something else so the
+ errorfd is set, not the read and write fd! */
+ API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
+ API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
+ /* wake up the application task */
+ sys_sem_signal(conn->op_completed);
+ } else {
+ /* Closing failed, restore some of the callbacks */
+ /* Closing of listen pcb will never fail! */
+ LWIP_ASSERT("Closing a listen pcb may not fail!", (conn->pcb.tcp->state != LISTEN));
+ tcp_sent(conn->pcb.tcp, sent_tcp);
+ tcp_poll(conn->pcb.tcp, poll_tcp, 4);
+ tcp_err(conn->pcb.tcp, err_tcp);
+ tcp_arg(conn->pcb.tcp, conn);
+ }
+ /* If closing didn't succeed, we get called again either
+ from poll_tcp or from sent_tcp */
+}
+#endif /* LWIP_TCP */
+
+/**
+ * Delete the pcb inside a netconn.
+ * Called from netconn_delete.
+ *
+ * @param msg the api_msg_msg pointing to the connection
+ */
+void
+do_delconn(struct api_msg_msg *msg)
+{
+ if (msg->conn->pcb.tcp != NULL) {
+ switch (NETCONNTYPE_GROUP(msg->conn->type)) {
+#if LWIP_RAW
+ case NETCONN_RAW:
+ raw_remove(msg->conn->pcb.raw);
+ break;
+#endif /* LWIP_RAW */
+#if LWIP_UDP
+ case NETCONN_UDP:
+ msg->conn->pcb.udp->recv_arg = NULL;
+ udp_remove(msg->conn->pcb.udp);
+ break;
+#endif /* LWIP_UDP */
+#if LWIP_TCP
+ case NETCONN_TCP:
+ msg->conn->state = NETCONN_CLOSE;
+ do_close_internal(msg->conn);
+ /* API_EVENT is called inside do_close_internal, before releasing
+ the application thread, so we can return at this point! */
+ return;
+#endif /* LWIP_TCP */
+ default:
+ break;
+ }
+ }
+ /* tcp netconns don't come here! */
+
+ /* Trigger select() in socket layer. This send should something else so the
+ errorfd is set, not the read and write fd! */
+ API_EVENT(msg->conn, NETCONN_EVT_RCVPLUS, 0);
+ API_EVENT(msg->conn, NETCONN_EVT_SENDPLUS, 0);
+
+ if (msg->conn->op_completed != SYS_SEM_NULL) {
+ sys_sem_signal(msg->conn->op_completed);
+ }
+}
+
+/**
+ * Bind a pcb contained in a netconn
+ * Called from netconn_bind.
+ *
+ * @param msg the api_msg_msg pointing to the connection and containing
+ * the IP address and port to bind to
+ */
+void
+do_bind(struct api_msg_msg *msg)
+{
+ if (!ERR_IS_FATAL(msg->conn->err)) {
+ if (msg->conn->pcb.tcp != NULL) {
+ switch (NETCONNTYPE_GROUP(msg->conn->type)) {
+#if LWIP_RAW
+ case NETCONN_RAW:
+ msg->conn->err = raw_bind(msg->conn->pcb.raw, msg->msg.bc.ipaddr);
+ break;
+#endif /* LWIP_RAW */
+#if LWIP_UDP
+ case NETCONN_UDP:
+ msg->conn->err = udp_bind(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port);
+ break;
+#endif /* LWIP_UDP */
+#if LWIP_TCP
+ case NETCONN_TCP:
+ msg->conn->err = tcp_bind(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, msg->msg.bc.port);
+ break;
+#endif /* LWIP_TCP */
+ default:
+ break;
+ }
+ } else {
+ /* msg->conn->pcb is NULL */
+ msg->conn->err = ERR_VAL;
+ }
+ }
+ TCPIP_APIMSG_ACK(msg);
+}
+
+#if LWIP_TCP
+/**
+ * TCP callback function if a connection (opened by tcp_connect/do_connect) has
+ * been established (or reset by the remote host).
+ *
+ * @see tcp.h (struct tcp_pcb.connected) for parameters and return values
+ */
+static err_t
+do_connected(void *arg, struct tcp_pcb *pcb, err_t err)
+{
+ struct netconn *conn;
+
+ LWIP_UNUSED_ARG(pcb);
+
+ conn = arg;
+
+ if (conn == NULL) {
+ return ERR_VAL;
+ }
+
+ conn->err = err;
+ if ((conn->type == NETCONN_TCP) && (err == ERR_OK)) {
+ setup_tcp(conn);
+ }
+ conn->state = NETCONN_NONE;
+ sys_sem_signal(conn->op_completed);
+ return ERR_OK;
+}
+#endif /* LWIP_TCP */
+
+/**
+ * Connect a pcb contained inside a netconn
+ * Called from netconn_connect.
+ *
+ * @param msg the api_msg_msg pointing to the connection and containing
+ * the IP address and port to connect to
+ */
+void
+do_connect(struct api_msg_msg *msg)
+{
+ if (msg->conn->pcb.tcp == NULL) {
+ sys_sem_signal(msg->conn->op_completed);
+ return;
+ }
+
+ switch (NETCONNTYPE_GROUP(msg->conn->type)) {
+#if LWIP_RAW
+ case NETCONN_RAW:
+ msg->conn->err = raw_connect(msg->conn->pcb.raw, msg->msg.bc.ipaddr);
+ sys_sem_signal(msg->conn->op_completed);
+ break;
+#endif /* LWIP_RAW */
+#if LWIP_UDP
+ case NETCONN_UDP:
+ msg->conn->err = udp_connect(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port);
+ sys_sem_signal(msg->conn->op_completed);
+ break;
+#endif /* LWIP_UDP */
+#if LWIP_TCP
+ case NETCONN_TCP:
+ msg->conn->state = NETCONN_CONNECT;
+ setup_tcp(msg->conn);
+ msg->conn->err = tcp_connect(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, msg->msg.bc.port,
+ do_connected);
+ /* sys_sem_signal() is called from do_connected (or err_tcp()),
+ * when the connection is established! */
+ break;
+#endif /* LWIP_TCP */
+ default:
+ LWIP_ERROR("Invalid netconn type", 0, do{ msg->conn->err = ERR_VAL;
+ sys_sem_signal(msg->conn->op_completed); }while(0));
+ break;
+ }
+}
+
+/**
+ * Connect a pcb contained inside a netconn
+ * Only used for UDP netconns.
+ * Called from netconn_disconnect.
+ *
+ * @param msg the api_msg_msg pointing to the connection to disconnect
+ */
+void
+do_disconnect(struct api_msg_msg *msg)
+{
+#if LWIP_UDP
+ if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) {
+ udp_disconnect(msg->conn->pcb.udp);
+ }
+#endif /* LWIP_UDP */
+ TCPIP_APIMSG_ACK(msg);
+}
+
+/**
+ * Set a TCP pcb contained in a netconn into listen mode
+ * Called from netconn_listen.
+ *
+ * @param msg the api_msg_msg pointing to the connection
+ */
+void
+do_listen(struct api_msg_msg *msg)
+{
+#if LWIP_TCP
+ if (!ERR_IS_FATAL(msg->conn->err)) {
+ if (msg->conn->pcb.tcp != NULL) {
+ if (msg->conn->type == NETCONN_TCP) {
+ if (msg->conn->pcb.tcp->state == CLOSED) {
+#if TCP_LISTEN_BACKLOG
+ struct tcp_pcb* lpcb = tcp_listen_with_backlog(msg->conn->pcb.tcp, msg->msg.lb.backlog);
+#else /* TCP_LISTEN_BACKLOG */
+ struct tcp_pcb* lpcb = tcp_listen(msg->conn->pcb.tcp);
+#endif /* TCP_LISTEN_BACKLOG */
+ if (lpcb == NULL) {
+ msg->conn->err = ERR_MEM;
+ } else {
+ /* delete the recvmbox and allocate the acceptmbox */
+ if (msg->conn->recvmbox != SYS_MBOX_NULL) {
+ /** @todo: should we drain the recvmbox here? */
+ sys_mbox_free(msg->conn->recvmbox);
+ msg->conn->recvmbox = SYS_MBOX_NULL;
+ }
+ if (msg->conn->acceptmbox == SYS_MBOX_NULL) {
+ if ((msg->conn->acceptmbox = sys_mbox_new(DEFAULT_ACCEPTMBOX_SIZE)) == SYS_MBOX_NULL) {
+ msg->conn->err = ERR_MEM;
+ }
+ }
+ if (msg->conn->err == ERR_OK) {
+ msg->conn->state = NETCONN_LISTEN;
+ msg->conn->pcb.tcp = lpcb;
+ tcp_arg(msg->conn->pcb.tcp, msg->conn);
+ tcp_accept(msg->conn->pcb.tcp, accept_function);
+ }
+ }
+ } else {
+ msg->conn->err = ERR_CONN;
+ }
+ }
+ }
+ }
+#endif /* LWIP_TCP */
+ TCPIP_APIMSG_ACK(msg);
+}
+
+/**
+ * Send some data on a RAW or UDP pcb contained in a netconn
+ * Called from netconn_send
+ *
+ * @param msg the api_msg_msg pointing to the connection
+ */
+void
+do_send(struct api_msg_msg *msg)
+{
+ if (!ERR_IS_FATAL(msg->conn->err)) {
+ if (msg->conn->pcb.tcp != NULL) {
+ switch (NETCONNTYPE_GROUP(msg->conn->type)) {
+#if LWIP_RAW
+ case NETCONN_RAW:
+ if (msg->msg.b->addr == NULL) {
+ msg->conn->err = raw_send(msg->conn->pcb.raw, msg->msg.b->p);
+ } else {
+ msg->conn->err = raw_sendto(msg->conn->pcb.raw, msg->msg.b->p, msg->msg.b->addr);
+ }
+ break;
+#endif
+#if LWIP_UDP
+ case NETCONN_UDP:
+ if (msg->msg.b->addr == NULL) {
+ msg->conn->err = udp_send(msg->conn->pcb.udp, msg->msg.b->p);
+ } else {
+ msg->conn->err = udp_sendto(msg->conn->pcb.udp, msg->msg.b->p, msg->msg.b->addr, msg->msg.b->port);
+ }
+ break;
+#endif /* LWIP_UDP */
+ default:
+ break;
+ }
+ }
+ }
+ TCPIP_APIMSG_ACK(msg);
+}
+
+/**
+ * Indicate data has been received from a TCP pcb contained in a netconn
+ * Called from netconn_recv
+ *
+ * @param msg the api_msg_msg pointing to the connection
+ */
+void
+do_recv(struct api_msg_msg *msg)
+{
+#if LWIP_TCP
+ if (!ERR_IS_FATAL(msg->conn->err)) {
+ if (msg->conn->pcb.tcp != NULL) {
+ if (msg->conn->type == NETCONN_TCP) {
+#if TCP_LISTEN_BACKLOG
+ if (msg->conn->pcb.tcp->state == LISTEN) {
+ tcp_accepted(msg->conn->pcb.tcp);
+ } else
+#endif /* TCP_LISTEN_BACKLOG */
+ {
+ tcp_recved(msg->conn->pcb.tcp, msg->msg.r.len);
+ }
+ }
+ }
+ }
+#endif /* LWIP_TCP */
+ TCPIP_APIMSG_ACK(msg);
+}
+
+#if LWIP_TCP
+/**
+ * See if more data needs to be written from a previous call to netconn_write.
+ * Called initially from do_write. If the first call can't send all data
+ * (because of low memory or empty send-buffer), this function is called again
+ * from sent_tcp() or poll_tcp() to send more data. If all data is sent, the
+ * blocking application thread (waiting in netconn_write) is released.
+ *
+ * @param conn netconn (that is currently in state NETCONN_WRITE) to process
+ * @return ERR_OK
+ * ERR_MEM if LWIP_TCPIP_CORE_LOCKING=1 and sending hasn't yet finished
+ */
+static err_t
+do_writemore(struct netconn *conn)
+{
+ err_t err;
+ void *dataptr;
+ u16_t len, available;
+ u8_t write_finished = 0;
+ size_t diff;
+
+ LWIP_ASSERT("conn->state == NETCONN_WRITE", (conn->state == NETCONN_WRITE));
+
+ dataptr = (u8_t*)conn->write_msg->msg.w.dataptr + conn->write_offset;
+ diff = conn->write_msg->msg.w.len - conn->write_offset;
+ if (diff > 0xffffUL) { /* max_u16_t */
+ len = 0xffff;
+#if LWIP_TCPIP_CORE_LOCKING
+ conn->write_delayed = 1;
+#endif
+ } else {
+ len = (u16_t)diff;
+ }
+ available = tcp_sndbuf(conn->pcb.tcp);
+ if (available < len) {
+ /* don't try to write more than sendbuf */
+ len = available;
+#if LWIP_TCPIP_CORE_LOCKING
+ conn->write_delayed = 1;
+#endif
+ }
+
+ err = tcp_write(conn->pcb.tcp, dataptr, len, conn->write_msg->msg.w.apiflags);
+ LWIP_ASSERT("do_writemore: invalid length!", ((conn->write_offset + len) <= conn->write_msg->msg.w.len));
+ if (err == ERR_OK) {
+ conn->write_offset += len;
+ if (conn->write_offset == conn->write_msg->msg.w.len) {
+ /* everything was written */
+ write_finished = 1;
+ conn->write_msg = NULL;
+ conn->write_offset = 0;
+ /* API_EVENT might call tcp_tmr, so reset conn->state now */
+ conn->state = NETCONN_NONE;
+ }
+ err = tcp_output_nagle(conn->pcb.tcp);
+ conn->err = err;
+ if ((err == ERR_OK) && (tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT)) {
+ API_EVENT(conn, NETCONN_EVT_SENDMINUS, len);
+ }
+ } else if (err == ERR_MEM) {
+ /* If ERR_MEM, we wait for sent_tcp or poll_tcp to be called
+ we do NOT return to the application thread, since ERR_MEM is
+ only a temporary error! */
+
+ /* tcp_enqueue returned ERR_MEM, try tcp_output anyway */
+ err = tcp_output(conn->pcb.tcp);
+
+#if LWIP_TCPIP_CORE_LOCKING
+ conn->write_delayed = 1;
+#endif
+ } else {
+ /* On errors != ERR_MEM, we don't try writing any more but return
+ the error to the application thread. */
+ conn->err = err;
+ write_finished = 1;
+ }
+
+ if (write_finished) {
+ /* everything was written: set back connection state
+ and back to application task */
+ conn->state = NETCONN_NONE;
+#if LWIP_TCPIP_CORE_LOCKING
+ if (conn->write_delayed != 0)
+#endif
+ {
+ sys_sem_signal(conn->op_completed);
+ }
+ }
+#if LWIP_TCPIP_CORE_LOCKING
+ else
+ return ERR_MEM;
+#endif
+ return ERR_OK;
+}
+#endif /* LWIP_TCP */
+
+/**
+ * Send some data on a TCP pcb contained in a netconn
+ * Called from netconn_write
+ *
+ * @param msg the api_msg_msg pointing to the connection
+ */
+void
+do_write(struct api_msg_msg *msg)
+{
+ if (!ERR_IS_FATAL(msg->conn->err)) {
+ if ((msg->conn->pcb.tcp != NULL) && (msg->conn->type == NETCONN_TCP)) {
+#if LWIP_TCP
+ msg->conn->state = NETCONN_WRITE;
+ /* set all the variables used by do_writemore */
+ LWIP_ASSERT("already writing", msg->conn->write_msg == NULL &&
+ msg->conn->write_offset == 0);
+ msg->conn->write_msg = msg;
+ msg->conn->write_offset = 0;
+#if LWIP_TCPIP_CORE_LOCKING
+ msg->conn->write_delayed = 0;
+ if (do_writemore(msg->conn) != ERR_OK) {
+ LWIP_ASSERT("state!", msg->conn->state == NETCONN_WRITE);
+ UNLOCK_TCPIP_CORE();
+ sys_arch_sem_wait(msg->conn->op_completed, 0);
+ LOCK_TCPIP_CORE();
+ LWIP_ASSERT("state!", msg->conn->state == NETCONN_NONE);
+ }
+#else
+ do_writemore(msg->conn);
+#endif
+ /* for both cases: if do_writemore was called, don't ACK the APIMSG! */
+ return;
+#endif /* LWIP_TCP */
+#if (LWIP_UDP || LWIP_RAW)
+ } else {
+ msg->conn->err = ERR_VAL;
+#endif /* (LWIP_UDP || LWIP_RAW) */
+ }
+ }
+ TCPIP_APIMSG_ACK(msg);
+}
+
+/**
+ * Return a connection's local or remote address
+ * Called from netconn_getaddr
+ *
+ * @param msg the api_msg_msg pointing to the connection
+ */
+void
+do_getaddr(struct api_msg_msg *msg)
+{
+ if (msg->conn->pcb.ip != NULL) {
+ *(msg->msg.ad.ipaddr) = (msg->msg.ad.local?msg->conn->pcb.ip->local_ip:msg->conn->pcb.ip->remote_ip);
+
+ switch (NETCONNTYPE_GROUP(msg->conn->type)) {
+#if LWIP_RAW
+ case NETCONN_RAW:
+ if (msg->msg.ad.local) {
+ *(msg->msg.ad.port) = msg->conn->pcb.raw->protocol;
+ } else {
+ /* return an error as connecting is only a helper for upper layers */
+ msg->conn->err = ERR_CONN;
+ }
+ break;
+#endif /* LWIP_RAW */
+#if LWIP_UDP
+ case NETCONN_UDP:
+ if (msg->msg.ad.local) {
+ *(msg->msg.ad.port) = msg->conn->pcb.udp->local_port;
+ } else {
+ if ((msg->conn->pcb.udp->flags & UDP_FLAGS_CONNECTED) == 0) {
+ msg->conn->err = ERR_CONN;
+ } else {
+ *(msg->msg.ad.port) = msg->conn->pcb.udp->remote_port;
+ }
+ }
+ break;
+#endif /* LWIP_UDP */
+#if LWIP_TCP
+ case NETCONN_TCP:
+ *(msg->msg.ad.port) = (msg->msg.ad.local?msg->conn->pcb.tcp->local_port:msg->conn->pcb.tcp->remote_port);
+ break;
+#endif /* LWIP_TCP */
+ }
+ } else {
+ msg->conn->err = ERR_CONN;
+ }
+ TCPIP_APIMSG_ACK(msg);
+}
+
+/**
+ * Close a TCP pcb contained in a netconn
+ * Called from netconn_close
+ *
+ * @param msg the api_msg_msg pointing to the connection
+ */
+void
+do_close(struct api_msg_msg *msg)
+{
+#if LWIP_TCP
+ if ((msg->conn->pcb.tcp != NULL) && (msg->conn->type == NETCONN_TCP)) {
+ msg->conn->state = NETCONN_CLOSE;
+ do_close_internal(msg->conn);
+ /* for tcp netconns, do_close_internal ACKs the message */
+ } else
+#endif /* LWIP_TCP */
+ {
+ msg->conn->err = ERR_VAL;
+ sys_sem_signal(msg->conn->op_completed);
+ }
+}
+
+#if LWIP_IGMP
+/**
+ * Join multicast groups for UDP netconns.
+ * Called from netconn_join_leave_group
+ *
+ * @param msg the api_msg_msg pointing to the connection
+ */
+void
+do_join_leave_group(struct api_msg_msg *msg)
+{
+ if (!ERR_IS_FATAL(msg->conn->err)) {
+ if (msg->conn->pcb.tcp != NULL) {
+ if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) {
+#if LWIP_UDP
+ if (msg->msg.jl.join_or_leave == NETCONN_JOIN) {
+ msg->conn->err = igmp_joingroup(msg->msg.jl.interface, msg->msg.jl.multiaddr);
+ } else {
+ msg->conn->err = igmp_leavegroup(msg->msg.jl.interface, msg->msg.jl.multiaddr);
+ }
+#endif /* LWIP_UDP */
+#if (LWIP_TCP || LWIP_RAW)
+ } else {
+ msg->conn->err = ERR_VAL;
+#endif /* (LWIP_TCP || LWIP_RAW) */
+ }
+ }
+ }
+ TCPIP_APIMSG_ACK(msg);
+}
+#endif /* LWIP_IGMP */
+
+#if LWIP_DNS
+/**
+ * Callback function that is called when DNS name is resolved
+ * (or on timeout). A waiting application thread is waked up by
+ * signaling the semaphore.
+ */
+static void
+do_dns_found(const char *name, struct ip_addr *ipaddr, void *arg)
+{
+ struct dns_api_msg *msg = (struct dns_api_msg*)arg;
+
+ LWIP_ASSERT("DNS response for wrong host name", strcmp(msg->name, name) == 0);
+
+ if (ipaddr == NULL) {
+ /* timeout or memory error */
+ *msg->err = ERR_VAL;
+ } else {
+ /* address was resolved */
+ *msg->err = ERR_OK;
+ *msg->addr = *ipaddr;
+ }
+ /* wake up the application task waiting in netconn_gethostbyname */
+ sys_sem_signal(msg->sem);
+}
+
+/**
+ * Execute a DNS query
+ * Called from netconn_gethostbyname
+ *
+ * @param arg the dns_api_msg pointing to the query
+ */
+void
+do_gethostbyname(void *arg)
+{
+ struct dns_api_msg *msg = (struct dns_api_msg*)arg;
+
+ *msg->err = dns_gethostbyname(msg->name, msg->addr, do_dns_found, msg);
+ if (*msg->err != ERR_INPROGRESS) {
+ /* on error or immediate success, wake up the application
+ * task waiting in netconn_gethostbyname */
+ sys_sem_signal(msg->sem);
+ }
+}
+#endif /* LWIP_DNS */
+
+#endif /* LWIP_NETCONN */
diff --git a/components/net/lwip-1.3.2/src/arch/include/arch/bpstruct.h b/components/net/lwip-1.3.2/src/arch/include/arch/bpstruct.h
index e490f4fa06..74ead358fa 100644
--- a/components/net/lwip-1.3.2/src/arch/include/arch/bpstruct.h
+++ b/components/net/lwip-1.3.2/src/arch/include/arch/bpstruct.h
@@ -1,35 +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 <[email protected]>
- *
- */
-
-#if defined(__ICCARM__)
-#pragma pack(1)
-#endif
+/*
+ * 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 <[email protected]>
+ *
+ */
+
+#if defined(__ICCARM__)
+#pragma pack(1)
+#endif
diff --git a/components/net/lwip-1.3.2/src/arch/include/arch/cc.h b/components/net/lwip-1.3.2/src/arch/include/arch/cc.h
index 04cddcf141..50cfd79083 100644
--- a/components/net/lwip-1.3.2/src/arch/include/arch/cc.h
+++ b/components/net/lwip-1.3.2/src/arch/include/arch/cc.h
@@ -90,11 +90,11 @@ typedef rt_uint32_t mem_ptr_t;
void sys_arch_assert(const char* file, int line);
#ifdef LWIP_DEBUG
-#define LWIP_PLATFORM_DIAG(x) do {rt_kprintf x;} while(0)
+#define LWIP_PLATFORM_DIAG(x) do {rt_kprintf x;} while(0)
#define LWIP_PLATFORM_ASSERT(x) { rt_kprintf(x); sys_arch_assert(__FILE__, __LINE__); }
-#else
-#define LWIP_PLATFORM_DIAG(x)
-#define LWIP_PLATFORM_ASSERT(x)
+#else
+#define LWIP_PLATFORM_DIAG(x)
+#define LWIP_PLATFORM_ASSERT(x)
#endif
#include "string.h"
diff --git a/components/net/lwip-1.3.2/src/arch/include/arch/cpu.h b/components/net/lwip-1.3.2/src/arch/include/arch/cpu.h
index c7891ab0a7..e2c6c60294 100644
--- a/components/net/lwip-1.3.2/src/arch/include/arch/cpu.h
+++ b/components/net/lwip-1.3.2/src/arch/include/arch/cpu.h
@@ -1,42 +1,42 @@
-/*
- * 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 <[email protected]>
- *
- * $Id: cpu.h,v 1.1.1.1 2004/12/16 14:17:14 bear Exp $
- */
-#ifndef __ARCH_CPU_H__
-#define __ARCH_CPU_H__
-
-#ifndef BYTE_ORDER
-#define BYTE_ORDER LITTLE_ENDIAN
-#endif /* BYTE_ORDER */
-
-#endif /* __ARCH_CPU_H__ */
+/*
+ * 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 <[email protected]>
+ *
+ * $Id: cpu.h,v 1.1.1.1 2004/12/16 14:17:14 bear Exp $
+ */
+#ifndef __ARCH_CPU_H__
+#define __ARCH_CPU_H__
+
+#ifndef BYTE_ORDER
+#define BYTE_ORDER LITTLE_ENDIAN
+#endif /* BYTE_ORDER */
+
+#endif /* __ARCH_CPU_H__ */
diff --git a/components/net/lwip-1.3.2/src/arch/include/arch/epstruct.h b/components/net/lwip-1.3.2/src/arch/include/arch/epstruct.h
index 448e6d4097..f6390959ea 100644
--- a/components/net/lwip-1.3.2/src/arch/include/arch/epstruct.h
+++ b/components/net/lwip-1.3.2/src/arch/include/arch/epstruct.h
@@ -1,35 +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 <[email protected]>
- *
- */
-
-#if defined(__ICCARM__)
-#pragma pack()
-#endif
+/*
+ * 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 <[email protected]>
+ *
+ */
+
+#if defined(__ICCARM__)
+#pragma pack()
+#endif
diff --git a/components/net/lwip-1.3.2/src/arch/include/arch/init.h b/components/net/lwip-1.3.2/src/arch/include/arch/init.h
index 708614d63d..7f1ad49977 100644
--- a/components/net/lwip-1.3.2/src/arch/include/arch/init.h
+++ b/components/net/lwip-1.3.2/src/arch/include/arch/init.h
@@ -1,44 +1,44 @@
-/*
- * 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 <[email protected]>
- *
- * $Id: init.h,v 1.1.1.1 2004/12/16 14:17:13 bear Exp $
- */
-#ifndef __ARCH_INIT_H__
-#define __ARCH_INIT_H__
-
-#define TCPIP_INIT_DONE(arg) sys_sem_signal(*(sys_sem_t *)arg)
-
-#endif /* __ARCH_INIT_H__ */
-
-
-
-
+/*
+ * 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 <[email protected]>
+ *
+ * $Id: init.h,v 1.1.1.1 2004/12/16 14:17:13 bear Exp $
+ */
+#ifndef __ARCH_INIT_H__
+#define __ARCH_INIT_H__
+
+#define TCPIP_INIT_DONE(arg) sys_sem_signal(*(sys_sem_t *)arg)
+
+#endif /* __ARCH_INIT_H__ */
+
+
+
+
diff --git a/components/net/lwip-1.3.2/src/arch/include/arch/lib.h b/components/net/lwip-1.3.2/src/arch/include/arch/lib.h
index 48ef182c95..35d4bba7f9 100644
--- a/components/net/lwip-1.3.2/src/arch/include/arch/lib.h
+++ b/components/net/lwip-1.3.2/src/arch/include/arch/lib.h
@@ -1,41 +1,41 @@
-/*
- * 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 <[email protected]>
- *
- * $Id: lib.h,v 1.1.1.1 2004/12/16 14:17:14 bear Exp $
- */
-#ifndef __ARCH_LIB_H__
-#define __ARCH_LIB_H__
-
-#define bcopy(s, d, l) rt_memcpy(s, d, l)
-#define bzero(d, n) rt_memset(d, 0, n)
-
-#endif /* __ARCH_LIB_H__ */
+/*
+ * 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 <[email protected]>
+ *
+ * $Id: lib.h,v 1.1.1.1 2004/12/16 14:17:14 bear Exp $
+ */
+#ifndef __ARCH_LIB_H__
+#define __ARCH_LIB_H__
+
+#define bcopy(s, d, l) rt_memcpy(s, d, l)
+#define bzero(d, n) rt_memset(d, 0, n)
+
+#endif /* __ARCH_LIB_H__ */
diff --git a/components/net/lwip-1.3.2/src/arch/include/arch/perf.h b/components/net/lwip-1.3.2/src/arch/include/arch/perf.h
index 0f7c1ef344..675f1f65dc 100644
--- a/components/net/lwip-1.3.2/src/arch/include/arch/perf.h
+++ b/components/net/lwip-1.3.2/src/arch/include/arch/perf.h
@@ -1,52 +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 <[email protected]>
- *
- * $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__ */
+/*
+ * 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 <[email protected]>
+ *
+ * $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__ */
diff --git a/components/net/lwip-1.3.2/src/arch/include/arch/sys_arch.h b/components/net/lwip-1.3.2/src/arch/include/arch/sys_arch.h
index c78340cee7..4bf6a762d9 100644
--- a/components/net/lwip-1.3.2/src/arch/include/arch/sys_arch.h
+++ b/components/net/lwip-1.3.2/src/arch/include/arch/sys_arch.h
@@ -1,57 +1,57 @@
-/*
- * 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 <[email protected]>
- *
- * $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/cpu.h"
-#include "arch/cc.h"
-
-#include <rtthread.h>
-
-#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"
-
-typedef rt_sem_t sys_sem_t;
-typedef rt_mailbox_t sys_mbox_t;
-typedef rt_thread_t sys_thread_t;
-
-#endif /* __ARCH_SYS_ARCH_H__ */
+/*
+ * 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 <[email protected]>
+ *
+ * $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/cpu.h"
+#include "arch/cc.h"
+
+#include <rtthread.h>
+
+#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"
+
+typedef rt_sem_t sys_sem_t;
+typedef rt_mailbox_t sys_mbox_t;
+typedef rt_thread_t sys_thread_t;
+
+#endif /* __ARCH_SYS_ARCH_H__ */
diff --git a/components/net/lwip-1.3.2/src/arch/include/arch/sys_arch_init.h b/components/net/lwip-1.3.2/src/arch/include/arch/sys_arch_init.h
index 163948e893..1a49d65c84 100644
--- a/components/net/lwip-1.3.2/src/arch/include/arch/sys_arch_init.h
+++ b/components/net/lwip-1.3.2/src/arch/include/arch/sys_arch_init.h
@@ -1,8 +1,8 @@
-#ifndef __LWIP_SYS_INIT_H__
-#define __LWIP_SYS_INIT_H__
-
-void lwip_sys_init(void);
-void lwip_system_init(void);
-
-#endif
-
+#ifndef __LWIP_SYS_INIT_H__
+#define __LWIP_SYS_INIT_H__
+
+void lwip_sys_init(void);
+void lwip_system_init(void);
+
+#endif
+
diff --git a/components/net/lwip-1.3.2/src/arch/sys_arch.c b/components/net/lwip-1.3.2/src/arch/sys_arch.c
index a03150f6d9..894c6fa4e3 100644
--- a/components/net/lwip-1.3.2/src/arch/sys_arch.c
+++ b/components/net/lwip-1.3.2/src/arch/sys_arch.c
@@ -1,233 +1,233 @@
-#include <rtthread.h>
-
-#include "lwip/debug.h"
-#include "lwip/sys.h"
-#include "lwip/opt.h"
-#include "lwip/stats.h"
-#include "arch/sys_arch.h"
-
-#include <string.h>
-
-#define LWIP_THREAD_MAGIC 0x1919
-#define LWIP_THREAD_NAME (rt_thread_self()->name)
-struct lwip_thread
-{
- rt_uint32_t magic;
- struct sys_timeouts timeouts;
-
- rt_thread_t tid;
-};
-
-void sys_init(void)
-{
- /* nothing to do in RT-Thread */
-
- return;
-}
-
-sys_sem_t sys_sem_new(u8_t count)
-{
- static unsigned short counter = 0;
- char tname[RT_NAME_MAX];
-
- rt_snprintf(tname, RT_NAME_MAX, "%s%d", SYS_LWIP_SEM_NAME, counter);
-
- LWIP_DEBUGF(SYS_DEBUG, ("%s, Create sem: %s \n", LWIP_THREAD_NAME, tname));
-
- counter++;
-
- return rt_sem_create(tname, count, RT_IPC_FLAG_FIFO);
-}
-
-void sys_sem_free(sys_sem_t sem)
-{
- LWIP_DEBUGF(SYS_DEBUG, ("%s, Delete sem: %s \n", LWIP_THREAD_NAME,
- sem->parent.parent.name));
-
- rt_sem_delete(sem);
-
- return;
-}
-
-void sys_sem_signal(sys_sem_t sem)
-{
- LWIP_DEBUGF(SYS_DEBUG, ("%s, Release signal: %s , %d\n", LWIP_THREAD_NAME,
- sem->parent.parent.name, sem->value));
-
- rt_sem_release(sem);
-
- return;
-}
-
-u32_t sys_arch_sem_wait(sys_sem_t sem, u32_t timeout)
-{
- rt_err_t ret;
- s32_t t;
- u32_t tick;
-
- /* get the begin tick */
- tick = rt_tick_get();
- LWIP_DEBUGF(SYS_DEBUG, ("%s, Wait sem: %s , %d\n", LWIP_THREAD_NAME,
- sem->parent.parent.name, sem->value));
-
- 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_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;
-}
-
-sys_mbox_t sys_mbox_new(int size)
-{
- static unsigned short counter = 0;
- char tname[RT_NAME_MAX];
-
- rt_snprintf(tname, RT_NAME_MAX, "%s%d", SYS_LWIP_MBOX_NAME, counter);
- LWIP_DEBUGF(SYS_DEBUG, ("%s, Create mbox: %s \n", LWIP_THREAD_NAME, tname));
-
- counter++;
-
- return rt_mb_create(tname, size, RT_IPC_FLAG_FIFO);
-}
-
-void sys_mbox_free(sys_mbox_t mbox)
-{
- LWIP_DEBUGF(SYS_DEBUG, ("%s, Delete mbox: %s\n", LWIP_THREAD_NAME,
- mbox->mb->parent.parent.name));
-
- rt_mb_delete(mbox);
-
- return;
-}
-
-void sys_mbox_post(sys_mbox_t mbox, void *msg)
-{
- LWIP_DEBUGF(SYS_DEBUG, ("%s, Post mail: %s ,0x%x\n", LWIP_THREAD_NAME,
- mbox->mb->parent.parent.name, (rt_uint32_t)msg));
-
- rt_mb_send_wait(mbox, (rt_uint32_t)msg, RT_WAITING_FOREVER);
-
- return;
-}
-
-err_t sys_mbox_trypost(sys_mbox_t mbox, void *msg)
-{
- LWIP_DEBUGF(SYS_DEBUG, ("%s, Try post mail: %s ,0x%x\n", LWIP_THREAD_NAME,
- mbox->mb->parent.parent.name, (rt_uint32_t)msg));
-
- if (rt_mb_send(mbox, (rt_uint32_t)msg) == RT_EOK) return ERR_OK;
-
- return ERR_MEM;
-}
-
-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;
-
- /* 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);
-
+#include <rtthread.h>
+
+#include "lwip/debug.h"
+#include "lwip/sys.h"
+#include "lwip/opt.h"
+#include "lwip/stats.h"
+#include "arch/sys_arch.h"
+
+#include <string.h>
+
+#define LWIP_THREAD_MAGIC 0x1919
+#define LWIP_THREAD_NAME (rt_thread_self()->name)
+struct lwip_thread
+{
+ rt_uint32_t magic;
+ struct sys_timeouts timeouts;
+
+ rt_thread_t tid;
+};
+
+void sys_init(void)
+{
+ /* nothing to do in RT-Thread */
+
+ return;
+}
+
+sys_sem_t sys_sem_new(u8_t count)
+{
+ static unsigned short counter = 0;
+ char tname[RT_NAME_MAX];
+
+ rt_snprintf(tname, RT_NAME_MAX, "%s%d", SYS_LWIP_SEM_NAME, counter);
+
+ LWIP_DEBUGF(SYS_DEBUG, ("%s, Create sem: %s \n", LWIP_THREAD_NAME, tname));
+
+ counter++;
+
+ return rt_sem_create(tname, count, RT_IPC_FLAG_FIFO);
+}
+
+void sys_sem_free(sys_sem_t sem)
+{
+ LWIP_DEBUGF(SYS_DEBUG, ("%s, Delete sem: %s \n", LWIP_THREAD_NAME,
+ sem->parent.parent.name));
+
+ rt_sem_delete(sem);
+
+ return;
+}
+
+void sys_sem_signal(sys_sem_t sem)
+{
+ LWIP_DEBUGF(SYS_DEBUG, ("%s, Release signal: %s , %d\n", LWIP_THREAD_NAME,
+ sem->parent.parent.name, sem->value));
+
+ rt_sem_release(sem);
+
+ return;
+}
+
+u32_t sys_arch_sem_wait(sys_sem_t sem, u32_t timeout)
+{
+ rt_err_t ret;
+ s32_t t;
+ u32_t tick;
+
+ /* get the begin tick */
+ tick = rt_tick_get();
+ LWIP_DEBUGF(SYS_DEBUG, ("%s, Wait sem: %s , %d\n", LWIP_THREAD_NAME,
+ sem->parent.parent.name, sem->value));
+
+ 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_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;
+}
+
+sys_mbox_t sys_mbox_new(int size)
+{
+ static unsigned short counter = 0;
+ char tname[RT_NAME_MAX];
+
+ rt_snprintf(tname, RT_NAME_MAX, "%s%d", SYS_LWIP_MBOX_NAME, counter);
+ LWIP_DEBUGF(SYS_DEBUG, ("%s, Create mbox: %s \n", LWIP_THREAD_NAME, tname));
+
+ counter++;
+
+ return rt_mb_create(tname, size, RT_IPC_FLAG_FIFO);
+}
+
+void sys_mbox_free(sys_mbox_t mbox)
+{
+ LWIP_DEBUGF(SYS_DEBUG, ("%s, Delete mbox: %s\n", LWIP_THREAD_NAME,
+ mbox->mb->parent.parent.name));
+
+ rt_mb_delete(mbox);
+
+ return;
+}
+
+void sys_mbox_post(sys_mbox_t mbox, void *msg)
+{
+ LWIP_DEBUGF(SYS_DEBUG, ("%s, Post mail: %s ,0x%x\n", LWIP_THREAD_NAME,
+ mbox->mb->parent.parent.name, (rt_uint32_t)msg));
+
+ rt_mb_send_wait(mbox, (rt_uint32_t)msg, RT_WAITING_FOREVER);
+
+ return;
+}
+
+err_t sys_mbox_trypost(sys_mbox_t mbox, void *msg)
+{
+ LWIP_DEBUGF(SYS_DEBUG, ("%s, Try post mail: %s ,0x%x\n", LWIP_THREAD_NAME,
+ mbox->mb->parent.parent.name, (rt_uint32_t)msg));
+
+ if (rt_mb_send(mbox, (rt_uint32_t)msg) == RT_EOK) return ERR_OK;
+
+ return ERR_MEM;
+}
+
+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;
+
+ /* 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);
- }
-
- LWIP_DEBUGF(SYS_DEBUG, ("%s, Fetch mail: %s , 0x%x\n", LWIP_THREAD_NAME,
- mbox->mb->parent.parent.name, *(rt_uint32_t **)msg));
-
- /* 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;
-}
-
-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;
-
- LWIP_DEBUGF(SYS_DEBUG, ("%s, Fetch mail: %s , 0x%x\n", LWIP_THREAD_NAME,
- mbox->mb->parent.parent.name, *(rt_uint32_t **)msg));
-
- return ret;
-}
-
-struct sys_timeouts *sys_arch_timeouts(void)
-{
- rt_thread_t self = rt_thread_self();
- struct lwip_thread* lwip_th = (struct lwip_thread*)self->user_data;
-
- if ((lwip_th != RT_NULL) && (lwip_th->magic == LWIP_THREAD_MAGIC))
- return &(lwip_th->timeouts);
-
- return RT_NULL;
-}
-
-sys_thread_t sys_thread_new(char *name, void (* thread)(void *arg), void *arg, int stacksize, int prio)
-{
- rt_thread_t t;
- struct lwip_thread* lwip_th;
-
- /* create lwip thread */
- lwip_th = (struct lwip_thread*) rt_malloc (sizeof(struct lwip_thread));
- RT_ASSERT(lwip_th != RT_NULL);
-
- /* create thread */
- t = rt_thread_create(name, thread, arg, stacksize, prio, 20);
- RT_ASSERT(t != RT_NULL);
- t->user_data = (rt_uint32_t)lwip_th;
-
- /* init lwip_thread */
- lwip_th->magic = LWIP_THREAD_MAGIC;
- lwip_th->timeouts.next = RT_NULL;
- lwip_th->tid = t;
-
- /* startup thread */
- rt_thread_startup(t);
-
- return t;
-}
-
+ {
+ LWIP_ASSERT("rt_mb_recv returned with error!", ret == RT_EOK);
+ }
+
+ LWIP_DEBUGF(SYS_DEBUG, ("%s, Fetch mail: %s , 0x%x\n", LWIP_THREAD_NAME,
+ mbox->mb->parent.parent.name, *(rt_uint32_t **)msg));
+
+ /* 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;
+}
+
+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;
+
+ LWIP_DEBUGF(SYS_DEBUG, ("%s, Fetch mail: %s , 0x%x\n", LWIP_THREAD_NAME,
+ mbox->mb->parent.parent.name, *(rt_uint32_t **)msg));
+
+ return ret;
+}
+
+struct sys_timeouts *sys_arch_timeouts(void)
+{
+ rt_thread_t self = rt_thread_self();
+ struct lwip_thread* lwip_th = (struct lwip_thread*)self->user_data;
+
+ if ((lwip_th != RT_NULL) && (lwip_th->magic == LWIP_THREAD_MAGIC))
+ return &(lwip_th->timeouts);
+
+ return RT_NULL;
+}
+
+sys_thread_t sys_thread_new(char *name, void (* thread)(void *arg), void *arg, int stacksize, int prio)
+{
+ rt_thread_t t;
+ struct lwip_thread* lwip_th;
+
+ /* create lwip thread */
+ lwip_th = (struct lwip_thread*) rt_malloc (sizeof(struct lwip_thread));
+ RT_ASSERT(lwip_th != RT_NULL);
+
+ /* create thread */
+ t = rt_thread_create(name, thread, arg, stacksize, prio, 20);
+ RT_ASSERT(t != RT_NULL);
+ t->user_data = (rt_uint32_t)lwip_th;
+
+ /* init lwip_thread */
+ lwip_th->magic = LWIP_THREAD_MAGIC;
+ lwip_th->timeouts.next = RT_NULL;
+ lwip_th->tid = t;
+
+ /* startup thread */
+ rt_thread_startup(t);
+
+ return t;
+}
+
sys_prot_t sys_arch_protect(void)
{
rt_base_t level;
@@ -236,7 +236,7 @@ sys_prot_t sys_arch_protect(void)
level = rt_hw_interrupt_disable();
/* must also lock scheduler */
- rt_enter_critical();
+ rt_enter_critical();
return level;
}
@@ -244,16 +244,16 @@ sys_prot_t sys_arch_protect(void)
void sys_arch_unprotect(sys_prot_t pval)
{
/* unlock scheduler */
- rt_exit_critical();
+ rt_exit_critical();
/* 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);
-}
+}
+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);
+}
diff --git a/components/net/lwip-1.3.2/src/core/memp.c b/components/net/lwip-1.3.2/src/core/memp.c
index 9b907e284d..a7506a810e 100644
--- a/components/net/lwip-1.3.2/src/core/memp.c
+++ b/components/net/lwip-1.3.2/src/core/memp.c
@@ -125,7 +125,7 @@ const u16_t memp_sizes[MEMP_MAX] = {
#define LWIP_MEMPOOL(name,num,size,desc) LWIP_MEM_ALIGN_SIZE(size),
#include "lwip/memp_std.h"
};
-
+
/** This array holds a textual description of each pool. */
#ifdef LWIP_DEBUG
static const char *memp_desc[MEMP_MAX] = {
@@ -289,11 +289,11 @@ memp_init(void)
/* check everything a first time to see if it worked */
memp_overflow_check_all();
#endif /* MEMP_OVERFLOW_CHECK */
-}
-#else
-/* fix time-wait tcp pcb issue */
+}
+#else
+/* fix time-wait tcp pcb issue */
static rt_uint16_t tcp_pcbs = 0;
-#endif /* MEMP_MEM_MALLOC */
+#endif /* MEMP_MEM_MALLOC */
/**
* Get an element from a specific pool.
@@ -312,7 +312,7 @@ memp_malloc(memp_t type)
#else
memp_malloc_fn(memp_t type, const char* file, const int line)
#endif
-{
+{
#if !MEMP_MEM_MALLOC
struct memp *memp;
SYS_ARCH_DECL_PROTECT(old_level);
@@ -344,34 +344,34 @@ memp_malloc_fn(memp_t type, const char* file, const int line)
SYS_ARCH_UNPROTECT(old_level);
return memp;
-#else
- void* ptr;
- rt_uint32_t size;
- SYS_ARCH_DECL_PROTECT(old_level);
+#else
+ void* ptr;
+ rt_uint32_t size;
+ SYS_ARCH_DECL_PROTECT(old_level);
+
+ size = memp_sizes[type];
+ LWIP_DEBUGF(MEMP_DEBUG, ("memp malloc %s, size %d, ", memp_desc[type], memp_sizes[type]));
- size = memp_sizes[type];
- LWIP_DEBUGF(MEMP_DEBUG, ("memp malloc %s, size %d, ", memp_desc[type], memp_sizes[type]));
-
SYS_ARCH_PROTECT(old_level);
- if (type == MEMP_TCP_PCB)
- {
- if (tcp_pcbs >= MEMP_NUM_TCP_PCB)
- {
+ if (type == MEMP_TCP_PCB)
+ {
+ if (tcp_pcbs >= MEMP_NUM_TCP_PCB)
+ {
SYS_ARCH_UNPROTECT(old_level);
- return NULL;
- }
- else
- {
- /* increased tcp pcb allocated number */
- tcp_pcbs ++;
- }
- }
- SYS_ARCH_UNPROTECT(old_level);
+ return NULL;
+ }
+ else
+ {
+ /* increased tcp pcb allocated number */
+ tcp_pcbs ++;
+ }
+ }
+ SYS_ARCH_UNPROTECT(old_level);
- ptr = mem_malloc(size);
- LWIP_DEBUGF(MEMP_DEBUG, ("mem 0x%x\n", ptr));
-
- return ptr;
+ ptr = mem_malloc(size);
+ LWIP_DEBUGF(MEMP_DEBUG, ("mem 0x%x\n", ptr));
+
+ return ptr;
#endif /* MEMP_MEM_MALLOC */
}
@@ -415,19 +415,19 @@ memp_free(memp_t type, void *mem)
#endif /* MEMP_SANITY_CHECK */
SYS_ARCH_UNPROTECT(old_level);
-#else
- SYS_ARCH_DECL_PROTECT(old_level);
+#else
+ SYS_ARCH_DECL_PROTECT(old_level);
SYS_ARCH_PROTECT(old_level);
- if (type == MEMP_TCP_PCB && mem)
- {
- tcp_pcbs --;
- }
- SYS_ARCH_UNPROTECT(old_level);
+ if (type == MEMP_TCP_PCB && mem)
+ {
+ tcp_pcbs --;
+ }
+ SYS_ARCH_UNPROTECT(old_level);
- LWIP_DEBUGF(MEMP_DEBUG, ("memp free %s, mem 0x%x\n", memp_desc[type], mem));
- /* release this memory */
- mem_free(mem);
+ LWIP_DEBUGF(MEMP_DEBUG, ("memp free %s, mem 0x%x\n", memp_desc[type], mem));
+ /* release this memory */
+ mem_free(mem);
#endif /* MEMP_MEM_MALLOC */
-}
+}
diff --git a/components/net/lwip-1.3.2/src/include/netif/ethernetif.h b/components/net/lwip-1.3.2/src/include/netif/ethernetif.h
index 87b38497d8..187a941efb 100644
--- a/components/net/lwip-1.3.2/src/include/netif/ethernetif.h
+++ b/components/net/lwip-1.3.2/src/include/netif/ethernetif.h
@@ -1,35 +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;
-
- struct eth_addr *ethaddr;
- struct netif *netif;
- struct rt_semaphore tx_ack;
-
- rt_uint16_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_rx_ready(struct eth_device* dev);
-rt_err_t eth_device_ready(struct eth_device* dev);
-rt_err_t eth_device_linkchange(struct eth_device* dev, rt_bool_t up);
-
-rt_err_t eth_device_init(struct eth_device* dev, const char* name);
-
-rt_err_t eth_system_device_init(void);
-
-#endif /* __NETIF_ETHERNETIF_H__ */
+#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;
+
+ struct eth_addr *ethaddr;
+ struct netif *netif;
+ struct rt_semaphore tx_ack;
+
+ rt_uint16_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_rx_ready(struct eth_device* dev);
+rt_err_t eth_device_ready(struct eth_device* dev);
+rt_err_t eth_device_linkchange(struct eth_device* dev, rt_bool_t up);
+
+rt_err_t eth_device_init(struct eth_device* dev, const char* name);
+
+rt_err_t eth_system_device_init(void);
+
+#endif /* __NETIF_ETHERNETIF_H__ */
diff --git a/components/net/lwip-1.3.2/src/lwipopts.h b/components/net/lwip-1.3.2/src/lwipopts.h
index 4dc278e29a..98ee6b58f7 100644
--- a/components/net/lwip-1.3.2/src/lwipopts.h
+++ b/components/net/lwip-1.3.2/src/lwipopts.h
@@ -122,11 +122,11 @@
#endif
/* the number of simultaneously queued TCP */
-#ifdef RT_LWIP_TCP_SEG_NUM
-#define MEMP_NUM_TCP_SEG RT_LWIP_TCP_SEG_NUM
-#else
-#define MEMP_NUM_TCP_SEG TCP_SND_QUEUELEN
-#endif
+#ifdef RT_LWIP_TCP_SEG_NUM
+#define MEMP_NUM_TCP_SEG RT_LWIP_TCP_SEG_NUM
+#else
+#define MEMP_NUM_TCP_SEG TCP_SND_QUEUELEN
+#endif
/* MEMP_NUM_SYS_TIMEOUT: the number of simultaneously active
timeouts. */
diff --git a/components/net/lwip-1.3.2/src/netif/ethernetif.c b/components/net/lwip-1.3.2/src/netif/ethernetif.c
index 6e9c2c55aa..9ca59a377c 100644
--- a/components/net/lwip-1.3.2/src/netif/ethernetif.c
+++ b/components/net/lwip-1.3.2/src/netif/ethernetif.c
@@ -1,449 +1,449 @@
-/*
- * 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-12-11 aozima list_if and set_if support multiple interface.
- */
-
-/*
- * Copyright (c) 2001-2004 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 <[email protected]>
- *
- */
-
-#include <rtthread.h>
-
-#include "lwip/debug.h"
-#include "lwip/opt.h"
-#include "lwip/def.h"
-#include "lwip/mem.h"
-#include "lwip/pbuf.h"
-#include "lwip/sys.h"
-#include "lwip/netif.h"
-#include "lwip/stats.h"
-#include "lwip/tcpip.h"
-
-#include "netif/etharp.h"
-#include "netif/ethernetif.h"
-
-/* eth rx/tx thread */
-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
-
-struct eth_tx_msg
-{
- struct netif *netif;
- struct pbuf *buf;
-};
-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
-
-err_t ethernetif_linkoutput(struct netif *netif, struct pbuf *p)
-{
- 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);
- }
-
- return ERR_OK;
-}
-
-/* ethernetif APIs */
-rt_err_t eth_device_init(struct eth_device* dev, const char* name)
-{
- struct netif* netif;
-
- 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;
- /* register to rt-thread device manager */
- rt_device_register(&(dev->parent), name, RT_DEVICE_FLAG_RDWR);
- dev->parent.type = RT_Device_Class_NetIf;
- 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;
- /* broadcast capability */
- netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
-
-#if LWIP_IGMP
- /* igmp support */
- netif->flags |= NETIF_FLAG_IGMP;
-#endif
-
- /* get hardware address */
- rt_device_control(&(dev->parent), NIOCTL_GADDR, netif->hwaddr);
-
- /* set output */
- netif->output = etharp_output;
- netif->linkoutput = ethernetif_linkoutput;
-
- return RT_EOK;
-}
-
-/* ethernet buffer */
-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));
- }
- }
-}
-
-/* ethernet buffer */
-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;
- }
- }
- }
-}
-
-rt_err_t eth_rx_ready(struct eth_device* dev)
-{
- /* post message to ethernet thread */
- return rt_mb_send(&eth_rx_thread_mb, (rt_uint32_t)dev);
-}
-
-rt_err_t eth_device_ready(struct eth_device* dev)
-{
- return eth_rx_ready(dev);
-}
-
-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);
-}
-
-rt_err_t eth_system_device_init()
-{
- rt_err_t result = RT_EOK;
-
- /* init rx thread */
- /* init mailbox and create ethernet 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_ETHERNETIF_THREAD_PREORITY, 16);
- RT_ASSERT(result == RT_EOK);
-
- result = rt_thread_startup(&eth_rx_thread);
- RT_ASSERT(result == RT_EOK);
-
- /* init tx thread */
- /* init mailbox and create ethernet 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);
-
- return result;
-}
-
-#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 in_addr addr;
- struct netif * netif = netif_list;
-
- if(strlen(netif_name) > sizeof(netif->name))
- {
- rt_kprintf("network interface name too long!\r\n");
- return;
- }
-
- 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) && inet_aton(ip_addr, &addr))
- {
- netif_set_ipaddr(netif, ip);
- }
-
- /* set gateway address */
- if ((gw_addr != RT_NULL) && inet_aton(gw_addr, &addr))
- {
- netif_set_gw(netif, ip);
- }
-
- /* set netmask address */
- if ((nm_addr != RT_NULL) && inet_aton(nm_addr, &addr))
- {
- netif_set_netmask(netif, ip);
- }
-}
-FINSH_FUNCTION_EXPORT(set_if, set network interface address);
-
-#if LWIP_DNS
-#include <lwip/dns.h>
-void set_dns(char* dns_server)
-{
- struct in_addr addr;
-
- if ((dns_server != RT_NULL) && inet_aton(dns_server, &addr))
- {
- dns_setserver(0, (struct ip_addr *)&addr);
- }
-}
-FINSH_FUNCTION_EXPORT(set_dns, set DNS server address);
-#endif
-
-void list_if(void)
-{
- rt_ubase_t index;
- struct netif * netif;
-
- 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", inet_ntoa(*((struct in_addr*)&(netif->ip_addr))));
- rt_kprintf("gw address: %s\n", inet_ntoa(*((struct in_addr*)&(netif->gw))));
- rt_kprintf("net mask : %s\n", inet_ntoa(*((struct in_addr*)&(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, inet_ntoa(*((struct in_addr*)&(ip_addr))));
- }
- }
-#endif /**< #if LWIP_DNS */
-}
-FINSH_FUNCTION_EXPORT(list_if, list network interface information);
-
-#include <lwip/tcp.h>
-void list_tcps()
-{
- struct tcp_pcb *pcb;
- 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)
- {
- rt_kprintf("%s:%d <==> %s:%d snd_nxt %d rcv_nxt %d ",
- inet_ntoa(*((struct in_addr*)&(pcb->local_ip))), pcb->local_port,
- inet_ntoa(*((struct in_addr*)&(pcb->remote_ip))), 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");
- for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next)
- {
- rt_kprintf("local port %d ", pcb->local_port);
- rt_kprintf("state: %s\n", tcp_state_str[pcb->state]);
- }
-
- rt_kprintf("TIME-WAIT PCB states:\n");
- for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next)
- {
- rt_kprintf("%s:%d <==> %s:%d snd_nxt %d rcv_nxt %d ",
- inet_ntoa(*((struct in_addr*)&(pcb->local_ip))), pcb->local_port,
- inet_ntoa(*((struct in_addr*)&(pcb->remote_ip))), 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 pcb);
-
-#endif
+/*
+ * 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-12-11 aozima list_if and set_if support multiple interface.
+ */
+
+/*
+ * Copyright (c) 2001-2004 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 <[email protected]>
+ *
+ */
+
+#include <rtthread.h>
+
+#include "lwip/debug.h"
+#include "lwip/opt.h"
+#include "lwip/def.h"
+#include "lwip/mem.h"
+#include "lwip/pbuf.h"
+#include "lwip/sys.h"
+#include "lwip/netif.h"
+#include "lwip/stats.h"
+#include "lwip/tcpip.h"
+
+#include "netif/etharp.h"
+#include "netif/ethernetif.h"
+
+/* eth rx/tx thread */
+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
+
+struct eth_tx_msg
+{
+ struct netif *netif;
+ struct pbuf *buf;
+};
+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
+
+err_t ethernetif_linkoutput(struct netif *netif, struct pbuf *p)
+{
+ 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);
+ }
+
+ return ERR_OK;
+}
+
+/* ethernetif APIs */
+rt_err_t eth_device_init(struct eth_device* dev, const char* name)
+{
+ struct netif* netif;
+
+ 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;
+ /* register to rt-thread device manager */
+ rt_device_register(&(dev->parent), name, RT_DEVICE_FLAG_RDWR);
+ dev->parent.type = RT_Device_Class_NetIf;
+ 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;
+ /* broadcast capability */
+ netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
+
+#if LWIP_IGMP
+ /* igmp support */
+ netif->flags |= NETIF_FLAG_IGMP;
+#endif
+
+ /* get hardware address */
+ rt_device_control(&(dev->parent), NIOCTL_GADDR, netif->hwaddr);
+
+ /* set output */
+ netif->output = etharp_output;
+ netif->linkoutput = ethernetif_linkoutput;
+
+ return RT_EOK;
+}
+
+/* ethernet buffer */
+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));
+ }
+ }
+}
+
+/* ethernet buffer */
+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;
+ }
+ }
+ }
+}
+
+rt_err_t eth_rx_ready(struct eth_device* dev)
+{
+ /* post message to ethernet thread */
+ return rt_mb_send(&eth_rx_thread_mb, (rt_uint32_t)dev);
+}
+
+rt_err_t eth_device_ready(struct eth_device* dev)
+{
+ return eth_rx_ready(dev);
+}
+
+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);
+}
+
+rt_err_t eth_system_device_init()
+{
+ rt_err_t result = RT_EOK;
+
+ /* init rx thread */
+ /* init mailbox and create ethernet 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_ETHERNETIF_THREAD_PREORITY, 16);
+ RT_ASSERT(result == RT_EOK);
+
+ result = rt_thread_startup(&eth_rx_thread);
+ RT_ASSERT(result == RT_EOK);
+
+ /* init tx thread */
+ /* init mailbox and create ethernet 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);
+
+ return result;
+}
+
+#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 in_addr addr;
+ struct netif * netif = netif_list;
+
+ if(strlen(netif_name) > sizeof(netif->name))
+ {
+ rt_kprintf("network interface name too long!\r\n");
+ return;
+ }
+
+ 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) && inet_aton(ip_addr, &addr))
+ {
+ netif_set_ipaddr(netif, ip);
+ }
+
+ /* set gateway address */
+ if ((gw_addr != RT_NULL) && inet_aton(gw_addr, &addr))
+ {
+ netif_set_gw(netif, ip);
+ }
+
+ /* set netmask address */
+ if ((nm_addr != RT_NULL) && inet_aton(nm_addr, &addr))
+ {
+ netif_set_netmask(netif, ip);
+ }
+}
+FINSH_FUNCTION_EXPORT(set_if, set network interface address);
+
+#if LWIP_DNS
+#include <lwip/dns.h>
+void set_dns(char* dns_server)
+{
+ struct in_addr addr;
+
+ if ((dns_server != RT_NULL) && inet_aton(dns_server, &addr))
+ {
+ dns_setserver(0, (struct ip_addr *)&addr);
+ }
+}
+FINSH_FUNCTION_EXPORT(set_dns, set DNS server address);
+#endif
+
+void list_if(void)
+{
+ rt_ubase_t index;
+ struct netif * netif;
+
+ 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", inet_ntoa(*((struct in_addr*)&(netif->ip_addr))));
+ rt_kprintf("gw address: %s\n", inet_ntoa(*((struct in_addr*)&(netif->gw))));
+ rt_kprintf("net mask : %s\n", inet_ntoa(*((struct in_addr*)&(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, inet_ntoa(*((struct in_addr*)&(ip_addr))));
+ }
+ }
+#endif /**< #if LWIP_DNS */
+}
+FINSH_FUNCTION_EXPORT(list_if, list network interface information);
+
+#include <lwip/tcp.h>
+void list_tcps()
+{
+ struct tcp_pcb *pcb;
+ 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)
+ {
+ rt_kprintf("%s:%d <==> %s:%d snd_nxt %d rcv_nxt %d ",
+ inet_ntoa(*((struct in_addr*)&(pcb->local_ip))), pcb->local_port,
+ inet_ntoa(*((struct in_addr*)&(pcb->remote_ip))), 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");
+ for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next)
+ {
+ rt_kprintf("local port %d ", pcb->local_port);
+ rt_kprintf("state: %s\n", tcp_state_str[pcb->state]);
+ }
+
+ rt_kprintf("TIME-WAIT PCB states:\n");
+ for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next)
+ {
+ rt_kprintf("%s:%d <==> %s:%d snd_nxt %d rcv_nxt %d ",
+ inet_ntoa(*((struct in_addr*)&(pcb->local_ip))), pcb->local_port,
+ inet_ntoa(*((struct in_addr*)&(pcb->remote_ip))), 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 pcb);
+
+#endif
diff --git a/components/net/lwip/src/arch/include/arch/bpstruct.h b/components/net/lwip/src/arch/include/arch/bpstruct.h
index e490f4fa06..74ead358fa 100644
--- a/components/net/lwip/src/arch/include/arch/bpstruct.h
+++ b/components/net/lwip/src/arch/include/arch/bpstruct.h
@@ -1,35 +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 <[email protected]>
- *
- */
-
-#if defined(__ICCARM__)
-#pragma pack(1)
-#endif
+/*
+ * 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 <[email protected]>
+ *
+ */
+
+#if defined(__ICCARM__)
+#pragma pack(1)
+#endif
diff --git a/components/net/lwip/src/arch/include/arch/epstruct.h b/components/net/lwip/src/arch/include/arch/epstruct.h
index 448e6d4097..f6390959ea 100644
--- a/components/net/lwip/src/arch/include/arch/epstruct.h
+++ b/components/net/lwip/src/arch/include/arch/epstruct.h
@@ -1,35 +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 <[email protected]>
- *
- */
-
-#if defined(__ICCARM__)
-#pragma pack()
-#endif
+/*
+ * 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 <[email protected]>
+ *
+ */
+
+#if defined(__ICCARM__)
+#pragma pack()
+#endif
diff --git a/components/net/uip/apps/hello-world/hello-world.c b/components/net/uip/apps/hello-world/hello-world.c
index 508326bd49..b7f329e745 100644
--- a/components/net/uip/apps/hello-world/hello-world.c
+++ b/components/net/uip/apps/hello-world/hello-world.c
@@ -1,115 +1,115 @@
-/**
- * \addtogroup helloworld
- * @{
- */
-
-/**
- * \file
- * An example of how to write uIP applications
- * with protosockets.
- * \author
- * Adam Dunkels <[email protected]>
- */
-
-/*
- * This is a short example of how to write uIP applications using
- * protosockets.
- */
-
-/*
- * We define the application state (struct hello_world_state) in the
- * hello-world.h file, so we need to include it here. We also include
- * uip.h (since this cannot be included in hello-world.h) and
- * <string.h>, since we use the memcpy() function in the code.
- */
-#include "hello-world.h"
-#include "uip.h"
-#include <string.h>
-
-/*
- * Declaration of the protosocket function that handles the connection
- * (defined at the end of the code).
- */
-static int handle_connection(struct hello_world_state *s);
-static int rt_show_info(struct hello_world_state *s);
-/*---------------------------------------------------------------------------*/
-/*
- * The initialization function. We must explicitly call this function
- * from the system initialization code, some time after uip_init() is
- * called.
- */
-void
-hello_world_init(void)
-{
- /* We start to listen for connections on TCP port 1000. */
- uip_listen(HTONS(1000));
-}
-/*---------------------------------------------------------------------------*/
-/*
- * In hello-world.h we have defined the UIP_APPCALL macro to
- * hello_world_appcall so that this funcion is uIP's application
- * function. This function is called whenever an uIP event occurs
- * (e.g. when a new connection is established, new data arrives, sent
- * data is acknowledged, data needs to be retransmitted, etc.).
- */
-void
-hello_world_appcall(void)
-{
- /*
- * The uip_conn structure has a field called "appstate" that holds
- * the application state of the connection. We make a pointer to
- * this to access it easier.
- */
- struct hello_world_state *s = &(uip_conn->appstate);
-
- /*
- * If a new connection was just established, we should initialize
- * the protosocket in our applications' state structure.
- */
- if(uip_connected()) {
- PSOCK_INIT(&s->p, s->inputbuffer, sizeof(s->inputbuffer));
- rt_show_info(s);
- }
-
- /*
- * Finally, we run the protosocket function that actually handles
- * the communication. We pass it a pointer to the application state
- * of the current connection.
- */
- handle_connection(s);
-}
-/*---------------------------------------------------------------------------*/
-/*
- * This is the protosocket function that handles the communication. A
- * protosocket function must always return an int, but must never
- * explicitly return - all return statements are hidden in the PSOCK
- * macros.
- */
-static int rt_show_info(struct hello_world_state *s)
-{
- PSOCK_BEGIN(&s->p);
- PSOCK_SEND_STR(&s->p,"RT-Thread RTOS");
- PSOCK_READTO(&s->p, '\n');
- PSOCK_END(&s->p);
-
-}
-static int
-handle_connection(struct hello_world_state *s)
-{
- int i;
- for (i=0;i<BUF_SIZE;i++)
- {
- s->name[i] = 0;
- s->inputbuffer[i] = 0;
- }
- PSOCK_BEGIN(&s->p);
- //PSOCK_SEND_STR(&s->p, "Hello. What is your name?\n");
- PSOCK_READTO(&s->p, '\n');
- strncpy(s->name, s->inputbuffer, sizeof(s->name));
- //PSOCK_SEND_STR(&s->p, "Hello ");
- PSOCK_SEND_STR(&s->p, s->name);
- //PSOCK_CLOSE(&s->p);
-
- PSOCK_END(&s->p);
-}
-/*---------------------------------------------------------------------------*/
+/**
+ * \addtogroup helloworld
+ * @{
+ */
+
+/**
+ * \file
+ * An example of how to write uIP applications
+ * with protosockets.
+ * \author
+ * Adam Dunkels <[email protected]>
+ */
+
+/*
+ * This is a short example of how to write uIP applications using
+ * protosockets.
+ */
+
+/*
+ * We define the application state (struct hello_world_state) in the
+ * hello-world.h file, so we need to include it here. We also include
+ * uip.h (since this cannot be included in hello-world.h) and
+ * <string.h>, since we use the memcpy() function in the code.
+ */
+#include "hello-world.h"
+#include "uip.h"
+#include <string.h>
+
+/*
+ * Declaration of the protosocket function that handles the connection
+ * (defined at the end of the code).
+ */
+static int handle_connection(struct hello_world_state *s);
+static int rt_show_info(struct hello_world_state *s);
+/*---------------------------------------------------------------------------*/
+/*
+ * The initialization function. We must explicitly call this function
+ * from the system initialization code, some time after uip_init() is
+ * called.
+ */
+void
+hello_world_init(void)
+{
+ /* We start to listen for connections on TCP port 1000. */
+ uip_listen(HTONS(1000));
+}
+/*---------------------------------------------------------------------------*/
+/*
+ * In hello-world.h we have defined the UIP_APPCALL macro to
+ * hello_world_appcall so that this funcion is uIP's application
+ * function. This function is called whenever an uIP event occurs
+ * (e.g. when a new connection is established, new data arrives, sent
+ * data is acknowledged, data needs to be retransmitted, etc.).
+ */
+void
+hello_world_appcall(void)
+{
+ /*
+ * The uip_conn structure has a field called "appstate" that holds
+ * the application state of the connection. We make a pointer to
+ * this to access it easier.
+ */
+ struct hello_world_state *s = &(uip_conn->appstate);
+
+ /*
+ * If a new connection was just established, we should initialize
+ * the protosocket in our applications' state structure.
+ */
+ if(uip_connected()) {
+ PSOCK_INIT(&s->p, s->inputbuffer, sizeof(s->inputbuffer));
+ rt_show_info(s);
+ }
+
+ /*
+ * Finally, we run the protosocket function that actually handles
+ * the communication. We pass it a pointer to the application state
+ * of the current connection.
+ */
+ handle_connection(s);
+}
+/*---------------------------------------------------------------------------*/
+/*
+ * This is the protosocket function that handles the communication. A
+ * protosocket function must always return an int, but must never
+ * explicitly return - all return statements are hidden in the PSOCK
+ * macros.
+ */
+static int rt_show_info(struct hello_world_state *s)
+{
+ PSOCK_BEGIN(&s->p);
+ PSOCK_SEND_STR(&s->p,"RT-Thread RTOS");
+ PSOCK_READTO(&s->p, '\n');
+ PSOCK_END(&s->p);
+
+}
+static int
+handle_connection(struct hello_world_state *s)
+{
+ int i;
+ for (i=0;i<BUF_SIZE;i++)
+ {
+ s->name[i] = 0;
+ s->inputbuffer[i] = 0;
+ }
+ PSOCK_BEGIN(&s->p);
+ //PSOCK_SEND_STR(&s->p, "Hello. What is your name?\n");
+ PSOCK_READTO(&s->p, '\n');
+ strncpy(s->name, s->inputbuffer, sizeof(s->name));
+ //PSOCK_SEND_STR(&s->p, "Hello ");
+ PSOCK_SEND_STR(&s->p, s->name);
+ //PSOCK_CLOSE(&s->p);
+
+ PSOCK_END(&s->p);
+}
+/*---------------------------------------------------------------------------*/
diff --git a/components/net/uip/apps/hello-world/hello-world.h b/components/net/uip/apps/hello-world/hello-world.h
index 102410a9b7..4f2e6d93e9 100644
--- a/components/net/uip/apps/hello-world/hello-world.h
+++ b/components/net/uip/apps/hello-world/hello-world.h
@@ -1,53 +1,53 @@
-/**
- * \addtogroup apps
- * @{
- */
-
-/**
- * \defgroup helloworld Hello, world
- * @{
- *
- * A small example showing how to write applications with
- * \ref psock "protosockets".
- */
-
-/**
- * \file
- * Header file for an example of how to write uIP applications
- * with protosockets.
- * \author
- * Adam Dunkels <[email protected]>
- */
-
-#ifndef __HELLO_WORLD_H__
-#define __HELLO_WORLD_H__
-
-/* Since this file will be included by uip.h, we cannot include uip.h
- here. But we might need to include uipopt.h if we need the u8_t and
- u16_t datatypes. */
-#include "uipopt.h"
-
-#include "psock.h"
-
-/* Next, we define the uip_tcp_appstate_t datatype. This is the state
- of our application, and the memory required for this state is
- allocated together with each TCP connection. One application state
- for each TCP connection. */
-#define BUF_SIZE 200
-typedef struct hello_world_state {
- struct psock p;
- char inputbuffer[BUF_SIZE];
- char name[BUF_SIZE];
-} uip_tcp_appstate_t;
-
-/* Finally we define the application function to be called by uIP. */
-void hello_world_appcall(void);
-#ifndef UIP_APPCALL
-#define UIP_APPCALL hello_world_appcall
-#endif /* UIP_APPCALL */
-
-void hello_world_init(void);
-
-#endif /* __HELLO_WORLD_H__ */
-/** @} */
-/** @} */
+/**
+ * \addtogroup apps
+ * @{
+ */
+
+/**
+ * \defgroup helloworld Hello, world
+ * @{
+ *
+ * A small example showing how to write applications with
+ * \ref psock "protosockets".
+ */
+
+/**
+ * \file
+ * Header file for an example of how to write uIP applications
+ * with protosockets.
+ * \author
+ * Adam Dunkels <[email protected]>
+ */
+
+#ifndef __HELLO_WORLD_H__
+#define __HELLO_WORLD_H__
+
+/* Since this file will be included by uip.h, we cannot include uip.h
+ here. But we might need to include uipopt.h if we need the u8_t and
+ u16_t datatypes. */
+#include "uipopt.h"
+
+#include "psock.h"
+
+/* Next, we define the uip_tcp_appstate_t datatype. This is the state
+ of our application, and the memory required for this state is
+ allocated together with each TCP connection. One application state
+ for each TCP connection. */
+#define BUF_SIZE 200
+typedef struct hello_world_state {
+ struct psock p;
+ char inputbuffer[BUF_SIZE];
+ char name[BUF_SIZE];
+} uip_tcp_appstate_t;
+
+/* Finally we define the application function to be called by uIP. */
+void hello_world_appcall(void);
+#ifndef UIP_APPCALL
+#define UIP_APPCALL hello_world_appcall
+#endif /* UIP_APPCALL */
+
+void hello_world_init(void);
+
+#endif /* __HELLO_WORLD_H__ */
+/** @} */
+/** @} */
diff --git a/components/net/uip/apps/telnetd/uip_shell.c b/components/net/uip/apps/telnetd/uip_shell.c
index 09bf3fa211..0c43ae8e40 100644
--- a/components/net/uip/apps/telnetd/uip_shell.c
+++ b/components/net/uip/apps/telnetd/uip_shell.c
@@ -1,123 +1,123 @@
- /*
- * Copyright (c) 2003, Adam Dunkels.
- * 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 uIP TCP/IP stack.
- *
- * $Id: shell.c,v 1.1 2006/06/07 09:43:54 adam Exp $
- *
- */
-
-#include "uip_shell.h"
-
-#include <string.h>
-
-struct ptentry {
- char *commandstr;
- void (* pfunc)(char *str);
-};
-
-#define SHELL_PROMPT "uIP 1.0> "
-
-/*---------------------------------------------------------------------------*/
-static void
-parse(register char *str, struct ptentry *t)
-{
- struct ptentry *p;
- for(p = t; p->commandstr != NULL; ++p) {
- if(strncmp(p->commandstr, str, strlen(p->commandstr)) == 0) {
- break;
- }
- }
-
- p->pfunc(str);
-}
-/*---------------------------------------------------------------------------*/
-static void
-inttostr(register char *str, unsigned int i)
-{
- str[0] = '0' + i / 100;
- if(str[0] == '0') {
- str[0] = ' ';
- }
- str[1] = '0' + (i / 10) % 10;
- if(str[0] == ' ' && str[1] == '0') {
- str[1] = ' ';
- }
- str[2] = '0' + i % 10;
- str[3] = ' ';
- str[4] = 0;
-}
-/*---------------------------------------------------------------------------*/
-static void
-help(char *str)
-{
- shell_output("Available commands:", "");
- shell_output("stats - show network statistics", "");
- shell_output("conn - show TCP connections", "");
- shell_output("help, ? - show help", "");
- shell_output("exit - exit shell", "");
-}
-/*---------------------------------------------------------------------------*/
-static void
-unknown(char *str)
-{
- if(strlen(str) > 0) {
- shell_output("Unknown command: ", str);
- }
-}
-/*---------------------------------------------------------------------------*/
-static struct ptentry parsetab[] =
- {{"stats", help},
- {"conn", help},
- {"help", help},
- {"exit", shell_quit},
- {"?", help},
-
- /* Default action */
- {NULL, unknown}};
-/*---------------------------------------------------------------------------*/
-void
-shell_init(void)
-{
-}
-/*---------------------------------------------------------------------------*/
-void
-shell_start(void)
-{
- shell_output("uIP command shell", "");
- shell_output("Type '?' and return for help", "");
- shell_prompt(SHELL_PROMPT);
-}
-/*---------------------------------------------------------------------------*/
-void
-shell_input(char *cmd)
-{
- parse(cmd, parsetab);
- shell_prompt(SHELL_PROMPT);
-}
-/*---------------------------------------------------------------------------*/
+ /*
+ * Copyright (c) 2003, Adam Dunkels.
+ * 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 uIP TCP/IP stack.
+ *
+ * $Id: shell.c,v 1.1 2006/06/07 09:43:54 adam Exp $
+ *
+ */
+
+#include "uip_shell.h"
+
+#include <string.h>
+
+struct ptentry {
+ char *commandstr;
+ void (* pfunc)(char *str);
+};
+
+#define SHELL_PROMPT "uIP 1.0> "
+
+/*---------------------------------------------------------------------------*/
+static void
+parse(register char *str, struct ptentry *t)
+{
+ struct ptentry *p;
+ for(p = t; p->commandstr != NULL; ++p) {
+ if(strncmp(p->commandstr, str, strlen(p->commandstr)) == 0) {
+ break;
+ }
+ }
+
+ p->pfunc(str);
+}
+/*---------------------------------------------------------------------------*/
+static void
+inttostr(register char *str, unsigned int i)
+{
+ str[0] = '0' + i / 100;
+ if(str[0] == '0') {
+ str[0] = ' ';
+ }
+ str[1] = '0' + (i / 10) % 10;
+ if(str[0] == ' ' && str[1] == '0') {
+ str[1] = ' ';
+ }
+ str[2] = '0' + i % 10;
+ str[3] = ' ';
+ str[4] = 0;
+}
+/*---------------------------------------------------------------------------*/
+static void
+help(char *str)
+{
+ shell_output("Available commands:", "");
+ shell_output("stats - show network statistics", "");
+ shell_output("conn - show TCP connections", "");
+ shell_output("help, ? - show help", "");
+ shell_output("exit - exit shell", "");
+}
+/*---------------------------------------------------------------------------*/
+static void
+unknown(char *str)
+{
+ if(strlen(str) > 0) {
+ shell_output("Unknown command: ", str);
+ }
+}
+/*---------------------------------------------------------------------------*/
+static struct ptentry parsetab[] =
+ {{"stats", help},
+ {"conn", help},
+ {"help", help},
+ {"exit", shell_quit},
+ {"?", help},
+
+ /* Default action */
+ {NULL, unknown}};
+/*---------------------------------------------------------------------------*/
+void
+shell_init(void)
+{
+}
+/*---------------------------------------------------------------------------*/
+void
+shell_start(void)
+{
+ shell_output("uIP command shell", "");
+ shell_output("Type '?' and return for help", "");
+ shell_prompt(SHELL_PROMPT);
+}
+/*---------------------------------------------------------------------------*/
+void
+shell_input(char *cmd)
+{
+ parse(cmd, parsetab);
+ shell_prompt(SHELL_PROMPT);
+}
+/*---------------------------------------------------------------------------*/
diff --git a/components/net/uip/rt-thread/clock-arch.c b/components/net/uip/rt-thread/clock-arch.c
index 0c00d83ff5..fa2cade08b 100644
--- a/components/net/uip/rt-thread/clock-arch.c
+++ b/components/net/uip/rt-thread/clock-arch.c
@@ -1,50 +1,50 @@
-/*
- * Copyright (c) 2006, 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 uIP TCP/IP stack
- *
- * $Id: clock-arch.c,v 1.2 2006/06/12 08:00:31 adam Exp $
- */
-
-/**
- * \file
- * Implementation of architecture-specific clock functionality
- * \author
- * Adam Dunkels <[email protected]>
- */
-
-#include "clock-arch.h"
-#include "stm32f10x.h"
-
-/*---------------------------------------------------------------------------*/
-clock_time_t
-clock_time(void)
-{
- return (rt_tick_get());
-}
-/*---------------------------------------------------------------------------*/
+/*
+ * Copyright (c) 2006, 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 uIP TCP/IP stack
+ *
+ * $Id: clock-arch.c,v 1.2 2006/06/12 08:00:31 adam Exp $
+ */
+
+/**
+ * \file
+ * Implementation of architecture-specific clock functionality
+ * \author
+ * Adam Dunkels <[email protected]>
+ */
+
+#include "clock-arch.h"
+#include "stm32f10x.h"
+
+/*---------------------------------------------------------------------------*/
+clock_time_t
+clock_time(void)
+{
+ return (rt_tick_get());
+}
+/*---------------------------------------------------------------------------*/
diff --git a/components/net/uip/rt-thread/clock-arch.h b/components/net/uip/rt-thread/clock-arch.h
index 0c4649d3ae..3c8978f3bb 100644
--- a/components/net/uip/rt-thread/clock-arch.h
+++ b/components/net/uip/rt-thread/clock-arch.h
@@ -1,40 +1,40 @@
-/*
- * Copyright (c) 2006, 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 uIP TCP/IP stack
- *
- * $Id: clock-arch.h,v 1.2 2006/06/12 08:00:31 adam Exp $
- */
-
-#ifndef __CLOCK_ARCH_H__
-#define __CLOCK_ARCH_H__
-
-typedef int clock_time_t;
-#define CLOCK_CONF_SECOND 100
-
-#endif /* __CLOCK_ARCH_H__ */
+/*
+ * Copyright (c) 2006, 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 uIP TCP/IP stack
+ *
+ * $Id: clock-arch.h,v 1.2 2006/06/12 08:00:31 adam Exp $
+ */
+
+#ifndef __CLOCK_ARCH_H__
+#define __CLOCK_ARCH_H__
+
+typedef int clock_time_t;
+#define CLOCK_CONF_SECOND 100
+
+#endif /* __CLOCK_ARCH_H__ */
diff --git a/components/net/uip/rt-thread/readme.txt b/components/net/uip/rt-thread/readme.txt
index d20386dfe2..4be911e853 100644
--- a/components/net/uip/rt-thread/readme.txt
+++ b/components/net/uip/rt-thread/readme.txt
@@ -1,12 +1,12 @@
-/************************************
-***
-***
-****
-******/
-
-
-
-2010-11-21
-��̫���е����������������ͻ���ɶ������⣿
-2010-11-21
+/************************************
+***
+***
+****
+******/
+
+
+
+2010-11-21
+��̫���е����������������ͻ���ɶ������⣿
+2010-11-21
����һ�����⣺HELLO WORLD�в������ӣ��Ͽ����֮��֮����Ҳ�������ӣ��� \ No newline at end of file
diff --git a/components/net/uip/rt-thread/uIPmain.c b/components/net/uip/rt-thread/uIPmain.c
index 089747472d..9d86f036fb 100644
--- a/components/net/uip/rt-thread/uIPmain.c
+++ b/components/net/uip/rt-thread/uIPmain.c
@@ -1,127 +1,127 @@
-/*
- * Copyright (c) 2001, Adam Dunkels.
- * 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. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Adam Dunkels.
- * 4. 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 uIP TCP/IP stack.
- *
- * $Id: main.c,v 1.16 2006/06/11 21:55:03 adam Exp $
- *
- */
-#include "uip.h"
-#include "uip_arp.h"
-#include "stm32_eth.h"
-#include "rtconfig.h"
-#include "rtdef.h"
-#include "uip_timer.h"
-#include "rtthread.h"
-
-
-
-
-
-#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
-// Define Prototypes
-void TransmitPacket(void)
-{
- int i;
- u8_t data[1500];
- // Copy the header portion part
- for(i=0; i < (UIP_LLH_LEN + 40); ++i)
- {
- data[i] = uip_buf[i];
- }
- // Copy the data portion part
- for(; i < uip_len; ++i)
- {
- data[i] = uip_appdata[i - UIP_LLH_LEN - 40 ];
- }
- ETH_HandleTxPkt(data,uip_len);
-}
-void uip_tcpip_thread(void *parameter)
-{
- int i;
- static u8_t cnt;
- while(1)
- {
- rt_thread_delay(CLOCK_SECOND*5);
- for (i = 0; i < UIP_CONNS; i++)
- {
- uip_periodic(i);
- /* If the above function invocation resulted in data that
- should be sent out on the network, the global variable
- uip_len is set to a value > 0. */
- if (uip_len > 0)
- {
- uip_arp_out();
- TransmitPacket();
- }
- }
-#if UIP_UDP
- for (i = 0; i < UIP_UDP_CONNS; i++)
- {
- uip_udp_periodic(i);
- /* If the above function invocation resulted in data that
- should be sent out on the network, the global variable
- uip_len is set to a value > 0. */
- if (uip_len > 0)
- {
- uip_arp_out();
- TransmitPacket();
- }
- }
-#endif /* UIP_UDP */
- /* Call the ARP timer function every 10 seconds. */
- if (++cnt > 2) uip_arp_timer();
- }
-}
-
-rt_thread_t sys_thread_new(char *name, void (* thread)(void *arg), void *arg, int stacksize, int prio)
-{
- rt_thread_t t;
- t = rt_thread_create(name, thread, arg, stacksize, prio, 20);
- RT_ASSERT(t != RT_NULL);
- rt_thread_startup(t);
- return t;
-}
-
-
-void uip_sys_init(void)
-{
-
- uip_init(); //uip init
- sys_thread_new("uip",uip_tcpip_thread, RT_NULL, RT_LWIP_TCPTHREAD_STACKSIZE, RT_LWIP_TCPTHREAD_PRIORITY);
- hello_world_init(); //
-}
-
-/*---------------------------------------------------------------------------*/
-void uip_log(char *m)
-{
- rt_kprintf("uIP log message: %s\n", m);
-}
+/*
+ * Copyright (c) 2001, Adam Dunkels.
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Adam Dunkels.
+ * 4. 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 uIP TCP/IP stack.
+ *
+ * $Id: main.c,v 1.16 2006/06/11 21:55:03 adam Exp $
+ *
+ */
+#include "uip.h"
+#include "uip_arp.h"
+#include "stm32_eth.h"
+#include "rtconfig.h"
+#include "rtdef.h"
+#include "uip_timer.h"
+#include "rtthread.h"
+
+
+
+
+
+#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
+// Define Prototypes
+void TransmitPacket(void)
+{
+ int i;
+ u8_t data[1500];
+ // Copy the header portion part
+ for(i=0; i < (UIP_LLH_LEN + 40); ++i)
+ {
+ data[i] = uip_buf[i];
+ }
+ // Copy the data portion part
+ for(; i < uip_len; ++i)
+ {
+ data[i] = uip_appdata[i - UIP_LLH_LEN - 40 ];
+ }
+ ETH_HandleTxPkt(data,uip_len);
+}
+void uip_tcpip_thread(void *parameter)
+{
+ int i;
+ static u8_t cnt;
+ while(1)
+ {
+ rt_thread_delay(CLOCK_SECOND*5);
+ for (i = 0; i < UIP_CONNS; i++)
+ {
+ uip_periodic(i);
+ /* If the above function invocation resulted in data that
+ should be sent out on the network, the global variable
+ uip_len is set to a value > 0. */
+ if (uip_len > 0)
+ {
+ uip_arp_out();
+ TransmitPacket();
+ }
+ }
+#if UIP_UDP
+ for (i = 0; i < UIP_UDP_CONNS; i++)
+ {
+ uip_udp_periodic(i);
+ /* If the above function invocation resulted in data that
+ should be sent out on the network, the global variable
+ uip_len is set to a value > 0. */
+ if (uip_len > 0)
+ {
+ uip_arp_out();
+ TransmitPacket();
+ }
+ }
+#endif /* UIP_UDP */
+ /* Call the ARP timer function every 10 seconds. */
+ if (++cnt > 2) uip_arp_timer();
+ }
+}
+
+rt_thread_t sys_thread_new(char *name, void (* thread)(void *arg), void *arg, int stacksize, int prio)
+{
+ rt_thread_t t;
+ t = rt_thread_create(name, thread, arg, stacksize, prio, 20);
+ RT_ASSERT(t != RT_NULL);
+ rt_thread_startup(t);
+ return t;
+}
+
+
+void uip_sys_init(void)
+{
+
+ uip_init(); //uip init
+ sys_thread_new("uip",uip_tcpip_thread, RT_NULL, RT_LWIP_TCPTHREAD_STACKSIZE, RT_LWIP_TCPTHREAD_PRIORITY);
+ hello_world_init(); //
+}
+
+/*---------------------------------------------------------------------------*/
+void uip_log(char *m)
+{
+ rt_kprintf("uIP log message: %s\n", m);
+}
diff --git a/components/net/uip/rt-thread/uip-conf.h b/components/net/uip/rt-thread/uip-conf.h
index 9c2a25044c..bb14c5389a 100644
--- a/components/net/uip/rt-thread/uip-conf.h
+++ b/components/net/uip/rt-thread/uip-conf.h
@@ -1,167 +1,167 @@
-/**
- * \addtogroup uipopt
- * @{
- */
-
-/**
- * \name Project-specific configuration options
- * @{
- *
- * uIP has a number of configuration options that can be overridden
- * for each project. These are kept in a project-specific uip-conf.h
- * file and all configuration names have the prefix UIP_CONF.
- */
-
-/*
- * Copyright (c) 2006, 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 uIP TCP/IP stack
- *
- * $Id: uip-conf.h,v 1.6 2006/06/12 08:00:31 adam Exp $
- */
-
-/**
- * \file
- * An example uIP configuration file
- * \author
- * Adam Dunkels <[email protected]>
- */
-
-#ifndef __UIP_CONF_H__
-#define __UIP_CONF_H__
-
-#include <inttypes.h>
-
-/**
- * 8 bit datatype
- *
- * This typedef defines the 8-bit type used throughout uIP.
- *
- * \hideinitializer
- */
-typedef uint8_t u8_t;
-
-/**
- * 16 bit datatype
- *
- * This typedef defines the 16-bit type used throughout uIP.
- *
- * \hideinitializer
- */
-typedef uint16_t u16_t;
-
-/**
- * Statistics datatype
- *
- * This typedef defines the dataype used for keeping statistics in
- * uIP.
- *
- * \hideinitializer
- */
-typedef unsigned short uip_stats_t;
-
-/**
- * Maximum number of TCP connections.
- *
- * \hideinitializer
- */
-#define UIP_CONF_MAX_CONNECTIONS 20
-
-/**
- * Maximum number of listening TCP ports.
- *
- * \hideinitializer
- */
-#define UIP_CONF_MAX_LISTENPORTS 40
-
-/**
- * uIP buffer size.
- *
- * \hideinitializer
- */
-#define UIP_CONF_BUFFER_SIZE 420
-
-/**
- * CPU byte order.
- *
- * \hideinitializer
- */
-#define UIP_CONF_BYTE_ORDER LITTLE_ENDIAN
-
-/**
- * Logging on or off
- *
- * \hideinitializer
- */
-#define UIP_CONF_LOGGING 1
-
-/**
- * UDP support on or off
- *
- * \hideinitializer
- */
-#define UIP_CONF_UDP 0
-
-/**
- * UDP checksums on or off
- *
- * \hideinitializer
- */
-#define UIP_CONF_UDP_CHECKSUMS 1
-
-/**
- * uIP statistics on or off
- *
- * \hideinitializer
- */
-#define UIP_CONF_STATISTICS 1
-
-/* Here we include the header file for the application(s) we use in
- our project. */
-/* #include "smtp.h" */
-#include "hello-world.h"
-//#include "telnetd.h"
-/* #include "webserver.h" */
-/* #include "dhcpc.h" */
-/* #include "resolv.h" */
-/* #include "webclient.h" */
-
-#define UIP_ARCH_ADD32 0
-
-#define UIP_ETHADDR0 0x00
-#define UIP_ETHADDR1 0x33
-#define UIP_ETHADDR2 0x44
-#define UIP_ETHADDR3 0x55
-#define UIP_ETHADDR4 0x66
-#define UIP_ETHADDR5 0x77
-#include <rtthread.h>
-
-#endif /* __UIP_CONF_H__ */
-
-/** @} */
-/** @} */
+/**
+ * \addtogroup uipopt
+ * @{
+ */
+
+/**
+ * \name Project-specific configuration options
+ * @{
+ *
+ * uIP has a number of configuration options that can be overridden
+ * for each project. These are kept in a project-specific uip-conf.h
+ * file and all configuration names have the prefix UIP_CONF.
+ */
+
+/*
+ * Copyright (c) 2006, 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 uIP TCP/IP stack
+ *
+ * $Id: uip-conf.h,v 1.6 2006/06/12 08:00:31 adam Exp $
+ */
+
+/**
+ * \file
+ * An example uIP configuration file
+ * \author
+ * Adam Dunkels <[email protected]>
+ */
+
+#ifndef __UIP_CONF_H__
+#define __UIP_CONF_H__
+
+#include <inttypes.h>
+
+/**
+ * 8 bit datatype
+ *
+ * This typedef defines the 8-bit type used throughout uIP.
+ *
+ * \hideinitializer
+ */
+typedef uint8_t u8_t;
+
+/**
+ * 16 bit datatype
+ *
+ * This typedef defines the 16-bit type used throughout uIP.
+ *
+ * \hideinitializer
+ */
+typedef uint16_t u16_t;
+
+/**
+ * Statistics datatype
+ *
+ * This typedef defines the dataype used for keeping statistics in
+ * uIP.
+ *
+ * \hideinitializer
+ */
+typedef unsigned short uip_stats_t;
+
+/**
+ * Maximum number of TCP connections.
+ *
+ * \hideinitializer
+ */
+#define UIP_CONF_MAX_CONNECTIONS 20
+
+/**
+ * Maximum number of listening TCP ports.
+ *
+ * \hideinitializer
+ */
+#define UIP_CONF_MAX_LISTENPORTS 40
+
+/**
+ * uIP buffer size.
+ *
+ * \hideinitializer
+ */
+#define UIP_CONF_BUFFER_SIZE 420
+
+/**
+ * CPU byte order.
+ *
+ * \hideinitializer
+ */
+#define UIP_CONF_BYTE_ORDER LITTLE_ENDIAN
+
+/**
+ * Logging on or off
+ *
+ * \hideinitializer
+ */
+#define UIP_CONF_LOGGING 1
+
+/**
+ * UDP support on or off
+ *
+ * \hideinitializer
+ */
+#define UIP_CONF_UDP 0
+
+/**
+ * UDP checksums on or off
+ *
+ * \hideinitializer
+ */
+#define UIP_CONF_UDP_CHECKSUMS 1
+
+/**
+ * uIP statistics on or off
+ *
+ * \hideinitializer
+ */
+#define UIP_CONF_STATISTICS 1
+
+/* Here we include the header file for the application(s) we use in
+ our project. */
+/* #include "smtp.h" */
+#include "hello-world.h"
+//#include "telnetd.h"
+/* #include "webserver.h" */
+/* #include "dhcpc.h" */
+/* #include "resolv.h" */
+/* #include "webclient.h" */
+
+#define UIP_ARCH_ADD32 0
+
+#define UIP_ETHADDR0 0x00
+#define UIP_ETHADDR1 0x33
+#define UIP_ETHADDR2 0x44
+#define UIP_ETHADDR3 0x55
+#define UIP_ETHADDR4 0x66
+#define UIP_ETHADDR5 0x77
+#include <rtthread.h>
+
+#endif /* __UIP_CONF_H__ */
+
+/** @} */
+/** @} */
diff --git a/components/net/uip/rt-thread/uip_addr.h b/components/net/uip/rt-thread/uip_addr.h
index 859477a0e3..60101f7c93 100644
--- a/components/net/uip/rt-thread/uip_addr.h
+++ b/components/net/uip/rt-thread/uip_addr.h
@@ -1,8 +1,8 @@
-
-#include "rtdef.h"
-
-
-
-struct ip_addr {
- rt_uint16_t uip_ip4addr_t[2];
+
+#include "rtdef.h"
+
+
+
+struct ip_addr {
+ rt_uint16_t uip_ip4addr_t[2];
} ; \ No newline at end of file
diff --git a/components/net/uip/rt-thread/uip_arch.c b/components/net/uip/rt-thread/uip_arch.c
index d41ee2b4a3..69a13aa1d3 100644
--- a/components/net/uip/rt-thread/uip_arch.c
+++ b/components/net/uip/rt-thread/uip_arch.c
@@ -1,143 +1,143 @@
-/*
- * Copyright (c) 2001, Adam Dunkels.
- * 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 uIP TCP/IP stack.
- *
- * $Id: uip_arch.c,v 1.2.2.1 2003/10/04 22:54:17 adam Exp $
- *
- */
-
-
-#include "uip.h"
-#include "uip_arch.h"
-
-#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
-#define IP_PROTO_TCP 6
-
-/*-----------------------------------------------------------------------------------*/
-void uip_add32(u8_t *op32, u16_t op16)
-{
-
- uip_acc32[3] = op32[3] + (op16 & 0xff);
- uip_acc32[2] = op32[2] + (op16 >> 8);
- uip_acc32[1] = op32[1];
- uip_acc32[0] = op32[0];
-
- if(uip_acc32[2] < (op16 >> 8)) {
- ++uip_acc32[1];
- if(uip_acc32[1] == 0) {
- ++uip_acc32[0];
- }
- }
-
-
- if(uip_acc32[3] < (op16 & 0xff)) {
- ++uip_acc32[2];
- if(uip_acc32[2] == 0) {
- ++uip_acc32[1];
- if(uip_acc32[1] == 0) {
- ++uip_acc32[0];
- }
- }
- }
-}
-/*-----------------------------------------------------------------------------------*/
-u16_t uip_chksum(u16_t *sdata, u16_t len)
-{
- u16_t acc;
-
- for (acc = 0; len > 1; len -= 2) {
- u16_t u = ((unsigned char *)sdata)[0] + (((unsigned char *)sdata)[1] << 8);
- if ((acc += u) < u) {
- /* Overflow, so we add the carry to acc (i.e., increase by
- one). */
- ++acc;
- }
- ++sdata;
- }
-
- /* add up any odd byte */
- if(len == 1) {
- acc += htons(((u16_t)(*(u8_t *)sdata)) << 8);
- if(acc < htons(((u16_t)(*(u8_t *)sdata)) << 8)) {
- ++acc;
- }
- }
-
- return acc;
-}
-/*-----------------------------------------------------------------------------------*/
-u16_t uip_ipchksum(void)
-{
- return uip_chksum((u16_t *)&uip_buf[UIP_LLH_LEN], 20);
-}
-/*-----------------------------------------------------------------------------------*/
-u16_t uip_tcpchksum(void)
-{
- u16_t hsum, sum;
-
-
- /* Compute the checksum of the TCP header. */
- hsum = uip_chksum((u16_t *)&uip_buf[20 + UIP_LLH_LEN], 20);
-
- /* Compute the checksum of the data in the TCP packet and add it to
- the TCP header checksum. */
- sum = uip_chksum((u16_t *)uip_appdata,
- (u16_t)(((((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - 40)));
-
- if((sum += hsum) < hsum) {
- ++sum;
- }
-
- if((sum += BUF->srcipaddr[0]) < BUF->srcipaddr[0]) {
- ++sum;
- }
- if((sum += BUF->srcipaddr[1]) < BUF->srcipaddr[1]) {
- ++sum;
- }
- if((sum += BUF->destipaddr[0]) < BUF->destipaddr[0]) {
- ++sum;
- }
- if((sum += BUF->destipaddr[1]) < BUF->destipaddr[1]) {
- ++sum;
- }
-
- if((sum += (u16_t)htons((u16_t)IP_PROTO_TCP)) < (u16_t)htons((u16_t)IP_PROTO_TCP)) {
- ++sum;
- }
-
- hsum = (u16_t)htons((((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - 20);
-
- if((sum += hsum) < hsum) {
- ++sum;
- }
-
- return sum;
-}
-
-
+/*
+ * Copyright (c) 2001, Adam Dunkels.
+ * 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 uIP TCP/IP stack.
+ *
+ * $Id: uip_arch.c,v 1.2.2.1 2003/10/04 22:54:17 adam Exp $
+ *
+ */
+
+
+#include "uip.h"
+#include "uip_arch.h"
+
+#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
+#define IP_PROTO_TCP 6
+
+/*-----------------------------------------------------------------------------------*/
+void uip_add32(u8_t *op32, u16_t op16)
+{
+
+ uip_acc32[3] = op32[3] + (op16 & 0xff);
+ uip_acc32[2] = op32[2] + (op16 >> 8);
+ uip_acc32[1] = op32[1];
+ uip_acc32[0] = op32[0];
+
+ if(uip_acc32[2] < (op16 >> 8)) {
+ ++uip_acc32[1];
+ if(uip_acc32[1] == 0) {
+ ++uip_acc32[0];
+ }
+ }
+
+
+ if(uip_acc32[3] < (op16 & 0xff)) {
+ ++uip_acc32[2];
+ if(uip_acc32[2] == 0) {
+ ++uip_acc32[1];
+ if(uip_acc32[1] == 0) {
+ ++uip_acc32[0];
+ }
+ }
+ }
+}
+/*-----------------------------------------------------------------------------------*/
+u16_t uip_chksum(u16_t *sdata, u16_t len)
+{
+ u16_t acc;
+
+ for (acc = 0; len > 1; len -= 2) {
+ u16_t u = ((unsigned char *)sdata)[0] + (((unsigned char *)sdata)[1] << 8);
+ if ((acc += u) < u) {
+ /* Overflow, so we add the carry to acc (i.e., increase by
+ one). */
+ ++acc;
+ }
+ ++sdata;
+ }
+
+ /* add up any odd byte */
+ if(len == 1) {
+ acc += htons(((u16_t)(*(u8_t *)sdata)) << 8);
+ if(acc < htons(((u16_t)(*(u8_t *)sdata)) << 8)) {
+ ++acc;
+ }
+ }
+
+ return acc;
+}
+/*-----------------------------------------------------------------------------------*/
+u16_t uip_ipchksum(void)
+{
+ return uip_chksum((u16_t *)&uip_buf[UIP_LLH_LEN], 20);
+}
+/*-----------------------------------------------------------------------------------*/
+u16_t uip_tcpchksum(void)
+{
+ u16_t hsum, sum;
+
+
+ /* Compute the checksum of the TCP header. */
+ hsum = uip_chksum((u16_t *)&uip_buf[20 + UIP_LLH_LEN], 20);
+
+ /* Compute the checksum of the data in the TCP packet and add it to
+ the TCP header checksum. */
+ sum = uip_chksum((u16_t *)uip_appdata,
+ (u16_t)(((((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - 40)));
+
+ if((sum += hsum) < hsum) {
+ ++sum;
+ }
+
+ if((sum += BUF->srcipaddr[0]) < BUF->srcipaddr[0]) {
+ ++sum;
+ }
+ if((sum += BUF->srcipaddr[1]) < BUF->srcipaddr[1]) {
+ ++sum;
+ }
+ if((sum += BUF->destipaddr[0]) < BUF->destipaddr[0]) {
+ ++sum;
+ }
+ if((sum += BUF->destipaddr[1]) < BUF->destipaddr[1]) {
+ ++sum;
+ }
+
+ if((sum += (u16_t)htons((u16_t)IP_PROTO_TCP)) < (u16_t)htons((u16_t)IP_PROTO_TCP)) {
+ ++sum;
+ }
+
+ hsum = (u16_t)htons((((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - 20);
+
+ if((sum += hsum) < hsum) {
+ ++sum;
+ }
+
+ return sum;
+}
+
+
diff --git a/components/net/uip/rt-thread/uip_eth.h b/components/net/uip/rt-thread/uip_eth.h
index e0a8ba8ba9..1ca7800eb8 100644
--- a/components/net/uip/rt-thread/uip_eth.h
+++ b/components/net/uip/rt-thread/uip_eth.h
@@ -1,35 +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 pbuf
-{
- rt_uint16_t len;
-};
-
-struct eth_device
-{
- /* inherit from rt_device */
- struct rt_device parent;
-
- //struct eth_addr *ethaddr;
- //struct netif *netif;
- struct rt_semaphore tx_ack;
- struct rt_semaphore tx_msg;
-
- /* 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, const char* name);
-
-rt_err_t eth_system_device_init(void);
-
-#endif /* __NETIF_ETHERNETIF_H__ */
+#ifndef __NETIF_ETHERNETIF_H__
+#define __NETIF_ETHERNETIF_H__
+
+//#include "lwip/netif.h"
+#include <rtthread.h>
+
+#define NIOCTL_GADDR 0x01
+#define ETHERNET_MTU 1500
+struct pbuf
+{
+ rt_uint16_t len;
+};
+
+struct eth_device
+{
+ /* inherit from rt_device */
+ struct rt_device parent;
+
+ //struct eth_addr *ethaddr;
+ //struct netif *netif;
+ struct rt_semaphore tx_ack;
+ struct rt_semaphore tx_msg;
+
+ /* 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, const char* name);
+
+rt_err_t eth_system_device_init(void);
+
+#endif /* __NETIF_ETHERNETIF_H__ */
diff --git a/components/net/uip/rt-thread/uip_etharp.c b/components/net/uip/rt-thread/uip_etharp.c
index a2d15a17a2..61e30fc6d0 100644
--- a/components/net/uip/rt-thread/uip_etharp.c
+++ b/components/net/uip/rt-thread/uip_etharp.c
@@ -1,58 +1,58 @@
-#include "uip_pbuf.h"
-#include "uip-conf.h"
-#include "rtdef.h"
-#include "uip.h"
-#include "uip_arp.h"
-#include "uip_netif.h"
-
-extern u16_t uip_len, uip_slen;
-void
-etharp_ip_input(struct netif *netif, struct pbuf *p)
-{
- u8_t *ptr;
- int i;
- ptr = p->payload;
- uip_len = p->len;
- for (i=0;i<p->len;i++) uip_buf[i] = ptr[i];
- uip_arp_ipin();
- uip_input();
- return;
-}
-void
-etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
-{
- u8_t *ptr,*pdata;
- //struct pbuf *q;
- int i;
- ptr = p->payload;
- uip_len = p->len;
- for (i=0;i<p->len;i++) uip_buf[i] = ptr[i];
- uip_arp_arpin(); //update arp table uip_arp_arpin
- if (uip_len)
- {
- if (( pdata =(u8_t*)rt_malloc(1500*sizeof(u8_t))) ==RT_NULL)
- {
- pbuf_free(p);
- return;
- }
- for (i=0; i < (UIP_LLH_LEN + 40); ++i)
- {
- pdata[i] = uip_buf[i];
- }
- for (; i < uip_len; ++i)
- {
- pdata[i] = uip_appdata[i - UIP_LLH_LEN - 40 ];
- }
- //q = p;
- p ->payload = pdata;
- p->len = uip_len;
- netif->linkoutput(netif,p);
- rt_free(pdata);
- pbuf_free(p);
- // pbuf_free(q);
- return ;
-
- // return 0; //ERR_OK
- }
- pbuf_free(p);
+#include "uip_pbuf.h"
+#include "uip-conf.h"
+#include "rtdef.h"
+#include "uip.h"
+#include "uip_arp.h"
+#include "uip_netif.h"
+
+extern u16_t uip_len, uip_slen;
+void
+etharp_ip_input(struct netif *netif, struct pbuf *p)
+{
+ u8_t *ptr;
+ int i;
+ ptr = p->payload;
+ uip_len = p->len;
+ for (i=0;i<p->len;i++) uip_buf[i] = ptr[i];
+ uip_arp_ipin();
+ uip_input();
+ return;
+}
+void
+etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
+{
+ u8_t *ptr,*pdata;
+ //struct pbuf *q;
+ int i;
+ ptr = p->payload;
+ uip_len = p->len;
+ for (i=0;i<p->len;i++) uip_buf[i] = ptr[i];
+ uip_arp_arpin(); //update arp table uip_arp_arpin
+ if (uip_len)
+ {
+ if (( pdata =(u8_t*)rt_malloc(1500*sizeof(u8_t))) ==RT_NULL)
+ {
+ pbuf_free(p);
+ return;
+ }
+ for (i=0; i < (UIP_LLH_LEN + 40); ++i)
+ {
+ pdata[i] = uip_buf[i];
+ }
+ for (; i < uip_len; ++i)
+ {
+ pdata[i] = uip_appdata[i - UIP_LLH_LEN - 40 ];
+ }
+ //q = p;
+ p ->payload = pdata;
+ p->len = uip_len;
+ netif->linkoutput(netif,p);
+ rt_free(pdata);
+ pbuf_free(p);
+ // pbuf_free(q);
+ return ;
+
+ // return 0; //ERR_OK
+ }
+ pbuf_free(p);
} \ No newline at end of file
diff --git a/components/net/uip/rt-thread/uip_etharp.h b/components/net/uip/rt-thread/uip_etharp.h
index bf8ff1f726..758dc4b62f 100644
--- a/components/net/uip/rt-thread/uip_etharp.h
+++ b/components/net/uip/rt-thread/uip_etharp.h
@@ -1,15 +1,15 @@
-#include "uip_pbuf.h"
-#include "uip-conf.h"
-#include "rtdef.h"
-
-
-struct eth_hdr {
- u8_t ip_addrdest[6];
- u8_t ip_addrsrc[6];
- u16_t type;
-} ;
-#define ETHTYPE_ARP UIP_ETHTYPE_ARP
-#define ETHTYPE_IP UIP_ETHTYPE_IP
-#define ETHTYPE_VLAN 0x8100
-#define ETHTYPE_PPPOEDISC 0x8863 /* PPP Over Ethernet Discovery Stage */
-#define ETHTYPE_PPPOE 0x8864 /* PPP Over Ethernet Session Stage */
+#include "uip_pbuf.h"
+#include "uip-conf.h"
+#include "rtdef.h"
+
+
+struct eth_hdr {
+ u8_t ip_addrdest[6];
+ u8_t ip_addrsrc[6];
+ u16_t type;
+} ;
+#define ETHTYPE_ARP UIP_ETHTYPE_ARP
+#define ETHTYPE_IP UIP_ETHTYPE_IP
+#define ETHTYPE_VLAN 0x8100
+#define ETHTYPE_PPPOEDISC 0x8863 /* PPP Over Ethernet Discovery Stage */
+#define ETHTYPE_PPPOE 0x8864 /* PPP Over Ethernet Session Stage */
diff --git a/components/net/uip/rt-thread/uip_ethernetif.c b/components/net/uip/rt-thread/uip_ethernetif.c
index aaa25150a0..fa4e52461e 100644
--- a/components/net/uip/rt-thread/uip_ethernetif.c
+++ b/components/net/uip/rt-thread/uip_ethernetif.c
@@ -1,313 +1,313 @@
-/*
- * 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 ethernetif_linkoutput send mail issue.
- */
-
-/*
- * Copyright (c) 2001-2004 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 <[email protected]>
- *
- */
-
-#include <rtthread.h>
-#include "uip.h"
-#include "uip_arp.h"
-#include "uip_netif.h"
-#include "uip_ethernetif.h"
-#include "uip_ipaddr.h"
-
-#ifndef NULL
-#define NULL (void *)0
-#endif /* NULL */
-
-#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
-extern u16_t uip_len, uip_slen;
-
-/* eth rx/tx thread */
-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
-
-struct eth_tx_msg
-{
- struct netif *netif;
- struct pbuf *buf;
-};
-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
-
-/* the interface provided to uIP */
-err_t eth_init(struct netif *netif)
-{
- return 0;
-}
-extern err_t ethernetif_linkoutput(struct netif *netif, struct pbuf *p);
-
-err_t eth_input(struct pbuf *p,struct netif *inp)
-{
-
- struct eth_hdr *ethhdr;
-
- if(p != RT_NULL)
- {
-#ifdef LINK_STATS
- //LINK_STATS_INC(link.recv);
-#endif LINK_STATS
-
- ethhdr = p->payload;
-
- switch(uip_htons(ethhdr->type))
- {
- case ETHTYPE_IP: //ETHTYPE_IP
- etharp_ip_input(inp, p);
- pbuf_header(p, -((rt_int16_t)sizeof(struct eth_hdr)));
- if (tcpip_input(p, inp) != ERR_OK)
- {
- // discard packet
- pbuf_free(p);
- }
- break;
-
- case ETHTYPE_ARP:
- etharp_arp_input(inp, (struct eth_addr *)inp->hwaddr, p);
- break;
-
- default:
- pbuf_free(p);
- p = RT_NULL;
- break;
- }
- }
- return ERR_OK;
-}
-
-err_t ethernetif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr)
-{
- return etharp_output(netif, p, ipaddr);
-}
-
-err_t ethernetif_linkoutput(struct netif *netif, struct pbuf *p)
-{
- 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);
- }
-
- return ERR_OK;
-}
-/* ethernetif APIs */
-rt_err_t eth_device_init(struct eth_device* dev, const char* name)
-{
- struct netif* netif;
- uip_ipaddr_t ipaddr;
- 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;
- /* register to rt-thread device manager */
- rt_device_register(&(dev->parent), name, RT_DEVICE_FLAG_RDWR);
- dev->parent.type = RT_Device_Class_NetIf;
- 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;
- /* broadcast capability */
- netif->flags = NETIF_FLAG_BROADCAST;
-
-#if LWIP_IGMP
- /* igmp support */
- netif->flags |= NETIF_FLAG_IGMP;
-#endif
-
- /* get hardware address */
- rt_device_control(&(dev->parent), NIOCTL_GADDR, netif->hwaddr);
-
- /* set output */
- netif->output = ethernetif_output;
- netif->linkoutput = ethernetif_linkoutput;
-
- /* add netif to lwip */
-
- if (netif_add(netif, IP_ADDR_ANY, IP_ADDR_BROADCAST, IP_ADDR_ANY, dev,
- eth_init, eth_input) == RT_NULL)
- {
- /* failed, unregister device and free netif */
- rt_device_unregister(&(dev->parent));
- rt_free(netif);
- return -RT_ERROR;
- }
-
- netif_set_default(netif);
- return RT_EOK;
-}
-
-/* ethernet buffer */
-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));
- }
- }
-}
-
-/* ethernet buffer */
-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;
-
- /* receive all of buffer */
- while (1)
- {
- p = device->eth_rx(&(device->parent));
- if (p != RT_NULL)
- {
- /* notify to upper layer */
- eth_input(p, device->netif);
- }
- else break;
- }
- }
- }
-}
-
-rt_err_t eth_device_ready(struct eth_device* dev)
-{
- /* post message to ethernet thread */
- return rt_mb_send(&eth_rx_thread_mb, (rt_uint32_t)dev);
-}
-
-rt_err_t eth_system_device_init()
-{
- rt_err_t result = RT_EOK;
-
- /* init rx thread */
- /* init mailbox and create ethernet 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_ETHERNETIF_THREAD_PREORITY, 16);
- RT_ASSERT(result == RT_EOK);
-
- result = rt_thread_startup(&eth_rx_thread);
- RT_ASSERT(result == RT_EOK);
-
- /* init tx thread */
- /* init mailbox and create ethernet 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);
-
- return result;
-}
+/*
+ * 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 ethernetif_linkoutput send mail issue.
+ */
+
+/*
+ * Copyright (c) 2001-2004 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 <[email protected]>
+ *
+ */
+
+#include <rtthread.h>
+#include "uip.h"
+#include "uip_arp.h"
+#include "uip_netif.h"
+#include "uip_ethernetif.h"
+#include "uip_ipaddr.h"
+
+#ifndef NULL
+#define NULL (void *)0
+#endif /* NULL */
+
+#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
+extern u16_t uip_len, uip_slen;
+
+/* eth rx/tx thread */
+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
+
+struct eth_tx_msg
+{
+ struct netif *netif;
+ struct pbuf *buf;
+};
+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
+
+/* the interface provided to uIP */
+err_t eth_init(struct netif *netif)
+{
+ return 0;
+}
+extern err_t ethernetif_linkoutput(struct netif *netif, struct pbuf *p);
+
+err_t eth_input(struct pbuf *p,struct netif *inp)
+{
+
+ struct eth_hdr *ethhdr;
+
+ if(p != RT_NULL)
+ {
+#ifdef LINK_STATS
+ //LINK_STATS_INC(link.recv);
+#endif LINK_STATS
+
+ ethhdr = p->payload;
+
+ switch(uip_htons(ethhdr->type))
+ {
+ case ETHTYPE_IP: //ETHTYPE_IP
+ etharp_ip_input(inp, p);
+ pbuf_header(p, -((rt_int16_t)sizeof(struct eth_hdr)));
+ if (tcpip_input(p, inp) != ERR_OK)
+ {
+ // discard packet
+ pbuf_free(p);
+ }
+ break;
+
+ case ETHTYPE_ARP:
+ etharp_arp_input(inp, (struct eth_addr *)inp->hwaddr, p);
+ break;
+
+ default:
+ pbuf_free(p);
+ p = RT_NULL;
+ break;
+ }
+ }
+ return ERR_OK;
+}
+
+err_t ethernetif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr)
+{
+ return etharp_output(netif, p, ipaddr);
+}
+
+err_t ethernetif_linkoutput(struct netif *netif, struct pbuf *p)
+{
+ 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);
+ }
+
+ return ERR_OK;
+}
+/* ethernetif APIs */
+rt_err_t eth_device_init(struct eth_device* dev, const char* name)
+{
+ struct netif* netif;
+ uip_ipaddr_t ipaddr;
+ 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;
+ /* register to rt-thread device manager */
+ rt_device_register(&(dev->parent), name, RT_DEVICE_FLAG_RDWR);
+ dev->parent.type = RT_Device_Class_NetIf;
+ 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;
+ /* broadcast capability */
+ netif->flags = NETIF_FLAG_BROADCAST;
+
+#if LWIP_IGMP
+ /* igmp support */
+ netif->flags |= NETIF_FLAG_IGMP;
+#endif
+
+ /* get hardware address */
+ rt_device_control(&(dev->parent), NIOCTL_GADDR, netif->hwaddr);
+
+ /* set output */
+ netif->output = ethernetif_output;
+ netif->linkoutput = ethernetif_linkoutput;
+
+ /* add netif to lwip */
+
+ if (netif_add(netif, IP_ADDR_ANY, IP_ADDR_BROADCAST, IP_ADDR_ANY, dev,
+ eth_init, eth_input) == RT_NULL)
+ {
+ /* failed, unregister device and free netif */
+ rt_device_unregister(&(dev->parent));
+ rt_free(netif);
+ return -RT_ERROR;
+ }
+
+ netif_set_default(netif);
+ return RT_EOK;
+}
+
+/* ethernet buffer */
+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));
+ }
+ }
+}
+
+/* ethernet buffer */
+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;
+
+ /* receive all of buffer */
+ while (1)
+ {
+ p = device->eth_rx(&(device->parent));
+ if (p != RT_NULL)
+ {
+ /* notify to upper layer */
+ eth_input(p, device->netif);
+ }
+ else break;
+ }
+ }
+ }
+}
+
+rt_err_t eth_device_ready(struct eth_device* dev)
+{
+ /* post message to ethernet thread */
+ return rt_mb_send(&eth_rx_thread_mb, (rt_uint32_t)dev);
+}
+
+rt_err_t eth_system_device_init()
+{
+ rt_err_t result = RT_EOK;
+
+ /* init rx thread */
+ /* init mailbox and create ethernet 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_ETHERNETIF_THREAD_PREORITY, 16);
+ RT_ASSERT(result == RT_EOK);
+
+ result = rt_thread_startup(&eth_rx_thread);
+ RT_ASSERT(result == RT_EOK);
+
+ /* init tx thread */
+ /* init mailbox and create ethernet 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);
+
+ return result;
+}
diff --git a/components/net/uip/rt-thread/uip_ethernetif.h b/components/net/uip/rt-thread/uip_ethernetif.h
index 612d053008..31a22e4eb9 100644
--- a/components/net/uip/rt-thread/uip_ethernetif.h
+++ b/components/net/uip/rt-thread/uip_ethernetif.h
@@ -1,31 +1,31 @@
-#ifndef __NETIF_ETHERNETIF_H__
-#define __NETIF_ETHERNETIF_H__
-
-//#include "lwip/netif.h"
-#include "uip_netif.h"
-#include <rtthread.h>
-
-#define NIOCTL_GADDR 0x01
-#define ETHERNET_MTU 1500
-
-struct eth_device
-{
- /* inherit from rt_device */
- struct rt_device parent;
-
- struct eth_addr *ethaddr;
- struct netif *netif;
- struct rt_semaphore tx_ack;
-
- /* 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, const char* name);
-
-rt_err_t eth_system_device_init(void);
-
-#endif /* __NETIF_ETHERNETIF_H__ */
+#ifndef __NETIF_ETHERNETIF_H__
+#define __NETIF_ETHERNETIF_H__
+
+//#include "lwip/netif.h"
+#include "uip_netif.h"
+#include <rtthread.h>
+
+#define NIOCTL_GADDR 0x01
+#define ETHERNET_MTU 1500
+
+struct eth_device
+{
+ /* inherit from rt_device */
+ struct rt_device parent;
+
+ struct eth_addr *ethaddr;
+ struct netif *netif;
+ struct rt_semaphore tx_ack;
+
+ /* 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, const char* name);
+
+rt_err_t eth_system_device_init(void);
+
+#endif /* __NETIF_ETHERNETIF_H__ */
diff --git a/components/net/uip/rt-thread/uip_ipaddr.h b/components/net/uip/rt-thread/uip_ipaddr.h
index 8f9e99b34a..98e2adf5da 100644
--- a/components/net/uip/rt-thread/uip_ipaddr.h
+++ b/components/net/uip/rt-thread/uip_ipaddr.h
@@ -1,20 +1,20 @@
-
-#include "rtdef.h"
-
-
-
-
-
-
-/* ethernetif APIs */
-#define IP_ADDR_ANY_VALUE 0x00000000UL
-#define IP_ADDR_BROADCAST_VALUE 0xffffffffUL
-
-//extern const struct ip_addr ip_addr_any;
-//extern const struct ip_addr ip_addr_broadcast;
-
-/** IP_ADDR_ can be used as a fixed IP address
- * for the wildcard and the broadcast address
- */
-#define IP_ADDR_ANY ((struct ip_addr *)0)
+
+#include "rtdef.h"
+
+
+
+
+
+
+/* ethernetif APIs */
+#define IP_ADDR_ANY_VALUE 0x00000000UL
+#define IP_ADDR_BROADCAST_VALUE 0xffffffffUL
+
+//extern const struct ip_addr ip_addr_any;
+//extern const struct ip_addr ip_addr_broadcast;
+
+/** IP_ADDR_ can be used as a fixed IP address
+ * for the wildcard and the broadcast address
+ */
+#define IP_ADDR_ANY ((struct ip_addr *)0)
#define IP_ADDR_BROADCAST ((struct ip_addr *)0) \ No newline at end of file
diff --git a/components/net/uip/rt-thread/uip_netif.c b/components/net/uip/rt-thread/uip_netif.c
index cd70ba31ab..ce1d20dcf1 100644
--- a/components/net/uip/rt-thread/uip_netif.c
+++ b/components/net/uip/rt-thread/uip_netif.c
@@ -1,53 +1,53 @@
-#include "rtdef.h"
-#include "uip-conf.h"
-#include "uip.h"
-#include "uip_netif.h"
-#include "uip_arp.h"
-#include "rtconfig.h"
-#include "uip_pbuf.h"
-
-void netif_set_default(struct netif *netif)
-{
-
-}
-void netif_set_addr(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask,
- struct ip_addr *gw)
-{
- uip_ipaddr_t hipaddr;
- uip_ipaddr(hipaddr, RT_LWIP_IPADDR0,RT_LWIP_IPADDR1,RT_LWIP_IPADDR2,RT_LWIP_IPADDR3);
- uip_sethostaddr(hipaddr);
- uip_ipaddr(hipaddr, RT_LWIP_GWADDR0,RT_LWIP_GWADDR1,RT_LWIP_GWADDR2,RT_LWIP_GWADDR3);
- uip_setdraddr(hipaddr);
- uip_ipaddr(hipaddr, RT_LWIP_MSKADDR0,RT_LWIP_MSKADDR1,RT_LWIP_MSKADDR2,RT_LWIP_MSKADDR3);
- uip_setnetmask(hipaddr);
- return ;
-}
-
-struct netif *
-netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask,
- struct ip_addr *gw,
- void *state,
- err_t (* init)(struct netif *netif),
- err_t (* input)(struct pbuf *p, struct netif *netif))
-{
- //if (netif_add(netif, IP_ADDR_ANY, IP_ADDR_BROADCAST, IP_ADDR_ANY, dev,
- //eth_init, eth_input) == RT_NULL)
- // netif->uip_hostaddr = ipaddr;
- //netif->uip_draddr = netmask;
- // netif->uip_netmask = gw;
- // netif_set_addr(netif,ipaddr,netmask,gw);
-
- // call user specified initialization function for netif
- if (init(netif) != 0) {
- return RT_NULL;
- }
- netif->input = input;
- netif->state = state;
- netif_set_addr(netif,ipaddr,netmask,gw);
- return netif;
-
-}
-err_t etharp_output(struct netif *netif, struct pbuf *q, struct ip_addr *ipaddr)
-{
- return 0;
-}
+#include "rtdef.h"
+#include "uip-conf.h"
+#include "uip.h"
+#include "uip_netif.h"
+#include "uip_arp.h"
+#include "rtconfig.h"
+#include "uip_pbuf.h"
+
+void netif_set_default(struct netif *netif)
+{
+
+}
+void netif_set_addr(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask,
+ struct ip_addr *gw)
+{
+ uip_ipaddr_t hipaddr;
+ uip_ipaddr(hipaddr, RT_LWIP_IPADDR0,RT_LWIP_IPADDR1,RT_LWIP_IPADDR2,RT_LWIP_IPADDR3);
+ uip_sethostaddr(hipaddr);
+ uip_ipaddr(hipaddr, RT_LWIP_GWADDR0,RT_LWIP_GWADDR1,RT_LWIP_GWADDR2,RT_LWIP_GWADDR3);
+ uip_setdraddr(hipaddr);
+ uip_ipaddr(hipaddr, RT_LWIP_MSKADDR0,RT_LWIP_MSKADDR1,RT_LWIP_MSKADDR2,RT_LWIP_MSKADDR3);
+ uip_setnetmask(hipaddr);
+ return ;
+}
+
+struct netif *
+netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask,
+ struct ip_addr *gw,
+ void *state,
+ err_t (* init)(struct netif *netif),
+ err_t (* input)(struct pbuf *p, struct netif *netif))
+{
+ //if (netif_add(netif, IP_ADDR_ANY, IP_ADDR_BROADCAST, IP_ADDR_ANY, dev,
+ //eth_init, eth_input) == RT_NULL)
+ // netif->uip_hostaddr = ipaddr;
+ //netif->uip_draddr = netmask;
+ // netif->uip_netmask = gw;
+ // netif_set_addr(netif,ipaddr,netmask,gw);
+
+ // call user specified initialization function for netif
+ if (init(netif) != 0) {
+ return RT_NULL;
+ }
+ netif->input = input;
+ netif->state = state;
+ netif_set_addr(netif,ipaddr,netmask,gw);
+ return netif;
+
+}
+err_t etharp_output(struct netif *netif, struct pbuf *q, struct ip_addr *ipaddr)
+{
+ return 0;
+}
diff --git a/components/net/uip/rt-thread/uip_netif.h b/components/net/uip/rt-thread/uip_netif.h
index 5cef2bb7ad..e5e335330e 100644
--- a/components/net/uip/rt-thread/uip_netif.h
+++ b/components/net/uip/rt-thread/uip_netif.h
@@ -1,269 +1,269 @@
-/*
- * Copyright (c) 2001-2004 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 <[email protected]>
- *
- */
-#ifndef __LWIP_NETIF_H__
-#define __LWIP_NETIF_H__
-
-//#include "lwip/opt.h"
-
-#define ENABLE_LOOPBACK (LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF)
-
-#include "lwip/err.h"
-
-#include "uip_ipaddr.h"
-
-//#include "lwip/inet.h"
-//#include "lwip/pbuf.h"
-#include "uip_pbuf.h"
-#include "uip-conf.h"
-
-#if LWIP_DHCP
-struct dhcp;
-#endif
-#if LWIP_AUTOIP
-struct autoip;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Throughout this file, IP addresses are expected to be in
- * the same byte order as in IP_PCB. */
-
-/** must be the maximum of all used hardware address lengths
- across all types of interfaces in use */
-#define NETIF_MAX_HWADDR_LEN 6U
-
-/** TODO: define the use (where, when, whom) of netif flags */
-
-/** whether the network interface is 'up'. this is
- * a software flag used to control whether this network
- * interface is enabled and processes traffic.
- */
-#define NETIF_FLAG_UP 0x01U
-/** if set, the netif has broadcast capability */
-#define NETIF_FLAG_BROADCAST 0x02U
-/** if set, the netif is one end of a point-to-point connection */
-#define NETIF_FLAG_POINTTOPOINT 0x04U
-/** if set, the interface is configured using DHCP */
-#define NETIF_FLAG_DHCP 0x08U
-/** if set, the interface has an active link
- * (set by the network interface driver) */
-#define NETIF_FLAG_LINK_UP 0x10U
-/** if set, the netif is an device using ARP */
-#define NETIF_FLAG_ETHARP 0x20U
-/** if set, the netif has IGMP capability */
-#define NETIF_FLAG_IGMP 0x40U
-
-/** Generic data structure used for all lwIP network interfaces.
- * The following fields should be filled in by the initialization
- * function for the device driver: hwaddr_len, hwaddr[], mtu, flags */
-struct ip_addr {
- rt_uint16_t uip_ip4addr_t[2];
-} ;
-
-struct netif {
- /** pointer to next in linked list */
- struct netif *next;
-
- /** IP address configuration in network byte order */
- struct ip_addr ip_addr;
- struct ip_addr netmask;
- struct ip_addr gw;
-
- /** This function is called by the network device driver
- * to pass a packet up the TCP/IP stack. */
- err_t (* input)(struct pbuf *p, struct netif *inp);
- /** This function is called by the IP module when it wants
- * to send a packet on the interface. This function typically
- * first resolves the hardware address, then sends the packet. */
- err_t (* output)(struct netif *netif, struct pbuf *p,
- struct ip_addr *ipaddr);
- /** This function is called by the ARP module when it wants
- * to send a packet on the interface. This function outputs
- * the pbuf as-is on the link medium. */
- err_t (* linkoutput)(struct netif *netif, struct pbuf *p);
-#if LWIP_NETIF_STATUS_CALLBACK
- /** This function is called when the netif state is set to up or down
- */
- void (* status_callback)(struct netif *netif);
-#endif /* LWIP_NETIF_STATUS_CALLBACK */
-#if LWIP_NETIF_LINK_CALLBACK
- /** This function is called when the netif link is set to up or down
- */
- void (* link_callback)(struct netif *netif);
-#endif /* LWIP_NETIF_LINK_CALLBACK */
- /** This field can be set by the device driver and could point
- * to state information for the device. */
- void *state;
-#if LWIP_DHCP
- /** the DHCP client state information for this netif */
- struct dhcp *dhcp;
-#endif /* LWIP_DHCP */
-#if LWIP_AUTOIP
- /** the AutoIP client state information for this netif */
- struct autoip *autoip;
-#endif
-#if LWIP_NETIF_HOSTNAME
- /* the hostname for this netif, NULL is a valid value */
- char* hostname;
-#endif /* LWIP_NETIF_HOSTNAME */
- /** maximum transfer unit (in bytes) */
- u16_t mtu;
- /** number of bytes used in hwaddr */
- u8_t hwaddr_len;
- /** link level hardware address of this interface */
- u8_t hwaddr[NETIF_MAX_HWADDR_LEN];
- /** flags (see NETIF_FLAG_ above) */
- u8_t flags;
- /** descriptive abbreviation */
- char name[2];
- /** number of this interface */
- u8_t num;
-#if LWIP_SNMP
- /** link type (from "snmp_ifType" enum from snmp.h) */
- u8_t link_type;
- /** (estimate) link speed */
- u32_t link_speed;
- /** timestamp at last change made (up/down) */
- u32_t ts;
- /** counters */
- u32_t ifinoctets;
- u32_t ifinucastpkts;
- u32_t ifinnucastpkts;
- u32_t ifindiscards;
- u32_t ifoutoctets;
- u32_t ifoutucastpkts;
- u32_t ifoutnucastpkts;
- u32_t ifoutdiscards;
-#endif /* LWIP_SNMP */
-#if LWIP_IGMP
- /* This function could be called to add or delete a entry in the multicast filter table of the ethernet MAC.*/
- err_t (*igmp_mac_filter)( struct netif *netif, struct ip_addr *group, u8_t action);
-#endif /* LWIP_IGMP */
-#if LWIP_NETIF_HWADDRHINT
- u8_t *addr_hint;
-#endif /* LWIP_NETIF_HWADDRHINT */
-#if ENABLE_LOOPBACK
- /* List of packets to be queued for ourselves. */
- struct pbuf *loop_first;
- struct pbuf *loop_last;
-#if LWIP_LOOPBACK_MAX_PBUFS
- u16_t loop_cnt_current;
-#endif /* LWIP_LOOPBACK_MAX_PBUFS */
-#endif /* ENABLE_LOOPBACK */
-};
-
-#if LWIP_SNMP
-#define NETIF_INIT_SNMP(netif, type, speed) \
- /* use "snmp_ifType" enum from snmp.h for "type", snmp_ifType_ethernet_csmacd by example */ \
- netif->link_type = type; \
- /* your link speed here (units: bits per second) */ \
- netif->link_speed = speed; \
- netif->ts = 0; \
- netif->ifinoctets = 0; \
- netif->ifinucastpkts = 0; \
- netif->ifinnucastpkts = 0; \
- netif->ifindiscards = 0; \
- netif->ifoutoctets = 0; \
- netif->ifoutucastpkts = 0; \
- netif->ifoutnucastpkts = 0; \
- netif->ifoutdiscards = 0
-#else /* LWIP_SNMP */
-#define NETIF_INIT_SNMP(netif, type, speed)
-#endif /* LWIP_SNMP */
-
-
-/** The list of network interfaces. */
-extern struct netif *netif_list;
-/** The default network interface. */
-extern struct netif *netif_default;
-
-#define netif_init() /* Compatibility define, not init needed. */
-
-struct netif *netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask,
- struct ip_addr *gw,
- void *state,
- err_t (* init)(struct netif *netif),
- err_t (* input)(struct pbuf *p, struct netif *netif));
-
-void
-netif_set_addr(struct netif *netif,struct ip_addr *ipaddr, struct ip_addr *netmask,
- struct ip_addr *gw);
-void netif_remove(struct netif * netif);
-
-/* Returns a network interface given its name. The name is of the form
- "et0", where the first two letters are the "name" field in the
- netif structure, and the digit is in the num field in the same
- structure. */
-struct netif *netif_find(char *name);
-
-void netif_set_default(struct netif *netif);
-
-void netif_set_ipaddr(struct netif *netif, struct ip_addr *ipaddr);
-void netif_set_netmask(struct netif *netif, struct ip_addr *netmask);
-void netif_set_gw(struct netif *netif, struct ip_addr *gw);
-
-void netif_set_up(struct netif *netif);
-void netif_set_down(struct netif *netif);
-u8_t netif_is_up(struct netif *netif);
-
-#if LWIP_NETIF_STATUS_CALLBACK
-/*
- * Set callback to be called when interface is brought up/down
- */
-void netif_set_status_callback(struct netif *netif, void (* status_callback)(struct netif *netif));
-#endif /* LWIP_NETIF_STATUS_CALLBACK */
-
-#if LWIP_NETIF_LINK_CALLBACK
-void netif_set_link_up(struct netif *netif);
-void netif_set_link_down(struct netif *netif);
-u8_t netif_is_link_up(struct netif *netif);
-/*
- * Set callback to be called when link is brought up/down
- */
-void netif_set_link_callback(struct netif *netif, void (* link_callback)(struct netif *netif));
-#endif /* LWIP_NETIF_LINK_CALLBACK */
-
-#ifdef __cplusplus
-}
-#endif
-
-#if ENABLE_LOOPBACK
-err_t netif_loop_output(struct netif *netif, struct pbuf *p, struct ip_addr *dest_ip);
-void netif_poll(struct netif *netif);
-#if !LWIP_NETIF_LOOPBACK_MULTITHREADING
-void netif_poll_all(void);
-#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */
-#endif /* ENABLE_LOOPBACK */
-
-#endif /* __LWIP_NETIF_H__ */
+/*
+ * Copyright (c) 2001-2004 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 <[email protected]>
+ *
+ */
+#ifndef __LWIP_NETIF_H__
+#define __LWIP_NETIF_H__
+
+//#include "lwip/opt.h"
+
+#define ENABLE_LOOPBACK (LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF)
+
+#include "lwip/err.h"
+
+#include "uip_ipaddr.h"
+
+//#include "lwip/inet.h"
+//#include "lwip/pbuf.h"
+#include "uip_pbuf.h"
+#include "uip-conf.h"
+
+#if LWIP_DHCP
+struct dhcp;
+#endif
+#if LWIP_AUTOIP
+struct autoip;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Throughout this file, IP addresses are expected to be in
+ * the same byte order as in IP_PCB. */
+
+/** must be the maximum of all used hardware address lengths
+ across all types of interfaces in use */
+#define NETIF_MAX_HWADDR_LEN 6U
+
+/** TODO: define the use (where, when, whom) of netif flags */
+
+/** whether the network interface is 'up'. this is
+ * a software flag used to control whether this network
+ * interface is enabled and processes traffic.
+ */
+#define NETIF_FLAG_UP 0x01U
+/** if set, the netif has broadcast capability */
+#define NETIF_FLAG_BROADCAST 0x02U
+/** if set, the netif is one end of a point-to-point connection */
+#define NETIF_FLAG_POINTTOPOINT 0x04U
+/** if set, the interface is configured using DHCP */
+#define NETIF_FLAG_DHCP 0x08U
+/** if set, the interface has an active link
+ * (set by the network interface driver) */
+#define NETIF_FLAG_LINK_UP 0x10U
+/** if set, the netif is an device using ARP */
+#define NETIF_FLAG_ETHARP 0x20U
+/** if set, the netif has IGMP capability */
+#define NETIF_FLAG_IGMP 0x40U
+
+/** Generic data structure used for all lwIP network interfaces.
+ * The following fields should be filled in by the initialization
+ * function for the device driver: hwaddr_len, hwaddr[], mtu, flags */
+struct ip_addr {
+ rt_uint16_t uip_ip4addr_t[2];
+} ;
+
+struct netif {
+ /** pointer to next in linked list */
+ struct netif *next;
+
+ /** IP address configuration in network byte order */
+ struct ip_addr ip_addr;
+ struct ip_addr netmask;
+ struct ip_addr gw;
+
+ /** This function is called by the network device driver
+ * to pass a packet up the TCP/IP stack. */
+ err_t (* input)(struct pbuf *p, struct netif *inp);
+ /** This function is called by the IP module when it wants
+ * to send a packet on the interface. This function typically
+ * first resolves the hardware address, then sends the packet. */
+ err_t (* output)(struct netif *netif, struct pbuf *p,
+ struct ip_addr *ipaddr);
+ /** This function is called by the ARP module when it wants
+ * to send a packet on the interface. This function outputs
+ * the pbuf as-is on the link medium. */
+ err_t (* linkoutput)(struct netif *netif, struct pbuf *p);
+#if LWIP_NETIF_STATUS_CALLBACK
+ /** This function is called when the netif state is set to up or down
+ */
+ void (* status_callback)(struct netif *netif);
+#endif /* LWIP_NETIF_STATUS_CALLBACK */
+#if LWIP_NETIF_LINK_CALLBACK
+ /** This function is called when the netif link is set to up or down
+ */
+ void (* link_callback)(struct netif *netif);
+#endif /* LWIP_NETIF_LINK_CALLBACK */
+ /** This field can be set by the device driver and could point
+ * to state information for the device. */
+ void *state;
+#if LWIP_DHCP
+ /** the DHCP client state information for this netif */
+ struct dhcp *dhcp;
+#endif /* LWIP_DHCP */
+#if LWIP_AUTOIP
+ /** the AutoIP client state information for this netif */
+ struct autoip *autoip;
+#endif
+#if LWIP_NETIF_HOSTNAME
+ /* the hostname for this netif, NULL is a valid value */
+ char* hostname;
+#endif /* LWIP_NETIF_HOSTNAME */
+ /** maximum transfer unit (in bytes) */
+ u16_t mtu;
+ /** number of bytes used in hwaddr */
+ u8_t hwaddr_len;
+ /** link level hardware address of this interface */
+ u8_t hwaddr[NETIF_MAX_HWADDR_LEN];
+ /** flags (see NETIF_FLAG_ above) */
+ u8_t flags;
+ /** descriptive abbreviation */
+ char name[2];
+ /** number of this interface */
+ u8_t num;
+#if LWIP_SNMP
+ /** link type (from "snmp_ifType" enum from snmp.h) */
+ u8_t link_type;
+ /** (estimate) link speed */
+ u32_t link_speed;
+ /** timestamp at last change made (up/down) */
+ u32_t ts;
+ /** counters */
+ u32_t ifinoctets;
+ u32_t ifinucastpkts;
+ u32_t ifinnucastpkts;
+ u32_t ifindiscards;
+ u32_t ifoutoctets;
+ u32_t ifoutucastpkts;
+ u32_t ifoutnucastpkts;
+ u32_t ifoutdiscards;
+#endif /* LWIP_SNMP */
+#if LWIP_IGMP
+ /* This function could be called to add or delete a entry in the multicast filter table of the ethernet MAC.*/
+ err_t (*igmp_mac_filter)( struct netif *netif, struct ip_addr *group, u8_t action);
+#endif /* LWIP_IGMP */
+#if LWIP_NETIF_HWADDRHINT
+ u8_t *addr_hint;
+#endif /* LWIP_NETIF_HWADDRHINT */
+#if ENABLE_LOOPBACK
+ /* List of packets to be queued for ourselves. */
+ struct pbuf *loop_first;
+ struct pbuf *loop_last;
+#if LWIP_LOOPBACK_MAX_PBUFS
+ u16_t loop_cnt_current;
+#endif /* LWIP_LOOPBACK_MAX_PBUFS */
+#endif /* ENABLE_LOOPBACK */
+};
+
+#if LWIP_SNMP
+#define NETIF_INIT_SNMP(netif, type, speed) \
+ /* use "snmp_ifType" enum from snmp.h for "type", snmp_ifType_ethernet_csmacd by example */ \
+ netif->link_type = type; \
+ /* your link speed here (units: bits per second) */ \
+ netif->link_speed = speed; \
+ netif->ts = 0; \
+ netif->ifinoctets = 0; \
+ netif->ifinucastpkts = 0; \
+ netif->ifinnucastpkts = 0; \
+ netif->ifindiscards = 0; \
+ netif->ifoutoctets = 0; \
+ netif->ifoutucastpkts = 0; \
+ netif->ifoutnucastpkts = 0; \
+ netif->ifoutdiscards = 0
+#else /* LWIP_SNMP */
+#define NETIF_INIT_SNMP(netif, type, speed)
+#endif /* LWIP_SNMP */
+
+
+/** The list of network interfaces. */
+extern struct netif *netif_list;
+/** The default network interface. */
+extern struct netif *netif_default;
+
+#define netif_init() /* Compatibility define, not init needed. */
+
+struct netif *netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask,
+ struct ip_addr *gw,
+ void *state,
+ err_t (* init)(struct netif *netif),
+ err_t (* input)(struct pbuf *p, struct netif *netif));
+
+void
+netif_set_addr(struct netif *netif,struct ip_addr *ipaddr, struct ip_addr *netmask,
+ struct ip_addr *gw);
+void netif_remove(struct netif * netif);
+
+/* Returns a network interface given its name. The name is of the form
+ "et0", where the first two letters are the "name" field in the
+ netif structure, and the digit is in the num field in the same
+ structure. */
+struct netif *netif_find(char *name);
+
+void netif_set_default(struct netif *netif);
+
+void netif_set_ipaddr(struct netif *netif, struct ip_addr *ipaddr);
+void netif_set_netmask(struct netif *netif, struct ip_addr *netmask);
+void netif_set_gw(struct netif *netif, struct ip_addr *gw);
+
+void netif_set_up(struct netif *netif);
+void netif_set_down(struct netif *netif);
+u8_t netif_is_up(struct netif *netif);
+
+#if LWIP_NETIF_STATUS_CALLBACK
+/*
+ * Set callback to be called when interface is brought up/down
+ */
+void netif_set_status_callback(struct netif *netif, void (* status_callback)(struct netif *netif));
+#endif /* LWIP_NETIF_STATUS_CALLBACK */
+
+#if LWIP_NETIF_LINK_CALLBACK
+void netif_set_link_up(struct netif *netif);
+void netif_set_link_down(struct netif *netif);
+u8_t netif_is_link_up(struct netif *netif);
+/*
+ * Set callback to be called when link is brought up/down
+ */
+void netif_set_link_callback(struct netif *netif, void (* link_callback)(struct netif *netif));
+#endif /* LWIP_NETIF_LINK_CALLBACK */
+
+#ifdef __cplusplus
+}
+#endif
+
+#if ENABLE_LOOPBACK
+err_t netif_loop_output(struct netif *netif, struct pbuf *p, struct ip_addr *dest_ip);
+void netif_poll(struct netif *netif);
+#if !LWIP_NETIF_LOOPBACK_MULTITHREADING
+void netif_poll_all(void);
+#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */
+#endif /* ENABLE_LOOPBACK */
+
+#endif /* __LWIP_NETIF_H__ */
diff --git a/components/net/uip/rt-thread/uip_pbuf.c b/components/net/uip/rt-thread/uip_pbuf.c
index 69ff3b5a6d..ea12e84e62 100644
--- a/components/net/uip/rt-thread/uip_pbuf.c
+++ b/components/net/uip/rt-thread/uip_pbuf.c
@@ -1,50 +1,50 @@
-#include "uip_pbuf.h"
-#include "rtdef.h"
-
-typedef rt_uint32_t mem_ptr_t;
-#define LWIP_MEM_ALIGN(addr) ((void *)(((mem_ptr_t)(addr) + RT_ALIGN_SIZE - 1) & ~(mem_ptr_t)(RT_ALIGN_SIZE-1)))
-#define LWIP_MEM_ALIGN_SIZE(size) (((size) + RT_ALIGN_SIZE - 1) & ~(RT_ALIGN_SIZE-1))
-#define SIZEOF_STRUCT_PBUF LWIP_MEM_ALIGN_SIZE(sizeof(struct pbuf))
-
-u8_t
-pbuf_free(struct pbuf *p)
-{
-
- //struct pbuf *q;
-
- if (p == RT_NULL) return 0;
- rt_free(p);
- //rt_free(&p->len);
-
- return 1;
-}
-
-struct pbuf *
-pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
-{
- struct pbuf *p;
- u16_t offset = 0;
- offset += 16;
-
- /* If pbuf is to be allocated in RAM, allocate memory for it. */
- p = (struct pbuf*)rt_malloc(LWIP_MEM_ALIGN_SIZE(SIZEOF_STRUCT_PBUF + offset) + LWIP_MEM_ALIGN_SIZE(length));
- if (p == RT_NULL) return RT_NULL;
- /* Set up internal structure of the pbuf. */
- p->payload = LWIP_MEM_ALIGN((void *)((u8_t *)p + SIZEOF_STRUCT_PBUF + offset));
- p->len = length;
- return p;
-}
-
-u8_t
-pbuf_header(struct pbuf *p, s16_t header_size_increment) //
-{
- //extrat link header
- uint8_t *ptr;
-
- ptr = p->payload;
- ptr -= header_size_increment;
- p->payload = ptr;
- p->len += header_size_increment;
-
- return 0;
+#include "uip_pbuf.h"
+#include "rtdef.h"
+
+typedef rt_uint32_t mem_ptr_t;
+#define LWIP_MEM_ALIGN(addr) ((void *)(((mem_ptr_t)(addr) + RT_ALIGN_SIZE - 1) & ~(mem_ptr_t)(RT_ALIGN_SIZE-1)))
+#define LWIP_MEM_ALIGN_SIZE(size) (((size) + RT_ALIGN_SIZE - 1) & ~(RT_ALIGN_SIZE-1))
+#define SIZEOF_STRUCT_PBUF LWIP_MEM_ALIGN_SIZE(sizeof(struct pbuf))
+
+u8_t
+pbuf_free(struct pbuf *p)
+{
+
+ //struct pbuf *q;
+
+ if (p == RT_NULL) return 0;
+ rt_free(p);
+ //rt_free(&p->len);
+
+ return 1;
+}
+
+struct pbuf *
+pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
+{
+ struct pbuf *p;
+ u16_t offset = 0;
+ offset += 16;
+
+ /* If pbuf is to be allocated in RAM, allocate memory for it. */
+ p = (struct pbuf*)rt_malloc(LWIP_MEM_ALIGN_SIZE(SIZEOF_STRUCT_PBUF + offset) + LWIP_MEM_ALIGN_SIZE(length));
+ if (p == RT_NULL) return RT_NULL;
+ /* Set up internal structure of the pbuf. */
+ p->payload = LWIP_MEM_ALIGN((void *)((u8_t *)p + SIZEOF_STRUCT_PBUF + offset));
+ p->len = length;
+ return p;
+}
+
+u8_t
+pbuf_header(struct pbuf *p, s16_t header_size_increment) //
+{
+ //extrat link header
+ uint8_t *ptr;
+
+ ptr = p->payload;
+ ptr -= header_size_increment;
+ p->payload = ptr;
+ p->len += header_size_increment;
+
+ return 0;
} \ No newline at end of file
diff --git a/components/net/uip/rt-thread/uip_pbuf.h b/components/net/uip/rt-thread/uip_pbuf.h
index 284dec87fc..56c5bf5e99 100644
--- a/components/net/uip/rt-thread/uip_pbuf.h
+++ b/components/net/uip/rt-thread/uip_pbuf.h
@@ -1,87 +1,87 @@
-
-#ifndef __UIP_PBUF_H__
-#define __UIP_PBUF_H__
-
-//#include "lwip/opt.h"
-//#include "lwip/err.h"
-#include "uip-conf.h"
-#include "uip_etharp.h"
-
-typedef rt_int16_t s16_t;
-typedef rt_int8_t err_t;
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define PBUF_TRANSPORT_HLEN 20
-#define PBUF_IP_HLEN 20
-
-typedef enum {
- PBUF_TRANSPORT,
- PBUF_IP,
- PBUF_LINK,
- PBUF_RAW
-} pbuf_layer;
-
-typedef enum {
- PBUF_RAM, /* pbuf data is stored in RAM */
- PBUF_ROM, /* pbuf data is stored in ROM */
- PBUF_REF, /* pbuf comes from the pbuf pool */
- PBUF_POOL /* pbuf payload refers to RAM */
-} pbuf_type;
-
-
-/** indicates this packet's data should be immediately passed to the application */
-#define PBUF_FLAG_PUSH 0x01U
-#ifdef RT_USING_LWIP
-struct pbuf {
- /** next pbuf in singly linked pbuf chain */
- struct pbuf *next;
-
- /** pointer to the actual data in the buffer */
- void *payload;
-
- /**
- * total length of this buffer and all next buffers in chain
- * belonging to the same packet.
- *
- * For non-queue packet chains this is the invariant:
- * p->tot_len == p->len + (p->next? p->next->tot_len: 0)
- */
- u16_t tot_len;
-
- /** length of this buffer */
- u16_t len;
-
- /** pbuf_type as u8_t instead of enum to save space */
- u8_t /*pbuf_type*/ type;
-
- /** misc flags */
- u8_t flags;
-
- /**
- * the reference count always equals the number of pointers
- * that refer to this pbuf. This can be pointers from an application,
- * the stack itself, or pbuf->next pointers from a chain.
- */
- u16_t ref;
-
-};
-#else /* RT_USING_UIP */
-struct pbuf
-{
- /** pointer to the actual data in the buffer */
- void *payload;
- rt_uint16_t len;
-};
-#endif
-/* Initializes the pbuf module. This call is empty for now, but may not be in future. */
-
-
-struct pbuf *pbuf_alloc(pbuf_layer l, u16_t size, pbuf_type type);
-
-u8_t pbuf_header(struct pbuf *p, s16_t header_size);
-
-u8_t pbuf_free(struct pbuf *p);
-
-#endif /* __UIP_PBUF_H__ */
+
+#ifndef __UIP_PBUF_H__
+#define __UIP_PBUF_H__
+
+//#include "lwip/opt.h"
+//#include "lwip/err.h"
+#include "uip-conf.h"
+#include "uip_etharp.h"
+
+typedef rt_int16_t s16_t;
+typedef rt_int8_t err_t;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PBUF_TRANSPORT_HLEN 20
+#define PBUF_IP_HLEN 20
+
+typedef enum {
+ PBUF_TRANSPORT,
+ PBUF_IP,
+ PBUF_LINK,
+ PBUF_RAW
+} pbuf_layer;
+
+typedef enum {
+ PBUF_RAM, /* pbuf data is stored in RAM */
+ PBUF_ROM, /* pbuf data is stored in ROM */
+ PBUF_REF, /* pbuf comes from the pbuf pool */
+ PBUF_POOL /* pbuf payload refers to RAM */
+} pbuf_type;
+
+
+/** indicates this packet's data should be immediately passed to the application */
+#define PBUF_FLAG_PUSH 0x01U
+#ifdef RT_USING_LWIP
+struct pbuf {
+ /** next pbuf in singly linked pbuf chain */
+ struct pbuf *next;
+
+ /** pointer to the actual data in the buffer */
+ void *payload;
+
+ /**
+ * total length of this buffer and all next buffers in chain
+ * belonging to the same packet.
+ *
+ * For non-queue packet chains this is the invariant:
+ * p->tot_len == p->len + (p->next? p->next->tot_len: 0)
+ */
+ u16_t tot_len;
+
+ /** length of this buffer */
+ u16_t len;
+
+ /** pbuf_type as u8_t instead of enum to save space */
+ u8_t /*pbuf_type*/ type;
+
+ /** misc flags */
+ u8_t flags;
+
+ /**
+ * the reference count always equals the number of pointers
+ * that refer to this pbuf. This can be pointers from an application,
+ * the stack itself, or pbuf->next pointers from a chain.
+ */
+ u16_t ref;
+
+};
+#else /* RT_USING_UIP */
+struct pbuf
+{
+ /** pointer to the actual data in the buffer */
+ void *payload;
+ rt_uint16_t len;
+};
+#endif
+/* Initializes the pbuf module. This call is empty for now, but may not be in future. */
+
+
+struct pbuf *pbuf_alloc(pbuf_layer l, u16_t size, pbuf_type type);
+
+u8_t pbuf_header(struct pbuf *p, s16_t header_size);
+
+u8_t pbuf_free(struct pbuf *p);
+
+#endif /* __UIP_PBUF_H__ */
diff --git a/components/net/uip/rt-thread/uip_tcpip.c b/components/net/uip/rt-thread/uip_tcpip.c
index 4cedb05864..9e65a3c18a 100644
--- a/components/net/uip/rt-thread/uip_tcpip.c
+++ b/components/net/uip/rt-thread/uip_tcpip.c
@@ -1,41 +1,41 @@
-#include "uip_pbuf.h"
-#include "uip-conf.h"
-#include "rtdef.h"
-#include "uip.h"
-#include "uip_arp.h"
-#include "uip_netif.h"
-
-err_t
-tcpip_input(struct pbuf *p, struct netif *inp)
-{
- int i;
- u8_t *pdata;
- if (uip_len)
- {
- uip_arp_out();
- if (( pdata =(u8_t*)rt_malloc(1500*sizeof(u8_t))) == RT_NULL)
- {
- pbuf_free(p);
- return 1;
- }
- for (i=0; i < (UIP_LLH_LEN + 40); ++i) // 14+40 =54
- {
- pdata[i] = uip_buf[i]; /* get dest an src ipaddr */
- }
- // Copy the data portion part
- for(; i < uip_len; ++i)
- {
- pdata[i] = uip_appdata[i - UIP_LLH_LEN - 40 ];
- }
- p ->payload = pdata;
- p->len = uip_len;
- inp->linkoutput(inp,p);
- rt_free(pdata);
- return 1;
- }
- else
- {
- pbuf_free(p);
- return 0;
- }
+#include "uip_pbuf.h"
+#include "uip-conf.h"
+#include "rtdef.h"
+#include "uip.h"
+#include "uip_arp.h"
+#include "uip_netif.h"
+
+err_t
+tcpip_input(struct pbuf *p, struct netif *inp)
+{
+ int i;
+ u8_t *pdata;
+ if (uip_len)
+ {
+ uip_arp_out();
+ if (( pdata =(u8_t*)rt_malloc(1500*sizeof(u8_t))) == RT_NULL)
+ {
+ pbuf_free(p);
+ return 1;
+ }
+ for (i=0; i < (UIP_LLH_LEN + 40); ++i) // 14+40 =54
+ {
+ pdata[i] = uip_buf[i]; /* get dest an src ipaddr */
+ }
+ // Copy the data portion part
+ for(; i < uip_len; ++i)
+ {
+ pdata[i] = uip_appdata[i - UIP_LLH_LEN - 40 ];
+ }
+ p ->payload = pdata;
+ p->len = uip_len;
+ inp->linkoutput(inp,p);
+ rt_free(pdata);
+ return 1;
+ }
+ else
+ {
+ pbuf_free(p);
+ return 0;
+ }
} \ No newline at end of file
diff --git a/components/net/uip/uip/psock.c b/components/net/uip/uip/psock.c
index 9085102d30..b6b3bff699 100644
--- a/components/net/uip/uip/psock.c
+++ b/components/net/uip/uip/psock.c
@@ -1,338 +1,338 @@
-/*
- * Copyright (c) 2004, 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 uIP TCP/IP stack
- *
- * Author: Adam Dunkels <[email protected]>
- *
- * $Id: psock.c,v 1.2 2006/06/12 08:00:30 adam Exp $
- */
-
-#include <stdio.h>
-#include <string.h>
-
-#include "uipopt.h"
-#include "psock.h"
-#include "uip.h"
-
-#define STATE_NONE 0
-#define STATE_ACKED 1
-#define STATE_READ 2
-#define STATE_BLOCKED_NEWDATA 3
-#define STATE_BLOCKED_CLOSE 4
-#define STATE_BLOCKED_SEND 5
-#define STATE_DATA_SENT 6
-
-/*
- * Return value of the buffering functions that indicates that a
- * buffer was not filled by incoming data.
- *
- */
-#define BUF_NOT_FULL 0
-#define BUF_NOT_FOUND 0
-
-/*
- * Return value of the buffering functions that indicates that a
- * buffer was completely filled by incoming data.
- *
- */
-#define BUF_FULL 1
-
-/*
- * Return value of the buffering functions that indicates that an
- * end-marker byte was found.
- *
- */
-#define BUF_FOUND 2
-
-/*---------------------------------------------------------------------------*/
-static void
-buf_setup(struct psock_buf *buf,
- u8_t *bufptr, u16_t bufsize)
-{
- buf->ptr = bufptr;
- buf->left = bufsize;
-}
-/*---------------------------------------------------------------------------*/
-static u8_t
-buf_bufdata(struct psock_buf *buf, u16_t len,
- u8_t **dataptr, u16_t *datalen)
-{
- if(*datalen < buf->left) {
- memcpy(buf->ptr, *dataptr, *datalen);
- buf->ptr += *datalen;
- buf->left -= *datalen;
- *dataptr += *datalen;
- *datalen = 0;
- return BUF_NOT_FULL;
- } else if(*datalen == buf->left) {
- memcpy(buf->ptr, *dataptr, *datalen);
- buf->ptr += *datalen;
- buf->left = 0;
- *dataptr += *datalen;
- *datalen = 0;
- return BUF_FULL;
- } else {
- memcpy(buf->ptr, *dataptr, buf->left);
- buf->ptr += buf->left;
- *datalen -= buf->left;
- *dataptr += buf->left;
- buf->left = 0;
- return BUF_FULL;
- }
-}
-/*---------------------------------------------------------------------------*/
-static u8_t
-buf_bufto(register struct psock_buf *buf, u8_t endmarker,
- register u8_t **dataptr, register u16_t *datalen)
-{
- u8_t c;
- while(buf->left > 0 && *datalen > 0) {
- c = *buf->ptr = **dataptr;
- ++*dataptr;
- ++buf->ptr;
- --*datalen;
- --buf->left;
-
- if(c == endmarker) {
- return BUF_FOUND;
- }
- }
-
- if(*datalen == 0) {
- return BUF_NOT_FOUND;
- }
-
- while(*datalen > 0) {
- c = **dataptr;
- --*datalen;
- ++*dataptr;
-
- if(c == endmarker) {
- return BUF_FOUND | BUF_FULL;
- }
- }
-
- return BUF_FULL;
-}
-/*---------------------------------------------------------------------------*/
-static char
-send_data(register struct psock *s)
-{
- if(s->state != STATE_DATA_SENT || uip_rexmit()) {
- if(s->sendlen > uip_mss()) {
- uip_send(s->sendptr, uip_mss());
- } else {
- uip_send(s->sendptr, s->sendlen);
- }
- s->state = STATE_DATA_SENT;
- return 1;
- }
- return 0;
-}
-/*---------------------------------------------------------------------------*/
-static char
-data_acked(register struct psock *s)
-{
- if(s->state == STATE_DATA_SENT && uip_acked()) {
- if(s->sendlen > uip_mss()) {
- s->sendlen -= uip_mss();
- s->sendptr += uip_mss();
- } else {
- s->sendptr += s->sendlen;
- s->sendlen = 0;
- }
- s->state = STATE_ACKED;
- return 1;
- }
- return 0;
-}
-/*---------------------------------------------------------------------------*/
-PT_THREAD(psock_send(register struct psock *s, const char *buf,
- unsigned int len))
-{
- PT_BEGIN(&s->psockpt);
-
- /* If there is no data to send, we exit immediately. */
- if(len == 0) {
- PT_EXIT(&s->psockpt);
- }
-
- /* Save the length of and a pointer to the data that is to be
- sent. */
- s->sendptr = buf;
- s->sendlen = len;
-
- s->state = STATE_NONE;
-
- /* We loop here until all data is sent. The s->sendlen variable is
- updated by the data_sent() function. */
- while(s->sendlen > 0) {
-
- /*
- * The condition for this PT_WAIT_UNTIL is a little tricky: the
- * protothread will wait here until all data has been acknowledged
- * (data_acked() returns true) and until all data has been sent
- * (send_data() returns true). The two functions data_acked() and
- * send_data() must be called in succession to ensure that all
- * data is sent. Therefore the & operator is used instead of the
- * && operator, which would cause only the data_acked() function
- * to be called when it returns false.
- */
- PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s));
- }
-
- s->state = STATE_NONE;
-
- PT_END(&s->psockpt);
-}
-/*---------------------------------------------------------------------------*/
-PT_THREAD(psock_generator_send(register struct psock *s,
- unsigned short (*generate)(void *), void *arg))
-{
- PT_BEGIN(&s->psockpt);
-
- /* Ensure that there is a generator function to call. */
- if(generate == NULL) {
- PT_EXIT(&s->psockpt);
- }
-
- /* Call the generator function to generate the data in the
- uip_appdata buffer. */
- s->sendlen = generate(arg);
- s->sendptr =(const u8_t*) uip_appdata;
-
- s->state = STATE_NONE;
- do {
- /* Call the generator function again if we are called to perform a
- retransmission. */
- if(uip_rexmit()) {
- generate(arg);
- }
- /* Wait until all data is sent and acknowledged. */
- PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s));
- } while(s->sendlen > 0);
-
- s->state = STATE_NONE;
-
- PT_END(&s->psockpt);
-}
-/*---------------------------------------------------------------------------*/
-u16_t
-psock_datalen(struct psock *psock)
-{
- return psock->bufsize - psock->buf.left;
-}
-/*---------------------------------------------------------------------------*/
-char
-psock_newdata(struct psock *s)
-{
- if(s->readlen > 0) {
- /* There is data in the uip_appdata buffer that has not yet been
- read with the PSOCK_READ functions. */
- return 1;
- } else if(s->state == STATE_READ) {
- /* All data in uip_appdata buffer already consumed. */
- s->state = STATE_BLOCKED_NEWDATA;
- return 0;
- } else if(uip_newdata()) {
- /* There is new data that has not been consumed. */
- return 1;
- } else {
- /* There is no new data. */
- return 0;
- }
-}
-/*---------------------------------------------------------------------------*/
-PT_THREAD(psock_readto(register struct psock *psock, unsigned char c))
-{
- PT_BEGIN(&psock->psockpt);
-
- buf_setup(&psock->buf, psock->bufptr, psock->bufsize);
-
- /* XXX: Should add buf_checkmarker() before do{} loop, if
- incoming data has been handled while waiting for a write. */
-
- do {
- if(psock->readlen == 0) {
- PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock));
- psock->state = STATE_READ;
- psock->readptr = (u8_t *)uip_appdata;
- psock->readlen = uip_datalen();
- }
- } while((buf_bufto(&psock->buf, c,
- &psock->readptr,
- &psock->readlen) & BUF_FOUND) == 0);
-
- if(psock_datalen(psock) == 0) {
- psock->state = STATE_NONE;
- PT_RESTART(&psock->psockpt);
- }
- PT_END(&psock->psockpt);
-}
-/*---------------------------------------------------------------------------*/
-PT_THREAD(psock_readbuf(register struct psock *psock))
-{
- PT_BEGIN(&psock->psockpt);
-
- buf_setup(&psock->buf, psock->bufptr, psock->bufsize);
-
- /* XXX: Should add buf_checkmarker() before do{} loop, if
- incoming data has been handled while waiting for a write. */
-
- do {
- if(psock->readlen == 0) {
- PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock));
- printf("Waited for newdata\n");
- psock->state = STATE_READ;
- psock->readptr = (u8_t *)uip_appdata;
- psock->readlen = uip_datalen();
- }
- } while(buf_bufdata(&psock->buf, psock->bufsize,
- &psock->readptr,
- &psock->readlen) != BUF_FULL);
-
- if(psock_datalen(psock) == 0) {
- psock->state = STATE_NONE;
- PT_RESTART(&psock->psockpt);
- }
- PT_END(&psock->psockpt);
-}
-/*---------------------------------------------------------------------------*/
-void
-psock_init(register struct psock *psock, char *buffer, unsigned int buffersize)
-{
- psock->state = STATE_NONE;
- psock->readlen = 0;
- psock->bufptr = buffer;
- psock->bufsize = buffersize;
- buf_setup(&psock->buf, buffer, buffersize);
- PT_INIT(&psock->pt);
- PT_INIT(&psock->psockpt);
-}
-/*---------------------------------------------------------------------------*/
+/*
+ * Copyright (c) 2004, 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 uIP TCP/IP stack
+ *
+ * Author: Adam Dunkels <[email protected]>
+ *
+ * $Id: psock.c,v 1.2 2006/06/12 08:00:30 adam Exp $
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "uipopt.h"
+#include "psock.h"
+#include "uip.h"
+
+#define STATE_NONE 0
+#define STATE_ACKED 1
+#define STATE_READ 2
+#define STATE_BLOCKED_NEWDATA 3
+#define STATE_BLOCKED_CLOSE 4
+#define STATE_BLOCKED_SEND 5
+#define STATE_DATA_SENT 6
+
+/*
+ * Return value of the buffering functions that indicates that a
+ * buffer was not filled by incoming data.
+ *
+ */
+#define BUF_NOT_FULL 0
+#define BUF_NOT_FOUND 0
+
+/*
+ * Return value of the buffering functions that indicates that a
+ * buffer was completely filled by incoming data.
+ *
+ */
+#define BUF_FULL 1
+
+/*
+ * Return value of the buffering functions that indicates that an
+ * end-marker byte was found.
+ *
+ */
+#define BUF_FOUND 2
+
+/*---------------------------------------------------------------------------*/
+static void
+buf_setup(struct psock_buf *buf,
+ u8_t *bufptr, u16_t bufsize)
+{
+ buf->ptr = bufptr;
+ buf->left = bufsize;
+}
+/*---------------------------------------------------------------------------*/
+static u8_t
+buf_bufdata(struct psock_buf *buf, u16_t len,
+ u8_t **dataptr, u16_t *datalen)
+{
+ if(*datalen < buf->left) {
+ memcpy(buf->ptr, *dataptr, *datalen);
+ buf->ptr += *datalen;
+ buf->left -= *datalen;
+ *dataptr += *datalen;
+ *datalen = 0;
+ return BUF_NOT_FULL;
+ } else if(*datalen == buf->left) {
+ memcpy(buf->ptr, *dataptr, *datalen);
+ buf->ptr += *datalen;
+ buf->left = 0;
+ *dataptr += *datalen;
+ *datalen = 0;
+ return BUF_FULL;
+ } else {
+ memcpy(buf->ptr, *dataptr, buf->left);
+ buf->ptr += buf->left;
+ *datalen -= buf->left;
+ *dataptr += buf->left;
+ buf->left = 0;
+ return BUF_FULL;
+ }
+}
+/*---------------------------------------------------------------------------*/
+static u8_t
+buf_bufto(register struct psock_buf *buf, u8_t endmarker,
+ register u8_t **dataptr, register u16_t *datalen)
+{
+ u8_t c;
+ while(buf->left > 0 && *datalen > 0) {
+ c = *buf->ptr = **dataptr;
+ ++*dataptr;
+ ++buf->ptr;
+ --*datalen;
+ --buf->left;
+
+ if(c == endmarker) {
+ return BUF_FOUND;
+ }
+ }
+
+ if(*datalen == 0) {
+ return BUF_NOT_FOUND;
+ }
+
+ while(*datalen > 0) {
+ c = **dataptr;
+ --*datalen;
+ ++*dataptr;
+
+ if(c == endmarker) {
+ return BUF_FOUND | BUF_FULL;
+ }
+ }
+
+ return BUF_FULL;
+}
+/*---------------------------------------------------------------------------*/
+static char
+send_data(register struct psock *s)
+{
+ if(s->state != STATE_DATA_SENT || uip_rexmit()) {
+ if(s->sendlen > uip_mss()) {
+ uip_send(s->sendptr, uip_mss());
+ } else {
+ uip_send(s->sendptr, s->sendlen);
+ }
+ s->state = STATE_DATA_SENT;
+ return 1;
+ }
+ return 0;
+}
+/*---------------------------------------------------------------------------*/
+static char
+data_acked(register struct psock *s)
+{
+ if(s->state == STATE_DATA_SENT && uip_acked()) {
+ if(s->sendlen > uip_mss()) {
+ s->sendlen -= uip_mss();
+ s->sendptr += uip_mss();
+ } else {
+ s->sendptr += s->sendlen;
+ s->sendlen = 0;
+ }
+ s->state = STATE_ACKED;
+ return 1;
+ }
+ return 0;
+}
+/*---------------------------------------------------------------------------*/
+PT_THREAD(psock_send(register struct psock *s, const char *buf,
+ unsigned int len))
+{
+ PT_BEGIN(&s->psockpt);
+
+ /* If there is no data to send, we exit immediately. */
+ if(len == 0) {
+ PT_EXIT(&s->psockpt);
+ }
+
+ /* Save the length of and a pointer to the data that is to be
+ sent. */
+ s->sendptr = buf;
+ s->sendlen = len;
+
+ s->state = STATE_NONE;
+
+ /* We loop here until all data is sent. The s->sendlen variable is
+ updated by the data_sent() function. */
+ while(s->sendlen > 0) {
+
+ /*
+ * The condition for this PT_WAIT_UNTIL is a little tricky: the
+ * protothread will wait here until all data has been acknowledged
+ * (data_acked() returns true) and until all data has been sent
+ * (send_data() returns true). The two functions data_acked() and
+ * send_data() must be called in succession to ensure that all
+ * data is sent. Therefore the & operator is used instead of the
+ * && operator, which would cause only the data_acked() function
+ * to be called when it returns false.
+ */
+ PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s));
+ }
+
+ s->state = STATE_NONE;
+
+ PT_END(&s->psockpt);
+}
+/*---------------------------------------------------------------------------*/
+PT_THREAD(psock_generator_send(register struct psock *s,
+ unsigned short (*generate)(void *), void *arg))
+{
+ PT_BEGIN(&s->psockpt);
+
+ /* Ensure that there is a generator function to call. */
+ if(generate == NULL) {
+ PT_EXIT(&s->psockpt);
+ }
+
+ /* Call the generator function to generate the data in the
+ uip_appdata buffer. */
+ s->sendlen = generate(arg);
+ s->sendptr =(const u8_t*) uip_appdata;
+
+ s->state = STATE_NONE;
+ do {
+ /* Call the generator function again if we are called to perform a
+ retransmission. */
+ if(uip_rexmit()) {
+ generate(arg);
+ }
+ /* Wait until all data is sent and acknowledged. */
+ PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s));
+ } while(s->sendlen > 0);
+
+ s->state = STATE_NONE;
+
+ PT_END(&s->psockpt);
+}
+/*---------------------------------------------------------------------------*/
+u16_t
+psock_datalen(struct psock *psock)
+{
+ return psock->bufsize - psock->buf.left;
+}
+/*---------------------------------------------------------------------------*/
+char
+psock_newdata(struct psock *s)
+{
+ if(s->readlen > 0) {
+ /* There is data in the uip_appdata buffer that has not yet been
+ read with the PSOCK_READ functions. */
+ return 1;
+ } else if(s->state == STATE_READ) {
+ /* All data in uip_appdata buffer already consumed. */
+ s->state = STATE_BLOCKED_NEWDATA;
+ return 0;
+ } else if(uip_newdata()) {
+ /* There is new data that has not been consumed. */
+ return 1;
+ } else {
+ /* There is no new data. */
+ return 0;
+ }
+}
+/*---------------------------------------------------------------------------*/
+PT_THREAD(psock_readto(register struct psock *psock, unsigned char c))
+{
+ PT_BEGIN(&psock->psockpt);
+
+ buf_setup(&psock->buf, psock->bufptr, psock->bufsize);
+
+ /* XXX: Should add buf_checkmarker() before do{} loop, if
+ incoming data has been handled while waiting for a write. */
+
+ do {
+ if(psock->readlen == 0) {
+ PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock));
+ psock->state = STATE_READ;
+ psock->readptr = (u8_t *)uip_appdata;
+ psock->readlen = uip_datalen();
+ }
+ } while((buf_bufto(&psock->buf, c,
+ &psock->readptr,
+ &psock->readlen) & BUF_FOUND) == 0);
+
+ if(psock_datalen(psock) == 0) {
+ psock->state = STATE_NONE;
+ PT_RESTART(&psock->psockpt);
+ }
+ PT_END(&psock->psockpt);
+}
+/*---------------------------------------------------------------------------*/
+PT_THREAD(psock_readbuf(register struct psock *psock))
+{
+ PT_BEGIN(&psock->psockpt);
+
+ buf_setup(&psock->buf, psock->bufptr, psock->bufsize);
+
+ /* XXX: Should add buf_checkmarker() before do{} loop, if
+ incoming data has been handled while waiting for a write. */
+
+ do {
+ if(psock->readlen == 0) {
+ PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock));
+ printf("Waited for newdata\n");
+ psock->state = STATE_READ;
+ psock->readptr = (u8_t *)uip_appdata;
+ psock->readlen = uip_datalen();
+ }
+ } while(buf_bufdata(&psock->buf, psock->bufsize,
+ &psock->readptr,
+ &psock->readlen) != BUF_FULL);
+
+ if(psock_datalen(psock) == 0) {
+ psock->state = STATE_NONE;
+ PT_RESTART(&psock->psockpt);
+ }
+ PT_END(&psock->psockpt);
+}
+/*---------------------------------------------------------------------------*/
+void
+psock_init(register struct psock *psock, char *buffer, unsigned int buffersize)
+{
+ psock->state = STATE_NONE;
+ psock->readlen = 0;
+ psock->bufptr = buffer;
+ psock->bufsize = buffersize;
+ buf_setup(&psock->buf, buffer, buffersize);
+ PT_INIT(&psock->pt);
+ PT_INIT(&psock->psockpt);
+}
+/*---------------------------------------------------------------------------*/
diff --git a/components/net/uip/uip/uip.c b/components/net/uip/uip/uip.c
index d315744e89..d81935138f 100644
--- a/components/net/uip/uip/uip.c
+++ b/components/net/uip/uip/uip.c
@@ -1,1903 +1,1903 @@
-#ifdef RT_UIP_DBUG_RPINTF
-#define DEBUG_PRINTF(...) rt_kprintf(__VA_ARGS__)
-#else
-#define DEBUG_PRINTF(...) /*printf(__VA_ARGS__)*/
-#endif
-
-
-/**
- * \defgroup uip The uIP TCP/IP stack
- * @{
- *
- * uIP is an implementation of the TCP/IP protocol stack intended for
- * small 8-bit and 16-bit microcontrollers.
- *
- * uIP provides the necessary protocols for Internet communication,
- * with a very small code footprint and RAM requirements - the uIP
- * code size is on the order of a few kilobytes and RAM usage is on
- * the order of a few hundred bytes.
- */
-
-/**
- * \file
- * The uIP TCP/IP stack code.
- * \author Adam Dunkels <[email protected]>
- */
-
-/*
- * Copyright (c) 2001-2003, Adam Dunkels.
- * 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 uIP TCP/IP stack.
- *
- * $Id: uip.c,v 1.65 2006/06/11 21:46:39 adam Exp $
- *
- */
-
-/*
- * uIP is a small implementation of the IP, UDP and TCP protocols (as
- * well as some basic ICMP stuff). The implementation couples the IP,
- * UDP, TCP and the application layers very tightly. To keep the size
- * of the compiled code down, this code frequently uses the goto
- * statement. While it would be possible to break the uip_process()
- * function into many smaller functions, this would increase the code
- * size because of the overhead of parameter passing and the fact that
- * the optimier would not be as efficient.
- *
- * The principle is that we have a small buffer, called the uip_buf,
- * in which the device driver puts an incoming packet. The TCP/IP
- * stack parses the headers in the packet, and calls the
- * application. If the remote host has sent data to the application,
- * this data is present in the uip_buf and the application read the
- * data from there. It is up to the application to put this data into
- * a byte stream if needed. The application will not be fed with data
- * that is out of sequence.
- *
- * If the application whishes to send data to the peer, it should put
- * its data into the uip_buf. The uip_appdata pointer points to the
- * first available byte. The TCP/IP stack will calculate the
- * checksums, and fill in the necessary header fields and finally send
- * the packet back to the peer.
-*/
-
-#include "uip.h"
-#include "uipopt.h"
-#include "uip_arch.h"
-
-#if UIP_CONF_IPV6
-#include "uip-neighbor.h"
-#endif /* UIP_CONF_IPV6 */
-
-#include <string.h>
-
-/*---------------------------------------------------------------------------*/
-/* Variable definitions. */
-
-
-/* The IP address of this host. If it is defined to be fixed (by
- setting UIP_FIXEDADDR to 1 in uipopt.h), the address is set
- here. Otherwise, the address */
-#if UIP_FIXEDADDR > 0
-const uip_ipaddr_t uip_hostaddr =
- {HTONS((UIP_IPADDR0 << 8) | UIP_IPADDR1),
- HTONS((UIP_IPADDR2 << 8) | UIP_IPADDR3)};
-const uip_ipaddr_t uip_draddr =
- {HTONS((UIP_DRIPADDR0 << 8) | UIP_DRIPADDR1),
- HTONS((UIP_DRIPADDR2 << 8) | UIP_DRIPADDR3)};
-const uip_ipaddr_t uip_netmask =
- {HTONS((UIP_NETMASK0 << 8) | UIP_NETMASK1),
- HTONS((UIP_NETMASK2 << 8) | UIP_NETMASK3)};
-#else
-uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask;
-#endif /* UIP_FIXEDADDR */
-
-static const uip_ipaddr_t all_ones_addr =
-#if UIP_CONF_IPV6
- {0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff};
-#else /* UIP_CONF_IPV6 */
- {0xffff,0xffff};
-#endif /* UIP_CONF_IPV6 */
-static const uip_ipaddr_t all_zeroes_addr =
-#if UIP_CONF_IPV6
- {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000};
-#else /* UIP_CONF_IPV6 */
- {0x0000,0x0000};
-#endif /* UIP_CONF_IPV6 */
-
-
-#if UIP_FIXEDETHADDR
-const struct uip_eth_addr uip_ethaddr = {{UIP_ETHADDR0,
- UIP_ETHADDR1,
- UIP_ETHADDR2,
- UIP_ETHADDR3,
- UIP_ETHADDR4,
- UIP_ETHADDR5}};
-#else
-struct uip_eth_addr uip_ethaddr = {{0,0x33,0x44,0x55,0x66,0x77}};
-#endif
-
-#ifndef UIP_CONF_EXTERNAL_BUFFER
-u8_t uip_buf[UIP_BUFSIZE + 2]; /* The packet buffer that contains
- incoming packets. */
-#endif /* UIP_CONF_EXTERNAL_BUFFER */
-
-volatile u8_t *uip_appdata; /* The uip_appdata pointer points to
- application data. */
-volatile u8_t *uip_sappdata; /* The uip_appdata pointer points to
- the application data which is to
- be sent. */
-#if UIP_URGDATA > 0
-void *uip_urgdata; /* The uip_urgdata pointer points to
- urgent data (out-of-band data), if
- present. */
-u16_t uip_urglen, uip_surglen;
-#endif /* UIP_URGDATA > 0 */
-
-u16_t uip_len, uip_slen;
- /* The uip_len is either 8 or 16 bits,
- depending on the maximum packet
- size. */
-
-u8_t uip_flags; /* The uip_flags variable is used for
- communication between the TCP/IP stack
- and the application program. */
-struct uip_conn *uip_conn; /* uip_conn always points to the current
- connection. */
-
-struct uip_conn uip_conns[UIP_CONNS];
- /* The uip_conns array holds all TCP
- connections. */
-u16_t uip_listenports[UIP_LISTENPORTS];
- /* The uip_listenports list all currently
- listning ports. */
-#if UIP_UDP
-struct uip_udp_conn *uip_udp_conn;
-struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
-#endif /* UIP_UDP */
-
-static u16_t ipid; /* Ths ipid variable is an increasing
- number that is used for the IP ID
- field. */
-
-void uip_setipid(u16_t id) { ipid = id; }
-
-static u8_t iss[4]; /* The iss variable is used for the TCP
- initial sequence number. */
-
-#if UIP_ACTIVE_OPEN
-static u16_t lastport; /* Keeps track of the last port used for
- a new connection. */
-#endif /* UIP_ACTIVE_OPEN */
-
-/* Temporary variables. */
-u8_t uip_acc32[4];
-static u8_t c, opt;
-static u16_t tmp16;
-
-/* Structures and definitions. */
-#define TCP_FIN 0x01
-#define TCP_SYN 0x02
-#define TCP_RST 0x04
-#define TCP_PSH 0x08
-#define TCP_ACK 0x10
-#define TCP_URG 0x20
-#define TCP_CTL 0x3f
-
-#define TCP_OPT_END 0 /* End of TCP options list */
-#define TCP_OPT_NOOP 1 /* "No-operation" TCP option */
-#define TCP_OPT_MSS 2 /* Maximum segment size TCP option */
-
-#define TCP_OPT_MSS_LEN 4 /* Length of TCP MSS option. */
-
-#define ICMP_ECHO_REPLY 0
-#define ICMP_ECHO 8
-
-#define ICMP6_ECHO_REPLY 129
-#define ICMP6_ECHO 128
-#define ICMP6_NEIGHBOR_SOLICITATION 135
-#define ICMP6_NEIGHBOR_ADVERTISEMENT 136
-
-#define ICMP6_FLAG_S (1 << 6)
-
-#define ICMP6_OPTION_SOURCE_LINK_ADDRESS 1
-#define ICMP6_OPTION_TARGET_LINK_ADDRESS 2
-
-
-/* Macros. */
-#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
-#define FBUF ((struct uip_tcpip_hdr *)&uip_reassbuf[0])
-#define ICMPBUF ((struct uip_icmpip_hdr *)&uip_buf[UIP_LLH_LEN])
-#define UDPBUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
-
-
-#if UIP_STATISTICS == 1
-struct uip_stats uip_stat;
-#define UIP_STAT(s) s
-#else
-#define UIP_STAT(s)
-#endif /* UIP_STATISTICS == 1 */
-
-#if UIP_LOGGING == 1
-#include <stdio.h>
-void uip_log(char *msg);
-#define UIP_LOG(m) uip_log(m)
-#else
-#define UIP_LOG(m)
-#endif /* UIP_LOGGING == 1 */
-
-#if ! UIP_ARCH_ADD32
-void
-uip_add32(u8_t *op32, u16_t op16)
-{
- uip_acc32[3] = op32[3] + (op16 & 0xff);
- uip_acc32[2] = op32[2] + (op16 >> 8);
- uip_acc32[1] = op32[1];
- uip_acc32[0] = op32[0];
-
- if(uip_acc32[2] < (op16 >> 8)) {
- ++uip_acc32[1];
- if(uip_acc32[1] == 0) {
- ++uip_acc32[0];
- }
- }
-
-
- if(uip_acc32[3] < (op16 & 0xff)) {
- ++uip_acc32[2];
- if(uip_acc32[2] == 0) {
- ++uip_acc32[1];
- if(uip_acc32[1] == 0) {
- ++uip_acc32[0];
- }
- }
- }
-}
-
-#endif /* UIP_ARCH_ADD32 */
-
-#if ! UIP_ARCH_CHKSUM
-/*---------------------------------------------------------------------------*/
-static u16_t
-chksum(u16_t sum, const u8_t *data, u16_t len)
-{
- u16_t t;
- const u8_t *dataptr;
- const u8_t *last_byte;
-
- dataptr = data;
- last_byte = data + len - 1;
-
- while(dataptr < last_byte) { /* At least two more bytes */
- t = (dataptr[0] << 8) + dataptr[1];
- sum += t;
- if(sum < t) {
- sum++; /* carry */
- }
- dataptr += 2;
- }
-
- if(dataptr == last_byte) {
- t = (dataptr[0] << 8) + 0;
- sum += t;
- if(sum < t) {
- sum++; /* carry */
- }
- }
-
- /* Return sum in host byte order. */
- return sum;
-}
-/*---------------------------------------------------------------------------*/
-u16_t
-uip_chksum(u16_t *data, u16_t len)
-{
- return uip_htons(chksum(0, (u8_t *)data, len));
-}
-/*---------------------------------------------------------------------------*/
-#ifndef UIP_ARCH_IPCHKSUM
-u16_t
-uip_ipchksum(void)
-{
- u16_t sum;
-
- sum = chksum(0, &uip_buf[UIP_LLH_LEN], UIP_IPH_LEN);
- DEBUG_PRINTF("uip_ipchksum: sum 0x%04x\n", sum);
- return (sum == 0) ? 0xffff : uip_htons(sum);
-}
-#endif
-/*---------------------------------------------------------------------------*/
-static u16_t
-upper_layer_chksum(u8_t proto)
-{
- u16_t upper_layer_len;
- u16_t sum;
-
-#if UIP_CONF_IPV6
- upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]);
-#else /* UIP_CONF_IPV6 */
- upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - UIP_IPH_LEN;
-#endif /* UIP_CONF_IPV6 */
-
- /* First sum pseudoheader. */
-
- /* IP protocol and length fields. This addition cannot carry. */
- sum = upper_layer_len + proto;
- /* Sum IP source and destination addresses. */
- sum = chksum(sum, (u8_t *)&BUF->srcipaddr[0], 2 * sizeof(uip_ipaddr_t));
-
- /* Sum TCP header and data. */
- sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN],
- upper_layer_len);
-
- return (sum == 0) ? 0xffff : uip_htons(sum);
-}
-/*---------------------------------------------------------------------------*/
-#if UIP_CONF_IPV6
-u16_t
-uip_icmp6chksum(void)
-{
- return upper_layer_chksum(UIP_PROTO_ICMP6);
-
-}
-#endif /* UIP_CONF_IPV6 */
-/*---------------------------------------------------------------------------*/
-u16_t
-uip_tcpchksum(void)
-{
- return upper_layer_chksum(UIP_PROTO_TCP);
-}
-/*---------------------------------------------------------------------------*/
-#if UIP_UDP_CHECKSUMS
-u16_t
-uip_udpchksum(void)
-{
- //return 0;
- return upper_layer_chksum(UIP_PROTO_UDP);
-}
-#endif /* UIP_UDP_CHECKSUMS */
-#endif /* UIP_ARCH_CHKSUM */
-/*---------------------------------------------------------------------------*/
-void
-uip_init(void)
-{
- for(c = 0; c < UIP_LISTENPORTS; ++c) {
- uip_listenports[c] = 0;
- }
- for(c = 0; c < UIP_CONNS; ++c) {
- uip_conns[c].tcpstateflags = UIP_CLOSED;
- }
-#if UIP_ACTIVE_OPEN
- lastport = 1024;
-#endif /* UIP_ACTIVE_OPEN */
-
-#if UIP_UDP
- for(c = 0; c < UIP_UDP_CONNS; ++c) {
- uip_udp_conns[c].lport = 0;
- }
-#endif /* UIP_UDP */
-
-
- /* IPv4 initialization. */
-#if UIP_FIXEDADDR == 0
- /* uip_hostaddr[0] = uip_hostaddr[1] = 0;*/
-#endif /* UIP_FIXEDADDR */
-
-}
-/*---------------------------------------------------------------------------*/
-#if UIP_ACTIVE_OPEN
-struct uip_conn *
-uip_connect(uip_ipaddr_t *ripaddr, u16_t rport)
-{
- register struct uip_conn *conn, *cconn;
-
- /* Find an unused local port. */
- again:
- ++lastport;
-
- if(lastport >= 32000) {
- lastport = 4096;
- }
-
- /* Check if this port is already in use, and if so try to find
- another one. */
- for(c = 0; c < UIP_CONNS; ++c) {
- conn = &uip_conns[c];
- if(conn->tcpstateflags != UIP_CLOSED &&
- conn->lport == uip_htons(lastport)) {
- goto again;
- }
- }
-
- conn = 0;
- for(c = 0; c < UIP_CONNS; ++c) {
- cconn = &uip_conns[c];
- if(cconn->tcpstateflags == UIP_CLOSED) {
- conn = cconn;
- break;
- }
- if(cconn->tcpstateflags == UIP_TIME_WAIT) {
- if(conn == 0 ||
- cconn->timer > conn->timer) {
- conn = cconn;
- }
- }
- }
-
- if(conn == 0) {
- return 0;
- }
-
- conn->tcpstateflags = UIP_SYN_SENT;
-
- conn->snd_nxt[0] = iss[0];
- conn->snd_nxt[1] = iss[1];
- conn->snd_nxt[2] = iss[2];
- conn->snd_nxt[3] = iss[3];
-
- conn->initialmss = conn->mss = UIP_TCP_MSS;
-
- conn->len = 1; /* TCP length of the SYN is one. */
- conn->nrtx = 0;
- conn->timer = 1; /* Send the SYN next time around. */
- conn->rto = UIP_RTO;
- conn->sa = 0;
- conn->sv = 16; /* Initial value of the RTT variance. */
- conn->lport = uip_htons(lastport);
- conn->rport = rport;
- uip_ipaddr_copy(&conn->ripaddr, ripaddr);
-
- return conn;
-}
-#endif /* UIP_ACTIVE_OPEN */
-/*---------------------------------------------------------------------------*/
-#if UIP_UDP
-struct uip_udp_conn *
-uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport)
-{
- register struct uip_udp_conn *conn;
-
- /* Find an unused local port. */
- again:
- ++lastport;
-
- if(lastport >= 32000) {
- lastport = 4096;
- }
-
- for(c = 0; c < UIP_UDP_CONNS; ++c) {
- if(uip_udp_conns[c].lport == uip_htons(lastport)) {
- goto again;
- }
- }
-
-
- conn = 0;
- for(c = 0; c < UIP_UDP_CONNS; ++c) {
- if(uip_udp_conns[c].lport == 0) {
- conn = &uip_udp_conns[c];
- break;
- }
- }
-
- if(conn == 0) {
- return 0;
- }
-
- conn->lport = HTONS(lastport);
- conn->rport = rport;
- if(ripaddr == NULL) {
- memset(conn->ripaddr, 0, sizeof(uip_ipaddr_t));
- } else {
- uip_ipaddr_copy(&conn->ripaddr, ripaddr);
- }
- conn->ttl = UIP_TTL;
-
- return conn;
-}
-#endif /* UIP_UDP */
-/*---------------------------------------------------------------------------*/
-void
-uip_unlisten(u16_t port)
-{
- for(c = 0; c < UIP_LISTENPORTS; ++c) {
- if(uip_listenports[c] == port) {
- uip_listenports[c] = 0;
- return;
- }
- }
-}
-/*---------------------------------------------------------------------------*/
-void
-uip_listen(u16_t port)
-{
- for(c = 0; c < UIP_LISTENPORTS; ++c) {
- if(uip_listenports[c] == 0) {
- uip_listenports[c] = port;
- return;
- }
- }
-}
-/*---------------------------------------------------------------------------*/
-/* XXX: IP fragment reassembly: not well-tested. */
-
-#if UIP_REASSEMBLY && !UIP_CONF_IPV6
-#define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN)
-static u8_t uip_reassbuf[UIP_REASS_BUFSIZE];
-static u8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)];
-static const u8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f,
- 0x0f, 0x07, 0x03, 0x01};
-static u16_t uip_reasslen;
-static u8_t uip_reassflags;
-#define UIP_REASS_FLAG_LASTFRAG 0x01
-static u8_t uip_reasstmr;
-
-#define IP_MF 0x20
-
-static u8_t
-uip_reass(void)
-{
- u16_t offset, len;
- u16_t i;
-
- /* If ip_reasstmr is zero, no packet is present in the buffer, so we
- write the IP header of the fragment into the reassembly
- buffer. The timer is updated with the maximum age. */
- if(uip_reasstmr == 0) {
- memcpy(uip_reassbuf, &BUF->vhl, UIP_IPH_LEN);
- uip_reasstmr = UIP_REASS_MAXAGE;
- uip_reassflags = 0;
- /* Clear the bitmap. */
- memset(uip_reassbitmap, 0, sizeof(uip_reassbitmap));
- }
-
- /* Check if the incoming fragment matches the one currently present
- in the reasembly buffer. If so, we proceed with copying the
- fragment into the buffer. */
- if(BUF->srcipaddr[0] == FBUF->srcipaddr[0] &&
- BUF->srcipaddr[1] == FBUF->srcipaddr[1] &&
- BUF->destipaddr[0] == FBUF->destipaddr[0] &&
- BUF->destipaddr[1] == FBUF->destipaddr[1] &&
- BUF->ipid[0] == FBUF->ipid[0] &&
- BUF->ipid[1] == FBUF->ipid[1]) {
-
- len = (BUF->len[0] << 8) + BUF->len[1] - (BUF->vhl & 0x0f) * 4;
- offset = (((BUF->ipoffset[0] & 0x3f) << 8) + BUF->ipoffset[1]) * 8;
-
- /* If the offset or the offset + fragment length overflows the
- reassembly buffer, we discard the entire packet. */
- if(offset > UIP_REASS_BUFSIZE ||
- offset + len > UIP_REASS_BUFSIZE) {
- uip_reasstmr = 0;
- goto nullreturn;
- }
-
- /* Copy the fragment into the reassembly buffer, at the right
- offset. */
- memcpy(&uip_reassbuf[UIP_IPH_LEN + offset],
- (char *)BUF + (int)((BUF->vhl & 0x0f) * 4),
- len);
-
- /* Update the bitmap. */
- if(offset / (8 * 8) == (offset + len) / (8 * 8)) {
- /* If the two endpoints are in the same byte, we only update
- that byte. */
-
- uip_reassbitmap[offset / (8 * 8)] |=
- bitmap_bits[(offset / 8 ) & 7] &
- ~bitmap_bits[((offset + len) / 8 ) & 7];
- } else {
- /* If the two endpoints are in different bytes, we update the
- bytes in the endpoints and fill the stuff inbetween with
- 0xff. */
- uip_reassbitmap[offset / (8 * 8)] |=
- bitmap_bits[(offset / 8 ) & 7];
- for(i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) {
- uip_reassbitmap[i] = 0xff;
- }
- uip_reassbitmap[(offset + len) / (8 * 8)] |=
- ~bitmap_bits[((offset + len) / 8 ) & 7];
- }
-
- /* If this fragment has the More Fragments flag set to zero, we
- know that this is the last fragment, so we can calculate the
- size of the entire packet. We also set the
- IP_REASS_FLAG_LASTFRAG flag to indicate that we have received
- the final fragment. */
-
- if((BUF->ipoffset[0] & IP_MF) == 0) {
- uip_reassflags |= UIP_REASS_FLAG_LASTFRAG;
- uip_reasslen = offset + len;
- }
-
- /* Finally, we check if we have a full packet in the buffer. We do
- this by checking if we have the last fragment and if all bits
- in the bitmap are set. */
- if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) {
- /* Check all bytes up to and including all but the last byte in
- the bitmap. */
- for(i = 0; i < uip_reasslen / (8 * 8) - 1; ++i) {
- if(uip_reassbitmap[i] != 0xff) {
- goto nullreturn;
- }
- }
- /* Check the last byte in the bitmap. It should contain just the
- right amount of bits. */
- if(uip_reassbitmap[uip_reasslen / (8 * 8)] !=
- (u8_t)~bitmap_bits[uip_reasslen / 8 & 7]) {
- goto nullreturn;
- }
-
- /* If we have come this far, we have a full packet in the
- buffer, so we allocate a pbuf and copy the packet into it. We
- also reset the timer. */
- uip_reasstmr = 0;
- memcpy(BUF, FBUF, uip_reasslen);
-
- /* Pretend to be a "normal" (i.e., not fragmented) IP packet
- from now on. */
- BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
- BUF->len[0] = uip_reasslen >> 8;
- BUF->len[1] = uip_reasslen & 0xff;
- BUF->ipchksum = 0;
- BUF->ipchksum = ~(uip_ipchksum());
-
- return uip_reasslen;
- }
- }
-
- nullreturn:
- return 0;
-}
-#endif /* UIP_REASSEMBLY */
-/*---------------------------------------------------------------------------*/
-static void
-uip_add_rcv_nxt(u16_t n)
-{
- uip_add32(uip_conn->rcv_nxt, n);
- uip_conn->rcv_nxt[0] = uip_acc32[0];
- uip_conn->rcv_nxt[1] = uip_acc32[1];
- uip_conn->rcv_nxt[2] = uip_acc32[2];
- uip_conn->rcv_nxt[3] = uip_acc32[3];
-}
-/*---------------------------------------------------------------------------*/
-void
-uip_process(u8_t flag)
-{
- register struct uip_conn *uip_connr = uip_conn;
-
-#if UIP_UDP
- if(flag == UIP_UDP_SEND_CONN) {
- goto udp_send;
- }
-#endif /* UIP_UDP */
-
- uip_sappdata = uip_appdata = &uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN];
-
- /* Check if we were invoked because of a poll request for a
- particular connection. */
- if(flag == UIP_POLL_REQUEST) { //����uIP����һ�����ӱ��벻�ϱ���ѯ
- if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED &&
- !uip_outstanding(uip_connr)) {
- uip_flags = UIP_POLL;
- UIP_APPCALL();
- goto appsend;
- }
- goto drop;
-
- /* Check if we were invoked because of the perodic timer fireing. */
- } else if(flag == UIP_TIMER) {
-#if UIP_REASSEMBLY
- if(uip_reasstmr != 0) {
- --uip_reasstmr;
- }
-#endif /* UIP_REASSEMBLY */
- /* Increase the initial sequence number. */
- if(++iss[3] == 0) {
- if(++iss[2] == 0) {
- if(++iss[1] == 0) {
- ++iss[0];
- }
- }
- }
-
- /* Reset the length variables. */
- uip_len = 0;
- uip_slen = 0;
-
- /* Check if the connection is in a state in which we simply wait
- for the connection to time out. If so, we increase the
- connection's timer and remove the connection if it times
- out. */
- if(uip_connr->tcpstateflags == UIP_TIME_WAIT ||
- uip_connr->tcpstateflags == UIP_FIN_WAIT_2) {
- ++(uip_connr->timer);
- if(uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) {
- uip_connr->tcpstateflags = UIP_CLOSED;
- }
- } else if(uip_connr->tcpstateflags != UIP_CLOSED) {//�������û�б��رգ�������������Ҫ����
- /* If the connection has outstanding data, we increase the
- connection's timer and see if it has reached the RTO value
- in which case we retransmit. */
- if(uip_outstanding(uip_connr)) {//�����������Ҫ����
- if(uip_connr->timer-- == 0) {
- if(uip_connr->nrtx == UIP_MAXRTX ||
- ((uip_connr->tcpstateflags == UIP_SYN_SENT ||
- uip_connr->tcpstateflags == UIP_SYN_RCVD) &&
- uip_connr->nrtx == UIP_MAXSYNRTX)) {
- uip_connr->tcpstateflags = UIP_CLOSED;
-
- /* We call UIP_APPCALL() with uip_flags set to
- UIP_TIMEDOUT to inform the application that the
- connection has timed out. */
- uip_flags = UIP_TIMEDOUT;
- UIP_APPCALL();
-
- /* We also send a reset packet to the remote host. */
- BUF->flags = TCP_RST | TCP_ACK;
- goto tcp_send_nodata;
- }
-
- /* Exponential backoff. */
- uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4?
- 4:
- uip_connr->nrtx);
- ++(uip_connr->nrtx);
-
- /* Ok, so we need to retransmit. We do this differently
- depending on which state we are in. In ESTABLISHED, we
- call upon the application so that it may prepare the
- data for the retransmit. In SYN_RCVD, we resend the
- SYNACK that we sent earlier and in LAST_ACK we have to
- retransmit our FINACK. */
- UIP_STAT(++uip_stat.tcp.rexmit);
- switch(uip_connr->tcpstateflags & UIP_TS_MASK) {
- case UIP_SYN_RCVD:
- /* In the SYN_RCVD state, we should retransmit our
- SYNACK. */
- goto tcp_send_synack;
-
-#if UIP_ACTIVE_OPEN
- case UIP_SYN_SENT: //��Ҫ����ͬ����
- /* In the SYN_SENT state, we retransmit out SYN. */
- BUF->flags = 0;
- goto tcp_send_syn;
-#endif /* UIP_ACTIVE_OPEN */
-
- case UIP_ESTABLISHED:
- /* In the ESTABLISHED state, we call upon the application
- to do the actual retransmit after which we jump into
- the code for sending out the packet (the apprexmit
- label). */
- uip_flags = UIP_REXMIT;
- UIP_APPCALL();
- goto apprexmit;
-
- case UIP_FIN_WAIT_1:
- case UIP_CLOSING:
- case UIP_LAST_ACK:
- /* In all these states we should retransmit a FINACK. */
- goto tcp_send_finack;
-
- }
- }
- } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) { //�������������
- /* If there was no need for a retransmission, we poll the
- application for new data. */
- uip_flags = UIP_POLL; //�������ò��ϱ���ѯ�ı�־
- UIP_APPCALL();
- goto appsend;
- }
- }
- goto drop;
- }
-#if UIP_UDP
- if(flag == UIP_UDP_TIMER) {
- if(uip_udp_conn->lport != 0) {
- uip_conn = NULL;
- uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
- uip_len = uip_slen = 0;
- uip_flags = UIP_POLL;
- UIP_UDP_APPCALL();
- goto udp_send;
- } else {
- goto drop;
- }
- }
-#endif
-//����յ�IP����������↑ʼ
- /* This is where the input processing starts. */
- UIP_STAT(++uip_stat.ip.recv);
-
- /* Start of IP input header processing code. */
-
-#if UIP_CONF_IPV6
- /* Check validity of the IP header. */
- if((BUF->vtc & 0xf0) != 0x60) { /* IP version and header length. */
- UIP_STAT(++uip_stat.ip.drop);
- UIP_STAT(++uip_stat.ip.vhlerr);
- UIP_LOG("ipv6: invalid version.");
- goto drop;
- }
-#else /* UIP_CONF_IPV6 */
- /* Check validity of the IP header. */
- if(BUF->vhl != 0x45) { /* IP version and header length. */
- UIP_STAT(++uip_stat.ip.drop);
- UIP_STAT(++uip_stat.ip.vhlerr);
- UIP_LOG("ip: invalid version or header length.");
- goto drop;
- }
-#endif /* UIP_CONF_IPV6 */
-
- /* Check the size of the packet. If the size reported to us in
- uip_len is smaller the size reported in the IP header, we assume
- that the packet has been corrupted in transit. If the size of
- uip_len is larger than the size reported in the IP packet header,
- the packet has been padded and we set uip_len to the correct
- value.. */
-
- if((BUF->len[0] << 8) + BUF->len[1] <= uip_len) {
- uip_len = (BUF->len[0] << 8) + BUF->len[1];
-#if UIP_CONF_IPV6
- uip_len += 40; /* The length reported in the IPv6 header is the
- length of the payload that follows the
- header. However, uIP uses the uip_len variable
- for holding the size of the entire packet,
- including the IP header. For IPv4 this is not a
- problem as the length field in the IPv4 header
- contains the length of the entire packet. But
- for IPv6 we need to add the size of the IPv6
- header (40 bytes). */
-#endif /* UIP_CONF_IPV6 */
- } else {
- UIP_LOG("ip: packet shorter than reported in IP header.");
- goto drop;
- }
-
-#if !UIP_CONF_IPV6
- /* Check the fragment flag. */
- if((BUF->ipoffset[0] & 0x3f) != 0 ||
- BUF->ipoffset[1] != 0) {
-#if UIP_REASSEMBLY
- uip_len = uip_reass();
- if(uip_len == 0) {
- goto drop;
- }
-#else /* UIP_REASSEMBLY */
- UIP_STAT(++uip_stat.ip.drop);
- UIP_STAT(++uip_stat.ip.fragerr);
- UIP_LOG("ip: fragment dropped.");
- goto drop;
-#endif /* UIP_REASSEMBLY */
- }
-#endif /* UIP_CONF_IPV6 */
-
- if(uip_ipaddr_cmp(uip_hostaddr, all_zeroes_addr)) {
- /* If we are configured to use ping IP address configuration and
- hasn't been assigned an IP address yet, we accept all ICMP
- packets. */
-#if UIP_PINGADDRCONF && !UIP_CONF_IPV6
- if(BUF->proto == UIP_PROTO_ICMP) {
- UIP_LOG("ip: possible ping config packet received.");
- goto icmp_input;
- } else {
- UIP_LOG("ip: packet dropped since no address assigned.");
- goto drop;
- }
-#endif /* UIP_PINGADDRCONF */
-
- } else {
- /* If IP broadcast support is configured, we check for a broadcast
- UDP packet, which may be destined to us. */
-#if UIP_BROADCAST
- DEBUG_PRINTF("UDP IP checksum 0x%04x\n", uip_ipchksum());
- if(BUF->proto == UIP_PROTO_UDP &&
- uip_ipaddr_cmp(BUF->destipaddr, all_ones_addr)
- /*&&
- uip_ipchksum() == 0xffff*/) {
- goto udp_input;
- }
-#endif /* UIP_BROADCAST */
-
- /* Check if the packet is destined for our IP address. */
-#if !UIP_CONF_IPV6
- if(!uip_ipaddr_cmp(BUF->destipaddr, uip_hostaddr)) {
- UIP_STAT(++uip_stat.ip.drop);
- goto drop;
- }
-#else /* UIP_CONF_IPV6 */
- /* For IPv6, packet reception is a little trickier as we need to
- make sure that we listen to certain multicast addresses (all
- hosts multicast address, and the solicited-node multicast
- address) as well. However, we will cheat here and accept all
- multicast packets that are sent to the ff02::/16 addresses. */
- if(!uip_ipaddr_cmp(BUF->destipaddr, uip_hostaddr) &&
- BUF->destipaddr[0] != HTONS(0xff02)) {
- UIP_STAT(++uip_stat.ip.drop);
- goto drop;
- }
-#endif /* UIP_CONF_IPV6 */
- }
-
-#if !UIP_CONF_IPV6
- if(uip_ipchksum() != 0xffff) { /* Compute and check the IP header
- checksum. */
- UIP_STAT(++uip_stat.ip.drop);
- UIP_STAT(++uip_stat.ip.chkerr);
- UIP_LOG("ip: bad checksum.");
- goto drop;
- }
-#endif /* UIP_CONF_IPV6 */
-
- if(BUF->proto == UIP_PROTO_TCP) { /* Check for TCP packet. If so,
- proceed with TCP input
- processing. */
- goto tcp_input;
- }
-
-#if UIP_UDP
- if(BUF->proto == UIP_PROTO_UDP) {
- goto udp_input;
- }
-#endif /* UIP_UDP */
-
-#if !UIP_CONF_IPV6
- /* ICMPv4 processing code follows. */
- if(BUF->proto != UIP_PROTO_ICMP) { /* We only allow ICMP packets from
- here. */
- UIP_STAT(++uip_stat.ip.drop);
- UIP_STAT(++uip_stat.ip.protoerr);
- UIP_LOG("ip: neither tcp nor icmp.");
- goto drop;
- }
-
-#if UIP_PINGADDRCONF
- icmp_input:
-#endif /* UIP_PINGADDRCONF */
- UIP_STAT(++uip_stat.icmp.recv);
-
- /* ICMP echo (i.e., ping) processing. This is simple, we only change
- the ICMP type from ECHO to ECHO_REPLY and adjust the ICMP
- checksum before we return the packet. */
- if(ICMPBUF->type != ICMP_ECHO) {
- UIP_STAT(++uip_stat.icmp.drop);
- UIP_STAT(++uip_stat.icmp.typeerr);
- UIP_LOG("icmp: not icmp echo.");
- goto drop;
- }
-
- /* If we are configured to use ping IP address assignment, we use
- the destination IP address of this ping packet and assign it to
- ourself. */
-#if UIP_PINGADDRCONF
- if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) {
- uip_hostaddr[0] = BUF->destipaddr[0];
- uip_hostaddr[1] = BUF->destipaddr[1];
- }
-#endif /* UIP_PINGADDRCONF */
-
- ICMPBUF->type = ICMP_ECHO_REPLY;
-
- if(ICMPBUF->icmpchksum >= HTONS(0xffff - (ICMP_ECHO << 8))) {
- ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8) + 1;
- } else {
- ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8);
- }
-
- /* Swap IP addresses. */
- uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr);
- uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
-
- UIP_STAT(++uip_stat.icmp.sent);
- goto send;
-
- /* End of IPv4 input header processing code. */
-#else /* !UIP_CONF_IPV6 */
-
- /* This is IPv6 ICMPv6 processing code. */
- DEBUG_PRINTF("icmp6_input: length %d\n", uip_len);
-
- if(BUF->proto != UIP_PROTO_ICMP6) { /* We only allow ICMPv6 packets from
- here. */
- UIP_STAT(++uip_stat.ip.drop);
- UIP_STAT(++uip_stat.ip.protoerr);
- UIP_LOG("ip: neither tcp nor icmp6.");
- goto drop;
- }
-
- UIP_STAT(++uip_stat.icmp.recv);
-
- /* If we get a neighbor solicitation for our address we should send
- a neighbor advertisement message back. */
- if(ICMPBUF->type == ICMP6_NEIGHBOR_SOLICITATION) {
- if(uip_ipaddr_cmp(ICMPBUF->icmp6data, uip_hostaddr)) {
-
- if(ICMPBUF->options[0] == ICMP6_OPTION_SOURCE_LINK_ADDRESS) {
- /* Save the sender's address in our neighbor list. */
- uip_neighbor_add(ICMPBUF->srcipaddr, &(ICMPBUF->options[2]));
- }
-
- /* We should now send a neighbor advertisement back to where the
- neighbor solicication came from. */
- ICMPBUF->type = ICMP6_NEIGHBOR_ADVERTISEMENT;
- ICMPBUF->flags = ICMP6_FLAG_S; /* Solicited flag. */
-
- ICMPBUF->reserved1 = ICMPBUF->reserved2 = ICMPBUF->reserved3 = 0;
-
- uip_ipaddr_copy(ICMPBUF->destipaddr, ICMPBUF->srcipaddr);
- uip_ipaddr_copy(ICMPBUF->srcipaddr, uip_hostaddr);
- ICMPBUF->options[0] = ICMP6_OPTION_TARGET_LINK_ADDRESS;
- ICMPBUF->options[1] = 1; /* Options length, 1 = 8 bytes. */
- memcpy(&(ICMPBUF->options[2]), &uip_ethaddr, sizeof(uip_ethaddr));
- ICMPBUF->icmpchksum = 0;
- ICMPBUF->icmpchksum = ~uip_icmp6chksum();
- goto send;
-
- }
- goto drop;
- } else if(ICMPBUF->type == ICMP6_ECHO) {
- /* ICMP echo (i.e., ping) processing. This is simple, we only
- change the ICMP type from ECHO to ECHO_REPLY and update the
- ICMP checksum before we return the packet. */
-
- ICMPBUF->type = ICMP6_ECHO_REPLY;
-
- uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr);
- uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
- ICMPBUF->icmpchksum = 0;
- ICMPBUF->icmpchksum = ~uip_icmp6chksum();
-
- UIP_STAT(++uip_stat.icmp.sent);
- goto send;
- } else {
- DEBUG_PRINTF("Unknown icmp6 message type %d\n", ICMPBUF->type);
- UIP_STAT(++uip_stat.icmp.drop);
- UIP_STAT(++uip_stat.icmp.typeerr);
- UIP_LOG("icmp: unknown ICMP message.");
- goto drop;
- }
-
- /* End of IPv6 ICMP processing. */
-
-#endif /* !UIP_CONF_IPV6 */
-
-#if UIP_UDP
- /* UDP input processing. */
- udp_input:
- /* UDP processing is really just a hack. We don't do anything to the
- UDP/IP headers, but let the UDP application do all the hard
- work. If the application sets uip_slen, it has a packet to
- send. */
-#if UIP_UDP_CHECKSUMS
- uip_len = uip_len - UIP_IPUDPH_LEN;
- uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
- if(UDPBUF->udpchksum != 0 && uip_udpchksum() != 0xffff) {
- UIP_STAT(++uip_stat.udp.drop);
- UIP_STAT(++uip_stat.udp.chkerr);
- UIP_LOG("udp: bad checksum.");
- goto drop;
- }
-#else /* UIP_UDP_CHECKSUMS */
- uip_len = uip_len - UIP_IPUDPH_LEN;
-#endif /* UIP_UDP_CHECKSUMS */
-
- /* Demultiplex this UDP packet between the UDP "connections". */
- for(uip_udp_conn = &uip_udp_conns[0];
- uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS];
- ++uip_udp_conn) {
- /* If the local UDP port is non-zero, the connection is considered
- to be used. If so, the local port number is checked against the
- destination port number in the received packet. If the two port
- numbers match, the remote port number is checked if the
- connection is bound to a remote port. Finally, if the
- connection is bound to a remote IP address, the source IP
- address of the packet is checked. */
- if(uip_udp_conn->lport != 0 &&
- UDPBUF->destport == uip_udp_conn->lport &&
- (uip_udp_conn->rport == 0 ||
- UDPBUF->srcport == uip_udp_conn->rport) &&
- (uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_zeroes_addr) ||
- uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_ones_addr) ||
- uip_ipaddr_cmp(BUF->srcipaddr, uip_udp_conn->ripaddr))) {
- goto udp_found;
- }
- }
- UIP_LOG("udp: no matching connection found");
- goto drop;
-
- udp_found:
- uip_conn = NULL;
- uip_flags = UIP_NEWDATA;
- uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
- uip_slen = 0;
- UIP_UDP_APPCALL();
- udp_send:
- if(uip_slen == 0) {
- goto drop;
- }
- uip_len = uip_slen + UIP_IPUDPH_LEN;
-
-#if UIP_CONF_IPV6
- /* For IPv6, the IP length field does not include the IPv6 IP header
- length. */
- BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
- BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
-#else /* UIP_CONF_IPV6 */
- BUF->len[0] = (uip_len >> 8);
- BUF->len[1] = (uip_len & 0xff);
-#endif /* UIP_CONF_IPV6 */
-
- BUF->ttl = uip_udp_conn->ttl;
- BUF->proto = UIP_PROTO_UDP;
-
- UDPBUF->udplen = HTONS(uip_slen + UIP_UDPH_LEN);
- UDPBUF->udpchksum = 0;
-
- BUF->srcport = uip_udp_conn->lport;
- BUF->destport = uip_udp_conn->rport;
-
- uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
- uip_ipaddr_copy(BUF->destipaddr, uip_udp_conn->ripaddr);
-
- uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPTCPH_LEN];
-
-#if UIP_UDP_CHECKSUMS
- /* Calculate UDP checksum. */
- UDPBUF->udpchksum = ~(uip_udpchksum());
- if(UDPBUF->udpchksum == 0) {
- UDPBUF->udpchksum = 0xffff;
- }
-#endif /* UIP_UDP_CHECKSUMS */
-
- goto ip_send_nolen;
-#endif /* UIP_UDP */
-
- /* TCP input processing. */
- tcp_input:
- UIP_STAT(++uip_stat.tcp.recv);
-
- /* Start of TCP input header processing code. */
-
- if(uip_tcpchksum() != 0xffff) { /* Compute and check the TCP
- checksum. */
- UIP_STAT(++uip_stat.tcp.drop);
- UIP_STAT(++uip_stat.tcp.chkerr);
- UIP_LOG("tcp: bad checksum.");
- goto drop;
- }
-
-
- /* Demultiplex this segment. */
- /* First check any active connections. */
- for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[UIP_CONNS - 1];
- ++uip_connr) {
- if(uip_connr->tcpstateflags != UIP_CLOSED &&
- BUF->destport == uip_connr->lport &&
- BUF->srcport == uip_connr->rport &&
- uip_ipaddr_cmp(BUF->srcipaddr, uip_connr->ripaddr)) {
- goto found;
- }
- }
-
- /* If we didn't find and active connection that expected the packet,
- either this packet is an old duplicate, or this is a SYN packet
- destined for a connection in LISTEN. If the SYN flag isn't set,
- it is an old packet and we send a RST. */
- if((BUF->flags & TCP_CTL) != TCP_SYN) {
- goto reset;
- }
-
- tmp16 = BUF->destport;
- /* Next, check listening connections. */
- for(c = 0; c < UIP_LISTENPORTS; ++c) {
- if(tmp16 == uip_listenports[c])
- goto found_listen;
- }
-
- /* No matching connection found, so we send a RST packet. */
- UIP_STAT(++uip_stat.tcp.synrst);
- reset:
-
- /* We do not send resets in response to resets. */
- if(BUF->flags & TCP_RST) {
- goto drop;
- }
-
- UIP_STAT(++uip_stat.tcp.rst);
-
- BUF->flags = TCP_RST | TCP_ACK;
- uip_len = UIP_IPTCPH_LEN;
- BUF->tcpoffset = 5 << 4;
-
- /* Flip the seqno and ackno fields in the TCP header. */
- c = BUF->seqno[3];
- BUF->seqno[3] = BUF->ackno[3];
- BUF->ackno[3] = c;
-
- c = BUF->seqno[2];
- BUF->seqno[2] = BUF->ackno[2];
- BUF->ackno[2] = c;
-
- c = BUF->seqno[1];
- BUF->seqno[1] = BUF->ackno[1];
- BUF->ackno[1] = c;
-
- c = BUF->seqno[0];
- BUF->seqno[0] = BUF->ackno[0];
- BUF->ackno[0] = c;
-
- /* We also have to increase the sequence number we are
- acknowledging. If the least significant byte overflowed, we need
- to propagate the carry to the other bytes as well. */
- if(++BUF->ackno[3] == 0) {
- if(++BUF->ackno[2] == 0) {
- if(++BUF->ackno[1] == 0) {
- ++BUF->ackno[0];
- }
- }
- }
-
- /* Swap port numbers. */
- tmp16 = BUF->srcport;
- BUF->srcport = BUF->destport;
- BUF->destport = tmp16;
-
- /* Swap IP addresses. */
- uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr);
- uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
-
- /* And send out the RST packet! */
- goto tcp_send_noconn;
-
- /* This label will be jumped to if we matched the incoming packet
- with a connection in LISTEN. In that case, we should create a new
- connection and send a SYNACK in return. */
- found_listen:
- /* First we check if there are any connections avaliable. Unused
- connections are kept in the same table as used connections, but
- unused ones have the tcpstate set to CLOSED. Also, connections in
- TIME_WAIT are kept track of and we'll use the oldest one if no
- CLOSED connections are found. Thanks to Eddie C. Dost for a very
- nice algorithm for the TIME_WAIT search. */
- uip_connr = 0;
- for(c = 0; c < UIP_CONNS; ++c) {
- if(uip_conns[c].tcpstateflags == UIP_CLOSED) {
- uip_connr = &uip_conns[c];
- break;
- }
- if(uip_conns[c].tcpstateflags == UIP_TIME_WAIT) {
- if(uip_connr == 0 ||
- uip_conns[c].timer > uip_connr->timer) {
- uip_connr = &uip_conns[c];
- }
- }
- }
-
- if(uip_connr == 0) {
- /* All connections are used already, we drop packet and hope that
- the remote end will retransmit the packet at a time when we
- have more spare connections. */
- UIP_STAT(++uip_stat.tcp.syndrop);
- UIP_LOG("tcp: found no unused connections.");
- goto drop;
- }
- uip_conn = uip_connr;
-
- /* Fill in the necessary fields for the new connection. */
- uip_connr->rto = uip_connr->timer = UIP_RTO;
- uip_connr->sa = 0;
- uip_connr->sv = 4;
- uip_connr->nrtx = 0;
- uip_connr->lport = BUF->destport;
- uip_connr->rport = BUF->srcport;
- uip_ipaddr_copy(uip_connr->ripaddr, BUF->srcipaddr);
- uip_connr->tcpstateflags = UIP_SYN_RCVD;
-
- uip_connr->snd_nxt[0] = iss[0];
- uip_connr->snd_nxt[1] = iss[1];
- uip_connr->snd_nxt[2] = iss[2];
- uip_connr->snd_nxt[3] = iss[3];
- uip_connr->len = 1;
-
- /* rcv_nxt should be the seqno from the incoming packet + 1. */
- uip_connr->rcv_nxt[3] = BUF->seqno[3];
- uip_connr->rcv_nxt[2] = BUF->seqno[2];
- uip_connr->rcv_nxt[1] = BUF->seqno[1];
- uip_connr->rcv_nxt[0] = BUF->seqno[0];
- uip_add_rcv_nxt(1);
-
- /* Parse the TCP MSS option, if present. */
- if((BUF->tcpoffset & 0xf0) > 0x50) {
- for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
- opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c];
- if(opt == TCP_OPT_END) {
- /* End of options. */
- break;
- } else if(opt == TCP_OPT_NOOP) {
- ++c;
- /* NOP option. */
- } else if(opt == TCP_OPT_MSS &&
- uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
- /* An MSS option with the right option length. */
- tmp16 = ((u16_t)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
- (u16_t)uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + c];
- uip_connr->initialmss = uip_connr->mss =
- tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
-
- /* And we are done processing options. */
- break;
- } else {
- /* All other options have a length field, so that we easily
- can skip past them. */
- if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
- /* If the length field is zero, the options are malformed
- and we don't process them further. */
- break;
- }
- c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
- }
- }
- }
-
- /* Our response will be a SYNACK. */
-#if UIP_ACTIVE_OPEN
- tcp_send_synack:
- BUF->flags = TCP_ACK;
-
- tcp_send_syn:
- BUF->flags |= TCP_SYN;
-#else /* UIP_ACTIVE_OPEN */
- tcp_send_synack:
- BUF->flags = TCP_SYN | TCP_ACK;
-#endif /* UIP_ACTIVE_OPEN */
-
- /* We send out the TCP Maximum Segment Size option with our
- SYNACK. */
- BUF->optdata[0] = TCP_OPT_MSS;
- BUF->optdata[1] = TCP_OPT_MSS_LEN;
- BUF->optdata[2] = (UIP_TCP_MSS) / 256;
- BUF->optdata[3] = (UIP_TCP_MSS) & 255;
- uip_len = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN;
- BUF->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4;
- goto tcp_send;
-
- /* This label will be jumped to if we found an active connection. */
- found:
- uip_conn = uip_connr;
- uip_flags = 0;
- /* We do a very naive form of TCP reset processing; we just accept
- any RST and kill our connection. We should in fact check if the
- sequence number of this reset is wihtin our advertised window
- before we accept the reset. */
- if(BUF->flags & TCP_RST) {
- uip_connr->tcpstateflags = UIP_CLOSED;
- UIP_LOG("tcp: got reset, aborting connection.");
- uip_flags = UIP_ABORT;
- UIP_APPCALL();
- goto drop;
- }
- /* Calculated the length of the data, if the application has sent
- any data to us. */
- c = (BUF->tcpoffset >> 4) << 2;
- /* uip_len will contain the length of the actual TCP data. This is
- calculated by subtracing the length of the TCP header (in
- c) and the length of the IP header (20 bytes). */
- uip_len = uip_len - c - UIP_IPH_LEN;
-
- /* First, check if the sequence number of the incoming packet is
- what we're expecting next. If not, we send out an ACK with the
- correct numbers in. */
- if(!(((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) &&
- ((BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)))) {
- if((uip_len > 0 || ((BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) &&
- (BUF->seqno[0] != uip_connr->rcv_nxt[0] ||
- BUF->seqno[1] != uip_connr->rcv_nxt[1] ||
- BUF->seqno[2] != uip_connr->rcv_nxt[2] ||
- BUF->seqno[3] != uip_connr->rcv_nxt[3])) {
- goto tcp_send_ack;
- }
- }
-
- /* Next, check if the incoming segment acknowledges any outstanding
- data. If so, we update the sequence number, reset the length of
- the outstanding data, calculate RTT estimations, and reset the
- retransmission timer. */
- if((BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) {
- uip_add32(uip_connr->snd_nxt, uip_connr->len);
-
- if(BUF->ackno[0] == uip_acc32[0] &&
- BUF->ackno[1] == uip_acc32[1] &&
- BUF->ackno[2] == uip_acc32[2] &&
- BUF->ackno[3] == uip_acc32[3]) {
- /* Update sequence number. */
- uip_connr->snd_nxt[0] = uip_acc32[0];
- uip_connr->snd_nxt[1] = uip_acc32[1];
- uip_connr->snd_nxt[2] = uip_acc32[2];
- uip_connr->snd_nxt[3] = uip_acc32[3];
-
-
- /* Do RTT estimation, unless we have done retransmissions. */
- if(uip_connr->nrtx == 0) {
- signed char m;
- m = uip_connr->rto - uip_connr->timer;
- /* This is taken directly from VJs original code in his paper */
- m = m - (uip_connr->sa >> 3);
- uip_connr->sa += m;
- if(m < 0) {
- m = -m;
- }
- m = m - (uip_connr->sv >> 2);
- uip_connr->sv += m;
- uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv;
-
- }
- /* Set the acknowledged flag. */
- uip_flags = UIP_ACKDATA;
- /* Reset the retransmission timer. */
- uip_connr->timer = uip_connr->rto;
-
- /* Reset length of outstanding data. */
- uip_connr->len = 0;
- }
-
- }
-
- /* Do different things depending on in what state the connection is. */
- switch(uip_connr->tcpstateflags & UIP_TS_MASK) {
- /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not
- implemented, since we force the application to close when the
- peer sends a FIN (hence the application goes directly from
- ESTABLISHED to LAST_ACK). */
- case UIP_SYN_RCVD:
- /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and
- we are waiting for an ACK that acknowledges the data we sent
- out the last time. Therefore, we want to have the UIP_ACKDATA
- flag set. If so, we enter the ESTABLISHED state. */
- if(uip_flags & UIP_ACKDATA) {
- uip_connr->tcpstateflags = UIP_ESTABLISHED;
- uip_flags = UIP_CONNECTED;
- uip_connr->len = 0;
- if(uip_len > 0) {
- uip_flags |= UIP_NEWDATA;
- uip_add_rcv_nxt(uip_len);
- }
- uip_slen = 0;
- UIP_APPCALL();
- goto appsend;
- }
- goto drop;
-#if UIP_ACTIVE_OPEN
- case UIP_SYN_SENT:
- /* In SYN_SENT, we wait for a SYNACK that is sent in response to
- our SYN. The rcv_nxt is set to sequence number in the SYNACK
- plus one, and we send an ACK. We move into the ESTABLISHED
- state. */
- if((uip_flags & UIP_ACKDATA) &&
- (BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) {
-
- /* Parse the TCP MSS option, if present. */
- if((BUF->tcpoffset & 0xf0) > 0x50) {
- for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
- opt = uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + c];
- if(opt == TCP_OPT_END) {
- /* End of options. */
- break;
- } else if(opt == TCP_OPT_NOOP) {
- ++c;
- /* NOP option. */
- } else if(opt == TCP_OPT_MSS &&
- uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
- /* An MSS option with the right option length. */
- tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
- uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c];
- uip_connr->initialmss =
- uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
-
- /* And we are done processing options. */
- break;
- } else {
- /* All other options have a length field, so that we easily
- can skip past them. */
- if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
- /* If the length field is zero, the options are malformed
- and we don't process them further. */
- break;
- }
- c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
- }
- }
- }
- uip_connr->tcpstateflags = UIP_ESTABLISHED;
- uip_connr->rcv_nxt[0] = BUF->seqno[0];
- uip_connr->rcv_nxt[1] = BUF->seqno[1];
- uip_connr->rcv_nxt[2] = BUF->seqno[2];
- uip_connr->rcv_nxt[3] = BUF->seqno[3];
- uip_add_rcv_nxt(1);
- uip_flags = UIP_CONNECTED | UIP_NEWDATA;
- uip_connr->len = 0;
- uip_len = 0;
- uip_slen = 0;
- UIP_APPCALL();
- goto appsend;
- }
- /* Inform the application that the connection failed */
- uip_flags = UIP_ABORT;
- UIP_APPCALL();
- /* The connection is closed after we send the RST */
- uip_conn->tcpstateflags = UIP_CLOSED;
- goto reset;
-#endif /* UIP_ACTIVE_OPEN */
-
- case UIP_ESTABLISHED:
- /* In the ESTABLISHED state, we call upon the application to feed
- data into the uip_buf. If the UIP_ACKDATA flag is set, the
- application should put new data into the buffer, otherwise we are
- retransmitting an old segment, and the application should put that
- data into the buffer.
-
- If the incoming packet is a FIN, we should close the connection on
- this side as well, and we send out a FIN and enter the LAST_ACK
- state. We require that there is no outstanding data; otherwise the
- sequence numbers will be screwed up. */
-
- if(BUF->flags & TCP_FIN && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
- if(uip_outstanding(uip_connr)) {
- goto drop;
- }
- uip_add_rcv_nxt(1 + uip_len);
- uip_flags |= UIP_CLOSE;
- if(uip_len > 0) {
- uip_flags |= UIP_NEWDATA;
- }
- UIP_APPCALL();
- uip_connr->len = 1;
- uip_connr->tcpstateflags = UIP_LAST_ACK;
- uip_connr->nrtx = 0;
- tcp_send_finack:
- BUF->flags = TCP_FIN | TCP_ACK;
- goto tcp_send_nodata;
- }
-
- /* Check the URG flag. If this is set, the segment carries urgent
- data that we must pass to the application. */
- if((BUF->flags & TCP_URG) != 0) {
-#if UIP_URGDATA > 0
- uip_urglen = (BUF->urgp[0] << 8) | BUF->urgp[1];
- if(uip_urglen > uip_len) {
- /* There is more urgent data in the next segment to come. */
- uip_urglen = uip_len;
- }
- uip_add_rcv_nxt(uip_urglen);
- uip_len -= uip_urglen;
- uip_urgdata = uip_appdata;
- uip_appdata += uip_urglen;
- } else {
- uip_urglen = 0;
-#else /* UIP_URGDATA > 0 */
- uip_appdata = ((char *)uip_appdata) + ((BUF->urgp[0] << 8) | BUF->urgp[1]);
- uip_len -= (BUF->urgp[0] << 8) | BUF->urgp[1];
-#endif /* UIP_URGDATA > 0 */
- }
-
- /* If uip_len > 0 we have TCP data in the packet, and we flag this
- by setting the UIP_NEWDATA flag and update the sequence number
- we acknowledge. If the application has stopped the dataflow
- using uip_stop(), we must not accept any data packets from the
- remote host. */
- if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
- uip_flags |= UIP_NEWDATA;
- uip_add_rcv_nxt(uip_len);
- }
-
- /* Check if the available buffer space advertised by the other end
- is smaller than the initial MSS for this connection. If so, we
- set the current MSS to the window size to ensure that the
- application does not send more data than the other end can
- handle.
-
- If the remote host advertises a zero window, we set the MSS to
- the initial MSS so that the application will send an entire MSS
- of data. This data will not be acknowledged by the receiver,
- and the application will retransmit it. This is called the
- "persistent timer" and uses the retransmission mechanim.
- */
- tmp16 = ((u16_t)BUF->wnd[0] << 8) + (u16_t)BUF->wnd[1];
- if(tmp16 > uip_connr->initialmss ||
- tmp16 == 0) {
- tmp16 = uip_connr->initialmss;
- }
- uip_connr->mss = tmp16;
-
- /* If this packet constitutes an ACK for outstanding data (flagged
- by the UIP_ACKDATA flag, we should call the application since it
- might want to send more data. If the incoming packet had data
- from the peer (as flagged by the UIP_NEWDATA flag), the
- application must also be notified.
-
- When the application is called, the global variable uip_len
- contains the length of the incoming data. The application can
- access the incoming data through the global pointer
- uip_appdata, which usually points UIP_IPTCPH_LEN + UIP_LLH_LEN
- bytes into the uip_buf array.
-
- If the application wishes to send any data, this data should be
- put into the uip_appdata and the length of the data should be
- put into uip_len. If the application don't have any data to
- send, uip_len must be set to 0. */
- if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {
- uip_slen = 0;
- UIP_APPCALL();
-
- appsend:
-
- if(uip_flags & UIP_ABORT) {
- uip_slen = 0;
- uip_connr->tcpstateflags = UIP_CLOSED;
- BUF->flags = TCP_RST | TCP_ACK;
- goto tcp_send_nodata;
- }
-
- if(uip_flags & UIP_CLOSE) {
- uip_slen = 0;
- uip_connr->len = 1;
- uip_connr->tcpstateflags = UIP_FIN_WAIT_1;
- uip_connr->nrtx = 0;
- BUF->flags = TCP_FIN | TCP_ACK;
- goto tcp_send_nodata;
- }
-
- /* If uip_slen > 0, the application has data to be sent. */
- if(uip_slen > 0) {
-
- /* If the connection has acknowledged data, the contents of
- the ->len variable should be discarded. */
- if((uip_flags & UIP_ACKDATA) != 0) {
- uip_connr->len = 0;
- }
-
- /* If the ->len variable is non-zero the connection has
- already data in transit and cannot send anymore right
- now. */
- if(uip_connr->len == 0) {
-
- /* The application cannot send more than what is allowed by
- the mss (the minumum of the MSS and the available
- window). */
- if(uip_slen > uip_connr->mss) {
- uip_slen = uip_connr->mss;
- }
-
- /* Remember how much data we send out now so that we know
- when everything has been acknowledged. */
- uip_connr->len = uip_slen;
- } else {
-
- /* If the application already had unacknowledged data, we
- make sure that the application does not send (i.e.,
- retransmit) out more than it previously sent out. */
- uip_slen = uip_connr->len;
- }
- }
- uip_connr->nrtx = 0;
- apprexmit:
- uip_appdata = uip_sappdata;
-
- /* If the application has data to be sent, or if the incoming
- packet had new data in it, we must send out a packet. */
- if(uip_slen > 0 && uip_connr->len > 0) {
- /* Add the length of the IP and TCP headers. */
- uip_len = uip_connr->len + UIP_TCPIP_HLEN;
- /* We always set the ACK flag in response packets. */
- BUF->flags = TCP_ACK | TCP_PSH;
- /* Send the packet. */
- goto tcp_send_noopts;
- }
- /* If there is no data to send, just send out a pure ACK if
- there is newdata. */
- if(uip_flags & UIP_NEWDATA) {
- uip_len = UIP_TCPIP_HLEN;
- BUF->flags = TCP_ACK;
- goto tcp_send_noopts;
- }
- }
- goto drop;
- case UIP_LAST_ACK:
- /* We can close this connection if the peer has acknowledged our
- FIN. This is indicated by the UIP_ACKDATA flag. */
- if(uip_flags & UIP_ACKDATA) {
- uip_connr->tcpstateflags = UIP_CLOSED;
- uip_flags = UIP_CLOSE;
- UIP_APPCALL();
- }
- break;
-
- case UIP_FIN_WAIT_1:
- /* The application has closed the connection, but the remote host
- hasn't closed its end yet. Thus we do nothing but wait for a
- FIN from the other side. */
- if(uip_len > 0) {
- uip_add_rcv_nxt(uip_len);
- }
- if(BUF->flags & TCP_FIN) {
- if(uip_flags & UIP_ACKDATA) {
- uip_connr->tcpstateflags = UIP_TIME_WAIT;
- uip_connr->timer = 0;
- uip_connr->len = 0;
- } else {
- uip_connr->tcpstateflags = UIP_CLOSING;
- }
- uip_add_rcv_nxt(1);
- uip_flags = UIP_CLOSE;
- UIP_APPCALL();
- goto tcp_send_ack;
- } else if(uip_flags & UIP_ACKDATA) {
- uip_connr->tcpstateflags = UIP_FIN_WAIT_2;
- uip_connr->len = 0;
- goto drop;
- }
- if(uip_len > 0) {
- goto tcp_send_ack;
- }
- goto drop;
-
- case UIP_FIN_WAIT_2:
- if(uip_len > 0) {
- uip_add_rcv_nxt(uip_len);
- }
- if(BUF->flags & TCP_FIN) {
- uip_connr->tcpstateflags = UIP_TIME_WAIT;
- uip_connr->timer = 0;
- uip_add_rcv_nxt(1);
- uip_flags = UIP_CLOSE;
- UIP_APPCALL();
- goto tcp_send_ack;
- }
- if(uip_len > 0) {
- goto tcp_send_ack;
- }
- goto drop;
-
- case UIP_TIME_WAIT:
- goto tcp_send_ack;
-
- case UIP_CLOSING:
- if(uip_flags & UIP_ACKDATA) {
- uip_connr->tcpstateflags = UIP_TIME_WAIT;
- uip_connr->timer = 0;
- }
- }
- goto drop;
-
-
- /* We jump here when we are ready to send the packet, and just want
- to set the appropriate TCP sequence numbers in the TCP header. */
- tcp_send_ack:
- BUF->flags = TCP_ACK;
- tcp_send_nodata:
- uip_len = UIP_IPTCPH_LEN;
- tcp_send_noopts:
- BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4;
- tcp_send:
- /* We're done with the input processing. We are now ready to send a
- reply. Our job is to fill in all the fields of the TCP and IP
- headers before calculating the checksum and finally send the
- packet. */
- BUF->ackno[0] = uip_connr->rcv_nxt[0];
- BUF->ackno[1] = uip_connr->rcv_nxt[1];
- BUF->ackno[2] = uip_connr->rcv_nxt[2];
- BUF->ackno[3] = uip_connr->rcv_nxt[3];
-
- BUF->seqno[0] = uip_connr->snd_nxt[0];
- BUF->seqno[1] = uip_connr->snd_nxt[1];
- BUF->seqno[2] = uip_connr->snd_nxt[2];
- BUF->seqno[3] = uip_connr->snd_nxt[3];
-
- BUF->proto = UIP_PROTO_TCP;
-
- BUF->srcport = uip_connr->lport;
- BUF->destport = uip_connr->rport;
-
- uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
- uip_ipaddr_copy(BUF->destipaddr, uip_connr->ripaddr);
-
- if(uip_connr->tcpstateflags & UIP_STOPPED) {
- /* If the connection has issued uip_stop(), we advertise a zero
- window so that the remote host will stop sending data. */
- BUF->wnd[0] = BUF->wnd[1] = 0;
- } else {
- BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8);
- BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff);
- }
-
- tcp_send_noconn:
- BUF->ttl = UIP_TTL;
-#if UIP_CONF_IPV6
- /* For IPv6, the IP length field does not include the IPv6 IP header
- length. */
- BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
- BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
-#else /* UIP_CONF_IPV6 */
- BUF->len[0] = (uip_len >> 8);
- BUF->len[1] = (uip_len & 0xff);
-#endif /* UIP_CONF_IPV6 */
-
- BUF->urgp[0] = BUF->urgp[1] = 0;
-
- /* Calculate TCP checksum. */
- BUF->tcpchksum = 0;
- BUF->tcpchksum = ~(uip_tcpchksum());
-
- ip_send_nolen:
-
-#if UIP_CONF_IPV6
- BUF->vtc = 0x60;
- BUF->tcflow = 0x00;
- BUF->flow = 0x00;
-#else /* UIP_CONF_IPV6 */
- BUF->vhl = 0x45;
- BUF->tos = 0;
- BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
- ++ipid;
- BUF->ipid[0] = ipid >> 8;
- BUF->ipid[1] = ipid & 0xff;
- /* Calculate IP checksum. */
- BUF->ipchksum = 0;
- BUF->ipchksum = ~(uip_ipchksum());
- DEBUG_PRINTF("uip ip_send_nolen: chkecum 0x%04x\n", uip_ipchksum());
-#endif /* UIP_CONF_IPV6 */
-
- UIP_STAT(++uip_stat.tcp.sent);
- send:
- DEBUG_PRINTF("Sending packet with length %d (%d)\n", uip_len,
- (BUF->len[0] << 8) | BUF->len[1]);
-
- UIP_STAT(++uip_stat.ip.sent);
- /* Return and let the caller do the actual transmission. */
- uip_flags = 0;
- return;
- drop:
- uip_len = 0;
- uip_flags = 0;
- return;
-}
-/*---------------------------------------------------------------------------*/
-u16_t
-uip_htons(u16_t val)
-{
- return HTONS(val);
-}
-/*---------------------------------------------------------------------------*/
-void
-uip_send(const void *data, int len)
-{
- if(len > 0) {
- uip_slen = len;
- if(data != uip_sappdata) {
- memcpy((void*)uip_sappdata, (data), uip_slen);
- }
- }
-}
-/** @} */
+#ifdef RT_UIP_DBUG_RPINTF
+#define DEBUG_PRINTF(...) rt_kprintf(__VA_ARGS__)
+#else
+#define DEBUG_PRINTF(...) /*printf(__VA_ARGS__)*/
+#endif
+
+
+/**
+ * \defgroup uip The uIP TCP/IP stack
+ * @{
+ *
+ * uIP is an implementation of the TCP/IP protocol stack intended for
+ * small 8-bit and 16-bit microcontrollers.
+ *
+ * uIP provides the necessary protocols for Internet communication,
+ * with a very small code footprint and RAM requirements - the uIP
+ * code size is on the order of a few kilobytes and RAM usage is on
+ * the order of a few hundred bytes.
+ */
+
+/**
+ * \file
+ * The uIP TCP/IP stack code.
+ * \author Adam Dunkels <[email protected]>
+ */
+
+/*
+ * Copyright (c) 2001-2003, Adam Dunkels.
+ * 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 uIP TCP/IP stack.
+ *
+ * $Id: uip.c,v 1.65 2006/06/11 21:46:39 adam Exp $
+ *
+ */
+
+/*
+ * uIP is a small implementation of the IP, UDP and TCP protocols (as
+ * well as some basic ICMP stuff). The implementation couples the IP,
+ * UDP, TCP and the application layers very tightly. To keep the size
+ * of the compiled code down, this code frequently uses the goto
+ * statement. While it would be possible to break the uip_process()
+ * function into many smaller functions, this would increase the code
+ * size because of the overhead of parameter passing and the fact that
+ * the optimier would not be as efficient.
+ *
+ * The principle is that we have a small buffer, called the uip_buf,
+ * in which the device driver puts an incoming packet. The TCP/IP
+ * stack parses the headers in the packet, and calls the
+ * application. If the remote host has sent data to the application,
+ * this data is present in the uip_buf and the application read the
+ * data from there. It is up to the application to put this data into
+ * a byte stream if needed. The application will not be fed with data
+ * that is out of sequence.
+ *
+ * If the application whishes to send data to the peer, it should put
+ * its data into the uip_buf. The uip_appdata pointer points to the
+ * first available byte. The TCP/IP stack will calculate the
+ * checksums, and fill in the necessary header fields and finally send
+ * the packet back to the peer.
+*/
+
+#include "uip.h"
+#include "uipopt.h"
+#include "uip_arch.h"
+
+#if UIP_CONF_IPV6
+#include "uip-neighbor.h"
+#endif /* UIP_CONF_IPV6 */
+
+#include <string.h>
+
+/*---------------------------------------------------------------------------*/
+/* Variable definitions. */
+
+
+/* The IP address of this host. If it is defined to be fixed (by
+ setting UIP_FIXEDADDR to 1 in uipopt.h), the address is set
+ here. Otherwise, the address */
+#if UIP_FIXEDADDR > 0
+const uip_ipaddr_t uip_hostaddr =
+ {HTONS((UIP_IPADDR0 << 8) | UIP_IPADDR1),
+ HTONS((UIP_IPADDR2 << 8) | UIP_IPADDR3)};
+const uip_ipaddr_t uip_draddr =
+ {HTONS((UIP_DRIPADDR0 << 8) | UIP_DRIPADDR1),
+ HTONS((UIP_DRIPADDR2 << 8) | UIP_DRIPADDR3)};
+const uip_ipaddr_t uip_netmask =
+ {HTONS((UIP_NETMASK0 << 8) | UIP_NETMASK1),
+ HTONS((UIP_NETMASK2 << 8) | UIP_NETMASK3)};
+#else
+uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask;
+#endif /* UIP_FIXEDADDR */
+
+static const uip_ipaddr_t all_ones_addr =
+#if UIP_CONF_IPV6
+ {0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff};
+#else /* UIP_CONF_IPV6 */
+ {0xffff,0xffff};
+#endif /* UIP_CONF_IPV6 */
+static const uip_ipaddr_t all_zeroes_addr =
+#if UIP_CONF_IPV6
+ {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000};
+#else /* UIP_CONF_IPV6 */
+ {0x0000,0x0000};
+#endif /* UIP_CONF_IPV6 */
+
+
+#if UIP_FIXEDETHADDR
+const struct uip_eth_addr uip_ethaddr = {{UIP_ETHADDR0,
+ UIP_ETHADDR1,
+ UIP_ETHADDR2,
+ UIP_ETHADDR3,
+ UIP_ETHADDR4,
+ UIP_ETHADDR5}};
+#else
+struct uip_eth_addr uip_ethaddr = {{0,0x33,0x44,0x55,0x66,0x77}};
+#endif
+
+#ifndef UIP_CONF_EXTERNAL_BUFFER
+u8_t uip_buf[UIP_BUFSIZE + 2]; /* The packet buffer that contains
+ incoming packets. */
+#endif /* UIP_CONF_EXTERNAL_BUFFER */
+
+volatile u8_t *uip_appdata; /* The uip_appdata pointer points to
+ application data. */
+volatile u8_t *uip_sappdata; /* The uip_appdata pointer points to
+ the application data which is to
+ be sent. */
+#if UIP_URGDATA > 0
+void *uip_urgdata; /* The uip_urgdata pointer points to
+ urgent data (out-of-band data), if
+ present. */
+u16_t uip_urglen, uip_surglen;
+#endif /* UIP_URGDATA > 0 */
+
+u16_t uip_len, uip_slen;
+ /* The uip_len is either 8 or 16 bits,
+ depending on the maximum packet
+ size. */
+
+u8_t uip_flags; /* The uip_flags variable is used for
+ communication between the TCP/IP stack
+ and the application program. */
+struct uip_conn *uip_conn; /* uip_conn always points to the current
+ connection. */
+
+struct uip_conn uip_conns[UIP_CONNS];
+ /* The uip_conns array holds all TCP
+ connections. */
+u16_t uip_listenports[UIP_LISTENPORTS];
+ /* The uip_listenports list all currently
+ listning ports. */
+#if UIP_UDP
+struct uip_udp_conn *uip_udp_conn;
+struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
+#endif /* UIP_UDP */
+
+static u16_t ipid; /* Ths ipid variable is an increasing
+ number that is used for the IP ID
+ field. */
+
+void uip_setipid(u16_t id) { ipid = id; }
+
+static u8_t iss[4]; /* The iss variable is used for the TCP
+ initial sequence number. */
+
+#if UIP_ACTIVE_OPEN
+static u16_t lastport; /* Keeps track of the last port used for
+ a new connection. */
+#endif /* UIP_ACTIVE_OPEN */
+
+/* Temporary variables. */
+u8_t uip_acc32[4];
+static u8_t c, opt;
+static u16_t tmp16;
+
+/* Structures and definitions. */
+#define TCP_FIN 0x01
+#define TCP_SYN 0x02
+#define TCP_RST 0x04
+#define TCP_PSH 0x08
+#define TCP_ACK 0x10
+#define TCP_URG 0x20
+#define TCP_CTL 0x3f
+
+#define TCP_OPT_END 0 /* End of TCP options list */
+#define TCP_OPT_NOOP 1 /* "No-operation" TCP option */
+#define TCP_OPT_MSS 2 /* Maximum segment size TCP option */
+
+#define TCP_OPT_MSS_LEN 4 /* Length of TCP MSS option. */
+
+#define ICMP_ECHO_REPLY 0
+#define ICMP_ECHO 8
+
+#define ICMP6_ECHO_REPLY 129
+#define ICMP6_ECHO 128
+#define ICMP6_NEIGHBOR_SOLICITATION 135
+#define ICMP6_NEIGHBOR_ADVERTISEMENT 136
+
+#define ICMP6_FLAG_S (1 << 6)
+
+#define ICMP6_OPTION_SOURCE_LINK_ADDRESS 1
+#define ICMP6_OPTION_TARGET_LINK_ADDRESS 2
+
+
+/* Macros. */
+#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
+#define FBUF ((struct uip_tcpip_hdr *)&uip_reassbuf[0])
+#define ICMPBUF ((struct uip_icmpip_hdr *)&uip_buf[UIP_LLH_LEN])
+#define UDPBUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
+
+
+#if UIP_STATISTICS == 1
+struct uip_stats uip_stat;
+#define UIP_STAT(s) s
+#else
+#define UIP_STAT(s)
+#endif /* UIP_STATISTICS == 1 */
+
+#if UIP_LOGGING == 1
+#include <stdio.h>
+void uip_log(char *msg);
+#define UIP_LOG(m) uip_log(m)
+#else
+#define UIP_LOG(m)
+#endif /* UIP_LOGGING == 1 */
+
+#if ! UIP_ARCH_ADD32
+void
+uip_add32(u8_t *op32, u16_t op16)
+{
+ uip_acc32[3] = op32[3] + (op16 & 0xff);
+ uip_acc32[2] = op32[2] + (op16 >> 8);
+ uip_acc32[1] = op32[1];
+ uip_acc32[0] = op32[0];
+
+ if(uip_acc32[2] < (op16 >> 8)) {
+ ++uip_acc32[1];
+ if(uip_acc32[1] == 0) {
+ ++uip_acc32[0];
+ }
+ }
+
+
+ if(uip_acc32[3] < (op16 & 0xff)) {
+ ++uip_acc32[2];
+ if(uip_acc32[2] == 0) {
+ ++uip_acc32[1];
+ if(uip_acc32[1] == 0) {
+ ++uip_acc32[0];
+ }
+ }
+ }
+}
+
+#endif /* UIP_ARCH_ADD32 */
+
+#if ! UIP_ARCH_CHKSUM
+/*---------------------------------------------------------------------------*/
+static u16_t
+chksum(u16_t sum, const u8_t *data, u16_t len)
+{
+ u16_t t;
+ const u8_t *dataptr;
+ const u8_t *last_byte;
+
+ dataptr = data;
+ last_byte = data + len - 1;
+
+ while(dataptr < last_byte) { /* At least two more bytes */
+ t = (dataptr[0] << 8) + dataptr[1];
+ sum += t;
+ if(sum < t) {
+ sum++; /* carry */
+ }
+ dataptr += 2;
+ }
+
+ if(dataptr == last_byte) {
+ t = (dataptr[0] << 8) + 0;
+ sum += t;
+ if(sum < t) {
+ sum++; /* carry */
+ }
+ }
+
+ /* Return sum in host byte order. */
+ return sum;
+}
+/*---------------------------------------------------------------------------*/
+u16_t
+uip_chksum(u16_t *data, u16_t len)
+{
+ return uip_htons(chksum(0, (u8_t *)data, len));
+}
+/*---------------------------------------------------------------------------*/
+#ifndef UIP_ARCH_IPCHKSUM
+u16_t
+uip_ipchksum(void)
+{
+ u16_t sum;
+
+ sum = chksum(0, &uip_buf[UIP_LLH_LEN], UIP_IPH_LEN);
+ DEBUG_PRINTF("uip_ipchksum: sum 0x%04x\n", sum);
+ return (sum == 0) ? 0xffff : uip_htons(sum);
+}
+#endif
+/*---------------------------------------------------------------------------*/
+static u16_t
+upper_layer_chksum(u8_t proto)
+{
+ u16_t upper_layer_len;
+ u16_t sum;
+
+#if UIP_CONF_IPV6
+ upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]);
+#else /* UIP_CONF_IPV6 */
+ upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - UIP_IPH_LEN;
+#endif /* UIP_CONF_IPV6 */
+
+ /* First sum pseudoheader. */
+
+ /* IP protocol and length fields. This addition cannot carry. */
+ sum = upper_layer_len + proto;
+ /* Sum IP source and destination addresses. */
+ sum = chksum(sum, (u8_t *)&BUF->srcipaddr[0], 2 * sizeof(uip_ipaddr_t));
+
+ /* Sum TCP header and data. */
+ sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN],
+ upper_layer_len);
+
+ return (sum == 0) ? 0xffff : uip_htons(sum);
+}
+/*---------------------------------------------------------------------------*/
+#if UIP_CONF_IPV6
+u16_t
+uip_icmp6chksum(void)
+{
+ return upper_layer_chksum(UIP_PROTO_ICMP6);
+
+}
+#endif /* UIP_CONF_IPV6 */
+/*---------------------------------------------------------------------------*/
+u16_t
+uip_tcpchksum(void)
+{
+ return upper_layer_chksum(UIP_PROTO_TCP);
+}
+/*---------------------------------------------------------------------------*/
+#if UIP_UDP_CHECKSUMS
+u16_t
+uip_udpchksum(void)
+{
+ //return 0;
+ return upper_layer_chksum(UIP_PROTO_UDP);
+}
+#endif /* UIP_UDP_CHECKSUMS */
+#endif /* UIP_ARCH_CHKSUM */
+/*---------------------------------------------------------------------------*/
+void
+uip_init(void)
+{
+ for(c = 0; c < UIP_LISTENPORTS; ++c) {
+ uip_listenports[c] = 0;
+ }
+ for(c = 0; c < UIP_CONNS; ++c) {
+ uip_conns[c].tcpstateflags = UIP_CLOSED;
+ }
+#if UIP_ACTIVE_OPEN
+ lastport = 1024;
+#endif /* UIP_ACTIVE_OPEN */
+
+#if UIP_UDP
+ for(c = 0; c < UIP_UDP_CONNS; ++c) {
+ uip_udp_conns[c].lport = 0;
+ }
+#endif /* UIP_UDP */
+
+
+ /* IPv4 initialization. */
+#if UIP_FIXEDADDR == 0
+ /* uip_hostaddr[0] = uip_hostaddr[1] = 0;*/
+#endif /* UIP_FIXEDADDR */
+
+}
+/*---------------------------------------------------------------------------*/
+#if UIP_ACTIVE_OPEN
+struct uip_conn *
+uip_connect(uip_ipaddr_t *ripaddr, u16_t rport)
+{
+ register struct uip_conn *conn, *cconn;
+
+ /* Find an unused local port. */
+ again:
+ ++lastport;
+
+ if(lastport >= 32000) {
+ lastport = 4096;
+ }
+
+ /* Check if this port is already in use, and if so try to find
+ another one. */
+ for(c = 0; c < UIP_CONNS; ++c) {
+ conn = &uip_conns[c];
+ if(conn->tcpstateflags != UIP_CLOSED &&
+ conn->lport == uip_htons(lastport)) {
+ goto again;
+ }
+ }
+
+ conn = 0;
+ for(c = 0; c < UIP_CONNS; ++c) {
+ cconn = &uip_conns[c];
+ if(cconn->tcpstateflags == UIP_CLOSED) {
+ conn = cconn;
+ break;
+ }
+ if(cconn->tcpstateflags == UIP_TIME_WAIT) {
+ if(conn == 0 ||
+ cconn->timer > conn->timer) {
+ conn = cconn;
+ }
+ }
+ }
+
+ if(conn == 0) {
+ return 0;
+ }
+
+ conn->tcpstateflags = UIP_SYN_SENT;
+
+ conn->snd_nxt[0] = iss[0];
+ conn->snd_nxt[1] = iss[1];
+ conn->snd_nxt[2] = iss[2];
+ conn->snd_nxt[3] = iss[3];
+
+ conn->initialmss = conn->mss = UIP_TCP_MSS;
+
+ conn->len = 1; /* TCP length of the SYN is one. */
+ conn->nrtx = 0;
+ conn->timer = 1; /* Send the SYN next time around. */
+ conn->rto = UIP_RTO;
+ conn->sa = 0;
+ conn->sv = 16; /* Initial value of the RTT variance. */
+ conn->lport = uip_htons(lastport);
+ conn->rport = rport;
+ uip_ipaddr_copy(&conn->ripaddr, ripaddr);
+
+ return conn;
+}
+#endif /* UIP_ACTIVE_OPEN */
+/*---------------------------------------------------------------------------*/
+#if UIP_UDP
+struct uip_udp_conn *
+uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport)
+{
+ register struct uip_udp_conn *conn;
+
+ /* Find an unused local port. */
+ again:
+ ++lastport;
+
+ if(lastport >= 32000) {
+ lastport = 4096;
+ }
+
+ for(c = 0; c < UIP_UDP_CONNS; ++c) {
+ if(uip_udp_conns[c].lport == uip_htons(lastport)) {
+ goto again;
+ }
+ }
+
+
+ conn = 0;
+ for(c = 0; c < UIP_UDP_CONNS; ++c) {
+ if(uip_udp_conns[c].lport == 0) {
+ conn = &uip_udp_conns[c];
+ break;
+ }
+ }
+
+ if(conn == 0) {
+ return 0;
+ }
+
+ conn->lport = HTONS(lastport);
+ conn->rport = rport;
+ if(ripaddr == NULL) {
+ memset(conn->ripaddr, 0, sizeof(uip_ipaddr_t));
+ } else {
+ uip_ipaddr_copy(&conn->ripaddr, ripaddr);
+ }
+ conn->ttl = UIP_TTL;
+
+ return conn;
+}
+#endif /* UIP_UDP */
+/*---------------------------------------------------------------------------*/
+void
+uip_unlisten(u16_t port)
+{
+ for(c = 0; c < UIP_LISTENPORTS; ++c) {
+ if(uip_listenports[c] == port) {
+ uip_listenports[c] = 0;
+ return;
+ }
+ }
+}
+/*---------------------------------------------------------------------------*/
+void
+uip_listen(u16_t port)
+{
+ for(c = 0; c < UIP_LISTENPORTS; ++c) {
+ if(uip_listenports[c] == 0) {
+ uip_listenports[c] = port;
+ return;
+ }
+ }
+}
+/*---------------------------------------------------------------------------*/
+/* XXX: IP fragment reassembly: not well-tested. */
+
+#if UIP_REASSEMBLY && !UIP_CONF_IPV6
+#define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN)
+static u8_t uip_reassbuf[UIP_REASS_BUFSIZE];
+static u8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)];
+static const u8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f,
+ 0x0f, 0x07, 0x03, 0x01};
+static u16_t uip_reasslen;
+static u8_t uip_reassflags;
+#define UIP_REASS_FLAG_LASTFRAG 0x01
+static u8_t uip_reasstmr;
+
+#define IP_MF 0x20
+
+static u8_t
+uip_reass(void)
+{
+ u16_t offset, len;
+ u16_t i;
+
+ /* If ip_reasstmr is zero, no packet is present in the buffer, so we
+ write the IP header of the fragment into the reassembly
+ buffer. The timer is updated with the maximum age. */
+ if(uip_reasstmr == 0) {
+ memcpy(uip_reassbuf, &BUF->vhl, UIP_IPH_LEN);
+ uip_reasstmr = UIP_REASS_MAXAGE;
+ uip_reassflags = 0;
+ /* Clear the bitmap. */
+ memset(uip_reassbitmap, 0, sizeof(uip_reassbitmap));
+ }
+
+ /* Check if the incoming fragment matches the one currently present
+ in the reasembly buffer. If so, we proceed with copying the
+ fragment into the buffer. */
+ if(BUF->srcipaddr[0] == FBUF->srcipaddr[0] &&
+ BUF->srcipaddr[1] == FBUF->srcipaddr[1] &&
+ BUF->destipaddr[0] == FBUF->destipaddr[0] &&
+ BUF->destipaddr[1] == FBUF->destipaddr[1] &&
+ BUF->ipid[0] == FBUF->ipid[0] &&
+ BUF->ipid[1] == FBUF->ipid[1]) {
+
+ len = (BUF->len[0] << 8) + BUF->len[1] - (BUF->vhl & 0x0f) * 4;
+ offset = (((BUF->ipoffset[0] & 0x3f) << 8) + BUF->ipoffset[1]) * 8;
+
+ /* If the offset or the offset + fragment length overflows the
+ reassembly buffer, we discard the entire packet. */
+ if(offset > UIP_REASS_BUFSIZE ||
+ offset + len > UIP_REASS_BUFSIZE) {
+ uip_reasstmr = 0;
+ goto nullreturn;
+ }
+
+ /* Copy the fragment into the reassembly buffer, at the right
+ offset. */
+ memcpy(&uip_reassbuf[UIP_IPH_LEN + offset],
+ (char *)BUF + (int)((BUF->vhl & 0x0f) * 4),
+ len);
+
+ /* Update the bitmap. */
+ if(offset / (8 * 8) == (offset + len) / (8 * 8)) {
+ /* If the two endpoints are in the same byte, we only update
+ that byte. */
+
+ uip_reassbitmap[offset / (8 * 8)] |=
+ bitmap_bits[(offset / 8 ) & 7] &
+ ~bitmap_bits[((offset + len) / 8 ) & 7];
+ } else {
+ /* If the two endpoints are in different bytes, we update the
+ bytes in the endpoints and fill the stuff inbetween with
+ 0xff. */
+ uip_reassbitmap[offset / (8 * 8)] |=
+ bitmap_bits[(offset / 8 ) & 7];
+ for(i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) {
+ uip_reassbitmap[i] = 0xff;
+ }
+ uip_reassbitmap[(offset + len) / (8 * 8)] |=
+ ~bitmap_bits[((offset + len) / 8 ) & 7];
+ }
+
+ /* If this fragment has the More Fragments flag set to zero, we
+ know that this is the last fragment, so we can calculate the
+ size of the entire packet. We also set the
+ IP_REASS_FLAG_LASTFRAG flag to indicate that we have received
+ the final fragment. */
+
+ if((BUF->ipoffset[0] & IP_MF) == 0) {
+ uip_reassflags |= UIP_REASS_FLAG_LASTFRAG;
+ uip_reasslen = offset + len;
+ }
+
+ /* Finally, we check if we have a full packet in the buffer. We do
+ this by checking if we have the last fragment and if all bits
+ in the bitmap are set. */
+ if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) {
+ /* Check all bytes up to and including all but the last byte in
+ the bitmap. */
+ for(i = 0; i < uip_reasslen / (8 * 8) - 1; ++i) {
+ if(uip_reassbitmap[i] != 0xff) {
+ goto nullreturn;
+ }
+ }
+ /* Check the last byte in the bitmap. It should contain just the
+ right amount of bits. */
+ if(uip_reassbitmap[uip_reasslen / (8 * 8)] !=
+ (u8_t)~bitmap_bits[uip_reasslen / 8 & 7]) {
+ goto nullreturn;
+ }
+
+ /* If we have come this far, we have a full packet in the
+ buffer, so we allocate a pbuf and copy the packet into it. We
+ also reset the timer. */
+ uip_reasstmr = 0;
+ memcpy(BUF, FBUF, uip_reasslen);
+
+ /* Pretend to be a "normal" (i.e., not fragmented) IP packet
+ from now on. */
+ BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
+ BUF->len[0] = uip_reasslen >> 8;
+ BUF->len[1] = uip_reasslen & 0xff;
+ BUF->ipchksum = 0;
+ BUF->ipchksum = ~(uip_ipchksum());
+
+ return uip_reasslen;
+ }
+ }
+
+ nullreturn:
+ return 0;
+}
+#endif /* UIP_REASSEMBLY */
+/*---------------------------------------------------------------------------*/
+static void
+uip_add_rcv_nxt(u16_t n)
+{
+ uip_add32(uip_conn->rcv_nxt, n);
+ uip_conn->rcv_nxt[0] = uip_acc32[0];
+ uip_conn->rcv_nxt[1] = uip_acc32[1];
+ uip_conn->rcv_nxt[2] = uip_acc32[2];
+ uip_conn->rcv_nxt[3] = uip_acc32[3];
+}
+/*---------------------------------------------------------------------------*/
+void
+uip_process(u8_t flag)
+{
+ register struct uip_conn *uip_connr = uip_conn;
+
+#if UIP_UDP
+ if(flag == UIP_UDP_SEND_CONN) {
+ goto udp_send;
+ }
+#endif /* UIP_UDP */
+
+ uip_sappdata = uip_appdata = &uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN];
+
+ /* Check if we were invoked because of a poll request for a
+ particular connection. */
+ if(flag == UIP_POLL_REQUEST) { //����uIP����һ�����ӱ��벻�ϱ���ѯ
+ if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED &&
+ !uip_outstanding(uip_connr)) {
+ uip_flags = UIP_POLL;
+ UIP_APPCALL();
+ goto appsend;
+ }
+ goto drop;
+
+ /* Check if we were invoked because of the perodic timer fireing. */
+ } else if(flag == UIP_TIMER) {
+#if UIP_REASSEMBLY
+ if(uip_reasstmr != 0) {
+ --uip_reasstmr;
+ }
+#endif /* UIP_REASSEMBLY */
+ /* Increase the initial sequence number. */
+ if(++iss[3] == 0) {
+ if(++iss[2] == 0) {
+ if(++iss[1] == 0) {
+ ++iss[0];
+ }
+ }
+ }
+
+ /* Reset the length variables. */
+ uip_len = 0;
+ uip_slen = 0;
+
+ /* Check if the connection is in a state in which we simply wait
+ for the connection to time out. If so, we increase the
+ connection's timer and remove the connection if it times
+ out. */
+ if(uip_connr->tcpstateflags == UIP_TIME_WAIT ||
+ uip_connr->tcpstateflags == UIP_FIN_WAIT_2) {
+ ++(uip_connr->timer);
+ if(uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) {
+ uip_connr->tcpstateflags = UIP_CLOSED;
+ }
+ } else if(uip_connr->tcpstateflags != UIP_CLOSED) {//�������û�б��رգ�������������Ҫ����
+ /* If the connection has outstanding data, we increase the
+ connection's timer and see if it has reached the RTO value
+ in which case we retransmit. */
+ if(uip_outstanding(uip_connr)) {//�����������Ҫ����
+ if(uip_connr->timer-- == 0) {
+ if(uip_connr->nrtx == UIP_MAXRTX ||
+ ((uip_connr->tcpstateflags == UIP_SYN_SENT ||
+ uip_connr->tcpstateflags == UIP_SYN_RCVD) &&
+ uip_connr->nrtx == UIP_MAXSYNRTX)) {
+ uip_connr->tcpstateflags = UIP_CLOSED;
+
+ /* We call UIP_APPCALL() with uip_flags set to
+ UIP_TIMEDOUT to inform the application that the
+ connection has timed out. */
+ uip_flags = UIP_TIMEDOUT;
+ UIP_APPCALL();
+
+ /* We also send a reset packet to the remote host. */
+ BUF->flags = TCP_RST | TCP_ACK;
+ goto tcp_send_nodata;
+ }
+
+ /* Exponential backoff. */
+ uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4?
+ 4:
+ uip_connr->nrtx);
+ ++(uip_connr->nrtx);
+
+ /* Ok, so we need to retransmit. We do this differently
+ depending on which state we are in. In ESTABLISHED, we
+ call upon the application so that it may prepare the
+ data for the retransmit. In SYN_RCVD, we resend the
+ SYNACK that we sent earlier and in LAST_ACK we have to
+ retransmit our FINACK. */
+ UIP_STAT(++uip_stat.tcp.rexmit);
+ switch(uip_connr->tcpstateflags & UIP_TS_MASK) {
+ case UIP_SYN_RCVD:
+ /* In the SYN_RCVD state, we should retransmit our
+ SYNACK. */
+ goto tcp_send_synack;
+
+#if UIP_ACTIVE_OPEN
+ case UIP_SYN_SENT: //��Ҫ����ͬ����
+ /* In the SYN_SENT state, we retransmit out SYN. */
+ BUF->flags = 0;
+ goto tcp_send_syn;
+#endif /* UIP_ACTIVE_OPEN */
+
+ case UIP_ESTABLISHED:
+ /* In the ESTABLISHED state, we call upon the application
+ to do the actual retransmit after which we jump into
+ the code for sending out the packet (the apprexmit
+ label). */
+ uip_flags = UIP_REXMIT;
+ UIP_APPCALL();
+ goto apprexmit;
+
+ case UIP_FIN_WAIT_1:
+ case UIP_CLOSING:
+ case UIP_LAST_ACK:
+ /* In all these states we should retransmit a FINACK. */
+ goto tcp_send_finack;
+
+ }
+ }
+ } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) { //�������������
+ /* If there was no need for a retransmission, we poll the
+ application for new data. */
+ uip_flags = UIP_POLL; //�������ò��ϱ���ѯ�ı�־
+ UIP_APPCALL();
+ goto appsend;
+ }
+ }
+ goto drop;
+ }
+#if UIP_UDP
+ if(flag == UIP_UDP_TIMER) {
+ if(uip_udp_conn->lport != 0) {
+ uip_conn = NULL;
+ uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
+ uip_len = uip_slen = 0;
+ uip_flags = UIP_POLL;
+ UIP_UDP_APPCALL();
+ goto udp_send;
+ } else {
+ goto drop;
+ }
+ }
+#endif
+//����յ�IP����������↑ʼ
+ /* This is where the input processing starts. */
+ UIP_STAT(++uip_stat.ip.recv);
+
+ /* Start of IP input header processing code. */
+
+#if UIP_CONF_IPV6
+ /* Check validity of the IP header. */
+ if((BUF->vtc & 0xf0) != 0x60) { /* IP version and header length. */
+ UIP_STAT(++uip_stat.ip.drop);
+ UIP_STAT(++uip_stat.ip.vhlerr);
+ UIP_LOG("ipv6: invalid version.");
+ goto drop;
+ }
+#else /* UIP_CONF_IPV6 */
+ /* Check validity of the IP header. */
+ if(BUF->vhl != 0x45) { /* IP version and header length. */
+ UIP_STAT(++uip_stat.ip.drop);
+ UIP_STAT(++uip_stat.ip.vhlerr);
+ UIP_LOG("ip: invalid version or header length.");
+ goto drop;
+ }
+#endif /* UIP_CONF_IPV6 */
+
+ /* Check the size of the packet. If the size reported to us in
+ uip_len is smaller the size reported in the IP header, we assume
+ that the packet has been corrupted in transit. If the size of
+ uip_len is larger than the size reported in the IP packet header,
+ the packet has been padded and we set uip_len to the correct
+ value.. */
+
+ if((BUF->len[0] << 8) + BUF->len[1] <= uip_len) {
+ uip_len = (BUF->len[0] << 8) + BUF->len[1];
+#if UIP_CONF_IPV6
+ uip_len += 40; /* The length reported in the IPv6 header is the
+ length of the payload that follows the
+ header. However, uIP uses the uip_len variable
+ for holding the size of the entire packet,
+ including the IP header. For IPv4 this is not a
+ problem as the length field in the IPv4 header
+ contains the length of the entire packet. But
+ for IPv6 we need to add the size of the IPv6
+ header (40 bytes). */
+#endif /* UIP_CONF_IPV6 */
+ } else {
+ UIP_LOG("ip: packet shorter than reported in IP header.");
+ goto drop;
+ }
+
+#if !UIP_CONF_IPV6
+ /* Check the fragment flag. */
+ if((BUF->ipoffset[0] & 0x3f) != 0 ||
+ BUF->ipoffset[1] != 0) {
+#if UIP_REASSEMBLY
+ uip_len = uip_reass();
+ if(uip_len == 0) {
+ goto drop;
+ }
+#else /* UIP_REASSEMBLY */
+ UIP_STAT(++uip_stat.ip.drop);
+ UIP_STAT(++uip_stat.ip.fragerr);
+ UIP_LOG("ip: fragment dropped.");
+ goto drop;
+#endif /* UIP_REASSEMBLY */
+ }
+#endif /* UIP_CONF_IPV6 */
+
+ if(uip_ipaddr_cmp(uip_hostaddr, all_zeroes_addr)) {
+ /* If we are configured to use ping IP address configuration and
+ hasn't been assigned an IP address yet, we accept all ICMP
+ packets. */
+#if UIP_PINGADDRCONF && !UIP_CONF_IPV6
+ if(BUF->proto == UIP_PROTO_ICMP) {
+ UIP_LOG("ip: possible ping config packet received.");
+ goto icmp_input;
+ } else {
+ UIP_LOG("ip: packet dropped since no address assigned.");
+ goto drop;
+ }
+#endif /* UIP_PINGADDRCONF */
+
+ } else {
+ /* If IP broadcast support is configured, we check for a broadcast
+ UDP packet, which may be destined to us. */
+#if UIP_BROADCAST
+ DEBUG_PRINTF("UDP IP checksum 0x%04x\n", uip_ipchksum());
+ if(BUF->proto == UIP_PROTO_UDP &&
+ uip_ipaddr_cmp(BUF->destipaddr, all_ones_addr)
+ /*&&
+ uip_ipchksum() == 0xffff*/) {
+ goto udp_input;
+ }
+#endif /* UIP_BROADCAST */
+
+ /* Check if the packet is destined for our IP address. */
+#if !UIP_CONF_IPV6
+ if(!uip_ipaddr_cmp(BUF->destipaddr, uip_hostaddr)) {
+ UIP_STAT(++uip_stat.ip.drop);
+ goto drop;
+ }
+#else /* UIP_CONF_IPV6 */
+ /* For IPv6, packet reception is a little trickier as we need to
+ make sure that we listen to certain multicast addresses (all
+ hosts multicast address, and the solicited-node multicast
+ address) as well. However, we will cheat here and accept all
+ multicast packets that are sent to the ff02::/16 addresses. */
+ if(!uip_ipaddr_cmp(BUF->destipaddr, uip_hostaddr) &&
+ BUF->destipaddr[0] != HTONS(0xff02)) {
+ UIP_STAT(++uip_stat.ip.drop);
+ goto drop;
+ }
+#endif /* UIP_CONF_IPV6 */
+ }
+
+#if !UIP_CONF_IPV6
+ if(uip_ipchksum() != 0xffff) { /* Compute and check the IP header
+ checksum. */
+ UIP_STAT(++uip_stat.ip.drop);
+ UIP_STAT(++uip_stat.ip.chkerr);
+ UIP_LOG("ip: bad checksum.");
+ goto drop;
+ }
+#endif /* UIP_CONF_IPV6 */
+
+ if(BUF->proto == UIP_PROTO_TCP) { /* Check for TCP packet. If so,
+ proceed with TCP input
+ processing. */
+ goto tcp_input;
+ }
+
+#if UIP_UDP
+ if(BUF->proto == UIP_PROTO_UDP) {
+ goto udp_input;
+ }
+#endif /* UIP_UDP */
+
+#if !UIP_CONF_IPV6
+ /* ICMPv4 processing code follows. */
+ if(BUF->proto != UIP_PROTO_ICMP) { /* We only allow ICMP packets from
+ here. */
+ UIP_STAT(++uip_stat.ip.drop);
+ UIP_STAT(++uip_stat.ip.protoerr);
+ UIP_LOG("ip: neither tcp nor icmp.");
+ goto drop;
+ }
+
+#if UIP_PINGADDRCONF
+ icmp_input:
+#endif /* UIP_PINGADDRCONF */
+ UIP_STAT(++uip_stat.icmp.recv);
+
+ /* ICMP echo (i.e., ping) processing. This is simple, we only change
+ the ICMP type from ECHO to ECHO_REPLY and adjust the ICMP
+ checksum before we return the packet. */
+ if(ICMPBUF->type != ICMP_ECHO) {
+ UIP_STAT(++uip_stat.icmp.drop);
+ UIP_STAT(++uip_stat.icmp.typeerr);
+ UIP_LOG("icmp: not icmp echo.");
+ goto drop;
+ }
+
+ /* If we are configured to use ping IP address assignment, we use
+ the destination IP address of this ping packet and assign it to
+ ourself. */
+#if UIP_PINGADDRCONF
+ if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) {
+ uip_hostaddr[0] = BUF->destipaddr[0];
+ uip_hostaddr[1] = BUF->destipaddr[1];
+ }
+#endif /* UIP_PINGADDRCONF */
+
+ ICMPBUF->type = ICMP_ECHO_REPLY;
+
+ if(ICMPBUF->icmpchksum >= HTONS(0xffff - (ICMP_ECHO << 8))) {
+ ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8) + 1;
+ } else {
+ ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8);
+ }
+
+ /* Swap IP addresses. */
+ uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr);
+ uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
+
+ UIP_STAT(++uip_stat.icmp.sent);
+ goto send;
+
+ /* End of IPv4 input header processing code. */
+#else /* !UIP_CONF_IPV6 */
+
+ /* This is IPv6 ICMPv6 processing code. */
+ DEBUG_PRINTF("icmp6_input: length %d\n", uip_len);
+
+ if(BUF->proto != UIP_PROTO_ICMP6) { /* We only allow ICMPv6 packets from
+ here. */
+ UIP_STAT(++uip_stat.ip.drop);
+ UIP_STAT(++uip_stat.ip.protoerr);
+ UIP_LOG("ip: neither tcp nor icmp6.");
+ goto drop;
+ }
+
+ UIP_STAT(++uip_stat.icmp.recv);
+
+ /* If we get a neighbor solicitation for our address we should send
+ a neighbor advertisement message back. */
+ if(ICMPBUF->type == ICMP6_NEIGHBOR_SOLICITATION) {
+ if(uip_ipaddr_cmp(ICMPBUF->icmp6data, uip_hostaddr)) {
+
+ if(ICMPBUF->options[0] == ICMP6_OPTION_SOURCE_LINK_ADDRESS) {
+ /* Save the sender's address in our neighbor list. */
+ uip_neighbor_add(ICMPBUF->srcipaddr, &(ICMPBUF->options[2]));
+ }
+
+ /* We should now send a neighbor advertisement back to where the
+ neighbor solicication came from. */
+ ICMPBUF->type = ICMP6_NEIGHBOR_ADVERTISEMENT;
+ ICMPBUF->flags = ICMP6_FLAG_S; /* Solicited flag. */
+
+ ICMPBUF->reserved1 = ICMPBUF->reserved2 = ICMPBUF->reserved3 = 0;
+
+ uip_ipaddr_copy(ICMPBUF->destipaddr, ICMPBUF->srcipaddr);
+ uip_ipaddr_copy(ICMPBUF->srcipaddr, uip_hostaddr);
+ ICMPBUF->options[0] = ICMP6_OPTION_TARGET_LINK_ADDRESS;
+ ICMPBUF->options[1] = 1; /* Options length, 1 = 8 bytes. */
+ memcpy(&(ICMPBUF->options[2]), &uip_ethaddr, sizeof(uip_ethaddr));
+ ICMPBUF->icmpchksum = 0;
+ ICMPBUF->icmpchksum = ~uip_icmp6chksum();
+ goto send;
+
+ }
+ goto drop;
+ } else if(ICMPBUF->type == ICMP6_ECHO) {
+ /* ICMP echo (i.e., ping) processing. This is simple, we only
+ change the ICMP type from ECHO to ECHO_REPLY and update the
+ ICMP checksum before we return the packet. */
+
+ ICMPBUF->type = ICMP6_ECHO_REPLY;
+
+ uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr);
+ uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
+ ICMPBUF->icmpchksum = 0;
+ ICMPBUF->icmpchksum = ~uip_icmp6chksum();
+
+ UIP_STAT(++uip_stat.icmp.sent);
+ goto send;
+ } else {
+ DEBUG_PRINTF("Unknown icmp6 message type %d\n", ICMPBUF->type);
+ UIP_STAT(++uip_stat.icmp.drop);
+ UIP_STAT(++uip_stat.icmp.typeerr);
+ UIP_LOG("icmp: unknown ICMP message.");
+ goto drop;
+ }
+
+ /* End of IPv6 ICMP processing. */
+
+#endif /* !UIP_CONF_IPV6 */
+
+#if UIP_UDP
+ /* UDP input processing. */
+ udp_input:
+ /* UDP processing is really just a hack. We don't do anything to the
+ UDP/IP headers, but let the UDP application do all the hard
+ work. If the application sets uip_slen, it has a packet to
+ send. */
+#if UIP_UDP_CHECKSUMS
+ uip_len = uip_len - UIP_IPUDPH_LEN;
+ uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
+ if(UDPBUF->udpchksum != 0 && uip_udpchksum() != 0xffff) {
+ UIP_STAT(++uip_stat.udp.drop);
+ UIP_STAT(++uip_stat.udp.chkerr);
+ UIP_LOG("udp: bad checksum.");
+ goto drop;
+ }
+#else /* UIP_UDP_CHECKSUMS */
+ uip_len = uip_len - UIP_IPUDPH_LEN;
+#endif /* UIP_UDP_CHECKSUMS */
+
+ /* Demultiplex this UDP packet between the UDP "connections". */
+ for(uip_udp_conn = &uip_udp_conns[0];
+ uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS];
+ ++uip_udp_conn) {
+ /* If the local UDP port is non-zero, the connection is considered
+ to be used. If so, the local port number is checked against the
+ destination port number in the received packet. If the two port
+ numbers match, the remote port number is checked if the
+ connection is bound to a remote port. Finally, if the
+ connection is bound to a remote IP address, the source IP
+ address of the packet is checked. */
+ if(uip_udp_conn->lport != 0 &&
+ UDPBUF->destport == uip_udp_conn->lport &&
+ (uip_udp_conn->rport == 0 ||
+ UDPBUF->srcport == uip_udp_conn->rport) &&
+ (uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_zeroes_addr) ||
+ uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_ones_addr) ||
+ uip_ipaddr_cmp(BUF->srcipaddr, uip_udp_conn->ripaddr))) {
+ goto udp_found;
+ }
+ }
+ UIP_LOG("udp: no matching connection found");
+ goto drop;
+
+ udp_found:
+ uip_conn = NULL;
+ uip_flags = UIP_NEWDATA;
+ uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
+ uip_slen = 0;
+ UIP_UDP_APPCALL();
+ udp_send:
+ if(uip_slen == 0) {
+ goto drop;
+ }
+ uip_len = uip_slen + UIP_IPUDPH_LEN;
+
+#if UIP_CONF_IPV6
+ /* For IPv6, the IP length field does not include the IPv6 IP header
+ length. */
+ BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
+ BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
+#else /* UIP_CONF_IPV6 */
+ BUF->len[0] = (uip_len >> 8);
+ BUF->len[1] = (uip_len & 0xff);
+#endif /* UIP_CONF_IPV6 */
+
+ BUF->ttl = uip_udp_conn->ttl;
+ BUF->proto = UIP_PROTO_UDP;
+
+ UDPBUF->udplen = HTONS(uip_slen + UIP_UDPH_LEN);
+ UDPBUF->udpchksum = 0;
+
+ BUF->srcport = uip_udp_conn->lport;
+ BUF->destport = uip_udp_conn->rport;
+
+ uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
+ uip_ipaddr_copy(BUF->destipaddr, uip_udp_conn->ripaddr);
+
+ uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPTCPH_LEN];
+
+#if UIP_UDP_CHECKSUMS
+ /* Calculate UDP checksum. */
+ UDPBUF->udpchksum = ~(uip_udpchksum());
+ if(UDPBUF->udpchksum == 0) {
+ UDPBUF->udpchksum = 0xffff;
+ }
+#endif /* UIP_UDP_CHECKSUMS */
+
+ goto ip_send_nolen;
+#endif /* UIP_UDP */
+
+ /* TCP input processing. */
+ tcp_input:
+ UIP_STAT(++uip_stat.tcp.recv);
+
+ /* Start of TCP input header processing code. */
+
+ if(uip_tcpchksum() != 0xffff) { /* Compute and check the TCP
+ checksum. */
+ UIP_STAT(++uip_stat.tcp.drop);
+ UIP_STAT(++uip_stat.tcp.chkerr);
+ UIP_LOG("tcp: bad checksum.");
+ goto drop;
+ }
+
+
+ /* Demultiplex this segment. */
+ /* First check any active connections. */
+ for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[UIP_CONNS - 1];
+ ++uip_connr) {
+ if(uip_connr->tcpstateflags != UIP_CLOSED &&
+ BUF->destport == uip_connr->lport &&
+ BUF->srcport == uip_connr->rport &&
+ uip_ipaddr_cmp(BUF->srcipaddr, uip_connr->ripaddr)) {
+ goto found;
+ }
+ }
+
+ /* If we didn't find and active connection that expected the packet,
+ either this packet is an old duplicate, or this is a SYN packet
+ destined for a connection in LISTEN. If the SYN flag isn't set,
+ it is an old packet and we send a RST. */
+ if((BUF->flags & TCP_CTL) != TCP_SYN) {
+ goto reset;
+ }
+
+ tmp16 = BUF->destport;
+ /* Next, check listening connections. */
+ for(c = 0; c < UIP_LISTENPORTS; ++c) {
+ if(tmp16 == uip_listenports[c])
+ goto found_listen;
+ }
+
+ /* No matching connection found, so we send a RST packet. */
+ UIP_STAT(++uip_stat.tcp.synrst);
+ reset:
+
+ /* We do not send resets in response to resets. */
+ if(BUF->flags & TCP_RST) {
+ goto drop;
+ }
+
+ UIP_STAT(++uip_stat.tcp.rst);
+
+ BUF->flags = TCP_RST | TCP_ACK;
+ uip_len = UIP_IPTCPH_LEN;
+ BUF->tcpoffset = 5 << 4;
+
+ /* Flip the seqno and ackno fields in the TCP header. */
+ c = BUF->seqno[3];
+ BUF->seqno[3] = BUF->ackno[3];
+ BUF->ackno[3] = c;
+
+ c = BUF->seqno[2];
+ BUF->seqno[2] = BUF->ackno[2];
+ BUF->ackno[2] = c;
+
+ c = BUF->seqno[1];
+ BUF->seqno[1] = BUF->ackno[1];
+ BUF->ackno[1] = c;
+
+ c = BUF->seqno[0];
+ BUF->seqno[0] = BUF->ackno[0];
+ BUF->ackno[0] = c;
+
+ /* We also have to increase the sequence number we are
+ acknowledging. If the least significant byte overflowed, we need
+ to propagate the carry to the other bytes as well. */
+ if(++BUF->ackno[3] == 0) {
+ if(++BUF->ackno[2] == 0) {
+ if(++BUF->ackno[1] == 0) {
+ ++BUF->ackno[0];
+ }
+ }
+ }
+
+ /* Swap port numbers. */
+ tmp16 = BUF->srcport;
+ BUF->srcport = BUF->destport;
+ BUF->destport = tmp16;
+
+ /* Swap IP addresses. */
+ uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr);
+ uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
+
+ /* And send out the RST packet! */
+ goto tcp_send_noconn;
+
+ /* This label will be jumped to if we matched the incoming packet
+ with a connection in LISTEN. In that case, we should create a new
+ connection and send a SYNACK in return. */
+ found_listen:
+ /* First we check if there are any connections avaliable. Unused
+ connections are kept in the same table as used connections, but
+ unused ones have the tcpstate set to CLOSED. Also, connections in
+ TIME_WAIT are kept track of and we'll use the oldest one if no
+ CLOSED connections are found. Thanks to Eddie C. Dost for a very
+ nice algorithm for the TIME_WAIT search. */
+ uip_connr = 0;
+ for(c = 0; c < UIP_CONNS; ++c) {
+ if(uip_conns[c].tcpstateflags == UIP_CLOSED) {
+ uip_connr = &uip_conns[c];
+ break;
+ }
+ if(uip_conns[c].tcpstateflags == UIP_TIME_WAIT) {
+ if(uip_connr == 0 ||
+ uip_conns[c].timer > uip_connr->timer) {
+ uip_connr = &uip_conns[c];
+ }
+ }
+ }
+
+ if(uip_connr == 0) {
+ /* All connections are used already, we drop packet and hope that
+ the remote end will retransmit the packet at a time when we
+ have more spare connections. */
+ UIP_STAT(++uip_stat.tcp.syndrop);
+ UIP_LOG("tcp: found no unused connections.");
+ goto drop;
+ }
+ uip_conn = uip_connr;
+
+ /* Fill in the necessary fields for the new connection. */
+ uip_connr->rto = uip_connr->timer = UIP_RTO;
+ uip_connr->sa = 0;
+ uip_connr->sv = 4;
+ uip_connr->nrtx = 0;
+ uip_connr->lport = BUF->destport;
+ uip_connr->rport = BUF->srcport;
+ uip_ipaddr_copy(uip_connr->ripaddr, BUF->srcipaddr);
+ uip_connr->tcpstateflags = UIP_SYN_RCVD;
+
+ uip_connr->snd_nxt[0] = iss[0];
+ uip_connr->snd_nxt[1] = iss[1];
+ uip_connr->snd_nxt[2] = iss[2];
+ uip_connr->snd_nxt[3] = iss[3];
+ uip_connr->len = 1;
+
+ /* rcv_nxt should be the seqno from the incoming packet + 1. */
+ uip_connr->rcv_nxt[3] = BUF->seqno[3];
+ uip_connr->rcv_nxt[2] = BUF->seqno[2];
+ uip_connr->rcv_nxt[1] = BUF->seqno[1];
+ uip_connr->rcv_nxt[0] = BUF->seqno[0];
+ uip_add_rcv_nxt(1);
+
+ /* Parse the TCP MSS option, if present. */
+ if((BUF->tcpoffset & 0xf0) > 0x50) {
+ for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
+ opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c];
+ if(opt == TCP_OPT_END) {
+ /* End of options. */
+ break;
+ } else if(opt == TCP_OPT_NOOP) {
+ ++c;
+ /* NOP option. */
+ } else if(opt == TCP_OPT_MSS &&
+ uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
+ /* An MSS option with the right option length. */
+ tmp16 = ((u16_t)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
+ (u16_t)uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + c];
+ uip_connr->initialmss = uip_connr->mss =
+ tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
+
+ /* And we are done processing options. */
+ break;
+ } else {
+ /* All other options have a length field, so that we easily
+ can skip past them. */
+ if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
+ /* If the length field is zero, the options are malformed
+ and we don't process them further. */
+ break;
+ }
+ c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
+ }
+ }
+ }
+
+ /* Our response will be a SYNACK. */
+#if UIP_ACTIVE_OPEN
+ tcp_send_synack:
+ BUF->flags = TCP_ACK;
+
+ tcp_send_syn:
+ BUF->flags |= TCP_SYN;
+#else /* UIP_ACTIVE_OPEN */
+ tcp_send_synack:
+ BUF->flags = TCP_SYN | TCP_ACK;
+#endif /* UIP_ACTIVE_OPEN */
+
+ /* We send out the TCP Maximum Segment Size option with our
+ SYNACK. */
+ BUF->optdata[0] = TCP_OPT_MSS;
+ BUF->optdata[1] = TCP_OPT_MSS_LEN;
+ BUF->optdata[2] = (UIP_TCP_MSS) / 256;
+ BUF->optdata[3] = (UIP_TCP_MSS) & 255;
+ uip_len = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN;
+ BUF->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4;
+ goto tcp_send;
+
+ /* This label will be jumped to if we found an active connection. */
+ found:
+ uip_conn = uip_connr;
+ uip_flags = 0;
+ /* We do a very naive form of TCP reset processing; we just accept
+ any RST and kill our connection. We should in fact check if the
+ sequence number of this reset is wihtin our advertised window
+ before we accept the reset. */
+ if(BUF->flags & TCP_RST) {
+ uip_connr->tcpstateflags = UIP_CLOSED;
+ UIP_LOG("tcp: got reset, aborting connection.");
+ uip_flags = UIP_ABORT;
+ UIP_APPCALL();
+ goto drop;
+ }
+ /* Calculated the length of the data, if the application has sent
+ any data to us. */
+ c = (BUF->tcpoffset >> 4) << 2;
+ /* uip_len will contain the length of the actual TCP data. This is
+ calculated by subtracing the length of the TCP header (in
+ c) and the length of the IP header (20 bytes). */
+ uip_len = uip_len - c - UIP_IPH_LEN;
+
+ /* First, check if the sequence number of the incoming packet is
+ what we're expecting next. If not, we send out an ACK with the
+ correct numbers in. */
+ if(!(((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) &&
+ ((BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)))) {
+ if((uip_len > 0 || ((BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) &&
+ (BUF->seqno[0] != uip_connr->rcv_nxt[0] ||
+ BUF->seqno[1] != uip_connr->rcv_nxt[1] ||
+ BUF->seqno[2] != uip_connr->rcv_nxt[2] ||
+ BUF->seqno[3] != uip_connr->rcv_nxt[3])) {
+ goto tcp_send_ack;
+ }
+ }
+
+ /* Next, check if the incoming segment acknowledges any outstanding
+ data. If so, we update the sequence number, reset the length of
+ the outstanding data, calculate RTT estimations, and reset the
+ retransmission timer. */
+ if((BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) {
+ uip_add32(uip_connr->snd_nxt, uip_connr->len);
+
+ if(BUF->ackno[0] == uip_acc32[0] &&
+ BUF->ackno[1] == uip_acc32[1] &&
+ BUF->ackno[2] == uip_acc32[2] &&
+ BUF->ackno[3] == uip_acc32[3]) {
+ /* Update sequence number. */
+ uip_connr->snd_nxt[0] = uip_acc32[0];
+ uip_connr->snd_nxt[1] = uip_acc32[1];
+ uip_connr->snd_nxt[2] = uip_acc32[2];
+ uip_connr->snd_nxt[3] = uip_acc32[3];
+
+
+ /* Do RTT estimation, unless we have done retransmissions. */
+ if(uip_connr->nrtx == 0) {
+ signed char m;
+ m = uip_connr->rto - uip_connr->timer;
+ /* This is taken directly from VJs original code in his paper */
+ m = m - (uip_connr->sa >> 3);
+ uip_connr->sa += m;
+ if(m < 0) {
+ m = -m;
+ }
+ m = m - (uip_connr->sv >> 2);
+ uip_connr->sv += m;
+ uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv;
+
+ }
+ /* Set the acknowledged flag. */
+ uip_flags = UIP_ACKDATA;
+ /* Reset the retransmission timer. */
+ uip_connr->timer = uip_connr->rto;
+
+ /* Reset length of outstanding data. */
+ uip_connr->len = 0;
+ }
+
+ }
+
+ /* Do different things depending on in what state the connection is. */
+ switch(uip_connr->tcpstateflags & UIP_TS_MASK) {
+ /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not
+ implemented, since we force the application to close when the
+ peer sends a FIN (hence the application goes directly from
+ ESTABLISHED to LAST_ACK). */
+ case UIP_SYN_RCVD:
+ /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and
+ we are waiting for an ACK that acknowledges the data we sent
+ out the last time. Therefore, we want to have the UIP_ACKDATA
+ flag set. If so, we enter the ESTABLISHED state. */
+ if(uip_flags & UIP_ACKDATA) {
+ uip_connr->tcpstateflags = UIP_ESTABLISHED;
+ uip_flags = UIP_CONNECTED;
+ uip_connr->len = 0;
+ if(uip_len > 0) {
+ uip_flags |= UIP_NEWDATA;
+ uip_add_rcv_nxt(uip_len);
+ }
+ uip_slen = 0;
+ UIP_APPCALL();
+ goto appsend;
+ }
+ goto drop;
+#if UIP_ACTIVE_OPEN
+ case UIP_SYN_SENT:
+ /* In SYN_SENT, we wait for a SYNACK that is sent in response to
+ our SYN. The rcv_nxt is set to sequence number in the SYNACK
+ plus one, and we send an ACK. We move into the ESTABLISHED
+ state. */
+ if((uip_flags & UIP_ACKDATA) &&
+ (BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) {
+
+ /* Parse the TCP MSS option, if present. */
+ if((BUF->tcpoffset & 0xf0) > 0x50) {
+ for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) {
+ opt = uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + c];
+ if(opt == TCP_OPT_END) {
+ /* End of options. */
+ break;
+ } else if(opt == TCP_OPT_NOOP) {
+ ++c;
+ /* NOP option. */
+ } else if(opt == TCP_OPT_MSS &&
+ uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
+ /* An MSS option with the right option length. */
+ tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
+ uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c];
+ uip_connr->initialmss =
+ uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
+
+ /* And we are done processing options. */
+ break;
+ } else {
+ /* All other options have a length field, so that we easily
+ can skip past them. */
+ if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
+ /* If the length field is zero, the options are malformed
+ and we don't process them further. */
+ break;
+ }
+ c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
+ }
+ }
+ }
+ uip_connr->tcpstateflags = UIP_ESTABLISHED;
+ uip_connr->rcv_nxt[0] = BUF->seqno[0];
+ uip_connr->rcv_nxt[1] = BUF->seqno[1];
+ uip_connr->rcv_nxt[2] = BUF->seqno[2];
+ uip_connr->rcv_nxt[3] = BUF->seqno[3];
+ uip_add_rcv_nxt(1);
+ uip_flags = UIP_CONNECTED | UIP_NEWDATA;
+ uip_connr->len = 0;
+ uip_len = 0;
+ uip_slen = 0;
+ UIP_APPCALL();
+ goto appsend;
+ }
+ /* Inform the application that the connection failed */
+ uip_flags = UIP_ABORT;
+ UIP_APPCALL();
+ /* The connection is closed after we send the RST */
+ uip_conn->tcpstateflags = UIP_CLOSED;
+ goto reset;
+#endif /* UIP_ACTIVE_OPEN */
+
+ case UIP_ESTABLISHED:
+ /* In the ESTABLISHED state, we call upon the application to feed
+ data into the uip_buf. If the UIP_ACKDATA flag is set, the
+ application should put new data into the buffer, otherwise we are
+ retransmitting an old segment, and the application should put that
+ data into the buffer.
+
+ If the incoming packet is a FIN, we should close the connection on
+ this side as well, and we send out a FIN and enter the LAST_ACK
+ state. We require that there is no outstanding data; otherwise the
+ sequence numbers will be screwed up. */
+
+ if(BUF->flags & TCP_FIN && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
+ if(uip_outstanding(uip_connr)) {
+ goto drop;
+ }
+ uip_add_rcv_nxt(1 + uip_len);
+ uip_flags |= UIP_CLOSE;
+ if(uip_len > 0) {
+ uip_flags |= UIP_NEWDATA;
+ }
+ UIP_APPCALL();
+ uip_connr->len = 1;
+ uip_connr->tcpstateflags = UIP_LAST_ACK;
+ uip_connr->nrtx = 0;
+ tcp_send_finack:
+ BUF->flags = TCP_FIN | TCP_ACK;
+ goto tcp_send_nodata;
+ }
+
+ /* Check the URG flag. If this is set, the segment carries urgent
+ data that we must pass to the application. */
+ if((BUF->flags & TCP_URG) != 0) {
+#if UIP_URGDATA > 0
+ uip_urglen = (BUF->urgp[0] << 8) | BUF->urgp[1];
+ if(uip_urglen > uip_len) {
+ /* There is more urgent data in the next segment to come. */
+ uip_urglen = uip_len;
+ }
+ uip_add_rcv_nxt(uip_urglen);
+ uip_len -= uip_urglen;
+ uip_urgdata = uip_appdata;
+ uip_appdata += uip_urglen;
+ } else {
+ uip_urglen = 0;
+#else /* UIP_URGDATA > 0 */
+ uip_appdata = ((char *)uip_appdata) + ((BUF->urgp[0] << 8) | BUF->urgp[1]);
+ uip_len -= (BUF->urgp[0] << 8) | BUF->urgp[1];
+#endif /* UIP_URGDATA > 0 */
+ }
+
+ /* If uip_len > 0 we have TCP data in the packet, and we flag this
+ by setting the UIP_NEWDATA flag and update the sequence number
+ we acknowledge. If the application has stopped the dataflow
+ using uip_stop(), we must not accept any data packets from the
+ remote host. */
+ if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) {
+ uip_flags |= UIP_NEWDATA;
+ uip_add_rcv_nxt(uip_len);
+ }
+
+ /* Check if the available buffer space advertised by the other end
+ is smaller than the initial MSS for this connection. If so, we
+ set the current MSS to the window size to ensure that the
+ application does not send more data than the other end can
+ handle.
+
+ If the remote host advertises a zero window, we set the MSS to
+ the initial MSS so that the application will send an entire MSS
+ of data. This data will not be acknowledged by the receiver,
+ and the application will retransmit it. This is called the
+ "persistent timer" and uses the retransmission mechanim.
+ */
+ tmp16 = ((u16_t)BUF->wnd[0] << 8) + (u16_t)BUF->wnd[1];
+ if(tmp16 > uip_connr->initialmss ||
+ tmp16 == 0) {
+ tmp16 = uip_connr->initialmss;
+ }
+ uip_connr->mss = tmp16;
+
+ /* If this packet constitutes an ACK for outstanding data (flagged
+ by the UIP_ACKDATA flag, we should call the application since it
+ might want to send more data. If the incoming packet had data
+ from the peer (as flagged by the UIP_NEWDATA flag), the
+ application must also be notified.
+
+ When the application is called, the global variable uip_len
+ contains the length of the incoming data. The application can
+ access the incoming data through the global pointer
+ uip_appdata, which usually points UIP_IPTCPH_LEN + UIP_LLH_LEN
+ bytes into the uip_buf array.
+
+ If the application wishes to send any data, this data should be
+ put into the uip_appdata and the length of the data should be
+ put into uip_len. If the application don't have any data to
+ send, uip_len must be set to 0. */
+ if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) {
+ uip_slen = 0;
+ UIP_APPCALL();
+
+ appsend:
+
+ if(uip_flags & UIP_ABORT) {
+ uip_slen = 0;
+ uip_connr->tcpstateflags = UIP_CLOSED;
+ BUF->flags = TCP_RST | TCP_ACK;
+ goto tcp_send_nodata;
+ }
+
+ if(uip_flags & UIP_CLOSE) {
+ uip_slen = 0;
+ uip_connr->len = 1;
+ uip_connr->tcpstateflags = UIP_FIN_WAIT_1;
+ uip_connr->nrtx = 0;
+ BUF->flags = TCP_FIN | TCP_ACK;
+ goto tcp_send_nodata;
+ }
+
+ /* If uip_slen > 0, the application has data to be sent. */
+ if(uip_slen > 0) {
+
+ /* If the connection has acknowledged data, the contents of
+ the ->len variable should be discarded. */
+ if((uip_flags & UIP_ACKDATA) != 0) {
+ uip_connr->len = 0;
+ }
+
+ /* If the ->len variable is non-zero the connection has
+ already data in transit and cannot send anymore right
+ now. */
+ if(uip_connr->len == 0) {
+
+ /* The application cannot send more than what is allowed by
+ the mss (the minumum of the MSS and the available
+ window). */
+ if(uip_slen > uip_connr->mss) {
+ uip_slen = uip_connr->mss;
+ }
+
+ /* Remember how much data we send out now so that we know
+ when everything has been acknowledged. */
+ uip_connr->len = uip_slen;
+ } else {
+
+ /* If the application already had unacknowledged data, we
+ make sure that the application does not send (i.e.,
+ retransmit) out more than it previously sent out. */
+ uip_slen = uip_connr->len;
+ }
+ }
+ uip_connr->nrtx = 0;
+ apprexmit:
+ uip_appdata = uip_sappdata;
+
+ /* If the application has data to be sent, or if the incoming
+ packet had new data in it, we must send out a packet. */
+ if(uip_slen > 0 && uip_connr->len > 0) {
+ /* Add the length of the IP and TCP headers. */
+ uip_len = uip_connr->len + UIP_TCPIP_HLEN;
+ /* We always set the ACK flag in response packets. */
+ BUF->flags = TCP_ACK | TCP_PSH;
+ /* Send the packet. */
+ goto tcp_send_noopts;
+ }
+ /* If there is no data to send, just send out a pure ACK if
+ there is newdata. */
+ if(uip_flags & UIP_NEWDATA) {
+ uip_len = UIP_TCPIP_HLEN;
+ BUF->flags = TCP_ACK;
+ goto tcp_send_noopts;
+ }
+ }
+ goto drop;
+ case UIP_LAST_ACK:
+ /* We can close this connection if the peer has acknowledged our
+ FIN. This is indicated by the UIP_ACKDATA flag. */
+ if(uip_flags & UIP_ACKDATA) {
+ uip_connr->tcpstateflags = UIP_CLOSED;
+ uip_flags = UIP_CLOSE;
+ UIP_APPCALL();
+ }
+ break;
+
+ case UIP_FIN_WAIT_1:
+ /* The application has closed the connection, but the remote host
+ hasn't closed its end yet. Thus we do nothing but wait for a
+ FIN from the other side. */
+ if(uip_len > 0) {
+ uip_add_rcv_nxt(uip_len);
+ }
+ if(BUF->flags & TCP_FIN) {
+ if(uip_flags & UIP_ACKDATA) {
+ uip_connr->tcpstateflags = UIP_TIME_WAIT;
+ uip_connr->timer = 0;
+ uip_connr->len = 0;
+ } else {
+ uip_connr->tcpstateflags = UIP_CLOSING;
+ }
+ uip_add_rcv_nxt(1);
+ uip_flags = UIP_CLOSE;
+ UIP_APPCALL();
+ goto tcp_send_ack;
+ } else if(uip_flags & UIP_ACKDATA) {
+ uip_connr->tcpstateflags = UIP_FIN_WAIT_2;
+ uip_connr->len = 0;
+ goto drop;
+ }
+ if(uip_len > 0) {
+ goto tcp_send_ack;
+ }
+ goto drop;
+
+ case UIP_FIN_WAIT_2:
+ if(uip_len > 0) {
+ uip_add_rcv_nxt(uip_len);
+ }
+ if(BUF->flags & TCP_FIN) {
+ uip_connr->tcpstateflags = UIP_TIME_WAIT;
+ uip_connr->timer = 0;
+ uip_add_rcv_nxt(1);
+ uip_flags = UIP_CLOSE;
+ UIP_APPCALL();
+ goto tcp_send_ack;
+ }
+ if(uip_len > 0) {
+ goto tcp_send_ack;
+ }
+ goto drop;
+
+ case UIP_TIME_WAIT:
+ goto tcp_send_ack;
+
+ case UIP_CLOSING:
+ if(uip_flags & UIP_ACKDATA) {
+ uip_connr->tcpstateflags = UIP_TIME_WAIT;
+ uip_connr->timer = 0;
+ }
+ }
+ goto drop;
+
+
+ /* We jump here when we are ready to send the packet, and just want
+ to set the appropriate TCP sequence numbers in the TCP header. */
+ tcp_send_ack:
+ BUF->flags = TCP_ACK;
+ tcp_send_nodata:
+ uip_len = UIP_IPTCPH_LEN;
+ tcp_send_noopts:
+ BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4;
+ tcp_send:
+ /* We're done with the input processing. We are now ready to send a
+ reply. Our job is to fill in all the fields of the TCP and IP
+ headers before calculating the checksum and finally send the
+ packet. */
+ BUF->ackno[0] = uip_connr->rcv_nxt[0];
+ BUF->ackno[1] = uip_connr->rcv_nxt[1];
+ BUF->ackno[2] = uip_connr->rcv_nxt[2];
+ BUF->ackno[3] = uip_connr->rcv_nxt[3];
+
+ BUF->seqno[0] = uip_connr->snd_nxt[0];
+ BUF->seqno[1] = uip_connr->snd_nxt[1];
+ BUF->seqno[2] = uip_connr->snd_nxt[2];
+ BUF->seqno[3] = uip_connr->snd_nxt[3];
+
+ BUF->proto = UIP_PROTO_TCP;
+
+ BUF->srcport = uip_connr->lport;
+ BUF->destport = uip_connr->rport;
+
+ uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
+ uip_ipaddr_copy(BUF->destipaddr, uip_connr->ripaddr);
+
+ if(uip_connr->tcpstateflags & UIP_STOPPED) {
+ /* If the connection has issued uip_stop(), we advertise a zero
+ window so that the remote host will stop sending data. */
+ BUF->wnd[0] = BUF->wnd[1] = 0;
+ } else {
+ BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8);
+ BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff);
+ }
+
+ tcp_send_noconn:
+ BUF->ttl = UIP_TTL;
+#if UIP_CONF_IPV6
+ /* For IPv6, the IP length field does not include the IPv6 IP header
+ length. */
+ BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
+ BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
+#else /* UIP_CONF_IPV6 */
+ BUF->len[0] = (uip_len >> 8);
+ BUF->len[1] = (uip_len & 0xff);
+#endif /* UIP_CONF_IPV6 */
+
+ BUF->urgp[0] = BUF->urgp[1] = 0;
+
+ /* Calculate TCP checksum. */
+ BUF->tcpchksum = 0;
+ BUF->tcpchksum = ~(uip_tcpchksum());
+
+ ip_send_nolen:
+
+#if UIP_CONF_IPV6
+ BUF->vtc = 0x60;
+ BUF->tcflow = 0x00;
+ BUF->flow = 0x00;
+#else /* UIP_CONF_IPV6 */
+ BUF->vhl = 0x45;
+ BUF->tos = 0;
+ BUF->ipoffset[0] = BUF->ipoffset[1] = 0;
+ ++ipid;
+ BUF->ipid[0] = ipid >> 8;
+ BUF->ipid[1] = ipid & 0xff;
+ /* Calculate IP checksum. */
+ BUF->ipchksum = 0;
+ BUF->ipchksum = ~(uip_ipchksum());
+ DEBUG_PRINTF("uip ip_send_nolen: chkecum 0x%04x\n", uip_ipchksum());
+#endif /* UIP_CONF_IPV6 */
+
+ UIP_STAT(++uip_stat.tcp.sent);
+ send:
+ DEBUG_PRINTF("Sending packet with length %d (%d)\n", uip_len,
+ (BUF->len[0] << 8) | BUF->len[1]);
+
+ UIP_STAT(++uip_stat.ip.sent);
+ /* Return and let the caller do the actual transmission. */
+ uip_flags = 0;
+ return;
+ drop:
+ uip_len = 0;
+ uip_flags = 0;
+ return;
+}
+/*---------------------------------------------------------------------------*/
+u16_t
+uip_htons(u16_t val)
+{
+ return HTONS(val);
+}
+/*---------------------------------------------------------------------------*/
+void
+uip_send(const void *data, int len)
+{
+ if(len > 0) {
+ uip_slen = len;
+ if(data != uip_sappdata) {
+ memcpy((void*)uip_sappdata, (data), uip_slen);
+ }
+ }
+}
+/** @} */
diff --git a/components/net/uip/uip/uip.h b/components/net/uip/uip/uip.h
index 6d358f346c..fd90db980c 100644
--- a/components/net/uip/uip/uip.h
+++ b/components/net/uip/uip/uip.h
@@ -1,1602 +1,1602 @@
-
-/**
- * \addtogroup uip
- * @{
- */
-
-/**
- * \file
- * Header file for the uIP TCP/IP stack.
- * \author Adam Dunkels <[email protected]>
- *
- * The uIP TCP/IP stack header file contains definitions for a number
- * of C macros that are used by uIP programs as well as internal uIP
- * structures, TCP/IP header structures and function declarations.
- *
- */
-
-
-/*
- * Copyright (c) 2001-2003, Adam Dunkels.
- * 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 uIP TCP/IP stack.
- *
- * $Id: uip.h,v 1.40 2006/06/08 07:12:07 adam Exp $
- *
- */
-
-#ifndef __UIP_H__
-#define __UIP_H__
-
-#include "uipopt.h"
-
-/**
- * Repressentation of an IP address.
- *
- */
-typedef u16_t uip_ip4addr_t[2];
-typedef u16_t uip_ip6addr_t[8];
-#if UIP_CONF_IPV6
-typedef uip_ip6addr_t uip_ipaddr_t;
-#else /* UIP_CONF_IPV6 */
-typedef uip_ip4addr_t uip_ipaddr_t;
-#endif /* UIP_CONF_IPV6 */
-
-/*---------------------------------------------------------------------------*/
-/* First, the functions that should be called from the
- * system. Initialization, the periodic timer and incoming packets are
- * handled by the following three functions.
- */
-
-/**
- * \defgroup uipconffunc uIP configuration functions
- * @{
- *
- * The uIP configuration functions are used for setting run-time
- * parameters in uIP such as IP addresses.
- */
-
-/**
- * Set the IP address of this host.
- *
- * The IP address is represented as a 4-byte array where the first
- * octet of the IP address is put in the first member of the 4-byte
- * array.
- *
- * Example:
- \code
-
- uip_ipaddr_t addr;
-
- uip_ipaddr(&addr, 192,168,1,2);
- uip_sethostaddr(&addr);
-
- \endcode
- * \param addr A pointer to an IP address of type uip_ipaddr_t;
- *
- * \sa uip_ipaddr()
- *
- * \hideinitializer
- */
-#define uip_sethostaddr(addr) uip_ipaddr_copy(uip_hostaddr, (addr))
-
-/**
- * Get the IP address of this host.
- *
- * The IP address is represented as a 4-byte array where the first
- * octet of the IP address is put in the first member of the 4-byte
- * array.
- *
- * Example:
- \code
- uip_ipaddr_t hostaddr;
-
- uip_gethostaddr(&hostaddr);
- \endcode
- * \param addr A pointer to a uip_ipaddr_t variable that will be
- * filled in with the currently configured IP address.
- *
- * \hideinitializer
- */
-#define uip_gethostaddr(addr) uip_ipaddr_copy((addr), uip_hostaddr)
-
-/**
- * Set the default router's IP address.
- *
- * \param addr A pointer to a uip_ipaddr_t variable containing the IP
- * address of the default router.
- *
- * \sa uip_ipaddr()
- *
- * \hideinitializer
- */
-#define uip_setdraddr(addr) uip_ipaddr_copy(uip_draddr, (addr))
-
-/**
- * Set the netmask.
- *
- * \param addr A pointer to a uip_ipaddr_t variable containing the IP
- * address of the netmask.
- *
- * \sa uip_ipaddr()
- *
- * \hideinitializer
- */
-#define uip_setnetmask(addr) uip_ipaddr_copy(uip_netmask, (addr))
-
-
-/**
- * Get the default router's IP address.
- *
- * \param addr A pointer to a uip_ipaddr_t variable that will be
- * filled in with the IP address of the default router.
- *
- * \hideinitializer
- */
-#define uip_getdraddr(addr) uip_ipaddr_copy((addr), uip_draddr)
-
-/**
- * Get the netmask.
- *
- * \param addr A pointer to a uip_ipaddr_t variable that will be
- * filled in with the value of the netmask.
- *
- * \hideinitializer
- */
-#define uip_getnetmask(addr) uip_ipaddr_copy((addr), uip_netmask)
-
-/** @} */
-
-/**
- * \defgroup uipinit uIP initialization functions
- * @{
- *
- * The uIP initialization functions are used for booting uIP.
- */
-
-/**
- * uIP initialization function.
- *
- * This function should be called at boot up to initilize the uIP
- * TCP/IP stack.
- */
-void uip_init(void);
-
-/**
- * uIP initialization function.
- *
- * This function may be used at boot time to set the initial ip_id.
- */
-void uip_setipid(u16_t id);
-
-/** @} */
-
-/**
- * \defgroup uipdevfunc uIP device driver functions
- * @{
- *
- * These functions are used by a network device driver for interacting
- * with uIP.
- */
-
-/**
- * Process an incoming packet.
- *
- * This function should be called when the device driver has received
- * a packet from the network. The packet from the device driver must
- * be present in the uip_buf buffer, and the length of the packet
- * should be placed in the uip_len variable.
- *
- * When the function returns, there may be an outbound packet placed
- * in the uip_buf packet buffer. If so, the uip_len variable is set to
- * the length of the packet. If no packet is to be sent out, the
- * uip_len variable is set to 0.
- *
- * The usual way of calling the function is presented by the source
- * code below.
- \code
- uip_len = devicedriver_poll();
- if(uip_len > 0) {
- uip_input();
- if(uip_len > 0) {
- devicedriver_send();
- }
- }
- \endcode
- *
- * \note If you are writing a uIP device driver that needs ARP
- * (Address Resolution Protocol), e.g., when running uIP over
- * Ethernet, you will need to call the uIP ARP code before calling
- * this function:
- \code
- #define BUF ((struct uip_eth_hdr *)&uip_buf[0])
- uip_len = ethernet_devicedrver_poll();
- if(uip_len > 0) {
- if(BUF->type == HTONS(UIP_ETHTYPE_IP)) {
- uip_arp_ipin();
- uip_input();
- if(uip_len > 0) {
- uip_arp_out();
- ethernet_devicedriver_send();
- }
- } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) {
- uip_arp_arpin();
- if(uip_len > 0) {
- ethernet_devicedriver_send();
- }
- }
- \endcode
- *
- * \hideinitializer
- */
-#define uip_input() uip_process(UIP_DATA)
-
-/**
- * Periodic processing for a connection identified by its number.
- *
- * This function does the necessary periodic processing (timers,
- * polling) for a uIP TCP conneciton, and should be called when the
- * periodic uIP timer goes off. It should be called for every
- * connection, regardless of whether they are open of closed.
- *
- * When the function returns, it may have an outbound packet waiting
- * for service in the uIP packet buffer, and if so the uip_len
- * variable is set to a value larger than zero. The device driver
- * should be called to send out the packet.
- *
- * The ususal way of calling the function is through a for() loop like
- * this:
- \code
- for(i = 0; i < UIP_CONNS; ++i) {
- uip_periodic(i);
- if(uip_len > 0) {
- devicedriver_send();
- }
- }
- \endcode
- *
- * \note If you are writing a uIP device driver that needs ARP
- * (Address Resolution Protocol), e.g., when running uIP over
- * Ethernet, you will need to call the uip_arp_out() function before
- * calling the device driver:
- \code
- for(i = 0; i < UIP_CONNS; ++i) {
- uip_periodic(i);
- if(uip_len > 0) {
- uip_arp_out();
- ethernet_devicedriver_send();
- }
- }
- \endcode
- *
- * \param conn The number of the connection which is to be periodically polled.
- *
- * \hideinitializer
- */
-#define uip_periodic(conn) do { uip_conn = &uip_conns[conn]; \
- uip_process(UIP_TIMER); } while (0)
-
-/**
- *
- *
- */
-#define uip_conn_active(conn) (uip_conns[conn].tcpstateflags != UIP_CLOSED)
-
-/**
- * Perform periodic processing for a connection identified by a pointer
- * to its structure.
- *
- * Same as uip_periodic() but takes a pointer to the actual uip_conn
- * struct instead of an integer as its argument. This function can be
- * used to force periodic processing of a specific connection.
- *
- * \param conn A pointer to the uip_conn struct for the connection to
- * be processed.
- *
- * \hideinitializer
- */
-#define uip_periodic_conn(conn) do { uip_conn = conn; \
- uip_process(UIP_TIMER); } while (0)
-
-/**
- * Reuqest that a particular connection should be polled.
- *
- * Similar to uip_periodic_conn() but does not perform any timer
- * processing. The application is polled for new data.
- *
- * \param conn A pointer to the uip_conn struct for the connection to
- * be processed.
- *
- * \hideinitializer
- */
-#define uip_poll_conn(conn) do { uip_conn = conn; \
- uip_process(UIP_POLL_REQUEST); } while (0)
-
-
-#if UIP_UDP
-/**
- * Periodic processing for a UDP connection identified by its number.
- *
- * This function is essentially the same as uip_periodic(), but for
- * UDP connections. It is called in a similar fashion as the
- * uip_periodic() function:
- \code
- for(i = 0; i < UIP_UDP_CONNS; i++) {
- uip_udp_periodic(i);
- if(uip_len > 0) {
- devicedriver_send();
- }
- }
- \endcode
- *
- * \note As for the uip_periodic() function, special care has to be
- * taken when using uIP together with ARP and Ethernet:
- \code
- for(i = 0; i < UIP_UDP_CONNS; i++) {
- uip_udp_periodic(i);
- if(uip_len > 0) {
- uip_arp_out();
- ethernet_devicedriver_send();
- }
- }
- \endcode
- *
- * \param conn The number of the UDP connection to be processed.
- *
- * \hideinitializer
- */
-#define uip_udp_periodic(conn) do { uip_udp_conn = &uip_udp_conns[conn]; \
- uip_process(UIP_UDP_TIMER); } while (0)
-
-/**
- * Periodic processing for a UDP connection identified by a pointer to
- * its structure.
- *
- * Same as uip_udp_periodic() but takes a pointer to the actual
- * uip_conn struct instead of an integer as its argument. This
- * function can be used to force periodic processing of a specific
- * connection.
- *
- * \param conn A pointer to the uip_udp_conn struct for the connection
- * to be processed.
- *
- * \hideinitializer
- */
-#define uip_udp_periodic_conn(conn) do { uip_udp_conn = conn; \
- uip_process(UIP_UDP_TIMER); } while (0)
-
-
-#endif /* UIP_UDP */
-
-/**
- * The uIP packet buffer.
- *
- * The uip_buf array is used to hold incoming and outgoing
- * packets. The device driver should place incoming data into this
- * buffer. When sending data, the device driver should read the link
- * level headers and the TCP/IP headers from this buffer. The size of
- * the link level headers is configured by the UIP_LLH_LEN define.
- *
- * \note The application data need not be placed in this buffer, so
- * the device driver must read it from the place pointed to by the
- * uip_appdata pointer as illustrated by the following example:
- \code
- void
- devicedriver_send(void)
- {
- hwsend(&uip_buf[0], UIP_LLH_LEN);
- if(uip_len <= UIP_LLH_LEN + UIP_TCPIP_HLEN) {
- hwsend(&uip_buf[UIP_LLH_LEN], uip_len - UIP_LLH_LEN);
- } else {
- hwsend(&uip_buf[UIP_LLH_LEN], UIP_TCPIP_HLEN);
- hwsend(uip_appdata, uip_len - UIP_TCPIP_HLEN - UIP_LLH_LEN);
- }
- }
- \endcode
- */
-extern u8_t uip_buf[UIP_BUFSIZE+2];
-
-/** @} */
-
-/*---------------------------------------------------------------------------*/
-/* Functions that are used by the uIP application program. Opening and
- * closing connections, sending and receiving data, etc. is all
- * handled by the functions below.
-*/
-/**
- * \defgroup uipappfunc uIP application functions
- * @{
- *
- * Functions used by an application running of top of uIP.
- */
-
-/**
- * Start listening to the specified port.
- *
- * \note Since this function expects the port number in network byte
- * order, a conversion using HTONS() or uip_htons() is necessary.
- *
- \code
- uip_listen(HTONS(80));
- \endcode
- *
- * \param port A 16-bit port number in network byte order.
- */
-void uip_listen(u16_t port);
-
-/**
- * Stop listening to the specified port.
- *
- * \note Since this function expects the port number in network byte
- * order, a conversion using HTONS() or uip_htons() is necessary.
- *
- \code
- uip_unlisten(HTONS(80));
- \endcode
- *
- * \param port A 16-bit port number in network byte order.
- */
-void uip_unlisten(u16_t port);
-
-/**
- * Connect to a remote host using TCP.
- *
- * This function is used to start a new connection to the specified
- * port on the specied host. It allocates a new connection identifier,
- * sets the connection to the SYN_SENT state and sets the
- * retransmission timer to 0. This will cause a TCP SYN segment to be
- * sent out the next time this connection is periodically processed,
- * which usually is done within 0.5 seconds after the call to
- * uip_connect().
- *
- * \note This function is avaliable only if support for active open
- * has been configured by defining UIP_ACTIVE_OPEN to 1 in uipopt.h.
- *
- * \note Since this function requires the port number to be in network
- * byte order, a conversion using HTONS() or uip_htons() is necessary.
- *
- \code
- uip_ipaddr_t ipaddr;
-
- uip_ipaddr(&ipaddr, 192,168,1,2);
- uip_connect(&ipaddr, HTONS(80));
- \endcode
- *
- * \param ripaddr The IP address of the remote hot.
- *
- * \param port A 16-bit port number in network byte order.
- *
- * \return A pointer to the uIP connection identifier for the new connection,
- * or NULL if no connection could be allocated.
- *
- */
-struct uip_conn *uip_connect(uip_ipaddr_t *ripaddr, u16_t port);
-
-
-
-/**
- * \internal
- *
- * Check if a connection has outstanding (i.e., unacknowledged) data.
- *
- * \param conn A pointer to the uip_conn structure for the connection.
- *
- * \hideinitializer
- */
-#define uip_outstanding(conn) ((conn)->len)
-
-/**
- * Send data on the current connection.
- *
- * This function is used to send out a single segment of TCP
- * data. Only applications that have been invoked by uIP for event
- * processing can send data.
- *
- * The amount of data that actually is sent out after a call to this
- * funcion is determined by the maximum amount of data TCP allows. uIP
- * will automatically crop the data so that only the appropriate
- * amount of data is sent. The function uip_mss() can be used to query
- * uIP for the amount of data that actually will be sent.
- *
- * \note This function does not guarantee that the sent data will
- * arrive at the destination. If the data is lost in the network, the
- * application will be invoked with the uip_rexmit() event being
- * set. The application will then have to resend the data using this
- * function.
- *
- * \param data A pointer to the data which is to be sent.
- *
- * \param len The maximum amount of data bytes to be sent.
- *
- * \hideinitializer
- */
-void uip_send(const void *data, int len);
-
-/**
- * The length of any incoming data that is currently avaliable (if avaliable)
- * in the uip_appdata buffer.
- *
- * The test function uip_data() must first be used to check if there
- * is any data available at all.
- *
- * \hideinitializer
- */
-/*void uip_datalen(void);*/
-#define uip_datalen() uip_len
-
-/**
- * The length of any out-of-band data (urgent data) that has arrived
- * on the connection.
- *
- * \note The configuration parameter UIP_URGDATA must be set for this
- * function to be enabled.
- *
- * \hideinitializer
- */
-#define uip_urgdatalen() uip_urglen
-
-/**
- * Close the current connection.
- *
- * This function will close the current connection in a nice way.
- *
- * \hideinitializer
- */
-#define uip_close() (uip_flags = UIP_CLOSE)
-
-/**
- * Abort the current connection.
- *
- * This function will abort (reset) the current connection, and is
- * usually used when an error has occured that prevents using the
- * uip_close() function.
- *
- * \hideinitializer
- */
-#define uip_abort() (uip_flags = UIP_ABORT)
-
-/**
- * Tell the sending host to stop sending data.
- *
- * This function will close our receiver's window so that we stop
- * receiving data for the current connection.
- *
- * \hideinitializer
- */
-#define uip_stop() (uip_conn->tcpstateflags |= UIP_STOPPED)
-
-/**
- * Find out if the current connection has been previously stopped with
- * uip_stop().
- *
- * \hideinitializer
- */
-#define uip_stopped(conn) ((conn)->tcpstateflags & UIP_STOPPED)
-
-/**
- * Restart the current connection, if is has previously been stopped
- * with uip_stop().
- *
- * This function will open the receiver's window again so that we
- * start receiving data for the current connection.
- *
- * \hideinitializer
- */
-#define uip_restart() do { uip_flags |= UIP_NEWDATA; \
- uip_conn->tcpstateflags &= ~UIP_STOPPED; \
- } while(0)
-
-
-/* uIP tests that can be made to determine in what state the current
- connection is, and what the application function should do. */
-
-/**
- * Is the current connection a UDP connection?
- *
- * This function checks whether the current connection is a UDP connection.
- *
- * \hideinitializer
- *
- */
-#define uip_udpconnection() (uip_conn == NULL)
-
-/**
- * Is new incoming data available?
- *
- * Will reduce to non-zero if there is new data for the application
- * present at the uip_appdata pointer. The size of the data is
- * avaliable through the uip_len variable.
- *
- * \hideinitializer
- */
-#define uip_newdata() (uip_flags & UIP_NEWDATA)
-
-/**
- * Has previously sent data been acknowledged?
- *
- * Will reduce to non-zero if the previously sent data has been
- * acknowledged by the remote host. This means that the application
- * can send new data.
- *
- * \hideinitializer
- */
-#define uip_acked() (uip_flags & UIP_ACKDATA)
-
-/**
- * Has the connection just been connected?
- *
- * Reduces to non-zero if the current connection has been connected to
- * a remote host. This will happen both if the connection has been
- * actively opened (with uip_connect()) or passively opened (with
- * uip_listen()).
- *
- * \hideinitializer
- */
-#define uip_connected() (uip_flags & UIP_CONNECTED)
-
-/**
- * Has the connection been closed by the other end?
- *
- * Is non-zero if the connection has been closed by the remote
- * host. The application may then do the necessary clean-ups.
- *
- * \hideinitializer
- */
-#define uip_closed() (uip_flags & UIP_CLOSE)
-
-/**
- * Has the connection been aborted by the other end?
- *
- * Non-zero if the current connection has been aborted (reset) by the
- * remote host.
- *
- * \hideinitializer
- */
-#define uip_aborted() (uip_flags & UIP_ABORT)
-
-/**
- * Has the connection timed out?
- *
- * Non-zero if the current connection has been aborted due to too many
- * retransmissions.
- *
- * \hideinitializer
- */
-#define uip_timedout() (uip_flags & UIP_TIMEDOUT)
-
-/**
- * Do we need to retransmit previously data?
- *
- * Reduces to non-zero if the previously sent data has been lost in
- * the network, and the application should retransmit it. The
- * application should send the exact same data as it did the last
- * time, using the uip_send() function.
- *
- * \hideinitializer
- */
-#define uip_rexmit() (uip_flags & UIP_REXMIT)
-
-/**
- * Is the connection being polled by uIP?
- *
- * Is non-zero if the reason the application is invoked is that the
- * current connection has been idle for a while and should be
- * polled.
- *
- * The polling event can be used for sending data without having to
- * wait for the remote host to send data.
- *
- * \hideinitializer
- */
-#define uip_poll() (uip_flags & UIP_POLL)
-
-/**
- * Get the initial maxium segment size (MSS) of the current
- * connection.
- *
- * \hideinitializer
- */
-#define uip_initialmss() (uip_conn->initialmss)
-
-/**
- * Get the current maxium segment size that can be sent on the current
- * connection.
- *
- * The current maxiumum segment size that can be sent on the
- * connection is computed from the receiver's window and the MSS of
- * the connection (which also is available by calling
- * uip_initialmss()).
- *
- * \hideinitializer
- */
-#define uip_mss() (uip_conn->mss)
-
-/**
- * Set up a new UDP connection.
- *
- * This function sets up a new UDP connection. The function will
- * automatically allocate an unused local port for the new
- * connection. However, another port can be chosen by using the
- * uip_udp_bind() call, after the uip_udp_new() function has been
- * called.
- *
- * Example:
- \code
- uip_ipaddr_t addr;
- struct uip_udp_conn *c;
-
- uip_ipaddr(&addr, 192,168,2,1);
- c = uip_udp_new(&addr, HTONS(12345));
- if(c != NULL) {
- uip_udp_bind(c, HTONS(12344));
- }
- \endcode
- * \param ripaddr The IP address of the remote host.
- *
- * \param rport The remote port number in network byte order.
- *
- * \return The uip_udp_conn structure for the new connection or NULL
- * if no connection could be allocated.
- */
-struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport);
-
-/**
- * Removed a UDP connection.
- *
- * \param conn A pointer to the uip_udp_conn structure for the connection.
- *
- * \hideinitializer
- */
-#define uip_udp_remove(conn) (conn)->lport = 0
-
-/**
- * Bind a UDP connection to a local port.
- *
- * \param conn A pointer to the uip_udp_conn structure for the
- * connection.
- *
- * \param port The local port number, in network byte order.
- *
- * \hideinitializer
- */
-#define uip_udp_bind(conn, port) (conn)->lport = port
-
-/**
- * Send a UDP datagram of length len on the current connection.
- *
- * This function can only be called in response to a UDP event (poll
- * or newdata). The data must be present in the uip_buf buffer, at the
- * place pointed to by the uip_appdata pointer.
- *
- * \param len The length of the data in the uip_buf buffer.
- *
- * \hideinitializer
- */
-#define uip_udp_send(len) uip_send((char *)uip_appdata, len)
-
-/** @} */
-
-/* uIP convenience and converting functions. */
-
-/**
- * \defgroup uipconvfunc uIP conversion functions
- * @{
- *
- * These functions can be used for converting between different data
- * formats used by uIP.
- */
-
-/**
- * Construct an IP address from four bytes.
- *
- * This function constructs an IP address of the type that uIP handles
- * internally from four bytes. The function is handy for specifying IP
- * addresses to use with e.g. the uip_connect() function.
- *
- * Example:
- \code
- uip_ipaddr_t ipaddr;
- struct uip_conn *c;
-
- uip_ipaddr(&ipaddr, 192,168,1,2);
- c = uip_connect(&ipaddr, HTONS(80));
- \endcode
- *
- * \param addr A pointer to a uip_ipaddr_t variable that will be
- * filled in with the IP address.
- *
- * \param addr0 The first octet of the IP address.
- * \param addr1 The second octet of the IP address.
- * \param addr2 The third octet of the IP address.
- * \param addr3 The forth octet of the IP address.
- *
- * \hideinitializer
- */
-#define uip_ipaddr(addr, addr0,addr1,addr2,addr3) do { \
- ((u16_t *)(addr))[0] = HTONS(((addr0) << 8) | (addr1)); \
- ((u16_t *)(addr))[1] = HTONS(((addr2) << 8) | (addr3)); \
- } while(0)
-
-/**
- * Construct an IPv6 address from eight 16-bit words.
- *
- * This function constructs an IPv6 address.
- *
- * \hideinitializer
- */
-#define uip_ip6addr(addr, addr0,addr1,addr2,addr3,addr4,addr5,addr6,addr7) do { \
- ((u16_t *)(addr))[0] = HTONS((addr0)); \
- ((u16_t *)(addr))[1] = HTONS((addr1)); \
- ((u16_t *)(addr))[2] = HTONS((addr2)); \
- ((u16_t *)(addr))[3] = HTONS((addr3)); \
- ((u16_t *)(addr))[4] = HTONS((addr4)); \
- ((u16_t *)(addr))[5] = HTONS((addr5)); \
- ((u16_t *)(addr))[6] = HTONS((addr6)); \
- ((u16_t *)(addr))[7] = HTONS((addr7)); \
- } while(0)
-
-/**
- * Copy an IP address to another IP address.
- *
- * Copies an IP address from one place to another.
- *
- * Example:
- \code
- uip_ipaddr_t ipaddr1, ipaddr2;
-
- uip_ipaddr(&ipaddr1, 192,16,1,2);
- uip_ipaddr_copy(&ipaddr2, &ipaddr1);
- \endcode
- *
- * \param dest The destination for the copy.
- * \param src The source from where to copy.
- *
- * \hideinitializer
- */
-#if !UIP_CONF_IPV6
-#define uip_ipaddr_copy(dest, src) do { \
- ((u16_t *)dest)[0] = ((u16_t *)src)[0]; \
- ((u16_t *)dest)[1] = ((u16_t *)src)[1]; \
- } while(0)
-#else /* !UIP_CONF_IPV6 */
-#define uip_ipaddr_copy(dest, src) memcpy(dest, src, sizeof(uip_ip6addr_t))
-#endif /* !UIP_CONF_IPV6 */
-
-/**
- * Compare two IP addresses
- *
- * Compares two IP addresses.
- *
- * Example:
- \code
- uip_ipaddr_t ipaddr1, ipaddr2;
-
- uip_ipaddr(&ipaddr1, 192,16,1,2);
- if(uip_ipaddr_cmp(&ipaddr2, &ipaddr1)) {
- printf("They are the same");
- }
- \endcode
- *
- * \param addr1 The first IP address.
- * \param addr2 The second IP address.
- *
- * \hideinitializer
- */
-#if !UIP_CONF_IPV6
-#define uip_ipaddr_cmp(addr1, addr2) (((u16_t *)addr1)[0] == ((u16_t *)addr2)[0] && \
- ((u16_t *)addr1)[1] == ((u16_t *)addr2)[1])
-#else /* !UIP_CONF_IPV6 */
-#define uip_ipaddr_cmp(addr1, addr2) (memcmp(addr1, addr2, sizeof(uip_ip6addr_t)) == 0)
-#endif /* !UIP_CONF_IPV6 */
-
-/**
- * Compare two IP addresses with netmasks
- *
- * Compares two IP addresses with netmasks. The masks are used to mask
- * out the bits that are to be compared.
- *
- * Example:
- \code
- uip_ipaddr_t ipaddr1, ipaddr2, mask;
-
- uip_ipaddr(&mask, 255,255,255,0);
- uip_ipaddr(&ipaddr1, 192,16,1,2);
- uip_ipaddr(&ipaddr2, 192,16,1,3);
- if(uip_ipaddr_maskcmp(&ipaddr1, &ipaddr2, &mask)) {
- printf("They are the same");
- }
- \endcode
- *
- * \param addr1 The first IP address.
- * \param addr2 The second IP address.
- * \param mask The netmask.
- *
- * \hideinitializer
- */
-#define uip_ipaddr_maskcmp(addr1, addr2, mask) \
- (((((u16_t *)addr1)[0] & ((u16_t *)mask)[0]) == \
- (((u16_t *)addr2)[0] & ((u16_t *)mask)[0])) && \
- ((((u16_t *)addr1)[1] & ((u16_t *)mask)[1]) == \
- (((u16_t *)addr2)[1] & ((u16_t *)mask)[1])))
-
-
-/**
- * Mask out the network part of an IP address.
- *
- * Masks out the network part of an IP address, given the address and
- * the netmask.
- *
- * Example:
- \code
- uip_ipaddr_t ipaddr1, ipaddr2, netmask;
-
- uip_ipaddr(&ipaddr1, 192,16,1,2);
- uip_ipaddr(&netmask, 255,255,255,0);
- uip_ipaddr_mask(&ipaddr2, &ipaddr1, &netmask);
- \endcode
- *
- * In the example above, the variable "ipaddr2" will contain the IP
- * address 192.168.1.0.
- *
- * \param dest Where the result is to be placed.
- * \param src The IP address.
- * \param mask The netmask.
- *
- * \hideinitializer
- */
-#define uip_ipaddr_mask(dest, src, mask) do { \
- ((u16_t *)dest)[0] = ((u16_t *)src)[0] & ((u16_t *)mask)[0]; \
- ((u16_t *)dest)[1] = ((u16_t *)src)[1] & ((u16_t *)mask)[1]; \
- } while(0)
-
-/**
- * Pick the first octet of an IP address.
- *
- * Picks out the first octet of an IP address.
- *
- * Example:
- \code
- uip_ipaddr_t ipaddr;
- u8_t octet;
-
- uip_ipaddr(&ipaddr, 1,2,3,4);
- octet = uip_ipaddr1(&ipaddr);
- \endcode
- *
- * In the example above, the variable "octet" will contain the value 1.
- *
- * \hideinitializer
- */
-#define uip_ipaddr1(addr) (uip_htons(((u16_t *)(addr))[0]) >> 8)
-
-/**
- * Pick the second octet of an IP address.
- *
- * Picks out the second octet of an IP address.
- *
- * Example:
- \code
- uip_ipaddr_t ipaddr;
- u8_t octet;
-
- uip_ipaddr(&ipaddr, 1,2,3,4);
- octet = uip_ipaddr2(&ipaddr);
- \endcode
- *
- * In the example above, the variable "octet" will contain the value 2.
- *
- * \hideinitializer
- */
-#define uip_ipaddr2(addr) (uip_htons(((u16_t *)(addr))[0]) & 0xff)
-
-/**
- * Pick the third octet of an IP address.
- *
- * Picks out the third octet of an IP address.
- *
- * Example:
- \code
- uip_ipaddr_t ipaddr;
- u8_t octet;
-
- uip_ipaddr(&ipaddr, 1,2,3,4);
- octet = uip_ipaddr3(&ipaddr);
- \endcode
- *
- * In the example above, the variable "octet" will contain the value 3.
- *
- * \hideinitializer
- */
-#define uip_ipaddr3(addr) (uip_htons(((u16_t *)(addr))[1]) >> 8)
-
-/**
- * Pick the fourth octet of an IP address.
- *
- * Picks out the fourth octet of an IP address.
- *
- * Example:
- \code
- uip_ipaddr_t ipaddr;
- u8_t octet;
-
- uip_ipaddr(&ipaddr, 1,2,3,4);
- octet = uip_ipaddr4(&ipaddr);
- \endcode
- *
- * In the example above, the variable "octet" will contain the value 4.
- *
- * \hideinitializer
- */
-#define uip_ipaddr4(addr) (uip_htons(((u16_t *)(addr))[1]) & 0xff)
-
-/**
- * Convert 16-bit quantity from host byte order to network byte order.
- *
- * This macro is primarily used for converting constants from host
- * byte order to network byte order. For converting variables to
- * network byte order, use the uip_htons() function instead.
- *
- * \hideinitializer
- */
-#ifndef HTONS
-# if UIP_BYTE_ORDER == UIP_BIG_ENDIAN
-# define HTONS(n) (n)
-# else /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */
-# define HTONS(n) (u16_t)((((u16_t) (n)) << 8) | (((u16_t) (n)) >> 8))
-# endif /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */
-#else
-#error "HTONS already defined!"
-#endif /* HTONS */
-
-/**
- * Convert 16-bit quantity from host byte order to network byte order.
- *
- * This function is primarily used for converting variables from host
- * byte order to network byte order. For converting constants to
- * network byte order, use the HTONS() macro instead.
- */
-
-#ifndef uip_htons
-u16_t uip_htons(u16_t val);
-#endif /* uip_htons */
-#ifndef ntohs
-#define ntohs uip_htons
-#endif
-
-/** @} */
-
-/**
- * Pointer to the application data in the packet buffer.
- *
- * This pointer points to the application data when the application is
- * called. If the application wishes to send data, the application may
- * use this space to write the data into before calling uip_send().
- */
-extern volatile u8_t *uip_appdata;
-
-#if UIP_URGDATA > 0
-/* u8_t *uip_urgdata:
- *
- * This pointer points to any urgent data that has been received. Only
- * present if compiled with support for urgent data (UIP_URGDATA).
- */
-extern void *uip_urgdata;
-#endif /* UIP_URGDATA > 0 */
-
-
-/**
- * \defgroup uipdrivervars Variables used in uIP device drivers
- * @{
- *
- * uIP has a few global variables that are used in device drivers for
- * uIP.
- */
-
-/**
- * The length of the packet in the uip_buf buffer.
- *
- * The global variable uip_len holds the length of the packet in the
- * uip_buf buffer.
- *
- * When the network device driver calls the uIP input function,
- * uip_len should be set to the length of the packet in the uip_buf
- * buffer.
- *
- * When sending packets, the device driver should use the contents of
- * the uip_len variable to determine the length of the outgoing
- * packet.
- *
- */
-extern u16_t uip_len;
-
-/** @} */
-
-#if UIP_URGDATA > 0
-extern u16_t uip_urglen, uip_surglen;
-#endif /* UIP_URGDATA > 0 */
-
-
-/**
- * Representation of a uIP TCP connection.
- *
- * The uip_conn structure is used for identifying a connection. All
- * but one field in the structure are to be considered read-only by an
- * application. The only exception is the appstate field whos purpose
- * is to let the application store application-specific state (e.g.,
- * file pointers) for the connection. The type of this field is
- * configured in the "uipopt.h" header file.
- */
-struct uip_conn {
- uip_ipaddr_t ripaddr; /**< The IP address of the remote host. */
-
- u16_t lport; /**< The local TCP port, in network byte order. */
- u16_t rport; /**< The local remote TCP port, in network byte
- order. */
-
- u8_t rcv_nxt[4]; /**< The sequence number that we expect to
- receive next. */
- u8_t snd_nxt[4]; /**< The sequence number that was last sent by
- us. */
- u16_t len; /**< Length of the data that was previously sent. */
- u16_t mss; /**< Current maximum segment size for the
- connection. */
- u16_t initialmss; /**< Initial maximum segment size for the
- connection. */
- u8_t sa; /**< Retransmission time-out calculation state
- variable. */
- u8_t sv; /**< Retransmission time-out calculation state
- variable. */
- u8_t rto; /**< Retransmission time-out. */
- u8_t tcpstateflags; /**< TCP state and flags. */
- u8_t timer; /**< The retransmission timer. */
- u8_t nrtx; /**< The number of retransmissions for the last
- segment sent. */
-
- /** The application state. */
- uip_tcp_appstate_t appstate;
-};
-
-
-/**
- * Pointer to the current TCP connection.
- *
- * The uip_conn pointer can be used to access the current TCP
- * connection.
- */
-extern struct uip_conn *uip_conn;
-/* The array containing all uIP connections. */
-extern struct uip_conn uip_conns[UIP_CONNS];
-/**
- * \addtogroup uiparch
- * @{
- */
-
-/**
- * 4-byte array used for the 32-bit sequence number calculations.
- */
-extern u8_t uip_acc32[4];
-
-/** @} */
-
-
-#if UIP_UDP
-/**
- * Representation of a uIP UDP connection.
- */
-struct uip_udp_conn {
- uip_ipaddr_t ripaddr; /**< The IP address of the remote peer. */
- u16_t lport; /**< The local port number in network byte order. */
- u16_t rport; /**< The remote port number in network byte order. */
- u8_t ttl; /**< Default time-to-live. */
-
- /** The application state. */
- uip_udp_appstate_t appstate;
-};
-
-/**
- * The current UDP connection.
- */
-extern struct uip_udp_conn *uip_udp_conn;
-extern struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
-#endif /* UIP_UDP */
-
-/**
- * The structure holding the TCP/IP statistics that are gathered if
- * UIP_STATISTICS is set to 1.
- *
- */
-struct uip_stats {
- struct {
- uip_stats_t drop; /**< Number of dropped packets at the IP
- layer. */
- uip_stats_t recv; /**< Number of received packets at the IP
- layer. */
- uip_stats_t sent; /**< Number of sent packets at the IP
- layer. */
- uip_stats_t vhlerr; /**< Number of packets dropped due to wrong
- IP version or header length. */
- uip_stats_t hblenerr; /**< Number of packets dropped due to wrong
- IP length, high byte. */
- uip_stats_t lblenerr; /**< Number of packets dropped due to wrong
- IP length, low byte. */
- uip_stats_t fragerr; /**< Number of packets dropped since they
- were IP fragments. */
- uip_stats_t chkerr; /**< Number of packets dropped due to IP
- checksum errors. */
- uip_stats_t protoerr; /**< Number of packets dropped since they
- were neither ICMP, UDP nor TCP. */
- } ip; /**< IP statistics. */
- struct {
- uip_stats_t drop; /**< Number of dropped ICMP packets. */
- uip_stats_t recv; /**< Number of received ICMP packets. */
- uip_stats_t sent; /**< Number of sent ICMP packets. */
- uip_stats_t typeerr; /**< Number of ICMP packets with a wrong
- type. */
- } icmp; /**< ICMP statistics. */
- struct {
- uip_stats_t drop; /**< Number of dropped TCP segments. */
- uip_stats_t recv; /**< Number of recived TCP segments. */
- uip_stats_t sent; /**< Number of sent TCP segments. */
- uip_stats_t chkerr; /**< Number of TCP segments with a bad
- checksum. */
- uip_stats_t ackerr; /**< Number of TCP segments with a bad ACK
- number. */
- uip_stats_t rst; /**< Number of recevied TCP RST (reset) segments. */
- uip_stats_t rexmit; /**< Number of retransmitted TCP segments. */
- uip_stats_t syndrop; /**< Number of dropped SYNs due to too few
- connections was avaliable. */
- uip_stats_t synrst; /**< Number of SYNs for closed ports,
- triggering a RST. */
- } tcp; /**< TCP statistics. */
-#if UIP_UDP
- struct {
- uip_stats_t drop; /**< Number of dropped UDP segments. */
- uip_stats_t recv; /**< Number of recived UDP segments. */
- uip_stats_t sent; /**< Number of sent UDP segments. */
- uip_stats_t chkerr; /**< Number of UDP segments with a bad
- checksum. */
- } udp; /**< UDP statistics. */
-#endif /* UIP_UDP */
-};
-
-/**
- * The uIP TCP/IP statistics.
- *
- * This is the variable in which the uIP TCP/IP statistics are gathered.
- */
-extern struct uip_stats uip_stat;
-
-
-/*---------------------------------------------------------------------------*/
-/* All the stuff below this point is internal to uIP and should not be
- * used directly by an application or by a device driver.
- */
-/*---------------------------------------------------------------------------*/
-/* u8_t uip_flags:
- *
- * When the application is called, uip_flags will contain the flags
- * that are defined in this file. Please read below for more
- * infomation.
- */
-extern u8_t uip_flags;
-
-/* The following flags may be set in the global variable uip_flags
- before calling the application callback. The UIP_ACKDATA,
- UIP_NEWDATA, and UIP_CLOSE flags may both be set at the same time,
- whereas the others are mutualy exclusive. Note that these flags
- should *NOT* be accessed directly, but only through the uIP
- functions/macros. */
-
-#define UIP_ACKDATA 1 /* Signifies that the outstanding data was
- acked and the application should send
- out new data instead of retransmitting
- the last data. */
-#define UIP_NEWDATA 2 /* Flags the fact that the peer has sent
- us new data. */
-#define UIP_REXMIT 4 /* Tells the application to retransmit the
- data that was last sent. */
-#define UIP_POLL 8 /* Used for polling the application, to
- check if the application has data that
- it wants to send. */
-#define UIP_CLOSE 16 /* The remote host has closed the
- connection, thus the connection has
- gone away. Or the application signals
- that it wants to close the
- connection. */
-#define UIP_ABORT 32 /* The remote host has aborted the
- connection, thus the connection has
- gone away. Or the application signals
- that it wants to abort the
- connection. */
-#define UIP_CONNECTED 64 /* We have got a connection from a remote
- host and have set up a new connection
- for it, or an active connection has
- been successfully established. */
-
-#define UIP_TIMEDOUT 128 /* The connection has been aborted due to
- too many retransmissions. */
-
-/* uip_process(flag):
- *
- * The actual uIP function which does all the work.
- */
-void uip_process(u8_t flag);
-
-/* The following flags are passed as an argument to the uip_process()
- function. They are used to distinguish between the two cases where
- uip_process() is called. It can be called either because we have
- incoming data that should be processed, or because the periodic
- timer has fired. These values are never used directly, but only in
- the macrose defined in this file. */
-
-#define UIP_DATA 1 /* Tells uIP that there is incoming
- data in the uip_buf buffer. The
- length of the data is stored in the
- global variable uip_len. */
-#define UIP_TIMER 2 /* Tells uIP that the periodic timer
- has fired. */
-#define UIP_POLL_REQUEST 3 /* Tells uIP that a connection should
- be polled. */
-#define UIP_UDP_SEND_CONN 4 /* Tells uIP that a UDP datagram
- should be constructed in the
- uip_buf buffer. */
-#if UIP_UDP
-#define UIP_UDP_TIMER 5
-#endif /* UIP_UDP */
-
-/* The TCP states used in the uip_conn->tcpstateflags. */
-#define UIP_CLOSED 0
-#define UIP_SYN_RCVD 1
-#define UIP_SYN_SENT 2
-#define UIP_ESTABLISHED 3
-#define UIP_FIN_WAIT_1 4
-#define UIP_FIN_WAIT_2 5
-#define UIP_CLOSING 6
-#define UIP_TIME_WAIT 7
-#define UIP_LAST_ACK 8
-#define UIP_TS_MASK 15
-
-#define UIP_STOPPED 16
-
-/* The TCP and IP headers. */
-struct uip_tcpip_hdr {
-#if UIP_CONF_IPV6
- /* IPv6 header. */
- u8_t vtc,
- tcflow;
- u16_t flow;
- u8_t len[2];
- u8_t proto, ttl;
- uip_ip6addr_t srcipaddr, destipaddr;
-#else /* UIP_CONF_IPV6 */
- /* IPv4 header. */
- u8_t vhl,
- tos,
- len[2],
- ipid[2],
- ipoffset[2],
- ttl,
- proto;
- u16_t ipchksum;
- u16_t srcipaddr[2],
- destipaddr[2];
-#endif /* UIP_CONF_IPV6 */
-
- /* TCP header. */
- u16_t srcport,
- destport;
- u8_t seqno[4],
- ackno[4],
- tcpoffset,
- flags,
- wnd[2];
- u16_t tcpchksum;
- u8_t urgp[2];
- u8_t optdata[4];
-};
-
-/* The ICMP and IP headers. */
-struct uip_icmpip_hdr {
-#if UIP_CONF_IPV6
- /* IPv6 header. */
- u8_t vtc,
- tcf;
- u16_t flow;
- u8_t len[2];
- u8_t proto, ttl;
- uip_ip6addr_t srcipaddr, destipaddr;
-#else /* UIP_CONF_IPV6 */
- /* IPv4 header. */
- u8_t vhl,
- tos,
- len[2],
- ipid[2],
- ipoffset[2],
- ttl,
- proto;
- u16_t ipchksum;
- u16_t srcipaddr[2],
- destipaddr[2];
-#endif /* UIP_CONF_IPV6 */
-
- /* ICMP (echo) header. */
- u8_t type, icode;
- u16_t icmpchksum;
-#if !UIP_CONF_IPV6
- u16_t id, seqno;
-#else /* !UIP_CONF_IPV6 */
- u8_t flags, reserved1, reserved2, reserved3;
- u8_t icmp6data[16];
- u8_t options[1];
-#endif /* !UIP_CONF_IPV6 */
-};
-
-
-/* The UDP and IP headers. */
-struct uip_udpip_hdr {
-#if UIP_CONF_IPV6
- /* IPv6 header. */
- u8_t vtc,
- tcf;
- u16_t flow;
- u8_t len[2];
- u8_t proto, ttl;
- uip_ip6addr_t srcipaddr, destipaddr;
-#else /* UIP_CONF_IPV6 */
- /* IP header. */
- u8_t vhl,
- tos,
- len[2],
- ipid[2],
- ipoffset[2],
- ttl,
- proto;
- u16_t ipchksum;
- u16_t srcipaddr[2],
- destipaddr[2];
-#endif /* UIP_CONF_IPV6 */
-
- /* UDP header. */
- u16_t srcport,
- destport;
- u16_t udplen;
- u16_t udpchksum;
-};
-
-
-
-/**
- * The buffer size available for user data in the \ref uip_buf buffer.
- *
- * This macro holds the available size for user data in the \ref
- * uip_buf buffer. The macro is intended to be used for checking
- * bounds of available user data.
- *
- * Example:
- \code
- snprintf(uip_appdata, UIP_APPDATA_SIZE, "%u\n", i);
- \endcode
- *
- * \hideinitializer
- */
-#define UIP_APPDATA_SIZE (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN)
-
-
-#define UIP_PROTO_ICMP 1
-#define UIP_PROTO_TCP 6
-#define UIP_PROTO_UDP 17
-#define UIP_PROTO_ICMP6 58
-
-/* Header sizes. */
-#if UIP_CONF_IPV6
-#define UIP_IPH_LEN 40
-#else /* UIP_CONF_IPV6 */
-#define UIP_IPH_LEN 20 /* Size of IP header */
-#endif /* UIP_CONF_IPV6 */
-#define UIP_UDPH_LEN 8 /* Size of UDP header */
-#define UIP_TCPH_LEN 20 /* Size of TCP header */
-#define UIP_IPUDPH_LEN (UIP_UDPH_LEN + UIP_IPH_LEN) /* Size of IP +
- UDP
- header */
-#define UIP_IPTCPH_LEN (UIP_TCPH_LEN + UIP_IPH_LEN) /* Size of IP +
- TCP
- header */
-#define UIP_TCPIP_HLEN UIP_IPTCPH_LEN
-
-
-#if UIP_FIXEDADDR
-extern const uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr;
-#else /* UIP_FIXEDADDR */
-extern uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr;
-#endif /* UIP_FIXEDADDR */
-
-
-
-/**
- * Representation of a 48-bit Ethernet address.
- */
-struct uip_eth_addr {
- u8_t addr[6];
-};
-
-/**
- * Calculate the Internet checksum over a buffer.
- *
- * The Internet checksum is the one's complement of the one's
- * complement sum of all 16-bit words in the buffer.
- *
- * See RFC1071.
- *
- * \param buf A pointer to the buffer over which the checksum is to be
- * computed.
- *
- * \param len The length of the buffer over which the checksum is to
- * be computed.
- *
- * \return The Internet checksum of the buffer.
- */
-u16_t uip_chksum(u16_t *buf, u16_t len);
-
-/**
- * Calculate the IP header checksum of the packet header in uip_buf.
- *
- * The IP header checksum is the Internet checksum of the 20 bytes of
- * the IP header.
- *
- * \return The IP header checksum of the IP header in the uip_buf
- * buffer.
- */
-u16_t uip_ipchksum(void);
-
-/**
- * Calculate the TCP checksum of the packet in uip_buf and uip_appdata.
- *
- * The TCP checksum is the Internet checksum of data contents of the
- * TCP segment, and a pseudo-header as defined in RFC793.
- *
- * \return The TCP checksum of the TCP segment in uip_buf and pointed
- * to by uip_appdata.
- */
-u16_t uip_tcpchksum(void);
-
-/**
- * Calculate the UDP checksum of the packet in uip_buf and uip_appdata.
- *
- * The UDP checksum is the Internet checksum of data contents of the
- * UDP segment, and a pseudo-header as defined in RFC768.
- *
- * \return The UDP checksum of the UDP segment in uip_buf and pointed
- * to by uip_appdata.
- */
-u16_t uip_udpchksum(void);
-
-
-#endif /* __UIP_H__ */
-
-
-/** @} */
+
+/**
+ * \addtogroup uip
+ * @{
+ */
+
+/**
+ * \file
+ * Header file for the uIP TCP/IP stack.
+ * \author Adam Dunkels <[email protected]>
+ *
+ * The uIP TCP/IP stack header file contains definitions for a number
+ * of C macros that are used by uIP programs as well as internal uIP
+ * structures, TCP/IP header structures and function declarations.
+ *
+ */
+
+
+/*
+ * Copyright (c) 2001-2003, Adam Dunkels.
+ * 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 uIP TCP/IP stack.
+ *
+ * $Id: uip.h,v 1.40 2006/06/08 07:12:07 adam Exp $
+ *
+ */
+
+#ifndef __UIP_H__
+#define __UIP_H__
+
+#include "uipopt.h"
+
+/**
+ * Repressentation of an IP address.
+ *
+ */
+typedef u16_t uip_ip4addr_t[2];
+typedef u16_t uip_ip6addr_t[8];
+#if UIP_CONF_IPV6
+typedef uip_ip6addr_t uip_ipaddr_t;
+#else /* UIP_CONF_IPV6 */
+typedef uip_ip4addr_t uip_ipaddr_t;
+#endif /* UIP_CONF_IPV6 */
+
+/*---------------------------------------------------------------------------*/
+/* First, the functions that should be called from the
+ * system. Initialization, the periodic timer and incoming packets are
+ * handled by the following three functions.
+ */
+
+/**
+ * \defgroup uipconffunc uIP configuration functions
+ * @{
+ *
+ * The uIP configuration functions are used for setting run-time
+ * parameters in uIP such as IP addresses.
+ */
+
+/**
+ * Set the IP address of this host.
+ *
+ * The IP address is represented as a 4-byte array where the first
+ * octet of the IP address is put in the first member of the 4-byte
+ * array.
+ *
+ * Example:
+ \code
+
+ uip_ipaddr_t addr;
+
+ uip_ipaddr(&addr, 192,168,1,2);
+ uip_sethostaddr(&addr);
+
+ \endcode
+ * \param addr A pointer to an IP address of type uip_ipaddr_t;
+ *
+ * \sa uip_ipaddr()
+ *
+ * \hideinitializer
+ */
+#define uip_sethostaddr(addr) uip_ipaddr_copy(uip_hostaddr, (addr))
+
+/**
+ * Get the IP address of this host.
+ *
+ * The IP address is represented as a 4-byte array where the first
+ * octet of the IP address is put in the first member of the 4-byte
+ * array.
+ *
+ * Example:
+ \code
+ uip_ipaddr_t hostaddr;
+
+ uip_gethostaddr(&hostaddr);
+ \endcode
+ * \param addr A pointer to a uip_ipaddr_t variable that will be
+ * filled in with the currently configured IP address.
+ *
+ * \hideinitializer
+ */
+#define uip_gethostaddr(addr) uip_ipaddr_copy((addr), uip_hostaddr)
+
+/**
+ * Set the default router's IP address.
+ *
+ * \param addr A pointer to a uip_ipaddr_t variable containing the IP
+ * address of the default router.
+ *
+ * \sa uip_ipaddr()
+ *
+ * \hideinitializer
+ */
+#define uip_setdraddr(addr) uip_ipaddr_copy(uip_draddr, (addr))
+
+/**
+ * Set the netmask.
+ *
+ * \param addr A pointer to a uip_ipaddr_t variable containing the IP
+ * address of the netmask.
+ *
+ * \sa uip_ipaddr()
+ *
+ * \hideinitializer
+ */
+#define uip_setnetmask(addr) uip_ipaddr_copy(uip_netmask, (addr))
+
+
+/**
+ * Get the default router's IP address.
+ *
+ * \param addr A pointer to a uip_ipaddr_t variable that will be
+ * filled in with the IP address of the default router.
+ *
+ * \hideinitializer
+ */
+#define uip_getdraddr(addr) uip_ipaddr_copy((addr), uip_draddr)
+
+/**
+ * Get the netmask.
+ *
+ * \param addr A pointer to a uip_ipaddr_t variable that will be
+ * filled in with the value of the netmask.
+ *
+ * \hideinitializer
+ */
+#define uip_getnetmask(addr) uip_ipaddr_copy((addr), uip_netmask)
+
+/** @} */
+
+/**
+ * \defgroup uipinit uIP initialization functions
+ * @{
+ *
+ * The uIP initialization functions are used for booting uIP.
+ */
+
+/**
+ * uIP initialization function.
+ *
+ * This function should be called at boot up to initilize the uIP
+ * TCP/IP stack.
+ */
+void uip_init(void);
+
+/**
+ * uIP initialization function.
+ *
+ * This function may be used at boot time to set the initial ip_id.
+ */
+void uip_setipid(u16_t id);
+
+/** @} */
+
+/**
+ * \defgroup uipdevfunc uIP device driver functions
+ * @{
+ *
+ * These functions are used by a network device driver for interacting
+ * with uIP.
+ */
+
+/**
+ * Process an incoming packet.
+ *
+ * This function should be called when the device driver has received
+ * a packet from the network. The packet from the device driver must
+ * be present in the uip_buf buffer, and the length of the packet
+ * should be placed in the uip_len variable.
+ *
+ * When the function returns, there may be an outbound packet placed
+ * in the uip_buf packet buffer. If so, the uip_len variable is set to
+ * the length of the packet. If no packet is to be sent out, the
+ * uip_len variable is set to 0.
+ *
+ * The usual way of calling the function is presented by the source
+ * code below.
+ \code
+ uip_len = devicedriver_poll();
+ if(uip_len > 0) {
+ uip_input();
+ if(uip_len > 0) {
+ devicedriver_send();
+ }
+ }
+ \endcode
+ *
+ * \note If you are writing a uIP device driver that needs ARP
+ * (Address Resolution Protocol), e.g., when running uIP over
+ * Ethernet, you will need to call the uIP ARP code before calling
+ * this function:
+ \code
+ #define BUF ((struct uip_eth_hdr *)&uip_buf[0])
+ uip_len = ethernet_devicedrver_poll();
+ if(uip_len > 0) {
+ if(BUF->type == HTONS(UIP_ETHTYPE_IP)) {
+ uip_arp_ipin();
+ uip_input();
+ if(uip_len > 0) {
+ uip_arp_out();
+ ethernet_devicedriver_send();
+ }
+ } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) {
+ uip_arp_arpin();
+ if(uip_len > 0) {
+ ethernet_devicedriver_send();
+ }
+ }
+ \endcode
+ *
+ * \hideinitializer
+ */
+#define uip_input() uip_process(UIP_DATA)
+
+/**
+ * Periodic processing for a connection identified by its number.
+ *
+ * This function does the necessary periodic processing (timers,
+ * polling) for a uIP TCP conneciton, and should be called when the
+ * periodic uIP timer goes off. It should be called for every
+ * connection, regardless of whether they are open of closed.
+ *
+ * When the function returns, it may have an outbound packet waiting
+ * for service in the uIP packet buffer, and if so the uip_len
+ * variable is set to a value larger than zero. The device driver
+ * should be called to send out the packet.
+ *
+ * The ususal way of calling the function is through a for() loop like
+ * this:
+ \code
+ for(i = 0; i < UIP_CONNS; ++i) {
+ uip_periodic(i);
+ if(uip_len > 0) {
+ devicedriver_send();
+ }
+ }
+ \endcode
+ *
+ * \note If you are writing a uIP device driver that needs ARP
+ * (Address Resolution Protocol), e.g., when running uIP over
+ * Ethernet, you will need to call the uip_arp_out() function before
+ * calling the device driver:
+ \code
+ for(i = 0; i < UIP_CONNS; ++i) {
+ uip_periodic(i);
+ if(uip_len > 0) {
+ uip_arp_out();
+ ethernet_devicedriver_send();
+ }
+ }
+ \endcode
+ *
+ * \param conn The number of the connection which is to be periodically polled.
+ *
+ * \hideinitializer
+ */
+#define uip_periodic(conn) do { uip_conn = &uip_conns[conn]; \
+ uip_process(UIP_TIMER); } while (0)
+
+/**
+ *
+ *
+ */
+#define uip_conn_active(conn) (uip_conns[conn].tcpstateflags != UIP_CLOSED)
+
+/**
+ * Perform periodic processing for a connection identified by a pointer
+ * to its structure.
+ *
+ * Same as uip_periodic() but takes a pointer to the actual uip_conn
+ * struct instead of an integer as its argument. This function can be
+ * used to force periodic processing of a specific connection.
+ *
+ * \param conn A pointer to the uip_conn struct for the connection to
+ * be processed.
+ *
+ * \hideinitializer
+ */
+#define uip_periodic_conn(conn) do { uip_conn = conn; \
+ uip_process(UIP_TIMER); } while (0)
+
+/**
+ * Reuqest that a particular connection should be polled.
+ *
+ * Similar to uip_periodic_conn() but does not perform any timer
+ * processing. The application is polled for new data.
+ *
+ * \param conn A pointer to the uip_conn struct for the connection to
+ * be processed.
+ *
+ * \hideinitializer
+ */
+#define uip_poll_conn(conn) do { uip_conn = conn; \
+ uip_process(UIP_POLL_REQUEST); } while (0)
+
+
+#if UIP_UDP
+/**
+ * Periodic processing for a UDP connection identified by its number.
+ *
+ * This function is essentially the same as uip_periodic(), but for
+ * UDP connections. It is called in a similar fashion as the
+ * uip_periodic() function:
+ \code
+ for(i = 0; i < UIP_UDP_CONNS; i++) {
+ uip_udp_periodic(i);
+ if(uip_len > 0) {
+ devicedriver_send();
+ }
+ }
+ \endcode
+ *
+ * \note As for the uip_periodic() function, special care has to be
+ * taken when using uIP together with ARP and Ethernet:
+ \code
+ for(i = 0; i < UIP_UDP_CONNS; i++) {
+ uip_udp_periodic(i);
+ if(uip_len > 0) {
+ uip_arp_out();
+ ethernet_devicedriver_send();
+ }
+ }
+ \endcode
+ *
+ * \param conn The number of the UDP connection to be processed.
+ *
+ * \hideinitializer
+ */
+#define uip_udp_periodic(conn) do { uip_udp_conn = &uip_udp_conns[conn]; \
+ uip_process(UIP_UDP_TIMER); } while (0)
+
+/**
+ * Periodic processing for a UDP connection identified by a pointer to
+ * its structure.
+ *
+ * Same as uip_udp_periodic() but takes a pointer to the actual
+ * uip_conn struct instead of an integer as its argument. This
+ * function can be used to force periodic processing of a specific
+ * connection.
+ *
+ * \param conn A pointer to the uip_udp_conn struct for the connection
+ * to be processed.
+ *
+ * \hideinitializer
+ */
+#define uip_udp_periodic_conn(conn) do { uip_udp_conn = conn; \
+ uip_process(UIP_UDP_TIMER); } while (0)
+
+
+#endif /* UIP_UDP */
+
+/**
+ * The uIP packet buffer.
+ *
+ * The uip_buf array is used to hold incoming and outgoing
+ * packets. The device driver should place incoming data into this
+ * buffer. When sending data, the device driver should read the link
+ * level headers and the TCP/IP headers from this buffer. The size of
+ * the link level headers is configured by the UIP_LLH_LEN define.
+ *
+ * \note The application data need not be placed in this buffer, so
+ * the device driver must read it from the place pointed to by the
+ * uip_appdata pointer as illustrated by the following example:
+ \code
+ void
+ devicedriver_send(void)
+ {
+ hwsend(&uip_buf[0], UIP_LLH_LEN);
+ if(uip_len <= UIP_LLH_LEN + UIP_TCPIP_HLEN) {
+ hwsend(&uip_buf[UIP_LLH_LEN], uip_len - UIP_LLH_LEN);
+ } else {
+ hwsend(&uip_buf[UIP_LLH_LEN], UIP_TCPIP_HLEN);
+ hwsend(uip_appdata, uip_len - UIP_TCPIP_HLEN - UIP_LLH_LEN);
+ }
+ }
+ \endcode
+ */
+extern u8_t uip_buf[UIP_BUFSIZE+2];
+
+/** @} */
+
+/*---------------------------------------------------------------------------*/
+/* Functions that are used by the uIP application program. Opening and
+ * closing connections, sending and receiving data, etc. is all
+ * handled by the functions below.
+*/
+/**
+ * \defgroup uipappfunc uIP application functions
+ * @{
+ *
+ * Functions used by an application running of top of uIP.
+ */
+
+/**
+ * Start listening to the specified port.
+ *
+ * \note Since this function expects the port number in network byte
+ * order, a conversion using HTONS() or uip_htons() is necessary.
+ *
+ \code
+ uip_listen(HTONS(80));
+ \endcode
+ *
+ * \param port A 16-bit port number in network byte order.
+ */
+void uip_listen(u16_t port);
+
+/**
+ * Stop listening to the specified port.
+ *
+ * \note Since this function expects the port number in network byte
+ * order, a conversion using HTONS() or uip_htons() is necessary.
+ *
+ \code
+ uip_unlisten(HTONS(80));
+ \endcode
+ *
+ * \param port A 16-bit port number in network byte order.
+ */
+void uip_unlisten(u16_t port);
+
+/**
+ * Connect to a remote host using TCP.
+ *
+ * This function is used to start a new connection to the specified
+ * port on the specied host. It allocates a new connection identifier,
+ * sets the connection to the SYN_SENT state and sets the
+ * retransmission timer to 0. This will cause a TCP SYN segment to be
+ * sent out the next time this connection is periodically processed,
+ * which usually is done within 0.5 seconds after the call to
+ * uip_connect().
+ *
+ * \note This function is avaliable only if support for active open
+ * has been configured by defining UIP_ACTIVE_OPEN to 1 in uipopt.h.
+ *
+ * \note Since this function requires the port number to be in network
+ * byte order, a conversion using HTONS() or uip_htons() is necessary.
+ *
+ \code
+ uip_ipaddr_t ipaddr;
+
+ uip_ipaddr(&ipaddr, 192,168,1,2);
+ uip_connect(&ipaddr, HTONS(80));
+ \endcode
+ *
+ * \param ripaddr The IP address of the remote hot.
+ *
+ * \param port A 16-bit port number in network byte order.
+ *
+ * \return A pointer to the uIP connection identifier for the new connection,
+ * or NULL if no connection could be allocated.
+ *
+ */
+struct uip_conn *uip_connect(uip_ipaddr_t *ripaddr, u16_t port);
+
+
+
+/**
+ * \internal
+ *
+ * Check if a connection has outstanding (i.e., unacknowledged) data.
+ *
+ * \param conn A pointer to the uip_conn structure for the connection.
+ *
+ * \hideinitializer
+ */
+#define uip_outstanding(conn) ((conn)->len)
+
+/**
+ * Send data on the current connection.
+ *
+ * This function is used to send out a single segment of TCP
+ * data. Only applications that have been invoked by uIP for event
+ * processing can send data.
+ *
+ * The amount of data that actually is sent out after a call to this
+ * funcion is determined by the maximum amount of data TCP allows. uIP
+ * will automatically crop the data so that only the appropriate
+ * amount of data is sent. The function uip_mss() can be used to query
+ * uIP for the amount of data that actually will be sent.
+ *
+ * \note This function does not guarantee that the sent data will
+ * arrive at the destination. If the data is lost in the network, the
+ * application will be invoked with the uip_rexmit() event being
+ * set. The application will then have to resend the data using this
+ * function.
+ *
+ * \param data A pointer to the data which is to be sent.
+ *
+ * \param len The maximum amount of data bytes to be sent.
+ *
+ * \hideinitializer
+ */
+void uip_send(const void *data, int len);
+
+/**
+ * The length of any incoming data that is currently avaliable (if avaliable)
+ * in the uip_appdata buffer.
+ *
+ * The test function uip_data() must first be used to check if there
+ * is any data available at all.
+ *
+ * \hideinitializer
+ */
+/*void uip_datalen(void);*/
+#define uip_datalen() uip_len
+
+/**
+ * The length of any out-of-band data (urgent data) that has arrived
+ * on the connection.
+ *
+ * \note The configuration parameter UIP_URGDATA must be set for this
+ * function to be enabled.
+ *
+ * \hideinitializer
+ */
+#define uip_urgdatalen() uip_urglen
+
+/**
+ * Close the current connection.
+ *
+ * This function will close the current connection in a nice way.
+ *
+ * \hideinitializer
+ */
+#define uip_close() (uip_flags = UIP_CLOSE)
+
+/**
+ * Abort the current connection.
+ *
+ * This function will abort (reset) the current connection, and is
+ * usually used when an error has occured that prevents using the
+ * uip_close() function.
+ *
+ * \hideinitializer
+ */
+#define uip_abort() (uip_flags = UIP_ABORT)
+
+/**
+ * Tell the sending host to stop sending data.
+ *
+ * This function will close our receiver's window so that we stop
+ * receiving data for the current connection.
+ *
+ * \hideinitializer
+ */
+#define uip_stop() (uip_conn->tcpstateflags |= UIP_STOPPED)
+
+/**
+ * Find out if the current connection has been previously stopped with
+ * uip_stop().
+ *
+ * \hideinitializer
+ */
+#define uip_stopped(conn) ((conn)->tcpstateflags & UIP_STOPPED)
+
+/**
+ * Restart the current connection, if is has previously been stopped
+ * with uip_stop().
+ *
+ * This function will open the receiver's window again so that we
+ * start receiving data for the current connection.
+ *
+ * \hideinitializer
+ */
+#define uip_restart() do { uip_flags |= UIP_NEWDATA; \
+ uip_conn->tcpstateflags &= ~UIP_STOPPED; \
+ } while(0)
+
+
+/* uIP tests that can be made to determine in what state the current
+ connection is, and what the application function should do. */
+
+/**
+ * Is the current connection a UDP connection?
+ *
+ * This function checks whether the current connection is a UDP connection.
+ *
+ * \hideinitializer
+ *
+ */
+#define uip_udpconnection() (uip_conn == NULL)
+
+/**
+ * Is new incoming data available?
+ *
+ * Will reduce to non-zero if there is new data for the application
+ * present at the uip_appdata pointer. The size of the data is
+ * avaliable through the uip_len variable.
+ *
+ * \hideinitializer
+ */
+#define uip_newdata() (uip_flags & UIP_NEWDATA)
+
+/**
+ * Has previously sent data been acknowledged?
+ *
+ * Will reduce to non-zero if the previously sent data has been
+ * acknowledged by the remote host. This means that the application
+ * can send new data.
+ *
+ * \hideinitializer
+ */
+#define uip_acked() (uip_flags & UIP_ACKDATA)
+
+/**
+ * Has the connection just been connected?
+ *
+ * Reduces to non-zero if the current connection has been connected to
+ * a remote host. This will happen both if the connection has been
+ * actively opened (with uip_connect()) or passively opened (with
+ * uip_listen()).
+ *
+ * \hideinitializer
+ */
+#define uip_connected() (uip_flags & UIP_CONNECTED)
+
+/**
+ * Has the connection been closed by the other end?
+ *
+ * Is non-zero if the connection has been closed by the remote
+ * host. The application may then do the necessary clean-ups.
+ *
+ * \hideinitializer
+ */
+#define uip_closed() (uip_flags & UIP_CLOSE)
+
+/**
+ * Has the connection been aborted by the other end?
+ *
+ * Non-zero if the current connection has been aborted (reset) by the
+ * remote host.
+ *
+ * \hideinitializer
+ */
+#define uip_aborted() (uip_flags & UIP_ABORT)
+
+/**
+ * Has the connection timed out?
+ *
+ * Non-zero if the current connection has been aborted due to too many
+ * retransmissions.
+ *
+ * \hideinitializer
+ */
+#define uip_timedout() (uip_flags & UIP_TIMEDOUT)
+
+/**
+ * Do we need to retransmit previously data?
+ *
+ * Reduces to non-zero if the previously sent data has been lost in
+ * the network, and the application should retransmit it. The
+ * application should send the exact same data as it did the last
+ * time, using the uip_send() function.
+ *
+ * \hideinitializer
+ */
+#define uip_rexmit() (uip_flags & UIP_REXMIT)
+
+/**
+ * Is the connection being polled by uIP?
+ *
+ * Is non-zero if the reason the application is invoked is that the
+ * current connection has been idle for a while and should be
+ * polled.
+ *
+ * The polling event can be used for sending data without having to
+ * wait for the remote host to send data.
+ *
+ * \hideinitializer
+ */
+#define uip_poll() (uip_flags & UIP_POLL)
+
+/**
+ * Get the initial maxium segment size (MSS) of the current
+ * connection.
+ *
+ * \hideinitializer
+ */
+#define uip_initialmss() (uip_conn->initialmss)
+
+/**
+ * Get the current maxium segment size that can be sent on the current
+ * connection.
+ *
+ * The current maxiumum segment size that can be sent on the
+ * connection is computed from the receiver's window and the MSS of
+ * the connection (which also is available by calling
+ * uip_initialmss()).
+ *
+ * \hideinitializer
+ */
+#define uip_mss() (uip_conn->mss)
+
+/**
+ * Set up a new UDP connection.
+ *
+ * This function sets up a new UDP connection. The function will
+ * automatically allocate an unused local port for the new
+ * connection. However, another port can be chosen by using the
+ * uip_udp_bind() call, after the uip_udp_new() function has been
+ * called.
+ *
+ * Example:
+ \code
+ uip_ipaddr_t addr;
+ struct uip_udp_conn *c;
+
+ uip_ipaddr(&addr, 192,168,2,1);
+ c = uip_udp_new(&addr, HTONS(12345));
+ if(c != NULL) {
+ uip_udp_bind(c, HTONS(12344));
+ }
+ \endcode
+ * \param ripaddr The IP address of the remote host.
+ *
+ * \param rport The remote port number in network byte order.
+ *
+ * \return The uip_udp_conn structure for the new connection or NULL
+ * if no connection could be allocated.
+ */
+struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport);
+
+/**
+ * Removed a UDP connection.
+ *
+ * \param conn A pointer to the uip_udp_conn structure for the connection.
+ *
+ * \hideinitializer
+ */
+#define uip_udp_remove(conn) (conn)->lport = 0
+
+/**
+ * Bind a UDP connection to a local port.
+ *
+ * \param conn A pointer to the uip_udp_conn structure for the
+ * connection.
+ *
+ * \param port The local port number, in network byte order.
+ *
+ * \hideinitializer
+ */
+#define uip_udp_bind(conn, port) (conn)->lport = port
+
+/**
+ * Send a UDP datagram of length len on the current connection.
+ *
+ * This function can only be called in response to a UDP event (poll
+ * or newdata). The data must be present in the uip_buf buffer, at the
+ * place pointed to by the uip_appdata pointer.
+ *
+ * \param len The length of the data in the uip_buf buffer.
+ *
+ * \hideinitializer
+ */
+#define uip_udp_send(len) uip_send((char *)uip_appdata, len)
+
+/** @} */
+
+/* uIP convenience and converting functions. */
+
+/**
+ * \defgroup uipconvfunc uIP conversion functions
+ * @{
+ *
+ * These functions can be used for converting between different data
+ * formats used by uIP.
+ */
+
+/**
+ * Construct an IP address from four bytes.
+ *
+ * This function constructs an IP address of the type that uIP handles
+ * internally from four bytes. The function is handy for specifying IP
+ * addresses to use with e.g. the uip_connect() function.
+ *
+ * Example:
+ \code
+ uip_ipaddr_t ipaddr;
+ struct uip_conn *c;
+
+ uip_ipaddr(&ipaddr, 192,168,1,2);
+ c = uip_connect(&ipaddr, HTONS(80));
+ \endcode
+ *
+ * \param addr A pointer to a uip_ipaddr_t variable that will be
+ * filled in with the IP address.
+ *
+ * \param addr0 The first octet of the IP address.
+ * \param addr1 The second octet of the IP address.
+ * \param addr2 The third octet of the IP address.
+ * \param addr3 The forth octet of the IP address.
+ *
+ * \hideinitializer
+ */
+#define uip_ipaddr(addr, addr0,addr1,addr2,addr3) do { \
+ ((u16_t *)(addr))[0] = HTONS(((addr0) << 8) | (addr1)); \
+ ((u16_t *)(addr))[1] = HTONS(((addr2) << 8) | (addr3)); \
+ } while(0)
+
+/**
+ * Construct an IPv6 address from eight 16-bit words.
+ *
+ * This function constructs an IPv6 address.
+ *
+ * \hideinitializer
+ */
+#define uip_ip6addr(addr, addr0,addr1,addr2,addr3,addr4,addr5,addr6,addr7) do { \
+ ((u16_t *)(addr))[0] = HTONS((addr0)); \
+ ((u16_t *)(addr))[1] = HTONS((addr1)); \
+ ((u16_t *)(addr))[2] = HTONS((addr2)); \
+ ((u16_t *)(addr))[3] = HTONS((addr3)); \
+ ((u16_t *)(addr))[4] = HTONS((addr4)); \
+ ((u16_t *)(addr))[5] = HTONS((addr5)); \
+ ((u16_t *)(addr))[6] = HTONS((addr6)); \
+ ((u16_t *)(addr))[7] = HTONS((addr7)); \
+ } while(0)
+
+/**
+ * Copy an IP address to another IP address.
+ *
+ * Copies an IP address from one place to another.
+ *
+ * Example:
+ \code
+ uip_ipaddr_t ipaddr1, ipaddr2;
+
+ uip_ipaddr(&ipaddr1, 192,16,1,2);
+ uip_ipaddr_copy(&ipaddr2, &ipaddr1);
+ \endcode
+ *
+ * \param dest The destination for the copy.
+ * \param src The source from where to copy.
+ *
+ * \hideinitializer
+ */
+#if !UIP_CONF_IPV6
+#define uip_ipaddr_copy(dest, src) do { \
+ ((u16_t *)dest)[0] = ((u16_t *)src)[0]; \
+ ((u16_t *)dest)[1] = ((u16_t *)src)[1]; \
+ } while(0)
+#else /* !UIP_CONF_IPV6 */
+#define uip_ipaddr_copy(dest, src) memcpy(dest, src, sizeof(uip_ip6addr_t))
+#endif /* !UIP_CONF_IPV6 */
+
+/**
+ * Compare two IP addresses
+ *
+ * Compares two IP addresses.
+ *
+ * Example:
+ \code
+ uip_ipaddr_t ipaddr1, ipaddr2;
+
+ uip_ipaddr(&ipaddr1, 192,16,1,2);
+ if(uip_ipaddr_cmp(&ipaddr2, &ipaddr1)) {
+ printf("They are the same");
+ }
+ \endcode
+ *
+ * \param addr1 The first IP address.
+ * \param addr2 The second IP address.
+ *
+ * \hideinitializer
+ */
+#if !UIP_CONF_IPV6
+#define uip_ipaddr_cmp(addr1, addr2) (((u16_t *)addr1)[0] == ((u16_t *)addr2)[0] && \
+ ((u16_t *)addr1)[1] == ((u16_t *)addr2)[1])
+#else /* !UIP_CONF_IPV6 */
+#define uip_ipaddr_cmp(addr1, addr2) (memcmp(addr1, addr2, sizeof(uip_ip6addr_t)) == 0)
+#endif /* !UIP_CONF_IPV6 */
+
+/**
+ * Compare two IP addresses with netmasks
+ *
+ * Compares two IP addresses with netmasks. The masks are used to mask
+ * out the bits that are to be compared.
+ *
+ * Example:
+ \code
+ uip_ipaddr_t ipaddr1, ipaddr2, mask;
+
+ uip_ipaddr(&mask, 255,255,255,0);
+ uip_ipaddr(&ipaddr1, 192,16,1,2);
+ uip_ipaddr(&ipaddr2, 192,16,1,3);
+ if(uip_ipaddr_maskcmp(&ipaddr1, &ipaddr2, &mask)) {
+ printf("They are the same");
+ }
+ \endcode
+ *
+ * \param addr1 The first IP address.
+ * \param addr2 The second IP address.
+ * \param mask The netmask.
+ *
+ * \hideinitializer
+ */
+#define uip_ipaddr_maskcmp(addr1, addr2, mask) \
+ (((((u16_t *)addr1)[0] & ((u16_t *)mask)[0]) == \
+ (((u16_t *)addr2)[0] & ((u16_t *)mask)[0])) && \
+ ((((u16_t *)addr1)[1] & ((u16_t *)mask)[1]) == \
+ (((u16_t *)addr2)[1] & ((u16_t *)mask)[1])))
+
+
+/**
+ * Mask out the network part of an IP address.
+ *
+ * Masks out the network part of an IP address, given the address and
+ * the netmask.
+ *
+ * Example:
+ \code
+ uip_ipaddr_t ipaddr1, ipaddr2, netmask;
+
+ uip_ipaddr(&ipaddr1, 192,16,1,2);
+ uip_ipaddr(&netmask, 255,255,255,0);
+ uip_ipaddr_mask(&ipaddr2, &ipaddr1, &netmask);
+ \endcode
+ *
+ * In the example above, the variable "ipaddr2" will contain the IP
+ * address 192.168.1.0.
+ *
+ * \param dest Where the result is to be placed.
+ * \param src The IP address.
+ * \param mask The netmask.
+ *
+ * \hideinitializer
+ */
+#define uip_ipaddr_mask(dest, src, mask) do { \
+ ((u16_t *)dest)[0] = ((u16_t *)src)[0] & ((u16_t *)mask)[0]; \
+ ((u16_t *)dest)[1] = ((u16_t *)src)[1] & ((u16_t *)mask)[1]; \
+ } while(0)
+
+/**
+ * Pick the first octet of an IP address.
+ *
+ * Picks out the first octet of an IP address.
+ *
+ * Example:
+ \code
+ uip_ipaddr_t ipaddr;
+ u8_t octet;
+
+ uip_ipaddr(&ipaddr, 1,2,3,4);
+ octet = uip_ipaddr1(&ipaddr);
+ \endcode
+ *
+ * In the example above, the variable "octet" will contain the value 1.
+ *
+ * \hideinitializer
+ */
+#define uip_ipaddr1(addr) (uip_htons(((u16_t *)(addr))[0]) >> 8)
+
+/**
+ * Pick the second octet of an IP address.
+ *
+ * Picks out the second octet of an IP address.
+ *
+ * Example:
+ \code
+ uip_ipaddr_t ipaddr;
+ u8_t octet;
+
+ uip_ipaddr(&ipaddr, 1,2,3,4);
+ octet = uip_ipaddr2(&ipaddr);
+ \endcode
+ *
+ * In the example above, the variable "octet" will contain the value 2.
+ *
+ * \hideinitializer
+ */
+#define uip_ipaddr2(addr) (uip_htons(((u16_t *)(addr))[0]) & 0xff)
+
+/**
+ * Pick the third octet of an IP address.
+ *
+ * Picks out the third octet of an IP address.
+ *
+ * Example:
+ \code
+ uip_ipaddr_t ipaddr;
+ u8_t octet;
+
+ uip_ipaddr(&ipaddr, 1,2,3,4);
+ octet = uip_ipaddr3(&ipaddr);
+ \endcode
+ *
+ * In the example above, the variable "octet" will contain the value 3.
+ *
+ * \hideinitializer
+ */
+#define uip_ipaddr3(addr) (uip_htons(((u16_t *)(addr))[1]) >> 8)
+
+/**
+ * Pick the fourth octet of an IP address.
+ *
+ * Picks out the fourth octet of an IP address.
+ *
+ * Example:
+ \code
+ uip_ipaddr_t ipaddr;
+ u8_t octet;
+
+ uip_ipaddr(&ipaddr, 1,2,3,4);
+ octet = uip_ipaddr4(&ipaddr);
+ \endcode
+ *
+ * In the example above, the variable "octet" will contain the value 4.
+ *
+ * \hideinitializer
+ */
+#define uip_ipaddr4(addr) (uip_htons(((u16_t *)(addr))[1]) & 0xff)
+
+/**
+ * Convert 16-bit quantity from host byte order to network byte order.
+ *
+ * This macro is primarily used for converting constants from host
+ * byte order to network byte order. For converting variables to
+ * network byte order, use the uip_htons() function instead.
+ *
+ * \hideinitializer
+ */
+#ifndef HTONS
+# if UIP_BYTE_ORDER == UIP_BIG_ENDIAN
+# define HTONS(n) (n)
+# else /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */
+# define HTONS(n) (u16_t)((((u16_t) (n)) << 8) | (((u16_t) (n)) >> 8))
+# endif /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */
+#else
+#error "HTONS already defined!"
+#endif /* HTONS */
+
+/**
+ * Convert 16-bit quantity from host byte order to network byte order.
+ *
+ * This function is primarily used for converting variables from host
+ * byte order to network byte order. For converting constants to
+ * network byte order, use the HTONS() macro instead.
+ */
+
+#ifndef uip_htons
+u16_t uip_htons(u16_t val);
+#endif /* uip_htons */
+#ifndef ntohs
+#define ntohs uip_htons
+#endif
+
+/** @} */
+
+/**
+ * Pointer to the application data in the packet buffer.
+ *
+ * This pointer points to the application data when the application is
+ * called. If the application wishes to send data, the application may
+ * use this space to write the data into before calling uip_send().
+ */
+extern volatile u8_t *uip_appdata;
+
+#if UIP_URGDATA > 0
+/* u8_t *uip_urgdata:
+ *
+ * This pointer points to any urgent data that has been received. Only
+ * present if compiled with support for urgent data (UIP_URGDATA).
+ */
+extern void *uip_urgdata;
+#endif /* UIP_URGDATA > 0 */
+
+
+/**
+ * \defgroup uipdrivervars Variables used in uIP device drivers
+ * @{
+ *
+ * uIP has a few global variables that are used in device drivers for
+ * uIP.
+ */
+
+/**
+ * The length of the packet in the uip_buf buffer.
+ *
+ * The global variable uip_len holds the length of the packet in the
+ * uip_buf buffer.
+ *
+ * When the network device driver calls the uIP input function,
+ * uip_len should be set to the length of the packet in the uip_buf
+ * buffer.
+ *
+ * When sending packets, the device driver should use the contents of
+ * the uip_len variable to determine the length of the outgoing
+ * packet.
+ *
+ */
+extern u16_t uip_len;
+
+/** @} */
+
+#if UIP_URGDATA > 0
+extern u16_t uip_urglen, uip_surglen;
+#endif /* UIP_URGDATA > 0 */
+
+
+/**
+ * Representation of a uIP TCP connection.
+ *
+ * The uip_conn structure is used for identifying a connection. All
+ * but one field in the structure are to be considered read-only by an
+ * application. The only exception is the appstate field whos purpose
+ * is to let the application store application-specific state (e.g.,
+ * file pointers) for the connection. The type of this field is
+ * configured in the "uipopt.h" header file.
+ */
+struct uip_conn {
+ uip_ipaddr_t ripaddr; /**< The IP address of the remote host. */
+
+ u16_t lport; /**< The local TCP port, in network byte order. */
+ u16_t rport; /**< The local remote TCP port, in network byte
+ order. */
+
+ u8_t rcv_nxt[4]; /**< The sequence number that we expect to
+ receive next. */
+ u8_t snd_nxt[4]; /**< The sequence number that was last sent by
+ us. */
+ u16_t len; /**< Length of the data that was previously sent. */
+ u16_t mss; /**< Current maximum segment size for the
+ connection. */
+ u16_t initialmss; /**< Initial maximum segment size for the
+ connection. */
+ u8_t sa; /**< Retransmission time-out calculation state
+ variable. */
+ u8_t sv; /**< Retransmission time-out calculation state
+ variable. */
+ u8_t rto; /**< Retransmission time-out. */
+ u8_t tcpstateflags; /**< TCP state and flags. */
+ u8_t timer; /**< The retransmission timer. */
+ u8_t nrtx; /**< The number of retransmissions for the last
+ segment sent. */
+
+ /** The application state. */
+ uip_tcp_appstate_t appstate;
+};
+
+
+/**
+ * Pointer to the current TCP connection.
+ *
+ * The uip_conn pointer can be used to access the current TCP
+ * connection.
+ */
+extern struct uip_conn *uip_conn;
+/* The array containing all uIP connections. */
+extern struct uip_conn uip_conns[UIP_CONNS];
+/**
+ * \addtogroup uiparch
+ * @{
+ */
+
+/**
+ * 4-byte array used for the 32-bit sequence number calculations.
+ */
+extern u8_t uip_acc32[4];
+
+/** @} */
+
+
+#if UIP_UDP
+/**
+ * Representation of a uIP UDP connection.
+ */
+struct uip_udp_conn {
+ uip_ipaddr_t ripaddr; /**< The IP address of the remote peer. */
+ u16_t lport; /**< The local port number in network byte order. */
+ u16_t rport; /**< The remote port number in network byte order. */
+ u8_t ttl; /**< Default time-to-live. */
+
+ /** The application state. */
+ uip_udp_appstate_t appstate;
+};
+
+/**
+ * The current UDP connection.
+ */
+extern struct uip_udp_conn *uip_udp_conn;
+extern struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
+#endif /* UIP_UDP */
+
+/**
+ * The structure holding the TCP/IP statistics that are gathered if
+ * UIP_STATISTICS is set to 1.
+ *
+ */
+struct uip_stats {
+ struct {
+ uip_stats_t drop; /**< Number of dropped packets at the IP
+ layer. */
+ uip_stats_t recv; /**< Number of received packets at the IP
+ layer. */
+ uip_stats_t sent; /**< Number of sent packets at the IP
+ layer. */
+ uip_stats_t vhlerr; /**< Number of packets dropped due to wrong
+ IP version or header length. */
+ uip_stats_t hblenerr; /**< Number of packets dropped due to wrong
+ IP length, high byte. */
+ uip_stats_t lblenerr; /**< Number of packets dropped due to wrong
+ IP length, low byte. */
+ uip_stats_t fragerr; /**< Number of packets dropped since they
+ were IP fragments. */
+ uip_stats_t chkerr; /**< Number of packets dropped due to IP
+ checksum errors. */
+ uip_stats_t protoerr; /**< Number of packets dropped since they
+ were neither ICMP, UDP nor TCP. */
+ } ip; /**< IP statistics. */
+ struct {
+ uip_stats_t drop; /**< Number of dropped ICMP packets. */
+ uip_stats_t recv; /**< Number of received ICMP packets. */
+ uip_stats_t sent; /**< Number of sent ICMP packets. */
+ uip_stats_t typeerr; /**< Number of ICMP packets with a wrong
+ type. */
+ } icmp; /**< ICMP statistics. */
+ struct {
+ uip_stats_t drop; /**< Number of dropped TCP segments. */
+ uip_stats_t recv; /**< Number of recived TCP segments. */
+ uip_stats_t sent; /**< Number of sent TCP segments. */
+ uip_stats_t chkerr; /**< Number of TCP segments with a bad
+ checksum. */
+ uip_stats_t ackerr; /**< Number of TCP segments with a bad ACK
+ number. */
+ uip_stats_t rst; /**< Number of recevied TCP RST (reset) segments. */
+ uip_stats_t rexmit; /**< Number of retransmitted TCP segments. */
+ uip_stats_t syndrop; /**< Number of dropped SYNs due to too few
+ connections was avaliable. */
+ uip_stats_t synrst; /**< Number of SYNs for closed ports,
+ triggering a RST. */
+ } tcp; /**< TCP statistics. */
+#if UIP_UDP
+ struct {
+ uip_stats_t drop; /**< Number of dropped UDP segments. */
+ uip_stats_t recv; /**< Number of recived UDP segments. */
+ uip_stats_t sent; /**< Number of sent UDP segments. */
+ uip_stats_t chkerr; /**< Number of UDP segments with a bad
+ checksum. */
+ } udp; /**< UDP statistics. */
+#endif /* UIP_UDP */
+};
+
+/**
+ * The uIP TCP/IP statistics.
+ *
+ * This is the variable in which the uIP TCP/IP statistics are gathered.
+ */
+extern struct uip_stats uip_stat;
+
+
+/*---------------------------------------------------------------------------*/
+/* All the stuff below this point is internal to uIP and should not be
+ * used directly by an application or by a device driver.
+ */
+/*---------------------------------------------------------------------------*/
+/* u8_t uip_flags:
+ *
+ * When the application is called, uip_flags will contain the flags
+ * that are defined in this file. Please read below for more
+ * infomation.
+ */
+extern u8_t uip_flags;
+
+/* The following flags may be set in the global variable uip_flags
+ before calling the application callback. The UIP_ACKDATA,
+ UIP_NEWDATA, and UIP_CLOSE flags may both be set at the same time,
+ whereas the others are mutualy exclusive. Note that these flags
+ should *NOT* be accessed directly, but only through the uIP
+ functions/macros. */
+
+#define UIP_ACKDATA 1 /* Signifies that the outstanding data was
+ acked and the application should send
+ out new data instead of retransmitting
+ the last data. */
+#define UIP_NEWDATA 2 /* Flags the fact that the peer has sent
+ us new data. */
+#define UIP_REXMIT 4 /* Tells the application to retransmit the
+ data that was last sent. */
+#define UIP_POLL 8 /* Used for polling the application, to
+ check if the application has data that
+ it wants to send. */
+#define UIP_CLOSE 16 /* The remote host has closed the
+ connection, thus the connection has
+ gone away. Or the application signals
+ that it wants to close the
+ connection. */
+#define UIP_ABORT 32 /* The remote host has aborted the
+ connection, thus the connection has
+ gone away. Or the application signals
+ that it wants to abort the
+ connection. */
+#define UIP_CONNECTED 64 /* We have got a connection from a remote
+ host and have set up a new connection
+ for it, or an active connection has
+ been successfully established. */
+
+#define UIP_TIMEDOUT 128 /* The connection has been aborted due to
+ too many retransmissions. */
+
+/* uip_process(flag):
+ *
+ * The actual uIP function which does all the work.
+ */
+void uip_process(u8_t flag);
+
+/* The following flags are passed as an argument to the uip_process()
+ function. They are used to distinguish between the two cases where
+ uip_process() is called. It can be called either because we have
+ incoming data that should be processed, or because the periodic
+ timer has fired. These values are never used directly, but only in
+ the macrose defined in this file. */
+
+#define UIP_DATA 1 /* Tells uIP that there is incoming
+ data in the uip_buf buffer. The
+ length of the data is stored in the
+ global variable uip_len. */
+#define UIP_TIMER 2 /* Tells uIP that the periodic timer
+ has fired. */
+#define UIP_POLL_REQUEST 3 /* Tells uIP that a connection should
+ be polled. */
+#define UIP_UDP_SEND_CONN 4 /* Tells uIP that a UDP datagram
+ should be constructed in the
+ uip_buf buffer. */
+#if UIP_UDP
+#define UIP_UDP_TIMER 5
+#endif /* UIP_UDP */
+
+/* The TCP states used in the uip_conn->tcpstateflags. */
+#define UIP_CLOSED 0
+#define UIP_SYN_RCVD 1
+#define UIP_SYN_SENT 2
+#define UIP_ESTABLISHED 3
+#define UIP_FIN_WAIT_1 4
+#define UIP_FIN_WAIT_2 5
+#define UIP_CLOSING 6
+#define UIP_TIME_WAIT 7
+#define UIP_LAST_ACK 8
+#define UIP_TS_MASK 15
+
+#define UIP_STOPPED 16
+
+/* The TCP and IP headers. */
+struct uip_tcpip_hdr {
+#if UIP_CONF_IPV6
+ /* IPv6 header. */
+ u8_t vtc,
+ tcflow;
+ u16_t flow;
+ u8_t len[2];
+ u8_t proto, ttl;
+ uip_ip6addr_t srcipaddr, destipaddr;
+#else /* UIP_CONF_IPV6 */
+ /* IPv4 header. */
+ u8_t vhl,
+ tos,
+ len[2],
+ ipid[2],
+ ipoffset[2],
+ ttl,
+ proto;
+ u16_t ipchksum;
+ u16_t srcipaddr[2],
+ destipaddr[2];
+#endif /* UIP_CONF_IPV6 */
+
+ /* TCP header. */
+ u16_t srcport,
+ destport;
+ u8_t seqno[4],
+ ackno[4],
+ tcpoffset,
+ flags,
+ wnd[2];
+ u16_t tcpchksum;
+ u8_t urgp[2];
+ u8_t optdata[4];
+};
+
+/* The ICMP and IP headers. */
+struct uip_icmpip_hdr {
+#if UIP_CONF_IPV6
+ /* IPv6 header. */
+ u8_t vtc,
+ tcf;
+ u16_t flow;
+ u8_t len[2];
+ u8_t proto, ttl;
+ uip_ip6addr_t srcipaddr, destipaddr;
+#else /* UIP_CONF_IPV6 */
+ /* IPv4 header. */
+ u8_t vhl,
+ tos,
+ len[2],
+ ipid[2],
+ ipoffset[2],
+ ttl,
+ proto;
+ u16_t ipchksum;
+ u16_t srcipaddr[2],
+ destipaddr[2];
+#endif /* UIP_CONF_IPV6 */
+
+ /* ICMP (echo) header. */
+ u8_t type, icode;
+ u16_t icmpchksum;
+#if !UIP_CONF_IPV6
+ u16_t id, seqno;
+#else /* !UIP_CONF_IPV6 */
+ u8_t flags, reserved1, reserved2, reserved3;
+ u8_t icmp6data[16];
+ u8_t options[1];
+#endif /* !UIP_CONF_IPV6 */
+};
+
+
+/* The UDP and IP headers. */
+struct uip_udpip_hdr {
+#if UIP_CONF_IPV6
+ /* IPv6 header. */
+ u8_t vtc,
+ tcf;
+ u16_t flow;
+ u8_t len[2];
+ u8_t proto, ttl;
+ uip_ip6addr_t srcipaddr, destipaddr;
+#else /* UIP_CONF_IPV6 */
+ /* IP header. */
+ u8_t vhl,
+ tos,
+ len[2],
+ ipid[2],
+ ipoffset[2],
+ ttl,
+ proto;
+ u16_t ipchksum;
+ u16_t srcipaddr[2],
+ destipaddr[2];
+#endif /* UIP_CONF_IPV6 */
+
+ /* UDP header. */
+ u16_t srcport,
+ destport;
+ u16_t udplen;
+ u16_t udpchksum;
+};
+
+
+
+/**
+ * The buffer size available for user data in the \ref uip_buf buffer.
+ *
+ * This macro holds the available size for user data in the \ref
+ * uip_buf buffer. The macro is intended to be used for checking
+ * bounds of available user data.
+ *
+ * Example:
+ \code
+ snprintf(uip_appdata, UIP_APPDATA_SIZE, "%u\n", i);
+ \endcode
+ *
+ * \hideinitializer
+ */
+#define UIP_APPDATA_SIZE (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN)
+
+
+#define UIP_PROTO_ICMP 1
+#define UIP_PROTO_TCP 6
+#define UIP_PROTO_UDP 17
+#define UIP_PROTO_ICMP6 58
+
+/* Header sizes. */
+#if UIP_CONF_IPV6
+#define UIP_IPH_LEN 40
+#else /* UIP_CONF_IPV6 */
+#define UIP_IPH_LEN 20 /* Size of IP header */
+#endif /* UIP_CONF_IPV6 */
+#define UIP_UDPH_LEN 8 /* Size of UDP header */
+#define UIP_TCPH_LEN 20 /* Size of TCP header */
+#define UIP_IPUDPH_LEN (UIP_UDPH_LEN + UIP_IPH_LEN) /* Size of IP +
+ UDP
+ header */
+#define UIP_IPTCPH_LEN (UIP_TCPH_LEN + UIP_IPH_LEN) /* Size of IP +
+ TCP
+ header */
+#define UIP_TCPIP_HLEN UIP_IPTCPH_LEN
+
+
+#if UIP_FIXEDADDR
+extern const uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr;
+#else /* UIP_FIXEDADDR */
+extern uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr;
+#endif /* UIP_FIXEDADDR */
+
+
+
+/**
+ * Representation of a 48-bit Ethernet address.
+ */
+struct uip_eth_addr {
+ u8_t addr[6];
+};
+
+/**
+ * Calculate the Internet checksum over a buffer.
+ *
+ * The Internet checksum is the one's complement of the one's
+ * complement sum of all 16-bit words in the buffer.
+ *
+ * See RFC1071.
+ *
+ * \param buf A pointer to the buffer over which the checksum is to be
+ * computed.
+ *
+ * \param len The length of the buffer over which the checksum is to
+ * be computed.
+ *
+ * \return The Internet checksum of the buffer.
+ */
+u16_t uip_chksum(u16_t *buf, u16_t len);
+
+/**
+ * Calculate the IP header checksum of the packet header in uip_buf.
+ *
+ * The IP header checksum is the Internet checksum of the 20 bytes of
+ * the IP header.
+ *
+ * \return The IP header checksum of the IP header in the uip_buf
+ * buffer.
+ */
+u16_t uip_ipchksum(void);
+
+/**
+ * Calculate the TCP checksum of the packet in uip_buf and uip_appdata.
+ *
+ * The TCP checksum is the Internet checksum of data contents of the
+ * TCP segment, and a pseudo-header as defined in RFC793.
+ *
+ * \return The TCP checksum of the TCP segment in uip_buf and pointed
+ * to by uip_appdata.
+ */
+u16_t uip_tcpchksum(void);
+
+/**
+ * Calculate the UDP checksum of the packet in uip_buf and uip_appdata.
+ *
+ * The UDP checksum is the Internet checksum of data contents of the
+ * UDP segment, and a pseudo-header as defined in RFC768.
+ *
+ * \return The UDP checksum of the UDP segment in uip_buf and pointed
+ * to by uip_appdata.
+ */
+u16_t uip_udpchksum(void);
+
+
+#endif /* __UIP_H__ */
+
+
+/** @} */
diff --git a/components/net/uip/uip/uip_timer.c b/components/net/uip/uip/uip_timer.c
index a411c14d5a..4cd4288196 100644
--- a/components/net/uip/uip/uip_timer.c
+++ b/components/net/uip/uip/uip_timer.c
@@ -1,197 +1,197 @@
-/**
- * \addtogroup timer
- * @{
- */
-
-/**
- * \file
- * Timer library implementation.
- * \author
- * Adam Dunkels <[email protected]>
- */
-
-/*
- * Copyright (c) 2004, 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 uIP TCP/IP stack
- *
- * Author: Adam Dunkels <[email protected]>
- *
- * $Id: timer.c,v 1.2 2006/06/12 08:00:30 adam Exp $
- */
-
-#include "uip_clock.h"
-#include "uip_timer.h"
-//#include "rtconfig.h"
-
-/*---------------------------------------------------------------------------*/
-/**
- * Set a timer.
- *
- * This function is used to set a timer for a time sometime in the
- * future. The function timer_expired() will evaluate to true after
- * the timer has expired.
- *
- * \param t A pointer to the timer
- * \param interval The interval before the timer expires.
- *
- */
-void
-timer_set(struct timer *t, clock_time_t interval)
-{
- t->interval = interval;
- t->start = clock_time();
-}
-/*---------------------------------------------------------------------------*/
-/**
- * Reset the timer with the same interval.
- *
- * This function resets the timer with the same interval that was
- * given to the timer_set() function. The start point of the interval
- * is the exact time that the timer last expired. Therefore, this
- * function will cause the timer to be stable over time, unlike the
- * timer_rester() function.
- *
- * \param t A pointer to the timer.
- *
- * \sa timer_restart()
- */
-void
-timer_reset(struct timer *t)
-{
- t->start += t->interval;
-}
-/*---------------------------------------------------------------------------*/
-/**
- * Restart the timer from the current point in time
- *
- * This function restarts a timer with the same interval that was
- * given to the timer_set() function. The timer will start at the
- * current time.
- *
- * \note A periodic timer will drift if this function is used to reset
- * it. For preioric timers, use the timer_reset() function instead.
- *
- * \param t A pointer to the timer.
- *
- * \sa timer_reset()
- */
-void
-timer_restart(struct timer *t)
-{
- t->start = clock_time();
-}
-/*---------------------------------------------------------------------------*/
-/**
- * Check if a timer has expired.
- *
- * This function tests if a timer has expired and returns true or
- * false depending on its status.
- *
- * \param t A pointer to the timer
- *
- * \return Non-zero if the timer has expired, zero otherwise.
- *
- */
-#include "rtdef.h"
-#include "uip-conf.h"
-#include "uip.h"
-
-/* eth rx/tx thread */
-static struct rt_mailbox uip_mbox;
-static struct rt_thread aa;
-
-static char uip_timeout_mb_pool[4 * 4];
-extern u16_t uip_len, uip_slen;
-
-void uip_timeout_entry2(void* parameter)
-{
-
-
-}
-void uip_timeout_entry(void* parameter)//����TIMEOUT���������������
-{
- // struct timer periodic_timer, arp_timer;
- static uint8_t cnt;
- int i;
- /* post message to ethernet thread */
-
- //if ((rt_sem_take(msg,RT_WAITING_NO)) != -RT_ETIMEOUT)
- //if (timer_expired(&periodic_timer)) //5s enter once
- {
- //timer_reset(&periodic_timer);
- for (i = 0; i < UIP_CONNS; i++)
- {
- uip_periodic(i);
- /* If the above function invocation resulted in data that
- should be sent out on the network, the global variable
- uip_len is set to a value > 0. */
- if (uip_len > 0)
- {
- uip_arp_out();
- TransmitPacket();
- }
- }
-#if UIP_UDP
- for (i = 0; i < UIP_UDP_CONNS; i++) //
- {
- uip_udp_periodic(i);
- /* If the above function invocation resulted in data that
- should be sent out on the network, the global variable
- uip_len is set to a value > 0. */
- if (uip_len > 0)
- {
- uip_arp_out();
- TransmitPacket();
- }
- }
-#endif /* UIP_UDP */
-
- /* Call the ARP timer function every 10 seconds. */
- //if (timer_expired(&arp_timer))
- if (++cnt >= 2) //t
- {
- //timer_reset(&arp_timer);
- uip_arp_timer();
- cnt = 0;
- }
- }
-
-}
-int
-timer_expired(struct timer *t)
-{//DZ������bug
- if ((clock_time() - t->start) >= (clock_time_t)t->interval)
- {
- //rt_mb_send(mbox,&
- }
-
-}
-/*---------------------------------------------------------------------------*/
-
-/** @} */
+/**
+ * \addtogroup timer
+ * @{
+ */
+
+/**
+ * \file
+ * Timer library implementation.
+ * \author
+ * Adam Dunkels <[email protected]>
+ */
+
+/*
+ * Copyright (c) 2004, 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 uIP TCP/IP stack
+ *
+ * Author: Adam Dunkels <[email protected]>
+ *
+ * $Id: timer.c,v 1.2 2006/06/12 08:00:30 adam Exp $
+ */
+
+#include "uip_clock.h"
+#include "uip_timer.h"
+//#include "rtconfig.h"
+
+/*---------------------------------------------------------------------------*/
+/**
+ * Set a timer.
+ *
+ * This function is used to set a timer for a time sometime in the
+ * future. The function timer_expired() will evaluate to true after
+ * the timer has expired.
+ *
+ * \param t A pointer to the timer
+ * \param interval The interval before the timer expires.
+ *
+ */
+void
+timer_set(struct timer *t, clock_time_t interval)
+{
+ t->interval = interval;
+ t->start = clock_time();
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * Reset the timer with the same interval.
+ *
+ * This function resets the timer with the same interval that was
+ * given to the timer_set() function. The start point of the interval
+ * is the exact time that the timer last expired. Therefore, this
+ * function will cause the timer to be stable over time, unlike the
+ * timer_rester() function.
+ *
+ * \param t A pointer to the timer.
+ *
+ * \sa timer_restart()
+ */
+void
+timer_reset(struct timer *t)
+{
+ t->start += t->interval;
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * Restart the timer from the current point in time
+ *
+ * This function restarts a timer with the same interval that was
+ * given to the timer_set() function. The timer will start at the
+ * current time.
+ *
+ * \note A periodic timer will drift if this function is used to reset
+ * it. For preioric timers, use the timer_reset() function instead.
+ *
+ * \param t A pointer to the timer.
+ *
+ * \sa timer_reset()
+ */
+void
+timer_restart(struct timer *t)
+{
+ t->start = clock_time();
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * Check if a timer has expired.
+ *
+ * This function tests if a timer has expired and returns true or
+ * false depending on its status.
+ *
+ * \param t A pointer to the timer
+ *
+ * \return Non-zero if the timer has expired, zero otherwise.
+ *
+ */
+#include "rtdef.h"
+#include "uip-conf.h"
+#include "uip.h"
+
+/* eth rx/tx thread */
+static struct rt_mailbox uip_mbox;
+static struct rt_thread aa;
+
+static char uip_timeout_mb_pool[4 * 4];
+extern u16_t uip_len, uip_slen;
+
+void uip_timeout_entry2(void* parameter)
+{
+
+
+}
+void uip_timeout_entry(void* parameter)//����TIMEOUT���������������
+{
+ // struct timer periodic_timer, arp_timer;
+ static uint8_t cnt;
+ int i;
+ /* post message to ethernet thread */
+
+ //if ((rt_sem_take(msg,RT_WAITING_NO)) != -RT_ETIMEOUT)
+ //if (timer_expired(&periodic_timer)) //5s enter once
+ {
+ //timer_reset(&periodic_timer);
+ for (i = 0; i < UIP_CONNS; i++)
+ {
+ uip_periodic(i);
+ /* If the above function invocation resulted in data that
+ should be sent out on the network, the global variable
+ uip_len is set to a value > 0. */
+ if (uip_len > 0)
+ {
+ uip_arp_out();
+ TransmitPacket();
+ }
+ }
+#if UIP_UDP
+ for (i = 0; i < UIP_UDP_CONNS; i++) //
+ {
+ uip_udp_periodic(i);
+ /* If the above function invocation resulted in data that
+ should be sent out on the network, the global variable
+ uip_len is set to a value > 0. */
+ if (uip_len > 0)
+ {
+ uip_arp_out();
+ TransmitPacket();
+ }
+ }
+#endif /* UIP_UDP */
+
+ /* Call the ARP timer function every 10 seconds. */
+ //if (timer_expired(&arp_timer))
+ if (++cnt >= 2) //t
+ {
+ //timer_reset(&arp_timer);
+ uip_arp_timer();
+ cnt = 0;
+ }
+ }
+
+}
+int
+timer_expired(struct timer *t)
+{//DZ������bug
+ if ((clock_time() - t->start) >= (clock_time_t)t->interval)
+ {
+ //rt_mb_send(mbox,&
+ }
+
+}
+/*---------------------------------------------------------------------------*/
+
+/** @} */
diff --git a/components/net/uip/uip/uip_timer.h b/components/net/uip/uip/uip_timer.h
index 6d90e563a4..ce3bd74ae8 100644
--- a/components/net/uip/uip/uip_timer.h
+++ b/components/net/uip/uip/uip_timer.h
@@ -1,86 +1,86 @@
-/**
- * \defgroup timer Timer library
- *
- * The timer library provides functions for setting, resetting and
- * restarting timers, and for checking if a timer has expired. An
- * application must "manually" check if its timers have expired; this
- * is not done automatically.
- *
- * A timer is declared as a \c struct \c timer and all access to the
- * timer is made by a pointer to the declared timer.
- *
- * \note The timer library uses the \ref clock "Clock library" to
- * measure time. Intervals should be specified in the format used by
- * the clock library.
- *
- * @{
- */
-
-
-/**
- * \file
- * Timer library header file.
- * \author
- * Adam Dunkels <[email protected]>
- */
-
-/*
- * Copyright (c) 2004, 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 uIP TCP/IP stack
- *
- * Author: Adam Dunkels <[email protected]>
- *
- * $Id: timer.h,v 1.3 2006/06/11 21:46:39 adam Exp $
- */
-#ifndef __TIMER_H__
-#define __TIMER_H__
-
-#include "uip_clock.h"
-
-/**
- * A timer.
- *
- * This structure is used for declaring a timer. The timer must be set
- * with timer_set() before it can be used.
- *
- * \hideinitializer
- */
-struct timer {
- clock_time_t start;
- clock_time_t interval;
-};
-
-void timer_set(struct timer *t, clock_time_t interval);
-void timer_reset(struct timer *t);
-void timer_restart(struct timer *t);
-int timer_expired(struct timer *t);
-
-#endif /* __TIMER_H__ */
-
-/** @} */
+/**
+ * \defgroup timer Timer library
+ *
+ * The timer library provides functions for setting, resetting and
+ * restarting timers, and for checking if a timer has expired. An
+ * application must "manually" check if its timers have expired; this
+ * is not done automatically.
+ *
+ * A timer is declared as a \c struct \c timer and all access to the
+ * timer is made by a pointer to the declared timer.
+ *
+ * \note The timer library uses the \ref clock "Clock library" to
+ * measure time. Intervals should be specified in the format used by
+ * the clock library.
+ *
+ * @{
+ */
+
+
+/**
+ * \file
+ * Timer library header file.
+ * \author
+ * Adam Dunkels <[email protected]>
+ */
+
+/*
+ * Copyright (c) 2004, 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 uIP TCP/IP stack
+ *
+ * Author: Adam Dunkels <[email protected]>
+ *
+ * $Id: timer.h,v 1.3 2006/06/11 21:46:39 adam Exp $
+ */
+#ifndef __TIMER_H__
+#define __TIMER_H__
+
+#include "uip_clock.h"
+
+/**
+ * A timer.
+ *
+ * This structure is used for declaring a timer. The timer must be set
+ * with timer_set() before it can be used.
+ *
+ * \hideinitializer
+ */
+struct timer {
+ clock_time_t start;
+ clock_time_t interval;
+};
+
+void timer_set(struct timer *t, clock_time_t interval);
+void timer_reset(struct timer *t);
+void timer_restart(struct timer *t);
+int timer_expired(struct timer *t);
+
+#endif /* __TIMER_H__ */
+
+/** @} */