Merge remote-tracking branch 'origin/master' into composite

This commit is contained in:
Gregory Nutt
2017-07-13 13:57:40 -06:00
43 changed files with 10609 additions and 5133 deletions

View File

@@ -466,6 +466,10 @@ config SAMDL_HAVE_TC7
bool
default n
config SAMDL_HAVE_USB
bool
default n
config SAMDL_AC
bool "Analog Comparator"
default n
@@ -737,3 +741,25 @@ config SAMDL_I2C_REGDEBUG
Enable very low-level register access debug. Depends on DEBUG_I2C.
endif # SAMDL_HAVE_I2C
if SAMDL_HAVE_USB
config SAMDL_USB_ENABLE_PPEP
bool "Enable Ping-Pong Endpoints"
default n
---help---
To maximize throughput, an endpoint can be configured for ping-pong
operation. When this is done the input and output endpoint with the same
address are used in the same direction. The CPU or DMA Controller can
then read/write one data buffer while the USB module writes/reads from
the other buffer. This gives double buffered communication.
config SAMDL_USB_REGDEBUG
bool "USB register-Level Debug"
default n
depends on DEBUG_USB_INFO
---help---
Enable very low-level register access debug. Depends on
CONFIG_DEBUG_USB_INFO.
endif # SAMDL_HAVE_USB

View File

@@ -98,3 +98,7 @@ endif
ifeq ($(CONFIG_SAMDL_HAVE_I2C),y)
CHIP_CSRCS += sam_i2c_master.c
endif
ifeq ($(CONFIG_SAMDL_USB),y)
CHIP_CSRCS += sam_usb.c
endif

View File

@@ -37,6 +37,7 @@
*
********************************************************************************************/
#ifndef __ARCH_ARM_SRC_SAMDL_CHIP_SAML_USB_H
#define __ARCH_ARM_SRC_SAMDL_CHIP_SAML_USB_H
@@ -53,6 +54,29 @@
/********************************************************************************************
* Pre-processor Definitions
********************************************************************************************/
/* Capabilities and characteristics of endpoints ********************************************/
/* EP EP BANKS EP SIZE EP TYPE
* --- --------- --------- ---------
* 0 2 64/1023 Control/Bulk/Iso/Interrupt
* 1 2 64/1023 Control/Bulk/Iso/Interrupt
* 2 2 64/1023 Control/Bulk/Iso/Interrupt
* 3 2 64/1023 Control/Bulk/Iso/Interrupt
* 4 2 64/1023 Control/Bulk/Iso/Interrupt
* 5 2 64/1023 Control/Bulk/Iso/Interrupt
* 6 2 64/1023 Control/Bulk/Iso/Interrupt
* 7 2 64/1023 Control/Bulk/Iso/Interrupt
*/
#define SAM_USB_NENDPOINTS (8)
#define SAM_USB_MAXPACKETSIZE(ep) (64)
#define SAM_USB_NBANKS(ep) (2)
#define SAM_USB_CONTROL(ep) (true)
#define SAM_USB_BULK(ep) (true)
#define SAM_USB_ISOCHRONOUS(ep) (true)
#define SAM_USB_INTERRUPT(ep) (true)
/* USB register offsets ********************************************************************/
/* Common USB Device/Host Register Offsets */

File diff suppressed because it is too large Load Diff

View File

@@ -101,7 +101,7 @@
# define USART4_ASSIGNED 1
#elif defined(CONFIG_USART5_SERIAL_CONSOLE)
# define CONSOLE_DEV g_usart5port /* USART5 is console */
# define TTYS5_DEV g_usart5port /* USART5 is ttyS0 */
# define TTYS0_DEV g_usart5port /* USART5 is ttyS0 */
#else
# undef CONSOLE_DEV /* No console */
# if defined(SAMDL_HAVE_USART0)

View File

@@ -1261,7 +1261,12 @@ static void spi_recvblock(struct spi_dev_s *dev, void *buffer, size_t nwords)
static void spi_wait_synchronization(struct sam_spidev_s *priv)
{
#if defined(CONFIG_ARCH_FAMILY_SAMD20)
while ((spi_getreg16(priv, SAM_SPI_STATUS_OFFSET) & SPI_STATUS_SYNCBUSY) != 0);
#elif defined(CONFIG_ARCH_FAMILY_SAMD21) || defined(CONFIG_ARCH_FAMILY_SAML21)
while ((spi_getreg16(priv, SAM_SPI_SYNCBUSY_OFFSET) & SPI_SYNCBUSY_ALL) != 0);
#endif
}
/****************************************************************************

4056
arch/arm/src/samdl/sam_usb.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,99 @@
/******************************************************************************
* arch/arm/src/samdl/sam_usb.h
*
* Copyright (C) 2015 Filament - www.filament.com
* Copyright (C) 2015 Offcode Ltd. All rights reserved.
* Author: Janne Rosberg <janne@offcode.fi>
*
* This driver is derived from the SAM34 UDP driver:
* 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.
*
*****************************************************************************/
#ifndef __ARCH_ARM_SRC_SAMDL_SAM_USB_H
#define __ARCH_ARM_SRC_SAMDL_SAM_USB_H
/*****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/usb/usbdev.h>
#include <stdint.h>
#include "chip.h"
#include "chip/saml_usb.h"
/*****************************************************************************
* Public Function Prototypes
****************************************************************************/
#ifndef __ASSEMBLY__
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/*****************************************************************************
* Name: sam_usb_suspend
*
* Description:
* Board logic must provide the sam_usb_suspend logic if the USB driver is
* used. This function is called whenever the USB enters or leaves
* suspend mode.
*
* When 'resume' is false, this function call provides an opportunity to
* perform board-specific power-saving actions so that less power is consumed
* while the USB is suspended.
*
* XXX:
* Certain power-saving operations are performed by the UDP driver when it
* enters suspend mode: The USB device peripheral clocks are be switched off.
* MCK and UDPCK are switched off and the USB transceiver is disabled.
*
* When 'resume' is true, normal clocking and operations must all be restored.
*
*****************************************************************************/
void sam_udp_suspend(FAR struct usbdev_s *dev, bool resume);
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_ARM_SRC_SAMDL_SAM_USB_H */

View File

@@ -301,7 +301,7 @@ static inline void sam_xosc_config(void)
/* Configure the XOSC clock */
regval = BOARD_XOSC_STARTUPTIME
regval = BOARD_XOSC_STARTUPTIME;
#ifdef BOARD_XOSC_ISCRYSTAL
/* XOSC is a crystal */
@@ -383,7 +383,7 @@ static inline void sam_xosc32k_config(void)
/* Configure XOSC32K */
regval = BOARD_XOSC32K_STARTUPTIME
regval = BOARD_XOSC32K_STARTUPTIME;
#ifdef BOARD_XOSC32K_ISCRYSTAL
regval |= SYSCTRL_XOSC32K_XTALEN;

View File

@@ -480,6 +480,19 @@
#define BOARD_SERCOM5_FREQUENCY BOARD_GCLK0_FREQUENCY
/* USB definitions ******************************************************************/
/* This is the source clock generator for the GCLK_USB clock
*/
#define BOARD_USB_GCLKGEN 0
#define BOARD_USB_FREQUENCY BOARD_GCLK0_FREQUENCY
/* default USB Pad calibration (not used yet by USB driver) */
#define BOARD_USB_PADCAL_P 29
#define BOARD_USB_PADCAL_N 5
#define BOARD_USB_PADCAL_TRIM 3
/* LED definitions ******************************************************************/
/* There are three LEDs on board the SAMD21 Xplained Pro board: The EDBG
* controls two of the LEDs, a power LED and a status LED. There is only

View File

@@ -604,6 +604,19 @@
#define BOARD_SERCOM5_FREQUENCY BOARD_GCLK0_FREQUENCY
/* USB definitions ******************************************************************/
/* This is the source clock generator for the GCLK_USB clock
*/
#define BOARD_USB_GCLKGEN 0
#define BOARD_USB_FREQUENCY BOARD_GCLK0_FREQUENCY
/* default USB Pad calibration (not used yet by USB driver) */
#define BOARD_USB_PADCAL_P 29
#define BOARD_USB_PADCAL_N 5
#define BOARD_USB_PADCAL_TRIM 3
/* LED definitions ******************************************************************/
/* There are three LEDs on board the SAML21 Xplained Pro board: The EDBG
* controls two of the LEDs, a power LED and a status LED. There is only

View File

@@ -64,6 +64,11 @@
# define __SOCKFD_OFFSET 0
#endif
/* Capabilities of a socket */
#define SOCKCAP_NONBLOCKING (1 << 0) /* Bit 0: Socket supports non-blocking
* operation. */
/****************************************************************************
* Public Types
****************************************************************************/
@@ -94,6 +99,39 @@ typedef uint16_t sockopt_t;
typedef uint16_t socktimeo_t;
/* This type defines the type of the socket capabilities set */
typedef uint8_t sockcaps_t;
/* This callbacks are socket operations that may be performed on a socket of
* a given address family.
*/
struct socket; /* Forward reference */
struct sock_intf_s
{
CODE int (*si_setup)(FAR struct socket *psock, int protocol);
CODE sockcaps_t (*si_sockcaps)(FAR struct socket *psock);
CODE void (*si_addref)(FAR struct socket *psock);
CODE int (*si_bind)(FAR struct socket *psock,
FAR const struct sockaddr *addr, socklen_t addrlen);
CODE int (*si_listen)(FAR struct socket *psock, int backlog);
CODE int (*si_connect)(FAR struct socket *psock,
FAR const struct sockaddr *addr, socklen_t addrlen);
CODE int (*si_accept)(FAR struct socket *psock, FAR struct sockaddr *addr,
FAR socklen_t *addrlen, FAR struct socket *newsock);
CODE ssize_t (*si_send)(FAR struct socket *psock, FAR const void *buf,
size_t len, int flags);
CODE ssize_t (*si_sendto)(FAR struct socket *psock, FAR const void *buf,
size_t len, int flags, FAR const struct sockaddr *to,
socklen_t tolen);
CODE ssize_t (*si_recvfrom)(FAR struct socket *psock, FAR void *buf,
size_t len, int flags, FAR struct sockaddr *from,
FAR socklen_t *fromlen);
CODE int (*si_close)(FAR struct socket *psock);
};
/* This is the internal representation of a socket reference by a file
* descriptor.
*/
@@ -120,6 +158,10 @@ struct socket
FAR void *s_conn; /* Connection: struct tcp_conn_s or udp_conn_s */
/* Socket interface */
FAR const struct sock_intf_s *s_sockif;
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS
/* Callback instance for TCP send */

