diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2014-06-18 10:50:09 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2014-06-18 10:50:09 -0600 |
commit | 247e1587c3f749a3dd832b79a3251ae678f3d7b4 (patch) | |
tree | b8db4e5a404206bf00e66b9e81538aab5c1f51f2 /nuttx/net/udp | |
parent | 80555e2ee1a0558241c63690ec50d1b40216f1cf (diff) | |
download | nuttx-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.defs | 51 | ||||
-rw-r--r-- | nuttx/net/udp/udp_callback.c | 95 | ||||
-rw-r--r-- | nuttx/net/udp/udp_conn.c | 475 | ||||
-rw-r--r-- | nuttx/net/udp/udp_input.c | 174 | ||||
-rw-r--r-- | nuttx/net/udp/udp_poll.c | 126 | ||||
-rw-r--r-- | nuttx/net/udp/udp_send.c | 177 |
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 */ |