diff options
Diffstat (limited to 'nuttx/net/udp')
-rw-r--r-- | nuttx/net/udp/Make.defs | 12 | ||||
-rw-r--r-- | nuttx/net/udp/udp.h | 47 | ||||
-rw-r--r-- | nuttx/net/udp/udp_devpoll.c (renamed from nuttx/net/udp/udp_poll.c) | 4 | ||||
-rw-r--r-- | nuttx/net/udp/udp_netpoll.c | 304 |
4 files changed, 362 insertions, 5 deletions
diff --git a/nuttx/net/udp/Make.defs b/nuttx/net/udp/Make.defs index 9cbe77b3d..4cd7b9a1d 100644 --- a/nuttx/net/udp/Make.defs +++ b/nuttx/net/udp/Make.defs @@ -1,7 +1,7 @@ ############################################################################ # net/udp/Make.defs # -# Copyright (C) 2014 Gregory Nutt. All rights reserved. +# Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. # Author: Gregory Nutt <gnutt@nuttx.org> # # Redistribution and use in source and binary forms, with or without @@ -41,9 +41,15 @@ ifeq ($(CONFIG_NET_UDP),y) NET_CSRCS += udp_sendto.c -# Tranport layer +ifneq ($(CONFIG_DISABLE_POLL),y) +ifeq ($(CONFIG_NET_UDP_READAHEAD),y) +NET_CSRCS += udp_netpoll.c +endif +endif -NET_CSRCS += udp_conn.c udp_poll.c udp_send.c udp_input.c udp_callback.c +# Transport layer + +NET_CSRCS += udp_conn.c udp_devpoll.c udp_send.c udp_input.c udp_callback.c NET_CSRCS += udp_ipselect.c # Include UDP build support diff --git a/nuttx/net/udp/udp.h b/nuttx/net/udp/udp.h index 2f193dea0..ddd470410 100644 --- a/nuttx/net/udp/udp.h +++ b/nuttx/net/udp/udp.h @@ -56,6 +56,12 @@ /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ +/* Conditions for support UDP poll/select operations */ + +#if !defined(CONFIG_DISABLE_POLL) && CONFIG_NSOCKET_DESCRIPTORS > 0 && \ + defined(CONFIG_NET_UDP_READAHEAD) +# define HAVE_UDP_POLL +#endif /* Allocate a new UDP data callback */ @@ -115,6 +121,7 @@ extern "C" struct sockaddr; /* Forward reference */ struct socket; /* Forward reference */ struct net_driver_s; /* Forward reference */ +struct pollfd; /* Forward reference */ /**************************************************************************** * Name: udp_initialize @@ -371,6 +378,46 @@ ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf, size_t len, int flags, FAR const struct sockaddr *to, socklen_t tolen); +/**************************************************************************** + * Function: udp_pollsetup + * + * Description: + * Setup to monitor events on one UDP/IP socket + * + * Input Parameters: + * psock - The UDP/IP socket of interest + * fds - The structure describing the events to be monitored, OR NULL if + * this is a request to stop monitoring events. + * + * Returned Value: + * 0: Success; Negated errno on failure + * + ****************************************************************************/ + +#ifdef HAVE_UDP_POLL +int udp_pollsetup(FAR struct socket *psock, FAR struct pollfd *fds); +#endif + +/**************************************************************************** + * Function: udp_pollteardown + * + * Description: + * Teardown monitoring of events on an UDP/IP socket + * + * Input Parameters: + * psock - The TCP/IP socket of interest + * fds - The structure describing the events to be monitored, OR NULL if + * this is a request to stop monitoring events. + * + * Returned Value: + * 0: Success; Negated errno on failure + * + ****************************************************************************/ + +#ifdef HAVE_UDP_POLL +int udp_pollteardown(FAR struct socket *psock, FAR struct pollfd *fds); +#endif + #undef EXTERN #ifdef __cplusplus } diff --git a/nuttx/net/udp/udp_poll.c b/nuttx/net/udp/udp_devpoll.c index b7112bd9c..8352b7b26 100644 --- a/nuttx/net/udp/udp_poll.c +++ b/nuttx/net/udp/udp_devpoll.c @@ -1,6 +1,6 @@ /**************************************************************************** - * net/udp/udp_poll.c - * Poll for the availability of UDP TX data + * net/udp/udp_devpoll.c + * Network device poll for the availability of UDP TX data * * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> diff --git a/nuttx/net/udp/udp_netpoll.c b/nuttx/net/udp/udp_netpoll.c new file mode 100644 index 000000000..0ab9a5f90 --- /dev/null +++ b/nuttx/net/udp/udp_netpoll.c @@ -0,0 +1,304 @@ +/**************************************************************************** + * net/udp/udp_netpoll.c + * + * Copyright (C) 2008-2009, 2011-2015 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> + +#include <stdint.h> +#include <poll.h> +#include <debug.h> + +#include <nuttx/kmalloc.h> +#include <nuttx/net/net.h> + +#include <devif/devif.h> +#include "udp/udp.h" + +#ifdef HAVE_UDP_POLL + +/**************************************************************************** + * Private Types + ****************************************************************************/ +/* This is an allocated container that holds the poll-related information */ + +struct udp_poll_s +{ + FAR struct socket *psock; /* Needed to handle loss of connection */ + struct pollfd *fds; /* Needed to handle poll events */ + FAR struct devif_callback_s *cb; /* Needed to teardown the poll */ +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: udp_poll_interrupt + * + * Description: + * This function is called from the interrupt level to perform the actual + * UDP receive operation via by the device interface layer. + * + * Parameters: + * dev The structure of the network driver that caused the interrupt + * conn The connection structure associated with the socket + * flags Set of events describing why the callback was invoked + * + * Returned Value: + * None + * + * Assumptions: + * Running at the interrupt level + * + ****************************************************************************/ + +static uint16_t udp_poll_interrupt(FAR struct net_driver_s *dev, FAR void *conn, + FAR void *pvpriv, uint16_t flags) +{ + FAR struct udp_poll_s *info = (FAR struct udp_poll_s *)pvpriv; + + nllvdbg("flags: %04x\n", flags); + + DEBUGASSERT(!info || (info->psock && info->fds)); + + /* 'priv' might be null in some race conditions (?) */ + + if (info) + { + pollevent_t eventset = 0; + + /* Check for data or connection availability events. */ + + if ((flags & (UDP_NEWDATA)) != 0) + { + eventset |= (POLLIN & info->fds->events); + } + + /* A poll is a sign that we are free to send data. */ + + if ((flags & UDP_POLL) != 0) + { + eventset |= (POLLOUT & info->fds->events); + } + + /* Awaken the caller of poll() is requested event occurred. */ + + if (eventset) + { + info->fds->revents |= eventset; + sem_post(info->fds->sem); + } + } + + return flags; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: udp_pollsetup + * + * Description: + * Setup to monitor events on one UDP/IP socket + * + * Input Parameters: + * psock - The UDP/IP socket of interest + * fds - The structure describing the events to be monitored, OR NULL if + * this is a request to stop monitoring events. + * + * Returned Value: + * 0: Success; Negated errno on failure + * + ****************************************************************************/ + +int udp_pollsetup(FAR struct socket *psock, FAR struct pollfd *fds) +{ + FAR struct udp_conn_s *conn = psock->s_conn; + FAR struct udp_poll_s *info; + FAR struct devif_callback_s *cb; + net_lock_t flags; + int ret; + + /* Sanity check */ + +#ifdef CONFIG_DEBUG + if (!conn || !fds) + { + return -EINVAL; + } +#endif + + /* Allocate a container to hold the poll information */ + + info = (FAR struct udp_poll_s *)kmm_malloc(sizeof(struct udp_poll_s)); + if (!info) + { + return -ENOMEM; + } + + /* Some of the following must be atomic */ + + flags = net_lock(); + + /* Setup the UDP remote connection */ + + ret = udp_connect(conn, NULL); + if (ret) + { + goto errout_with_lock; + } + + /* Allocate a TCP/IP callback structure */ + + cb = udp_callback_alloc(conn); + if (!cb) + { + ret = -EBUSY; + goto errout_with_lock; + } + + /* Initialize the poll info container */ + + info->psock = psock; + info->fds = fds; + info->cb = cb; + + /* Initialize the callback structure. Save the reference to the info + * structure as callback private data so that it will be available during + * callback processing. + */ + + cb->flags = (0); + cb->priv = (FAR void *)info; + cb->event = udp_poll_interrupt; + + if (info->fds->events & POLLOUT) + cb->flags |= UDP_POLL; + if (info->fds->events & POLLIN) + cb->flags |= UDP_NEWDATA; + + /* Save the reference in the poll info structure as fds private as well + * for use durring poll teardown as well. + */ + + fds->priv = (FAR void *)info; + + /* Check for read data availability now */ + + if (!IOB_QEMPTY(&conn->readahead)) + { + /* Normal data may be read without blocking. */ + + fds->revents |= (POLLRDNORM & fds->events); + } + + /* Check if any requested events are already in effect */ + + if (fds->revents != 0) + { + /* Yes.. then signal the poll logic */ + sem_post(fds->sem); + } + + net_unlock(flags); + return OK; + +errout_with_lock: + kmm_free(info); + net_unlock(flags); + return ret; +} + +/**************************************************************************** + * Function: udp_pollteardown + * + * Description: + * Teardown monitoring of events on an UDP/IP socket + * + * Input Parameters: + * psock - The TCP/IP socket of interest + * fds - The structure describing the events to be monitored, OR NULL if + * this is a request to stop monitoring events. + * + * Returned Value: + * 0: Success; Negated errno on failure + * + ****************************************************************************/ + +int udp_pollteardown(FAR struct socket *psock, FAR struct pollfd *fds) +{ + FAR struct udp_conn_s *conn = psock->s_conn; + FAR struct udp_poll_s *info; + net_lock_t flags; + + /* Sanity check */ + +#ifdef CONFIG_DEBUG + if (!conn || !fds->priv) + { + return -EINVAL; + } +#endif + + /* Recover the socket descriptor poll state info from the poll structure */ + + info = (FAR struct udp_poll_s *)fds->priv; + DEBUGASSERT(info && info->fds && info->cb); + if (info) + { + /* Release the callback */ + + flags = net_lock(); + udp_callback_free(conn, info->cb); + net_unlock(flags); + + /* Release the poll/select data slot */ + + info->fds->priv = NULL; + + /* Then free the poll info container */ + + kmm_free(info); + } + + return OK; +} + +#endif /* !HAVE_UDP_POLL */ |