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

This commit is contained in:
Gregory Nutt 2016-04-14 08:40:24 -06:00
commit 0a01f5dfff
10 changed files with 563 additions and 136 deletions

View File

@ -11629,3 +11629,17 @@
no longer qualifies for inclusion in the open source repositories. no longer qualifies for inclusion in the open source repositories.
The code as of this data is still available in the Obsoleted The code as of this data is still available in the Obsoleted
repository at configs/nucleus2g (2016-04-12). repository at configs/nucleus2g (2016-04-12).
* arch/arm/src/stm32l4: Fix the STM32L4 SPI driver. That SPI driver is
quite different. They now handle frames of arbitrary size between 4
and 16 bits. It was broken before a new bit has to be set (rx fifo
threshold) to handle <= 8-bit transactions. If not set, the default is
16-bit packed >=8-bit frames and the RXNE bit is never set (it is set
when 16-bits are received). weird things as always.
This also add 8-bit access routines to the data register, because a
16-bit access to the data register when the frame size is below 9 bits
is interpreted as a packed dual frame exchange. Sebastien Lorquet
(2016-04-13).
* net/sockets/listen.c and accept.c and include/nuttx/net: Separate
out psock_listen() and psock_accepti() for internal OS usage
(2016-04-14).

View File

@ -55,8 +55,7 @@
* *
****************************************************c********************************/ ****************************************************c********************************/
/* /* This driver is ported from the stm32 one, which only supports 8 and 16 bits
* This driver is ported from the stm32 one, which only supports 8 and 16 bits
* transfers. The STM32L4 family supports frame size from 4 to 16 bits, but we do not * transfers. The STM32L4 family supports frame size from 4 to 16 bits, but we do not
* support that yet. For the moment, we replace uses of the CR1_DFF bit with a check * support that yet. For the moment, we replace uses of the CR1_DFF bit with a check
* of the CR2_DS[0..3] bits. If the value is SPI_CR2_DS_16BIT it means 16 bits, else 8 bits. * of the CR2_DS[0..3] bits. If the value is SPI_CR2_DS_16BIT it means 16 bits, else 8 bits.
@ -90,11 +89,13 @@
#include "stm32l4_dma.h" #include "stm32l4_dma.h"
#include "stm32l4_spi.h" #include "stm32l4_spi.h"
#if defined(CONFIG_STM32L4_SPI1) || defined(CONFIG_STM32L4_SPI2) || defined(CONFIG_STM32L4_SPI3) #if defined(CONFIG_STM32L4_SPI1) || defined(CONFIG_STM32L4_SPI2) || \
defined(CONFIG_STM32L4_SPI3)
/************************************************************************************ /************************************************************************************
* Pre-processor Definitions * Pre-processor Definitions
************************************************************************************/ ************************************************************************************/
/* Configuration ********************************************************************/ /* Configuration ********************************************************************/
/* SPI interrupts */ /* SPI interrupts */
@ -414,22 +415,62 @@ static inline uint16_t spi_getreg(FAR struct stm32l4_spidev_s *priv, uint8_t off
* *
************************************************************************************/ ************************************************************************************/
static inline void spi_putreg(FAR struct stm32l4_spidev_s *priv, uint8_t offset, uint16_t value) static inline void spi_putreg(FAR struct stm32l4_spidev_s *priv, uint8_t offset,
uint16_t value)
{ {
putreg16(value, priv->spibase + offset); putreg16(value, priv->spibase + offset);
} }
/************************************************************************************
* Name: spi_getreg8
*
* Description:
* Get the contents of the SPI register at offset
*
* Input Parameters:
* priv - private SPI device structure
* offset - offset to the register of interest
*
* Returned Value:
* The contents of the 8-bit register
*
************************************************************************************/
static inline uint8_t spi_getreg8(FAR struct stm32l4_spidev_s *priv, uint8_t offset)
{
return getreg8(priv->spibase + offset);
}
/************************************************************************************
* Name: spi_putreg8
*
* Description:
* Write a 8-bit value to the SPI register at offset
*
* Input Parameters:
* priv - private SPI device structure
* offset - offset to the register of interest
* value - the 8-bit value to be written
*
************************************************************************************/
static inline void spi_putreg8(FAR struct stm32l4_spidev_s *priv, uint8_t offset,
uint8_t value)
{
putreg8(value, priv->spibase + offset);
}
/************************************************************************************ /************************************************************************************
* Name: spi_readword * Name: spi_readword
* *
* Description: * Description:
* Read one byte from SPI * Read one word (TWO bytes!) from SPI
* *
* Input Parameters: * Input Parameters:
* priv - Device-specific state data * priv - Device-specific state data
* *
* Returned Value: * Returned Value:
* Byte as read * Word as read
* *
************************************************************************************/ ************************************************************************************/
@ -445,14 +486,39 @@ static inline uint16_t spi_readword(FAR struct stm32l4_spidev_s *priv)
} }
/************************************************************************************ /************************************************************************************
* Name: spi_writeword * Name: spi_readbyte
* *
* Description: * Description:
* Write one byte to SPI * Read one byte from SPI
* *
* Input Parameters: * Input Parameters:
* priv - Device-specific state data * priv - Device-specific state data
* byte - Byte to send *
* Returned Value:
* Byte as read
*
************************************************************************************/
static inline uint8_t spi_readbyte(FAR struct stm32l4_spidev_s *priv)
{
/* Wait until the receive buffer is not empty */
while ((spi_getreg(priv, STM32L4_SPI_SR_OFFSET) & SPI_SR_RXNE) == 0);
/* Then return the received byte */
return spi_getreg8(priv, STM32L4_SPI_DR_OFFSET);
}
/************************************************************************************
* Name: spi_writeword
*
* Description:
* Write one 16-bit frame to the SPI FIFO
*
* Input Parameters:
* priv - Device-specific state data
* byte - Word to send
* *
* Returned Value: * Returned Value:
* None * None
@ -470,6 +536,32 @@ static inline void spi_writeword(FAR struct stm32l4_spidev_s *priv, uint16_t wor
spi_putreg(priv, STM32L4_SPI_DR_OFFSET, word); spi_putreg(priv, STM32L4_SPI_DR_OFFSET, word);
} }
/************************************************************************************
* Name: spi_writebyte
*
* Description:
* Write one 8-bit frame to the SPI FIFO
*
* Input Parameters:
* priv - Device-specific state data
* byte - Byte to send
*
* Returned Value:
* None
*
************************************************************************************/
static inline void spi_writebyte(FAR struct stm32l4_spidev_s *priv, uint8_t byte)
{
/* Wait until the transmit buffer is empty */
while ((spi_getreg(priv, STM32L4_SPI_SR_OFFSET) & SPI_SR_TXE) == 0);
/* Then send the byte */
spi_putreg8(priv, STM32L4_SPI_DR_OFFSET, byte);
}
/************************************************************************************ /************************************************************************************
* Name: spi_16bitmode * Name: spi_16bitmode
* *
@ -486,7 +578,22 @@ static inline void spi_writeword(FAR struct stm32l4_spidev_s *priv, uint16_t wor
static inline bool spi_16bitmode(FAR struct stm32l4_spidev_s *priv) static inline bool spi_16bitmode(FAR struct stm32l4_spidev_s *priv)
{ {
return ((spi_getreg(priv, STM32L4_SPI_CR2_OFFSET) & SPI_CR2_DS_MASK) == SPI_CR2_DS_16BIT); uint8_t bits = priv->nbits;
/* Get the real number of bits */
if (bits < 0)
{
bits = -bits;
}
return (bits > 8);
/* Should we read the hardware regs? seems to be equivalent ~~ sebastien lorquet
* (20160413)
*/
// return ((spi_getreg(priv, STM32L4_SPI_CR2_OFFSET) & SPI_CR2_DS_MASK) == SPI_CR2_DS_16BIT);
} }
/************************************************************************************ /************************************************************************************
@ -761,11 +868,12 @@ static inline void spi_dmatxstart(FAR struct stm32l4_spidev_s *priv)
static void spi_modifycr(uint32_t addr, FAR struct stm32l4_spidev_s *priv, uint16_t setbits, uint16_t clrbits) static void spi_modifycr(uint32_t addr, FAR struct stm32l4_spidev_s *priv, uint16_t setbits, uint16_t clrbits)
{ {
uint16_t cr1; uint16_t cr;
cr1 = spi_getreg(priv, addr);
cr1 &= ~clrbits; cr = spi_getreg(priv, addr);
cr1 |= setbits; cr &= ~clrbits;
spi_putreg(priv, addr, cr1); cr |= setbits;
spi_putreg(priv, addr, cr);
} }
/************************************************************************************ /************************************************************************************
@ -1007,6 +1115,7 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
FAR struct stm32l4_spidev_s *priv = (FAR struct stm32l4_spidev_s *)dev; FAR struct stm32l4_spidev_s *priv = (FAR struct stm32l4_spidev_s *)dev;
uint16_t setbits1, setbits2; uint16_t setbits1, setbits2;
uint16_t clrbits1, clrbits2; uint16_t clrbits1, clrbits2;
int savbits = nbits;
spivdbg("nbits=%d\n", nbits); spivdbg("nbits=%d\n", nbits);
@ -1014,11 +1123,10 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
if (nbits != priv->nbits) if (nbits != priv->nbits)
{ {
/* Yes... Set CR1/2 appropriately */ /* Yes... Set CR1/2 appropriately */
/* Negative sign means LSBFIRST, set this in CR1*/
/* negative sign means LSBFIRST, set this in CR1*/ if (nbits < 0)
if(nbits<0)
{ {
setbits1 = SPI_CR1_LSBFIRST; setbits1 = SPI_CR1_LSBFIRST;
clrbits1 = 0; clrbits1 = 0;
@ -1030,8 +1138,9 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
clrbits1 = SPI_CR1_LSBFIRST; clrbits1 = SPI_CR1_LSBFIRST;
} }
/* set the number of bits (valid range 4-16) */ /* Set the number of bits (valid range 4-16) */
if(nbits<4 || nbits>16)
if (nbits < 4 || nbits > 16)
{ {
return; return;
} }
@ -1039,6 +1148,19 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
clrbits2 = SPI_CR2_DS_MASK; clrbits2 = SPI_CR2_DS_MASK;
setbits2 = SPI_CR2_DS_VAL(nbits); setbits2 = SPI_CR2_DS_VAL(nbits);
/* If nbits is <=8, then we are in byte mode and FRXTH shall be set
* (else, transaction will not complete).
*/
if (nbits < 9)
{
setbits2 |= SPI_CR2_FRXTH; /* RX FIFO Threshold = 1 byte */
}
else
{
clrbits2 |= SPI_CR2_FRXTH; /* RX FIFO Threshold = 2 bytes */
}
spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, 0, SPI_CR1_SPE); spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, 0, SPI_CR1_SPE);
spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, setbits1, clrbits1); spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, setbits1, clrbits1);
spi_modifycr(STM32L4_SPI_CR2_OFFSET, priv, setbits2, clrbits2); spi_modifycr(STM32L4_SPI_CR2_OFFSET, priv, setbits2, clrbits2);
@ -1046,7 +1168,7 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
/* Save the selection so the subsequence re-configurations will be faster */ /* Save the selection so the subsequence re-configurations will be faster */
priv->nbits = nbits; priv->nbits = savbits; // nbits has been clobbered... save the signed value.
} }
} }
@ -1074,16 +1196,38 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
DEBUGASSERT(priv && priv->spibase); DEBUGASSERT(priv && priv->spibase);
spi_writeword(priv, wd); /* According to the number of bits, access data register as word or byte
ret = spi_readword(priv); * This is absolutely required because of packing. With <=8 bit frames,
* two bytes are received by a 16-bit read of the data register!
*/
/* Check and clear any error flags (Reading from the SR clears the error flags) */ if (spi_16bitmode(priv))
{
spi_writeword(priv, wd);
ret = spi_readword(priv);
}
else
{
spi_writebyte(priv, (uint8_t)(wd & 0xFF));
ret = (uint16_t)spi_readbyte(priv);
}
/* Check and clear any error flags (Reading from the SR clears the error
* flags).
*/
regval = spi_getreg(priv, STM32L4_SPI_SR_OFFSET); regval = spi_getreg(priv, STM32L4_SPI_SR_OFFSET);
spivdbg("Sent: %04x Return: %04x Status: %02x\n", wd, ret, regval); if (spi_16bitmode(priv))
UNUSED(regval); {
spivdbg("Sent: %04x Return: %04x Status: %02x\n", wd, ret, regval);
}
else
{
spivdbg("Sent: %02x Return: %02x Status: %02x\n", wd, ret, regval);
}
UNUSED(regval);
return ret; return ret;
} }
@ -1341,7 +1485,7 @@ static void spi_bus_initialize(FAR struct stm32l4_spidev_s *priv)
spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, setbits, clrbits); spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, setbits, clrbits);
clrbits = SPI_CR2_DS_MASK; clrbits = SPI_CR2_DS_MASK;
setbits = SPI_CR2_DS_8BIT; setbits = SPI_CR2_DS_8BIT | SPI_CR2_FRXTH; /* FRXTH must be high in 8-bit mode */
spi_modifycr(STM32L4_SPI_CR2_OFFSET, priv, setbits, clrbits); spi_modifycr(STM32L4_SPI_CR2_OFFSET, priv, setbits, clrbits);
priv->frequency = 0; priv->frequency = 0;

