summaryrefslogtreecommitdiff
path: root/nuttx/net/udp
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2014-06-18 10:50:09 -0600
committerGregory Nutt <gnutt@nuttx.org>2014-06-18 10:50:09 -0600
commit247e1587c3f749a3dd832b79a3251ae678f3d7b4 (patch)
treeb8db4e5a404206bf00e66b9e81538aab5c1f51f2 /nuttx/net/udp
parent80555e2ee1a0558241c63690ec50d1b40216f1cf (diff)
downloadnuttx-247e1587c3f749a3dd832b79a3251ae678f3d7b4.tar.gz
nuttx-247e1587c3f749a3dd832b79a3251ae678f3d7b4.tar.bz2
nuttx-247e1587c3f749a3dd832b79a3251ae678f3d7b4.zip
Move UDP files from net/uip to net/udp
Diffstat (limited to 'nuttx/net/udp')
-rw-r--r--nuttx/net/udp/Make.defs51
-rw-r--r--nuttx/net/udp/udp_callback.c95
-rw-r--r--nuttx/net/udp/udp_conn.c475
-rw-r--r--nuttx/net/udp/udp_input.c174
-rw-r--r--nuttx/net/udp/udp_poll.c126
-rw-r--r--nuttx/net/udp/udp_send.c177
6 files changed, 1098 insertions, 0 deletions
diff --git a/nuttx/net/udp/Make.defs b/nuttx/net/udp/Make.defs
new file mode 100644
index 000000000..cebc6f385
--- /dev/null
+++ b/nuttx/net/udp/Make.defs
@@ -0,0 +1,51 @@
+############################################################################
+# net/udp/Make.defs
+#
+# Copyright (C) 2014 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+
+ifeq ($(CONFIG_NET),y)
+
+# UDP source files
+
+ifeq ($(CONFIG_NET_UDP),y)
+
+NET_CSRCS += udp_conn.c udp_poll.c udp_send.c udp_input.c udp_callback.c
+
+# Include uip build support
+
+DEPPATH += --dep-path udp
+VPATH += :udp
+CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)net$(DELIM)udp}
+
+endif # CONFIG_NET_UDP
+endif # CONFIG_NET
diff --git a/nuttx/net/udp/udp_callback.c b/nuttx/net/udp/udp_callback.c
new file mode 100644
index 000000000..9cdc8633d
--- /dev/null
+++ b/nuttx/net/udp/udp_callback.c
@@ -0,0 +1,95 @@
+/****************************************************************************
+ * net/udp/udp_callback.c
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#if defined(CONFIG_NET) && defined(CONFIG_NET_UDP)
+
+#include <stdint.h>
+#include <debug.h>
+
+#include <nuttx/net/uip/uipopt.h>
+#include <nuttx/net/uip/uip.h>
+#include <nuttx/net/uip/uip-arch.h>
+
+#include "uip/uip_internal.h"
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: uip_udpcallback
+ *
+ * Description:
+ * Inform the application holding the UDP socket of a change in state.
+ *
+ * Returned Value:
+ * OK if packet has been processed, otherwise ERROR.
+ *
+ * Assumptions:
+ * This function is called at the interrupt level with interrupts disabled.
+ *
+ ****************************************************************************/
+
+uint16_t uip_udpcallback(struct uip_driver_s *dev, struct uip_udp_conn *conn,
+ uint16_t flags)
+{
+ nllvdbg("flags: %04x\n", flags);
+
+ /* Some sanity checking */
+
+ if (conn)
+ {
+ /* Perform the callback */
+
+ flags = uip_callbackexecute(dev, conn, flags, conn->list);
+ }
+
+ return flags;
+}
+
+#endif /* CONFIG_NET && CONFIG_NET_UDP */
diff --git a/nuttx/net/udp/udp_conn.c b/nuttx/net/udp/udp_conn.c
new file mode 100644
index 000000000..0d36d7d67
--- /dev/null
+++ b/nuttx/net/udp/udp_conn.c
@@ -0,0 +1,475 @@
+/****************************************************************************
+ * net/udp/udp_conn.c
+ *
+ * Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Large parts of this file were leveraged from uIP logic:
+ *
+ * Copyright (c) 2001-2003, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Compilation Switches
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#if defined(CONFIG_NET) && defined(CONFIG_NET_UDP)
+
+#include <stdint.h>
+#include <string.h>
+#include <semaphore.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/irq.h>
+
+#include <nuttx/net/uip/uipopt.h>
+#include <nuttx/net/uip/uip.h>
+#include <nuttx/net/uip/uip-arch.h>
+
+#include "uip/uip_internal.h"
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The array containing all uIP UDP connections. */
+
+struct uip_udp_conn g_udp_connections[CONFIG_NET_UDP_CONNS];
+
+/* A list of all free UDP connections */
+
+static dq_queue_t g_free_udp_connections;
+static sem_t g_free_sem;
+
+/* A list of all allocated UDP connections */
+
+static dq_queue_t g_active_udp_connections;
+
+/* Last port used by a UDP connection connection. */
+
+static uint16_t g_last_udp_port;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: _uip_semtake() and _uip_semgive()
+ *
+ * Description:
+ * Take/give semaphore
+ *
+ ****************************************************************************/
+
+static inline void _uip_semtake(FAR sem_t *sem)
+{
+ /* Take the semaphore (perhaps waiting) */
+
+ while (uip_lockedwait(sem) != 0)
+ {
+ /* The only case that an error should occur here is if
+ * the wait was awakened by a signal.
+ */
+
+ ASSERT(*get_errno_ptr() == EINTR);
+ }
+}
+
+#define _uip_semgive(sem) sem_post(sem)
+
+/****************************************************************************
+ * Name: uip_find_conn()
+ *
+ * Description:
+ * Find the UDP connection that uses this local port number. Called only
+ * from user user level code, but with interrupts disabled.
+ *
+ ****************************************************************************/
+
+static FAR struct uip_udp_conn *uip_find_conn(uint16_t portno)
+{
+ int i;
+
+ /* Now search each connection structure.*/
+
+ for (i = 0; i < CONFIG_NET_UDP_CONNS; i++)
+ {
+ if (g_udp_connections[ i ].lport == portno)
+ {
+ return &g_udp_connections[ i ];
+ }
+ }
+
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: uip_selectport()
+ *
+ * Description:
+ * Select an unused port number.
+ *
+ * NOTE that in principle this function could fail if there is no available
+ * port number. There is no check for that case and it would actually
+ * in an infinite loop if that were the case. In this simple, small UDP
+ * implementation, it is reasonable to assume that that error cannot happen
+ * and that a port number will always be available.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Return:
+ * Next available port number
+ *
+ ****************************************************************************/
+
+static uint16_t uip_selectport(void)
+{
+ uint16_t portno;
+
+ /* Find an unused local port number. Loop until we find a valid
+ * listen port number that is not being used by any other connection.
+ */
+
+ uip_lock_t flags = uip_lock();
+ do
+ {
+ /* Guess that the next available port number will be the one after
+ * the last port number assigned.
+ */
+
+ ++g_last_udp_port;
+
+ /* Make sure that the port number is within range */
+
+ if (g_last_udp_port >= 32000)
+ {
+ g_last_udp_port = 4096;
+ }
+ }
+ while (uip_find_conn(htons(g_last_udp_port)));
+
+ /* Initialize and return the connection structure, bind it to the
+ * port number
+ */
+
+ portno = g_last_udp_port;
+ uip_unlock(flags);
+
+ return portno;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: uip_udpinit()
+ *
+ * Description:
+ * Initialize the UDP connection structures. Called once and only from
+ * the UIP layer.
+ *
+ ****************************************************************************/
+
+void uip_udpinit(void)
+{
+ int i;
+
+ /* Initialize the queues */
+
+ dq_init(&g_free_udp_connections);
+ dq_init(&g_active_udp_connections);
+ sem_init(&g_free_sem, 0, 1);
+
+ for (i = 0; i < CONFIG_NET_UDP_CONNS; i++)
+ {
+ /* Mark the connection closed and move it to the free list */
+
+ g_udp_connections[i].lport = 0;
+ dq_addlast(&g_udp_connections[i].node, &g_free_udp_connections);
+ }
+
+ g_last_udp_port = 1024;
+}
+
+/****************************************************************************
+ * Name: uip_udpalloc()
+ *
+ * Description:
+ * Allocate a new, uninitialized UDP connection structure.
+ *
+ ****************************************************************************/
+
+struct uip_udp_conn *uip_udpalloc(void)
+{
+ struct uip_udp_conn *conn;
+
+ /* The free list is only accessed from user, non-interrupt level and
+ * is protected by a semaphore (that behaves like a mutex).
+ */
+
+ _uip_semtake(&g_free_sem);
+ conn = (struct uip_udp_conn *)dq_remfirst(&g_free_udp_connections);
+ if (conn)
+ {
+ /* Make sure that the connection is marked as uninitialized */
+
+ conn->lport = 0;
+
+ /* Enqueue the connection into the active list */
+
+ dq_addlast(&conn->node, &g_active_udp_connections);
+ }
+
+ _uip_semgive(&g_free_sem);
+ return conn;
+}
+
+/****************************************************************************
+ * Name: uip_udpfree()
+ *
+ * Description:
+ * Free a UDP connection structure that is no longer in use. This should be
+ * done by the implementation of close(). uip_udpdisable must have been
+ * previously called.
+ *
+ ****************************************************************************/
+
+void uip_udpfree(struct uip_udp_conn *conn)
+{
+ /* The free list is only accessed from user, non-interrupt level and
+ * is protected by a semaphore (that behaves like a mutex).
+ */
+
+ DEBUGASSERT(conn->crefs == 0);
+
+ _uip_semtake(&g_free_sem);
+ conn->lport = 0;
+
+ /* Remove the connection from the active list */
+
+ dq_rem(&conn->node, &g_active_udp_connections);
+
+ /* Free the connection */
+
+ dq_addlast(&conn->node, &g_free_udp_connections);
+ _uip_semgive(&g_free_sem);
+}
+
+/****************************************************************************
+ * Name: uip_udpactive()
+ *
+ * Description:
+ * Find a connection structure that is the appropriate
+ * connection to be used within the provided TCP/IP header
+ *
+ * Assumptions:
+ * This function is called from UIP logic at interrupt level
+ *
+ ****************************************************************************/
+
+struct uip_udp_conn *uip_udpactive(FAR struct uip_udpip_hdr *buf)
+{
+ FAR struct uip_udp_conn *conn =
+ (FAR struct uip_udp_conn *)g_active_udp_connections.head;
+
+ while (conn)
+ {
+ /* If the local UDP port is non-zero, the connection is considered
+ * to be used. If so, the local port number is checked against the
+ * destination port number in the received packet. If the two port
+ * numbers match, the remote port number is checked if the
+ * connection is bound to a remote port. Finally, if the
+ * connection is bound to a remote IP address, the source IP
+ * address of the packet is checked.
+ */
+
+ if (conn->lport != 0 && buf->destport == conn->lport &&
+ (conn->rport == 0 || buf->srcport == conn->rport) &&
+ (uip_ipaddr_cmp(conn->ripaddr, g_allzeroaddr) ||
+ uip_ipaddr_cmp(conn->ripaddr, g_alloneaddr) ||
+ uiphdr_ipaddr_cmp(buf->srcipaddr, &conn->ripaddr)))
+ {
+ /* Matching connection found.. return a reference to it */
+
+ break;
+ }
+
+ /* Look at the next active connection */
+
+ conn = (struct uip_udp_conn *)conn->node.flink;
+ }
+
+ return conn;
+}
+
+/****************************************************************************
+ * Name: uip_nextudpconn()
+ *
+ * Description:
+ * Traverse the list of allocated UDP connections
+ *
+ * Assumptions:
+ * This function is called from UIP logic at interrupt level (or with
+ * interrupts disabled).
+ *
+ ****************************************************************************/
+
+FAR struct uip_udp_conn *uip_nextudpconn(FAR struct uip_udp_conn *conn)
+{
+ if (!conn)
+ {
+ return (struct uip_udp_conn *)g_active_udp_connections.head;
+ }
+ else
+ {
+ return (struct uip_udp_conn *)conn->node.flink;
+ }
+}
+
+/****************************************************************************
+ * Name: uip_udpbind()
+ *
+ * Description:
+ * This function implements the UIP specific parts of the standard UDP
+ * bind() operation.
+ *
+ * Assumptions:
+ * This function is called from normal user level code.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_IPv6
+int uip_udpbind(FAR struct uip_udp_conn *conn,
+ FAR const struct sockaddr_in6 *addr)
+#else
+int uip_udpbind(FAR struct uip_udp_conn *conn,
+ FAR const struct sockaddr_in *addr)
+#endif
+{
+ int ret = -EADDRINUSE;
+ uip_lock_t flags;
+
+ /* Is the user requesting to bind to any port? */
+
+ if (!addr->sin_port)
+ {
+ /* Yes.. Find an unused local port number */
+
+ conn->lport = htons(uip_selectport());
+ ret = OK;
+ }
+ else
+ {
+ /* Interrupts must be disabled while access the UDP connection list */
+
+ flags = uip_lock();
+
+ /* Is any other UDP connection bound to this port? */
+
+ if (!uip_find_conn(addr->sin_port))
+ {
+ /* No.. then bind the socket to the port */
+
+ conn->lport = addr->sin_port;
+ ret = OK;
+ }
+
+ uip_unlock(flags);
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: uip_udpconnect()
+ *
+ * Description:
+ * This function sets up a new UDP connection. The function will
+ * automatically allocate an unused local port for the new
+ * connection. However, another port can be chosen by using the
+ * uip_udpbind() call, after the uip_udpconnect() function has been
+ * called.
+ *
+ * uip_udpenable() must be called before the connection is made active (i.e.,
+ * is eligible for callbacks.
+ *
+ * addr The address of the remote host.
+ *
+ * Assumptions:
+ * This function is called user code. Interrupts may be enabled.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_IPv6
+int uip_udpconnect(FAR struct uip_udp_conn *conn,
+ FAR const struct sockaddr_in6 *addr)
+#else
+int uip_udpconnect(FAR struct uip_udp_conn *conn,
+ FAR const struct sockaddr_in *addr)
+#endif
+{
+ /* Has this address already been bound to a local port (lport)? */
+
+ if (!conn->lport)
+ {
+ /* No.. Find an unused local port number and bind it to the
+ * connection structure.
+ */
+
+ conn->lport = htons(uip_selectport());
+ }
+
+ /* Is there a remote port (rport) */
+
+ if (addr)
+ {
+ conn->rport = addr->sin_port;
+ uip_ipaddr_copy(conn->ripaddr, addr->sin_addr.s_addr);
+ }
+ else
+ {
+ conn->rport = 0;
+ uip_ipaddr_copy(conn->ripaddr, g_allzeroaddr);
+ }
+
+ conn->ttl = UIP_TTL;
+ return OK;
+}
+
+#endif /* CONFIG_NET && CONFIG_NET_UDP */
diff --git a/nuttx/net/udp/udp_input.c b/nuttx/net/udp/udp_input.c
new file mode 100644
index 000000000..e2d7c434f
--- /dev/null
+++ b/nuttx/net/udp/udp_input.c
@@ -0,0 +1,174 @@
+/****************************************************************************
+ * net/udp/udp_input.c
+ * Handling incoming UDP input
+ *
+ * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Adapted for NuttX from logic in uIP which also has a BSD-like license:
+ *
+ * Original author Adam Dunkels <adam@dunkels.com>
+ * Copyright () 2001-2003, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#if defined(CONFIG_NET) && defined(CONFIG_NET_UDP)
+
+#include <debug.h>
+
+#include <nuttx/net/uip/uipopt.h>
+#include <nuttx/net/uip/uip.h>
+#include <nuttx/net/uip/uip-arch.h>
+
+#include "uip/uip_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define UDPBUF ((struct uip_udpip_hdr *)&dev->d_buf[UIP_LLH_LEN])
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: uip_udpinput
+ *
+ * Description:
+ * Handle incoming UDP input
+ *
+ * Parameters:
+ * dev - The device driver structure containing the received UDP packet
+ *
+ * Return:
+ * OK The packet has been processed and can be deleted
+ * ERROR Hold the packet and try again later. There is a listening socket
+ * but no receive in place to catch the packet yet.
+ *
+ * Assumptions:
+ * Called from the interrupt level or with interrupts disabled.
+ *
+ ****************************************************************************/
+
+int uip_udpinput(FAR struct uip_driver_s *dev)
+{
+ struct uip_udp_conn *conn;
+ struct uip_udpip_hdr *pbuf = UDPBUF;
+ int ret = OK;
+
+#ifdef CONFIG_NET_STATISTICS
+ uip_stat.udp.recv++;
+#endif
+
+ /* UDP processing is really just a hack. We don't do anything to the UDP/IP
+ * headers, but let the UDP application do all the hard work. If the
+ * application sets d_sndlen, it has a packet to send.
+ */
+
+ dev->d_len -= UIP_IPUDPH_LEN;
+#ifdef CONFIG_NET_UDP_CHECKSUMS
+ dev->d_appdata = &dev->d_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
+ if (pbuf->udpchksum != 0 && uip_udpchksum(dev) != 0xffff)
+ {
+#ifdef CONFIG_NET_STATISTICS
+ uip_stat.udp.drop++;
+ uip_stat.udp.chkerr++;
+#endif
+ nlldbg("Bad UDP checksum\n");
+ dev->d_len = 0;
+ }
+ else
+#endif
+ {
+ /* Demultiplex this UDP packet between the UDP "connections". */
+
+ conn = uip_udpactive(pbuf);
+ if (conn)
+ {
+ uint16_t flags;
+
+ /* Set-up for the application callback */
+
+ dev->d_appdata = &dev->d_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
+ dev->d_snddata = &dev->d_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
+ dev->d_sndlen = 0;
+
+ /* Perform the application callback */
+
+ flags = uip_udpcallback(dev, conn, UIP_NEWDATA);
+
+ /* If the operation was successful, the UIP_NEWDATA flag is removed
+ * and thus the packet can be deleted (OK will be returned).
+ */
+
+ if ((flags & UIP_NEWDATA) != 0)
+ {
+ /* No.. the packet was not processed now. Return ERROR so
+ * that the driver may retry again later.
+ */
+
+ ret = ERROR;
+ }
+
+ /* If the application has data to send, setup the UDP/IP header */
+
+ if (dev->d_sndlen > 0)
+ {
+ uip_udpsend(dev, conn);
+ }
+ }
+ else
+ {
+ nlldbg("No listener on UDP port\n");
+ dev->d_len = 0;
+ }
+ }
+
+ return ret;
+}
+
+#endif /* CONFIG_NET && CONFIG_NET_UDP */
diff --git a/nuttx/net/udp/udp_poll.c b/nuttx/net/udp/udp_poll.c
new file mode 100644
index 000000000..23b663250
--- /dev/null
+++ b/nuttx/net/udp/udp_poll.c
@@ -0,0 +1,126 @@
+/****************************************************************************
+ * net/udp/udp_poll.c
+ * Poll for the availability of UDP TX data
+ *
+ * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Adapted for NuttX from logic in uIP which also has a BSD-like license:
+ *
+ * Original author Adam Dunkels <adam@dunkels.com>
+ * Copyright () 2001-2003, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#if defined(CONFIG_NET) && defined(CONFIG_NET_UDP)
+
+#include <debug.h>
+
+#include <nuttx/net/uip/uipopt.h>
+#include <nuttx/net/uip/uip.h>
+#include <nuttx/net/uip/uip-arch.h>
+
+#include "uip/uip_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: uip_udppoll
+ *
+ * Description:
+ * Poll a UDP "connection" structure for availability of TX data
+ *
+ * Parameters:
+ * dev - The device driver structure to use in the send operation
+ * conn - The UDP "connection" to poll for TX data
+ *
+ * Return:
+ * None
+ *
+ * Assumptions:
+ * Called from the interrupt level or with interrupts disabled.
+ *
+ ****************************************************************************/
+
+void uip_udppoll(FAR struct uip_driver_s *dev, FAR struct uip_udp_conn *conn)
+{
+ /* Verify that the UDP connection is valid */
+
+ if (conn->lport != 0)
+ {
+ /* Set-up for the application callback */
+
+ dev->d_appdata = &dev->d_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
+ dev->d_snddata = &dev->d_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
+
+ dev->d_len = 0;
+ dev->d_sndlen = 0;
+
+ /* Perform the application callback */
+
+ (void)uip_udpcallback(dev, conn, UIP_POLL);
+
+ /* If the application has data to send, setup the UDP/IP header */
+
+ if (dev->d_sndlen > 0)
+ {
+ uip_udpsend(dev, conn);
+ return;
+ }
+ }
+
+ /* Make sure that d_len is zero meaning that there is nothing to be sent */
+
+ dev->d_len = 0;
+}
+
+#endif /* CONFIG_NET && CONFIG_NET_UDP */
diff --git a/nuttx/net/udp/udp_send.c b/nuttx/net/udp/udp_send.c
new file mode 100644
index 000000000..aab52f6d4
--- /dev/null
+++ b/nuttx/net/udp/udp_send.c
@@ -0,0 +1,177 @@
+/****************************************************************************
+ * net/udp/udp_send.c
+ *
+ * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Adapted for NuttX from logic in uIP which also has a BSD-like license:
+ *
+ * Original author Adam Dunkels <adam@dunkels.com>
+ * Copyright () 2001-2003, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#if defined(CONFIG_NET) && defined(CONFIG_NET_UDP)
+
+#include <debug.h>
+
+#include <nuttx/net/uip/uipopt.h>
+#include <nuttx/net/uip/uip.h>
+#include <nuttx/net/uip/uip-arch.h>
+
+#include "uip/uip_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define UDPBUF ((struct uip_udpip_hdr *)&dev->d_buf[UIP_LLH_LEN])
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: uip_udpsend
+ *
+ * Description:
+ * Set-up to send a UDP packet
+ *
+ * Parameters:
+ * dev - The device driver structure to use in the send operation
+ * conn - The UDP "connection" structure holding port information
+ *
+ * Return:
+ * None
+ *
+ * Assumptions:
+ * Called from the interrupt level or with interrupts disabled.
+ *
+ ****************************************************************************/
+
+void uip_udpsend(struct uip_driver_s *dev, struct uip_udp_conn *conn)
+{
+ struct uip_udpip_hdr *pudpbuf = UDPBUF;
+
+ if (dev->d_sndlen > 0)
+ {
+ /* The total length to send is the size of the application data plus
+ * the IP and UDP headers (and, eventually, the Ethernet header)
+ */
+
+ dev->d_len = dev->d_sndlen + UIP_IPUDPH_LEN;
+
+ /* Initialize the IP header. Note that for IPv6, the IP length field
+ * does not include the IPv6 IP header length.
+ */
+
+#ifdef CONFIG_NET_IPv6
+
+ pudpbuf->vtc = 0x60;
+ pudpbuf->tcf = 0x00;
+ pudpbuf->flow = 0x00;
+ pudpbuf->len[0] = (dev->d_sndlen >> 8);
+ pudpbuf->len[1] = (dev->d_sndlen & 0xff);
+ pudpbuf->nexthdr = UIP_PROTO_UDP;
+ pudpbuf->hoplimit = conn->ttl;
+
+ uip_ipaddr_copy(pudpbuf->srcipaddr, &dev->d_ipaddr);
+ uip_ipaddr_copy(pudpbuf->destipaddr, &conn->ripaddr);
+
+#else /* CONFIG_NET_IPv6 */
+
+ pudpbuf->vhl = 0x45;
+ pudpbuf->tos = 0;
+ pudpbuf->len[0] = (dev->d_len >> 8);
+ pudpbuf->len[1] = (dev->d_len & 0xff);
+ ++g_ipid;
+ pudpbuf->ipid[0] = g_ipid >> 8;
+ pudpbuf->ipid[1] = g_ipid & 0xff;
+ pudpbuf->ipoffset[0] = 0;
+ pudpbuf->ipoffset[1] = 0;
+ pudpbuf->ttl = conn->ttl;
+ pudpbuf->proto = UIP_PROTO_UDP;
+
+ uiphdr_ipaddr_copy(pudpbuf->srcipaddr, &dev->d_ipaddr);
+ uiphdr_ipaddr_copy(pudpbuf->destipaddr, &conn->ripaddr);
+
+ /* Calculate IP checksum. */
+
+ pudpbuf->ipchksum = 0;
+ pudpbuf->ipchksum = ~(uip_ipchksum(dev));
+
+#endif /* CONFIG_NET_IPv6 */
+
+ /* Initialize the UDP header */
+
+ pudpbuf->srcport = conn->lport;
+ pudpbuf->destport = conn->rport;
+ pudpbuf->udplen = HTONS(dev->d_sndlen + UIP_UDPH_LEN);
+
+#ifdef CONFIG_NET_UDP_CHECKSUMS
+ /* Calculate UDP checksum. */
+
+ pudpbuf->udpchksum = 0;
+ pudpbuf->udpchksum = ~(uip_udpchksum(dev));
+ if (pudpbuf->udpchksum == 0)
+ {
+ pudpbuf->udpchksum = 0xffff;
+ }
+#else
+ pudpbuf->udpchksum = 0;
+#endif
+
+ nllvdbg("Outgoing UDP packet length: %d (%d)\n",
+ dev->d_len, (pudpbuf->len[0] << 8) | pudpbuf->len[1]);
+
+#ifdef CONFIG_NET_STATISTICS
+ uip_stat.udp.sent++;
+ uip_stat.ip.sent++;
+#endif
+ }
+}
+
+#endif /* CONFIG_NET && CONFIG_NET_UDP */