diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2007-09-09 19:47:52 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2007-09-09 19:47:52 +0000 |
commit | 029001d3f18801589c585b190fdc9655bec8e545 (patch) | |
tree | 880c7410b4fbcb43c2dd5cfce6618d4d5b0953e5 /nuttx/net | |
parent | 7a65f932826220c741ffbf5698b48692a787d915 (diff) | |
download | px4-nuttx-029001d3f18801589c585b190fdc9655bec8e545.tar.gz px4-nuttx-029001d3f18801589c585b190fdc9655bec8e545.tar.bz2 px4-nuttx-029001d3f18801589c585b190fdc9655bec8e545.zip |
Implment TCP recv()
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@340 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/net')
-rw-r--r-- | nuttx/net/connect.c | 4 | ||||
-rw-r--r-- | nuttx/net/recvfrom.c | 335 | ||||
-rw-r--r-- | nuttx/net/sendto.c | 19 | ||||
-rw-r--r-- | nuttx/net/uip/Make.defs | 2 | ||||
-rw-r--r-- | nuttx/net/uip/uip-udpconn.c | 96 | ||||
-rw-r--r-- | nuttx/net/uip/uip-wait.c | 131 | ||||
-rw-r--r-- | nuttx/net/uip/uip.c | 4 |
7 files changed, 346 insertions, 245 deletions
diff --git a/nuttx/net/connect.c b/nuttx/net/connect.c index 5bc978fe9..2a9708b9a 100644 --- a/nuttx/net/connect.c +++ b/nuttx/net/connect.c @@ -182,8 +182,6 @@ int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) #ifdef CONFIG_NET_UDP case SOCK_DGRAM: -#warning Put UDP connect logic here -#if 0 { int ret = uip_udpconnect(psock->s_conn, inaddr); if (ret < 0) @@ -194,7 +192,7 @@ int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) } break; #endif -#endif + default: err = EBADF; goto errout; diff --git a/nuttx/net/recvfrom.c b/nuttx/net/recvfrom.c index a8bc59505..401580f37 100644 --- a/nuttx/net/recvfrom.c +++ b/nuttx/net/recvfrom.c @@ -53,6 +53,8 @@ * Definitions ****************************************************************************/ +#define TCP_TIMEO 10 /* Deciseconds after data received before recv() returns */ + /**************************************************************************** * Private Types ****************************************************************************/ @@ -63,27 +65,33 @@ struct recvfrom_s FAR struct socket *rf_sock; /* The parent socket structure */ #endif sem_t rf_sem; /* Semaphore signals recv completion */ - sint16 rf_buflen; /* Length of receive buffer (error if <0) */ + size_t rf_buflen; /* Length of receive buffer */ char *rf_buffer; /* Pointer to receive buffer */ -#if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK) +#ifndef CONFIG_DISABLE_CLOCK uint32 rf_starttime; /* rcv start time for determining timeout */ #endif + size_t rf_recvlen; /* The received length */ + int rf_result; /* OK on success, otherwise a negated errno. */ }; /**************************************************************************** * Private Functions ****************************************************************************/ -void recvfrom_interrupt(void *private) +static void recvfrom_interrupt(void *private) { struct recvfrom_s *pstate = (struct recvfrom_s *)private; - struct uip_udp_conn *udp_conn; + FAR struct socket *psock; size_t recvlen; /* 'private' might be null in some race conditions (?) */ if (pstate) { + /* Get the socket reference from the private data */ + + psock = pstate->rf_sock; + /* If new data is available, then complete the read action. */ if (uip_newdata()) @@ -98,52 +106,155 @@ void recvfrom_interrupt(void *private) recvlen = uip_len; } - /* Copy the appdate into the user data and send it */ + /* Copy the new appdata into the user buffer */ memcpy(pstate->rf_buffer, uip_appdata, recvlen); - /* Don't allow any further call backs. */ + /* Update the accumulated size of the data read */ - udp_conn = (struct uip_udp_conn *)pstate->rf_sock->s_conn; - udp_conn->private = NULL; - udp_conn->callback = NULL; + pstate->rf_recvlen += recvlen; + pstate->rf_buffer += recvlen; + pstate->rf_buflen -= recvlen; - /* Wake up the waiting thread, returning the number of bytes - * actually read. - */ + /* 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; + + /* Don't allow any further UDP call backs. */ + + udp_conn = (struct uip_udp_conn *)psock->s_conn; + udp_conn->private = NULL; + udp_conn->callback = 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; + + /* The TCP receive buffer is full. Return now, perhaps truncating + * the received data (need to fix that). + * + * Don't allow any further TCP call backs. + */ + + conn = (struct uip_conn *)psock->s_conn; + conn->private = NULL; + conn->callback = NULL; + + /* Wake up the waiting thread, returning the number of bytes + * actually read. + */ - pstate->rf_buflen = recvlen; - sem_post(&pstate->rf_sem); + sem_post(&pstate->rf_sem); + } + + /* Reset the timeout. We will want a short timeout to terminate + * the TCP receive. + */ + +#ifndef CONFIG_DISABLE_CLOCK + pstate->rf_starttime = g_system_timer; +#endif } /* 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 (pstate->rf_sock) +#ifndef CONFIG_DISABLE_CLOCK + else { - /* Check if SO_RCVTIMEO has been selected for this socket */ + socktimeo_t timeo; + + /* 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 non... we well let the read hang forever. + */ + + else + { +#ifdef CONFIG_NET_SOCKOPTS + timeo = psock->s_rcvtimeo; +#else + timeo = 0; +#endif + } + + /* Is there an effective timeout? */ - if (pstate->rf_sock->s_rcvtimeo) + if (timeo) { /* Yes.. Check if the timeout has elapsed */ - if (net_timeo(pstate->rf_starttime, pstate->rf_sock->s_rcvtimeo)) + if (net_timeo(pstate->rf_starttime, timeo)) { - /* Don't allow any further call backs. */ + /* Yes.. the timeout has elapsed... do not allow any further + * callbacks + */ + +#ifdef CONFIG_NET_UDP + if (psock->s_type == SOCK_DGRAM) + { + struct uip_udp_conn *udp_conn; + + /* Stop further callbacks */ + + udp_conn = (struct uip_udp_conn *)psock->s_conn; + udp_conn->private = NULL; + udp_conn->callback = NULL; + + /* Report a timeout error */ + + pstate->rf_result = -EAGAIN; + } + else +#endif + { + struct uip_conn *conn; + + conn = (struct uip_conn *)psock->s_conn; + conn->private = NULL; + conn->callback = NULL; + + /* Report an error only if no data has been received */ - udp_conn = (struct uip_udp_conn *)pstate->rf_sock->s_conn; - udp_conn->private = NULL; - udp_conn->callback = NULL; + if (pstate->rf_recvlen == 0) + { + /* Report the timeout error */ - /* Wake up the waiting thread, returning the error -EAGAIN - * that signals the timeout event + pstate->rf_result = -EAGAIN; + } + } + + /* 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). */ - pstate->rf_buflen = -EAGAIN; sem_post(&pstate->rf_sem); - } + } } } #endif @@ -151,6 +262,91 @@ void recvfrom_interrupt(void *private) } /**************************************************************************** + * Function: recvfrom_init + * + * Description: + * Initialize the state structure + * + * Parameters: + * psock Pointer to the socket structure for the socket + * buf Buffer to receive data + * len Length of buffer + * pstate A pointer to the state structure to be initialized + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static void recvfrom_init(FAR struct socket *psock, FAR void *buf, size_t len, + struct recvfrom_s *pstate) +{ + /* Initialize the state structure. */ + + memset(pstate, 0, sizeof(struct recvfrom_s)); + (void)sem_init(&pstate->rf_sem, 0, 0); /* Doesn't really fail */ + pstate->rf_sock = psock; + pstate->rf_buflen = len; + pstate->rf_buffer = buf; + +#ifndef CONFIG_DISABLE_CLOCK + /* Set up the start time for the timeout */ + + pstate->rf_starttime = g_system_timer; +#endif +} + +/**************************************************************************** + * Function: recvfrom_result + * + * Description: + * Evaluate the result of the recv operations + * + * Parameters: + * result The result of the sem_wait operation (may indicate EINTR) + * pstate A pointer to the state structure to be initialized + * + * Returned Value: + * The result of the recv operation with errno set appropriately + * + * Assumptions: + * + ****************************************************************************/ + +static ssize_t recvfrom_result(int result, struct recvfrom_s *pstate) +{ + int save_errno = *get_errno_ptr(); /* In case something we do changes it */ + + /* Release semaphore in the state structure */ + + sem_destroy(&pstate->rf_sem); + + /* Check for a error/timeout detected by the interrupt handler. Errors are + * signaled by negative errno values for the rcv length + */ + + if (pstate->rf_result < 0) + { + /* Return EGAIN on a timeout */ + + return pstate->rf_result; + } + + /* If sem_wait failed, then we were probably reawakened by a signal. In + * this case, sem_wait will have set errno appropriately. + */ + + if (result < 0) + { + return -save_errno; + } + + return pstate->rf_recvlen; +} + +/**************************************************************************** * Function: udp_recvfrom * * Description: @@ -182,7 +378,6 @@ static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, struct uip_udp_conn *udp_conn; struct recvfrom_s state; irqstate_t save; - int err; int ret; /* Perform the UDP recvfrom() operation */ @@ -193,25 +388,15 @@ static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, */ save = irqsave(); - memset(&state, 0, sizeof(struct recvfrom_s)); - (void)sem_init(&state. rf_sem, 0, 0); /* Doesn't really fail */ - state.rf_sock = psock; - state.rf_buflen = len; - state.rf_buffer = buf; - -#if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK) - /* Set up the start time for the timeout */ - - state.rf_starttime = g_system_timer; -#endif + recvfrom_init(psock, buf, len, &state); /* Setup the UDP socket */ - err = uip_udpconnect(psock->s_conn, NULL); - if (err < 0) + ret = uip_udpconnect(psock->s_conn, NULL); + if (ret < 0) { irqrestore(save); - return err; + return ret; } /* Set up the callback in the connection */ @@ -220,6 +405,10 @@ static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, udp_conn->private = (void*)&state; udp_conn->callback = recvfrom_interrupt; + /* Enable the UDP socket */ + + uip_udpenable(psock->s_conn); + /* 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) * interrupts are disabled! They will be re-enabled while the task sleeps @@ -230,33 +419,13 @@ static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, /* Make sure that no further interrupts are processed */ + uip_udpdisable(psock->s_conn); udp_conn->private = NULL; udp_conn->callback = NULL; - sem_destroy(&state. rf_sem); irqrestore(save); - /* Check for a error/timeout detected by the interrupt handler. Errors are - * signaled by negative errno values for the rcv length - */ - - if (state.rf_buflen < 0) - { - /* Return EGAIN on a timeout */ - - return state.rf_buflen; - } - - /* If sem_wait failed, then we were probably reawakened by a signal. In - * this case, sem_wait will have set errno appropriately. - */ - - if (ret < 0) - { - return -*get_errno_ptr(); - } - #warning "Needs to return server address" - return state.rf_buflen; + return recvfrom_result(ret, &state); } #endif /* CONFIG_NET_UDP */ @@ -288,6 +457,11 @@ static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, FAR const struct sockaddr_in *infrom ) #endif { + struct uip_conn *conn; + struct recvfrom_s state; + irqstate_t save; + int ret; + /* Verify that the SOCK_STREAM has been connected */ if (_SS_ISCONNECTED(psock->s_flags)) @@ -297,8 +471,37 @@ static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, return -ENOTCONN; } -#warning "TCP/IP recv not implemented" - return -ENOSYS; + + /* Initialize the state structure. This is done with interrupts + * disabled because we don't want anything to happen until we + * are ready. + */ + + save = irqsave(); + recvfrom_init(psock, buf, len, &state); + + /* Set up the callback in the connection */ + + conn = (struct uip_conn *)psock->s_conn; + conn->private = (void*)&state; + conn->callback = recvfrom_interrupt; + + /* 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) + * interrupts are disabled! They will be re-enabled while the task sleeps + * and automatically re-enabled when the task restarts. + */ + + ret = sem_wait(&state. rf_sem); + + /* Make sure that no further interrupts are processed */ + + conn->private = NULL; + conn->callback = NULL; + irqrestore(save); + +#warning "Needs to return server address" + return recvfrom_result(ret, &state); } /**************************************************************************** diff --git a/nuttx/net/sendto.c b/nuttx/net/sendto.c index bba9c5b47..b14f301a2 100644 --- a/nuttx/net/sendto.c +++ b/nuttx/net/sendto.c @@ -244,9 +244,26 @@ ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, udp_conn = (struct uip_udp_conn *)psock->s_conn; udp_conn->private = (void*)&state; udp_conn->callback = sendto_interrupt; - irqrestore(save); + + /* Enable the UDP socket */ + + uip_udpenable(psock->s_conn); + + /* 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) + * interrupts are disabled! They will be re-enabled while the task sleeps + * and automatically re-enabled when the task restarts. + */ sem_wait(&state.st_sem); + + /* Make sure that no further interrupts are processed */ + + uip_udpdisable(psock->s_conn); + udp_conn->private = NULL; + udp_conn->callback = NULL; + irqrestore(save); + sem_destroy(&state.st_sem); /* Set the socket state to idle */ diff --git a/nuttx/net/uip/Make.defs b/nuttx/net/uip/Make.defs index 4ad51f9bc..628b39638 100644 --- a/nuttx/net/uip/Make.defs +++ b/nuttx/net/uip/Make.defs @@ -35,5 +35,5 @@ UIP_ASRCS = UIP_CSRCS = uip-arp.c uip.c uip-fw.c uip-neighbor.c uip-split.c \ - uip-tcpconn.c uip-udpconn.c uip-wait.c + uip-tcpconn.c uip-udpconn.c diff --git a/nuttx/net/uip/uip-udpconn.c b/nuttx/net/uip/uip-udpconn.c index 6ed0f6eb9..8c88a9bc0 100644 --- a/nuttx/net/uip/uip-udpconn.c +++ b/nuttx/net/uip/uip-udpconn.c @@ -114,34 +114,26 @@ static inline void _uip_semtake(sem_t *sem) * * Description: * Find the UDP connection that uses this local port number. Called only - * from user, non-interrupt level logic. + * from user user level code, but with interrupts disabled. * ****************************************************************************/ -struct uip_udp_conn *uip_find_conn( uint16 portno ) +static inline struct uip_udp_conn *uip_find_conn( uint16 portno ) { - struct uip_udp_conn *conn; uint16 nlastport = htons(g_last_udp_port); - irqstate_t flags; + int i; - /* Now search each active connection structure. This list is modifiable - * from interrupt level, we we must diable interrupts to access it safely. - */ + /* Now search each connection structure.*/ - flags = irqsave(); - conn = (struct uip_udp_conn *)g_active_udp_connections.head; - while (conn) + for (i = 0; i < UIP_UDP_CONNS; i++) { - if (conn->lport == nlastport) + if (g_udp_connections[ i ].lport == nlastport) { - break; + return &g_udp_connections[ i ]; } - - conn = (struct uip_udp_conn *)conn->node.flink; } - irqrestore(flags); - return conn; + return NULL; } /**************************************************************************** @@ -198,7 +190,7 @@ struct uip_udp_conn *uip_udpalloc(void) conn = (struct uip_udp_conn *)dq_remfirst(&g_free_udp_connections); if (conn) { - /* Make sure that the connectin is marked as uninitialized */ + /* Make sure that the connection is marked as uninitialized */ conn->lport = 0; } @@ -211,25 +203,13 @@ struct uip_udp_conn *uip_udpalloc(void) * * Description: * Free a UDP connection structure that is no longer in use. This should be - * done by the implementation of close() + * done by the implementation of close(). uip_udpdisable must have been + * previously called. * ****************************************************************************/ void uip_udpfree(struct uip_udp_conn *conn) { - irqstate_t flags; - - /* The active list is accessed from the interrupt level and me must be - * certain that no interrupts occur while the active list is modified. - */ - - flags = irqsave(); - if (conn->lport != 0) - { - dq_rem(&conn->node, &g_active_udp_connections); - } - irqrestore(flags); - /* The free list is only accessed from user, non-interrupt level and * is protected by a semaphore (that behaves like a mutex). */ @@ -308,14 +288,25 @@ void uip_udppoll(unsigned int conn) uip_interrupt(UIP_UDP_TIMER); } -/* This function sets up a new UDP connection. The function will +/**************************************************************************** + * Name: uip_udpconnect() + * + * Description: + * This function sets up a new UDP connection. The function will * automatically allocate an unused local port for the new * connection. However, another port can be chosen by using the * uip_udpbind() call, after the uip_udpconnect() function has been * called. * + * uip_udpenable() must be called before the connection is made active (i.e., + * is eligible for callbacks. + * * addr The address of the remote host. - */ + * + * Assumptions: + * This function is called user code. Interrupts may be enabled. + * + ****************************************************************************/ #ifdef CONFIG_NET_IPv6 int uip_udpconnect(struct uip_udp_conn *conn, const struct sockaddr_in6 *addr) @@ -329,6 +320,7 @@ int uip_udpconnect(struct uip_udp_conn *conn, const struct sockaddr_in *addr) * number that is not being used by any other connection. */ + flags = irqsave(); do { /* Guess that the next available port number will be the one after @@ -348,6 +340,7 @@ int uip_udpconnect(struct uip_udp_conn *conn, const struct sockaddr_in *addr) /* Initialize and return the connection structure, bind it to the port number */ conn->lport = HTONS(g_last_udp_port); + irqrestore(flags); if (addr) { @@ -356,21 +349,46 @@ int uip_udpconnect(struct uip_udp_conn *conn, const struct sockaddr_in *addr) } else { - conn->rport = 0; - uip_ipaddr_copy(&conn->ripaddr, &all_zeroes_addr); - } + conn->rport = 0; + uip_ipaddr_copy(&conn->ripaddr, &all_zeroes_addr); + } conn->ttl = UIP_TTL; + return OK; +} + +/**************************************************************************** + * Name: uip_udpenable() uip_udpdisable. + * + * Description: + * Enable/disable callbacks for the specified connection + * + * Assumptions: + * This function is called user code. Interrupts may be enabled. + * + ****************************************************************************/ - /* Now add the connection structure to the active connectionlist. This list +void uip_udpenable(struct uip_udp_conn *conn) +{ + /* Add the connection structure to the active connectionlist. This list * is modifiable from interrupt level, we we must diable interrupts to * access it safely. */ - flags = irqsave(); + irqstate_t flags = irqsave(); dq_addlast(&conn->node, &g_active_udp_connections); irqrestore(flags); +} - return OK; +void uip_udpdisable(struct uip_udp_conn *conn) +{ + /* Remove the connection structure to the active connectionlist. This list + * is modifiable from interrupt level, we we must diable interrupts to + * access it safely. + */ + + irqstate_t flags = irqsave(); + dq_rem(&conn->node, &g_active_udp_connections); + irqrestore(flags); } #endif /* CONFIG_NET && CONFIG_NET_UDP */ diff --git a/nuttx/net/uip/uip-wait.c b/nuttx/net/uip/uip-wait.c deleted file mode 100644 index 14775f54e..000000000 --- a/nuttx/net/uip/uip-wait.c +++ /dev/null @@ -1,131 +0,0 @@ -/************************************************************ - * uip-wait.c - * - * Copyright (C) 2007 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <spudmonkey@racsa.co.cr> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ************************************************************/ - -/************************************************************ - * Included Files - ************************************************************/ - -#include <nuttx/config.h> -#include <semaphore.h> -#include <arch/irq.h> -#include <net/uip/uip.h> - -/************************************************************ - * Definitions - ************************************************************/ - -/************************************************************ - * Private Data - ************************************************************/ - -/* Threads and tasks can both wait a semaphore. This - * initializer uses internal, non-portable knowledge of the\ - * structure of sem_t to initialize it to the value 0. - */ - -static sem_t uip_waitsem = { 0 }; /* Semaphore to wait on */ -static uint16 uip_waitflags = 0; /* UIP flags to wait for */ - -/************************************************************ - * Private Functions - ************************************************************/ - -/************************************************************ - * Global Functions - ************************************************************/ - -/* This function is called user code to set up the wait */ - -int uip_event_wait(uint16 waitflags) -{ - /* Prevent conflicts with the interrupt level operation of - * uip_event_signal(). - */ - irqstate_t save = irqsave(); - - /* At present, we support only a single waiter. If uip_waitflags - * is non-zero on entry, then there is a problem. - */ - - if ( uip_waitflags == 0) - { - /* If the requested event bits are not set in the uip_flags, - * then wait. We will be awakened as soon as an interrupt is - * received that sets these bits. - */ - - goto errout_with_irqdisabled; - } - - /* Loop until the requested bits are set in the flags */ - - while ((waitflags & uip_flags) != 0) - { - /* Set the event flags that the caller is waiting on */ - - uip_waitflags = waitflags; - - /* Wait for the event to occur */ - - if (sem_wait(&uip_waitsem) != 0) - { - goto errout_with_irqdisabled; - } - } - - irqrestore(save); - return OK; - -errout_with_irqdisabled: - irqrestore(save); - return ERROR; -} - -/* This function is called from uip_interrupt() to wake up any - * waiting threads/tasks. - */ - -void uip_event_signal(void) -{ - /* If any bits in uip_waitflags match bits set in uip_flags, then - * there must be a thread/task waiting for this event to occur. - */ - - if ((uip_waitflags & uip_flags) != 0) - { - sem_post(&uip_waitsem); /* Post the event */ - uip_waitflags = 0; /* Prohibit posting the event multiple times */ - } -} diff --git a/nuttx/net/uip/uip.c b/nuttx/net/uip/uip.c index 2175ebc05..b607fecf7 100644 --- a/nuttx/net/uip/uip.c +++ b/nuttx/net/uip/uip.c @@ -595,8 +595,6 @@ static void uip_add_rcv_nxt(uint16 n) static void uip_udp_callback(void) { - uip_event_signal(); - /* Some sanity checking */ if (uip_udp_conn && uip_udp_conn->callback) @@ -609,8 +607,6 @@ static void uip_udp_callback(void) static void uip_tcp_callback(void) { - uip_event_signal(); - /* Some sanity checking */ if (uip_conn && uip_conn->callback) |