View File

@ -85,6 +85,7 @@ CONFIG_ARCH="arm"
# CONFIG_ARCH_CHIP_DM320 is not set # CONFIG_ARCH_CHIP_DM320 is not set
# CONFIG_ARCH_CHIP_EFM32 is not set # CONFIG_ARCH_CHIP_EFM32 is not set
# CONFIG_ARCH_CHIP_IMX1 is not set # CONFIG_ARCH_CHIP_IMX1 is not set
# CONFIG_ARCH_CHIP_IMX6 is not set
# CONFIG_ARCH_CHIP_KINETIS is not set # CONFIG_ARCH_CHIP_KINETIS is not set
# CONFIG_ARCH_CHIP_KL is not set # CONFIG_ARCH_CHIP_KL is not set
# CONFIG_ARCH_CHIP_LM is not set # CONFIG_ARCH_CHIP_LM is not set
@ -103,6 +104,7 @@ CONFIG_ARCH="arm"
CONFIG_ARCH_CHIP_SAMV7=y CONFIG_ARCH_CHIP_SAMV7=y
# CONFIG_ARCH_CHIP_STM32 is not set # CONFIG_ARCH_CHIP_STM32 is not set
# CONFIG_ARCH_CHIP_STM32F7 is not set # CONFIG_ARCH_CHIP_STM32F7 is not set
# CONFIG_ARCH_CHIP_STM32L4 is not set
# CONFIG_ARCH_CHIP_STR71X is not set # CONFIG_ARCH_CHIP_STR71X is not set
# CONFIG_ARCH_CHIP_TMS570 is not set # CONFIG_ARCH_CHIP_TMS570 is not set
# CONFIG_ARCH_CHIP_MOXART is not set # CONFIG_ARCH_CHIP_MOXART is not set
@ -124,6 +126,8 @@ CONFIG_ARCH_CORTEXM7=y
# CONFIG_ARCH_CORTEXR7F is not set # CONFIG_ARCH_CORTEXR7F is not set
CONFIG_ARCH_FAMILY="armv7-m" CONFIG_ARCH_FAMILY="armv7-m"
CONFIG_ARCH_CHIP="samv7" CONFIG_ARCH_CHIP="samv7"
# CONFIG_ARM_TOOLCHAIN_IAR is not set
CONFIG_ARM_TOOLCHAIN_GNU=y
# CONFIG_ARMV7M_USEBASEPRI is not set # CONFIG_ARMV7M_USEBASEPRI is not set
CONFIG_ARCH_HAVE_CMNVECTOR=y CONFIG_ARCH_HAVE_CMNVECTOR=y
CONFIG_ARMV7M_CMNVECTOR=y CONFIG_ARMV7M_CMNVECTOR=y
@ -132,6 +136,7 @@ CONFIG_ARCH_HAVE_FPU=y
CONFIG_ARCH_HAVE_DPFPU=y CONFIG_ARCH_HAVE_DPFPU=y
CONFIG_ARCH_FPU=y CONFIG_ARCH_FPU=y
CONFIG_ARCH_DPFPU=y CONFIG_ARCH_DPFPU=y
# CONFIG_ARCH_HAVE_TRUSTZONE is not set
CONFIG_ARM_HAVE_MPU_UNIFIED=y CONFIG_ARM_HAVE_MPU_UNIFIED=y
CONFIG_ARM_MPU=y CONFIG_ARM_MPU=y
CONFIG_ARM_MPU_NREGIONS=16 CONFIG_ARM_MPU_NREGIONS=16
@ -148,6 +153,7 @@ CONFIG_ARMV7M_HAVE_ITCM=y
CONFIG_ARMV7M_HAVE_DTCM=y CONFIG_ARMV7M_HAVE_DTCM=y
# CONFIG_ARMV7M_ITCM is not set # CONFIG_ARMV7M_ITCM is not set
# CONFIG_ARMV7M_DTCM is not set # CONFIG_ARMV7M_DTCM is not set
# CONFIG_ARMV7M_TOOLCHAIN_IARW is not set
# CONFIG_ARMV7M_TOOLCHAIN_ATOLLIC is not set # CONFIG_ARMV7M_TOOLCHAIN_ATOLLIC is not set
# CONFIG_ARMV7M_TOOLCHAIN_BUILDROOT is not set # CONFIG_ARMV7M_TOOLCHAIN_BUILDROOT is not set
# CONFIG_ARMV7M_TOOLCHAIN_CODEREDW is not set # CONFIG_ARMV7M_TOOLCHAIN_CODEREDW is not set
@ -794,6 +800,8 @@ CONFIG_ARCH_LOWPUTC=y
CONFIG_LIB_SENDFILE_BUFSIZE=512 CONFIG_LIB_SENDFILE_BUFSIZE=512
# CONFIG_ARCH_ROMGETC is not set # CONFIG_ARCH_ROMGETC is not set
# CONFIG_ARCH_OPTIMIZED_FUNCTIONS is not set # CONFIG_ARCH_OPTIMIZED_FUNCTIONS is not set
CONFIG_ARCH_HAVE_TLS=y
# CONFIG_TLS is not set
# CONFIG_LIBC_NETDB is not set # CONFIG_LIBC_NETDB is not set
# CONFIG_NETDB_HOSTFILE is not set # CONFIG_NETDB_HOSTFILE is not set