View File

@@ -209,7 +209,6 @@ static void copy_base62(FAR char *dest, int len)
* that full path.
*
* Returned Value:
*
* Upon successful completion, mkstemp() returns an open file descriptor.
* Otherwise, -1 is returned if no suitable file could be created.
*
@@ -284,6 +283,8 @@ int mkstemp(FAR char *path_template)
return fd;
}
retries--;
}
/* We could not find an unique filename */

View File

@@ -224,6 +224,7 @@ void icmpv6_input(FAR struct net_driver_s *dev)
case ICMPV6_ROUTER_ADVERTISE:
{
FAR struct icmpv6_router_advertise_s *adv;
FAR uint8_t *options;
uint16_t pktlen;
uint16_t optlen;
int ndx;
@@ -241,14 +242,17 @@ void icmpv6_input(FAR struct net_driver_s *dev)
optlen = ICMPv6_RADV_OPTLEN(pktlen);
/* We need to have a valid router advertisement with a Prefix and
* with the "A" bit set in the flags.
* with the "A" bit set in the flags. Options immediately follow
* the ICMPv6 router advertisement.
*/
adv = ICMPv6RADVERTISE;
options = (FAR uint8_t *)adv + sizeof(struct icmpv6_router_advertise_s);
for (ndx = 0; ndx + sizeof(struct icmpv6_prefixinfo_s) <= optlen; )
{
FAR struct icmpv6_prefixinfo_s *opt =
(FAR struct icmpv6_prefixinfo_s *)&adv->options[ndx];
(FAR struct icmpv6_prefixinfo_s *)&options[ndx];
/* Is this the sought for prefix? Is it the correct size? Is
* the "A" flag set?

View File

@@ -39,6 +39,7 @@ ifeq ($(CONFIG_NET_LOCAL),y)
NET_CSRCS += local_conn.c local_release.c local_bind.c local_fifo.c
NET_CSRCS += local_recvfrom.c local_sendpacket.c local_recvutils.c
NET_CSRCS += local_sockif.c
ifeq ($(CONFIG_NET_LOCAL_STREAM),y)
NET_CSRCS += local_connect.c local_listen.c local_accept.c local_send.c

View File

@@ -51,6 +51,8 @@
#include <stdint.h>
#include <poll.h>
#include <nuttx/net/net.h>
#ifdef CONFIG_NET_LOCAL
/****************************************************************************
@@ -77,6 +79,7 @@
/****************************************************************************
* Public Type Definitions
****************************************************************************/
/* Local, Unix domain socket types */
enum local_type_e
@@ -204,6 +207,10 @@ extern "C"
# define EXTERN extern
#endif
/* The local socket interface */
EXTERN const struct sock_intf_s g_local_sockif;
#ifdef CONFIG_NET_LOCAL_STREAM
/* A list of all SOCK_STREAM listener connections */
@@ -302,26 +309,31 @@ int local_release(FAR struct local_conn_s *conn);
* Name: local_listen
*
* Description:
* Listen for a new connection of a SOCK_STREAM Unix domain socket.
* To accept connections, a socket is first created with psock_socket(), a
* willingness to accept incoming connections and a queue limit for
* incoming connections are specified with psock_listen(), and then the
* connections are accepted with psock_accept(). For the case of local
* Unix sockets, psock_listen() calls this function. The psock_listen()
* call applies only to sockets of type SOCK_STREAM or SOCK_SEQPACKET.
*
* This function is called as part of the implementation of listen();
*
* Input Parameters:
* server - A reference to the server-side local connection structure
* backlog - Maximum number of pending connections.
* Parameters:
* psock Reference to an internal, boound socket structure.
* backlog The maximum length the queue of pending connections may grow.
* If a connection request arrives with the queue full, the client
* may receive an error with an indication of ECONNREFUSED or,
* if the underlying protocol supports retransmission, the request
* may be ignored so that retries succeed.
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
* Assumptions:
* The network is NOT locked
* On success, zero is returned. On error, a negated errno value is
* returned. See list() for the set of appropriate error values.
*
****************************************************************************/
int local_listen(FAR struct local_conn_s *server, int backlog);
int local_listen(FAR struct socket *psock, int backlog);
/****************************************************************************
* Name: psock_local_accept
* Name: local_accept
*
* Description:
* This function implements accept() for Unix domain sockets. See the
@@ -343,7 +355,7 @@ int local_listen(FAR struct local_conn_s *server, int backlog);
*
****************************************************************************/
int psock_local_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
int local_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
FAR socklen_t *addrlen, FAR void **newconn);
/****************************************************************************
@@ -421,7 +433,7 @@ ssize_t psock_local_sendto(FAR struct socket *psock, FAR const void *buf,
int local_send_packet(int fd, FAR const uint8_t *buf, size_t len);
/****************************************************************************
* Name: psock_recvfrom
* Name: local_recvfrom
*
* Description:
* recvfrom() receives messages from a local socket, and may be used to
@@ -448,7 +460,7 @@ int local_send_packet(int fd, FAR const uint8_t *buf, size_t len);
*
****************************************************************************/
ssize_t psock_local_recvfrom(FAR struct socket *psock, FAR void *buf,
ssize_t local_recvfrom(FAR struct socket *psock, FAR void *buf,
size_t len, int flags, FAR struct sockaddr *from,
FAR socklen_t *fromlen);

View File

@@ -88,7 +88,7 @@ static int local_waitlisten(FAR struct local_conn_s *server)
****************************************************************************/
/****************************************************************************
* Name: psock_local_accept
* Name: local_accept
*
* Description:
* This function implements accept() for Unix domain sockets. See the
@@ -110,7 +110,7 @@ static int local_waitlisten(FAR struct local_conn_s *server)
*
****************************************************************************/
int psock_local_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
int local_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
FAR socklen_t *addrlen, FAR void **newconn)
{
@@ -122,6 +122,18 @@ int psock_local_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
/* Some sanity checks */
DEBUGASSERT(psock && psock->s_conn);
/* Is the socket a stream? */
if (psock->s_domain != PF_LOCAL || psock->s_type != SOCK_STREAM)
{
return -EOPNOTSUPP;
}
/* Verify that a valid memory block has been provided to receive the
* address
*/
server = (FAR struct local_conn_s *)psock->s_conn;
if (server->lc_proto != SOCK_STREAM ||
@@ -213,7 +225,7 @@ int psock_local_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
/* Return the address family */
if (addr)
if (addr != NULL)
{
ret = local_getaddr(client, addr, addrlen);
}

View File

@@ -66,29 +66,46 @@ dq_queue_t g_local_listeners;
* Name: local_listen
*
* Description:
* Listen for a new connection of a SOCK_STREAM Unix domain socket.
* To accept connections, a socket is first created with psock_socket(), a
* willingness to accept incoming connections and a queue limit for
* incoming connections are specified with psock_listen(), and then the
* connections are accepted with psock_accept(). For the case of local
* Unix sockets, psock_listen() calls this function. The psock_listen()
* call applies only to sockets of type SOCK_STREAM or SOCK_SEQPACKET.
*
* This function is called as part of the implementation of listen();
*
* Input Parameters:
* server - A reference to the server-side local connection structure
* backlog - Maximum number of pending connections.
* Parameters:
* psock Reference to an internal, boound socket structure.
* backlog The maximum length the queue of pending connections may grow.
* If a connection request arrives with the queue full, the client
* may receive an error with an indication of ECONNREFUSED or,
* if the underlying protocol supports retransmission, the request
* may be ignored so that retries succeed.
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
* Assumptions:
* The network is NOT locked
* On success, zero is returned. On error, a negated errno value is
* returned. See list() for the set of appropriate error values.
*
****************************************************************************/
int local_listen(FAR struct local_conn_s *server, int backlog)
int local_listen(FAR struct socket *psock, int backlog)
{
FAR struct local_conn_s *server;
/* Verify that the sockfd corresponds to a connected SOCK_STREAM in this
* address family.
*/
if (psock->s_domain != PF_LOCAL || psock->s_type != SOCK_STREAM)
{
nerr("ERROR: Unsupported socket family=%d or socket type=%d\n",
psocl->s_domain, psock->s_type);
return -EOPNOTSUPP;
}
server = (FAR struct local_conn_s *)psock->s_conn;
/* Some sanity checks */
DEBUGASSERT(server);
if (server->lc_proto != SOCK_STREAM ||
server->lc_state == LOCAL_STATE_UNBOUND ||
server->lc_type != LOCAL_TYPE_PATHNAME)

View File

@@ -387,11 +387,11 @@ errout_with_halfduplex:
****************************************************************************/
/****************************************************************************
* Name: psock_local_recvfrom
* Name: local_recvfrom
*
* Description:
* psock_local_recvfrom() receives messages from a local socket and may be
* used to receive data on a socket whether or not it is connection-oriented.
* local_recvfrom() receives messages from a local socket and may be used
* to receive data on a socket whether or not it is connection-oriented.
*
* If from is not NULL, and the underlying protocol provides the source
* address, this source address is filled in. The argument fromlen
@@ -409,12 +409,13 @@ errout_with_halfduplex:
* Returned Value:
* On success, returns the number of characters received. If no data is
* available to be received and the peer has performed an orderly shutdown,
* recv() will return 0. Otherwise, on errors, -1 is returned, and errno
* is set appropriately (see receive from for the complete list).
* recv() will return 0. Otherwise, on errors, a negated errno value is
* returned (see recv_from() for the complete list of appropriate error
* values).
*
****************************************************************************/
ssize_t psock_local_recvfrom(FAR struct socket *psock, FAR void *buf,
ssize_t local_recvfrom(FAR struct socket *psock, FAR void *buf,
size_t len, int flags, FAR struct sockaddr *from,
FAR socklen_t *fromlen)
{

574
net/local/local_sockif.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -39,7 +39,9 @@ ifeq ($(CONFIG_NET_PKT),y)
# Socket layer
SOCK_CSRCS += pkt_sockif.c
SOCK_CSRCS += pkt_send.c
SOCK_CSRCS += pkt_recvfrom.c
# Transport layer

View File

@@ -91,12 +91,17 @@ extern "C"
# define EXTERN extern
#endif
/* The packet socket interface */
EXTERN const struct sock_intf_s g_pkt_sockif;
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
struct net_driver_s; /* Forward reference */
struct eth_hdr_s; /* Forward reference */
struct socket; /* Forward reference */
/****************************************************************************
* Name: pkt_initialize()
@@ -197,6 +202,41 @@ uint16_t pkt_callback(FAR struct net_driver_s *dev,
/* pkt_input() is prototyped in include/nuttx/net/pkt.h */
/****************************************************************************
* Name: pkt_recvfrom
*
* Description:
* Implements the socket recvfrom interface for the case of the AF_INET
* and AF_INET6 address families. pkt_recvfrom() receives messages from
* a socket, and may be used to receive data on a socket whether or not it
* is connection-oriented.
*
* If 'from' is not NULL, and the underlying protocol provides the source
* address, this source address is filled in. The argument 'fromlen' is
* initialized to the size of the buffer associated with from, and
* modified on return to indicate the actual size of the address stored
* there.
*
* Parameters:
* psock A pointer to a NuttX-specific, internal socket structure
* buf Buffer to receive data
* len Length of buffer
* flags Receive flags
* from Address of source (may be NULL)
* fromlen The length of the address structure
*
* Returned Value:
* On success, returns the number of characters received. If no data is
* available to be received and the peer has performed an orderly shutdown,
* recv() will return 0. Otherwise, on errors, a negated errno value is
* returned (see recvfrom() for the list of appropriate error values).
*
****************************************************************************/
ssize_t pkt_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
int flags, FAR struct sockaddr *from,
FAR socklen_t *fromlen);
/****************************************************************************
* Name: pkt_find_device
*

485
net/pkt/pkt_recvfrom.c Normal file
View File

@@ -0,0 +1,485 @@
/****************************************************************************
* net/socket/pkt_recvfrom.c
*
* Copyright (C) 2007-2009, 2011-2017 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>
#ifdef CONFIG_NET
#include <sys/types.h>
#include <sys/socket.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <debug.h>
#include <assert.h>
#include <arch/irq.h>
#include <nuttx/clock.h>
#include <nuttx/semaphore.h>
#include <nuttx/net/net.h>
#include <nuttx/net/netdev.h>
#include "netdev/netdev.h"
#include "devif/devif.h"
#include "pkt/pkt.h"
#include "socket/socket.h"
#include <netpacket/packet.h>
/****************************************************************************
* Private Types
****************************************************************************/
struct pkt_recvfrom_s
{
FAR struct devif_callback_s *pr_cb; /* Reference to callback instance */
sem_t pr_sem; /* Semaphore signals recv completion */
size_t pr_buflen; /* Length of receive buffer */
uint8_t *pr_buffer; /* Pointer to receive buffer */
ssize_t pr_recvlen; /* The received length */
int pr_result; /* Success:OK, failure:negated errno */
};
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: pkt_add_recvlen
*
* Description:
* Update information about space available for new data and update size
* of data in buffer, This logic accounts for the case where
* recvfrom_udpreadahead() sets state.pr_recvlen == -1 .
*
* Parameters:
* pstate recvfrom state structure
* recvlen size of new data appended to buffer
*
* Returned Value:
* None
*
****************************************************************************/
static inline void pkt_add_recvlen(FAR struct pkt_recvfrom_s *pstate,
size_t recvlen)
{
if (pstate->pr_recvlen < 0)
{
pstate->pr_recvlen = 0;
}
pstate->pr_recvlen += recvlen;
pstate->pr_buffer += recvlen;
pstate->pr_buflen -= recvlen;
}
/****************************************************************************
* Name: pkt_recvfrom_newdata
*
* Description:
* Copy the read data from the packet
*
* Parameters:
* dev The structure of the network driver that caused the interrupt
* pstate recvfrom state structure
*
* Returned Value:
* None.
*
* Assumptions:
* The network is locked.
*
****************************************************************************/
static void pkt_recvfrom_newdata(FAR struct net_driver_s *dev,
FAR struct pkt_recvfrom_s *pstate)
{
size_t recvlen;
if (dev->d_len > pstate->pr_buflen)
{
recvlen = pstate->pr_buflen;
}
else
{
recvlen = dev->d_len;
}
/* Copy the new packet data into the user buffer */
memcpy(pstate->pr_buffer, dev->d_buf, recvlen);
ninfo("Received %d bytes (of %d)\n", (int)recvlen, (int)dev->d_len);
/* Update the accumulated size of the data read */
pkt_add_recvlen(pstate, recvlen);
}
/****************************************************************************
* Name: pkt_recvfrom_sender
*
* Description:
*
* Parameters:
*
* Returned Values:
*
* Assumptions:
*
****************************************************************************/
static inline void pkt_recvfrom_sender(FAR struct net_driver_s *dev,
FAR struct pkt_recvfrom_s *pstate)
{
}
/****************************************************************************
* Name: pkt_recvfrom_interrupt
*
* Description:
*
* Parameters:
*
* Returned Values:
*
* Assumptions:
*
****************************************************************************/
static uint16_t pkt_recvfrom_interrupt(FAR struct net_driver_s *dev,
FAR void *pvconn, FAR void *pvpriv,
uint16_t flags)
{
struct pkt_recvfrom_s *pstate = (struct pkt_recvfrom_s *)pvpriv;
ninfo("flags: %04x\n", flags);
/* 'priv' might be null in some race conditions (?) */
if (pstate)
{
/* If a new packet is available, then complete the read action. */
if ((flags & PKT_NEWDATA) != 0)
{
/* Copy the packet */
pkt_recvfrom_newdata(dev, pstate);
/* We are finished. */
ninfo("PKT done\n");
/* Don't allow any further call backs. */
pstate->pr_cb->flags = 0;
pstate->pr_cb->priv = NULL;
pstate->pr_cb->event = NULL;
#if 0
/* Save the sender's address in the caller's 'from' location */
pkt_recvfrom_sender(dev, pstate);
#endif
/* indicate that the data has been consumed */
flags &= ~PKT_NEWDATA;
/* Wake up the waiting thread, returning the number of bytes
* actually read.
*/
sem_post(&pstate->pr_sem);
}
}
return flags;
}
/****************************************************************************
* Name: pkt_recvfrom_initialize
*
* Description:
* Initialize the state structure
*
* Parameters:
* psock Pointer to the socket structure for the socket
* buf Buffer to receive data
* len Length of buffer
* pstate A pointer to the state structure to be initialized
*
* Returned Value:
* None
*
* Assumptions:
*
****************************************************************************/
static void pkt_recvfrom_initialize(FAR struct socket *psock, FAR void *buf,
size_t len, FAR struct sockaddr *infrom,
FAR socklen_t *fromlen,
FAR struct pkt_recvfrom_s *pstate)
{
/* Initialize the state structure. */
memset(pstate, 0, sizeof(struct pkt_recvfrom_s));
/* This semaphore is used for signaling and, hence, should not have
* priority inheritance enabled.
*/
(void)sem_init(&pstate->pr_sem, 0, 0); /* Doesn't really fail */
(void)sem_setprotocol(&pstate->pr_sem, SEM_PRIO_NONE);
pstate->pr_buflen = len;
pstate->pr_buffer = buf;
}
/* The only un-initialization that has to be performed is destroying the
* semaphore.
*/
#define pkt_recvfrom_uninitialize(s) sem_destroy(&(s)->pr_sem)
/****************************************************************************
* Name: pkt_recvfrom_result
*
* Description:
* Evaluate the result of the recv operations
*
* Parameters:
* result The result of the net_lockedwait operation (may indicate EINTR)
* pstate A pointer to the state structure to be initialized
*
* Returned Value:
* The result of the recv operation with errno set appropriately
*
* Assumptions:
*
****************************************************************************/
static ssize_t pkt_recvfrom_result(int result, struct pkt_recvfrom_s *pstate)
{
int save_errno = get_errno(); /* In case something we do changes it */
/* Check for a error/timeout detected by the interrupt handler. Errors are
* signaled by negative errno values for the rcv length
*/
if (pstate->pr_result < 0)
{
/* This might return EAGAIN on a timeout or ENOTCONN on loss of
* connection (TCP only)
*/
return pstate->pr_result;
}
/* If net_lockedwait failed, then we were probably reawakened by a signal. In
* this case, net_lockedwait will have set errno appropriately.
*/
if (result < 0)
{
return -save_errno;
}
return pstate->pr_recvlen;
}
/****************************************************************************
* Name: pkt_recvfrom_rxnotify
*
* Description:
* Notify the appropriate device driver that we are ready to receive a
* packet (PKT)
*
* Parameters:
* conn - The PKT connection structure
*
* Returned Value:
* None
*
****************************************************************************/
#if 0 /* Not implemented */
static void pkt_recvfrom_rxnotify(FAR struct pkt_conn_s *conn)
{
# warning Missing logic
}
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: pkt_recvfrom
*
* Description:
* Implements the socket recvfrom interface for the case of the AF_INET
* and AF_INET6 address families. pkt_recvfrom() receives messages from
* a socket, and may be used to receive data on a socket whether or not it
* is connection-oriented.
*
* If 'from' is not NULL, and the underlying protocol provides the source
* address, this source address is filled in. The argument 'fromlen' is
* initialized to the size of the buffer associated with from, and
* modified on return to indicate the actual size of the address stored
* there.
*
* Parameters:
* psock A pointer to a NuttX-specific, internal socket structure
* buf Buffer to receive data
* len Length of buffer
* flags Receive flags
* from Address of source (may be NULL)
* fromlen The length of the address structure
*
* Returned Value:
* On success, returns the number of characters received. If no data is
* available to be received and the peer has performed an orderly shutdown,
* recv() will return 0. Otherwise, on errors, a negated errno value is
* returned (see recvfrom() for the list of appropriate error values).
*
****************************************************************************/
ssize_t pkt_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
int flags, FAR struct sockaddr *from,
FAR socklen_t *fromlen)
{
FAR struct pkt_conn_s *conn = (FAR struct pkt_conn_s *)psock->s_conn;
FAR struct net_driver_s *dev;
struct pkt_recvfrom_s state;
ssize_t ret;
/* If a 'from' address has been provided, verify that it is large
* enough to hold this address family.
*/
if (from != NULL && *fromlen < sizeof(sa_family_t))
{
return -EINVAL;
}
if (psock->s_type != SOCK_RAW)
{
nerr("ERROR: Unsupported socket type: %d\n", psock->s_type);
ret = -ENOSYS;
}
/* Perform the packet recvfrom() operation */
/* Initialize the state structure. This is done with interrupts
* disabled because we don't want anything to happen until we
* are ready.
*/
net_lock();
pkt_recvfrom_initialize(psock, buf, len, from, fromlen, &state);
/* Get the device driver that will service this transfer */
dev = pkt_find_device(conn);
if (dev == NULL)
{
ret = -ENODEV;
goto errout_with_state;
}
/* TODO pkt_recvfrom_initialize() expects from to be of type sockaddr_in, but
* in our case is sockaddr_ll
*/
#if 0
ret = pkt_connect(conn, NULL);
if (ret < 0)
{
goto errout_with_state;
}
#endif
/* Set the socket state to receiving */
psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_RECV);
/* Set up the callback in the connection */
state.pr_cb = pkt_callback_alloc(dev, conn);
if (state.pr_cb)
{
state.pr_cb->flags = (PKT_NEWDATA | PKT_POLL);
state.pr_cb->priv = (FAR void *)&state;
state.pr_cb->event = pkt_recvfrom_interrupt;
/* Notify the device driver of the receive call */
#if 0 /* Not implemented */
pkt_recvfrom_rxnotify(conn);
#endif
/* Wait for either the receive to complete or for an error/timeout to occur.
* NOTES: (1) net_lockedwait 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.
*/
ret = net_lockedwait(&state.pr_sem);
/* Make sure that no further interrupts are processed */
pkt_callback_free(dev, conn, state.pr_cb);
ret = pkt_recvfrom_result(ret, &state);
}
else
{
ret = -EBUSY;
}
/* Set the socket state to idle */
psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_IDLE);
errout_with_state:
net_unlock();
pkt_recvfrom_uninitialize(&state);
return ret;
}
#endif /* CONFIG_NET */

551
net/pkt/pkt_sockif.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
############################################################################
# net/socket/Make.defs
#
# Copyright (C) 2014-2015 Gregory Nutt. All rights reserved.
# Copyright (C) 2014-2015, 2017 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
@@ -39,6 +39,16 @@ SOCK_CSRCS += bind.c connect.c getsockname.c recv.c recvfrom.c send.c
SOCK_CSRCS += sendto.c socket.c net_sockets.c net_close.c net_dupsd.c
SOCK_CSRCS += net_dupsd2.c net_clone.c net_poll.c net_vfcntl.c
# Socket address families
SOCK_CSRCS += net_sockif.c
ifeq ($(CONFIG_NET_IPv4),y)
SOCK_CSRCS += inet_sockif.c inet_recvfrom.c inet_connect.c inet_close.c
else ifeq ($(CONFIG_NET_IPv6),y)
SOCK_CSRCS += inet_sockif.c inet_recvfrom.c inet_connect.c inet_close.c
endif
# TCP/IP support
ifeq ($(CONFIG_NET_TCP),y)

View File

@@ -38,8 +38,6 @@
****************************************************************************/
#include <nuttx/config.h>
#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0 && \
(defined(CONFIG_NET_TCP) || defined(CONFIG_NET_LOCAL_STREAM))
#include <sys/types.h>
#include <sys/socket.h>
@@ -56,6 +54,8 @@
#include "socket/socket.h"
#include "usrsock/usrsock.h"
#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -115,8 +115,7 @@
* ENFILE
* The system maximum for file descriptors has been reached.
* EFAULT
* The addr parameter is not in a writable part of the user address
* space.
* The addr parameter is not in a writable part of the user address space.
* ENOBUFS or ENOMEM
* Not enough free memory.
* EPROTO
@@ -130,29 +129,20 @@ int psock_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
FAR socklen_t *addrlen, FAR struct socket *newsock)
{
int errcode;
#if defined(NET_TCP_HAVE_STACK) || defined(CONFIG_NET_LOCAL_STREAM)
int ret;
#endif
DEBUGASSERT(psock != NULL);
DEBUGASSERT(psock != NULL && psock->s_conn != NULL && newsock != NULL);
/* Treat as a cancellation point */
(void)enter_cancellation_point();
/* Is the socket a stream? */
/* May sure that the socket has been opened with socket() */
if (psock->s_type != SOCK_STREAM)
if (psock == NULL || psock->s_conn == NULL)
{
#ifdef CONFIG_NET_USRSOCK
if (psock->s_type == SOCK_USRSOCK_TYPE)
{
#warning "Missing logic"
}
#endif
errcode = EOPNOTSUPP;
goto errout;
nerr("ERROR: Socket invalid or not opened\n");
return -EINVAL;
}
/* Is the socket listening for a connection? */
@@ -163,127 +153,16 @@ int psock_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
goto errout;
}
/* Verify that a valid memory block has been provided to receive the
* address
*/
/* Let the address family's accept() method handle the operation */
if (addr)
{
/* If an address is provided, then the length must also be provided. */
DEBUGASSERT(addrlen);
/* A valid length depends on the address domain */
switch (psock->s_domain)
{
#ifdef CONFIG_NET_IPv4
case PF_INET:
{
if (*addrlen < sizeof(struct sockaddr_in))
{
errcode = EBADF;
goto errout;
}
}
break;
#endif /* CONFIG_NET_IPv4 */
#ifdef CONFIG_NET_IPv6
case PF_INET6:
{
if (*addrlen < sizeof(struct sockaddr_in6))
{
errcode = EBADF;
goto errout;
}
}
break;
#endif /* CONFIG_NET_IPv6 */
#ifdef CONFIG_NET_LOCAL_STREAM
case PF_LOCAL:
{
if (*addrlen < sizeof(sa_family_t))
{
errcode = EBADF;
goto errout;
}
}
break;
#endif /* CONFIG_NET_IPv6 */
default:
DEBUGPANIC();
errcode = EINVAL;
goto errout;
}
}
/* Initialize the socket structure. */
newsock->s_domain = psock->s_domain;
newsock->s_type = SOCK_STREAM;
/* Perform the correct accept operation for this address domain */
#ifdef CONFIG_NET_LOCAL_STREAM
#ifdef CONFIG_NET_TCP
if (psock->s_domain == PF_LOCAL)
#endif
{
/* Perform the local accept operation (with the network unlocked) */
ret = psock_local_accept(psock, addr, addrlen, &newsock->s_conn);
DEBUGASSERT(psock->s_sockif != NULL && psock->s_sockif->si_accept != NULL);
ret = psock->s_sockif->si_accept(psock, addr, addrlen, newsock);
if (ret < 0)
{
nerr("ERROR: si_accept failed: %d\n", ret);
errcode = -ret;
goto errout;
}
}
#endif /* CONFIG_NET_LOCAL_STREAM */
#ifdef CONFIG_NET_TCP
#ifdef CONFIG_NET_LOCAL_STREAM
else
#endif
{
#ifdef NET_TCP_HAVE_STACK
/* Perform the local accept operation (with the network locked) */
net_lock();
ret = psock_tcp_accept(psock, addr, addrlen, &newsock->s_conn);
if (ret < 0)
{
net_unlock();
errcode = -ret;
goto errout;
}
/* Begin monitoring for TCP connection events on the newly connected
* socket
*/
ret = net_startmonitor(newsock);
if (ret < 0)
{
/* net_startmonitor() can only fail on certain race conditions
* where the connection was lost just before this function was
* called. Undo everything we have done and return a failure.
*/
net_unlock();
errcode = -ret;
goto errout_after_accept;
}
net_unlock();
#else
errcode = EOPNOTSUPP;
goto errout;
#endif /* NET_TCP_HAVE_STACK */
}
#endif /* CONFIG_NET_TCP */
/* Mark the new socket as connected. */
@@ -293,11 +172,6 @@ int psock_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
leave_cancellation_point();
return OK;
#ifdef NET_TCP_HAVE_STACK
errout_after_accept:
psock_close(newsock);
#endif
errout:
set_errno(errcode);
leave_cancellation_point();
@@ -447,4 +321,4 @@ errout:
return ERROR;
}
#endif /* CONFIG_NET && CONFIG_NSOCKET_DESCRIPTORS && (CONFIG_NET_TCP || CONFIG_NET_LOCAL_STREAM) */
#endif /* CONFIG_NET && CONFIG_NSOCKET_DESCRIPTORS */

