summaryrefslogtreecommitdiff
path: root/nuttx/net/sendto.c
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2007-09-15 22:45:45 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2007-09-15 22:45:45 +0000
commit42027d080b72b8198072e7dc3933d8b70b6b40a5 (patch)
treed471d699ed674cbc615d89cd830e83c1b61d9eea /nuttx/net/sendto.c
parent8bd136d2202c6706ac2166a31b90f1ec18139dea (diff)
downloadpx4-nuttx-42027d080b72b8198072e7dc3933d8b70b6b40a5.tar.gz
px4-nuttx-42027d080b72b8198072e7dc3933d8b70b6b40a5.tar.bz2
px4-nuttx-42027d080b72b8198072e7dc3933d8b70b6b40a5.zip
Add basic structure to support multiple network interfaces
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@343 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/net/sendto.c')
-rw-r--r--nuttx/net/sendto.c68
1 files changed, 56 insertions, 12 deletions
diff --git a/nuttx/net/sendto.c b/nuttx/net/sendto.c
index b14f301a2..0d03252f5 100644
--- a/nuttx/net/sendto.c
+++ b/nuttx/net/sendto.c
@@ -45,6 +45,7 @@
#include <string.h>
#include <errno.h>
#include <arch/irq.h>
+#include <net/uip/uip-arch.h>
#include "net-internal.h"
@@ -61,32 +62,64 @@ struct sendto_s
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 */
+ int st_sndlen; /* Result of the send (length sent or negated errno) */
};
/****************************************************************************
* Private Functions
****************************************************************************/
-void sendto_interrupt(void *private)
+/****************************************************************************
+ * Function: sendto_interrupt
+ *
+ * Description:
+ * This function is called from the interrupt level to perform the actual
+ * 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*
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ * Running at the interrupt level
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_UDP
+void sendto_interrupt(struct uip_driver_s *dev, void *private)
{
struct sendto_s *pstate = (struct sendto_s *)private;
if (private)
{
- /* Copy the user data into appdata and send it */
+ /* Check if the connectin was rejected */
+
+ if ((uip_flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0)
+ {
+ pstate->st_sndlen = -ENOTCONN;
+ }
+ else
+ {
+ /* Copy the user data into d_appdata and send it */
- memcpy(uip_appdata, pstate->st_buffer, pstate->st_buflen);
- uip_udp_send(pstate->st_buflen);
+ memcpy(dev->d_appdata, pstate->st_buffer, pstate->st_buflen);
+ uip_send(dev, dev->d_appdata, pstate->st_buflen);
+ pstate->st_sndlen = pstate->st_buflen;
+ }
- /* Don't allow any furhter call backs. */
+ /* Don't allow any further call backs. */
- uip_conn->private = NULL;
- uip_conn->callback = NULL;
+ uip_udp_conn->private = NULL;
+ uip_udp_conn->event = NULL;
/* Wake up the waiting thread */
sem_post(&pstate->st_sem);
}
}
+#endif
/****************************************************************************
* Global Functions
@@ -242,8 +275,8 @@ ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
/* Set up the callback in the connection */
udp_conn = (struct uip_udp_conn *)psock->s_conn;
- udp_conn->private = (void*)&state;
- udp_conn->callback = sendto_interrupt;
+ udp_conn->private = (void*)&state;
+ udp_conn->event = sendto_interrupt;
/* Enable the UDP socket */
@@ -260,8 +293,8 @@ ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
/* Make sure that no further interrupts are processed */
uip_udpdisable(psock->s_conn);
- udp_conn->private = NULL;
- udp_conn->callback = NULL;
+ udp_conn->private = NULL;
+ udp_conn->event = NULL;
irqrestore(save);
sem_destroy(&state.st_sem);
@@ -269,7 +302,18 @@ ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
/* Set the socket state to idle */
psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_IDLE);
- return len;
+
+ /* Check for errors */
+
+ if (state.st_sndlen < 0)
+ {
+ err = -state.st_sndlen;
+ goto errout;
+ }
+
+ /* Sucess */
+
+ return state.st_sndlen;
#else
err = ENOSYS;
#endif