diff --git a/ChangeLog b/ChangeLog index 90124431af..bdd2ad17eb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -253,3 +253,4 @@ * fs/ and lib/ subystem debug can not be selectively enabled/disabled * Added vsnprintf * Integrated uIP telnetd + * Add missing logic to readahead buffer logic diff --git a/Documentation/NuttX.html b/Documentation/NuttX.html index 17ec1169d4..fe6c5d5609 100644 --- a/Documentation/NuttX.html +++ b/Documentation/NuttX.html @@ -733,6 +733,7 @@ Other memory: * fs/ and lib/ subystem debug can not be selectively enabled/disabled * Added vsnprintf * Integrated uIP telnetd + * Add missing logic to readahead buffer logic diff --git a/configs/ntosd-dm320/defconfig b/configs/ntosd-dm320/defconfig index 318124ca94..b8ecb377dd 100644 --- a/configs/ntosd-dm320/defconfig +++ b/configs/ntosd-dm320/defconfig @@ -306,7 +306,6 @@ CONFIG_EXAMPLE_UIP_SMTP=n CONFIG_EXAMPLE_UIP_TELNETD=n CONFIG_EXAMPLE_UIP_WEBSERVER=y CONFIG_EXAMPLE_UIP_DHCPC=n -CONFIG_EXAMPLE_UIP_RESOLV=n CONFIG_EXAMPLE_UIP_WEBCLIENT=n # diff --git a/configs/ntosd-dm320/netconfig b/configs/ntosd-dm320/netconfig index b5013165d1..70d43c30c4 100644 --- a/configs/ntosd-dm320/netconfig +++ b/configs/ntosd-dm320/netconfig @@ -306,7 +306,6 @@ CONFIG_EXAMPLE_UIP_SMTP=n CONFIG_EXAMPLE_UIP_TELNETD=n CONFIG_EXAMPLE_UIP_WEBSERVER=y CONFIG_EXAMPLE_UIP_DHCPC=n -CONFIG_EXAMPLE_UIP_RESOLV=n CONFIG_EXAMPLE_UIP_WEBCLIENT=n # diff --git a/configs/ntosd-dm320/udpconfig b/configs/ntosd-dm320/udpconfig index b65ace104a..b8216ee5e8 100644 --- a/configs/ntosd-dm320/udpconfig +++ b/configs/ntosd-dm320/udpconfig @@ -306,7 +306,6 @@ CONFIG_EXAMPLE_UIP_SMTP=n CONFIG_EXAMPLE_UIP_TELNETD=n CONFIG_EXAMPLE_UIP_WEBSERVER=y CONFIG_EXAMPLE_UIP_DHCPC=n -CONFIG_EXAMPLE_UIP_RESOLV=n CONFIG_EXAMPLE_UIP_WEBCLIENT=n # diff --git a/configs/ntosd-dm320/uipconfig b/configs/ntosd-dm320/uipconfig index 0e36ffb36f..b66546b388 100644 --- a/configs/ntosd-dm320/uipconfig +++ b/configs/ntosd-dm320/uipconfig @@ -306,7 +306,6 @@ CONFIG_EXAMPLE_UIP_SMTP=n CONFIG_EXAMPLE_UIP_TELNETD=n CONFIG_EXAMPLE_UIP_WEBSERVER=y CONFIG_EXAMPLE_UIP_DHCPC=n -CONFIG_EXAMPLE_UIP_RESOLV=n CONFIG_EXAMPLE_UIP_WEBCLIENT=n # diff --git a/configs/sim/defconfig b/configs/sim/defconfig index 4510227acc..6107a781e4 100644 --- a/configs/sim/defconfig +++ b/configs/sim/defconfig @@ -268,7 +268,6 @@ CONFIG_EXAMPLE_UIP_SMTP=n CONFIG_EXAMPLE_UIP_TELNETD=n CONFIG_EXAMPLE_UIP_WEBSERVER=y CONFIG_EXAMPLE_UIP_DHCPC=n -CONFIG_EXAMPLE_UIP_RESOLV=n CONFIG_EXAMPLE_UIP_WEBCLIENT=n # diff --git a/configs/sim/netconfig b/configs/sim/netconfig index 163c0c27ff..002502356b 100644 --- a/configs/sim/netconfig +++ b/configs/sim/netconfig @@ -269,7 +269,6 @@ CONFIG_EXAMPLE_UIP_SMTP=n CONFIG_EXAMPLE_UIP_TELNETD=n CONFIG_EXAMPLE_UIP_WEBSERVER=y CONFIG_EXAMPLE_UIP_DHCPC=n -CONFIG_EXAMPLE_UIP_RESOLV=n CONFIG_EXAMPLE_UIP_WEBCLIENT=n # diff --git a/examples/uip/main.c b/examples/uip/main.c index 951cde539d..83da6fe2c9 100644 --- a/examples/uip/main.c +++ b/examples/uip/main.c @@ -59,21 +59,25 @@ * our project as defined in the config//defconfig file */ +/* DHCPC may be used in conjunction with any other feature (or not) */ + +#if defined(CONFIG_EXAMPLE_UIP_DHCPC) +# include +# include +#endif + +/* Pick the netutils feature under test (which may be DHCPC) */ + #if defined(CONFIG_EXAMPLE_UIP_SMTP) # include #elif defined(CONFIG_EXAMPLE_UIP_TELNETD) # include #elif defined(CONFIG_EXAMPLE_UIP_WEBSERVER) # include -#elif defined(CONFIG_EXAMPLE_UIP_DHCPC) -# include -# include -#elif defined(CONFIG_EXAMPLE_UIP_RESOLV) -# include #elif defined(CONFIG_EXAMPLE_UIP_WEBCLIENT) # include # include -#else +#elif !defined(CONFIG_EXAMPLE_UIP_DHCPC) # error "No network application specified" #endif @@ -155,19 +159,19 @@ int user_start(int argc, char *argv[]) uip_setnetmask("eth0", &addr); #endif -#if defined(CONFIG_EXAMPLE_UIP_WEBSERVER) - httpd_init(); - httpd_listen(); -#elif defined(CONFIG_EXAMPLE_UIP_TELNETD) - telnetd_init(); -#elif defined(CONFIG_EXAMPLE_UIP_DHCPC) +#if defined(CONFIG_EXAMPLE_UIP_DHCPC) || defined(CONFIG_EXAMPLE_UIP_WEBCLIENT) + /* Set up the resolver */ + + resolv_init(); +#endif + +#if defined(CONFIG_EXAMPLE_UIP_DHCPC) /* Get the MAC address of the NIC */ uip_getmacaddr("eth0", mac); - /* Set up the resolver and DHCPC modules */ + /* Set up the DHCPC modules */ - resolv_init(); handle = dhcpc_open(&mac, IFHWADDRLEN); /* Get an IP address */ @@ -182,6 +186,13 @@ int user_start(int argc, char *argv[]) resolv_conf(&ds.dnsaddr); dhcpc_close(handle); } +#endif + +#if defined(CONFIG_EXAMPLE_UIP_WEBSERVER) + httpd_init(); + httpd_listen(); +#elif defined(CONFIG_EXAMPLE_UIP_TELNETD) + telnetd_init(); #elif defined(CONFIG_EXAMPLE_UIP_SMTP) uip_ipaddr(addr.s_addr, 127, 0, 0, 1); handle = smtp_open(); @@ -194,10 +205,9 @@ int user_start(int argc, char *argv[]) } #elif defined(CONFIG_EXAMPLE_UIP_WEBCLIENT) webclient_init(); - resolv_init(); - uip_ipaddr(addr.s_addr, 195, 54, 122, 204); + addr.s_addr = HTONL(CONFIG_EXAMPLE_UIP_DNSADDR); resolv_conf(&addr); - resolv_query("www.sics.se"); + resolv_query(CONFIG_EXAMPLE_UIP_SERVERURL); #endif while(1) diff --git a/include/net/uip/uip-tcp.h b/include/net/uip/uip-tcp.h index 8d7db5c357..f6d19b8de5 100644 --- a/include/net/uip/uip-tcp.h +++ b/include/net/uip/uip-tcp.h @@ -121,6 +121,9 @@ struct uip_conn uint8 timer; /* The retransmission timer (units: half-seconds) */ uint8 nrtx; /* The number of retransmissions for the last * segment sent */ + uint8 data_flags; /* Flags that will be handled by the data_event() + * callback function (see data_event() discussion below). + */ /* Read-ahead buffering */ @@ -143,6 +146,10 @@ struct uip_conn * UIP_NEWDATA - May be cleared to suppress returning the ACK response. * (dev->d_len should also be set to zero in this case). * + * + * The provider of the data_event callback must also set data_flags. This + * will inform the uIP layer which flags are and are not handled by the + * callback. * accept() is called when the TCP logic has created a connection * connection_event() is called on any of the subset of connection-related events */ diff --git a/include/net/uip/uip.h b/include/net/uip/uip.h index c662e2ccfc..e42460a2a6 100644 --- a/include/net/uip/uip.h +++ b/include/net/uip/uip.h @@ -266,9 +266,8 @@ extern void uip_setipid(uint16 id); * * 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() event being - * set. The application will then have to resend the data using this - * function. + * application will be invoked with the UIP_REXMIT flag set. The + * application will then have to resend the data using this function. * * data A pointer to the data which is to be sent. * @@ -277,92 +276,6 @@ extern void uip_setipid(uint16 id); extern void uip_send(struct uip_driver_s *dev, const void *buf, int len); -/* The length of any incoming data that is currently avaliable (if avaliable) - * in the d_appdata buffer. - * - * The test function uip_data() must first be used to check if there - * is any data available at all. - */ - -#define uip_datalen(dev) ((dev)->d_len) - -/* uIP tests that can be made to determine in what state the current - * connection is, and what the application function should do. - * - * Is new incoming data available? - * - * Will reduce to non-zero if there is new data for the application - * present at the d_appdata pointer. The size of the data is - * avaliable through the d_len element. - */ - -#define uip_newdata_event(f) ((f) & 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. - */ - -#define uip_ack_event(f) ((f) & UIP_ACKDATA) - -/* Has the connection just been connected? - * - * Reduces to non-zero if the current connenetutils/telnetd/telnetd.cction 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()). - */ - -#define uip_connected_event(f) ((f) & 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. - */ - -#define uip_close_event(f) ((f) & 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. - */ - -#define uip_abort_event(f) ((f) & UIP_ABORT) - -/* Has the connection timed out? - * - * Non-zero if the current connection has been aborted due to too many - * retransmissions. - */ - -#define uip_timeout_event(f) ((f) & 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. - */ - -#define uip_rexmit_event(f) ((f) & 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. - */ - -#define uip_poll_event(f) ((f) & UIP_POLL) - /* uIP convenience and converting functions. * * These functions can be used for converting between different data diff --git a/net/connect.c b/net/connect.c index 2316e1ba33..8d26f8e7ee 100644 --- a/net/connect.c +++ b/net/connect.c @@ -146,6 +146,7 @@ static inline void tcp_setup_callbacks(struct uip_conn *conn, FAR struct socket { /* Set up the callbacks in the connection */ + conn->data_flags = UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT|UIP_CONNECTED; conn->data_private = (void*)pstate; conn->data_event = tcp_connect_interrupt; @@ -165,6 +166,7 @@ static inline void tcp_teardown_callbacks(struct uip_conn *conn, int status) { /* Make sure that no further interrupts are processed */ + conn->data_flags = 0; conn->data_private = NULL; conn->data_event = NULL; diff --git a/net/net-close.c b/net/net-close.c index 24a526ba6d..f64d70de70 100644 --- a/net/net-close.c +++ b/net/net-close.c @@ -102,6 +102,7 @@ static uint8 netclose_interrupt(struct uip_driver_s *dev, { /* The disconnection is complete */ + conn->data_flags = 0; conn->data_private = NULL; conn->data_event = NULL; sem_post(&pstate->cl_sem); @@ -160,6 +161,7 @@ static inline void netclose_disconnect(FAR struct socket *psock) sem_init(&state.cl_sem, 0, 0); conn = psock->s_conn; + conn->data_flags = UIP_NEWDATA|UIP_CLOSE|UIP_ABORT; conn->data_private = (void*)&state; conn->data_event = netclose_interrupt; @@ -170,6 +172,7 @@ static inline void netclose_disconnect(FAR struct socket *psock) /* We are now disconnected */ sem_destroy(&state.cl_sem); + conn->data_flags = 0; conn->data_private = NULL; conn->data_event = NULL; } diff --git a/net/recvfrom.c b/net/recvfrom.c index cb6cc88be3..af28635f78 100644 --- a/net/recvfrom.c +++ b/net/recvfrom.c @@ -369,7 +369,7 @@ static uint8 recvfrom_tcpinterrupt(struct uip_driver_s *dev, { /* If new data is available, then complete the read action. */ - if (uip_newdata_event(flags)) + if ((flags & UIP_NEWDATA) != 0) { /* Copy the data from the packet */ @@ -391,6 +391,7 @@ static uint8 recvfrom_tcpinterrupt(struct uip_driver_s *dev, * Don't allow any further TCP call backs. */ + conn->data_flags = 0; conn->data_private = NULL; conn->data_event = NULL; @@ -418,6 +419,7 @@ static uint8 recvfrom_tcpinterrupt(struct uip_driver_s *dev, /* Stop further callbacks */ + conn->data_flags = 0; conn->data_private = NULL; conn->data_event = NULL; @@ -443,6 +445,7 @@ static uint8 recvfrom_tcpinterrupt(struct uip_driver_s *dev, nvdbg("TCP timeout\n"); + conn->data_flags = 0; conn->data_private = NULL; conn->data_event = NULL; @@ -543,7 +546,7 @@ static void recvfrom_udpinterrupt(struct uip_driver_s *dev, { /* If new data is available, then complete the read action. */ - if (uip_newdata_event(flags)) + if ((flags & UIP_NEWDATA) != 0) { /* Copy the data from the packet */ @@ -860,6 +863,7 @@ static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, /* Set up the callback in the connection */ conn = (struct uip_conn *)psock->s_conn; + conn->data_flags = UIP_NEWDATA|UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT; conn->data_private = (void*)&state; conn->data_event = recvfrom_tcpinterrupt; @@ -873,6 +877,7 @@ static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, /* Make sure that no further interrupts are processed */ + conn->data_flags = 0; conn->data_private = NULL; conn->data_event = NULL; } diff --git a/net/send.c b/net/send.c index c0bb11fe0c..69cf883ac5 100644 --- a/net/send.c +++ b/net/send.c @@ -110,7 +110,7 @@ static uint8 send_interrupt(struct uip_driver_s *dev, struct uip_conn *conn, uin * then send it now. */ - if (pstate->snd_state != STATE_DATA_SENT || uip_rexmit_event(flags)) + if (pstate->snd_state != STATE_DATA_SENT || (flags & UIP_REXMIT) != 0) { if (pstate->snd_buflen > uip_mss(conn)) { @@ -126,7 +126,7 @@ static uint8 send_interrupt(struct uip_driver_s *dev, struct uip_conn *conn, uin /* Check if all data has been sent and acknowledged */ - else if (pstate->snd_state == STATE_DATA_SENT && uip_ack_event(flags)) + else if (pstate->snd_state == STATE_DATA_SENT && (flags & UIP_ACKDATA) != 0) { /* Yes.. the data has been sent AND acknowledged */ @@ -152,6 +152,7 @@ static uint8 send_interrupt(struct uip_driver_s *dev, struct uip_conn *conn, uin /* Don't allow any further call backs. */ + conn->data_flags = 0; conn->data_private = NULL; conn->data_event = NULL; @@ -169,6 +170,7 @@ static uint8 send_interrupt(struct uip_driver_s *dev, struct uip_conn *conn, uin { /* Stop further callbacks */ + conn->data_flags = 0; conn->data_private = NULL; conn->data_event = NULL; @@ -301,6 +303,7 @@ ssize_t send(int sockfd, const void *buf, size_t len, int flags) /* Set up the callback in the connection */ conn = (struct uip_conn *)psock->s_conn; + conn->data_flags = UIP_REXMIT|UIP_ACKDATA|UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT; conn->data_private = (void*)&state; conn->data_event = send_interrupt; @@ -318,6 +321,7 @@ ssize_t send(int sockfd, const void *buf, size_t len, int flags) /* Make sure that no further interrupts are processed */ + conn->data_flags = 0; conn->data_private = NULL; conn->data_event = NULL; } diff --git a/net/uip/uip-tcpcallback.c b/net/uip/uip-tcpcallback.c index 845c49a813..d96e97981c 100644 --- a/net/uip/uip-tcpcallback.c +++ b/net/uip/uip-tcpcallback.c @@ -84,7 +84,7 @@ uip_dataevent(struct uip_driver_s *dev, struct uip_conn *conn, uint8 flags) * can have zero-length with UIP_NEWDATA set just to cause an ACK). */ - if (uip_newdata_event(flags) && dev->d_len > 0) + if ((flags & UIP_NEWDATA) != 0 && dev->d_len > 0) { #if CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0 /* Allocate a read-ahead buffer to hold the newly received data */ @@ -174,7 +174,7 @@ uint8 uip_tcpcallback(struct uip_driver_s *dev, struct uip_conn *conn, uint8 fla if (conn->data_event) { /* Perform the callback. Callback function normally returns the input flags, - * however, the implemenation may set one of the following: + * however, the implementation may set one of the following: * * UIP_CLOSE - Gracefully close the current connection * UIP_ABORT - Abort (reset) the current connection on an error that @@ -188,12 +188,17 @@ uint8 uip_tcpcallback(struct uip_driver_s *dev, struct uip_conn *conn, uint8 fla ret = conn->data_event(dev, conn, flags); } - else + + /* If there is no data callback -OR- if the data callback does not handle the + * newdata event, then there is no handler in place to handle new incoming data. + */ + + if (!conn->data_event || (conn->data_flags & UIP_NEWDATA) == 0) { - /* There is no handler to receive new data in place */ + /* In either case, we will take a default newdata action */ nvdbg("No listener on connection\n"); - ret = uip_dataevent(dev, conn, flags); + ret = uip_dataevent(dev, conn, ret); } /* Check if there is a connection-related event and a connection diff --git a/netutils/dhcpc/dhcpc.c b/netutils/dhcpc/dhcpc.c index a847280136..bdb885ccce 100644 --- a/netutils/dhcpc/dhcpc.c +++ b/netutils/dhcpc/dhcpc.c @@ -1,5 +1,5 @@ /**************************************************************************** - * dhcpc.c + * netutils/dhcpc/dhcpc.c * * Copyright (C) 2007 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -103,10 +103,10 @@ struct dhcpc_state_internal { struct uip_udp_conn *conn; - const void *mac_addr; - int mac_len; - int sockfd; - char buffer[256]; + const void *mac_addr; + int mac_len; + int sockfd; + char buffer[256]; }; struct dhcp_msg diff --git a/netutils/resolv/resolv.c b/netutils/resolv/resolv.c index 741116bb7d..4ac604fb68 100644 --- a/netutils/resolv/resolv.c +++ b/netutils/resolv/resolv.c @@ -1,4 +1,5 @@ -/* uip-resolv.c +/**************************************************************************** + * uip-resolv.c * DNS host name to IP address resolver. * * The uIP DNS resolver functions are used to lookup a hostname and diff --git a/netutils/webclient/webclient.c b/netutils/webclient/webclient.c index 8b5c660011..3521f68936 100644 --- a/netutils/webclient/webclient.c +++ b/netutils/webclient/webclient.c @@ -338,7 +338,7 @@ static void newdata(struct uip_driver_s *dev) { uint16 len; - len = uip_datalen(dev); + len = dev->d_len; if (s.state == WEBCLIENT_STATE_STATUSLINE) { len = parse_statusline(dev, len); @@ -363,7 +363,7 @@ uint8 uip_interrupt_event(struct uip_driver_s *dev, struct uip_conn *conn, uint8 #warning OBSOLETE -- needs to be redesigned g_return = flags; - if (uip_connected_event(flags)) + if ((flags & UIP_CONNECTED) != 0) { s.timer = 0; s.state = WEBCLIENT_STATE_STATUSLINE; @@ -378,33 +378,33 @@ uint8 uip_interrupt_event(struct uip_driver_s *dev, struct uip_conn *conn, uint8 return UIP_ABORT; } - if (uip_abort_event(flags)) + if ((flags & UIP_ABORT) != 0) { webclient_aborted(); } - if (uip_timeout_event(flags)) + if ((flags & UIP_TIMEDOUT) != 0) { webclient_timedout(); } - if (uip_ack_event(flags)) + if ((flags & UIP_ACKDATA) != 0) { s.timer = 0; acked(conn); } - if (uip_newdata_event(flags)) + if ((flags & UIP_NEWDATA) != 0) { s.timer = 0; newdata(dev); } - if (uip_rexmit_event(flags) || uip_newdata_event(flags) || uip_ack_event(flags)) + if ((flags & UIP_REXMIT) != 0 || (flags & UIP_NEWDATA) != 0 || (flags & UIP_ACKDATA) != 0) { senddata(dev, conn); } - else if (uip_poll_event(flags)) + else if ((flags & UIP_POLL) != 0) { ++s.timer; if (s.timer == WEBCLIENT_TIMEOUT) @@ -414,7 +414,7 @@ uint8 uip_interrupt_event(struct uip_driver_s *dev, struct uip_conn *conn, uint8 } } - if (uip_close_event(flags)) + if ((flags & UIP_CLOSE) != 0) { if (s.httpflag != HTTPFLAG_MOVED) {