summaryrefslogtreecommitdiff
path: root/nuttx/net/sendto.c
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2008-09-01 15:22:54 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2008-09-01 15:22:54 +0000
commitbe49f2a7430aa0dd9c0c09002af15bb2618cadb0 (patch)
treea4e4aa6be32a7606a0f2a3cfdc429f0543bbe8c2 /nuttx/net/sendto.c
parent17edc87d5eadbdcd81add3cd4ff8941fee253e14 (diff)
downloadnuttx-be49f2a7430aa0dd9c0c09002af15bb2618cadb0.tar.gz
nuttx-be49f2a7430aa0dd9c0c09002af15bb2618cadb0.tar.bz2
nuttx-be49f2a7430aa0dd9c0c09002af15bb2618cadb0.zip
Verify UDP support
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@859 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/net/sendto.c')
-rw-r--r--nuttx/net/sendto.c69
1 files changed, 44 insertions, 25 deletions
diff --git a/nuttx/net/sendto.c b/nuttx/net/sendto.c
index 89133d200..519510fe6 100644
--- a/nuttx/net/sendto.c
+++ b/nuttx/net/sendto.c
@@ -1,7 +1,7 @@
/****************************************************************************
* net/sendto.c
*
- * Copyright (C) 2007 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
@@ -49,6 +49,7 @@
#include <net/uip/uip-arch.h>
#include "net-internal.h"
+#include "uip/uip-internal.h"
/****************************************************************************
* Definitions
@@ -60,7 +61,7 @@
struct sendto_s
{
- FAR struct uip_callback_s *snd_cb; /* Reference to callback instance */
+ FAR struct uip_callback_s *st_cb; /* Reference to callback instance */
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 */
@@ -79,12 +80,13 @@ struct sendto_s
* send operation when polled by the uIP layer.
*
* 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
+ * dev The sructure of the network driver that caused the interrupt
+ * conn An instance of the UDP connection structure cast to void *
+ * pvprivate An instance of struct sendto_s cast to void*
+ * flags Set of events describing why the callback was invoked
*
* Returned Value:
- * None
+ * Modified value of the input flags
*
* Assumptions:
* Running at the interrupt level
@@ -92,9 +94,9 @@ struct sendto_s
****************************************************************************/
#ifdef CONFIG_NET_UDP
-void sendto_interrupt(struct uip_driver_s *dev, struct uip_udp_conn *conn, uint8 flags)
+uint16 sendto_interrupt(struct uip_driver_s *dev, void *conn, void *pvprivate, uint16 flags)
{
- struct sendto_s *pstate = (struct sendto_s *)conn->private;
+ struct sendto_s *pstate = (struct sendto_s *)pvprivate;
nvdbg("flags: %04x\n", flags);
if (pstate)
@@ -107,9 +109,23 @@ void sendto_interrupt(struct uip_driver_s *dev, struct uip_udp_conn *conn, uint8
pstate->st_sndlen = -ENOTCONN;
}
+
+ /* Check if the outgoing packet is available (it may have been claimed
+ * by a sendto interrupt serving a different thread.
+ */
+
+ else if (dev->d_sndlen > 0)
+ {
+ /* Another thread has beat us sending data, wait for the next poll */
+
+ return flags;
+ }
+
+ /* It looks like we are good to send the data */
+
else
{
- /* No.. Copy the user data into d_snddata and send it */
+ /* Copy the user data into d_snddata and send it */
uip_send(dev, pstate->st_buffer, pstate->st_buflen);
pstate->st_sndlen = pstate->st_buflen;
@@ -125,6 +141,8 @@ void sendto_interrupt(struct uip_driver_s *dev, struct uip_udp_conn *conn, uint8
sem_post(&pstate->st_sem);
}
+
+ return flags;
}
#endif
@@ -202,6 +220,7 @@ ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
{
FAR struct socket *psock;
#ifdef CONFIG_NET_UDP
+ FAR struct uip_udp_conn *conn;
#ifdef CONFIG_NET_IPv6
FAR const struct sockaddr_in6 *into = (const struct sockaddr_in6 *)to;
#else
@@ -277,7 +296,8 @@ ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
/* Setup the UDP socket */
- ret = uip_udpconnect(psock->s_conn, into);
+ conn = (struct uip_udp_conn *)psock->s_conn;
+ ret = uip_udpconnect(conn, into);
if (ret < 0)
{
irqrestore(save);
@@ -287,34 +307,33 @@ ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
/* Set up the callback in the connection */
- state.st_cb = uip_udpcallbackalloc((struct uip_udp_conn *)psock->s_conn);
+ state.st_cb = uip_udpcallbackalloc(conn);
if (state.st_cb)
{
state.st_cb->flags = UIP_POLL|UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT;
- state.st_cb->flags = 0;
state.st_cb->private = (void*)&state;
state.st_cb->event = sendto_interrupt;
- /* Enable the UDP socket */
+ /* Enable the UDP socket */
- uip_udpenable(psock->s_conn);
+ uip_udpenable(conn);
- /* Notify the device driver of the availabilty of TX data */
+ /* Notify the device driver of the availabilty of TX data */
- netdev_txnotify(&udp_conn->ripaddr);
+ netdev_txnotify(&conn->ripaddr);
- /* 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.
- */
+ /* 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);
+ sem_wait(&state.st_sem);
- /* Make sure that no further interrupts are processed */
+ /* Make sure that no further interrupts are processed */
- uip_udpdisable(psock->s_conn);
- uip_udpcallbackfree(psock->s_conn, state.st_cb);
+ uip_udpdisable(conn);
+ uip_udpcallbackfree(conn, state.st_cb);
}
irqrestore(save);