View File

@ -99,6 +99,7 @@ CONFIG_ARCH="arm"
CONFIG_ARCH_CHIP_SAMV7=y CONFIG_ARCH_CHIP_SAMV7=y
# CONFIG_ARCH_CHIP_STM32 is not set # CONFIG_ARCH_CHIP_STM32 is not set
# CONFIG_ARCH_CHIP_STM32F7 is not set # CONFIG_ARCH_CHIP_STM32F7 is not set
# CONFIG_ARCH_CHIP_STM32L4 is not set
# CONFIG_ARCH_CHIP_STR71X is not set # CONFIG_ARCH_CHIP_STR71X is not set
# CONFIG_ARCH_CHIP_TMS570 is not set # CONFIG_ARCH_CHIP_TMS570 is not set
# CONFIG_ARCH_CHIP_MOXART is not set # CONFIG_ARCH_CHIP_MOXART is not set
@ -120,6 +121,8 @@ CONFIG_ARCH_CORTEXM7=y
# CONFIG_ARCH_CORTEXR7F is not set # CONFIG_ARCH_CORTEXR7F is not set
CONFIG_ARCH_FAMILY="armv7-m" CONFIG_ARCH_FAMILY="armv7-m"
CONFIG_ARCH_CHIP="samv7" CONFIG_ARCH_CHIP="samv7"
# CONFIG_ARM_TOOLCHAIN_IAR is not set
CONFIG_ARM_TOOLCHAIN_GNU=y
CONFIG_ARMV7M_USEBASEPRI=y CONFIG_ARMV7M_USEBASEPRI=y
CONFIG_ARCH_HAVE_CMNVECTOR=y CONFIG_ARCH_HAVE_CMNVECTOR=y
CONFIG_ARMV7M_CMNVECTOR=y CONFIG_ARMV7M_CMNVECTOR=y
@ -128,6 +131,7 @@ CONFIG_ARCH_HAVE_FPU=y
CONFIG_ARCH_HAVE_DPFPU=y CONFIG_ARCH_HAVE_DPFPU=y
CONFIG_ARCH_FPU=y CONFIG_ARCH_FPU=y
CONFIG_ARCH_DPFPU=y CONFIG_ARCH_DPFPU=y
# CONFIG_ARCH_HAVE_TRUSTZONE is not set
CONFIG_ARM_HAVE_MPU_UNIFIED=y CONFIG_ARM_HAVE_MPU_UNIFIED=y
# CONFIG_ARM_MPU is not set # CONFIG_ARM_MPU is not set
@ -143,6 +147,7 @@ CONFIG_ARMV7M_HAVE_ITCM=y
CONFIG_ARMV7M_HAVE_DTCM=y CONFIG_ARMV7M_HAVE_DTCM=y
# CONFIG_ARMV7M_ITCM is not set # CONFIG_ARMV7M_ITCM is not set
# CONFIG_ARMV7M_DTCM is not set # CONFIG_ARMV7M_DTCM is not set
# CONFIG_ARMV7M_TOOLCHAIN_IARW is not set
# CONFIG_ARMV7M_TOOLCHAIN_ATOLLIC is not set # CONFIG_ARMV7M_TOOLCHAIN_ATOLLIC is not set
# CONFIG_ARMV7M_TOOLCHAIN_BUILDROOT is not set # CONFIG_ARMV7M_TOOLCHAIN_BUILDROOT is not set
# CONFIG_ARMV7M_TOOLCHAIN_CODEREDW is not set # CONFIG_ARMV7M_TOOLCHAIN_CODEREDW is not set
@ -711,6 +716,8 @@ CONFIG_ARCH_LOWPUTC=y
CONFIG_LIB_SENDFILE_BUFSIZE=512 CONFIG_LIB_SENDFILE_BUFSIZE=512
# CONFIG_ARCH_ROMGETC is not set # CONFIG_ARCH_ROMGETC is not set
# CONFIG_ARCH_OPTIMIZED_FUNCTIONS is not set # CONFIG_ARCH_OPTIMIZED_FUNCTIONS is not set
CONFIG_ARCH_HAVE_TLS=y
# CONFIG_TLS is not set
# CONFIG_LIBC_NETDB is not set # CONFIG_LIBC_NETDB is not set
# CONFIG_NETDB_HOSTFILE is not set # CONFIG_NETDB_HOSTFILE is not set

