diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2007-09-08 21:54:43 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2007-09-08 21:54:43 +0000 |
commit | 255e1fe83691a2c5a3328bcec13e2bce0a140696 (patch) | |
tree | 9868873a70e46df85e9ec0cf7c599239808b8808 /nuttx/net | |
parent | b084f0f30622b823a1cb99324505aaca673ccef1 (diff) | |
download | px4-nuttx-255e1fe83691a2c5a3328bcec13e2bce0a140696.tar.gz px4-nuttx-255e1fe83691a2c5a3328bcec13e2bce0a140696.tar.bz2 px4-nuttx-255e1fe83691a2c5a3328bcec13e2bce0a140696.zip |
Added receive timeout via setsockopt(SO_RCVTIMEO)
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@336 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/net')
-rw-r--r-- | nuttx/net/recvfrom.c | 102 | ||||
-rw-r--r-- | nuttx/net/sendto.c | 6 | ||||
-rw-r--r-- | nuttx/net/uip/uip-wait.c | 55 |
3 files changed, 82 insertions, 81 deletions
diff --git a/nuttx/net/recvfrom.c b/nuttx/net/recvfrom.c index d6d8b4aca..d008262bf 100644 --- a/nuttx/net/recvfrom.c +++ b/nuttx/net/recvfrom.c @@ -58,9 +58,15 @@ struct recvfrom_s { - sem_t rf_sem; - uint16 rf_buflen; - char * rf_buffer; +#if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK) + 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) */ + char *rf_buffer; /* Pointer to receive buffer */ +#if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK) + uint32 rf_starttime; /* rcv start time for determining timeout */ +#endif }; /**************************************************************************** @@ -72,38 +78,61 @@ void recvfrom_interrupt(void *private) struct recvfrom_s *pstate = (struct recvfrom_s *)private; size_t recvlen; - /* If new data is available and we are correctly intialized, then complete - * the read action. We could also check for POLL events here in order to - * implement SO_RECVTIMEO. - */ + /* 'private' might be null in some race conditions (?) */ - if (uip_newdata() && private) + if (pstate) { - /* Get the length of the data to return */ - if (uip_len > pstate-> rf_buflen) - { - recvlen = pstate-> rf_buflen; - } - else + /* If new data is available, then complete the read action. */ + + if (uip_newdata()) { - recvlen = uip_len; - } + /* Get the length of the data to return */ + if (uip_len > pstate-> rf_buflen) + { + recvlen = pstate-> rf_buflen; + } + else + { + recvlen = uip_len; + } + + /* Copy the appdate into the user data and send it */ - /* Copy the appdate into the user data and send it */ + memcpy(pstate->rf_buffer, uip_appdata, recvlen); - memcpy(pstate->rf_buffer, uip_appdata, recvlen); + /* Don't allow any further call backs. */ - /* Don't allow any further call backs. */ + uip_conn->private = NULL; + uip_conn->callback = NULL; - uip_conn->private = NULL; - uip_conn->callback = NULL; + /* Wake up the waiting thread, returning the number of bytes + * actually read. + */ - /* Wake up the waiting thread, returning the number of bytes - * actually read. + pstate->rf_buflen = recvlen; + sem_post(&pstate-> rf_sem); + } + + /* No data has been received. If this is a poll event, then check + * for a timeout. */ - pstate->rf_buflen = recvlen; - sem_post(&pstate-> rf_sem); +#if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK) + else if (uip_newdata() && pstate->rf_sock) + { + /* Check if SO_RCVTIMEO has been selected for this socket */ + + uint rcvtimeo = ; + if (pstate->rf_sock->s_rcvtimeo) + { + /* Yes.. Check if the timeout has elapsed */ + + if (net_timeo(pstate->rf_starttime, pstate->rf_sock->s_rcvtimeo)) + { + } + } + } +#endif } } @@ -213,6 +242,12 @@ ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr * 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 + /* Setup the UDP socket */ ret = uip_udpconnect(psock->s_conn, NULL); @@ -244,6 +279,20 @@ ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr * sem_destroy(&state. rf_sem); irqrestore(save); + /* Check for a timeout. Errors are signaled by negative errno values + * for the rcv length + */ + +#if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK) + if (state.rf_buflen < 0) + { + /* Return EGAIN on a timeout */ + + err = -state.rf_buflen; + goto errout; + } +#endif + /* If sem_wait failed, then we were probably reawakened by a signal. In * this case, sem_wait will have set errno appropriately. */ @@ -253,8 +302,9 @@ ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr * return ERROR; } - return state.rf_buflen; #warning "Needs to return server address" + return state.rf_buflen; + #else err = ENOSYS; #endif diff --git a/nuttx/net/sendto.c b/nuttx/net/sendto.c index 1917ebf58..eef1a31b4 100644 --- a/nuttx/net/sendto.c +++ b/nuttx/net/sendto.c @@ -58,9 +58,9 @@ struct sendto_s { - sem_t st_sem; - uint16 st_buflen; - const char *st_buffer; + sem_t st_sem; /* Semaphore signals sendto completion */ + uint16 st_buflen; /* Length of send buffer (error if <0) */ + const char *st_buffer; /* Pointer to send buffer */ }; /**************************************************************************** diff --git a/nuttx/net/uip/uip-wait.c b/nuttx/net/uip/uip-wait.c index c7bf0a1bb..14775f54e 100644 --- a/nuttx/net/uip/uip-wait.c +++ b/nuttx/net/uip/uip-wait.c @@ -39,7 +39,6 @@ #include <nuttx/config.h> #include <semaphore.h> -#include <wdog.h> #include <arch/irq.h> #include <net/uip/uip.h> @@ -63,31 +62,18 @@ static uint16 uip_waitflags = 0; /* UIP flags to wait for */ * Private Functions ************************************************************/ -/* Called from the timer interrupt handler when a event wait - * watchdog expires. - */ - -static void uip_event_timeout(int argc, uint32 itcb, ...) -{ - irqstate_t save = irqsave(); /* Should not be necessary */ - uip_flags |= UIP_APPTIMEOUT; /* Set software timeout event */ - uip_event_signal(); /* Signal the waiting thread/task */ - irqrestore(save); /* Restore interrupts */ -} - /************************************************************ * Global Functions ************************************************************/ /* This function is called user code to set up the wait */ -int uip_event_timedwait(uint16 waitflags, int timeout) +int uip_event_wait(uint16 waitflags) { /* Prevent conflicts with the interrupt level operation of * uip_event_signal(). */ irqstate_t save = irqsave(); - WDOG_ID wdog; /* At present, we support only a single waiter. If uip_waitflags * is non-zero on entry, then there is a problem. @@ -111,52 +97,17 @@ int uip_event_timedwait(uint16 waitflags, int timeout) uip_waitflags = waitflags; - /* Was a timeut requested as well? */ - - if (timeout) - { - /* Yes, then set the application timeout event as well */ - - uip_waitflags |= UIP_APPTIMEOUT; - - /* Create a watchdog */ - - wdog = wd_create(); - if (!wdog) - { - goto errout_with_irqdisabled; - } - - /* Start the watchdog */ - - wd_start(wdog, timeout, (wdentry_t)uip_event_timeout, 0); - } - - /* Wait for the event (or timeout) to occur */ + /* Wait for the event to occur */ if (sem_wait(&uip_waitsem) != 0) { - goto errout_with_watchdog; - } - - /* We no longer need the watchdog */ - - if (wdog) - { - wd_delete(wdog); - wdog = NULL; + goto errout_with_irqdisabled; } } irqrestore(save); return OK; -errout_with_watchdog: - if (wdog) - { - wd_delete(wdog); - } - errout_with_irqdisabled: irqrestore(save); return ERROR; |