diff options
Diffstat (limited to 'nuttx')
-rw-r--r-- | nuttx/ChangeLog | 6 | ||||
-rw-r--r-- | nuttx/Documentation/NuttX.html | 3 | ||||
-rw-r--r-- | nuttx/TODO | 7 | ||||
-rw-r--r-- | nuttx/arch/arm/src/common/up_blocktask.c | 4 | ||||
-rw-r--r-- | nuttx/arch/arm/src/common/up_unblocktask.c | 4 | ||||
-rw-r--r-- | nuttx/drivers/net/dm90x0.c | 6 | ||||
-rw-r--r-- | nuttx/examples/nettest/nettest-client.c | 2 | ||||
-rw-r--r-- | nuttx/include/net/uip/uip.h | 23 | ||||
-rw-r--r-- | nuttx/net/connect.c | 3 | ||||
-rw-r--r-- | nuttx/net/recvfrom.c | 6 | ||||
-rw-r--r-- | nuttx/net/send.c | 3 | ||||
-rw-r--r-- | nuttx/net/uip/uip-icmpinput.c | 4 | ||||
-rw-r--r-- | nuttx/net/uip/uip-tcpappsend.c | 75 | ||||
-rw-r--r-- | nuttx/net/uip/uip-tcpcallback.c | 42 | ||||
-rw-r--r-- | nuttx/net/uip/uip-tcpsend.c | 2 | ||||
-rw-r--r-- | nuttx/net/uip/uip-udpconn.c | 2 | ||||
-rw-r--r-- | nuttx/netutils/telnetd/telnetd.c | 3 | ||||
-rw-r--r-- | nuttx/netutils/webclient/webclient.c | 4 |
18 files changed, 124 insertions, 75 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index d0cce3b78..230f98650 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -218,5 +218,11 @@ * Basic client functionality verified: socket(), bind(), connect(), recv(), send(). 0.3.1 2007-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr> + * Separated net/uip/uip.c into several functions in several files. + * Corrected a TCP problem where packets were dropped because there was no + recv() in place but the packet was being ACKed. There are still TCP + recv buffering issues, but this is part of a larger buffering issue. + + diff --git a/nuttx/Documentation/NuttX.html b/nuttx/Documentation/NuttX.html index 3f67662f9..0626fbd20 100644 --- a/nuttx/Documentation/NuttX.html +++ b/nuttx/Documentation/NuttX.html @@ -676,6 +676,9 @@ Other memory: 0.3.1 2007-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr> * Separated net/uip/uip.c into several functions in several files. + * Corrected a TCP problem where packets were dropped because there was no + recv() in place but the packet was being ACKed. There are still TCP + recv buffering issues, but this is part of a larger buffering issue. </pre></ul> <table width ="100%"> diff --git a/nuttx/TODO b/nuttx/TODO index 9ca34227a..28b64ece8 100644 --- a/nuttx/TODO +++ b/nuttx/TODO @@ -43,6 +43,9 @@ o Network nececcesary (2) Copy buffer structure into uip_driver_structure when driver requests write data + (3) Extra read buffers will be necessary to buffer TCP data when there is no recv + in place to accept the data. At present, received data is not ACKed, but is + eventually lost in this case. - Improve performance by stimulating the driver to accept new TX data before the next polling interval. @@ -55,10 +58,6 @@ o Network polling should respond with TX data only if the UDP packet is intended for the the network supported by the driver. (2) If there were multiple drivers, polling would occur at double the rate. -- TCP Bug: - When TCP data is received with no read in place, it appears that uIP ACKs the data - even though it was not taken accepted. We must either (1) buffer incoming data, or - (2) not ACK it so that it will be re-sent. o USB - Implement USB device support diff --git a/nuttx/arch/arm/src/common/up_blocktask.c b/nuttx/arch/arm/src/common/up_blocktask.c index b72604429..ed27d2e87 100644 --- a/nuttx/arch/arm/src/common/up_blocktask.c +++ b/nuttx/arch/arm/src/common/up_blocktask.c @@ -95,8 +95,6 @@ void up_block_task(_TCB *tcb, tstate_t task_state) _TCB *rtcb = (_TCB*)g_readytorun.head; boolean switch_needed; - lldbg("Blocking TCB=%p\n", tcb); - /* Remove the tcb task from the ready-to-run list. If we * are blocking the task at the head of the task list (the * most likely case), then a context switch to the next @@ -138,7 +136,6 @@ void up_block_task(_TCB *tcb, tstate_t task_state) */ rtcb = (_TCB*)g_readytorun.head; - lldbg("New Active Task TCB=%p\n", rtcb); /* Then switch contexts */ @@ -157,7 +154,6 @@ void up_block_task(_TCB *tcb, tstate_t task_state) */ rtcb = (_TCB*)g_readytorun.head; - lldbg("New Active Task TCB=%p\n", rtcb); /* Then switch contexts */ diff --git a/nuttx/arch/arm/src/common/up_unblocktask.c b/nuttx/arch/arm/src/common/up_unblocktask.c index 6f7afab7b..143c7ed7b 100644 --- a/nuttx/arch/arm/src/common/up_unblocktask.c +++ b/nuttx/arch/arm/src/common/up_unblocktask.c @@ -91,8 +91,6 @@ void up_unblock_task(_TCB *tcb) { _TCB *rtcb = (_TCB*)g_readytorun.head; - lldbg("Unblocking TCB=%p\n", tcb); - /* Remove the task from the blocked task list */ sched_removeblocked(tcb); @@ -130,7 +128,6 @@ void up_unblock_task(_TCB *tcb) */ rtcb = (_TCB*)g_readytorun.head; - lldbg("New Active Task TCB=%p\n", rtcb); /* Then switch contexts */ @@ -151,7 +148,6 @@ void up_unblock_task(_TCB *tcb) */ rtcb = (_TCB*)g_readytorun.head; - lldbg("New Active Task TCB=%p\n", rtcb); /* Then switch contexts */ diff --git a/nuttx/drivers/net/dm90x0.c b/nuttx/drivers/net/dm90x0.c index b8a9c3ae6..ccd2c69c1 100644 --- a/nuttx/drivers/net/dm90x0.c +++ b/nuttx/drivers/net/dm90x0.c @@ -260,10 +260,10 @@ # define CONFIG_DM9X_MODE DM9X_MODE_AUTO #endif -/* TX poll deley = 5 seconds. CLK_TCK is the number of clock ticks per second */ +/* TX poll deley = 1 seconds. CLK_TCK is the number of clock ticks per second */ -#define DM6X_WDDELAY (5*CLK_TCK) -#define DM6X_POLLHSEC (5*2) +#define DM6X_WDDELAY (1*CLK_TCK) +#define DM6X_POLLHSEC (1*2) /* TX timeout = 1 minute */ diff --git a/nuttx/examples/nettest/nettest-client.c b/nuttx/examples/nettest/nettest-client.c index ea8a4312c..a38ff0049 100644 --- a/nuttx/examples/nettest/nettest-client.c +++ b/nuttx/examples/nettest/nettest-client.c @@ -158,7 +158,7 @@ void send_client(void) } else if (nbytesrecvd != SENDSIZE) { - message("client: Bad recv length=%d: %d\n", nbytessent); + message("client: Bad recv length=%d: %d\n", nbytesrecvd); close(sockfd); exit(-1); } diff --git a/nuttx/include/net/uip/uip.h b/nuttx/include/net/uip/uip.h index e002777c3..facac0bcf 100644 --- a/nuttx/include/net/uip/uip.h +++ b/nuttx/include/net/uip/uip.h @@ -185,10 +185,18 @@ struct uip_conn /* Higher level logic can retain application specific information * in the following: * - * data_event() is called on all events. May return one of the following: - * UIP_CLOSE - Gracefully close the current connection - * UIP_ABORT - Abort (reset) the current connection on an error that - * prevents UIP_CLOSE from working. + * data_event() is called on all events. Normally, the input flags are + * returned, however, the implemenation may set one of the following: + * + * UIP_CLOSE - Gracefully close the current connection + * UIP_ABORT - Abort (reset) the current connection on an error that + * prevents UIP_CLOSE from working. + * + * Or clear the following: + * + * UIP_NEWDATA - May be cleared to suppress returning the ACK response. + * (dev->d_len should also be set to zero in this case). + * * accept() is called when the TCP logic has created a connection * connection_event() is called on any of the subset of connection-related events */ @@ -255,18 +263,17 @@ struct uip_stats } 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 recv; /* Number of received 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. */ + available connections. */ + uip_stats_t synrst; /* Number of SYNs for closed ports triggering a RST. */ } tcp; /* TCP statistics. */ #ifdef CONFIG_NET_UDP diff --git a/nuttx/net/connect.c b/nuttx/net/connect.c index 56aee612c..d4f40b30f 100644 --- a/nuttx/net/connect.c +++ b/nuttx/net/connect.c @@ -259,7 +259,8 @@ static uint8 tcp_connect_interrupt(struct uip_driver_s *dev, sem_post(&pstate->tc_sem); } - return 0; + + return flags; } /**************************************************************************** diff --git a/nuttx/net/recvfrom.c b/nuttx/net/recvfrom.c index 579013913..b0c9a223f 100644 --- a/nuttx/net/recvfrom.c +++ b/nuttx/net/recvfrom.c @@ -123,6 +123,10 @@ static void recvfrom_newdata(struct uip_driver_s *dev, struct recvfrom_s *pstate pstate->rf_recvlen += recvlen; pstate->rf_buffer += recvlen; pstate->rf_buflen -= recvlen; + + /* Indicate no data in the buffer */ + + dev->d_len = 0; } /**************************************************************************** @@ -313,7 +317,7 @@ static uint8 recvfrom_tcpinterrupt(struct uip_driver_s *dev, } #endif /* CONFIG_NET_SOCKOPTS && !CONFIG_DISABLE_CLOCK */ } - return 0; + return flags; } /**************************************************************************** diff --git a/nuttx/net/send.c b/nuttx/net/send.c index 98dcec352..c758b8eba 100644 --- a/nuttx/net/send.c +++ b/nuttx/net/send.c @@ -180,7 +180,8 @@ static uint8 send_interrupt(struct uip_driver_s *dev, struct uip_conn *conn, uin sem_post(&pstate->snd_sem); } - return 0; + + return flags; } /**************************************************************************** diff --git a/nuttx/net/uip/uip-icmpinput.c b/nuttx/net/uip/uip-icmpinput.c index b6eace772..8dd276330 100644 --- a/nuttx/net/uip/uip-icmpinput.c +++ b/nuttx/net/uip/uip-icmpinput.c @@ -185,7 +185,7 @@ typeerr: ICMPBUF->reserved1 = ICMPBUF->reserved2 = ICMPBUF->reserved3 = 0; uiphdr_ipaddr_copy(ICMPBUF->destipaddr, ICMPBUF->srcipaddr); - uiphdr_ipaddr_copy(ICMPBUF->srcipaddr, dev->d_ipaddr); + uiphdr_ipaddr_copy(ICMPBUF->srcipaddr, &dev->d_ipaddr); ICMPBUF->options[0] = ICMP6_OPTION_TARGET_LINK_ADDRESS; ICMPBUF->options[1] = 1; /* Options length, 1 = 8 bytes. */ memcpy(&(ICMPBUF->options[2]), &dev->d_mac, IFHWADDRLEN); @@ -207,7 +207,7 @@ typeerr: ICMPBUF->type = ICMP6_ECHO_REPLY; uiphdr_ipaddr_copy(ICMPBUF->destipaddr, ICMPBUF->srcipaddr); - uiphdr_ipaddr_copy(ICMPBUF->srcipaddr, dev->d_ipaddr); + uiphdr_ipaddr_copy(ICMPBUF->srcipaddr, &dev->d_ipaddr); ICMPBUF->icmpchksum = 0; ICMPBUF->icmpchksum = ~uip_icmp6chksum(dev); } diff --git a/nuttx/net/uip/uip-tcpappsend.c b/nuttx/net/uip/uip-tcpappsend.c index 63bad3fbd..fa19c23f0 100644 --- a/nuttx/net/uip/uip-tcpappsend.c +++ b/nuttx/net/uip/uip-tcpappsend.c @@ -100,6 +100,8 @@ void uip_tcpappsend(struct uip_driver_s *dev, struct uip_conn *conn, uint8 resul vdbg("result: %02x\n", result); + /* Check for connection aborted */ + if (result & UIP_ABORT) { dev->d_sndlen = 0; @@ -109,6 +111,8 @@ void uip_tcpappsend(struct uip_driver_s *dev, struct uip_conn *conn, uint8 resul uip_tcpsend(dev, conn, TCP_RST | TCP_ACK, UIP_IPTCPH_LEN); } + /* Check for connection closed */ + else if (result & UIP_CLOSE) { conn->tcpstateflags = UIP_FIN_WAIT_1; @@ -120,51 +124,56 @@ void uip_tcpappsend(struct uip_driver_s *dev, struct uip_conn *conn, uint8 resul uip_tcpsend(dev, conn, TCP_FIN | TCP_ACK, UIP_IPTCPH_LEN); } - /* If d_sndlen > 0, the application has data to be sent. */ + /* None of the above */ - else if (dev->d_sndlen > 0) + else { - /* If the connection has acknowledged data, the contents of - * the ->len variable should be discarded. - */ - - if (result & UIP_ACKDATA) - { - conn->len = 0; - } + /* If d_sndlen > 0, the application has data to be sent. */ - /* If the ->len variable is non-zero the connection has - * already data in transit and cannot send anymore right - * now. - */ - - if (conn->len == 0) + if (dev->d_sndlen > 0) { - /* The application cannot send more than what is - * allowed by the mss (the minumum of the MSS and the - * available window). + /* If the connection has acknowledged data, the contents of + * the ->len variable should be discarded. */ - if (dev->d_sndlen > conn->mss) + if (result & UIP_ACKDATA) { - dev->d_sndlen = conn->mss; + conn->len = 0; } - /* Remember how much data we send out now so that we - * know when everything has been acknowledged. + /* If the ->len variable is non-zero the connection has + * already data in transit and cannot send anymore right + * now. */ - conn->len = dev->d_sndlen; - } - 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. - */ + if (conn->len == 0) + { + /* The application cannot send more than what is + * allowed by the mss (the minumum of the MSS and the + * available window). + */ + + if (dev->d_sndlen > conn->mss) + { + dev->d_sndlen = conn->mss; + } + + /* Remember how much data we send out now so that we + * know when everything has been acknowledged. + */ - dev->d_sndlen = conn->len; + conn->len = dev->d_sndlen; + } + 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. + */ + + dev->d_sndlen = conn->len; + } } /* Then handle the rest of the operation just as for the rexmit case */ diff --git a/nuttx/net/uip/uip-tcpcallback.c b/nuttx/net/uip/uip-tcpcallback.c index 72fae7736..761283bb0 100644 --- a/nuttx/net/uip/uip-tcpcallback.c +++ b/nuttx/net/uip/uip-tcpcallback.c @@ -75,11 +75,13 @@ uint8 uip_tcpcallback(struct uip_driver_s *dev, struct uip_conn *conn, uint8 flags) { - /* Preserve the UIP_ACKDATA & UIP_NEWDATA in the response. These are - * needed by uIP to handle ACKing and buffer state. + /* Preserve the UIP_ACKDATA, UIP_CLOSE, and UIP_ABORT in the response. + * These is needed by uIP to handle responses and buffer state. The + * UIP_NEWDATA indication will trigger the ACK response, but must be + * explicitly set in the callback. */ - uint8 ret = flags & (UIP_ACKDATA|UIP_NEWDATA); + uint8 ret = flags; vdbg("flags: %02x\n", flags); @@ -87,13 +89,37 @@ uint8 uip_tcpcallback(struct uip_driver_s *dev, struct uip_conn *conn, uint8 fla if (conn->data_event) { - /* Perform the callback. Callback function may return on of: - * UIP_CLOSE - Gracefully close the current connection - * UIP_ABORT - Abort (reset) the current connection on an error that - * prevents UIP_CLOSE from working. + /* Perform the callback. Callback function normally returns the input flags, + * however, the implemenation may set one of the following: + * + * UIP_CLOSE - Gracefully close the current connection + * UIP_ABORT - Abort (reset) the current connection on an error that + * prevents UIP_CLOSE from working. + * + * Or clear the following: + * + * UIP_NEWDATA - May be cleared to suppress returning the ACK response. + * (dev->d_len should also be set to zero in this case). */ - ret |= conn->data_event(dev, conn, flags); + ret = conn->data_event(dev, conn, flags); + } + else if ((flags & UIP_CONN_EVENTS) == 0) + { + /* There is no handler to receive new data in place and this is not a + * connection event (which may also include new data that must be ACKed). + * In this case, clear the UIP_NEWDATA bit so that no ACK will be sent + * and drop the packet. + */ + + dbg("No listener on connection\n"); + +#ifdef CONFIG_NET_STATISTICS + uip_stat.tcp.drop++; +#endif + + ret &= ~UIP_NEWDATA; + dev->d_len = 0; } /* Check if there is a connection-related event and a connection diff --git a/nuttx/net/uip/uip-tcpsend.c b/nuttx/net/uip/uip-tcpsend.c index 9c367159d..31766d202 100644 --- a/nuttx/net/uip/uip-tcpsend.c +++ b/nuttx/net/uip/uip-tcpsend.c @@ -316,7 +316,7 @@ void uip_tcpreset(struct uip_driver_s *dev) /* Swap IP addresses. */ uiphdr_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr); - uiphdr_ipaddr_copy(BUF->srcipaddr, dev->d_ipaddr); + uiphdr_ipaddr_copy(BUF->srcipaddr, &dev->d_ipaddr); /* And send out the RST packet */ diff --git a/nuttx/net/uip/uip-udpconn.c b/nuttx/net/uip/uip-udpconn.c index f5779453a..87ca3f8a6 100644 --- a/nuttx/net/uip/uip-udpconn.c +++ b/nuttx/net/uip/uip-udpconn.c @@ -249,7 +249,7 @@ struct uip_udp_conn *uip_udpactive(struct uip_udpip_hdr *buf) (conn->rport == 0 || buf->srcport == conn->rport) && (uip_ipaddr_cmp(conn->ripaddr, all_zeroes_addr) || uip_ipaddr_cmp(conn->ripaddr, all_ones_addr) || - uiphdr_ipaddr_cmp(buf->srcipaddr, conn->ripaddr))) + uiphdr_ipaddr_cmp(buf->srcipaddr, &conn->ripaddr))) { /* Matching connection found.. return a reference to it */ diff --git a/nuttx/netutils/telnetd/telnetd.c b/nuttx/netutils/telnetd/telnetd.c index 8efeac5cd..bf39826f5 100644 --- a/nuttx/netutils/telnetd/telnetd.c +++ b/nuttx/netutils/telnetd/telnetd.c @@ -345,5 +345,6 @@ uint8 uip_interrupt_event(struct uip_driver_s *dev, struct uip_conn *conn, uint8 { senddata(dev, conn); } - return 0; + + return flags; } diff --git a/nuttx/netutils/webclient/webclient.c b/nuttx/netutils/webclient/webclient.c index 0c13c6c62..929bd6d1e 100644 --- a/nuttx/netutils/webclient/webclient.c +++ b/nuttx/netutils/webclient/webclient.c @@ -264,7 +264,7 @@ static uint16 parse_statusline(struct uip_driver_s *dev, uint16 len) } else { - g_return = UIP_ABORT; + g_return |= UIP_ABORT; webclient_aborted(); return 0; } @@ -409,7 +409,7 @@ static void newdata(struct uip_driver_s *dev) uint8 uip_interrupt_event(struct uip_driver_s *dev, struct uip_conn *conn, uint8 flags) { #warning OBSOLETE -- needs to be redesigned - g_return = 0; + g_return = flags; if (uip_connected_event(flags)) { |