View File

@ -81,6 +81,7 @@ CONFIG_ARCH="arm"
# CONFIG_ARCH_CHIP_DM320 is not set # CONFIG_ARCH_CHIP_DM320 is not set
# CONFIG_ARCH_CHIP_EFM32 is not set # CONFIG_ARCH_CHIP_EFM32 is not set
# CONFIG_ARCH_CHIP_IMX1 is not set # CONFIG_ARCH_CHIP_IMX1 is not set
# CONFIG_ARCH_CHIP_IMX6 is not set
# CONFIG_ARCH_CHIP_KINETIS is not set # CONFIG_ARCH_CHIP_KINETIS is not set
# CONFIG_ARCH_CHIP_KL is not set # CONFIG_ARCH_CHIP_KL is not set
# CONFIG_ARCH_CHIP_LM is not set # CONFIG_ARCH_CHIP_LM is not set
@ -99,6 +100,7 @@ CONFIG_ARCH="arm"
CONFIG_ARCH_CHIP_SAMV7=y CONFIG_ARCH_CHIP_SAMV7=y
# CONFIG_ARCH_CHIP_STM32 is not set # CONFIG_ARCH_CHIP_STM32 is not set
# CONFIG_ARCH_CHIP_STM32F7 is not set # CONFIG_ARCH_CHIP_STM32F7 is not set
# CONFIG_ARCH_CHIP_STM32L4 is not set
# CONFIG_ARCH_CHIP_STR71X is not set # CONFIG_ARCH_CHIP_STR71X is not set
# CONFIG_ARCH_CHIP_TMS570 is not set # CONFIG_ARCH_CHIP_TMS570 is not set
# CONFIG_ARCH_CHIP_MOXART is not set # CONFIG_ARCH_CHIP_MOXART is not set
@ -120,6 +122,8 @@ CONFIG_ARCH_CORTEXM7=y
# CONFIG_ARCH_CORTEXR7F is not set # CONFIG_ARCH_CORTEXR7F is not set
CONFIG_ARCH_FAMILY="armv7-m" CONFIG_ARCH_FAMILY="armv7-m"
CONFIG_ARCH_CHIP="samv7" CONFIG_ARCH_CHIP="samv7"
# CONFIG_ARM_TOOLCHAIN_IAR is not set
CONFIG_ARM_TOOLCHAIN_GNU=y
# CONFIG_ARMV7M_USEBASEPRI is not set # CONFIG_ARMV7M_USEBASEPRI is not set
CONFIG_ARCH_HAVE_CMNVECTOR=y CONFIG_ARCH_HAVE_CMNVECTOR=y
CONFIG_ARMV7M_CMNVECTOR=y CONFIG_ARMV7M_CMNVECTOR=y
@ -128,6 +132,7 @@ CONFIG_ARCH_HAVE_FPU=y
CONFIG_ARCH_HAVE_DPFPU=y CONFIG_ARCH_HAVE_DPFPU=y
CONFIG_ARCH_FPU=y CONFIG_ARCH_FPU=y
CONFIG_ARCH_DPFPU=y CONFIG_ARCH_DPFPU=y
# CONFIG_ARCH_HAVE_TRUSTZONE is not set
CONFIG_ARM_HAVE_MPU_UNIFIED=y CONFIG_ARM_HAVE_MPU_UNIFIED=y
# CONFIG_ARM_MPU is not set # CONFIG_ARM_MPU is not set
@ -143,6 +148,7 @@ CONFIG_ARMV7M_HAVE_ITCM=y
CONFIG_ARMV7M_HAVE_DTCM=y CONFIG_ARMV7M_HAVE_DTCM=y
# CONFIG_ARMV7M_ITCM is not set # CONFIG_ARMV7M_ITCM is not set
# CONFIG_ARMV7M_DTCM is not set # CONFIG_ARMV7M_DTCM is not set
# CONFIG_ARMV7M_TOOLCHAIN_IARW is not set
# CONFIG_ARMV7M_TOOLCHAIN_ATOLLIC is not set # CONFIG_ARMV7M_TOOLCHAIN_ATOLLIC is not set
# CONFIG_ARMV7M_TOOLCHAIN_BUILDROOT is not set # CONFIG_ARMV7M_TOOLCHAIN_BUILDROOT is not set
# CONFIG_ARMV7M_TOOLCHAIN_CODEREDW is not set # CONFIG_ARMV7M_TOOLCHAIN_CODEREDW is not set
@ -958,6 +964,8 @@ CONFIG_ARCH_LOWPUTC=y
CONFIG_LIB_SENDFILE_BUFSIZE=512 CONFIG_LIB_SENDFILE_BUFSIZE=512
# CONFIG_ARCH_ROMGETC is not set # CONFIG_ARCH_ROMGETC is not set
# CONFIG_ARCH_OPTIMIZED_FUNCTIONS is not set # CONFIG_ARCH_OPTIMIZED_FUNCTIONS is not set
CONFIG_ARCH_HAVE_TLS=y
# CONFIG_TLS is not set
CONFIG_LIBC_NETDB=y CONFIG_LIBC_NETDB=y
# CONFIG_NETDB_HOSTFILE is not set # CONFIG_NETDB_HOSTFILE is not set
CONFIG_NETDB_DNSCLIENT=y CONFIG_NETDB_DNSCLIENT=y

View File

@ -80,6 +80,7 @@ CONFIG_ARCH="arm"
# CONFIG_ARCH_CHIP_DM320 is not set # CONFIG_ARCH_CHIP_DM320 is not set
# CONFIG_ARCH_CHIP_EFM32 is not set # CONFIG_ARCH_CHIP_EFM32 is not set
# CONFIG_ARCH_CHIP_IMX1 is not set # CONFIG_ARCH_CHIP_IMX1 is not set
# CONFIG_ARCH_CHIP_IMX6 is not set
# CONFIG_ARCH_CHIP_KINETIS is not set # CONFIG_ARCH_CHIP_KINETIS is not set
# CONFIG_ARCH_CHIP_KL is not set # CONFIG_ARCH_CHIP_KL is not set
# CONFIG_ARCH_CHIP_LM is not set # CONFIG_ARCH_CHIP_LM is not set
@ -98,6 +99,7 @@ CONFIG_ARCH="arm"
CONFIG_ARCH_CHIP_SAMV7=y CONFIG_ARCH_CHIP_SAMV7=y
# CONFIG_ARCH_CHIP_STM32 is not set # CONFIG_ARCH_CHIP_STM32 is not set
# CONFIG_ARCH_CHIP_STM32F7 is not set # CONFIG_ARCH_CHIP_STM32F7 is not set
# CONFIG_ARCH_CHIP_STM32L4 is not set
# CONFIG_ARCH_CHIP_STR71X is not set # CONFIG_ARCH_CHIP_STR71X is not set
# CONFIG_ARCH_CHIP_TMS570 is not set # CONFIG_ARCH_CHIP_TMS570 is not set
# CONFIG_ARCH_CHIP_MOXART is not set # CONFIG_ARCH_CHIP_MOXART is not set
@ -119,6 +121,8 @@ CONFIG_ARCH_CORTEXM7=y
# CONFIG_ARCH_CORTEXR7F is not set # CONFIG_ARCH_CORTEXR7F is not set
CONFIG_ARCH_FAMILY="armv7-m" CONFIG_ARCH_FAMILY="armv7-m"
CONFIG_ARCH_CHIP="samv7" CONFIG_ARCH_CHIP="samv7"
# CONFIG_ARM_TOOLCHAIN_IAR is not set
CONFIG_ARM_TOOLCHAIN_GNU=y
# CONFIG_ARMV7M_USEBASEPRI is not set # CONFIG_ARMV7M_USEBASEPRI is not set
CONFIG_ARCH_HAVE_CMNVECTOR=y CONFIG_ARCH_HAVE_CMNVECTOR=y
CONFIG_ARMV7M_CMNVECTOR=y CONFIG_ARMV7M_CMNVECTOR=y
@ -127,6 +131,7 @@ CONFIG_ARCH_HAVE_FPU=y
CONFIG_ARCH_HAVE_DPFPU=y CONFIG_ARCH_HAVE_DPFPU=y
CONFIG_ARCH_FPU=y CONFIG_ARCH_FPU=y
CONFIG_ARCH_DPFPU=y CONFIG_ARCH_DPFPU=y
# CONFIG_ARCH_HAVE_TRUSTZONE is not set
CONFIG_ARM_HAVE_MPU_UNIFIED=y CONFIG_ARM_HAVE_MPU_UNIFIED=y
# CONFIG_ARM_MPU is not set # CONFIG_ARM_MPU is not set
@ -142,6 +147,7 @@ CONFIG_ARMV7M_HAVE_ITCM=y
CONFIG_ARMV7M_HAVE_DTCM=y CONFIG_ARMV7M_HAVE_DTCM=y
# CONFIG_ARMV7M_ITCM is not set # CONFIG_ARMV7M_ITCM is not set
# CONFIG_ARMV7M_DTCM is not set # CONFIG_ARMV7M_DTCM is not set
# CONFIG_ARMV7M_TOOLCHAIN_IARW is not set
# CONFIG_ARMV7M_TOOLCHAIN_ATOLLIC is not set # CONFIG_ARMV7M_TOOLCHAIN_ATOLLIC is not set
# CONFIG_ARMV7M_TOOLCHAIN_BUILDROOT is not set # CONFIG_ARMV7M_TOOLCHAIN_BUILDROOT is not set
# CONFIG_ARMV7M_TOOLCHAIN_CODEREDW is not set # CONFIG_ARMV7M_TOOLCHAIN_CODEREDW is not set
@ -786,6 +792,8 @@ CONFIG_ARCH_LOWPUTC=y
CONFIG_LIB_SENDFILE_BUFSIZE=512 CONFIG_LIB_SENDFILE_BUFSIZE=512
# CONFIG_ARCH_ROMGETC is not set # CONFIG_ARCH_ROMGETC is not set
# CONFIG_ARCH_OPTIMIZED_FUNCTIONS is not set # CONFIG_ARCH_OPTIMIZED_FUNCTIONS is not set
CONFIG_ARCH_HAVE_TLS=y
# CONFIG_TLS is not set
# CONFIG_LIBC_NETDB is not set # CONFIG_LIBC_NETDB is not set
# CONFIG_NETDB_HOSTFILE is not set # CONFIG_NETDB_HOSTFILE is not set

View File

@ -80,6 +80,7 @@ CONFIG_ARCH="arm"
# CONFIG_ARCH_CHIP_DM320 is not set # CONFIG_ARCH_CHIP_DM320 is not set
# CONFIG_ARCH_CHIP_EFM32 is not set # CONFIG_ARCH_CHIP_EFM32 is not set
# CONFIG_ARCH_CHIP_IMX1 is not set # CONFIG_ARCH_CHIP_IMX1 is not set
# CONFIG_ARCH_CHIP_IMX6 is not set
# CONFIG_ARCH_CHIP_KINETIS is not set # CONFIG_ARCH_CHIP_KINETIS is not set
# CONFIG_ARCH_CHIP_KL is not set # CONFIG_ARCH_CHIP_KL is not set
# CONFIG_ARCH_CHIP_LM is not set # CONFIG_ARCH_CHIP_LM is not set
@ -98,6 +99,7 @@ CONFIG_ARCH="arm"
CONFIG_ARCH_CHIP_SAMV7=y CONFIG_ARCH_CHIP_SAMV7=y
# CONFIG_ARCH_CHIP_STM32 is not set # CONFIG_ARCH_CHIP_STM32 is not set
# CONFIG_ARCH_CHIP_STM32F7 is not set # CONFIG_ARCH_CHIP_STM32F7 is not set
# CONFIG_ARCH_CHIP_STM32L4 is not set
# CONFIG_ARCH_CHIP_STR71X is not set # CONFIG_ARCH_CHIP_STR71X is not set
# CONFIG_ARCH_CHIP_TMS570 is not set # CONFIG_ARCH_CHIP_TMS570 is not set
# CONFIG_ARCH_CHIP_MOXART is not set # CONFIG_ARCH_CHIP_MOXART is not set
@ -119,6 +121,8 @@ CONFIG_ARCH_CORTEXM7=y
# CONFIG_ARCH_CORTEXR7F is not set # CONFIG_ARCH_CORTEXR7F is not set
CONFIG_ARCH_FAMILY="armv7-m" CONFIG_ARCH_FAMILY="armv7-m"
CONFIG_ARCH_CHIP="samv7" CONFIG_ARCH_CHIP="samv7"
# CONFIG_ARM_TOOLCHAIN_IAR is not set
CONFIG_ARM_TOOLCHAIN_GNU=y
# CONFIG_ARMV7M_USEBASEPRI is not set # CONFIG_ARMV7M_USEBASEPRI is not set
CONFIG_ARCH_HAVE_CMNVECTOR=y CONFIG_ARCH_HAVE_CMNVECTOR=y
CONFIG_ARMV7M_CMNVECTOR=y CONFIG_ARMV7M_CMNVECTOR=y
@ -127,6 +131,7 @@ CONFIG_ARCH_HAVE_FPU=y
CONFIG_ARCH_HAVE_DPFPU=y CONFIG_ARCH_HAVE_DPFPU=y
CONFIG_ARCH_FPU=y CONFIG_ARCH_FPU=y
CONFIG_ARCH_DPFPU=y CONFIG_ARCH_DPFPU=y
# CONFIG_ARCH_HAVE_TRUSTZONE is not set
CONFIG_ARM_HAVE_MPU_UNIFIED=y CONFIG_ARM_HAVE_MPU_UNIFIED=y
# CONFIG_ARM_MPU is not set # CONFIG_ARM_MPU is not set
@ -142,6 +147,7 @@ CONFIG_ARMV7M_HAVE_ITCM=y
CONFIG_ARMV7M_HAVE_DTCM=y CONFIG_ARMV7M_HAVE_DTCM=y
# CONFIG_ARMV7M_ITCM is not set # CONFIG_ARMV7M_ITCM is not set
# CONFIG_ARMV7M_DTCM is not set # CONFIG_ARMV7M_DTCM is not set
# CONFIG_ARMV7M_TOOLCHAIN_IARW is not set
# CONFIG_ARMV7M_TOOLCHAIN_ATOLLIC is not set # CONFIG_ARMV7M_TOOLCHAIN_ATOLLIC is not set
# CONFIG_ARMV7M_TOOLCHAIN_BUILDROOT is not set # CONFIG_ARMV7M_TOOLCHAIN_BUILDROOT is not set
# CONFIG_ARMV7M_TOOLCHAIN_CODEREDW is not set # CONFIG_ARMV7M_TOOLCHAIN_CODEREDW is not set
@ -933,6 +939,8 @@ CONFIG_ARCH_LOWPUTC=y
CONFIG_LIB_SENDFILE_BUFSIZE=512 CONFIG_LIB_SENDFILE_BUFSIZE=512
# CONFIG_ARCH_ROMGETC is not set # CONFIG_ARCH_ROMGETC is not set
# CONFIG_ARCH_OPTIMIZED_FUNCTIONS is not set # CONFIG_ARCH_OPTIMIZED_FUNCTIONS is not set
CONFIG_ARCH_HAVE_TLS=y
# CONFIG_TLS is not set
# CONFIG_LIBC_NETDB is not set # CONFIG_LIBC_NETDB is not set
# CONFIG_NETDB_HOSTFILE is not set # CONFIG_NETDB_HOSTFILE is not set

View File

