diff --git a/arch/sim/src/up_uipdriver.c b/arch/sim/src/up_uipdriver.c index 82e740bc03..d7425f82f3 100644 --- a/arch/sim/src/up_uipdriver.c +++ b/arch/sim/src/up_uipdriver.c @@ -87,7 +87,7 @@ static struct uip_driver_s g_sim_dev; * Private Functions ****************************************************************************/ -static void timer_set( struct timer *t, unsigned int interval ) +static void timer_set(struct timer *t, unsigned int interval) { t->interval = interval; t->start = up_getwalltime(); @@ -104,9 +104,9 @@ void timer_reset(struct timer *t) } #ifdef CONFIG_NET_PROMISCUOUS -# define uipdriver_comparemac(a,b) (0) +# define up_comparemac(a,b) (0) #else -static inline int uip_comparemac(struct uip_eth_addr *paddr1, struct uip_eth_addr *paddr2) +static inline int up_comparemac(struct uip_eth_addr *paddr1, struct uip_eth_addr *paddr2) { return memcmp(paddr1, paddr2, sizeof(struct uip_eth_addr)); } @@ -155,7 +155,7 @@ void uipdriver_loop(void) * MAC address */ - if (g_sim_dev.d_len > UIP_LLH_LEN && uip_comparemac( &BUF->dest, &g_sim_dev.d_mac) == 0) + if (g_sim_dev.d_len > UIP_LLH_LEN && up_comparemac( &BUF->dest, &g_sim_dev.d_mac) == 0) { /* We only accept IP packets of the configured type and ARP packets */ @@ -201,7 +201,7 @@ void uipdriver_loop(void) else if (timer_expired(&g_periodic_timer)) { timer_reset(&g_periodic_timer); - uip_poll(&g_sim_dev, sim_uiptxpoll, UIP_DRV_TIMER); + uip_poll(&g_sim_dev, sim_uiptxpoll, 1); } sched_unlock(); } diff --git a/include/net/uip/uip.h b/include/net/uip/uip.h index 15c72b22c4..155f0e6a77 100644 --- a/include/net/uip/uip.h +++ b/include/net/uip/uip.h @@ -58,11 +58,9 @@ * Definitions ****************************************************************************/ -/* 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. +/* The following flags may be set in the set of flags before calling the + * application callback. The UIP_ACKDATA, UIP_NEWDATA, and UIP_CLOSE flags + * may be set at the same time, whereas the others are mutualy exclusive. */ #define UIP_ACKDATA (1 << 0) /* Signifies that the outstanding data was acked and the @@ -87,7 +85,7 @@ #define UIP_DATA_EVENTS (UIP_ACKDATA|UIP_NEWDATA|UIP_REXMIT|UIP_POLL) #define UIP_CONN_EVENTS (UIP_CLOSE|UIP_ABORT|UIP_CONNECTED|UIP_TIMEDOUT) -/* The TCP states used in the uip_conn->tcpstateflags. */ +/* The TCP states used in the struct uip_conn tcpstateflags field. */ #define UIP_CLOSED 0 /* The connection is not in use and available */ #define UIP_ALLOCATED 1 /* The connection is allocated, but not yet initialized */ @@ -186,14 +184,20 @@ struct uip_conn /* Higher level logic can retain application specific information * in the following: + * + * data_event() is called on all events. + * accept() is called when the TCP logic has created a connection + * connection_event() is called on any of the subset of connection-related events */ void *data_private; - void (*data_event)(struct uip_driver_s *dev, void *private); + uint8 (*data_event)(struct uip_driver_s *dev, struct uip_conn *conn, uint8 flags); + void *accept_private; - int (*accept)(void *private, struct uip_conn *conn); + int (*accept)(struct uip_conn *listener, struct uip_conn *conn); + void *connection_private; - void (*connection_event)(void *private); + void (*connection_event)(struct uip_conn *conn, uint8 flags); }; #ifdef CONFIG_NET_UDP @@ -210,7 +214,7 @@ struct uip_udp_conn /* Defines the UDP callback */ void *private; - void (*event)(struct uip_driver_s *dev, void *private); + void (*event)(struct uip_driver_s *dev, struct uip_udp_conn *conn, uint8 flags); }; #endif /* CONFIG_NET_UDP */ @@ -451,14 +455,6 @@ extern void *uip_urgdata; extern uint16 uip_urglen; /* Length of (received) urgent data */ #endif /* UIP_URGDATA > 0 */ -/* 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 current UDP connection. */ #ifdef CONFIG_NET_UDP @@ -472,15 +468,6 @@ extern struct uip_udp_conn *uip_udp_conn; extern struct uip_stats uip_stat; -/* uint8 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 uint8 uip_flags; - /**************************************************************************** * Public Function Prototypes ****************************************************************************/ @@ -573,10 +560,7 @@ int uip_listen(uint16 port); int uip_unlisten(uint16 port); -/* Check if a connection has outstanding (i.e., unacknowledged) data. - * - * conn A pointer to the uip_conn structure for the connection. - */ +/* Check if a connection has outstanding (i.e., unacknowledged) data. */ #define uip_outstanding(conn) ((conn)->len) @@ -623,29 +607,13 @@ void uip_send(struct uip_driver_s *dev, const void *buf, int len); #define uip_urgdatalen() uip_urglen -/* Close the current connection. - * - * This function will close the current connection in a nice way. - */ - -#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. - */ - -#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. */ -#define uip_stop() (uip_conn->tcpstateflags |= UIP_STOPPED) +#define uip_stop(conn) ((conn)->tcpstateflags |= UIP_STOPPED) /* Find out if the current connection has been previously stopped with * uip_stop(). @@ -660,29 +628,24 @@ void uip_send(struct uip_driver_s *dev, const void *buf, int len); * start receiving data for the current connection. */ -#define uip_restart() do { uip_flags |= UIP_NEWDATA; \ - uip_conn->tcpstateflags &= ~UIP_STOPPED; \ - } while(0) +#define uip_restart(conn,f) \ + do { \ + (f) |= UIP_NEWDATA; \ + (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. - */ - -#define uip_udpconnection() (uip_conn == NULL) - -/* Is new incoming data available? + * 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() (uip_flags & UIP_NEWDATA) +#define uip_newdata_event(f) ((f) & UIP_NEWDATA) /* Has previously sent data been acknowledged? * @@ -691,7 +654,7 @@ void uip_send(struct uip_driver_s *dev, const void *buf, int len); * can send new data. */ -#define uip_ack_event() (uip_flags & UIP_ACKDATA) +#define uip_ack_event(f) ((f) & UIP_ACKDATA) /* Has the connection just been connected? * @@ -701,7 +664,7 @@ void uip_send(struct uip_driver_s *dev, const void *buf, int len); * uip_listen()). */ -#define uip_connected_event() (uip_flags & UIP_CONNECTED) +#define uip_connected_event(f) ((f) & UIP_CONNECTED) /* Has the connection been closed by the other end? * @@ -709,7 +672,7 @@ void uip_send(struct uip_driver_s *dev, const void *buf, int len); * host. The application may then do the necessary clean-ups. */ -#define uip_close_event() (uip_flags & UIP_CLOSE) +#define uip_close_event(f) ((f) & UIP_CLOSE) /* Has the connection been aborted by the other end? * @@ -717,7 +680,7 @@ void uip_send(struct uip_driver_s *dev, const void *buf, int len); * remote host. */ -#define uip_abort_event() (uip_flags & UIP_ABORT) +#define uip_abort_event(f) ((f) & UIP_ABORT) /* Has the connection timed out? * @@ -725,7 +688,7 @@ void uip_send(struct uip_driver_s *dev, const void *buf, int len); * retransmissions. */ -#define uip_timeout_event() (uip_flags & UIP_TIMEDOUT) +#define uip_timeout_event(f) ((f) & UIP_TIMEDOUT) /* Do we need to retransmit previously data? * @@ -735,7 +698,7 @@ void uip_send(struct uip_driver_s *dev, const void *buf, int len); * time, using the uip_send() function. */ -#define uip_rexmit_event() (uip_flags & UIP_REXMIT) +#define uip_rexmit_event(f) ((f) & UIP_REXMIT) /* Is the connection being polled by uIP? * @@ -747,13 +710,13 @@ void uip_send(struct uip_driver_s *dev, const void *buf, int len); * wait for the remote host to send data. */ -#define uip_poll_event() (uip_flags & UIP_POLL) +#define uip_poll_event(f) ((f) & UIP_POLL) /* Get the initial maxium segment size (MSS) of the current * connection. */ -#define uip_initialmss() (uip_conn->initialmss) +#define uip_initialmss(conn) ((conn)->initialmss) /* Get the current maxium segment size that can be sent on the current * connection. @@ -764,7 +727,7 @@ void uip_send(struct uip_driver_s *dev, const void *buf, int len); * uip_initialmss()). */ -#define uip_mss() (uip_conn->mss) +#define uip_mss(conn) ((conn)->mss) /* Bind a UDP connection to a local address */ diff --git a/net/accept.c b/net/accept.c index 66c05e989a..34318190da 100644 --- a/net/accept.c +++ b/net/accept.c @@ -61,7 +61,6 @@ struct accept_s #else FAR const struct sockaddr_in *acpt_addr; /* Return connection adress */ #endif - FAR struct uip_conn *acpt_listenconn; /* The listener connection */ FAR struct uip_conn *acpt_newconn; /* The accepted connection */ int acpt_result; /* The result of the wait */ }; @@ -80,11 +79,21 @@ struct accept_s * Description: * Receive interrupt level callbacks when connections occur * + * Parameters: + * listener The conection stucture of the listener + * conn The connection stucture that was just accepted + * + * Returned Value: + * None + * + * Assumptions: + * Running at the interrupt level + * ****************************************************************************/ -static int accept_interrupt(void *private, struct uip_conn *conn) +static int accept_interrupt(struct uip_conn *listener, struct uip_conn *conn) { - struct accept_s *pstate = (struct accept_s *)private; + struct accept_s *pstate = (struct accept_s *)listener->accept_private; int ret = -EINVAL; if (pstate) { @@ -92,16 +101,16 @@ static int accept_interrupt(void *private, struct uip_conn *conn) #warning "need to return the address of the connection" /* Save the connection structure */ - - pstate->acpt_newconn = conn; - pstate->acpt_result = OK; + + pstate->acpt_newconn = conn; + pstate->acpt_result = OK; sem_post(&pstate->acpt_sem); - + /* Stop any further callbacks */ - pstate->acpt_listenconn->accept_private = NULL; - pstate->acpt_listenconn->accept = NULL; - ret = OK; + listener->accept_private = NULL; + listener->accept = NULL; + ret = OK; } return ret; } @@ -275,7 +284,6 @@ int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) save = irqsave(); state.acpt_addr = inaddr; - state.acpt_listenconn = psock->s_conn; state.acpt_newconn = NULL; state.acpt_result = OK; diff --git a/net/connect.c b/net/connect.c index 47047b3cf3..56aee612c8 100644 --- a/net/connect.c +++ b/net/connect.c @@ -65,11 +65,12 @@ struct tcp_connect_s * Private Function Prototypes ****************************************************************************/ -static void connection_event(void *private); +static void connection_event(struct uip_conn *conn, uint8 flags); static inline void tcp_setup_callbacks(struct uip_conn *conn, FAR struct socket *psock, FAR struct tcp_connect_s *pstate); static inline void tcp_teardown_callbacks(struct uip_conn *conn, int status); -static void tcp_connect_interrupt(struct uip_driver_s *dev, void *private); +static uint8 tcp_connect_interrupt(struct uip_driver_s *dev, + struct uip_conn *conn, uint8 flags); #ifdef CONFIG_NET_IPv6 static inline int tcp_connect(FAR struct socket *psock, const struct sockaddr_in6 *inaddr); #else @@ -87,7 +88,8 @@ static inline int tcp_connect(FAR struct socket *psock, const struct sockaddr_in * * Parameters: * dev The sructure of the network driver that caused the interrupt - * private An instance of struct recvfrom_s cast to void* + * conn The connection structure associated with the socket + * flags Set of events describing why the callback was invoked * * Returned Value: * None @@ -97,19 +99,19 @@ static inline int tcp_connect(FAR struct socket *psock, const struct sockaddr_in * ****************************************************************************/ -static void connection_event(void *private) +static void connection_event(struct uip_conn *conn, uint8 flags) { - FAR struct socket *psock = (FAR struct socket *)private; + FAR struct socket *psock = (FAR struct socket *)conn->connection_private; if (psock) { - vdbg("uip_flags: %02x s_flags: %02x\n", uip_flags, psock->s_flags); + vdbg("flags: %02x s_flags: %02x\n", flags, psock->s_flags); /* UIP_CLOSE: The remote host has closed the connection * UIP_ABORT: The remote host has aborted the connection * UIP_TIMEDOUT: Connection aborted due to too many retransmissions. */ - if ((uip_flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0) + if ((flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0) { /* Indicate that the socket is no longer connected */ @@ -118,7 +120,7 @@ static void connection_event(void *private) /* UIP_CONNECTED: The socket is successfully connected */ - else if ((uip_flags & UIP_CONNECTED) != 0) + else if ((flags & UIP_CONNECTED) != 0) { /* Indicate that the socket is now connected */ @@ -178,7 +180,8 @@ static inline void tcp_teardown_callbacks(struct uip_conn *conn, int status) * * Parameters: * dev The sructure of the network driver that caused the interrupt - * private An instance of struct recvfrom_s cast to void* + * conn The connection structure associated with the socket + * flags Set of events describing why the callback was invoked * * Returned Value: * None @@ -188,11 +191,12 @@ static inline void tcp_teardown_callbacks(struct uip_conn *conn, int status) * ****************************************************************************/ -static void tcp_connect_interrupt(struct uip_driver_s *dev, void *private) +static uint8 tcp_connect_interrupt(struct uip_driver_s *dev, + struct uip_conn *conn, uint8 flags) { - struct tcp_connect_s *pstate = (struct tcp_connect_s *)private; + struct tcp_connect_s *pstate = (struct tcp_connect_s *)conn->data_private; - vdbg("uip_flags: %02x\n", uip_flags); + vdbg("flags: %02x\n", flags); /* 'private' might be null in some race conditions (?) */ @@ -213,7 +217,7 @@ static void tcp_connect_interrupt(struct uip_driver_s *dev, void *private) * UIP_ABORT: The remote host has aborted the connection */ - if ((uip_flags & (UIP_CLOSE|UIP_ABORT)) != 0) + if ((flags & (UIP_CLOSE|UIP_ABORT)) != 0) { /* Indicate that remote host refused the connection */ @@ -222,7 +226,7 @@ static void tcp_connect_interrupt(struct uip_driver_s *dev, void *private) /* UIP_TIMEDOUT: Connection aborted due to too many retransmissions. */ - else if ((uip_flags & UIP_TIMEDOUT) != 0) + else if ((flags & UIP_TIMEDOUT) != 0) { /* Indicate that the remote host is unreachable (or should this be timedout?) */ @@ -231,7 +235,7 @@ static void tcp_connect_interrupt(struct uip_driver_s *dev, void *private) /* UIP_CONNECTED: The socket is successfully connected */ - else if ((uip_flags & UIP_CONNECTED) != 0) + else if ((flags & UIP_CONNECTED) != 0) { /* Indicate that the socket is no longer connected */ @@ -242,7 +246,7 @@ static void tcp_connect_interrupt(struct uip_driver_s *dev, void *private) else { - return; + return 0; } vdbg("Resuming: %d\n", pstate->tc_result); @@ -255,6 +259,7 @@ static void tcp_connect_interrupt(struct uip_driver_s *dev, void *private) sem_post(&pstate->tc_sem); } + return 0; } /**************************************************************************** diff --git a/net/recvfrom.c b/net/recvfrom.c index 149abc10b6..5790139132 100644 --- a/net/recvfrom.c +++ b/net/recvfrom.c @@ -81,15 +81,14 @@ struct recvfrom_s ****************************************************************************/ /**************************************************************************** - * Function: recvfrom_interrupt + * Function: recvfrom_newdata * * Description: - * This function is called from the interrupt level to perform the actual - * receive operation via by the uIP layer. + * Copy the read data from the packet * * Parameters: * dev The sructure of the network driver that caused the interrupt - * private An instance of struct recvfrom_s cast to void* + * pstate recvfrom state structure * * Returned Value: * None @@ -99,81 +98,140 @@ struct recvfrom_s * ****************************************************************************/ -static void recvfrom_interrupt(struct uip_driver_s *dev, void *private) +static void recvfrom_newdata(struct uip_driver_s *dev, struct recvfrom_s *pstate) { - struct recvfrom_s *pstate = (struct recvfrom_s *)private; -#if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK) - FAR struct socket *psock; -#endif size_t recvlen; - vdbg("uip_flags: %02x\n", uip_flags); + /* Get the length of the data to return */ + + if (dev->d_len > pstate->rf_buflen) + { + recvlen = pstate->rf_buflen; + } + else + { + recvlen = dev->d_len; + } + + /* Copy the new appdata into the user buffer */ + + memcpy(pstate->rf_buffer, dev->d_appdata, recvlen); + vdbg("Received %d bytes (of %d)\n", recvlen, dev->d_len); + + /* Update the accumulated size of the data read */ + + pstate->rf_recvlen += recvlen; + pstate->rf_buffer += recvlen; + pstate->rf_buflen -= recvlen; +} + +/**************************************************************************** + * Function: recvfrom_timeout + * + * Description: + * Check for recvfrom timeout. + * + * Parameters: + * pstate recvfrom state structure + * + * Returned Value: + * TRUE:timeout FALSE:no timeout + * + * Assumptions: + * Running at the interrupt level + * + ****************************************************************************/ + +#if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK) +static int recvfrom_timeout(struct recvfrom_s *pstate) +{ + FAR struct socket *psock = 0; + socktimeo_t timeo = 0; + + /* If this is a TCP socket that has already received some data, + * than we will always use a short timeout. + */ + + if (pstate->rf_recvlen > 0) + { + /* Use the short timeout */ + + timeo = TCP_TIMEO; + } + + /* No.. check for a timeout configured via setsockopts(SO_RCVTIMEO). + * If none... we well let the read hang forever. + */ + + else + { + /* Get the socket reference from the private data */ + + psock = pstate->rf_sock; + if (psock) + { + timeo = psock->s_rcvtimeo; + } + } + + /* Is there an effective timeout? */ + + if (timeo) + { + /* Yes.. Check if the timeout has elapsed */ + + return net_timeo(pstate->rf_starttime, timeo); + } + + /* No timeout */ + + return FALSE; +} +#endif /* CONFIG_NET_SOCKOPTS && !CONFIG_DISABLE_CLOCK */ + +/**************************************************************************** + * Function: recvfrom_tcpinterrupt + * + * Description: + * This function is called from the interrupt level to perform the actual + * TCP receive operation via by the uIP layer. + * + * Parameters: + * dev The sructure of the network driver that caused the interrupt + * conn The connection structure associated with the socket + * flags Set of events describing why the callback was invoked + * + * Returned Value: + * None + * + * Assumptions: + * Running at the interrupt level + * + ****************************************************************************/ + +static uint8 recvfrom_tcpinterrupt(struct uip_driver_s *dev, + struct uip_conn *conn, uint8 flags) +{ + struct recvfrom_s *pstate = (struct recvfrom_s *)conn->data_private; + + vdbg("flags: %02x\n", flags); /* 'private' might be null in some race conditions (?) */ if (pstate) { -#if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK) - /* Get the socket reference from the private data */ - - psock = pstate->rf_sock; -#endif - /* If new data is available, then complete the read action. */ - if (uip_newdata_event()) + if (uip_newdata_event(flags)) { - /* Get the length of the data to return */ + /* Copy the data from the packet */ - if (dev->d_len > pstate->rf_buflen) - { - recvlen = pstate->rf_buflen; - } - else - { - recvlen = dev->d_len; - } + recvfrom_newdata(dev, pstate); - /* Copy the new appdata into the user buffer */ + /* If the user buffer has been filled, then we are finished. */ - memcpy(pstate->rf_buffer, dev->d_appdata, recvlen); - vdbg("Received %d bytes (of %d)\n", recvlen, dev->d_len); - - /* Update the accumulated size of the data read */ - - pstate->rf_recvlen += recvlen; - pstate->rf_buffer += recvlen; - pstate->rf_buflen -= recvlen; - - /* Are we finished? If this is a UDP socket or if the user - * buffer has been filled, then we are finished. - */ - -#ifdef CONFIG_NET_UDP - if (psock->s_type == SOCK_DGRAM) - { - struct uip_udp_conn *udp_conn; - - vdbg("UDP resume\n"); - - /* Don't allow any further UDP call backs. */ - - udp_conn = (struct uip_udp_conn *)psock->s_conn; - udp_conn->private = NULL; - udp_conn->event = NULL; - - /* Wake up the waiting thread, returning the number of bytes - * actually read. - */ - - sem_post(&pstate->rf_sem); - } - else -#endif if (pstate->rf_buflen == 0) { - struct uip_conn *conn; - vdbg("TCP resume\n"); /* The TCP receive buffer is full. Return now, perhaps truncating @@ -182,7 +240,6 @@ static void recvfrom_interrupt(struct uip_driver_s *dev, void *private) * Don't allow any further TCP call backs. */ - conn = (struct uip_conn *)psock->s_conn; conn->data_private = NULL; conn->data_event = NULL; @@ -204,26 +261,14 @@ static void recvfrom_interrupt(struct uip_driver_s *dev, void *private) /* Check for a loss of connection */ - else if ((uip_flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0) + else if ((flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0) { vdbg("error\n"); /* Stop further callbacks */ -#ifdef CONFIG_NET_UDP - if (psock->s_type == SOCK_DGRAM) - { - struct uip_udp_conn *udp_conn = (struct uip_udp_conn *)psock->s_conn; - udp_conn->private = NULL; - udp_conn->event = NULL; - } - else -#endif - { - struct uip_conn *conn = (struct uip_conn *)psock->s_conn; - conn->data_private = NULL; - conn->data_event = NULL; - } + conn->data_private = NULL; + conn->data_event = NULL; /* Report not connected */ @@ -239,92 +284,140 @@ static void recvfrom_interrupt(struct uip_driver_s *dev, void *private) */ #if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK) - else + else if (recvfrom_timeout(pstate)) { - socktimeo_t timeo; - - /* If this is a TCP socket that has already received some data, - * than we will always use a short timeout. + /* Yes.. the timeout has elapsed... do not allow any further + * callbacks */ - if (pstate->rf_recvlen > 0) - { - /* Use the short timeout */ + vdbg("TCP timeout\n"); - timeo = TCP_TIMEO; + conn->data_private = NULL; + conn->data_event = NULL; + + /* Report an error only if no data has been received */ + + if (pstate->rf_recvlen == 0) + { + /* Report the timeout error */ + + pstate->rf_result = -EAGAIN; } - /* No.. check for a timeout configured via setsockopts(SO_RCVTIMEO). - * If none... we well let the read hang forever. + /* Wake up the waiting thread, returning either the error -EAGAIN + * that signals the timeout event or the data received up to + * the point tht the timeout occured (no error). */ - else - { - timeo = psock->s_rcvtimeo; - } + sem_post(&pstate->rf_sem); + } +#endif /* CONFIG_NET_SOCKOPTS && !CONFIG_DISABLE_CLOCK */ + } + return 0; +} - /* Is there an effective timeout? */ - - if (timeo) - { - /* Yes.. Check if the timeout has elapsed */ - - if (net_timeo(pstate->rf_starttime, timeo)) - { - /* Yes.. the timeout has elapsed... do not allow any further - * callbacks - */ +/**************************************************************************** + * Function: recvfrom_udpinterrupt + * + * Description: + * This function is called from the interrupt level to perform the actual + * UDP receive operation via by the uIP layer. + * + * Parameters: + * dev The sructure of the network driver that caused the interrupt + * conn The connection structure associated with the socket + * flags Set of events describing why the callback was invoked + * + * Returned Value: + * None + * + * Assumptions: + * Running at the interrupt level + * + ****************************************************************************/ #ifdef CONFIG_NET_UDP - if (psock->s_type == SOCK_DGRAM) - { - struct uip_udp_conn *udp_conn; +static void recvfrom_udpinterrupt(struct uip_driver_s *dev, + struct uip_udp_conn *conn, uint8 flags) +{ + struct recvfrom_s *pstate = (struct recvfrom_s *)conn->private; - vdbg("UDP timeout\n"); + vdbg("flags: %02x\n", flags); - /* Stop further callbacks */ + /* 'private' might be null in some race conditions (?) */ - udp_conn = (struct uip_udp_conn *)psock->s_conn; - udp_conn->private = NULL; - udp_conn->event = NULL; + if (pstate) + { + /* If new data is available, then complete the read action. */ - /* Report a timeout error */ + if (uip_newdata_event(flags)) + { + /* Copy the data from the packet */ - pstate->rf_result = -EAGAIN; - } - else -#endif - { - struct uip_conn *conn; + recvfrom_newdata(dev, pstate); - vdbg("TCP timeout\n"); + /* We are finished. */ - conn = (struct uip_conn *)psock->s_conn; - conn->data_private = NULL; - conn->data_event = NULL; + vdbg("UDP resume\n"); - /* Report an error only if no data has been received */ + /* Don't allow any further UDP call backs. */ - if (pstate->rf_recvlen == 0) - { - /* Report the timeout error */ + conn->private = NULL; + conn->event = NULL; - pstate->rf_result = -EAGAIN; - } - } + /* Wake up the waiting thread, returning the number of bytes + * actually read. + */ - /* Wake up the waiting thread, returning either the error -EAGAIN - * that signals the timeout event or the data received up to - * the point tht the timeout occured (no error). - */ - - sem_post(&pstate->rf_sem); - } - } + sem_post(&pstate->rf_sem); } -#endif + + /* Check for a loss of connection */ + + else if ((flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0) + { + vdbg("error\n"); + + /* Stop further callbacks */ + + conn->private = NULL; + conn->event = NULL; + + /* Report not connected */ + + pstate->rf_result = -ENOTCONN; + + /* Wake up the waiting thread */ + + sem_post(&pstate->rf_sem); + } + + /* No data has been received -- this is some other event... probably a + * poll -- check for a timeout. + */ + +#if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK) + else if (recvfrom_timeout(pstate)) + { + /* Yes.. the timeout has elapsed... do not allow any further + * callbacks + */ + + vdbg("UDP timeout\n"); + + /* Stop further callbacks */ + + conn->private = NULL; + conn->event = NULL; + + /* Report a timeout error */ + + pstate->rf_result = -EAGAIN; + } +#endif /* CONFIG_NET_SOCKOPTS && !CONFIG_DISABLE_CLOCK */ } } +#endif /**************************************************************************** * Function: recvfrom_init @@ -468,7 +561,7 @@ static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, udp_conn = (struct uip_udp_conn *)psock->s_conn; udp_conn->private = (void*)&state; - udp_conn->event = recvfrom_interrupt; + udp_conn->event = recvfrom_udpinterrupt; /* Enable the UDP socket */ @@ -549,7 +642,7 @@ static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, conn = (struct uip_conn *)psock->s_conn; conn->data_private = (void*)&state; - conn->data_event = recvfrom_interrupt; + conn->data_event = recvfrom_tcpinterrupt; /* Wait for either the receive to complete or for an error/timeout to occur. * NOTES: (1) sem_wait will also terminate if a signal is received, (2) diff --git a/net/send.c b/net/send.c index 84c6757b0d..98dcec3521 100644 --- a/net/send.c +++ b/net/send.c @@ -89,7 +89,8 @@ struct send_s * * Parameters: * dev The sructure of the network driver that caused the interrupt - * private An instance of struct send_s cast to void* + * conn The connection structure associated with the socket + * flags Set of events describing why the callback was invoked * * Returned Value: * None @@ -99,22 +100,21 @@ struct send_s * ****************************************************************************/ -static void send_interrupt(struct uip_driver_s *dev, void *private) +static uint8 send_interrupt(struct uip_driver_s *dev, struct uip_conn *conn, uint8 flags) { - struct send_s *pstate = (struct send_s *)private; - struct uip_conn *conn; + struct send_s *pstate = (struct send_s *)conn->data_private; - vdbg("uip_flags: %02x state: %d\n", uip_flags, pstate->snd_state); + vdbg("flags: %02x state: %d\n", flags, pstate->snd_state); /* If the data has not been sent OR if it needs to be retransmitted, * then send it now. */ - if (pstate->snd_state != STATE_DATA_SENT || uip_rexmit_event()) + if (pstate->snd_state != STATE_DATA_SENT || uip_rexmit_event(flags)) { - if (pstate->snd_buflen > uip_mss()) + if (pstate->snd_buflen > uip_mss(conn)) { - uip_send(dev, pstate->snd_buffer, uip_mss()); + uip_send(dev, pstate->snd_buffer, uip_mss(conn)); } else { @@ -126,17 +126,17 @@ static void send_interrupt(struct uip_driver_s *dev, void *private) /* Check if all data has been sent and acknowledged */ - else if (pstate->snd_state == STATE_DATA_SENT && uip_ack_event()) + else if (pstate->snd_state == STATE_DATA_SENT && uip_ack_event(flags)) { /* Yes.. the data has been sent AND acknowledged */ - if (pstate->snd_buflen > uip_mss()) + if (pstate->snd_buflen > uip_mss(conn)) { /* Not all data has been sent */ - pstate->snd_sent += uip_mss(); - pstate->snd_buflen -= uip_mss(); - pstate->snd_buffer += uip_mss(); + pstate->snd_sent += uip_mss(conn); + pstate->snd_buflen -= uip_mss(conn); + pstate->snd_buffer += uip_mss(conn); /* Send again on the next poll */ @@ -152,7 +152,6 @@ static void send_interrupt(struct uip_driver_s *dev, void *private) /* Don't allow any further call backs. */ - conn = (struct uip_conn *)pstate->snd_sock->s_conn; conn->data_private = NULL; conn->data_event = NULL; @@ -166,11 +165,10 @@ static void send_interrupt(struct uip_driver_s *dev, void *private) /* Check for a loss of connection */ - else if ((uip_flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0) + else if ((flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0) { /* Stop further callbacks */ - conn = (struct uip_conn *)pstate->snd_sock->s_conn; conn->data_private = NULL; conn->data_event = NULL; @@ -182,6 +180,7 @@ static void send_interrupt(struct uip_driver_s *dev, void *private) sem_post(&pstate->snd_sem); } + return 0; } /**************************************************************************** diff --git a/net/sendto.c b/net/sendto.c index 0d03252f59..d18ea8e3d8 100644 --- a/net/sendto.c +++ b/net/sendto.c @@ -79,6 +79,7 @@ struct sendto_s * Parameters: * dev The sructure of the network driver that caused the interrupt * private An instance of struct sendto_s cast to void* + * flags Set of events describing why the callback was invoked * * Returned Value: * None @@ -89,14 +90,14 @@ struct sendto_s ****************************************************************************/ #ifdef CONFIG_NET_UDP -void sendto_interrupt(struct uip_driver_s *dev, void *private) +void sendto_interrupt(struct uip_driver_s *dev, struct uip_udp_conn *conn, uint8 flags) { - struct sendto_s *pstate = (struct sendto_s *)private; - if (private) + struct sendto_s *pstate = (struct sendto_s *)conn->private; + if (pstate) { /* Check if the connectin was rejected */ - if ((uip_flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0) + if ((flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0) { pstate->st_sndlen = -ENOTCONN; } @@ -111,8 +112,8 @@ void sendto_interrupt(struct uip_driver_s *dev, void *private) /* Don't allow any further call backs. */ - uip_udp_conn->private = NULL; - uip_udp_conn->event = NULL; + conn->private = NULL; + conn->event = NULL; /* Wake up the waiting thread */ diff --git a/net/uip/uip-initialize.c b/net/uip/uip-initialize.c index 42778d2c13..baed0f878f 100644 --- a/net/uip/uip-initialize.c +++ b/net/uip/uip-initialize.c @@ -62,20 +62,6 @@ void *uip_urgdata; /* urgent data (out-of-band data), if present. */ uint16 uip_urglen; /* Length of (received) urgent data */ #endif -/* The uip_flags variable is used for communication between the TCP/IP - * stack and the application program. - */ - -uint8 uip_flags; - -/* uip_conn always points to the current connection. */ - -struct uip_conn *uip_conn; - -#ifdef CONFIG_NET_UDP -struct uip_udp_conn *uip_udp_conn; -#endif /* CONFIG_NET_UDP */ - #ifdef CONFIG_NET_STATISTICS struct uip_stats uip_stat; #endif diff --git a/net/uip/uip-internal.h b/net/uip/uip-internal.h index 4d7309f298..118ccd53f0 100644 --- a/net/uip/uip-internal.h +++ b/net/uip/uip-internal.h @@ -160,9 +160,10 @@ EXTERN void uip_tcprexmit(struct uip_driver_s *dev, struct uip_conn *conn, EXTERN void uip_tcpinput(struct uip_driver_s *dev); -/* Defined in uip_uipcallback.c *********************************************/ +/* Defined in uip_tcpcallback.c *********************************************/ -EXTERN void uip_tcpcallback(struct uip_driver_s *dev); +EXTERN uint8 uip_tcpcallback(struct uip_driver_s *dev, + struct uip_conn *conn, uint8 flags); #ifdef CONFIG_NET_UDP /* Defined in uip_udpconn.c *************************************************/ @@ -185,7 +186,8 @@ EXTERN void uip_udpinput(struct uip_driver_s *dev); /* Defined in uip_uipcallback.c *********************************************/ -EXTERN void uip_udpcallback(struct uip_driver_s *dev); +EXTERN void uip_udpcallback(struct uip_driver_s *dev, + struct uip_udp_conn *conn, uint8 flags); #endif /* CONFIG_NET_UDP */ /* Defined in uip-icmpinput.c ***********************************************/ diff --git a/net/uip/uip-listen.c b/net/uip/uip-listen.c index edbb9d469d..f1097c40c7 100644 --- a/net/uip/uip-listen.c +++ b/net/uip/uip-listen.c @@ -187,7 +187,7 @@ int uip_accept(struct uip_conn *conn, uint16 portno) { struct uip_conn *listener; int ret = ERROR; - + /* The interrupt logic has already allocated and initialized a TCP * connection -- now check if is an application in place to accept the * connection. @@ -198,7 +198,7 @@ int uip_accept(struct uip_conn *conn, uint16 portno) { /* Yes.. accept the connection */ - ret = listener->accept(listener->accept_private, conn); + ret = listener->accept(listener, conn); } return ret; } diff --git a/net/uip/uip-poll.c b/net/uip/uip-poll.c index d80b77995a..f17f42e75a 100644 --- a/net/uip/uip-poll.c +++ b/net/uip/uip-poll.c @@ -83,7 +83,6 @@ static int uip_polludpconnections(struct uip_driver_s *dev, { /* Perform the UDP TX poll */ - uip_udp_conn = udp_conn; uip_udppoll(dev, udp_conn); /* Call back into the driver */ @@ -91,7 +90,6 @@ static int uip_polludpconnections(struct uip_driver_s *dev, bstop = callback(dev); } - uip_udp_conn = NULL; return bstop; } #else @@ -122,7 +120,6 @@ static inline int uip_polltcpconnections(struct uip_driver_s *dev, { /* Perform the TCP TX poll */ - uip_conn = conn; uip_tcppoll(dev, conn); /* Call back into the driver */ @@ -130,7 +127,6 @@ static inline int uip_polltcpconnections(struct uip_driver_s *dev, bstop = callback(dev); } - uip_conn = NULL; return bstop; } @@ -159,7 +155,6 @@ static inline int uip_polltcptimer(struct uip_driver_s *dev, { /* Perform the TCP timer poll */ - uip_conn = conn; uip_tcptimer(dev, conn, hsec); /* Call back into the driver */ @@ -167,7 +162,6 @@ static inline int uip_polltcptimer(struct uip_driver_s *dev, bstop = callback(dev); } - uip_conn = NULL; return bstop; } diff --git a/net/uip/uip-tcpcallback.c b/net/uip/uip-tcpcallback.c index ad18227124..4a314e9974 100644 --- a/net/uip/uip-tcpcallback.c +++ b/net/uip/uip-tcpcallback.c @@ -73,33 +73,33 @@ * ****************************************************************************/ -void uip_tcpcallback(struct uip_driver_s *dev) +uint8 uip_tcpcallback(struct uip_driver_s *dev, struct uip_conn *conn, uint8 flags) { - vdbg("uip_flags: %02x\n", uip_flags); + uint8 ret = 0; - /* Some sanity checking */ + vdbg("flags: %02x\n", flags); - if (uip_conn) + /* Check if there is a data callback */ + + if (conn->data_event) { - /* Check if there is a data callback */ + /* Perform the callback */ - if (uip_conn->data_event) - { - /* Perform the callback */ - - uip_conn->data_event(dev, uip_conn->data_private); - } - - /* Check if there is a connection-related event and a connection - * callback. - */ - if (((uip_flags & UIP_CONN_EVENTS) != 0) && uip_conn->connection_event) - { - /* Perform the callback */ - - uip_conn->connection_event(uip_conn->connection_private); - } + ret = conn->data_event(dev, conn, flags); } + + /* Check if there is a connection-related event and a connection + * callback. + */ + + if (((flags & UIP_CONN_EVENTS) != 0) && conn->connection_event) + { + /* Perform the callback */ + + conn->connection_event(conn, flags); + } + + return ret; } #endif /* CONFIG_NET */ diff --git a/net/uip/uip-tcpinput.c b/net/uip/uip-tcpinput.c index 71cd54d9e1..2ecd23d98f 100644 --- a/net/uip/uip-tcpinput.c +++ b/net/uip/uip-tcpinput.c @@ -95,9 +95,11 @@ void uip_tcpinput(struct uip_driver_s *dev) { - register struct uip_conn *uip_connr = uip_conn; + struct uip_conn *conn = NULL; uint16 tmp16; uint8 opt; + uint8 flags; + uint8 result; int len; int i; @@ -121,8 +123,8 @@ void uip_tcpinput(struct uip_driver_s *dev) /* Demultiplex this segment. First check any active connections. */ - uip_connr = uip_tcpactive(BUF); - if (uip_connr) + conn = uip_tcpactive(BUF); + if (conn) { goto found; } @@ -135,40 +137,40 @@ void uip_tcpinput(struct uip_driver_s *dev) if ((BUF->flags & TCP_CTL) == TCP_SYN) { - /* This is a SYN packet for a connection. Find the connection - * listening on this port. - */ + /* This is a SYN packet for a connection. Find the connection + * listening on this port. + */ - tmp16 = BUF->destport; - if (uip_islistener(tmp16)) - { - /* We matched the incoming packet with a connection in LISTEN. - * We now need to create a new connection and send a SYNACK in - * response. - */ + tmp16 = BUF->destport; + if (uip_islistener(tmp16)) + { + /* We matched the incoming packet with a connection in LISTEN. + * We now need to create a new connection and send a SYNACK in + * response. + */ /* First allocate a new connection structure and see if there is any * user application to accept it. */ - uip_connr = uip_tcpaccept(BUF); - if (uip_connr) + conn = uip_tcpaccept(BUF); + if (conn) { /* The connection structure was successfully allocated. Now see * there is an application waiting to accept the connection (or at * least queue it it for acceptance). */ - if (uip_accept(uip_connr, tmp16) != OK) + if (uip_accept(conn, tmp16) != OK) { /* No, then we have to give the connection back */ - uip_tcpfree(uip_connr); - uip_connr = NULL; + uip_tcpfree(conn); + conn = NULL; } } - if (!uip_connr) + if (!conn) { /* Either (1) all available connections are in use, or (2) there is no * application in place to accept the connection. We drop packet and hope that @@ -183,8 +185,7 @@ void uip_tcpinput(struct uip_driver_s *dev) goto drop; } - uip_incr32(uip_conn->rcv_nxt, 1); - uip_conn = uip_connr; + uip_incr32(conn->rcv_nxt, 1); /* Parse the TCP MSS option, if present. */ @@ -212,7 +213,7 @@ void uip_tcpinput(struct uip_driver_s *dev) tmp16 = ((uint16)dev->d_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + i] << 8) | (uint16)dev->d_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + i]; - uip_connr->initialmss = uip_connr->mss = + conn->initialmss = conn->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16; /* And we are done processing options. */ @@ -240,8 +241,8 @@ void uip_tcpinput(struct uip_driver_s *dev) /* Our response will be a SYNACK. */ - uip_tcpack(dev, uip_connr, TCP_ACK | TCP_SYN); - goto done; + uip_tcpack(dev, conn, TCP_ACK | TCP_SYN); + return; } } @@ -260,12 +261,11 @@ void uip_tcpinput(struct uip_driver_s *dev) uip_stat.tcp.synrst++; #endif uip_tcpreset(dev); - goto done; + return; found: - uip_conn = uip_connr; - uip_flags = 0; + 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 @@ -275,11 +275,10 @@ found: if (BUF->flags & TCP_RST) { - uip_connr->tcpstateflags = UIP_CLOSED; + conn->tcpstateflags = UIP_CLOSED; dbg("Recvd reset - TCP state: UIP_CLOSED\n"); - uip_flags = UIP_ABORT; - uip_tcpcallback(dev); + (void)uip_tcpcallback(dev, conn, UIP_ABORT); goto drop; } @@ -301,17 +300,17 @@ found: * correct numbers in. */ - if (!(((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) && + if (!(((conn->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) && ((BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)))) { if ((dev->d_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])) + (BUF->seqno[0] != conn->rcv_nxt[0] || + BUF->seqno[1] != conn->rcv_nxt[1] || + BUF->seqno[2] != conn->rcv_nxt[2] || + BUF->seqno[3] != conn->rcv_nxt[3])) { - uip_tcpsend(dev, uip_connr, TCP_ACK, UIP_IPTCPH_LEN); - goto done; + uip_tcpsend(dev, conn, TCP_ACK, UIP_IPTCPH_LEN); + return; } } @@ -321,61 +320,61 @@ found: * retransmission timer. */ - if ((BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) + if ((BUF->flags & TCP_ACK) && uip_outstanding(conn)) { /* Temporary variables. */ uint8 acc32[4]; - uip_add32(uip_connr->snd_nxt, uip_connr->len, acc32); + uip_add32(conn->snd_nxt, conn->len, acc32); if (BUF->ackno[0] == acc32[0] && BUF->ackno[1] == acc32[1] && BUF->ackno[2] == acc32[2] && BUF->ackno[3] == acc32[3]) { /* Update sequence number. */ - uip_connr->snd_nxt[0] = acc32[0]; - uip_connr->snd_nxt[1] = acc32[1]; - uip_connr->snd_nxt[2] = acc32[2]; - uip_connr->snd_nxt[3] = acc32[3]; + conn->snd_nxt[0] = acc32[0]; + conn->snd_nxt[1] = acc32[1]; + conn->snd_nxt[2] = acc32[2]; + conn->snd_nxt[3] = acc32[3]; /* Do RTT estimation, unless we have done retransmissions. */ - if (uip_connr->nrtx == 0) + if (conn->nrtx == 0) { signed char m; - m = uip_connr->rto - uip_connr->timer; + m = conn->rto - conn->timer; /* This is taken directly from VJs original code in his paper */ - m = m - (uip_connr->sa >> 3); - uip_connr->sa += m; + m = m - (conn->sa >> 3); + conn->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; + m = m - (conn->sv >> 2); + conn->sv += m; + conn->rto = (conn->sa >> 3) + conn->sv; } /* Set the acknowledged flag. */ - uip_flags = UIP_ACKDATA; + flags = UIP_ACKDATA; /* Reset the retransmission timer. */ - uip_connr->timer = uip_connr->rto; + conn->timer = conn->rto; /* Reset length of outstanding data. */ - uip_connr->len = 0; + conn->len = 0; } } /* Do different things depending on in what state the connection is. */ - switch(uip_connr->tcpstateflags & UIP_TS_MASK) + switch (conn->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 @@ -390,24 +389,24 @@ found: * flag set. If so, we enter the ESTABLISHED state. */ - if (uip_flags & UIP_ACKDATA) + if (flags & UIP_ACKDATA) { - uip_connr->tcpstateflags = UIP_ESTABLISHED; - uip_connr->len = 0; + conn->tcpstateflags = UIP_ESTABLISHED; + conn->len = 0; vdbg("TCP state: UIP_ESTABLISHED\n"); - uip_flags = UIP_CONNECTED; + flags = UIP_CONNECTED; if (dev->d_len > 0) { - uip_flags |= UIP_NEWDATA; - uip_incr32(uip_conn->rcv_nxt, dev->d_len); + flags |= UIP_NEWDATA; + uip_incr32(conn->rcv_nxt, dev->d_len); } - dev->d_sndlen = 0; - uip_tcpcallback(dev); - uip_tcpappsend(dev, uip_connr, uip_flags); - goto done; + dev->d_sndlen = 0; + result = uip_tcpcallback(dev, conn, flags); + uip_tcpappsend(dev, conn, result); + return; } goto drop; @@ -418,8 +417,7 @@ found: * state. */ - if ((uip_flags & UIP_ACKDATA) && - (BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) + if ((flags & UIP_ACKDATA) && (BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) { /* Parse the TCP MSS option, if present. */ @@ -448,8 +446,8 @@ found: tmp16 = (dev->d_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + i] << 8) | dev->d_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + i]; - uip_connr->initialmss = - uip_connr->mss = + conn->initialmss = + conn->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16; /* And we are done processing options. */ @@ -475,31 +473,29 @@ found: } } - 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]; + conn->tcpstateflags = UIP_ESTABLISHED; + conn->rcv_nxt[0] = BUF->seqno[0]; + conn->rcv_nxt[1] = BUF->seqno[1]; + conn->rcv_nxt[2] = BUF->seqno[2]; + conn->rcv_nxt[3] = BUF->seqno[3]; vdbg("TCP state: UIP_ESTABLISHED\n"); - uip_incr32(uip_conn->rcv_nxt, 1); - uip_flags = UIP_CONNECTED | UIP_NEWDATA; - uip_connr->len = 0; - dev->d_len = 0; - dev->d_sndlen = 0; - uip_tcpcallback(dev); - uip_tcpappsend(dev, uip_connr, uip_flags); - goto done; + uip_incr32(conn->rcv_nxt, 1); + conn->len = 0; + dev->d_len = 0; + dev->d_sndlen = 0; + result = uip_tcpcallback(dev, conn, UIP_CONNECTED | UIP_NEWDATA); + uip_tcpappsend(dev, conn, result); + return; } /* Inform the application that the connection failed */ - uip_flags = UIP_ABORT; - uip_tcpcallback(dev); + (void)uip_tcpcallback(dev, conn, UIP_ABORT); /* The connection is closed after we send the RST */ - uip_conn->tcpstateflags = UIP_CLOSED; + conn->tcpstateflags = UIP_CLOSED; vdbg("TCP state: UIP_CLOSED\n"); /* We do not send resets in response to resets. */ @@ -509,7 +505,7 @@ found: goto drop; } uip_tcpreset(dev); - goto done; + return; case UIP_ESTABLISHED: /* In the ESTABLISHED state, we call upon the application to feed @@ -524,30 +520,30 @@ found: * sequence numbers will be screwed up. */ - if (BUF->flags & TCP_FIN && !(uip_connr->tcpstateflags & UIP_STOPPED)) + if (BUF->flags & TCP_FIN && !(conn->tcpstateflags & UIP_STOPPED)) { - if (uip_outstanding(uip_connr)) + if (uip_outstanding(conn)) { goto drop; } - uip_incr32(uip_conn->rcv_nxt, dev->d_len + 1); - uip_flags |= UIP_CLOSE; + uip_incr32(conn->rcv_nxt, dev->d_len + 1); + flags |= UIP_CLOSE; if (dev->d_len > 0) { - uip_flags |= UIP_NEWDATA; + flags |= UIP_NEWDATA; } - uip_tcpcallback(dev); + (void)uip_tcpcallback(dev, conn, flags); - uip_connr->tcpstateflags = UIP_LAST_ACK; - uip_connr->len = 1; - uip_connr->nrtx = 0; + conn->tcpstateflags = UIP_LAST_ACK; + conn->len = 1; + conn->nrtx = 0; vdbg("TCP state: UIP_LAST_ACK\n"); - uip_tcpsend(dev, uip_connr, TCP_FIN | TCP_ACK, UIP_IPTCPH_LEN); - goto done; + uip_tcpsend(dev, conn, TCP_FIN | TCP_ACK, UIP_IPTCPH_LEN); + return; } /* Check the URG flag. If this is set, the segment carries urgent @@ -563,7 +559,7 @@ found: uip_urglen = dev->d_len; } - uip_incr32(uip_conn->rcv_nxt, uip_urglen); + uip_incr32(conn->rcv_nxt, uip_urglen); dev->d_len -= uip_urglen; uip_urgdata = dev->d_appdata; dev->d_appdata += uip_urglen; @@ -586,10 +582,10 @@ found: * remote host. */ - if (dev->d_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) + if (dev->d_len > 0 && !(conn->tcpstateflags & UIP_STOPPED)) { - uip_flags |= UIP_NEWDATA; - uip_incr32(uip_conn->rcv_nxt, dev->d_len); + flags |= UIP_NEWDATA; + uip_incr32(conn->rcv_nxt, dev->d_len); } /* Check if the available buffer space advertised by the other end @@ -606,11 +602,11 @@ found: */ tmp16 = ((uint16)BUF->wnd[0] << 8) + (uint16)BUF->wnd[1]; - if (tmp16 > uip_connr->initialmss || tmp16 == 0) + if (tmp16 > conn->initialmss || tmp16 == 0) { - tmp16 = uip_connr->initialmss; + tmp16 = conn->initialmss; } - uip_connr->mss = tmp16; + conn->mss = tmp16; /* If this packet constitutes an ACK for outstanding data (flagged * by the UIP_ACKDATA flag, we should call the application since it @@ -630,12 +626,12 @@ found: * send, d_len must be set to 0. */ - if (uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) + if (flags & (UIP_NEWDATA | UIP_ACKDATA)) { dev->d_sndlen = 0; - uip_tcpcallback(dev); - uip_tcpappsend(dev, uip_connr, uip_flags); - goto done; + result = uip_tcpcallback(dev, conn, flags); + uip_tcpappsend(dev, conn, result); + return; } goto drop; @@ -644,13 +640,12 @@ found: * FIN. This is indicated by the UIP_ACKDATA flag. */ - if (uip_flags & UIP_ACKDATA) + if (flags & UIP_ACKDATA) { - uip_connr->tcpstateflags = UIP_CLOSED; + conn->tcpstateflags = UIP_CLOSED; vdbg("TCP state: UIP_CLOSED\n"); - uip_flags = UIP_CLOSE; - uip_tcpcallback(dev); + (void)uip_tcpcallback(dev, conn, UIP_CLOSE); } break; @@ -662,90 +657,85 @@ found: if (dev->d_len > 0) { - uip_incr32(uip_conn->rcv_nxt, dev->d_len); + uip_incr32(conn->rcv_nxt, dev->d_len); } if (BUF->flags & TCP_FIN) { - if (uip_flags & UIP_ACKDATA) + if (flags & UIP_ACKDATA) { - uip_connr->tcpstateflags = UIP_TIME_WAIT; - uip_connr->timer = 0; - uip_connr->len = 0; + conn->tcpstateflags = UIP_TIME_WAIT; + conn->timer = 0; + conn->len = 0; vdbg("TCP state: UIP_TIME_WAIT\n"); } else { - uip_connr->tcpstateflags = UIP_CLOSING; + conn->tcpstateflags = UIP_CLOSING; vdbg("TCP state: UIP_CLOSING\n"); } - uip_incr32(uip_conn->rcv_nxt, 1); - uip_flags = UIP_CLOSE; - uip_tcpcallback(dev); - uip_tcpsend(dev, uip_connr, TCP_ACK, UIP_IPTCPH_LEN); - goto done; + uip_incr32(conn->rcv_nxt, 1); + (void)uip_tcpcallback(dev, conn, UIP_CLOSE); + uip_tcpsend(dev, conn, TCP_ACK, UIP_IPTCPH_LEN); + return; } - else if (uip_flags & UIP_ACKDATA) + else if (flags & UIP_ACKDATA) { - uip_connr->tcpstateflags = UIP_FIN_WAIT_2; - uip_connr->len = 0; + conn->tcpstateflags = UIP_FIN_WAIT_2; + conn->len = 0; vdbg("TCP state: UIP_FIN_WAIT_2\n"); goto drop; } if (dev->d_len > 0) { - uip_tcpsend(dev, uip_connr, TCP_ACK, UIP_IPTCPH_LEN); - goto done; + uip_tcpsend(dev, conn, TCP_ACK, UIP_IPTCPH_LEN); + return; } goto drop; case UIP_FIN_WAIT_2: if (dev->d_len > 0) { - uip_incr32(uip_conn->rcv_nxt, dev->d_len); + uip_incr32(conn->rcv_nxt, dev->d_len); } if (BUF->flags & TCP_FIN) { - uip_connr->tcpstateflags = UIP_TIME_WAIT; - uip_connr->timer = 0; + conn->tcpstateflags = UIP_TIME_WAIT; + conn->timer = 0; vdbg("TCP state: UIP_TIME_WAIT\n"); - uip_incr32(uip_conn->rcv_nxt, 1); - uip_flags = UIP_CLOSE; - uip_tcpcallback(dev); - uip_tcpsend(dev, uip_connr, TCP_ACK, UIP_IPTCPH_LEN); - goto done; + uip_incr32(conn->rcv_nxt, 1); + (void)uip_tcpcallback(dev, conn, UIP_CLOSE); + uip_tcpsend(dev, conn, TCP_ACK, UIP_IPTCPH_LEN); + return; } if (dev->d_len > 0) { - uip_tcpsend(dev, uip_connr, TCP_ACK, UIP_IPTCPH_LEN); - goto done; + uip_tcpsend(dev, conn, TCP_ACK, UIP_IPTCPH_LEN); + return; } goto drop; case UIP_TIME_WAIT: - uip_tcpsend(dev, uip_connr, TCP_ACK, UIP_IPTCPH_LEN); - goto done; + uip_tcpsend(dev, conn, TCP_ACK, UIP_IPTCPH_LEN); + return; case UIP_CLOSING: - if (uip_flags & UIP_ACKDATA) + if (flags & UIP_ACKDATA) { - uip_connr->tcpstateflags = UIP_TIME_WAIT; - uip_connr->timer = 0; + conn->tcpstateflags = UIP_TIME_WAIT; + conn->timer = 0; vdbg("TCP state: UIP_TIME_WAIT\n"); } - } - goto drop; -done: - uip_flags = 0; - return; + default: + break; + } drop: - uip_flags = 0; dev->d_len = 0; } diff --git a/net/uip/uip-tcppoll.c b/net/uip/uip-tcppoll.c index f2deac0faa..9b66ef7072 100644 --- a/net/uip/uip-tcppoll.c +++ b/net/uip/uip-tcppoll.c @@ -94,6 +94,8 @@ void uip_tcppoll(struct uip_driver_s *dev, struct uip_conn *conn) { + uint8 result; + /* Verify that the connection is established and if the connection has * oustanding (unacknowledged) sent data. */ @@ -111,12 +113,11 @@ void uip_tcppoll(struct uip_driver_s *dev, struct uip_conn *conn) /* Perfom the callback */ - uip_flags = UIP_POLL; - uip_tcpcallback(dev); + result = uip_tcpcallback(dev, conn, UIP_POLL); /* Handle the callback response */ - uip_tcpappsend(dev, conn, uip_flags); + uip_tcpappsend(dev, conn, result); } else { diff --git a/net/uip/uip-tcptimer.c b/net/uip/uip-tcptimer.c index 66210e2466..beb16bc0f3 100644 --- a/net/uip/uip-tcptimer.c +++ b/net/uip/uip-tcptimer.c @@ -95,6 +95,8 @@ void uip_tcptimer(struct uip_driver_s *dev, struct uip_conn *conn, int hsec) { + uint8 result; + dev->d_snddata = &dev->d_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN]; dev->d_appdata = &dev->d_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN]; @@ -157,13 +159,12 @@ void uip_tcptimer(struct uip_driver_s *dev, struct uip_conn *conn, int hsec) conn->tcpstateflags = UIP_CLOSED; vdbg("TCP state: UIP_CLOSED\n"); - /* We call uip_tcpcallback() with uip_flags set to - * UIP_TIMEDOUT to inform the application that the - * connection has timed out. + /* We call uip_tcpcallback() with UIP_TIMEDOUT to + * inform the application that the connection has + * timed out. */ - uip_flags = UIP_TIMEDOUT; - uip_tcpcallback(dev); + result = uip_tcpcallback(dev, conn, UIP_TIMEDOUT); /* We also send a reset packet to the remote host. */ @@ -209,9 +210,8 @@ void uip_tcptimer(struct uip_driver_s *dev, struct uip_conn *conn, int hsec) * the code for sending out the packet. */ - uip_flags = UIP_REXMIT; - uip_tcpcallback(dev); - uip_tcprexmit(dev, conn, uip_flags); + result = uip_tcpcallback(dev, conn, UIP_REXMIT); + uip_tcprexmit(dev, conn, result); goto done; case UIP_FIN_WAIT_1: @@ -233,9 +233,8 @@ void uip_tcptimer(struct uip_driver_s *dev, struct uip_conn *conn, int hsec) * application for new data. */ - uip_flags = UIP_POLL; - uip_tcpcallback(dev); - uip_tcpappsend(dev, conn, uip_flags); + result = uip_tcpcallback(dev, conn, UIP_POLL); + uip_tcpappsend(dev, conn, result); goto done; } } @@ -245,7 +244,6 @@ void uip_tcptimer(struct uip_driver_s *dev, struct uip_conn *conn, int hsec) dev->d_len = 0; done: - uip_flags = 0; return; } diff --git a/net/uip/uip-udpcallback.c b/net/uip/uip-udpcallback.c index ed283d1939..29ee7d7369 100644 --- a/net/uip/uip-udpcallback.c +++ b/net/uip/uip-udpcallback.c @@ -73,17 +73,18 @@ * ****************************************************************************/ -void uip_udpcallback(struct uip_driver_s *dev) +void uip_udpcallback(struct uip_driver_s *dev, struct uip_udp_conn *conn, + uint8 flags) { - vdbg("uip_flags: %02x\n", uip_flags); + vdbg("flags: %02x\n", flags); /* Some sanity checking */ - if (uip_udp_conn && uip_udp_conn->event) + if (conn && conn->event) { /* Perform the callback */ - uip_udp_conn->event(dev, uip_udp_conn->private); + conn->event(dev, conn, flags); } } diff --git a/net/uip/uip-udpinput.c b/net/uip/uip-udpinput.c index 6bd347355d..46e673402d 100644 --- a/net/uip/uip-udpinput.c +++ b/net/uip/uip-udpinput.c @@ -95,6 +95,8 @@ void uip_udpinput(struct uip_driver_s *dev) { + struct uip_udp_conn *conn; + /* 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 d_sndlen, it has a packet to send. @@ -117,31 +119,25 @@ void uip_udpinput(struct uip_driver_s *dev) { /* Demultiplex this UDP packet between the UDP "connections". */ - uip_udp_conn = uip_udpactive(UDPBUF); - if (uip_udp_conn) + conn = uip_udpactive(UDPBUF); + if (conn) { /* Setup for the application callback */ - uip_conn = NULL; - dev->d_appdata = &dev->d_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN]; dev->d_snddata = &dev->d_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN]; dev->d_sndlen = 0; /* Perform the application callback */ - uip_flags = UIP_NEWDATA; - uip_udpcallback(dev); - uip_flags = 0; + uip_udpcallback(dev, conn, UIP_NEWDATA); /* If the application has data to send, setup the UDP/IP header */ if (dev->d_sndlen > 0) { - uip_udpsend(dev, uip_udp_conn); + uip_udpsend(dev, conn); } - - uip_udp_conn = NULL; } else { diff --git a/net/uip/uip-udppoll.c b/net/uip/uip-udppoll.c index aa5a205bc8..e664fcd738 100644 --- a/net/uip/uip-udppoll.c +++ b/net/uip/uip-udppoll.c @@ -100,9 +100,6 @@ void uip_udppoll(struct uip_driver_s *dev, struct uip_udp_conn *conn) { /* Setup for the application callback */ - uip_conn = NULL; - uip_udp_conn = conn; - dev->d_appdata = &dev->d_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN]; dev->d_snddata = &dev->d_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN]; @@ -111,16 +108,13 @@ void uip_udppoll(struct uip_driver_s *dev, struct uip_udp_conn *conn) /* Perform the application callback */ - uip_flags = UIP_POLL; - uip_udpcallback(dev); + uip_udpcallback(dev, conn, UIP_POLL); /* If the application has data to send, setup the UDP/IP header */ if (dev->d_sndlen > 0) { uip_udpsend(dev, conn); - uip_udp_conn = NULL; - uip_flags = 0; return; } } @@ -128,8 +122,6 @@ void uip_udppoll(struct uip_driver_s *dev, struct uip_udp_conn *conn) /* Make sure that d_len is zerp meaning that there is nothing to be sent */ dev->d_len = 0; - uip_udp_conn = NULL; - uip_flags = 0; } #endif /* CONFIG_NET && CONFIG_NET_UDP */ diff --git a/netutils/telnetd/telnetd.c b/netutils/telnetd/telnetd.c index 0753934849..8efeac5cdb 100644 --- a/netutils/telnetd/telnetd.c +++ b/netutils/telnetd/telnetd.c @@ -138,7 +138,7 @@ static void acked(void) } } -static void senddata(struct uip_driver_s *dev) +static void senddata(struct uip_driver_s *dev, struct uip_conn *conn) { char *bufptr, *lineptr; int buflen, linelen; @@ -155,7 +155,7 @@ static void senddata(struct uip_driver_s *dev) { linelen = TELNETD_CONF_LINELEN; } - if (buflen + linelen < uip_mss()) + if (buflen + linelen < uip_mss(conn)) { memcpy(bufptr, lineptr, linelen); bufptr += linelen; @@ -302,11 +302,12 @@ static void newdata(struct uip_driver_s *dev) * event of interest occurs. */ -void uip_interrupt_event(struct uip_driver_s *dev, void *private) +uint8 uip_interrupt_event(struct uip_driver_s *dev, struct uip_conn *conn, uint8 flags) { #warning OBSOLETE -- needs to be redesigned unsigned int i; - if (uip_connected_event()) + + if (uip_connected_event(flags)) { for (i = 0; i < TELNETD_CONF_NUMLINES; ++i) { @@ -321,28 +322,28 @@ void uip_interrupt_event(struct uip_driver_s *dev, void *private) if (s.state == STATE_CLOSE) { s.state = STATE_NORMAL; - uip_close(); - return; + return UIP_CLOSE; } - if (uip_close_event() || uip_abort_event() || uip_timeout_event()) + if (uip_close_event(flags) || uip_abort_event(flags) || uip_timeout_event(flags)) { closed(); } - if (uip_ack_event()) + if (uip_ack_event(flags)) { acked(); } - if (uip_newdata_event()) + if (uip_newdata_event(flags)) { newdata(dev); } - if (uip_rexmit_event() || uip_newdata_event() || uip_ack_event() || - uip_connected_event() || uip_poll_event()) + if (uip_rexmit_event(flags) || uip_newdata_event(flags) || uip_ack_event(flags) || + uip_connected_event(flags) || uip_poll_event(flags)) { - senddata(dev); + senddata(dev, conn); } + return 0; } diff --git a/netutils/webclient/webclient.c b/netutils/webclient/webclient.c index f285c3f41b..0c13c6c62d 100644 --- a/netutils/webclient/webclient.c +++ b/netutils/webclient/webclient.c @@ -78,6 +78,8 @@ #define ISO_cr 0x0d #define ISO_space 0x20 +static uint8 g_return; /* Kludge for now */ + static struct webclient_state s; @@ -180,7 +182,7 @@ static char *copy_string(char *dest, const char *src, int len) return dest + len; } -static void senddata(struct uip_driver_s *dev) +static void senddata(struct uip_driver_s *dev, struct uip_conn *conn) { uint16 len; char *getrequest; @@ -203,20 +205,20 @@ static void senddata(struct uip_driver_s *dev) cptr = copy_string(cptr, http_user_agent_fields, strlen(http_user_agent_fields)); - len = s.getrequestleft > uip_mss()? - uip_mss(): + len = s.getrequestleft > uip_mss(conn)? + uip_mss(conn): s.getrequestleft; uip_send(dev, &(getrequest[s.getrequestptr]), len); } } -static void acked(void) +static void acked(struct uip_conn *conn) { uint16 len; if (s.getrequestleft > 0) { - len = s.getrequestleft > uip_mss()? - uip_mss(): + len = s.getrequestleft > uip_mss(conn)? + uip_mss(conn): s.getrequestleft; s.getrequestleft -= len; s.getrequestptr += len; @@ -262,7 +264,7 @@ static uint16 parse_statusline(struct uip_driver_s *dev, uint16 len) } else { - uip_abort(); + g_return = UIP_ABORT; webclient_aborted(); return 0; } @@ -404,63 +406,63 @@ static void newdata(struct uip_driver_s *dev) * event of interest occurs. */ -void uip_interrupt_event(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 - if (uip_connected_event()) + g_return = 0; + + if (uip_connected_event(flags)) { s.timer = 0; s.state = WEBCLIENT_STATE_STATUSLINE; - senddata(dev); + senddata(dev, conn); webclient_connected(); - return; + return g_return; } if (s.state == WEBCLIENT_STATE_CLOSE) { webclient_closed(); - uip_abort(); - return; + return UIP_ABORT; } - if (uip_abort_event()) + if (uip_abort_event(flags)) { webclient_aborted(); } - if (uip_timeout_event()) + if (uip_timeout_event(flags)) { webclient_timedout(); } - if (uip_ack_event()) + if (uip_ack_event(flags)) { s.timer = 0; - acked(); + acked(conn); } - if (uip_newdata_event()) + if (uip_newdata_event(flags)) { s.timer = 0; newdata(dev); } - if (uip_rexmit_event() || uip_newdata_event() || uip_ack_event()) + if (uip_rexmit_event(flags) || uip_newdata_event(flags) || uip_ack_event(flags)) { - senddata(dev); + senddata(dev, conn); } - else if (uip_poll_event()) + else if (uip_poll_event(flags)) { ++s.timer; if (s.timer == WEBCLIENT_TIMEOUT) { webclient_timedout(); - uip_abort(); - return; + return UIP_ABORT; } } - if (uip_close_event()) + if (uip_close_event(flags)) { if (s.httpflag != HTTPFLAG_MOVED) { @@ -476,9 +478,10 @@ void uip_interrupt_event(struct uip_driver_s *dev) #endif if (resolv_query(s.host, &addr) < 0) { - return; + return g_return; } webclient_get(s.host, s.port, s.file); } } + return g_return; } diff --git a/netutils/webserver/httpd.c b/netutils/webserver/httpd.c index 1f6f58df8b..57e60f8723 100644 --- a/netutils/webserver/httpd.c +++ b/netutils/webserver/httpd.c @@ -95,7 +95,7 @@ static void next_scriptstate(struct httpd_state *pstate) pstate->scriptptr = p; } -static void handle_script(struct httpd_state *pstate) +static void handle_script(struct httpd_state *pstate, struct uip_conn *conn) { char *ptr; @@ -122,8 +122,8 @@ static void handle_script(struct httpd_state *pstate) /* See if we find the start of script marker in the block of HTML to be sent. */ - if (pstate->file.len > uip_mss()) { - pstate->len = uip_mss(); + if (pstate->file.len > uip_mss(conn)) { + pstate->len = uip_mss(conn); } else { pstate->len = pstate->file.len; } @@ -136,8 +136,8 @@ static void handle_script(struct httpd_state *pstate) if (ptr != NULL && ptr != pstate->file.data) { pstate->len = (int)(ptr - pstate->file.data); - if (pstate->len >= uip_mss()) { - pstate->len = uip_mss(); + if (pstate->len >= uip_mss(conn)) { + pstate->len = uip_mss(conn); } } send_part_of_file(pstate); @@ -186,7 +186,7 @@ static int send_headers(struct httpd_state *pstate, const char *statushdr) return ret; } -static void handle_output(struct httpd_state *pstate) +static void handle_output(struct httpd_state *pstate, struct uip_conn *conn) { char *ptr; @@ -203,7 +203,7 @@ static void handle_output(struct httpd_state *pstate) ptr = strchr(pstate->filename, ISO_period); if (ptr != NULL && strncmp(ptr, http_shtml, 6) == 0) { - handle_script(pstate); + handle_script(pstate, conn); } else { @@ -266,11 +266,11 @@ static int handle_input(struct httpd_state *pstate) return OK; } -static void handle_connection(struct httpd_state *pstate) +static void handle_connection(struct httpd_state *pstate, struct uip_conn *conn) { handle_input(pstate); if (pstate->state == STATE_OUTPUT) { - handle_output(pstate); + handle_output(pstate, conn); } }