Skip to content
Snippets Groups Projects
Commit c9d98ea4 authored by Gregory Nutt's avatar Gregory Nutt
Browse files

Implement UDP sendto() timeouts. Currently disabled because it probably unnecessary.

parent fad8a2b5
No related branches found
No related tags found
No related merge requests found
......@@ -4639,5 +4639,7 @@
6.28 2013-xx-xx Gregory Nutt <gnutt@nuttx.org>
* arch/arm/src/lpc17xx/lpc17_i2c.c: Interrupts were not being
re-enabled in the I2C intializatin function.
re-enabled in the I2C intializatin function (2013-4-30).
* net/sendto.c: Added skeleton of implementation of send timeouts
for UDP. However, this functionality really does not make
sense, so it is disabled in the code (2013-4-30).
......@@ -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);
}
......
/****************************************************************************
* 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,17 +83,61 @@
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) */
};
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* 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
*
......@@ -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;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment