diff --git a/configs/nucleo-l476rg/src/stm32_spi.c b/configs/nucleo-l476rg/src/stm32_spi.c index a400cd52677..71d65d8a10d 100644 --- a/configs/nucleo-l476rg/src/stm32_spi.c +++ b/configs/nucleo-l476rg/src/stm32_spi.c @@ -1,5 +1,5 @@ /**************************************************************************** - * configs/nucleo-l476rg/src/stm32_spi.c + * configs/nucleo-l476rg/src/stm32l4_spi.c * * Copyright (C) 2014 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -53,17 +53,17 @@ #include "nucleo-l476rg.h" -#if defined(CONFIG_STM32_SPI1) || defined(CONFIG_STM32_SPI2) || defined(CONFIG_STM32_SPI3) +#if defined(CONFIG_STM32L4_SPI1) || defined(CONFIG_STM32L4_SPI2) || defined(CONFIG_STM32L4_SPI3) /************************************************************************************ * Public Data ************************************************************************************/ /* Global driver instances */ -#ifdef CONFIG_STM32_SPI1 +#ifdef CONFIG_STM32L4_SPI1 struct spi_dev_s *g_spi1; #endif -#ifdef CONFIG_STM32_SPI2 +#ifdef CONFIG_STM32L4_SPI2 struct spi_dev_s *g_spi2; #endif @@ -72,7 +72,7 @@ struct spi_dev_s *g_spi2; ************************************************************************************/ /************************************************************************************ - * Name: stm32_spiinitialize + * Name: stm32l4_spiinitialize * * Description: * Called to configure SPI chip select GPIO pins for the Nucleo-F401RE and @@ -80,55 +80,55 @@ struct spi_dev_s *g_spi2; * ************************************************************************************/ -void weak_function stm32_spiinitialize(void) +void weak_function stm32l4_spiinitialize(void) { -#ifdef CONFIG_STM32_SPI1 +#ifdef CONFIG_STM32L4_SPI1 /* Configure SPI-based devices */ - g_spi1 = up_spiinitialize(1); + g_spi1 = stm32l4_spibus_initialize(1); if (!g_spi1) { spierr("ERROR: FAILED to initialize SPI port 1\n"); } #ifdef CONFIG_WL_CC3000 - stm32_configgpio(GPIO_SPI_CS_WIFI); + stm32l4_configgpio(GPIO_SPI_CS_WIFI); #endif #ifdef HAVE_MMCSD - stm32_configgpio(GPIO_SPI_CS_SD_CARD); + stm32l4_configgpio(GPIO_SPI_CS_SD_CARD); #endif #endif -#ifdef CONFIG_STM32_SPI2 +#ifdef CONFIG_STM32L4_SPI2 /* Configure SPI-based devices */ - g_spi2 = up_spiinitialize(2); + g_spi2 = stm32l4_spibus_initialize(2); /* Setup CS, EN & IRQ line IOs */ #ifdef CONFIG_WL_CC3000 - stm32_configgpio(GPIO_WIFI_CS); - stm32_configgpio(GPIO_WIFI_EN); - stm32_configgpio(GPIO_WIFI_INT); + stm32l4_configgpio(GPIO_WIFI_CS); + stm32l4_configgpio(GPIO_WIFI_EN); + stm32l4_configgpio(GPIO_WIFI_INT); #endif #endif } /**************************************************************************** - * Name: stm32_spi1/2/3select and stm32_spi1/2/3status + * Name: stm32l4_spi1/2/3select and stm32l4_spi1/2/3status * * Description: - * The external functions, stm32_spi1/2/3select and stm32_spi1/2/3status must be + * The external functions, stm32l4_spi1/2/3select and stm32l4_spi1/2/3status must be * provided by board-specific logic. They are implementations of the select * and status methods of the SPI interface defined by struct spi_ops_s (see * include/nuttx/spi/spi.h). All other methods (including up_spiinitialize()) * are provided by common STM32 logic. To use this common SPI logic on your * board: * - * 1. Provide logic in stm32_boardinitialize() to configure SPI chip select + * 1. Provide logic in stm32l4_boardinitialize() to configure SPI chip select * pins. - * 2. Provide stm32_spi1/2/3select() and stm32_spi1/2/3status() functions in your + * 2. Provide stm32l4_spi1/2/3select() and stm32l4_spi1/2/3status() functions in your * board-specific logic. These functions will perform chip selection and * status operations using GPIOs in the way your board is configured. * 3. Add a calls to up_spiinitialize() in your low level application @@ -140,65 +140,65 @@ void weak_function stm32_spiinitialize(void) * ****************************************************************************/ -#ifdef CONFIG_STM32_SPI1 -void stm32_spi1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) +#ifdef CONFIG_STM32L4_SPI1 +void stm32l4_spi1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) { spiinfo("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); #ifdef CONFIG_WL_CC3000 if (devid == SPIDEV_WIRELESS) { - stm32_gpiowrite(GPIO_SPI_CS_WIFI, !selected); + stm32l4_gpiowrite(GPIO_SPI_CS_WIFI, !selected); } else #endif #ifdef HAVE_MMCSD if (devid == SPIDEV_MMCSD) { - stm32_gpiowrite(GPIO_SPI_CS_SD_CARD, !selected); + stm32l4_gpiowrite(GPIO_SPI_CS_SD_CARD, !selected); } #endif } -uint8_t stm32_spi1status(FAR struct spi_dev_s *dev, enum spi_dev_e devid) +uint8_t stm32l4_spi1status(FAR struct spi_dev_s *dev, enum spi_dev_e devid) { return 0; } #endif -#ifdef CONFIG_STM32_SPI2 -void stm32_spi2select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) +#ifdef CONFIG_STM32L4_SPI2 +void stm32l4_spi2select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) { spiinfo("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); #ifdef CONFIG_WL_CC3000 if (devid == SPIDEV_WIRELESS) { - stm32_gpiowrite(GPIO_WIFI_CS, !selected); + stm32l4_gpiowrite(GPIO_WIFI_CS, !selected); } #endif } -uint8_t stm32_spi2status(FAR struct spi_dev_s *dev, enum spi_dev_e devid) +uint8_t stm32l4_spi2status(FAR struct spi_dev_s *dev, enum spi_dev_e devid) { return 0; } #endif -#ifdef CONFIG_STM32_SPI3 -void stm32_spi3select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) +#ifdef CONFIG_STM32L4_SPI3 +void stm32l4_spi3select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) spiinfo("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); } -uint8_t stm32_spi3status(FAR struct spi_dev_s *dev, enum spi_dev_e devid) +uint8_t stm32l4_spi3status(FAR struct spi_dev_s *dev, enum spi_dev_e devid) { return 0; } #endif /**************************************************************************** - * Name: stm32_spi1cmddata + * Name: stm32l4_spi1cmddata * * Description: * Set or clear the SH1101A A0 or SD1306 D/C n bit to select data (true) @@ -221,26 +221,26 @@ uint8_t stm32_spi3status(FAR struct spi_dev_s *dev, enum spi_dev_e devid) ****************************************************************************/ #ifdef CONFIG_SPI_CMDDATA -#ifdef CONFIG_STM32_SPI1 -int stm32_spi1cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd) +#ifdef CONFIG_STM32L4_SPI1 +int stm32l4_spi1cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd) { return OK; } #endif -#ifdef CONFIG_STM32_SPI2 -int stm32_spi2cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd) +#ifdef CONFIG_STM32L4_SPI2 +int stm32l4_spi2cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd) { return OK; } #endif -#ifdef CONFIG_STM32_SPI3 -int stm32_spi3cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd) +#ifdef CONFIG_STM32L4_SPI3 +int stm32l4_spi3cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd) { return OK; } #endif #endif /* CONFIG_SPI_CMDDATA */ -#endif /* CONFIG_STM32_SPI1 || CONFIG_STM32_SPI2 || CONFIG_STM32_SPI3 */ +#endif /* CONFIG_STM32L4_SPI1 || CONFIG_STM32L4_SPI2 || CONFIG_STM32L4_SPI3 */ diff --git a/drivers/analog/Kconfig b/drivers/analog/Kconfig index c9a2334361b..ec14bdcd054 100644 --- a/drivers/analog/Kconfig +++ b/drivers/analog/Kconfig @@ -66,6 +66,25 @@ config ADS1255_FREQUENCY endif # ADC_ADS125X +config ADC_LTC1867L + bool "LTC 1863L/1867L support" + default n + select SPI + ---help--- + Enable driver support for the LTC 1863L (12 bit) and LTC 1867L (16 bit) SPI powered ADC. + + Note that the ADC conversion is started via the ANIOC_TRIGGER iotcl. + +if ADC_LTC1867L + +config LTC1867L_FREQUENCY + int "LTC 1863L/1867L SPI frequency" + default 1000000 + ---help--- + LTC 1863L/1867L SPI frequency. Maximum is 20 MHz. + +endif # ADC_LTC1867L + config ADC_PGA11X bool "TI PGA112/3/6/7 support" default n diff --git a/drivers/analog/Make.defs b/drivers/analog/Make.defs index fbcc369a4ce..01d5a2fe8e2 100644 --- a/drivers/analog/Make.defs +++ b/drivers/analog/Make.defs @@ -83,6 +83,10 @@ endif ifeq ($(CONFIG_ADC_ADS125X),y) CSRCS += ads1255.c endif + +ifeq ($(CONFIG_ADC_LTC1867L),y) + CSRCS += ltc1867l.c +endif endif # Add analog driver build support (the nested if-then-else implements an OR) diff --git a/drivers/analog/ltc1867l.c b/drivers/analog/ltc1867l.c new file mode 100644 index 00000000000..0f5bf1a758e --- /dev/null +++ b/drivers/analog/ltc1867l.c @@ -0,0 +1,380 @@ +/**************************************************************************** + * arch/drivers/analog/ltc1867l.c + * + * Copyright (C) 2017 DS-Automotion GmbH. All rights reserved. + * Author: Martin Lederhilger + * + * This file is a part of NuttX: + * + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#if defined(CONFIG_ADC_LTC1867L) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Device uses SPI Mode 1: CKPOL = 0, CKPHA = 0 */ + +#define LTC1867L_SPI_MODE (SPIDEV_MODE0) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct ltc1867l_dev_s +{ + FAR const struct adc_callback_s *cb; + FAR struct spi_dev_s *spi; + unsigned int devno; + FAR struct ltc1867l_channel_config_s *channel_config; + int channel_config_count; + sem_t sem; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static void adc_lock(FAR struct spi_dev_s *spi); +static void adc_unlock(FAR struct spi_dev_s *spi); + +/* ADC methods */ + +static int adc_bind(FAR struct adc_dev_s *dev, + FAR const struct adc_callback_s *callback); +static void adc_reset(FAR struct adc_dev_s *dev); +static int adc_setup(FAR struct adc_dev_s *dev); +static void adc_shutdown(FAR struct adc_dev_s *dev); +static void adc_rxint(FAR struct adc_dev_s *dev, bool enable); +static int adc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct adc_ops_s g_adcops = +{ + .ao_bind = adc_bind, /* ao_bind */ + .ao_reset = adc_reset, /* ao_reset */ + .ao_setup = adc_setup, /* ao_setup */ + .ao_shutdown = adc_shutdown, /* ao_shutdown */ + .ao_rxint = adc_rxint, /* ao_rxint */ + .ao_ioctl = adc_ioctl /* ao_read */ +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: adc_lock + * + * Description: + * Lock and configure the SPI bus. + * + ****************************************************************************/ + +static void adc_lock(FAR struct spi_dev_s *spi) +{ + (void)SPI_LOCK(spi, true); + SPI_SETMODE(spi, LTC1867L_SPI_MODE); + SPI_SETBITS(spi, 16); + (void)SPI_HWFEATURES(spi, 0); + SPI_SETFREQUENCY(spi, CONFIG_LTC1867L_FREQUENCY); +} + +/**************************************************************************** + * Name: adc_unlock + * + * Description: + * Unlock the SPI bus. + * + ****************************************************************************/ + +static void adc_unlock(FAR struct spi_dev_s *spi) +{ + (void)SPI_LOCK(spi, false); +} + +/**************************************************************************** + * Name: adc_bind + * + * Description: + * Bind the upper-half driver callbacks to the lower-half implementation. This + * must be called early in order to receive ADC event notifications. + * + ****************************************************************************/ + +static int adc_bind(FAR struct adc_dev_s *dev, + FAR const struct adc_callback_s *callback) +{ + FAR struct ltc1867l_dev_s *priv = (FAR struct ltc1867l_dev_s *)dev->ad_priv; + priv->cb = callback; + return OK; +} + +/**************************************************************************** + * Name: adc_reset + * + * Description: + * Reset the ADC device. Called early to initialize the hardware. This + * is called, before ao_setup() and on error conditions. + * + ****************************************************************************/ + +static void adc_reset(FAR struct adc_dev_s *dev) +{ +} + +/**************************************************************************** + * Name: adc_setup + * + * Description: + * Configure the ADC. This method is called the first time that the ADC + * device is opened. This will occur when the port is first opened. + * This setup includes configuring and attaching ADC interrupts. Interrupts + * are all disabled upon return. + * + ****************************************************************************/ + +static int adc_setup(FAR struct adc_dev_s *dev) +{ + return OK; +} + +/**************************************************************************** + * Name: adc_shutdown + * + * Description: + * Disable the ADC. This method is called when the ADC device is closed. + * This method reverses the operation the setup method. + * + ****************************************************************************/ + +static void adc_shutdown(FAR struct adc_dev_s *dev) +{ +} + +/**************************************************************************** + * Name: adc_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void adc_rxint(FAR struct adc_dev_s *dev, bool enable) +{ +} + +/**************************************************************************** + * Name: adc_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int adc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg) +{ + FAR struct ltc1867l_dev_s *priv = (FAR struct ltc1867l_dev_s *)dev->ad_priv; + FAR struct spi_dev_s *spi = priv->spi; + int i; + uint16_t command; + uint16_t data; + int32_t dataToPost; + int ret = OK; + + if(cmd == ANIOC_TRIGGER) + { + while (sem_wait(&priv->sem) != OK); + + adc_lock(spi); + + for (i = 0; i <= priv->channel_config_count; i++) + { + SPI_SELECT(spi, priv->devno, true); + + if (i < priv->channel_config_count) + { + command = priv->channel_config[i].analog_multiplexer_config | + priv->channel_config[i].analog_inputMode; + command = command << 8; + } + else + { + command = 0; + } + + data = SPI_SEND(spi, command); + up_udelay(2); + SPI_SELECT(spi, priv->devno, false); + up_udelay(4); + + if (i > 0) + { + if (priv->channel_config[i-1].analog_inputMode == LTC1867L_UNIPOLAR || + (priv->channel_config[i-1].analog_inputMode == LTC1867L_BIPOLAR && + data >= 0 && data <= 0x7fff)) + { + dataToPost = data; + } + else + { + dataToPost = -(0xffff - data) - 1; + } + + priv->cb->au_receive(dev, priv->channel_config[i-1].channel, dataToPost); + } + } + + adc_unlock(spi); + sem_post(&priv->sem); + } + else + { + aerr("ERROR: Unrecognized cmd: %d\n", cmd); + ret = -ENOTTY; + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ltc1867l_register + * + * Description: + * Register the LTC1867L character device as 'devpath' + * + * Input Parameters: + * devpath - The full path to the driver to register. E.g., "/dev/adc0" + * spi - An instance of the SPI interface to use to communicate with + * LTC1867L + * devno - SPI device number + * channel_config - A pointer to an array which holds the configuration + * for each sampled channel. + * channel_config_count - Number of channels to sample + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int ltc1867l_register(FAR const char *devpath, FAR struct spi_dev_s *spi, + unsigned int devno, + FAR struct ltc1867l_channel_config_s* channel_config, + int channel_config_count) +{ + FAR struct ltc1867l_dev_s *adcpriv; + FAR struct adc_dev_s *adcdev; + int ret; + + /* Sanity check */ + + DEBUGASSERT(spi != NULL); + DEBUGASSERT(channel_config != NULL); + + /* Initialize the LTC1867L device structure */ + + adcpriv = (FAR struct ltc1867l_dev_s *)kmm_malloc(sizeof(struct ltc1867l_dev_s)); + if (adcpriv == NULL) + { + aerr("ERROR: Failed to allocate ltc1867l_dev_s instance\n"); + return -ENOMEM; + } + + adcpriv->spi = spi; + adcpriv->devno = devno; + adcpriv->channel_config = channel_config; + adcpriv->channel_config_count = channel_config_count; + + ret = sem_init(&adcpriv->sem, 1, 1); + if(ret == -1) + { + kmm_free(adcpriv); + return -errno; + } + + adcdev = (FAR struct adc_dev_s *)kmm_malloc(sizeof(struct adc_dev_s)); + if (adcdev == NULL) + { + aerr("ERROR: Failed to allocate adc_dev_s instance\n"); + sem_destroy(&adcpriv->sem); + kmm_free(adcpriv); + return -ENOMEM; + } + + memset(adcdev, 0, sizeof(struct adc_dev_s)); + adcdev->ad_ops = &g_adcops; + adcdev->ad_priv = adcpriv; + + /* Register the character driver */ + + ret = adc_register(devpath, adcdev); + if (ret < 0) + { + aerr("ERROR: Failed to register adc driver: %d\n", ret); + kmm_free(adcdev); + sem_destroy(&adcpriv->sem); + kmm_free(adcpriv); + } + + return ret; +} +#endif diff --git a/include/nuttx/analog/ltc1867l.h b/include/nuttx/analog/ltc1867l.h new file mode 100644 index 00000000000..447ba494b17 --- /dev/null +++ b/include/nuttx/analog/ltc1867l.h @@ -0,0 +1,137 @@ +/**************************************************************************** + * include/nuttx/sensors/ltc1867l.h + * + * Copyright (C) 2017 DS-Automotion GmbH. All rights reserved. + * Author: Martin Lederhilger + * + * 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 __INCLUDE_NUTTX_ANALOG_LTC1867L_H +#define __INCLUDE_NUTTX_ANALOG_LTC1867L_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#if defined(CONFIG_ADC_LTC1867L) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* LTC1867L Configuration *******************************************/ + +#define LTC1867L_CONFIG_BIT_SLP (1 << 1) +#define LTC1867L_CONFIG_BIT_UNI (1 << 2) +#define LTC1867L_CONFIG_BIT_COM (1 << 3) +#define LTC1867L_CONFIG_BIT_S0 (1 << 4) +#define LTC1867L_CONFIG_BIT_S1 (1 << 5) +#define LTC1867L_CONFIG_BIT_OS (1 << 6) +#define LTC1867L_CONFIG_BIT_SD (1 << 7) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +enum ltc1867l_analog_multiplexer_config_e +{ + LTC1867L_P_CH0_M_CH1 = 0, + LTC1867L_P_CH2_M_CH3 = LTC1867L_CONFIG_BIT_S0, + LTC1867L_P_CH4_M_CH5 = LTC1867L_CONFIG_BIT_S1, + LTC1867L_P_CH6_M_CH7 = LTC1867L_CONFIG_BIT_S1 | LTC1867L_CONFIG_BIT_S0, + LTC1867L_P_CH1_M_CH0 = LTC1867L_CONFIG_BIT_OS, + LTC1867L_P_CH3_M_CH2 = LTC1867L_CONFIG_BIT_OS | LTC1867L_CONFIG_BIT_S0, + LTC1867L_P_CH5_M_CH4 = LTC1867L_CONFIG_BIT_OS | LTC1867L_CONFIG_BIT_S1, + LTC1867L_P_CH7_M_CH6 = LTC1867L_CONFIG_BIT_OS |LTC1867L_CONFIG_BIT_S1 | LTC1867L_CONFIG_BIT_S0, + LTC1867L_P_CH0_M_GND = LTC1867L_CONFIG_BIT_SD, + LTC1867L_P_CH2_M_GND = LTC1867L_CONFIG_BIT_SD | LTC1867L_CONFIG_BIT_S0, + LTC1867L_P_CH4_M_GND = LTC1867L_CONFIG_BIT_SD | LTC1867L_CONFIG_BIT_S1, + LTC1867L_P_CH6_M_GND = LTC1867L_CONFIG_BIT_SD | LTC1867L_CONFIG_BIT_S1 | LTC1867L_CONFIG_BIT_S0, + LTC1867L_P_CH1_M_GND = LTC1867L_CONFIG_BIT_SD | LTC1867L_CONFIG_BIT_OS, + LTC1867L_P_CH3_M_GND = LTC1867L_CONFIG_BIT_SD | LTC1867L_CONFIG_BIT_OS | LTC1867L_CONFIG_BIT_S0, + LTC1867L_P_CH5_M_GND = LTC1867L_CONFIG_BIT_SD | LTC1867L_CONFIG_BIT_OS | LTC1867L_CONFIG_BIT_S1, + LTC1867L_P_CH7_M_GND = LTC1867L_CONFIG_BIT_SD | LTC1867L_CONFIG_BIT_OS | LTC1867L_CONFIG_BIT_S1 | LTC1867L_CONFIG_BIT_S0, + LTC1867L_P_CH0_M_CH7COM = LTC1867L_CONFIG_BIT_SD | LTC1867L_CONFIG_BIT_COM, + LTC1867L_P_CH2_M_CH7COM = LTC1867L_CONFIG_BIT_SD | LTC1867L_CONFIG_BIT_S0 | LTC1867L_CONFIG_BIT_COM, + LTC1867L_P_CH4_M_CH7COM = LTC1867L_CONFIG_BIT_SD | LTC1867L_CONFIG_BIT_S1 | LTC1867L_CONFIG_BIT_COM, + LTC1867L_P_CH6_M_CH7COM = LTC1867L_CONFIG_BIT_SD | LTC1867L_CONFIG_BIT_S1 | LTC1867L_CONFIG_BIT_S0 | LTC1867L_CONFIG_BIT_COM, + LTC1867L_P_CH1_M_CH7COM = LTC1867L_CONFIG_BIT_SD | LTC1867L_CONFIG_BIT_OS | LTC1867L_CONFIG_BIT_COM, + LTC1867L_P_CH3_M_CH7COM = LTC1867L_CONFIG_BIT_SD | LTC1867L_CONFIG_BIT_OS | LTC1867L_CONFIG_BIT_S0 | LTC1867L_CONFIG_BIT_COM, + LTC1867L_P_CH5_M_CH7COM = LTC1867L_CONFIG_BIT_SD | LTC1867L_CONFIG_BIT_OS | LTC1867L_CONFIG_BIT_S1 | LTC1867L_CONFIG_BIT_COM +}; + +enum ltc1867l_analog_input_mode_e +{ + LTC1867L_UNIPOLAR = LTC1867L_CONFIG_BIT_UNI, + LTC1867L_BIPOLAR = 0, +}; + +struct ltc1867l_channel_config_s +{ + uint8_t channel; /* This will be the channel number returned in struct adc_msg_s for a conversion */ + enum ltc1867l_analog_multiplexer_config_e analog_multiplexer_config; /* Analog multiplexer configuration */ + enum ltc1867l_analog_input_mode_e analog_inputMode; /* Analog input mode */ +} packed_struct; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: ltc1867l_register + * + * Description: + * Register the LTC1867L character device as 'devpath' + * + * Input Parameters: + * devpath - The full path to the driver to register. E.g., "/dev/adc0" + * spi - An instance of the SPI interface to use to communicate with + * LTC1867L + * devno - SPI device number + * channel_config - A pointer to an array which holds the configuration + * for each sampled channel. + * channel_config_count - Number of channels to sample + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int ltc1867l_register(FAR const char *devpath, FAR struct spi_dev_s *spi, + unsigned int devno, + FAR struct ltc1867l_channel_config_s* channel_config, + int channel_config_count); + +#endif /* CONFIG_ADC_LTC1867L */ +#endif /* __INCLUDE_NUTTX_ANALOG_LTC1867L_H */ diff --git a/include/nuttx/net/net.h b/include/nuttx/net/net.h index 1c64351fe2e..337e0a63665 100644 --- a/include/nuttx/net/net.h +++ b/include/nuttx/net/net.h @@ -79,7 +79,7 @@ enum net_lltype_e NET_LL_SLIP, /* Serial Line Internet Protocol (SLIP) */ NET_LL_TUN, /* TUN Virtual Network Device */ NET_LL_IEEE80211, /* IEEE 802.11 */ - NET_LL_6LOWPAN /* IEEE 802.15.4 6LoWPAN */ + NET_LL_IEEE805154 /* IEEE 802.15.4 MAC */ }; /* This defines a bitmap big enough for one bit for each socket option */ diff --git a/include/nuttx/net/sixlowpan.h b/include/nuttx/net/sixlowpan.h index 4b956db8aa8..4887d255f0a 100644 --- a/include/nuttx/net/sixlowpan.h +++ b/include/nuttx/net/sixlowpan.h @@ -63,12 +63,6 @@ #define SIXLOWPAN_UDP_8_BIT_PORT_MIN 0xF000 #define SIXLOWPAN_UDP_8_BIT_PORT_MAX 0xf0ff /* F000 + 255 */ -/* 6lowpan compressions */ - -#define SIXLOWPAN_COMPRESSION_IPV6 0 -#define SIXLOWPAN_COMPRESSION_HC1 1 -#define SIXLOWPAN_COMPRESSION_HC06 2 - /* 6lowpan dispatches */ #define SIXLOWPAN_DISPATCH_IPV6 0x41 /* 01000001 = 65 */ @@ -229,6 +223,10 @@ (((a)->u16[6]) == 0) && \ (((a)->u8[14]) == 0)) +/* Maximum size of an IEEE802.15.4 frame */ + +#define SIXLOWPAN_MAC_MAXFRAME 127 + /**************************************************************************** * Public Types ****************************************************************************/ @@ -253,7 +251,7 @@ struct sixlowpan_frag_hdr * sixlowpan_hc1_hc_udp structure */ -struct sixlowpan_hc1_hdr +struct sixlowpan_hc1hdr_s { uint8_t dispatch; uint8_t encoding; @@ -262,7 +260,7 @@ struct sixlowpan_hc1_hdr /* HC1 followed by HC_UDP */ -struct sixlowpan_hc1_hc_udp_hdr +struct sixlowpan_hc1_hcudp_hdr_s { uint8_t dispatch; uint8_t hc1_encoding; @@ -272,18 +270,6 @@ struct sixlowpan_hc1_hc_udp_hdr uint16_t udpchksum; }; -/* An address context for IPHC address compression each context can have up - * to 8 bytes - */ - -struct sixlowpan_addr_context -{ - uint8_t used; /* Possibly use as prefix-length */ - uint8_t number; - uint8_t prefix[8]; -}; - - /* The structure of a next header compressor. This compressor is provided * by architecture-specific logic outside of the network stack. * diff --git a/include/pthread.h b/include/pthread.h index edf943c9bb5..af6ef51e23e 100644 --- a/include/pthread.h +++ b/include/pthread.h @@ -295,10 +295,26 @@ struct pthread_mutex_s typedef struct pthread_mutex_s pthread_mutex_t; #define __PTHREAD_MUTEX_T_DEFINED 1 -#ifdef CONFIG_PTHREAD_MUTEX_TYPES -# define PTHREAD_MUTEX_INITIALIZER {-1, SEM_INITIALIZER(1), PTHREAD_MUTEX_DEFAULT, 0} +#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE +# ifdef CONFIG_PTHREAD_MUTEX_DEFAULT_UNSAFE +# define __PTHREAD_MUTEX_DEFAULT_FLAGS 0 +# else +# define __PTHREAD_MUTEX_DEFAULT_FLAGS _PTHREAD_MFLAGS_ROBUST +# endif +#endif + +#if defined(CONFIG_PTHREAD_MUTEX_TYPES) && !defined(CONFIG_PTHREAD_MUTEX_UNSAFE) +# define PTHREAD_MUTEX_INITIALIZER {NULL, SEM_INITIALIZER(1), -1, \ + __PTHREAD_MUTEX_DEFAULT_FLAGS, \ + PTHREAD_MUTEX_DEFAULT, 0} +#elif defined(CONFIG_PTHREAD_MUTEX_TYPES) +# define PTHREAD_MUTEX_INITIALIZER {SEM_INITIALIZER(1), -1, \ + PTHREAD_MUTEX_DEFAULT, 0} +#elif !defined(CONFIG_PTHREAD_MUTEX_UNSAFE) +# define PTHREAD_MUTEX_INITIALIZER {NULL, SEM_INITIALIZER(1), -1,\ + __PTHREAD_MUTEX_DEFAULT_FLAGS} #else -# define PTHREAD_MUTEX_INITIALIZER {-1, SEM_INITIALIZER(1)} +# define PTHREAD_MUTEX_INITIALIZER {SEM_INITIALIZER(1), -1} #endif struct pthread_barrierattr_s diff --git a/mm/mm_heap/mm_realloc.c b/mm/mm_heap/mm_realloc.c index bf28ff62dfc..bf0effa54d4 100644 --- a/mm/mm_heap/mm_realloc.c +++ b/mm/mm_heap/mm_realloc.c @@ -1,7 +1,7 @@ /**************************************************************************** * mm/mm_heap/mm_realloc.c * - * Copyright (C) 2007, 2009, 2013-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2013-2014, 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -79,6 +79,7 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem, FAR struct mm_allocnode_s *oldnode; FAR struct mm_freenode_s *prev; FAR struct mm_freenode_s *next; + size_t newsize; size_t oldsize; size_t prevsize = 0; size_t nextsize = 0; @@ -86,7 +87,7 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem, /* If oldmem is NULL, then realloc is equivalent to malloc */ - if (!oldmem) + if (oldmem == NULL) { return mm_malloc(heap, size); } @@ -103,7 +104,7 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem, * (2) to make sure that it is an even multiple of our granule size. */ - size = MM_ALIGN_UP(size + SIZEOF_MM_ALLOCNODE); + newsize = MM_ALIGN_UP(size + SIZEOF_MM_ALLOCNODE); /* Map the memory chunk into an allocated node structure */ @@ -116,15 +117,15 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem, /* Check if this is a request to reduce the size of the allocation. */ oldsize = oldnode->size; - if (size <= oldsize) + if (newsize <= oldsize) { /* Handle the special case where we are not going to change the size * of the allocation. */ - if (size < oldsize) + if (newsize < oldsize) { - mm_shrinkchunk(heap, oldnode, size); + mm_shrinkchunk(heap, oldnode, newsize); } /* Then return the original address */ @@ -152,9 +153,9 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem, /* Now, check if we can extend the current allocation or not */ - if (nextsize + prevsize + oldsize >= size) + if (nextsize + prevsize + oldsize >= newsize) { - size_t needed = size - oldsize; + size_t needed = newsize - oldsize; size_t takeprev = 0; size_t takenext = 0; diff --git a/net/net_initialize.c b/net/net_initialize.c index df3a72226d3..988faf6b547 100644 --- a/net/net_initialize.c +++ b/net/net_initialize.c @@ -1,7 +1,7 @@ /**************************************************************************** - * net/net_sockets.c + * net/net_initialize.c * - * Copyright (C) 2007-2009, 2011-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011-2015, 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -49,6 +49,7 @@ #include "devif/devif.h" #include "netdev/netdev.h" #include "arp/arp.h" +#include "sixlowpan/sixlowpan.h" #include "neighbor/neighbor.h" #include "tcp/tcp.h" #include "udp/udp.h" @@ -58,26 +59,6 @@ #include "route/route.h" #include "utils/utils.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Public Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -119,7 +100,13 @@ void net_setup(void) /* Initialize the Neighbor Table data structures */ neighbor_initialize(); + +#ifdef CONFIG_NET_6LOWPAN + /* Initialize 6loWPAN data structures */ + + sixlowpan_initialize(); #endif +#endif /* CONFIG_NET_IPv6 */ #ifdef CONFIG_NET_IOB /* Initialize I/O buffering */ diff --git a/net/netdev/netdev_register.c b/net/netdev/netdev_register.c index dafc17dcc3a..9a3a01c66d2 100644 --- a/net/netdev/netdev_register.c +++ b/net/netdev/netdev_register.c @@ -228,9 +228,9 @@ int netdev_register(FAR struct net_driver_s *dev, enum net_lltype_e lltype) #endif #ifdef CONFIG_NET_6LOWPAN - case NET_LL_6LOWPAN: /* IEEE 802.15.4 */ + case NET_LL_IEEE802154: /* IEEE 802.15.4 MAC */ dev->d_llhdrlen = 0; /* REVISIT */ - dev->d_mtu = CONFIG_NET_6LOWPAN_MTU; + dev->d_mtu = SIXLOWPAN_MAC_MAXFRAME; #ifdef CONFIG_NET_TCP dev->d_recvwndo = CONFIG_NET_6LOWPAN_TCP_RECVWNDO; #endif diff --git a/net/sixlowpan/Kconfig b/net/sixlowpan/Kconfig index e72e42268b4..4505a7ee880 100644 --- a/net/sixlowpan/Kconfig +++ b/net/sixlowpan/Kconfig @@ -13,27 +13,149 @@ menuconfig NET_6LOWPAN if NET_6LOWPAN -config NET_6LOWPAN_MTU - int "6LoWPAN packet buffer size (MTU)" - default 1294 - range 590 1518 +config NET_6LOWPAN_FRAG + bool "6loWPAN Fragmentation" + default y ---help--- - Packet buffer size. This size includes the TCP/UDP payload plus the - size of TCP/UDP header, the IP header, and data link layer headers. - This value is normally referred to as the MTU (Maximum Transmission - Unit); the payload is the MSS (Maximum Segment Size). + CONFIG_NET_6LOWPAN_FRAG specifies if 6lowpan fragmentation should be + used or not. Fragmentation is on by default. - IPv6 hosts are required to be able to handle an MSS of 1220 octets, - resulting in a minimum buffer size of of 1220+20+40+xx = xx. REVISIT! +choice + prompt "6loWPAN Compression" + default NET_6LOWPAN_COMPRESSION_HC06 + +config NET_6LOWPAN_COMPRESSION_IPv6 + bool "IPv6 Dispatch" + ---help--- + Packets compression when only IPv6 dispatch is used. There is no + compression in this case, all fields are sent inline. We just add + the IPv6 dispatch byte before the packet. + +config NET_6LOWPAN_COMPRESSION_HC1 + bool "6loWPAN HC1" + ---help--- + Compress IP/UDP header using HC1 and HC_UDP + +config NET_6LOWPAN_COMPRESSION_HC06 + bool "6loWPAN HC06" + ---help--- + Compress IP/UDP header using HC06 compression + +endchoice # 6loWPAN Compression + +config NET_6LOWPAN_COMPRESSION_THRESHOLD + int "Lower compression threshold" + default 63 + depends on !NET_6LOWPAN_COMPRESSION_IPv6 + ---help--- + CONFIG_NET_6LOWPAN_COMPRESSION_THRESHOLD sets a lower threshold for + when packets should not be compressed. + +if NET_6LOWPAN_COMPRESSION_HC06 + +config NET_6LOWPAN_MAXADDRCONTEXT + int "Maximum address contexts" + default 1 + ---help--- + If we use IPHC compression, how many address contexts do we support? + +config NET_6LOWPAN_MAXADDRCONTEXT_PREFIX_0_0 + hex "Address context 0 Prefix 0" + default 0xaa + ---help--- + Prefix 0 for address context ze0ro (assumes CONFIG_NET_6LOWPAN_MAXADDRCONTEXT >= 0) + +config NET_6LOWPAN_MAXADDRCONTEXT_PREFIX_0_1 + hex "Address context 0 Prefix 1" + default 0xaa + ---help--- + Prefix 1 for address context 0 (assumes CONFIG_NET_6LOWPAN_MAXADDRCONTEXT >= 0) + +config NET_6LOWPAN_MAXADDRCONTEXT_PREINIT_1 + bool "Pre-initialize address context 1" + default n + ---help--- + Preinitialize address context 1 for better header compression + (Saves up to 13 bytes per 6lowpan packet). Assumes + CONFIG_NET_6LOWPAN_MAXADDRCONTEXT >= 1) + +if NET_6LOWPAN_MAXADDRCONTEXT_PREINIT_1 + +config NET_6LOWPAN_MAXADDRCONTEXT_PREFIX_1_0 + hex "Address context 1 Prefix 0" + default 0xaa + ---help--- + Prefix 0 for address context 1 (assumes CONFIG_NET_6LOWPAN_MAXADDRCONTEXT >= 1) + +config NET_6LOWPAN_MAXADDRCONTEXT_PREFIX_1_1 + hex "Address context 1 Prefix 1" + default 0xaa + ---help--- + Prefix 1 for address context 1 (assumes CONFIG_NET_6LOWPAN_MAXADDRCONTEXT >= 1) + +endif # NET_6LOWPAN_MAXADDRCONTEXT_PREINIT_1 + +config NET_6LOWPAN_MAXADDRCONTEXT_PREINIT_2 + bool "Pre-initialize address context 2" + default n + depends on NET_6LOWPAN_MAXADDRCONTEXT_PREINIT_1 + ---help--- + Preinitialize any address contexts for better header compression + (Saves up to 13 bytes per 6lowpan packet). Assumes + CONFIG_NET_6LOWPAN_MAXADDRCONTEXT >= 2) + +if NET_6LOWPAN_MAXADDRCONTEXT_PREINIT_2 + +config NET_6LOWPAN_MAXADDRCONTEXT_PREFIX_2_0 + hex "Address context 2 Prefix 0" + default 0xaa + ---help--- + Prefix 0 for address context 2 (assumes CONFIG_NET_6LOWPAN_MAXADDRCONTEXT >= 2) + +config NET_6LOWPAN_MAXADDRCONTEXT_PREFIX_2_1 + hex "Address context 2 Prefix 1" + default 0xaa + ---help--- + Prefix 1 for address context 2 (assumes CONFIG_NET_6LOWPAN_MAXADDRCONTEXT >= 2) + +endif # NET_6LOWPAN_MAXADDRCONTEXT_PREINIT_0 +endif # NET_6LOWPAN_COMPRESSION_HC06 + +config NET_6LOWPAN_RIMEADDR_SIZE + int "Rime address size" + default 2 + +config NET_SIXLOWPAN_MAXAGE + int "Packet reassembly timeout" + default 20 + ---help--- + Timeout for packet reassembly at the 6lowpan layer (should be < 60s) + +config NET_6LOWPAN_MAX_MACTRANSMITS + int "Max MAC transmissions" + default 4 + ---help--- + CONFIG_NET_6LOWPAN_MAX_MACTRANSMITS specifies how many times the MAC + layer should resend packets if no link-layer ACK wasreceived. This + only makes sense with the csma_driver. + +config NET_SIXLOWPAN_MAXPAYLOAD + int "Max packet size" + default 102 + ---help--- + CONFIG_NET_SIXLOWPAN_MAXPAYLOAD specifies the maximum size of packets + before they get fragmented. The default is 127 bytes (the maximum size + of a 802.15.4 frame) - 25 bytes (for the 802.15.4 MAClayer header). This + can be increased for systems with larger packet sizes. config NET_6LOWPAN_TCP_RECVWNDO int "6LoWPAN TCP receive window size" - default 1220 + default 102 depends on NET_TCP ---help--- The size of the advertised receiver's window. Should be set low - (i.e., to the size of the MSS) if the application is slow to process - incoming data, or high (32768 bytes) if the application processes - data quickly. REVISIT! + (i.e., to the size of the IEEE802.15.4 frame payload) if the application + is slow to process incoming data, or high (32768 bytes) if the + application processes data quickly. REVISIT! endif # NET_6LOWPAN diff --git a/net/sixlowpan/Make.defs b/net/sixlowpan/Make.defs index 150cb6ec882..1e581517315 100644 --- a/net/sixlowpan/Make.defs +++ b/net/sixlowpan/Make.defs @@ -39,8 +39,18 @@ ifeq ($(CONFIG_NET_6LOWPAN),y) # Include IEEE 802.15.4 file in the build +NET_CSRCS += sixlowpan_initialize.c sixlowpan_globals.c +NET_CSRCS += sixlowpan_input.c sixlowpan_send.c NET_CSRCS += sixlowpan_compressor.c sixlowpan_sniffer.c +ifeq ($(CONFIG_NET_6LOWPAN_COMPRESSION_HC1),y) +NET_CSRCS += sixlowpan_hc1.c +endif + +ifeq ($(CONFIG_NET_6LOWPAN_COMPRESSION_HC06),y) +NET_CSRCS += sixlowpan_hc06.c +endif + # Include the sixlowpan directory in the build DEPPATH += --dep-path sixlowpan diff --git a/net/sixlowpan/sixlowpan.h b/net/sixlowpan/sixlowpan.h index e85135e0cf5..46a282b41da 100644 --- a/net/sixlowpan/sixlowpan.h +++ b/net/sixlowpan/sixlowpan.h @@ -41,9 +41,19 @@ ****************************************************************************/ #include +#include #ifdef CONFIG_NET_6LOWPAN +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct rimeaddr_s +{ + uint8_t u8[CONFIG_NET_6LOWPAN_RIMEADDR_SIZE]; +}; + /**************************************************************************** * Public Data ****************************************************************************/ @@ -55,7 +65,8 @@ extern FAR struct sixlowpan_nhcompressor_s *g_sixlowpan_compressor; /* Rime Sniffer support for one single listener to enable trace of IP */ -extern struct sixlowpan_rime_sniffer_s *g_sixlopan_sniffer; +struct sixlowpan_rime_sniffer_s; /* Foward reference */ +extern FAR struct sixlowpan_rime_sniffer_s *g_sixlowpan_sniffer; /**************************************************************************** * Public Types @@ -65,5 +76,234 @@ extern struct sixlowpan_rime_sniffer_s *g_sixlopan_sniffer; * Public Function Prototypes ****************************************************************************/ +struct net_driver_s; /* Forward reference */ +struct socket; /* Forward reference */ + +/**************************************************************************** + * Name: sixlowpan_initialize + * + * Description: + * sixlowpan_initialize() is called during OS initialization at power-up + * reset. It is called from the common net_setup() function. + * sixlowpan_initialize() configures 6loWPAN networking data structures. + * It is called prior to platform-specific driver initialization so that + * the 6loWPAN networking subsystem is prepared to deal with network + * driver initialization actions. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sixlowpan_initialize(void); + +/**************************************************************************** + * Function: psock_6lowpan_tcp_send + * + * Description: + * psock_6lowpan_tcp_send() call may be used only when the TCP socket is in a + * connected state (so that the intended recipient is known). + * + * Parameters: + * psock - An instance of the internal socket structure. + * buf - Data to send + * len - Length of data to send + * + * Returned Value: + * On success, returns the number of characters sent. On error, + * -1 is returned, and errno is set appropriately. Returned error numbers + * must be consistent with definition of errors reported by send() or + * sendto(). + * + ****************************************************************************/ + +#ifdef CONFIG_NET_TCP +ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf, + size_t len); +#endif + +/**************************************************************************** + * Function: psock_6lowpan_udp_send + * + * Description: + * psock_6lowpan_udp_send() call may be used with connectionlesss UDP + * sockets. + * + * Parameters: + * psock - An instance of the internal socket structure. + * buf - Data to send + * len - Length of data to send + * + * Returned Value: + * On success, returns the number of characters sent. On error, + * -1 is returned, and errno is set appropriately. Returned error numbers + * must be consistent with definition of errors reported by send() or + * sendto(). + * + ****************************************************************************/ + +#ifdef CONFIG_NET_UDP +ssize_t psock_6lowpan_udp_send(FAR struct socket *psock, FAR const void *buf, + size_t len); +#endif + +/**************************************************************************** + * Name: sixlowpan_output + * + * Description: + * Process an outgoing UDP or TCP packet. Called from UDP/TCP logic to + * determine if the the packet should be formatted for 6loWPAN output. + * + * Input Parameters: + * dev - The IEEE802.15.4 MAC network driver interface. + * + * Returned Value: + * Ok is returned on success; Othewise a negated errno value is returned. + * This function is expected to fail if the driver is not an IEEE802.15.4 + * MAC network driver. In that case, the UDP/TCP will fall back to normal + * IPv4/IPv6 formatting. + * + ****************************************************************************/ + +int sixlowpan_output(FAR struct net_driver_s *dev); + +/**************************************************************************** + * Name: sixlowpan_hc06_initialize + * + * Description: + * sixlowpan_hc06_initialize() is called during OS initialization at power-up + * reset. It is called from the common sixlowpan_initialize() function. + * sixlowpan_hc06_initialize() configures HC06 networking data structures. + * It is called prior to platform-specific driver initialization so that + * the 6loWPAN networking subsystem is prepared to deal with network + * driver initialization actions. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06 +void sixlowpan_hc06_initialize(void); +#endif + +/**************************************************************************** + * Name: sixlowpan_hc06_initialize + * + * Description: + * Compress IP/UDP header + * + * This function is called by the 6lowpan code to create a compressed + * 6lowpan packet in the packetbuf buffer from a full IPv6 packet in the + * uip_buf buffer. + * + * HC-06 (draft-ietf-6lowpan-hc, version 6) + * http://tools.ietf.org/html/draft-ietf-6lowpan-hc-06 + * + * NOTE: sixlowpan_compresshdr_hc06() does not support ISA100_UDP header + * compression + * + * Input Parameters: + * dev - A reference to the IEE802.15.4 network device state + * destaddr - L2 destination address, needed to compress IP dest + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06 +void sixlowpan_compresshdr_hc06(FAR struct net_driver_s *dev, + FAR struct rimeaddr_s *destaddr); +#endif + +/**************************************************************************** + * Name: sixlowpan_hc06_initialize + * + * Description: + * Uncompress HC06 (i.e., IPHC and LOWPAN_UDP) headers and put them in + * sixlowpan_buf + * + * This function is called by the input function when the dispatch is HC06. + * We process the packet in the rime buffer, uncompress the header fields, + * and copy the result in the sixlowpan buffer. At the end of the + * decompression, g_rime_hdrlen and g_uncompressed_hdrlen are set to the + * appropriate values + * + * Input Parmeters: + * dev - A reference to the IEE802.15.4 network device state + * iplen - Equal to 0 if the packet is not a fragment (IP length is then + * inferred from the L2 length), non 0 if the packet is a 1st + * fragment. + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06 +void sixlowpan_uncompresshdr_hc06(FAR struct net_driver_s *dev, + uint16_t iplen); +#endif + +/**************************************************************************** + * Name: sixlowpan_compresshdr_hc1 + * + * Description: + * Compress IP/UDP header using HC1 and HC_UDP + * + * This function is called by the 6lowpan code to create a compressed + * 6lowpan packet in the packetbuf buffer from a full IPv6 packet in the + * uip_buf buffer. + * + * Input Parmeters: + * dev - A reference to the IEE802.15.4 network device state + * destaddr - L2 destination address, needed to compress the IP + * destination field + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC1 +void sixlowpan_compresshdr_hc1(FAR struct net_driver_s *dev, + FAR struct rimeaddr_s *destaddr); +#endif + +/**************************************************************************** + * Name: sixlowpan_uncompresshdr_hc1 + * + * Description: + * Uncompress HC1 (and HC_UDP) headers and put them in sixlowpan_buf + * + * This function is called by the input function when the dispatch is + * HC1. It processes the packet in the rime buffer, uncompresses the + * header fields, and copies the result in the sixlowpan buffer. At the + * end of the decompression, g_rime_hdrlen and uncompressed_hdr_len + * are set to the appropriate values + * + * Input Parameters: + * dev - A reference to the IEE802.15.4 network device state + * iplen - Equal to 0 if the packet is not a fragment (IP length is then + * inferred from the L2 length), non 0 if the packet is a 1st + * fragment. + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC1 +void sixlowpan_uncompresshdr_hc1(FAR struct net_driver_s *dev, + uint16_t ip_len); +#endif + #endif /* CONFIG_NET_6LOWPAN */ #endif /* _NET_SIXLOWPAN_SIXLOWPAN_H */ diff --git a/net/sixlowpan/sixlowpan_compressor.c b/net/sixlowpan/sixlowpan_compressor.c index 0f781138021..3457530b79e 100644 --- a/net/sixlowpan/sixlowpan_compressor.c +++ b/net/sixlowpan/sixlowpan_compressor.c @@ -42,18 +42,10 @@ #include "nuttx/net/net.h" #include "nuttx/net/sixlowpan.h" -#include "sixlowpan/sixlopan.h" +#include "sixlowpan/sixlowpan.h" #ifdef CONFIG_NET_6LOWPAN -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/* A pointer to the optional, architecture-specific compressor */ - -FAR struct sixlowpan_nhcompressor_s *g_sixlowpan_compressor; - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/include/nuttx/net/6lowpan.h b/net/sixlowpan/sixlowpan_globals.c similarity index 74% rename from include/nuttx/net/6lowpan.h rename to net/sixlowpan/sixlowpan_globals.c index cbd7e071bf3..6a5729d6196 100644 --- a/include/nuttx/net/6lowpan.h +++ b/net/sixlowpan/sixlowpan_globals.c @@ -1,12 +1,9 @@ /**************************************************************************** - * include/nuttx/net/6lowpan.h + * net/sixlowpan/sixlowpan_globals.c * - * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * - * Includes some definitions that a compatible with the LGPL GNU C Library - * header file of the same name. - * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -36,27 +33,28 @@ * ****************************************************************************/ -#ifndef __INCLUDE_NUTTX_NET_6LOWPAN_H -#define __INCLUDE_NUTTX_NET_6LOWPAN_H - /**************************************************************************** * Included Files ****************************************************************************/ #include -#include +#include "nuttx/net/sixlowpan.h" -/**************************************************************************** - * Public Type Definitions - ****************************************************************************/ +#include "sixlowpan/sixlowpan.h" + +#ifdef CONFIG_NET_6LOWPAN /**************************************************************************** * Public Data ****************************************************************************/ -/**************************************************************************** - * Public Function Prototypes - ****************************************************************************/ +/* A pointer to the optional, architecture-specific compressor */ -#endif /* __INCLUDE_NUTTX_NET_6LOWPAN_H */ +FAR struct sixlowpan_nhcompressor_s *g_sixlowpan_compressor; + +/* A pointer to the optional, architecture-specific sniffer */ + +FAR struct sixlowpan_rime_sniffer_s *g_sixlowpan_sniffer; + +#endif /* CONFIG_NET_6LOWPAN */ diff --git a/net/sixlowpan/sixlowpan_hc06.c b/net/sixlowpan/sixlowpan_hc06.c new file mode 100644 index 00000000000..733edc900b5 --- /dev/null +++ b/net/sixlowpan/sixlowpan_hc06.c @@ -0,0 +1,250 @@ +/**************************************************************************** + * net/sixlowpan/sixlowpan_hc06.c + * 6lowpan HC06 implementation (draft-ietf-6lowpan-hc-06) + * + * Copyright (C) 2017, Gregory Nutt, all rights reserved + * Author: Gregory Nutt + * + * Derives from Contiki: + * + * Copyright (c) 2008, Swedish Institute of Computer Science. + * All rights reserved. + * Authors: Adam Dunkels + * Nicolas Tsiftes + * Niclas Finne + * Mathilde Durvy + * Julien Abeille + * Joakim Eriksson + * Joel Hoglund + * + * 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 of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + ****************************************************************************/ + +/* FOR HC-06 COMPLIANCE TODO: + * + * -Add compression options to UDP, currently only supports + * both ports compressed or both ports elided + * -Verify TC/FL compression works + * -Add stateless multicast option + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "sixlowpan/sixlowpan.h" + +#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* An address context for IPHC address compression each context can have up + * to 8 bytes + */ + +struct sixlowpan_addrcontext_s +{ + uint8_t used; /* Possibly use as prefix-length */ + uint8_t number; + uint8_t prefix[8]; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* HC06 specific variables */ + +#if CONFIG_NET_6LOWPAN_MAXADDRCONTEXT > 0 +/* Addresses contexts for IPHC. */ + +static struct sixlowpan_addrcontext_s + g_hc06_addrcontexts[CONFIG_NET_6LOWPAN_MAXADDRCONTEXT]; +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sixlowpan_hc06_initialize + * + * Description: + * sixlowpan_hc06_initialize() is called during OS initialization at power-up + * reset. It is called from the common sixlowpan_initialize() function. + * sixlowpan_hc06_initialize() configures HC06 networking data structures. + * It is called prior to platform-specific driver initialization so that + * the 6loWPAN networking subsystem is prepared to deal with network + * driver initialization actions. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sixlowpan_hc06_initialize(void) +{ +#if CONFIG_NET_6LOWPAN_MAXADDRCONTEXT > 0 +#if CONFIG_NET_6LOWPAN_MAXADDRCONTEXT > 1 + int i; +#endif + + /* Preinitialize any address contexts for better header compression + * (Saves up to 13 bytes per 6lowpan packet). + */ + + g_hc06_addrcontexts[0].used = 1; + g_hc06_addrcontexts[0].number = 0; + + g_hc06_addrcontexts[0].prefix[0] = CONFIG_NET_6LOWPAN_MAXADDRCONTEXT_PREFIX_0_0; + g_hc06_addrcontexts[0].prefix[1] = CONFIG_NET_6LOWPAN_MAXADDRCONTEXT_PREFIX_0_1; + +#if CONFIG_NET_6LOWPAN_MAXADDRCONTEXT > 1 + for (i = 1; i < CONFIG_NET_6LOWPAN_MAXADDRCONTEXT; i++) + { +#ifdef CONFIG_NET_6LOWPAN_MAXADDRCONTEXT_PREINIT_1 + if (i == 1) + { + g_hc06_addrcontexts[1].used = 1; + g_hc06_addrcontexts[1].number = 1; + + g_hc06_addrcontexts[1].prefix[0] = CONFIG_NET_6LOWPAN_MAXADDRCONTEXT_PREFIX_1_0; + g_hc06_addrcontexts[1].prefix[1] = CONFIG_NET_6LOWPAN_MAXADDRCONTEXT_PREFIX_1_1; + } + else +#ifdef CONFIG_NET_6LOWPAN_MAXADDRCONTEXT_PREINIT_2 + if (i == 2) + { + g_hc06_addrcontexts[2].used = 1; + g_hc06_addrcontexts[2].number = 2; + + g_hc06_addrcontexts[2].prefix[0] = CONFIG_NET_6LOWPAN_MAXADDRCONTEXT_PREFIX_2_0; + g_hc06_addrcontexts[2].prefix[1] = CONFIG_NET_6LOWPAN_MAXADDRCONTEXT_PREFIX_2_1; + } + else +#endif /* SIXLOWPAN_CONF_ADDR_CONTEXT_2 */ + { + g_hc06_addrcontexts[i].used = 0; + } +#else + g_hc06_addrcontexts[i].used = 0; +#endif /* SIXLOWPAN_CONF_ADDR_CONTEXT_1 */ + } +#endif /* CONFIG_NET_6LOWPAN_MAXADDRCONTEXT > 1 */ +#endif /* CONFIG_NET_6LOWPAN_MAXADDRCONTEXT > 0 */ +} + +/**************************************************************************** + * Name: sixlowpan_hc06_initialize + * + * Description: + * Compress IP/UDP header + * + * This function is called by the 6lowpan code to create a compressed + * 6lowpan packet in the packetbuf buffer from a full IPv6 packet in the + * uip_buf buffer. + * + * HC-06 (draft-ietf-6lowpan-hc, version 6) + * http://tools.ietf.org/html/draft-ietf-6lowpan-hc-06 + * + * NOTE: sixlowpan_compresshdr_hc06() does not support ISA100_UDP header + * compression + * + * For LOWPAN_UDP compression, we either compress both ports or none. + * General format with LOWPAN_UDP compression is + * 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |0|1|1|TF |N|HLI|C|S|SAM|M|D|DAM| SCI | DCI | comp. IPv6 hdr| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | compressed IPv6 fields ..... | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | LOWPAN_UDP | non compressed UDP fields ... | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | L4 data ... | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * NOTE: The g_addr_context number 00 is reserved for the link local prefix. + * For unicast addresses, if we cannot compress the prefix, we neither + * compress the IID. + * + * Input Parameters: + * dev - A reference to the IEE802.15.4 network device state + * destaddr - L2 destination address, needed to compress IP dest + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sixlowpan_compresshdr_hc06(FAR struct net_driver_s *dev, + FAR struct rimeaddr_s *destaddr) +{ + /* REVISIT: To be provided */ +} + +/**************************************************************************** + * Name: sixlowpan_hc06_initialize + * + * Description: + * Uncompress HC06 (i.e., IPHC and LOWPAN_UDP) headers and put them in + * sixlowpan_buf + * + * This function is called by the input function when the dispatch is HC06. + * We process the packet in the rime buffer, uncompress the header fields, + * and copy the result in the sixlowpan buffer. At the end of the + * decompression, g_rime_hdrlen and g_uncompressed_hdrlen are set to the + * appropriate values + * + * Input Parmeters: + * dev - A reference to the IEE802.15.4 network device state + * iplen - Equal to 0 if the packet is not a fragment (IP length is then + * inferred from the L2 length), non 0 if the packet is a 1st + * fragment. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sixlowpan_uncompresshdr_hc06(FAR struct net_driver_s *dev, + uint16_t iplen) +{ + /* REVISIT: To be provided */ +} + + +#endif /* CONFIG_NET_6LOWPAN_COMPRESSION_HC06 */ diff --git a/net/sixlowpan/sixlowpan_hc1.c b/net/sixlowpan/sixlowpan_hc1.c new file mode 100644 index 00000000000..3f9b93f17db --- /dev/null +++ b/net/sixlowpan/sixlowpan_hc1.c @@ -0,0 +1,149 @@ +/**************************************************************************** + * net/sixlowpan/sixlowpan_hc1.c + * + * Copyright (C) 2017, Gregory Nutt, all rights reserved + * Author: Gregory Nutt + * + * Derives from Contiki: + * + * Copyright (c) 2008, Swedish Institute of Computer Science. + * All rights reserved. + * Authors: Adam Dunkels + * Nicolas Tsiftes + * Niclas Finne + * Mathilde Durvy + * Julien Abeille + * Joakim Eriksson + * Joel Hoglund + * + * 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 of the Institute 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 INSTITUTE 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 INSTITUTE 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 + +#include +#include "sixlowpan/sixlowpan.h" + +#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC1 + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sixlowpan_compresshdr_hc1 + * + * Description: + * Compress IP/UDP header using HC1 and HC_UDP + * + * This function is called by the 6lowpan code to create a compressed + * 6lowpan packet in the packetbuf buffer from a full IPv6 packet in the + * uip_buf buffer. + * + * If we can compress everything, we use HC1 dispatch, if not we use + * IPv6 dispatch. We can compress everything if: + * + * - IP version is + * - Flow label and traffic class are 0 + * - Both src and dest ip addresses are link local + * - Both src and dest interface ID are recoverable from lower layer + * header + * - Next header is either ICMP, UDP or TCP + * + * Moreover, if next header is UDP, we try to compress it using HC_UDP. + * This is feasible is both ports are between F0B0 and F0B0 + 15\n\n + * + * Resulting header structure: + * - For ICMP, TCP, non compressed UDP\n + * HC1 encoding = 11111010 (UDP) 11111110 (TCP) 11111100 (ICMP)\n + * 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | LoWPAN HC1 Dsp | HC1 encoding | IPv6 Hop limit| L4 hdr + data| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | ... + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * - For compressed UDP + * HC1 encoding = 11111011, HC_UDP encoding = 11100000\n + * 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | LoWPAN HC1 Dsp| HC1 encoding | HC_UDP encod.| IPv6 Hop limit| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | src p.| dst p.| UDP checksum | L4 data... + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * Input Parmeters: + * dev - A reference to the IEE802.15.4 network device state + * destaddr - L2 destination address, needed to compress the IP + * destination field + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sixlowpan_compresshdr_hc1(FAR struct net_driver_s *dev, + FAR struct rimeaddr_s *destaddr) +{ +/* REVISIT: To be provided */ +} + +/**************************************************************************** + * Name: sixlowpan_uncompresshdr_hc1 + * + * Description: + * Uncompress HC1 (and HC_UDP) headers and put them in sixlowpan_buf + * + * This function is called by the input function when the dispatch is + * HC1. It processes the packet in the rime buffer, uncompresses the + * header fields, and copies the result in the sixlowpan buffer. At the + * end of the decompression, g_rime_hdrlen and uncompressed_hdr_len + * are set to the appropriate values + * + * Input Parameters: + * dev - A reference to the IEE802.15.4 network device state + * iplen - Equal to 0 if the packet is not a fragment (IP length is then + * inferred from the L2 length), non 0 if the packet is a 1st + * fragment. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sixlowpan_uncompresshdr_hc1(FAR struct net_driver_s *dev, + uint16_t iplen) +{ +/* REVISIT: To be provided */ +} + +#endif /* CONFIG_NET_6LOWPAN_COMPRESSION_HC1 */ diff --git a/net/sixlowpan/sixlowpan_initialize.c b/net/sixlowpan/sixlowpan_initialize.c new file mode 100644 index 00000000000..07e10b6a377 --- /dev/null +++ b/net/sixlowpan/sixlowpan_initialize.c @@ -0,0 +1,78 @@ +/**************************************************************************** + * net/sixlowpan/sixlowpan_initialize.c + * + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include "sixlowpan/sixlowpan.h" + +#ifdef CONFIG_NET_6LOWPAN + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sixlowpan_initialize + * + * Description: + * sixlowpan_initialize() is called during OS initialization at power-up + * reset. It is called from the common net_setup() function. + * sixlowpan_initialize() configures 6loWPAN networking data structures. + * It is called prior to platform-specific driver initialization so that + * the 6loWPAN networking subsystem is prepared to deal with network + * driver initialization actions. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sixlowpan_initialize(void) +{ +#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06 + /* Initialize HC06 data data structures */ + + sixlowpan_hc06_initialize(); +#endif +} + +#endif /* CONFIG_NET_6LOWPAN */ diff --git a/net/sixlowpan/sixlowpan_input.c b/net/sixlowpan/sixlowpan_input.c new file mode 100644 index 00000000000..f28c0eafda1 --- /dev/null +++ b/net/sixlowpan/sixlowpan_input.c @@ -0,0 +1,83 @@ +/**************************************************************************** + * net/sixlowpan/sixlowpan_input.c + * + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include + +#include "nuttx/net/netdev.h" +#include "sixlowpan/sixlowpan.h" + +#ifdef CONFIG_NET_6LOWPAN + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sixlowpan_input + * + * Description: + * Process an incoming IP packet. + * + * This function is called when the device driver has received a 6loWPAN + * packet from the network. The packet from the device driver must be + * present in the d_buf buffer, and the length of the packet should be + * placed in the d_len field. + * + * When the function returns, there may be an outbound packet placed + * in the d_buf packet buffer. If so, the d_len field is set to + * the length of the packet. If no packet is to be sent out, the + * d_len field is set to 0. + * + * Input Parameters: + * dev - The IEEE802.15.4 MAC network driver interface. + * + * Returned Value: + * Ok is returned on success; Othewise a negated errno value is returned. + * + ****************************************************************************/ + +int sixlowpan_input(FAR struct net_driver_s *dev) +{ + /* REVISIT: To be provided */ + return -ENOSYS; +} + +#endif /* CONFIG_NET_6LOWPAN */ diff --git a/net/sixlowpan/sixlowpan_send.c b/net/sixlowpan/sixlowpan_send.c new file mode 100644 index 00000000000..de338945975 --- /dev/null +++ b/net/sixlowpan/sixlowpan_send.c @@ -0,0 +1,309 @@ +/**************************************************************************** + * net/sixlowpan/sixlowpan_send.c + * + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include +#include + +#include "nuttx/net/net.h" +#include "nuttx/net/netdev.h" + +#include "netdev/netdev.h" +#include "socket/socket.h" +#include "tcp/tcp.h" +#include "udp/udp.h" +#include "sixlowpan/sixlowpan.h" + +#ifdef CONFIG_NET_6LOWPAN + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sixlowpan_send + * + * Description: + * Process an outgoing UDP or TCP packet. Called from UDP/TCP logic to + * determine if the the packet should be formatted for 6loWPAN output. + * + * Input Parameters: + * dev - The IEEE802.15.4 MAC network driver interface. + * + * Returned Value: + * Ok is returned on success; Othewise a negated errno value is returned. + * This function is expected to fail if the driver is not an IEEE802.15.4 + * MAC network driver. In that case, the UDP/TCP will fall back to normal + * IPv4/IPv6 formatting. + * + * Assumptions: + * Called with the network locked. + * + ****************************************************************************/ + +int sixlowpan_send(FAR struct net_driver_s *dev) +{ + net_lock(); + /* REVISIT: To be provided */ + net_unlock(); + return -ENOSYS; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: psock_6lowpan_tcp_send + * + * Description: + * psock_6lowpan_tcp_send() call may be used only when the TCP socket is in a + * connected state (so that the intended recipient is known). + * + * Parameters: + * psock - An instance of the internal socket structure. + * buf - Data to send + * len - Length of data to send + * + * Returned Value: + * On success, returns the number of characters sent. On error, + * -1 is returned, and errno is set appropriately. Returned error numbers + * must be consistent with definition of errors reported by send() or + * sendto(). + * + ****************************************************************************/ + +#ifdef CONFIG_NET_TCP +ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf, + size_t len) +{ + FAR struct tcp_conn_s *conn; + FAR struct net_driver_s *dev; + int ret; + + DEBUGASSERT(psock != NULL && psock->s_crefs > 0); + DEBUGASSERT(psock->s_type == SOCK_STREAM); + + /* Make sure that this is a valid socket */ + + if (psock != NULL || psock->s_crefs <= 0) + { + nerr("ERROR: Invalid socket\n"); + return (ssize_t)-EBADF; + } + + /* Make sure that this is a connected TCP socket */ + + if (psock->s_type != SOCK_STREAM || !_SS_ISCONNECTED(psock->s_flags)) + { + nerr("ERROR: Not connected\n"); + return (ssize_t)-ENOTCONN; + } + + /* Get the underlying TCP connection structure */ + + conn = (FAR struct tcp_conn_s *)psock->s_conn; + DEBUGASSERT(conn != NULL); + + /* Ignore if not IPv6 domain */ + + if (conn->domain != PF_INET6) + { + nwarn("WARNING: Not IPv6\n"); + return (ssize_t)-EPROTOTYPE; + } + + /* Route outgoing message to the correct device */ + +#ifdef CONFIG_NETDEV_MULTINIC + dev = netdev_findby_ipv6addr(conn->u.ipv6.laddr, conn->u.ipv6.raddr); + if (dev == NULL || dev->d_lltype != NET_LL_IEEE805154) + { + nwarn("WARNING: Not routable or not IEEE802.15.4 MAC\n"); + return (ssize_t)-ENETUNREACH; + } +#else + dev = netdev_findby_ipv6addr(conn->u.ipv6.raddr); + if (dev == NULL) + { + nwarn("WARNING: Not routable\n"); + return (ssize_t)-ENETUNREACH; + } +#endif + +#ifdef CONFIG_NET_ICMPv6_NEIGHBOR + /* Make sure that the IP address mapping is in the Neighbor Table */ + + ret = icmpv6_neighbor(conn->u.ipv6.raddr); + if (ret < 0) + { + nerr("ERROR: Not reachable\n"); + return (ssize_t)-ENETUNREACH; + } +#endif + + /* Set the socket state to sending */ + + psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_SEND); + + /* If routable, then call sixlowpan_send() to format and send the 6loWPAN + * packet. + */ + + ret = sixlowpan_send(dev); + if (ret < 0) + { + nerr("ERROR: sixlowpan_send() failed: %d\n", ret); + } + + return ret; +} +#endif + +/**************************************************************************** + * Function: psock_6lowpan_udp_send + * + * Description: + * psock_6lowpan_udp_send() call may be used with connectionlesss UDP + * sockets. + * + * Parameters: + * psock - An instance of the internal socket structure. + * buf - Data to send + * len - Length of data to send + * + * Returned Value: + * On success, returns the number of characters sent. On error, + * -1 is returned, and errno is set appropriately. Returned error numbers + * must be consistent with definition of errors reported by send() or + * sendto(). + * + ****************************************************************************/ + +#ifdef CONFIG_NET_UDP +ssize_t psock_6lowpan_udp_send(FAR struct socket *psock, FAR const void *buf, + size_t len) +{ + FAR struct udp_conn_s *conn; + FAR struct net_driver_s *dev; + int ret; + + DEBUGASSERT(psock != NULL && psock->s_crefs > 0); + DEBUGASSERT(psock->s_type == SOCK_DGRAM); + + /* Make sure that this is a valid socket */ + + if (psock != NULL || psock->s_crefs <= 0) + { + nerr("ERROR: Invalid socket\n"); + return (ssize_t)-EBADF; + } + + /* Was the UDP socket connected via connect()? */ + + if (psock->s_type != SOCK_DGRAM || !_SS_ISCONNECTED(psock->s_flags)) + { + /* No, then it is not legal to call send() with this socket. */ + + return -ENOTCONN; + } + + /* Get the underlying UDP "connection" structure */ + + conn = (FAR struct udp_conn_s *)psock->s_conn; + DEBUGASSERT(conn != NULL); + + /* Ignore if not IPv6 domain */ + + if (conn->domain != PF_INET6) + { + nwarn("WARNING: Not IPv6\n"); + return (ssize_t)-EPROTOTYPE; + } + + /* Route outgoing message to the correct device */ + +#ifdef CONFIG_NETDEV_MULTINIC + dev = netdev_findby_ipv6addr(conn->u.ipv6.laddr, conn->u.ipv6.raddr); + if (dev == NULL || dev->d_lltype != NET_LL_IEEE805154) + { + nwarn("WARNING: Not routable or not IEEE802.15.4 MAC\n"); + return (ssize_t)-ENETUNREACH; + } +#else + dev = netdev_findby_ipv6addr(conn->u.ipv6.raddr); + if (dev == NULL) + { + nwarn("WARNING: Not routable\n"); + return (ssize_t)-ENETUNREACH; + } +#endif + +#ifdef CONFIG_NET_ICMPv6_NEIGHBOR + /* Make sure that the IP address mapping is in the Neighbor Table */ + + ret = icmpv6_neighbor(conn->u.ipv6.raddr); + if (ret < 0) + { + nerr("ERROR: Not reachable\n"); + return (ssize_t)-ENETUNREACH; + } +#endif + + /* Set the socket state to sending */ + + psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_SEND); + + /* If routable, then call sixlowpan_send() to format and send the 6loWPAN + * packet. + */ + + ret = sixlowpan_send(dev); + if (ret < 0) + { + nerr("ERROR: sixlowpan_send() failed: %d\n", ret); + } + + return ret; +} +#endif + +#endif /* CONFIG_NET_6LOWPAN */ diff --git a/net/sixlowpan/sixlowpan_sniffer.c b/net/sixlowpan/sixlowpan_sniffer.c index 9f00efe62ac..baf3acc09cb 100644 --- a/net/sixlowpan/sixlowpan_sniffer.c +++ b/net/sixlowpan/sixlowpan_sniffer.c @@ -42,18 +42,10 @@ #include "nuttx/net/net.h" #include "nuttx/net/sixlowpan.h" -#include "sixlowpan/sixlopan.h" +#include "sixlowpan/sixlowpan.h" #ifdef CONFIG_NET_6LOWPAN -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/* A pointer to the optional, architecture-specific sniffer */ - -FAR struct sixlowpan_rime_sniffer_s *g_sixlowpan_sniffer; - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/net/socket/send.c b/net/socket/send.c index e90b27b116a..20252fcdaeb 100644 --- a/net/socket/send.c +++ b/net/socket/send.c @@ -45,9 +45,10 @@ #include +#include "pkt/pkt.h" #include "tcp/tcp.h" #include "udp/udp.h" -#include "pkt/pkt.h" +#include "sixlowpan/sixlowpan.h" #include "local/local.h" #include "socket/socket.h" @@ -133,6 +134,8 @@ ssize_t psock_send(FAR struct socket *psock, FAR const void *buf, size_t len, #if defined(CONFIG_NET_PKT) case SOCK_RAW: { + /* Raw packet send */ + ret = psock_pkt_send(psock, buf, len); } break; @@ -146,6 +149,8 @@ ssize_t psock_send(FAR struct socket *psock, FAR const void *buf, size_t len, if (psock->s_domain == PF_LOCAL) #endif { + /* Local TCP packet send */ + ret = psock_local_send(psock, buf, len, flags); } #endif /* CONFIG_NET_LOCAL_STREAM */ @@ -155,7 +160,17 @@ ssize_t psock_send(FAR struct socket *psock, FAR const void *buf, size_t len, else #endif { - ret = psock_tcp_send(psock, buf, len); +#ifdef CONFIG_NET_6LOWPAN + /* Try 6loWPAN TCP packet send */ + + ret = psock_6lowpan_tcp_send(psock, buf, len); + if (ret < 0) +#endif + { + /* Try TCP/IP packet send */ + + ret = psock_tcp_send(psock, buf, len); + } } #endif /* CONFIG_NET_TCP */ } @@ -170,6 +185,7 @@ ssize_t psock_send(FAR struct socket *psock, FAR const void *buf, size_t len, if (psock->s_domain == PF_LOCAL) #endif { + /* Local UDP packet send */ #warning Missing logic ret = -ENOSYS; } @@ -180,7 +196,17 @@ ssize_t psock_send(FAR struct socket *psock, FAR const void *buf, size_t len, else #endif { - ret = psock_udp_send(psock, buf, len); +#ifdef CONFIG_NET_6LOWPAN + /* Try 6loWPAN UDP packet send */ + + ret = psock_6lowpan_udp_send(psock, buf, len); + if (ret < 0) +#endif + { + /* UDP/IP packet send */ + + ret = psock_udp_send(psock, buf, len); + } } #endif /* CONFIG_NET_UDP */ } diff --git a/net/tcp/tcp_send.c b/net/tcp/tcp_send.c index edce06a196f..a68394b24c1 100644 --- a/net/tcp/tcp_send.c +++ b/net/tcp/tcp_send.c @@ -121,7 +121,7 @@ static inline FAR struct tcp_hdr_s *tcp_header(FAR struct net_driver_s *dev) * None * * Assumptions: - * Called from the interrupt level or with interrupts disabled. + * Called with the network locked. * ****************************************************************************/ @@ -189,7 +189,7 @@ static inline void tcp_ipv4_sendcomplete(FAR struct net_driver_s *dev, * None * * Assumptions: - * Called from the interrupt level or with interrupts disabled. + * Called with the network locked. * ****************************************************************************/ @@ -252,7 +252,7 @@ static inline void tcp_ipv6_sendcomplete(FAR struct net_driver_s *dev, * None * * Assumptions: - * Called from the interrupt level or with interrupts disabled. + * Called with the network locked. * ****************************************************************************/ @@ -300,7 +300,7 @@ static void tcp_sendcomplete(FAR struct net_driver_s *dev, * None * * Assumptions: - * Called from the interrupt level or with interrupts disabled. + * Called with the network locked. * ****************************************************************************/ @@ -383,7 +383,7 @@ static void tcp_sendcommon(FAR struct net_driver_s *dev, * None * * Assumptions: - * Called from the interrupt level or with interrupts disabled. + * Called with the network locked. * ****************************************************************************/ @@ -411,7 +411,7 @@ void tcp_send(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn, * None * * Assumptions: - * Called from the interrupt level or with interrupts disabled. + * Called with the network locked. * ****************************************************************************/ @@ -528,7 +528,7 @@ void tcp_reset(FAR struct net_driver_s *dev) * None * * Assumptions: - * Called from the interrupt level or with interrupts disabled. + * Called with the network locked. * ****************************************************************************/ diff --git a/net/tcp/tcp_send_buffered.c b/net/tcp/tcp_send_buffered.c index e3c12aed7e6..76941f3a999 100644 --- a/net/tcp/tcp_send_buffered.c +++ b/net/tcp/tcp_send_buffered.c @@ -952,7 +952,7 @@ ssize_t psock_tcp_send(FAR struct socket *psock, FAR const void *buf, int errcode; int ret = OK; - if (!psock || psock->s_crefs <= 0) + if (psock == NULL || psock->s_crefs <= 0) { nerr("ERROR: Invalid socket\n"); errcode = EBADF; diff --git a/net/tcp/tcp_send_unbuffered.c b/net/tcp/tcp_send_unbuffered.c index d6422437c8c..6c3688d85ad 100644 --- a/net/tcp/tcp_send_unbuffered.c +++ b/net/tcp/tcp_send_unbuffered.c @@ -722,7 +722,7 @@ ssize_t psock_tcp_send(FAR struct socket *psock, /* Verify that the sockfd corresponds to valid, allocated socket */ - if (!psock || psock->s_crefs <= 0) + if (psock == NULL || psock->s_crefs <= 0) { nerr("ERROR: Invalid socket\n"); errcode = EBADF;