mirror of
https://github.com/apache/nuttx.git
synced 2026-03-26 18:23:50 +08:00
Merge remote-tracking branch 'origin/master' into composite
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
4056
arch/arm/src/samdl/sam_usb.c
Normal file
File diff suppressed because it is too large
Load Diff
99
arch/arm/src/samdl/sam_usb.h
Normal file
99
arch/arm/src/samdl/sam_usb.h
Normal 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 */
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,11 +99,44 @@ 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.
|
||||
*/
|
||||
|
||||
struct devif_callback_s; /* Forward reference */
|
||||
struct devif_callback_s; /* Forward reference */
|
||||
|
||||
struct socket
|
||||
{
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -209,9 +209,8 @@ 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.
|
||||
* 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 */
|
||||
|
||||
@@ -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;
|
||||
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?
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,8 +355,8 @@ int local_listen(FAR struct local_conn_s *server, int backlog);
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int psock_local_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
|
||||
FAR socklen_t *addrlen, FAR void **newconn);
|
||||
int local_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
|
||||
FAR socklen_t *addrlen, FAR void **newconn);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: psock_local_send
|
||||
@@ -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,9 +460,9 @@ 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,
|
||||
size_t len, int flags, FAR struct sockaddr *from,
|
||||
FAR socklen_t *fromlen);
|
||||
ssize_t local_recvfrom(FAR struct socket *psock, FAR void *buf,
|
||||
size_t len, int flags, FAR struct sockaddr *from,
|
||||
FAR socklen_t *fromlen);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: local_fifo_read
|
||||
|
||||
@@ -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,8 +110,8 @@ static int local_waitlisten(FAR struct local_conn_s *server)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int psock_local_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
|
||||
FAR socklen_t *addrlen, FAR void **newconn)
|
||||
int local_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
|
||||
FAR socklen_t *addrlen, FAR void **newconn)
|
||||
|
||||
{
|
||||
FAR struct local_conn_s *server;
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,14 +409,15 @@ 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,
|
||||
size_t len, int flags, FAR struct sockaddr *from,
|
||||
FAR socklen_t *fromlen)
|
||||
ssize_t local_recvfrom(FAR struct socket *psock, FAR void *buf,
|
||||
size_t len, int flags, FAR struct sockaddr *from,
|
||||
FAR socklen_t *fromlen)
|
||||
{
|
||||
DEBUGASSERT(psock && psock->s_conn && buf);
|
||||
|
||||
|
||||
574
net/local/local_sockif.c
Normal file
574
net/local/local_sockif.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
|
||||
@@ -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
485
net/pkt/pkt_recvfrom.c
Normal 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
551
net/pkt/pkt_sockif.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
DEBUGASSERT(psock->s_sockif != NULL && psock->s_sockif->si_accept != NULL);
|
||||
ret = psock->s_sockif->si_accept(psock, addr, addrlen, newsock);
|
||||
if (ret < 0)
|
||||
{
|
||||
/* 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);
|
||||
if (ret < 0)
|
||||
{
|
||||
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;
|
||||
nerr("ERROR: si_accept failed: %d\n", ret);
|
||||
errcode = -ret;
|
||||
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 */
|
||||
|
||||
@@ -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
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
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
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
1022
net/socket/inet_sockif.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
/* Let the address family's listen() method handle the operation */
|
||||
|
||||
DEBUGASSERT(psock->s_sockif != NULL && psock->s_sockif->si_listen != NULL);
|
||||
ret = psock->s_sockif->si_listen(psock, backlog);
|
||||
if (ret < 0)
|
||||
{
|
||||
FAR struct local_conn_s *conn =
|
||||
(FAR struct local_conn_s *)psock->s_conn;
|
||||
|
||||
errcode = local_listen(conn, backlog);
|
||||
if (errcode < 0)
|
||||
{
|
||||
errcode = -errcode;
|
||||
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;
|
||||
nerr("ERROR: si_listen failed: %d\n", ret);
|
||||
errcode = -ret;
|
||||
goto errout;
|
||||
#endif /* NET_TCP_HAVE_STACK */
|
||||
}
|
||||
#endif /* CONFIG_NET_TCP */
|
||||
|
||||
psock->s_flags |= _SF_LISTENING;
|
||||
return OK;
|
||||
|
||||
@@ -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
111
net/socket/net_sockif.c
Normal 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 */
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user