View File

@@ -1,7 +1,7 @@
/****************************************************************************
* net/socket/bind.c
*
* Copyright (C) 2007-2009, 2012, 2014-2016 Gregory Nutt. All rights reserved.
* Copyright (C) 2007-2009, 2012, 2014-2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -38,85 +38,23 @@
****************************************************************************/
#include <nuttx/config.h>
#ifdef CONFIG_NET
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#include <string.h>
#include <debug.h>
#include <assert.h>
#ifdef CONFIG_NET_PKT
# include <netpacket/packet.h>
#endif
#include <errno.h>
#include <debug.h>
#include <nuttx/net/net.h>
#include <nuttx/net/udp.h>
#include "socket/socket.h"
#include "netdev/netdev.h"
#include "tcp/tcp.h"
#include "udp/udp.h"
#include "pkt/pkt.h"
#include "local/local.h"
#include "usrsock/usrsock.h"
#ifdef CONFIG_NET
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: pkt_bind
*
* Description:
* Bind a raw socket to an network device.
*
* Parameters:
* conn AF_PACKET connection structure
* addr Peer address information
*
* Returned Value:
* 0 on success; -1 on error with errno set appropriately
*
****************************************************************************/
#ifdef CONFIG_NET_PKT
static int pkt_bind(FAR struct pkt_conn_s *conn,
FAR const struct sockaddr_ll *addr)
{
int ifindex;
#if 0
char hwaddr[6] = /* our MAC for debugging */
{
0x00, 0xa1, 0xb1, 0xc1, 0xd1, 0xe1
};
#endif
char hwaddr[6] = /* MAC from ifconfig */
{
0x00, 0xe0, 0xde, 0xad, 0xbe, 0xef
};
/* Look at the addr and identify network interface */
ifindex = addr->sll_ifindex;
#if 0
/* Get the MAC address of that interface */
memcpy(hwaddr, g_netdevices->d_mac.ether, 6);
#endif
/* Put ifindex and mac address into connection */
conn->ifindex = ifindex;
memcpy(conn->lmac, hwaddr, 6);
return OK;
}
#endif /* CONFIG_NET_PKT */
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -157,7 +95,6 @@ int psock_bind(FAR struct socket *psock, const struct sockaddr *addr,
#ifdef CONFIG_NET_PKT
FAR const struct sockaddr_ll *lladdr = (const struct sockaddr_ll *)addr;
#endif
socklen_t minlen;
int errcode;
int ret = OK;
@@ -169,165 +106,10 @@ int psock_bind(FAR struct socket *psock, const struct sockaddr *addr,
goto errout;
}
/* Verify that a valid address has been provided */
/* Let the address family's connect() method handle the operation */
switch (addr->sa_family)
{
#ifdef CONFIG_NET_IPv4
case AF_INET:
minlen = sizeof(struct sockaddr_in);
break;
#endif
#ifdef CONFIG_NET_IPv6
case AF_INET6:
minlen = sizeof(struct sockaddr_in6);
break;
#endif
#ifdef CONFIG_NET_LOCAL
case AF_LOCAL:
minlen = sizeof(sa_family_t);
break;
#endif
#ifdef CONFIG_NET_PKT
case AF_PACKET:
minlen = sizeof(struct sockaddr_ll);
break;
#endif
default:
nerr("ERROR: Unrecognized address family: %d\n", addr->sa_family);
errcode = EAFNOSUPPORT;
goto errout;
}
if (addrlen < minlen)
{
nerr("ERROR: Invalid address length: %d < %d\n", addrlen, minlen);
errcode = EBADF;
goto errout;
}
/* Perform the binding depending on the protocol type */
switch (psock->s_type)
{
#ifdef CONFIG_NET_USRSOCK
case SOCK_USRSOCK_TYPE:
{
FAR struct usrsock_conn_s *conn = psock->s_conn;
DEBUGASSERT(conn);
/* Perform the usrsock bind operation */
ret = usrsock_bind(conn, addr, addrlen);
}
break;
#endif
#ifdef CONFIG_NET_PKT
case SOCK_RAW:
ret = pkt_bind(psock->s_conn, lladdr);
break;
#endif
/* Bind a stream socket which may either be TCP/IP or a local, Unix
* domain socket.
*/
#if defined(CONFIG_NET_TCP) || defined(CONFIG_NET_LOCAL_STREAM)
case SOCK_STREAM:
{
#ifdef CONFIG_NET_LOCAL_STREAM
#ifdef CONFIG_NET_TCP
/* Is this a Unix domain socket? */
if (psock->s_domain == PF_LOCAL)
#endif
{
/* Bind the Unix domain connection structure */
ret = psock_local_bind(psock, addr, addrlen);
}
#endif /* CONFIG_NET_LOCAL_STREAM */
#ifdef CONFIG_NET_TCP
#ifdef CONFIG_NET_LOCAL_STREAM
else
#endif
{
#ifdef NET_TCP_HAVE_STACK
/* Bind the TCP/IP connection structure */
ret = tcp_bind(psock->s_conn, addr);
#else
ret = -ENOSYS;
#endif
}
#endif /* CONFIG_NET_TCP */
/* Mark the socket bound */
if (ret >= 0)
{
psock->s_flags |= _SF_BOUND;
}
}
break;
#endif /* CONFIG_NET_TCP || CONFIG_NET_LOCAL_STREAM */
/* Bind a datagram socket which may either be TCP/IP or a local, Unix
* domain socket.
*/
#if defined(CONFIG_NET_UDP) || defined(CONFIG_NET_LOCAL_DGRAM)
case SOCK_DGRAM:
{
#ifdef CONFIG_NET_LOCAL_DGRAM
#ifdef CONFIG_NET_UDP
/* Is this a Unix domain socket? */
if (psock->s_domain == PF_LOCAL)
#endif
{
/* Bind the Unix domain connection structure */
ret = psock_local_bind(psock, addr, addrlen);
}
#endif /* CONFIG_NET_LOCAL_DGRAM */
#ifdef CONFIG_NET_UDP
#ifdef CONFIG_NET_LOCAL_DGRAM
else
#endif
{
#ifdef NET_UDP_HAVE_STACK
/* Bind the UDPP/IP connection structure */
ret = udp_bind(psock->s_conn, addr);
#else
ret = -ENOSYS;
#endif
}
#endif /* CONFIG_NET_UDP */
/* Mark the socket bound */
if (ret >= 0)
{
psock->s_flags |= _SF_BOUND;
}
}
break;
#endif /* CONFIG_NET_UDP || CONFIG_NET_LOCAL_DGRAM */
default:
errcode = EBADF;
goto errout;
}
DEBUGASSERT(psock->s_sockif != NULL && psock->s_sockif->si_bind != NULL);
ret = psock->s_sockif->si_bind(psock, addr, addrlen);
/* Was the bind successful */

File diff suppressed because it is too large Load Diff

610
net/socket/inet_close.c Normal file

File diff suppressed because it is too large Load Diff

567
net/socket/inet_connect.c Normal file

File diff suppressed because it is too large Load Diff

1674
net/socket/inet_recvfrom.c Normal file

File diff suppressed because it is too large Load Diff

1022
net/socket/inet_sockif.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
/****************************************************************************
* net/socket/listen.c
*
* Copyright (C) 2007-2009, 201-2016 Gregory Nutt. All rights reserved.
* Copyright (C) 2007-2009, 201-2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -38,17 +38,15 @@
****************************************************************************/
#include <nuttx/config.h>
#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
#include <sys/socket.h>
#include <errno.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include "tcp/tcp.h"
#include "local/local.h"
#include "socket/socket.h"
#include "usrsock/usrsock.h"
#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
/****************************************************************************
* Public Functions
@@ -86,83 +84,29 @@
int psock_listen(FAR struct socket *psock, int backlog)
{
int errcode;
int ret;
DEBUGASSERT(psock != NULL);
/* Verify that the sockfd corresponds to a connected SOCK_STREAM */
if (psock->s_type != SOCK_STREAM || !psock->s_conn)
if (psock == NULL || psock->s_conn == NULL)
{
#ifdef CONFIG_NET_USRSOCK
if (psock->s_type == SOCK_USRSOCK_TYPE)
{
#warning "Missing logic"
}
#endif
errcode = EOPNOTSUPP;
nerr("ERROR: Invalid or unconnected socket\n");
errcode = EINVAL;
goto errout;
}
#ifdef CONFIG_NET_LOCAL
#ifdef CONFIG_NET_TCP
if (psock->s_domain == PF_LOCAL)
#endif
{
FAR struct local_conn_s *conn =
(FAR struct local_conn_s *)psock->s_conn;
/* Let the address family's listen() method handle the operation */
errcode = local_listen(conn, backlog);
if (errcode < 0)
DEBUGASSERT(psock->s_sockif != NULL && psock->s_sockif->si_listen != NULL);
ret = psock->s_sockif->si_listen(psock, backlog);
if (ret < 0)
{
errcode = -errcode;
nerr("ERROR: si_listen failed: %d\n", ret);
errcode = -ret;
goto errout;
}
}
#endif /* CONFIG_NET_LOCAL */
#ifdef CONFIG_NET_TCP
#ifdef CONFIG_NET_LOCAL
else
#endif
{
#ifdef NET_TCP_HAVE_STACK
FAR struct tcp_conn_s *conn =
(FAR struct tcp_conn_s *)psock->s_conn;
if (conn->lport <= 0)
{
errcode = EOPNOTSUPP;
goto errout;
}
/* Set up the backlog for this connection */
#ifdef CONFIG_NET_TCPBACKLOG
errcode = tcp_backlogcreate(conn, backlog);
if (errcode < 0)
{
errcode = -errcode;
goto errout;
}
#endif
/* Start listening to the bound port. This enables callbacks when
* accept() is called and enables poll()/select() logic.
*/
errcode = tcp_listen(conn);
if (errcode < 0)
{
errcode = -errcode;
goto errout;
}
#else
errcode = EOPNOTSUPP;
goto errout;
#endif /* NET_TCP_HAVE_STACK */
}
#endif /* CONFIG_NET_TCP */
psock->s_flags |= _SF_LISTENING;
return OK;

View File

@@ -79,6 +79,7 @@ int net_clone(FAR struct socket *psock1, FAR struct socket *psock2)
psock2->s_domain = psock1->s_domain; /* IP domain: PF_INET, PF_INET6, or PF_PACKET */
psock2->s_type = psock1->s_type; /* Protocol type: Only SOCK_STREAM or SOCK_DGRAM */
psock2->s_sockif = psock1->s_sockif; /* Socket interface */
psock2->s_flags = psock1->s_flags; /* See _SF_* definitions */
#ifdef CONFIG_NET_SOCKOPTS
psock2->s_options = psock1->s_options; /* Selected socket options */
@@ -94,65 +95,19 @@ int net_clone(FAR struct socket *psock1, FAR struct socket *psock2)
* instance for TCP send */
#endif
/* Increment the reference count on the connection */
/* Increment the reference count on the socket */
DEBUGASSERT(psock2->s_conn);
psock2->s_crefs = 1; /* One reference on the new socket itself */
#ifdef CONFIG_NET_LOCAL
if (psock2->s_domain == PF_LOCAL)
{
FAR struct local_conn_s *conn = psock2->s_conn;
DEBUGASSERT(conn->lc_crefs > 0 && conn->lc_crefs < 255);
conn->lc_crefs++;
}
else
#endif
#ifdef CONFIG_NET_PKT
if (psock2->s_type == SOCK_RAW)
{
FAR struct pkt_conn_s *conn = psock2->s_conn;
DEBUGASSERT(conn->crefs > 0 && conn->crefs < 255);
conn->crefs++;
}
else
#endif
#ifdef NET_TCP_HAVE_STACK
if (psock2->s_type == SOCK_STREAM)
{
FAR struct tcp_conn_s *conn = psock2->s_conn;
DEBUGASSERT(conn->crefs > 0 && conn->crefs < 255);
conn->crefs++;
}
else
#endif
#ifdef NET_UDP_HAVE_STACK
if (psock2->s_type == SOCK_DGRAM)
{
FAR struct udp_conn_s *conn = psock2->s_conn;
DEBUGASSERT(conn->crefs > 0 && conn->crefs < 255);
conn->crefs++;
}
else
#endif
#ifdef CONFIG_NET_USRSOCK
if (psock2->s_type == SOCK_USRSOCK_TYPE)
{
FAR struct usrsock_conn_s *conn = psock2->s_conn;
DEBUGASSERT(conn->crefs > 0 && conn->crefs < 255);
conn->crefs++;
}
else
#endif
{
nerr("ERROR: Unsupported type: %d\n", psock2->s_type);
ret = -EBADF;
}
/* Increment the reference count on the underlying connection structure
* for this address family type.
*/
DEBUGASSERT(psock2->s_sockif != NULL && psock2->s_sockif->si_addref != NULL);
psock2->s_sockif->si_addref(psock2);
net_unlock();
return ret;
}
#endif /* CONFIG_NET */

