diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2013-04-30 08:12:54 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2013-04-30 08:12:54 -0600 |
commit | 0a925b25adf3c6aa533f0ddbff298ad3d6fb344b (patch) | |
tree | 0c7567a0a2a1de65def4ba1aa3ba9dfc4e310cd5 /nuttx/net | |
parent | 4b6733594977f659fea662cfa3721f72c89da367 (diff) | |
download | px4-nuttx-0a925b25adf3c6aa533f0ddbff298ad3d6fb344b.tar.gz px4-nuttx-0a925b25adf3c6aa533f0ddbff298ad3d6fb344b.tar.bz2 px4-nuttx-0a925b25adf3c6aa533f0ddbff298ad3d6fb344b.zip |
Implement UDP sendto() timeouts. Currently disabled because it probably unnecessary.
Diffstat (limited to 'nuttx/net')
-rw-r--r-- | nuttx/net/send.c | 21 | ||||
-rw-r--r-- | nuttx/net/sendto.c | 111 |
2 files changed, 110 insertions, 22 deletions
diff --git a/nuttx/net/send.c b/nuttx/net/send.c index b26a0e5bb..37f5bb8ed 100644 --- a/nuttx/net/send.c +++ b/nuttx/net/send.c @@ -89,7 +89,7 @@ struct send_s uint32_t snd_isn; /* Initial sequence number */ uint32_t snd_acked; /* The number of bytes acked */ #if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK) - uint32_t snd_time; /* last send time for determining timeout */ + uint32_t snd_time; /* Last send time for determining timeout */ #endif #if defined(CONFIG_NET_TCP_SPLIT) bool snd_odd; /* True: Odd packet in pair transaction */ @@ -118,7 +118,7 @@ struct send_s ****************************************************************************/ #if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK) -static inline int send_timeout(struct send_s *pstate) +static inline int send_timeout(FAR struct send_s *pstate) { FAR struct socket *psock = 0; @@ -160,11 +160,11 @@ static inline int send_timeout(struct send_s *pstate) * ****************************************************************************/ -static uint16_t send_interrupt(struct uip_driver_s *dev, void *pvconn, - void *pvpriv, uint16_t flags) +static uint16_t send_interrupt(FAR struct uip_driver_s *dev, FAR void *pvconn, + FAR void *pvpriv, uint16_t flags) { - struct uip_conn *conn = (struct uip_conn*)pvconn; - struct send_s *pstate = (struct send_s *)pvpriv; + FAR struct uip_conn *conn = (FAR struct uip_conn*)pvconn; + FAR struct send_s *pstate = (FAR struct send_s *)pvpriv; nllvdbg("flags: %04x acked: %d sent: %d\n", flags, pstate->snd_acked, pstate->snd_sent); @@ -501,7 +501,8 @@ end_wait: * ****************************************************************************/ -ssize_t psock_send(FAR struct socket *psock, const void *buf, size_t len, int flags) +ssize_t psock_send(FAR struct socket *psock, FAR const void *buf, size_t len, + int flags) { struct send_s state; uip_lock_t save; @@ -561,7 +562,7 @@ ssize_t psock_send(FAR struct socket *psock, const void *buf, size_t len, int fl conn->unacked = 0; - /* Update the initial time for calculating timeouts */ + /* Set the initial time for calculating timeouts */ #if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK) state.snd_time = clock_systimer(); @@ -622,7 +623,7 @@ ssize_t psock_send(FAR struct socket *psock, const void *buf, size_t len, int fl return state.snd_sent; errout: - *get_errno_ptr() = err; + set_errno(err); return ERROR; } @@ -690,7 +691,7 @@ errout: * ****************************************************************************/ -ssize_t send(int sockfd, const void *buf, size_t len, int flags) +ssize_t send(int sockfd, FAR const void *buf, size_t len, int flags) { return psock_send(sockfd_socket(sockfd), buf, len, flags); } diff --git a/nuttx/net/sendto.c b/nuttx/net/sendto.c index 320eacc19..9ac781e17 100644 --- a/nuttx/net/sendto.c +++ b/nuttx/net/sendto.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/sendto.c * - * Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011-2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without @@ -47,14 +47,35 @@ #include <errno.h> #include <debug.h> #include <arch/irq.h> + +#include <nuttx/clock.h> #include <nuttx/net/uip/uip-arch.h> #include "net_internal.h" #include "uip/uip_internal.h" /**************************************************************************** - * Definitions + * Pre-processor Definitions ****************************************************************************/ +/* timeouts on sendto() do not make sense. Each polling cycle from the + * driver is an opportunity to send a packet. If the driver is not polling, + * then the network is not up (and there is not polling cycles to drive + * the timeout). + * + * There is a remote possibility that if there is a lot of other network + * traffic that a UDP sendto could get delayed, but I would not expect this + * generate a timeout. + */ + +#undef CONFIG_NET_SENDTO_TIMEOUT + +/* If supported, the sendto timeout function would depend on socket options + * and a system clock. + */ + +#if !defined(CONFIG_NET_SOCKOPTS) || defined(CONFIG_DISABLE_CLOCK) +# undef CONFIG_NET_SENDTO_TIMEOUT +#endif /**************************************************************************** * Private Types @@ -62,11 +83,15 @@ struct sendto_s { +#ifdef CONFIG_NET_SENDTO_TIMEOUT + FAR struct socket *st_sock; /* Points to the parent socket structure */ + uint32_t st_time; /* Last send time for determining timeout */ +#endif FAR struct uip_callback_s *st_cb; /* Reference to callback instance */ - sem_t st_sem; /* Semaphore signals sendto completion */ - uint16_t st_buflen; /* Length of send buffer (error if <0) */ - const char *st_buffer; /* Pointer to send buffer */ - int st_sndlen; /* Result of the send (length sent or negated errno) */ + sem_t st_sem; /* Semaphore signals sendto completion */ + uint16_t st_buflen; /* Length of send buffer (error if <0) */ + const char *st_buffer; /* Pointer to send buffer */ + int st_sndlen; /* Result of the send (length sent or negated errno) */ }; /**************************************************************************** @@ -74,6 +99,46 @@ struct sendto_s ****************************************************************************/ /**************************************************************************** + * Function: send_timeout + * + * Description: + * Check for send timeout. + * + * Parameters: + * pstate send state structure + * + * Returned Value: + * TRUE:timeout FALSE:no timeout + * + * Assumptions: + * Running at the interrupt level + * + ****************************************************************************/ + +#ifdef CONFIG_NET_SENDTO_TIMEOUT +static inline int send_timeout(FAR struct sendto_s *pstate) +{ + FAR struct socket *psock = 0; + + /* Check for a timeout configured via setsockopts(SO_SNDTIMEO). + * If none... we well let the send wait forever. + */ + + psock = pstate->st_sock; + if (psock && psock->s_sndtimeo != 0) + { + /* Check if the configured timeout has elapsed */ + + return net_timeo(pstate->st_time, psock->s_sndtimeo); + } + + /* No timeout */ + + return FALSE; +} +#endif /* CONFIG_NET_SENDTO_TIMEOUT */ + +/**************************************************************************** * Function: sendto_interrupt * * Description: @@ -98,12 +163,12 @@ struct sendto_s static uint16_t sendto_interrupt(struct uip_driver_s *dev, void *conn, void *pvpriv, uint16_t flags) { - struct sendto_s *pstate = (struct sendto_s *)pvpriv; + FAR struct sendto_s *pstate = (FAR struct sendto_s *)pvpriv; nllvdbg("flags: %04x\n", flags); if (pstate) { - /* Check if the outgoing packet is available (it may have been claimed + /* Check if the outgoing packet is available. It may have been claimed * by a sendto interrupt serving a different thread -OR- if the output * buffer currently contains unprocessed incoming data. In these cases * we will just have to wait for the next polling cycle. @@ -112,10 +177,25 @@ static uint16_t sendto_interrupt(struct uip_driver_s *dev, void *conn, if (dev->d_sndlen > 0 || (flags & UIP_NEWDATA) != 0) { /* Another thread has beat us sending data or the buffer is busy, - * wait for the next polling cycle + * Check for a timeout. If not timed out, wait for the next + * polling cycle and check again. */ - return flags; +#ifdef CONFIG_NET_SENDTO_TIMEOUT + if (send_timeout(pstate)) + { + /* Yes.. report the timeout */ + + nlldbg("SEND timeout\n"); + pstate->st_sndlen = -ETIMEDOUT; + } + else +#endif /* CONFIG_NET_SENDTO_TIMEOUT */ + { + /* No timeout. Just wait for the next polling cycle */ + + return flags; + } } /* It looks like we are good to send the data */ @@ -283,12 +363,19 @@ ssize_t psock_sendto(FAR struct socket *psock, FAR const void *buf, * are ready. */ - save = uip_lock(); + save = uip_lock(); memset(&state, 0, sizeof(struct sendto_s)); sem_init(&state.st_sem, 0, 0); state.st_buflen = len; state.st_buffer = buf; + /* Set the initial time for calculating timeouts */ + +#ifdef CONFIG_NET_SENDTO_TIMEOUT + state.st_sock = psock; + state.st_time = clock_systimer(); +#endif + /* Setup the UDP socket */ conn = (struct uip_udp_conn *)psock->s_conn; @@ -354,7 +441,7 @@ ssize_t psock_sendto(FAR struct socket *psock, FAR const void *buf, #endif errout: - errno = err; + set_errno(err); return ERROR; } |