@ -503,6 +503,106 @@ struct sockaddr; /* Forward reference. Defined in nuttx/include/sys/socket.h */
int psock_bind(FAR struct socket *psock, FAR const struct sockaddr *addr, int psock_bind(FAR struct socket *psock, FAR const struct sockaddr *addr,
socklen_t addrlen); socklen_t addrlen);
/****************************************************************************
* Function: psock_listen
*
* Description:
* 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(). The psock_listen() call
* applies only to sockets of type SOCK_STREAM or SOCK_SEQPACKET.
*
* 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:
* On success, zero is returned. On error, -1 is returned, and errno is set
* appropriately.
*
* EADDRINUSE
* Another socket is already listening on the same port.
* EOPNOTSUPP
* The socket is not of a type that supports the listen operation.
*
****************************************************************************/
int psock_listen(FAR struct socket *psock, int backlog);
/****************************************************************************
* Function: psock_accept
*
* Description:
* The psock_accept function is used with connection-based socket types
* (SOCK_STREAM, SOCK_SEQPACKET and SOCK_RDM). It extracts the first
* connection request on the queue of pending connections, creates a new
* connected socket with mostly the same properties as 'sockfd', and
* allocates a new socket descriptor for the socket, which is returned. The
* newly created socket is no longer in the listening state. The original
* socket 'sockfd' is unaffected by this call. Per file descriptor flags
* are not inherited across an psock_accept.
*
* The 'sockfd' argument is a socket descriptor that has been created with
* socket(), bound to a local address with bind(), and is listening for
* connections after a call to listen().
*
* On return, the 'addr' structure is filled in with the address of the
* connecting entity. The 'addrlen' argument initially contains the size
* of the structure pointed to by 'addr'; on return it will contain the
* actual length of the address returned.
*
* If no pending connections are present on the queue, and the socket is
* not marked as non-blocking, psock_accept blocks the caller until a
* connection is present. If the socket is marked non-blocking and no
* pending connections are present on the queue, psock_accept returns
* EAGAIN.
*
* Parameters:
* psock Reference to the listening socket structure
* addr Receives the address of the connecting client
* addrlen Input: allocated size of 'addr', Return: returned size of 'addr'
* newsock Location to return the accepted socket information.
*
* Returned Value:
* Returns 0 (OK) on success. On failure, it returns -1 (ERROR) with the
* errno variable set to indicate the nature of the error.
*
* EAGAIN or EWOULDBLOCK
* The socket is marked non-blocking and no connections are present to
* be accepted.
* EOPNOTSUPP
* The referenced socket is not of type SOCK_STREAM.
* EINTR
* The system call was interrupted by a signal that was caught before
* a valid connection arrived.
* ECONNABORTED
* A connection has been aborted.
* EINVAL
* Socket is not listening for connections.
* EMFILE
* The per-process limit of open file descriptors has been reached.
* 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.
* ENOBUFS or ENOMEM
* Not enough free memory.
* EPROTO
* Protocol error.
* EPERM
* Firewall rules forbid connection.
*
****************************************************************************/
int psock_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
FAR socklen_t *addrlen, FAR struct socket *newsock);
/**************************************************************************** /****************************************************************************
* Name: psock_connect * Name: psock_connect
* *

View File

@ -59,17 +59,17 @@
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Function: accept * Function: psock_accept
* *
* Description: * Description:
* The accept function is used with connection-based socket types * The psock_accept function is used with connection-based socket types
* (SOCK_STREAM, SOCK_SEQPACKET and SOCK_RDM). It extracts the first * (SOCK_STREAM, SOCK_SEQPACKET and SOCK_RDM). It extracts the first
* connection request on the queue of pending connections, creates a new * connection request on the queue of pending connections, creates a new
* connected socket with mostly the same properties as 'sockfd', and * connected socket with mostly the same properties as 'sockfd', and
* allocates a new socket descriptor for the socket, which is returned. The * allocates a new socket descriptor for the socket, which is returned. The
* newly created socket is no longer in the listening state. The original * newly created socket is no longer in the listening state. The original
* socket 'sockfd' is unaffected by this call. Per file descriptor flags * socket 'sockfd' is unaffected by this call. Per file descriptor flags
* are not inherited across an accept. * are not inherited across an psock_accept.
* *
* The 'sockfd' argument is a socket descriptor that has been created with * The 'sockfd' argument is a socket descriptor that has been created with
* socket(), bound to a local address with bind(), and is listening for * socket(), bound to a local address with bind(), and is listening for
@ -81,26 +81,24 @@
* actual length of the address returned. * actual length of the address returned.
* *
* If no pending connections are present on the queue, and the socket is * If no pending connections are present on the queue, and the socket is
* not marked as non-blocking, accept blocks the caller until a connection * not marked as non-blocking, psock_accept blocks the caller until a
* is present. If the socket is marked non-blocking and no pending * connection is present. If the socket is marked non-blocking and no
* connections are present on the queue, accept returns EAGAIN. * pending connections are present on the queue, psock_accept returns
* EAGAIN.
* *
* Parameters: * Parameters:
* sockfd The listening socket descriptor * psock Reference to the listening socket structure
* addr Receives the address of the connecting client * addr Receives the address of the connecting client
* addrlen Input: allocated size of 'addr', Return: returned size of 'addr' * addrlen Input: allocated size of 'addr', Return: returned size of 'addr'
* newsock Location to return the accepted socket information.
* *
* Returned Value: * Returned Value:
* Returns -1 on error. If it succeeds, it returns a non-negative integer * Returns 0 (OK) on success. On failure, it returns -1 (ERROR) with the
* that is a descriptor for the accepted socket. * errno variable set to indicate the nature of the error.
* *
* EAGAIN or EWOULDBLOCK * EAGAIN or EWOULDBLOCK
* The socket is marked non-blocking and no connections are present to * The socket is marked non-blocking and no connections are present to
* be accepted. * be accepted.
* EBADF
* The descriptor is invalid.
* ENOTSOCK
* The descriptor references a file, not a socket.
* EOPNOTSUPP * EOPNOTSUPP
* The referenced socket is not of type SOCK_STREAM. * The referenced socket is not of type SOCK_STREAM.
* EINTR * EINTR
@ -124,42 +122,17 @@
* EPERM * EPERM
* Firewall rules forbid connection. * Firewall rules forbid connection.
* *
* Assumptions:
*
****************************************************************************/ ****************************************************************************/
int accept(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen) int psock_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
FAR socklen_t *addrlen, FAR struct socket *newsock)
{ {
FAR struct socket *psock = sockfd_socket(sockfd);
FAR struct socket *pnewsock;
int newfd;
int err; int err;
int ret; int ret;
/* Verify that the sockfd corresponds to valid, allocated socket */ DEBUGASSERT(psock != NULL);
if (!psock || psock->s_crefs <= 0) /* Is the socket a stream? */
{
/* It is not a valid socket description. Distinguish between the cases
* where sockfd is a just valid and when it is a valid file descriptor used
* in the wrong context.
*/
#if CONFIG_NFILE_DESCRIPTORS > 0
if ((unsigned int)sockfd < CONFIG_NFILE_DESCRIPTORS)
{
err = ENOTSOCK;
}
else
#endif
{
err = EBADF;
}
goto errout;
}
/* We have a socket descriptor, but it is a stream? */
if (psock->s_type != SOCK_STREAM) if (psock->s_type != SOCK_STREAM)
{ {
@ -232,28 +205,10 @@ int accept(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen)
} }
} }
/* Allocate a socket descriptor for the new connection now (so that it
* cannot fail later)
*/
newfd = sockfd_allocate(0);
if (newfd < 0)
{
err = ENFILE;
goto errout;
}
pnewsock = sockfd_socket(newfd);
if (!pnewsock)
{
err = ENFILE;
goto errout_with_socket;
}
/* Initialize the socket structure. */ /* Initialize the socket structure. */
pnewsock->s_domain = psock->s_domain; newsock->s_domain = psock->s_domain;
pnewsock->s_type = SOCK_STREAM; newsock->s_type = SOCK_STREAM;
/* Perform the correct accept operation for this address domain */ /* Perform the correct accept operation for this address domain */
@ -264,11 +219,11 @@ int accept(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen)
{ {
/* Perform the local accept operation (with the network unlocked) */ /* Perform the local accept operation (with the network unlocked) */
ret = psock_local_accept(psock, addr, addrlen, &pnewsock->s_conn); ret = psock_local_accept(psock, addr, addrlen, &newsock->s_conn);
if (ret < 0) if (ret < 0)
{ {
err = -ret; err = -ret;
goto errout_with_socket; goto errout;
} }
} }
#endif /* CONFIG_NET_LOCAL_STREAM */ #endif /* CONFIG_NET_LOCAL_STREAM */
@ -283,19 +238,19 @@ int accept(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen)
/* Perform the local accept operation (with the network locked) */ /* Perform the local accept operation (with the network locked) */
state = net_lock(); state = net_lock();
ret = psock_tcp_accept(psock, addr, addrlen, &pnewsock->s_conn); ret = psock_tcp_accept(psock, addr, addrlen, &newsock->s_conn);
if (ret < 0) if (ret < 0)
{ {
net_unlock(state); net_unlock(state);
err = -ret; err = -ret;
goto errout_with_socket; goto errout;
} }
/* Begin monitoring for TCP connection events on the newly connected /* Begin monitoring for TCP connection events on the newly connected
* socket * socket
*/ */
ret = net_startmonitor(pnewsock); ret = net_startmonitor(newsock);
if (ret < 0) if (ret < 0)
{ {
/* net_startmonitor() can only fail on certain race conditions /* net_startmonitor() can only fail on certain race conditions
@ -314,12 +269,145 @@ int accept(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen)
/* Mark the new socket as connected. */ /* Mark the new socket as connected. */
pnewsock->s_flags |= _SF_CONNECTED; newsock->s_flags |= _SF_CONNECTED;
pnewsock->s_flags &= ~_SF_CLOSED; newsock->s_flags &= ~_SF_CLOSED;
return newfd; return OK;
errout_after_accept: errout_after_accept:
psock_close(pnewsock); psock_close(newsock);
errout:
set_errno(err);
return ERROR;
}
/****************************************************************************
* Function: accept
*
* Description:
* The accept function is used with connection-based socket types
* (SOCK_STREAM, SOCK_SEQPACKET and SOCK_RDM). It extracts the first
* connection request on the queue of pending connections, creates a new
* connected socket with mostly the same properties as 'sockfd', and
* allocates a new socket descriptor for the socket, which is returned. The
* newly created socket is no longer in the listening state. The original
* socket 'sockfd' is unaffected by this call. Per file descriptor flags
* are not inherited across an accept.
*
* The 'sockfd' argument is a socket descriptor that has been created with
* socket(), bound to a local address with bind(), and is listening for
* connections after a call to listen().
*
* On return, the 'addr' structure is filled in with the address of the
* connecting entity. The 'addrlen' argument initially contains the size
* of the structure pointed to by 'addr'; on return it will contain the
* actual length of the address returned.
*
* If no pending connections are present on the queue, and the socket is
* not marked as non-blocking, accept blocks the caller until a connection
* is present. If the socket is marked non-blocking and no pending
* connections are present on the queue, accept returns EAGAIN.
*
* Parameters:
* sockfd The listening socket descriptor
* addr Receives the address of the connecting client
* addrlen Input: allocated size of 'addr', Return: returned size of 'addr'
*
* Returned Value:
* Returns -1 on error. If it succeeds, it returns a non-negative integer
* that is a descriptor for the accepted socket.
*
* EAGAIN or EWOULDBLOCK
* The socket is marked non-blocking and no connections are present to
* be accepted.
* EBADF
* The descriptor is invalid.
* ENOTSOCK
* The descriptor references a file, not a socket.
* EOPNOTSUPP
* The referenced socket is not of type SOCK_STREAM.
* EINTR
* The system call was interrupted by a signal that was caught before
* a valid connection arrived.
* ECONNABORTED
* A connection has been aborted.
* EINVAL
* Socket is not listening for connections.
* EMFILE
* The per-process limit of open file descriptors has been reached.
* 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.
* ENOBUFS or ENOMEM
* Not enough free memory.
* EPROTO
* Protocol error.
* EPERM
* Firewall rules forbid connection.
*
****************************************************************************/
int accept(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen)
{
FAR struct socket *psock = sockfd_socket(sockfd);
FAR struct socket *newsock;
int newfd;
int err;
int ret;
/* Verify that the sockfd corresponds to valid, allocated socket */
if (psock == NULL || psock->s_crefs <= 0)
{
/* It is not a valid socket description. Distinguish between the cases
* where sockfd is a just valid and when it is a valid file descriptor used
* in the wrong context.
*/
#if CONFIG_NFILE_DESCRIPTORS > 0
if ((unsigned int)sockfd < CONFIG_NFILE_DESCRIPTORS)
{
err = ENOTSOCK;
}
else
#endif
{
err = EBADF;
}
goto errout;
}
/* Allocate a socket descriptor for the new connection now (so that it
* cannot fail later)
*/
newfd = sockfd_allocate(0);
if (newfd < 0)
{
err = ENFILE;
goto errout;
}
newsock = sockfd_socket(newfd);
if (newsock == NULL)
{
err = ENFILE;
goto errout_with_socket;
}
ret = psock_accept(psock, addr, addrlen, newsock);
if (ret < 0)
{
/* The errno value has already been set */
sockfd_release(newfd);
return ERROR;
}
return newfd;
errout_with_socket: errout_with_socket:
sockfd_release(newfd); sockfd_release(newfd);

View File

@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
* net/socket/listen.c * net/socket/listen.c
* *
* Copyright (C) 2007-2009, 2015 Gregory Nutt. All rights reserved. * Copyright (C) 2007-2009, 201-2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -42,6 +42,7 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <errno.h> #include <errno.h>
#include <assert.h>
#include <debug.h> #include <debug.h>
#include "tcp/tcp.h" #include "tcp/tcp.h"
@ -53,17 +54,17 @@
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Function: listen * Function: psock_listen
* *
* Description: * Description:
* To accept connections, a socket is first created with socket(), a * To accept connections, a socket is first created with psock_socket(), a
* willingness to accept incoming connections and a queue limit for incoming * willingness to accept incoming connections and a queue limit for
* connections are specified with listen(), and then the connections are * incoming connections are specified with psock_listen(), and then the
* accepted with accept(). The listen() call applies only to sockets of * connections are accepted with psock_accept(). The psock_listen() call
* type SOCK_STREAM or SOCK_SEQPACKET. * applies only to sockets of type SOCK_STREAM or SOCK_SEQPACKET.
* *
* Parameters: * Parameters:
* sockfd Socket descriptor of the bound socket * psock Reference to an internal, boound socket structure.
* backlog The maximum length the queue of pending connections may grow. * backlog The maximum length the queue of pending connections may grow.
* If a connection request arrives with the queue full, the client * If a connection request arrives with the queue full, the client
* may receive an error with an indication of ECONNREFUSED or, * may receive an error with an indication of ECONNREFUSED or,
@ -76,44 +77,16 @@
* *
* EADDRINUSE * EADDRINUSE
* Another socket is already listening on the same port. * Another socket is already listening on the same port.
* EBADF
* The argument 'sockfd' is not a valid descriptor.
* ENOTSOCK
* The argument 'sockfd' is not a socket.
* EOPNOTSUPP * EOPNOTSUPP
* The socket is not of a type that supports the listen operation. * The socket is not of a type that supports the listen operation.
* *
* Assumptions:
*
****************************************************************************/ ****************************************************************************/
int listen(int sockfd, int backlog) int psock_listen(FAR struct socket *psock, int backlog)
{ {
FAR struct socket *psock = sockfd_socket(sockfd);
int err; int err;
/* Verify that the sockfd corresponds to valid, allocated socket */ DEBUGASSERT(psock != NULL);
if (!psock || psock->s_crefs <= 0)
{
/* It is not a valid socket description. Distinguish between the cases
* where sockfd is a just invalid and when it is a valid file descriptor used
* in the wrong context.
*/
#if CONFIG_NFILE_DESCRIPTORS > 0
if ((unsigned int)sockfd < CONFIG_NFILE_DESCRIPTORS)
{
err = ENOTSOCK;
}
else
#endif
{
err = EBADF;
}
goto errout;
}
/* Verify that the sockfd corresponds to a connected SOCK_STREAM */ /* Verify that the sockfd corresponds to a connected SOCK_STREAM */
@ -181,4 +154,73 @@ errout:
return ERROR; return ERROR;
} }
/****************************************************************************
* Function: listen
*
* Description:
* To accept connections, a socket is first created with socket(), a
* willingness to accept incoming connections and a queue limit for incoming
* connections are specified with listen(), and then the connections are
* accepted with accept(). The listen() call applies only to sockets of
* type SOCK_STREAM or SOCK_SEQPACKET.
*
* Parameters:
* sockfd Socket descriptor of the bound socket
* 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:
* On success, zero is returned. On error, -1 is returned, and errno is set
* appropriately.
*
* EADDRINUSE
* Another socket is already listening on the same port.
* EBADF
* The argument 'sockfd' is not a valid descriptor.
* ENOTSOCK
* The argument 'sockfd' is not a socket.
* EOPNOTSUPP
* The socket is not of a type that supports the listen operation.
*
****************************************************************************/
int listen(int sockfd, int backlog)
{
FAR struct socket *psock = sockfd_socket(sockfd);
int err;
/* Verify that the sockfd corresponds to valid, allocated socket */
if (psock == NULL || psock->s_crefs <= 0)
{
/* It is not a valid socket description. Distinguish between the
* cases where sockfd is a just invalid and when it is a valid file
* descriptor used in the wrong context.
*/
#if CONFIG_NFILE_DESCRIPTORS > 0
if ((unsigned int)sockfd < CONFIG_NFILE_DESCRIPTORS)
{
err = ENOTSOCK;
}
else
#endif
{
err = EBADF;
}
set_errno(err);
return ERROR;
}
/* The let psock_listen to the work. If psock_listen() fails, it will have
* set the errno variable.
*/
return psock_listen(psock, backlog);
}
#endif /* CONFIG_NET && CONFIG_NSOCKET_DESCRIPTORS */ #endif /* CONFIG_NET && CONFIG_NSOCKET_DESCRIPTORS */