File diff suppressed because it is too large Load Diff

111
net/socket/net_sockif.c Normal file
View File

@@ -0,0 +1,111 @@
/****************************************************************************
* net/socket/net_sockif.c
*
* Copyright (C) 2017 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 <sys/types.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/net/net.h>
#include "local/local.h"
#include "pkt/pkt.h"
#include "socket/socket.h"
#ifdef CONFIG_NET
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: net_sockif
*
* Description:
* Return the socket interface associated with this address family.
*
* Parameters:
* family - Address family
*
* Returned Value:
* On success, a non-NULL instance of struct sock_intf_s is returned. NULL
* is returned only if the address family is not supported.
*
****************************************************************************/
FAR const struct sock_intf_s *net_sockif(sa_family_t family)
{
FAR const struct sock_intf_s *sockif = NULL;
/* Get the socket interface */
switch (family)
{
#if defined(CONFIG_NET_IPv4) || defined(CONFIG_NET_IPv6)
#ifdef CONFIG_NET_IPv4
case PF_INET:
#endif
#ifdef CONFIG_NET_IPv6
case PF_INET6:
#endif
sockif = &g_inet_sockif;
break;
#endif
#ifdef CONFIG_NET_LOCAL
case PF_LOCAL:
sockif = &g_local_sockif;
break;
#endif
#ifdef CONFIG_NET_PKT
case PF_PACKET:
sockif = &g_pkt_sockif;
break;
#endif
default:
nerr("ERROR: Address family unsupported: %d\n", family);
}
return sockif;
}
#endif /* CONFIG_NET */

View File

@@ -84,7 +84,7 @@ int net_vfcntl(int sockfd, int cmd, va_list ap)
/* Verify that the sockfd corresponds to valid, allocated socket */
if (!psock || psock->s_crefs <= 0)
if (psock == NULL || psock->s_crefs <= 0)
{
errcode = EBADF;
goto errout;
@@ -140,38 +140,25 @@ int net_vfcntl(int sockfd, int cmd, va_list ap)
*/
{
sockcaps_t sockcaps;
/* This summarizes the behavior of all NuttX sockets */
ret = O_RDWR | O_SYNC | O_RSYNC;
#if defined(CONFIG_NET_LOCAL) || defined(CONFIG_NET_TCP_READAHEAD) || \
defined(CONFIG_NET_UDP_READAHEAD)
/* Unix domain sockets may be non-blocking. TCP/IP and UDP/IP
* sockets may also be non-blocking if read-ahead is enabled
*/
if ((0
#ifdef CONFIG_NET_LOCAL
|| psock->s_domain == PF_LOCAL /* Unix domain stream or datagram */
#endif
#ifdef CONFIG_NET_TCP_READAHEAD
|| psock->s_type == SOCK_STREAM /* IP or Unix domain stream */
#endif
#ifdef CONFIG_NET_UDP_READAHEAD
|| psock->s_type == SOCK_DGRAM /* IP or Unix domain datagram */
#endif
) && _SS_ISNONBLOCK(psock->s_flags))
{
ret |= O_NONBLOCK;
}
#endif /* CONFIG_NET_LOCAL || CONFIG_NET_TCP_READAHEAD || CONFIG_NET_UDP_READAHEAD */
DEBUGASSERT(psock->s_sockif != NULL &&
psock->s_sockif->si_sockcaps != NULL);
sockcaps = psock->s_sockif->si_sockcaps(psock);
#ifdef CONFIG_NET_USRSOCK
if (psock->s_type == SOCK_USRSOCK_TYPE && _SS_ISNONBLOCK(psock->s_flags))
if ((sockcaps & SOCKCAP_NONBLOCKING) != 0 &&
_SS_ISNONBLOCK(psock->s_flags))
{
ret |= O_NONBLOCK;
}
#endif
}
break;
@@ -185,16 +172,19 @@ int net_vfcntl(int sockfd, int cmd, va_list ap)
*/
{
#if defined(CONFIG_NET_LOCAL) || defined(CONFIG_NET_TCP_READAHEAD) || \
defined(CONFIG_NET_UDP_READAHEAD) || defined(CONFIG_NET_USRSOCK)
/* Non-blocking is the only configurable option. And it applies
* only Unix domain sockets and to read operations on TCP/IP
* and UDP/IP sockets when read-ahead is enabled.
*/
int mode = va_arg(ap, int);
#if defined(CONFIG_NET_LOCAL_STREAM) || defined(CONFIG_NET_TCP_READAHEAD)
if (psock->s_type == SOCK_STREAM) /* IP or Unix domain stream */
sockcaps_t sockcaps;
DEBUGASSERT(psock->s_sockif != NULL &&
psock->s_sockif->si_sockcaps != NULL);
sockcaps = psock->s_sockif->si_sockcaps(psock);
if ((sockcaps & SOCKCAP_NONBLOCKING) != 0)
{
if ((mode & O_NONBLOCK) != 0)
{
@@ -206,37 +196,6 @@ int net_vfcntl(int sockfd, int cmd, va_list ap)
}
}
else
#endif
#if defined(CONFIG_NET_LOCAL_DGRAM) || defined(CONFIG_NET_UDP_READAHEAD)
if (psock->s_type == SOCK_DGRAM) /* IP or Unix domain datagram */
{
if ((mode & O_NONBLOCK) != 0)
{
psock->s_flags |= _SF_NONBLOCK;
}
else
{
psock->s_flags &= ~_SF_NONBLOCK;
}
}
else
#endif
#if defined(CONFIG_NET_USRSOCK)
if (psock->s_type == SOCK_USRSOCK_TYPE) /* usrsock socket */
{
if ((mode & O_NONBLOCK) != 0)
{
psock->s_flags |= _SF_NONBLOCK;
}
else
{
psock->s_flags &= ~_SF_NONBLOCK;
}
}
else
#endif
#endif /* CONFIG_NET_LOCAL || CONFIG_NET_TCP_READAHEAD ||
CONFIG_NET_UDP_READAHEAD || CONFIG_NET_USRSOCK */
{
nerr("ERROR: Non-blocking not supported for this socket\n");
}

File diff suppressed because it is too large Load Diff

View File

@@ -42,6 +42,8 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <assert.h>
#include <debug.h>
#include <nuttx/cancelpt.h>
@@ -51,7 +53,6 @@
#include "sixlowpan/sixlowpan.h"
#include "local/local.h"
#include "socket/socket.h"
#include "usrsock/usrsock.h"
/****************************************************************************
* Public Functions
@@ -126,132 +127,21 @@ ssize_t psock_send(FAR struct socket *psock, FAR const void *buf, size_t len,
{
ssize_t ret;
DEBUGASSERT(psock != NULL && buf != NULL);
/* Treat as a cancellation point */
(void)enter_cancellation_point();
switch (psock->s_type)
{
#if defined(CONFIG_NET_PKT)
case SOCK_RAW:
{
/* Raw packet send */
/* Let the address family's send() method handle the operation */
ret = psock_pkt_send(psock, buf, len);
}
break;
#endif
#if defined(CONFIG_NET_TCP) || defined(CONFIG_NET_LOCAL_STREAM)
case SOCK_STREAM:
{
#ifdef CONFIG_NET_LOCAL_STREAM
#ifdef CONFIG_NET_TCP
if (psock->s_domain == PF_LOCAL)
#endif
{
/* Local TCP packet send */
ret = psock_local_send(psock, buf, len, flags);
}
#endif /* CONFIG_NET_LOCAL_STREAM */
#ifdef CONFIG_NET_TCP
#ifdef CONFIG_NET_LOCAL_STREAM
else
#endif
{
#ifdef CONFIG_NET_6LOWPAN
/* Try 6LoWPAN TCP packet send */
ret = psock_6lowpan_tcp_send(psock, buf, len);
#if defined(CONFIG_NETDEV_MULTINIC) && defined(NET_TCP_HAVE_STACK)
if (ret < 0)
{
/* TCP/IP packet send */
ret = psock_tcp_send(psock, buf, len);
}
#endif /* CONFIG_NETDEV_MULTINIC && NET_TCP_HAVE_STACK */
#elif defined(NET_TCP_HAVE_STACK)
ret = psock_tcp_send(psock, buf, len);
#else
ret = -ENOSYS;
#endif /* CONFIG_NET_6LOWPAN */
}
#endif /* CONFIG_NET_TCP */
}
break;
#endif /* CONFIG_NET_TCP || CONFIG_NET_LOCAL_STREAM */
#ifdef CONFIG_NET_UDP
case SOCK_DGRAM:
{
#ifdef CONFIG_NET_LOCAL_DGRAM
#ifdef CONFIG_NET_UDP
if (psock->s_domain == PF_LOCAL)
#endif
{
/* Local UDP packet send */
#warning Missing logic
ret = -ENOSYS;
}
#endif /* CONFIG_NET_LOCAL_DGRAM */
#ifdef CONFIG_NET_UDP
#ifdef CONFIG_NET_LOCAL_DGRAM
else
#endif
{
#if defined(CONFIG_NET_6LOWPAN)
/* Try 6LoWPAN UDP packet send */
ret = psock_6lowpan_udp_send(psock, buf, len);
#if defined(CONFIG_NETDEV_MULTINIC) && defined(NET_UDP_HAVE_STACK)
if (ret < 0)
{
/* UDP/IP packet send */
ret = psock_udp_send(psock, buf, len);
}
#endif /* CONFIG_NETDEV_MULTINIC && NET_UDP_HAVE_STACK */
#elif defined(NET_UDP_HAVE_STACK)
/* Only UDP/IP packet send */
ret = psock_udp_send(psock, buf, len);
#else
ret = -ENOSYS;
#endif /* CONFIG_NET_6LOWPAN */
}
#endif /* CONFIG_NET_UDP */
}
break;
#endif /* CONFIG_NET_UDP */
#ifdef CONFIG_NET_USRSOCK
case SOCK_USRSOCK_TYPE:
{
ret = usrsock_sendto(psock, buf, len, NULL, 0);
}
break;
#endif /*CONFIG_NET_USRSOCK*/
default:
{
/* EDESTADDRREQ. Signifies that the socket is not connection-mode
* and no peer address is set.
*/
ret = -EDESTADDRREQ;
}
break;
}
DEBUGASSERT(psock->s_sockif != NULL && psock->s_sockif->si_send != NULL);
ret = psock->s_sockif->si_send(psock, buf, len, flags);
leave_cancellation_point();
if (ret < 0)
{
nerr("ERROR: socket si_send() (or usrsock_sendto()) failed: %d\n", ret);
set_errno(-ret);
ret = ERROR;
}

View File

@@ -42,6 +42,7 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <stdint.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
@@ -52,7 +53,6 @@
#include "sixlowpan/sixlowpan.h"
#include "local/local.h"
#include "socket/socket.h"
#include "usrsock/usrsock.h"
/****************************************************************************
* Public Functions
@@ -127,18 +127,16 @@ ssize_t psock_sendto(FAR struct socket *psock, FAR const void *buf,
size_t len, int flags, FAR const struct sockaddr *to,
socklen_t tolen)
{
socklen_t minlen;
#if defined(CONFIG_NET_UDP) || defined(CONFIG_NET_LOCAL_DGRAM) || \
defined(CONFIG_NET_USRSOCK)
ssize_t nsent;
#endif
int errcode;
DEBUGASSERT(psock != NULL && buf != NULL);
/* If to is NULL or tolen is zero, then this function is same as send (for
* connected socket types)
*/
if (!to || !tolen)
if (to == NULL || tolen <= 0)
{
#if defined(CONFIG_NET_TCP) || defined(CONFIG_NET_LOCAL_STREAM) || \
defined(CONFIG_NET_USRSOCK)
@@ -150,57 +148,6 @@ ssize_t psock_sendto(FAR struct socket *psock, FAR const void *buf,
#endif
}
#ifdef CONFIG_NET_USRSOCK
if (psock->s_type == SOCK_USRSOCK_TYPE)
{
/* Perform the usrsock sendto operation */
nsent = usrsock_sendto(psock, buf, len, to, tolen);
if (nsent < 0)
{
errcode = -nsent;
goto errout;
}
return nsent;
}
#endif
/* Verify that a valid address has been provided */
switch (to->sa_family)
{
#ifdef CONFIG_NET_IPv4
case AF_INET:
minlen = sizeof(struct sockaddr_in);
break;
#endif
#ifdef CONFIG_NET_IPv6
case AF_INET6:
minlen = sizeof(struct sockaddr_in6);
break;
#endif
#ifdef CONFIG_NET_LOCAL_DGRAM
case AF_LOCAL:
minlen = sizeof(sa_family_t);
break;
#endif
default:
nerr("ERROR: Unrecognized address family: %d\n", to->sa_family);
errcode = EAFNOSUPPORT;
goto errout;
}
if (tolen < minlen)
{
nerr("ERROR: Invalid address length: %d < %d\n", tolen, minlen);
errcode = EBADF;
goto errout;
}
/* Verify that the psock corresponds to valid, allocated socket */
if (!psock || psock->s_crefs <= 0)
@@ -210,68 +157,21 @@ ssize_t psock_sendto(FAR struct socket *psock, FAR const void *buf,
goto errout;
}
/* If this is a connected socket, then return EISCONN */
/* Let the address family's send() method handle the operation */
if (psock->s_type != SOCK_DGRAM)
{
nerr("ERROR: Connected socket\n");
errcode = EISCONN;
goto errout;
}
#if defined(CONFIG_NET_UDP) || defined(CONFIG_NET_LOCAL_DGRAM)
/* Now handle the sendto() operation according to the socket domain,
* currently either IP or Unix domains.
*/
#ifdef CONFIG_NET_LOCAL_DGRAM
#ifdef CONFIG_NET_UDP
if (psock->s_domain == PF_LOCAL)
#endif
{
nsent = psock_local_sendto(psock, buf, len, flags, to, tolen);
}
#endif /* CONFIG_NET_LOCAL_DGRAM */
#ifdef CONFIG_NET_UDP
#ifdef CONFIG_NET_LOCAL_DGRAM
else
#endif
{
#if defined(CONFIG_NET_6LOWPAN)
/* Try 6LoWPAN UDP packet sendto() */
nsent = psock_6lowpan_udp_sendto(psock, buf, len, flags, to, tolen);
#if defined(CONFIG_NETDEV_MULTINIC) && defined(NET_UDP_HAVE_STACK)
if (nsent < 0)
{
/* UDP/IP packet sendto */
nsent = psock_udp_sendto(psock, buf, len, flags, to, tolen);
}
#endif /* CONFIG_NETDEV_MULTINIC && NET_UDP_HAVE_STACK */
#elif defined(NET_UDP_HAVE_STACK)
nsent = psock_udp_sendto(psock, buf, len, flags, to, tolen);
#else
nsent = -ENOSYS;
#endif /* CONFIG_NET_6LOWPAN */
}
#endif /* CONFIG_NET_UDP */
DEBUGASSERT(psock->s_sockif != NULL && psock->s_sockif->si_send != NULL);
nsent = psock->s_sockif->si_send(psock, buf, len, flags);
/* Check if the domain-specific sendto() logic failed */
if (nsent < 0)
{
nerr("ERROR: UDP or Unix domain sendto() failed: %ld\n", (long)nsent);
nerr("ERROR: Family-specific send failed: %ld\n", (long)nsent);
errcode = -nsent;
goto errout;
}
return nsent;
#else
errcode = ENOSYS;
#endif /* CONFIG_NET_UDP || CONFIG_NET_LOCAL_DGRAM */
errout:
set_errno(errcode);

File diff suppressed because it is too large Load Diff

View File

@@ -149,6 +149,10 @@ extern "C"
#define EXTERN extern
#endif
#if defined(CONFIG_NET_IPv4) || defined(CONFIG_NET_IPv6)
EXTERN const struct sock_intf_s g_inet_sockif;
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
@@ -223,6 +227,23 @@ void sockfd_release(int sockfd);
FAR struct socket *sockfd_socket(int sockfd);
/****************************************************************************
* Name: net_sockif
*
* Description:
* Return the socket interface associated with this address family.
*
* Parameters:
* family - Address family
*
* Returned Value:
* On success, a non-NULL instance of struct sock_intf_s is returned. NULL
* is returned only if the address family is not supported.
*
****************************************************************************/
FAR const struct sock_intf_s *net_sockif(sa_family_t family);
/****************************************************************************
* Name: net_startmonitor
*
@@ -410,13 +431,99 @@ int net_timeo(systime_t start_time, socktimeo_t timeo);
* In this case the process will also receive a SIGPIPE unless
* MSG_NOSIGNAL is set.
*
* Assumptions:
*
****************************************************************************/
ssize_t psock_send(FAR struct socket *psock, FAR const void *buf, size_t len,
int flags);
/****************************************************************************
* Name: inet_connect
*
* Description:
* inet_connect() connects the local socket referred to by the structure
* 'psock' to the address specified by 'addr'. The addrlen argument
* specifies the size of 'addr'. The format of the address in 'addr' is
* determined by the address space of the socket 'psock'.
*
* If the socket 'psock' is of type SOCK_DGRAM then 'addr' is the address
* to which datagrams are sent by default, and the only address from which
* datagrams are received. If the socket is of type SOCK_STREAM or
* SOCK_SEQPACKET, this call attempts to make a connection to the socket
* that is bound to the address specified by 'addr'.
*
* Generally, connection-based protocol sockets may successfully
* inet_connect() only once; connectionless protocol sockets may use
* inet_connect() multiple times to change their association.
* Connectionless sockets may dissolve the association by connecting to
* an address with the sa_family member of sockaddr set to AF_UNSPEC.
*
* Parameters:
* psock Pointer to a socket structure initialized by psock_socket()
* addr Server address (form depends on type of socket)
* addrlen Length of actual 'addr'
*
* Returned Value:
* 0 on success; a negated errno value on failue. See connect() for the
* list of appropriate errno values to be returned.
*
****************************************************************************/
int inet_connect(FAR struct socket *psock, FAR const struct sockaddr *addr,
socklen_t addrlen);
/****************************************************************************
* Name: inet_recvfrom
*
* Description:
* Implements the socket recvfrom interface for the case of the AF_INET
* and AF_INET6 address families. inet_recvfrom() receives messages from
* a socket, and may be used to receive data on a socket whether or not it
* is connection-oriented.
*
* If 'from' is not NULL, and the underlying protocol provides the source
* address, this source address is filled in. The argument 'fromlen' is
* initialized to the size of the buffer associated with from, and
* modified on return to indicate the actual size of the address stored
* there.
*
* Parameters:
* psock A pointer to a NuttX-specific, internal socket structure
* buf Buffer to receive data
* len Length of buffer
* flags Receive flags
* from Address of source (may be NULL)
* fromlen The length of the address structure
*
* Returned Value:
* On success, returns the number of characters received. If no data is
* available to be received and the peer has performed an orderly shutdown,
* recv() will return 0. Otherwise, on errors, a negated errno value is
* returned (see recvfrom() for the list of appropriate error values).
*
****************************************************************************/
ssize_t inet_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
int flags, FAR struct sockaddr *from,
FAR socklen_t *fromlen);
/****************************************************************************
* Name: inet_close
*
* Description:
* Performs the close operation on an AF_INET or AF_INET6 socket instance
*
* Parameters:
* psock Socket instance
*
* Returned Value:
* 0 on success; -1 on error with errno set appropriately.
*
* Assumptions:
*
****************************************************************************/
int inet_close(FAR struct socket *psock);
#undef EXTERN
#if defined(__cplusplus)
}

View File

@@ -874,7 +874,7 @@ static void enable_feature(const char *destconfig, const char *varname)
int ret;
snprintf(g_buffer, BUFFER_SIZE,
"kconfig-tweak --file %s --disable %s",
"kconfig-tweak --file %s --enable %s",
destconfig, varname);
ret = system(g_buffer);