diff --git a/Kconfig b/Kconfig index d2157939e8..f0dd167c3c 100644 --- a/Kconfig +++ b/Kconfig @@ -848,15 +848,6 @@ config DEBUG_SYSCALL_INFO endif # DEBUG_SYSCALL -config DEBUG_WIRELESS - bool "Wireless Device Debug Output" - default n - depends on WIRELESS - ---help--- - Enable low level debug SYSLOG output from the wireless subsystem and - device drivers. (disabled by default). Support for this debug option - is architecture-specific and may not be available for some MCUs. - comment "OS Function Debug Options" config DEBUG_DMA diff --git a/arch/arm/src/kinetis/kinetis_i2c.c b/arch/arm/src/kinetis/kinetis_i2c.c index 6350b18f34..6efc2ff09a 100644 --- a/arch/arm/src/kinetis/kinetis_i2c.c +++ b/arch/arm/src/kinetis/kinetis_i2c.c @@ -1,8 +1,8 @@ /**************************************************************************** - * arch/arm/src/kinetis/kinetis_i2c.c * * Copyright (C) 2016-2017 Gregory Nutt. All rights reserved. - * Author: Matias v01d + * Authors: Matias v01d + * David Sidrane * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -68,7 +68,7 @@ #include "kinetis_i2c.h" #if defined(CONFIG_KINETIS_I2C0) || defined(CONFIG_KINETIS_I2C1) || \ - defined(CONFIG_KINETIS_I2C2) + defined(CONFIG_KINETIS_I2C2) || defined(CONFIG_KINETIS_I2C3) /**************************************************************************** * Pre-processor Definitions @@ -83,6 +83,12 @@ #define STATE_TIMEOUT 2 #define STATE_NAK 3 +#define MKI2C_OUTPUT(p) (((p) & (_PIN_PORT_MASK | _PIN_MASK)) | \ + GPIO_OPENDRAIN | GPIO_OUTPUT_ONE) + +#define MKI2C_INPUT(p) (((p) & (_PIN_PORT_MASK | _PIN_MASK)) | \ + PIN_ANALOG) + /* TODO: * - revisar tamanio de todos los registros (getreg/putreg) */ @@ -91,18 +97,29 @@ * Private Types ****************************************************************************/ +/* I2C Device hardware configuration */ + +struct kinetis_i2c_config_s +{ + uint32_t base; /* I2C base address */ + uint32_t clk_reg; /* Clock Register */ + uint32_t clk_bit; /* Clock enable bit */ + uint32_t scl_pin; /* GPIO configuration for SCL as SCL */ + uint32_t sda_pin; /* GPIO configuration for SDA as SDA */ + uint16_t irqid; /* IRQ for this device */ +}; + /* I2C device state structure */ struct kinetis_i2cdev_s { struct i2c_master_s dev; /* Generic I2C device */ - uintptr_t base; /* Base address of registers */ - uint32_t basefreq; /* Branch frequency */ + const struct kinetis_i2c_config_s *config; /* Port configuration */ uint32_t frequency; /* Current I2C frequency */ - uint16_t irqid; /* IRQ for this device */ uint16_t nmsg; /* Number of transfer remaining */ uint16_t wrcnt; /* number of bytes sent to tx fifo */ uint16_t rdcnt; /* number of bytes read from rx fifo */ + int refs; /* Reference count */ volatile uint8_t state; /* State of state machine */ bool restart; /* Should next transfer restart or not */ sem_t mutex; /* Only one thread can access at a time */ @@ -123,8 +140,23 @@ static uint8_t kinetis_i2c_getreg(struct kinetis_i2cdev_s *priv, static void kinetis_i2c_putreg(struct kinetis_i2cdev_s *priv, uint8_t value, uint8_t offset); +/* Exclusion Helpers */ + +static inline void kinetis_i2c_sem_init(FAR struct kinetis_i2cdev_s *priv); +static inline void kinetis_i2c_sem_destroy(FAR struct kinetis_i2cdev_s *priv); +static inline void kinetis_i2c_sem_wait(FAR struct kinetis_i2cdev_s *priv); +static inline void kinetis_i2c_sem_post(struct kinetis_i2cdev_s *priv); + +/* Signal Helper */ + +static inline void kinetis_i2c_endwait(struct kinetis_i2cdev_s *priv); +static inline void kinetis_i2c_wait(struct kinetis_i2cdev_s *priv); + /* I2C helpers */ +static int kinetis_i2c_init(FAR struct kinetis_i2cdev_s *priv); +static int kinetis_i2c_deinit(FAR struct kinetis_i2cdev_s *priv); + static void kinetis_i2c_setfrequency(struct kinetis_i2cdev_s *priv, uint32_t frequency); static int kinetis_i2c_start(struct kinetis_i2cdev_s *priv); @@ -148,7 +180,7 @@ static int kinetis_i2c_reset(struct i2c_master_s *dev); /* I2C lower half driver operations */ -static const struct i2c_ops_s g_i2c_ops = +static const struct i2c_ops_s kinetis_i2c_ops = { .transfer = kinetis_i2c_transfer #ifdef CONFIG_I2C_RESET @@ -156,16 +188,90 @@ static const struct i2c_ops_s g_i2c_ops = #endif }; -/* I2C device state instances */ +/* I2C device structures */ #ifdef CONFIG_KINETIS_I2C0 -static struct kinetis_i2cdev_s g_i2c0_dev; +static const struct kinetis_i2c_config_s kinetis_i2c0_config = +{ + .base = KINETIS_I2C0_BASE, + .clk_reg = KINETIS_SIM_SCGC4, + .clk_bit = SIM_SCGC4_I2C0, + .scl_pin = PIN_I2C0_SCL, + .sda_pin = PIN_I2C0_SDA, + .irqid = KINETIS_IRQ_I2C0, +}; + +static struct kinetis_i2cdev_s g_i2c0_dev = +{ + .dev.ops = &kinetis_i2c_ops, + .config = &kinetis_i2c0_config, + .refs = 0, + .state = STATE_OK, + .msgs = NULL, +}; #endif + #ifdef CONFIG_KINETIS_I2C1 -static struct kinetis_i2cdev_s g_i2c1_dev; +static const struct kinetis_i2c_config_s kinetis_i2c1_config = +{ + .base = KINETIS_I2C1_BASE, + .clk_reg = KINETIS_SIM_SCGC4, + .clk_bit = SIM_SCGC4_I2C1, + .scl_pin = PIN_I2C1_SCL, + .sda_pin = PIN_I2C1_SDA, + .irqid = KINETIS_IRQ_I2C1, +}; + +static struct kinetis_i2cdev_s g_i2c1_dev = +{ + .dev.ops = &kinetis_i2c_ops, + .config = &kinetis_i2c1_config, + .refs = 0, + .state = STATE_OK, + .msgs = NULL, +}; #endif + #ifdef CONFIG_KINETIS_I2C2 -static struct kinetis_i2cdev_s g_i2c2_dev; +static const struct kinetis_i2c_config_s kinetis_i2c2_config = +{ + .base = KINETIS_I2C2_BASE, + .clk_reg = KINETIS_SIM_SCGC1, + .clk_bit = SIM_SCGC1_I2C2, + .scl_pin = PIN_I2C2_SCL, + .sda_pin = PIN_I2C2_SDA, + .irqid = KINETIS_IRQ_I2C2, +}; + +static struct kinetis_i2cdev_s g_i2c2_dev = +{ + .dev.ops = &kinetis_i2c_ops, + .config = &kinetis_i2c2_config, + .refs = 0, + .state = STATE_OK, + .msgs = NULL, +}; +#endif + +#ifdef CONFIG_KINETIS_I2C3 +static const struct kinetis_i2c_config_s kinetis_i2c3_config = +{ + .base = KINETIS_I2C3_BASE, + .clk_reg = KINETIS_SIM_SCGC1, + .clk_bit = SIM_SCGC1_I2C3, + .scl_pin = PIN_I2C3_SCL, + .sda_pin = PIN_I2C3_SDA, + .irqid = KINETIS_IRQ_I2C3, +}; + +static struct kinetis_i2cdev_s g_i2c3_dev = +{ + .dev.ops = &kinetis_i2c_ops, + .config = &kinetis_i2c3_config, + .refs = 0, + .state = STATE_OK, + .msgs = NULL, +}; #endif /**************************************************************************** @@ -183,7 +289,7 @@ static struct kinetis_i2cdev_s g_i2c2_dev; static uint8_t kinetis_i2c_getreg(struct kinetis_i2cdev_s *priv, uint8_t offset) { - return getreg8(priv->base + offset); + return getreg8(priv->config->base + offset); } /**************************************************************************** @@ -197,7 +303,187 @@ static uint8_t kinetis_i2c_getreg(struct kinetis_i2cdev_s *priv, static void kinetis_i2c_putreg(struct kinetis_i2cdev_s *priv, uint8_t value, uint8_t offset) { - putreg8(value, priv->base + offset); + putreg8(value, priv->config->base + offset); +} + +/************************************************************************************ + * Name: kinetis_i2c_sem_init + * + * Description: + * Initialize semaphores + * + ************************************************************************************/ + +static inline void kinetis_i2c_sem_init(FAR struct kinetis_i2cdev_s *priv) +{ + sem_init(&priv->mutex, 0, 1); + + /* This semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_init(&priv->wait, 0, 0); + sem_setprotocol(&priv->wait, SEM_PRIO_NONE); +} + +/************************************************************************************ + * Name: kinetis_i2c_sem_destroy + * + * Description: + * Destroy semaphores. + * + ************************************************************************************/ + +static inline void kinetis_i2c_sem_destroy(FAR struct kinetis_i2cdev_s *priv) +{ + sem_destroy(&priv->mutex); + sem_destroy(&priv->wait); +} + +/************************************************************************************ + * Name: kinetis_i2c_sem_wait + * + * Description: + * Take the exclusive access, waiting as necessary + * + ************************************************************************************/ + +static inline void kinetis_i2c_sem_wait(FAR struct kinetis_i2cdev_s *priv) +{ + while (sem_wait(&priv->mutex) != 0) + { + DEBUGASSERT(errno == EINTR); + } +} + +/************************************************************************************ + * Name: kinetis_i2c_sem_post + * + * Description: + * Release the mutual exclusion semaphore + * + ************************************************************************************/ + +static inline void kinetis_i2c_sem_post(struct kinetis_i2cdev_s *priv) +{ + sem_post(&priv->mutex); +} + +/************************************************************************************ + * Name: kinetis_i2c_wait + * + * Description: + * Wait on the signaling semaphore + * + ************************************************************************************/ + +static inline void kinetis_i2c_wait(struct kinetis_i2cdev_s *priv) +{ + sem_wait(&priv->wait); +} + +/************************************************************************************ + * Name: kinetis_i2c_endwait + * + * Description: + * Release the signaling semaphore + * + ************************************************************************************/ + +static inline void kinetis_i2c_endwait(struct kinetis_i2cdev_s *priv) +{ + sem_post(&priv->wait); +} + +/************************************************************************************ + * Name: kinetis_i2c_init + * + * Description: + * Setup the I2C hardware, ready for operation with defaults + * + ************************************************************************************/ + +static int kinetis_i2c_init(FAR struct kinetis_i2cdev_s *priv) +{ + uint32_t regval; + + /* Enable the clock to peripheral */ + + modifyreg32(priv->config->clk_reg, 0, priv->config->clk_bit); + + /* Disable while configuring */ + + kinetis_i2c_putreg(priv, 0, KINETIS_I2C_C1_OFFSET); + + /* Configure pins */ + + if (kinetis_pinconfig(priv->config->scl_pin) < 0) + { + return ERROR; + } + + if (kinetis_pinconfig(priv->config->sda_pin) < 0) + { + kinetis_pinconfig(MKI2C_INPUT(priv->config->scl_pin)); + return ERROR; + } + + /* High-drive select */ + + regval = kinetis_i2c_getreg(priv, KINETIS_I2C_C2_OFFSET); + regval |= I2C_C2_HDRS; + kinetis_i2c_putreg(priv, regval, KINETIS_I2C_C2_OFFSET); + + /* Attach Interrupt Handler */ + + irq_attach(priv->config->irqid, kinetis_i2c_interrupt, priv); + + /* Enable Interrupt Handler */ + + up_enable_irq(priv->config->irqid); + + /* Force a frequency update */ + + priv->frequency = 0; + + /* Set the default I2C frequency */ + + kinetis_i2c_setfrequency(priv, I2C_DEFAULT_FREQUENCY); + + /* Enable I2C */ + + kinetis_i2c_putreg(priv, I2C_C1_IICEN, KINETIS_I2C_C1_OFFSET); + return OK; +} + +/************************************************************************************ + * Name: kinetis_i2c_deinit + * + * Description: + * Shutdown the I2C hardware + * + ************************************************************************************/ + +static int kinetis_i2c_deinit(FAR struct kinetis_i2cdev_s *priv) +{ + /* Disable I2C */ + + kinetis_i2c_putreg(priv, 0, KINETIS_I2C_C1_OFFSET); + + /* Unconfigure GPIO pins */ + + kinetis_pinconfig(MKI2C_INPUT(priv->config->scl_pin)); + kinetis_pinconfig(MKI2C_INPUT(priv->config->sda_pin)); + + /* Disable and detach interrupts */ + + up_disable_irq(priv->config->irqid); + irq_detach(priv->config->irqid); + + /* Disable clocking */ + + modifyreg32(priv->config->clk_reg, priv->config->clk_bit, 0); + return OK; } /**************************************************************************** @@ -565,7 +851,7 @@ static void kinetis_i2c_stop(struct kinetis_i2cdev_s *priv) kinetis_i2c_putreg(priv, I2C_C1_IICEN | I2C_C1_IICIE, KINETIS_I2C_C1_OFFSET); - sem_post(&priv->wait); + kinetis_i2c_endwait(priv); } /**************************************************************************** @@ -585,7 +871,7 @@ static void kinetis_i2c_timeout(int argc, uint32_t arg, ...) irqstate_t flags = enter_critical_section(); priv->state = STATE_TIMEOUT; - sem_post(&priv->wait); + kinetis_i2c_endwait(priv); leave_critical_section(flags); } @@ -612,7 +898,7 @@ void kinetis_i2c_nextmsg(struct kinetis_i2cdev_s *priv) if (priv->restart) { - sem_post(&priv->wait); + kinetis_i2c_endwait(priv); } } else @@ -695,7 +981,7 @@ static int kinetis_i2c_interrupt(int irq, void *context, void *arg) KINETIS_I2C_D_OFFSET); priv->wrcnt++; - sem_post(&priv->wait); + kinetis_i2c_endwait(priv); } } else @@ -824,7 +1110,7 @@ static int kinetis_i2c_transfer(struct i2c_master_s *dev, /* Get exclusive access to the I2C bus */ - sem_wait(&priv->mutex); + kinetis_i2c_sem_wait(priv); /* Set up for the transfer */ @@ -888,7 +1174,7 @@ static int kinetis_i2c_transfer(struct i2c_master_s *dev, wd_start(priv->timeout, I2C_TIMEOUT, kinetis_i2c_timeout, 1, (uint32_t) priv); - sem_wait(&priv->wait); + kinetis_i2c_wait(priv); wd_cancel(priv->timeout); @@ -901,7 +1187,7 @@ static int kinetis_i2c_transfer(struct i2c_master_s *dev, /* Release access to I2C bus */ - sem_post(&priv->mutex); + kinetis_i2c_sem_post(priv); if (priv->state != STATE_OK) { @@ -930,8 +1216,118 @@ static int kinetis_i2c_transfer(struct i2c_master_s *dev, #ifdef CONFIG_I2C_RESET static int kinetis_i2c_reset(struct i2c_master_s *dev) { - i2cinfo("No reset...\n"); - return OK; + struct kinetis_i2cdev_s *priv = (struct kinetis_i2cdev_s *)dev; + unsigned int clock_count; + unsigned int stretch_count; + uint32_t scl_gpio; + uint32_t sda_gpio; + uint32_t frequency; + int ret = ERROR; + + DEBUGASSERT(dev); + + /* Our caller must own a ref */ + + DEBUGASSERT(priv->refs > 0); + + /* Lock out other clients */ + + kinetis_i2c_sem_wait(priv); + + /* Save the current frequency */ + + frequency = priv->frequency; + + /* De-init the port */ + + kinetis_i2c_deinit(priv); + + /* Use GPIO configuration to un-wedge the bus */ + + scl_gpio = MKI2C_OUTPUT(priv->config->scl_pin); + sda_gpio = MKI2C_OUTPUT(priv->config->sda_pin); + + kinetis_pinconfig(scl_gpio); + kinetis_pinconfig(sda_gpio); + + /* Let SDA go high */ + + kinetis_gpiowrite(sda_gpio, 1); + + /* Clock the bus until any slaves currently driving it let it go. */ + + clock_count = 0; + while (!kinetis_gpioread(sda_gpio)) + { + /* Give up if we have tried too hard */ + + if (clock_count++ > 10) + { + goto out; + } + + /* Sniff to make sure that clock stretching has finished. + * + * If the bus never relaxes, the reset has failed. + */ + + stretch_count = 0; + while (!kinetis_gpioread(scl_gpio)) + { + /* Give up if we have tried too hard */ + + if (stretch_count++ > 10) + { + goto out; + } + + up_udelay(10); + } + + /* Drive SCL low */ + + kinetis_gpiowrite(scl_gpio, 0); + up_udelay(10); + + /* Drive SCL high again */ + + kinetis_gpiowrite(scl_gpio, 1); + up_udelay(10); + } + + /* Generate a start followed by a stop to reset slave + * state machines. + */ + + kinetis_gpiowrite(sda_gpio, 0); + up_udelay(10); + kinetis_gpiowrite(scl_gpio, 0); + up_udelay(10); + kinetis_gpiowrite(scl_gpio, 1); + up_udelay(10); + kinetis_gpiowrite(sda_gpio, 1); + up_udelay(10); + + /* Revert the GPIO configuration. */ + + kinetis_pinconfig(MKI2C_INPUT(sda_gpio)); + kinetis_pinconfig(MKI2C_INPUT(scl_gpio)); + + /* Re-init the port */ + + kinetis_i2c_init(priv); + + /* Restore the frequency */ + + kinetis_i2c_setfrequency(priv, frequency); + ret = OK; + +out: + + /* Release the port for re-use by other clients */ + + kinetis_i2c_sem_post(priv); + return ret; } #endif /* CONFIG_I2C_RESET */ @@ -950,145 +1346,58 @@ static int kinetis_i2c_reset(struct i2c_master_s *dev) struct i2c_master_s *kinetis_i2cbus_initialize(int port) { struct kinetis_i2cdev_s *priv; + irqstate_t flags; i2cinfo("port=%d\n", port); - if (port > 1) + switch(port) { - i2cerr("ERROR: Kinetis I2C Only suppors ports 0 and 1\n"); - return NULL; - } - - irqstate_t flags; - uint32_t regval; - - flags = enter_critical_section(); - #ifdef CONFIG_KINETIS_I2C0 - if (port == 0) - { - priv = &g_i2c0_dev; - priv->base = KINETIS_I2C0_BASE; - priv->irqid = KINETIS_IRQ_I2C0; - priv->basefreq = BOARD_BUS_FREQ; - - /* Enable clock */ - - regval = getreg32(KINETIS_SIM_SCGC4); - regval |= SIM_SCGC4_I2C0; - putreg32(regval, KINETIS_SIM_SCGC4); - - /* Disable while configuring */ - - kinetis_i2c_putreg(priv, 0, KINETIS_I2C_C1_OFFSET); - - /* Configure pins */ - - kinetis_pinconfig(PIN_I2C0_SCL); - kinetis_pinconfig(PIN_I2C0_SDA); - } - else + case 0: + priv = &g_i2c0_dev; + break; #endif #ifdef CONFIG_KINETIS_I2C1 - if (port == 1) - { - priv = &g_i2c1_dev; - priv->base = KINETIS_I2C1_BASE; - priv->irqid = KINETIS_IRQ_I2C1; - priv->basefreq = BOARD_BUS_FREQ; - - /* Enable clock */ - - regval = getreg32(KINETIS_SIM_SCGC4); - regval |= SIM_SCGC4_I2C1; - putreg32(regval, KINETIS_SIM_SCGC4); - - /* Disable while configuring */ - - kinetis_i2c_putreg(priv, 0, KINETIS_I2C_C1_OFFSET); - - /* Configure pins */ - - kinetis_pinconfig(PIN_I2C1_SCL); - kinetis_pinconfig(PIN_I2C1_SDA); - } - else + case 1: + priv = &g_i2c1_dev; + break; #endif #ifdef CONFIG_KINETIS_I2C2 - if (port == 2) - { - priv = &g_i2c2_dev; - priv->base = KINETIS_I2C2_BASE; - priv->irqid = KINETIS_IRQ_I2C2; - priv->basefreq = BOARD_BUS_FREQ; - - /* Enable clock */ - - regval = getreg32(KINETIS_SIM_SCGC4); - regval |= SIM_SCGC4_I2C2; - putreg32(regval, KINETIS_SIM_SCGC4); - - /* Disable while configuring */ - - kinetis_i2c_putreg(priv, 0, KINETIS_I2C_C1_OFFSET); - - /* Configure pins */ - - kinetis_pinconfig(PIN_I2C2_SCL); - kinetis_pinconfig(PIN_I2C2_SDA); - } - else + case 2: + priv = &g_i2c2_dev; + break; #endif - { - leave_critical_section(flags); - i2cerr("ERROR: Unsupport I2C bus: %d\n", port); - return NULL; +#ifdef CONFIG_KINETIS_I2C3 + case 3: + priv = &g_i2c3_dev; + break; +#endif + default: + i2cerr("ERROR: Kinetis I2C Only suppors ports 0 and %d\n", KINETIS_NI2C-1); + return NULL; } - /* Set the default I2C frequency */ - - kinetis_i2c_setfrequency(priv, I2C_DEFAULT_FREQUENCY); - - /* Enable */ - - kinetis_i2c_putreg(priv, I2C_C1_IICEN, KINETIS_I2C_C1_OFFSET); - - /* High-drive select (TODO: why)? */ - - regval = kinetis_i2c_getreg(priv, KINETIS_I2C_C2_OFFSET); - regval |= I2C_C2_HDRS; - kinetis_i2c_putreg(priv, regval, KINETIS_I2C_C2_OFFSET); - + flags = enter_critical_section(); + if ((volatile int)priv->refs++ == 0) + { + priv->timeout = wd_create(); + DEBUGASSERT(priv->timeout != 0); + if (priv->timeout == NULL) + { + priv->refs--; + goto errout; + } + kinetis_i2c_sem_init(priv); + kinetis_i2c_init(priv); + } leave_critical_section(flags); - /* Initialize semaphores */ - - sem_init(&priv->mutex, 0, 1); - sem_init(&priv->wait, 0, 0); - - /* The wait semaphore is used for signaling and, hence, should not have - * priority inheritance enabled. - */ - - sem_setprotocol(&priv->wait, SEM_PRIO_NONE); - - /* Allocate a watchdog timer */ - - priv->timeout = wd_create(); - DEBUGASSERT(priv->timeout != 0); - - /* Attach Interrupt Handler */ - - irq_attach(priv->irqid, kinetis_i2c_interrupt, priv); - - /* Enable Interrupt Handler */ - - up_enable_irq(priv->irqid); - - /* Install our operations */ - - priv->dev.ops = &g_i2c_ops; return &priv->dev; + +errout: + leave_critical_section(flags); + return NULL; + } /**************************************************************************** @@ -1102,13 +1411,32 @@ struct i2c_master_s *kinetis_i2cbus_initialize(int port) int kinetis_i2cbus_uninitialize(struct i2c_master_s *dev) { struct kinetis_i2cdev_s *priv = (struct kinetis_i2cdev_s *)dev; + irqstate_t flags; DEBUGASSERT(priv != NULL); - kinetis_i2c_putreg(priv, 0, KINETIS_I2C_C1_OFFSET); + /* Decrement reference count and check for underflow */ - up_disable_irq(priv->irqid); - irq_detach(priv->irqid); + if (priv->refs == 0) + { + return ERROR; + } + + flags = enter_critical_section(); + + if (--priv->refs) + { + leave_critical_section(flags); + return OK; + } + + leave_critical_section(flags); + + /* Disable power and other HW resource (GPIO's) */ + + kinetis_i2c_deinit(priv); + kinetis_i2c_sem_destroy(priv); + wd_delete(priv->timeout); return OK; } diff --git a/arch/arm/src/stm32/chip/stm32f33xxx_rcc.h b/arch/arm/src/stm32/chip/stm32f33xxx_rcc.h index 806b22e050..ef65a7d436 100644 --- a/arch/arm/src/stm32/chip/stm32f33xxx_rcc.h +++ b/arch/arm/src/stm32/chip/stm32f33xxx_rcc.h @@ -344,7 +344,7 @@ # define RCC_CFGR3_USART1SW_HSI (0 << RCC_CFGR3_USART1SW_SHIFT) /* HSI clock */ #define RCC_CFGR3_I2C1SW (1 << 4) /* Bit 4: I2C1 clock source selection */ #define RCC_CFGR3_TIM1SW (1 << 8) /* Bit 8: TIM1 clock source selection */ -#define RCC_CFGR3_HRTIM1SW (1 << 9) /* Bit 9: HRTIM clock source selection */ +#define RCC_CFGR3_HRTIM1SW (1 << 12) /* Bit 12: HRTIM clock source selection */ #define RCC_CFGR3_USART2SW_SHIFT (16) /* Bits 16-17: USART2 clock source selection */ #define RCC_CFGR3_USART2SW_MASK (3 << RCC_CFGR3_USART2SW_SHIFT) # define RCC_CFGR3_USART2SW_PCLK (0 << RCC_CFGR3_USART2SW_SHIFT) /* PCLK */ diff --git a/arch/arm/src/stm32/stm32_hrtim.c b/arch/arm/src/stm32/stm32_hrtim.c index 109cf19da3..c553fdd6e2 100644 --- a/arch/arm/src/stm32/stm32_hrtim.c +++ b/arch/arm/src/stm32/stm32_hrtim.c @@ -437,10 +437,8 @@ static int stm32_hrtim_ioctl(FAR struct file *filep, int cmd, unsigned long arg) /* HRTIM Register access */ -#ifdef HRTIM_HAVE_CLK_FROM_PLL static void stm32_modifyreg32(unsigned int addr, uint32_t clrbits, uint32_t setbits); -#endif static uint32_t hrtim_cmn_getreg(FAR struct stm32_hrtim_s *priv, int offset); static void hrtim_cmn_putreg(FAR struct stm32_hrtim_s *priv, int offset, uint32_t value); @@ -954,13 +952,11 @@ static int stm32_hrtim_ioctl(FAR struct file *filep, int cmd, unsigned long arg) * ****************************************************************************/ -#ifdef HRTIM_HAVE_CLK_FROM_PLL static void stm32_modifyreg32(unsigned int addr, uint32_t clrbits, uint32_t setbits) { putreg32((getreg32(addr) & ~clrbits) | setbits, addr); } -#endif /**************************************************************************** * Name: hrtim_cmn_getreg @@ -2921,12 +2917,6 @@ static int stm32_hrtimconfig(FAR struct stm32_hrtim_s *priv) int ret; uint32_t regval = 0; - /* Configure PLL VCO output as HRTIM clock source */ - -#ifdef HRTIM_HAVE_CLK_FROM_PLL - stm32_modifyreg32(STM32_RCC_CFGR3, 0, RCC_CFGR3_HRTIM1SW); -#endif - /* HRTIM DLL calibration */ ret = hrtim_dll_cal(priv); diff --git a/arch/arm/src/stm32/stm32_otgfsdev.c b/arch/arm/src/stm32/stm32_otgfsdev.c index 4d23392912..90b5b97ace 100644 --- a/arch/arm/src/stm32/stm32_otgfsdev.c +++ b/arch/arm/src/stm32/stm32_otgfsdev.c @@ -299,7 +299,7 @@ #define EP0 (0) -/* The set of all enpoints available to the class implementation (1-3) */ +/* The set of all endpoints available to the class implementation (1-3) */ #define STM32_EP_AVAILABLE (0x0e) /* All available endpoints */ diff --git a/arch/arm/src/stm32/stm32_pwr.c b/arch/arm/src/stm32/stm32_pwr.c index b2aee60177..2b0ed2a14c 100644 --- a/arch/arm/src/stm32/stm32_pwr.c +++ b/arch/arm/src/stm32/stm32_pwr.c @@ -64,19 +64,20 @@ static uint16_t g_bkp_writable_counter = 0; * Private Functions ************************************************************************************/ -static inline uint16_t stm32_pwr_getreg(uint8_t offset) +static inline uint32_t stm32_pwr_getreg(uint8_t offset) { - return (uint16_t)getreg32(STM32_PWR_BASE + (uint32_t)offset); + return getreg32(STM32_PWR_BASE + (uint32_t)offset); } -static inline void stm32_pwr_putreg(uint8_t offset, uint16_t value) +static inline void stm32_pwr_putreg(uint8_t offset, uint32_t value) { - putreg32((uint32_t)value, STM32_PWR_BASE + (uint32_t)offset); + putreg32(value, STM32_PWR_BASE + (uint32_t)offset); } -static inline void stm32_pwr_modifyreg(uint8_t offset, uint16_t clearbits, uint16_t setbits) +static inline void stm32_pwr_modifyreg(uint8_t offset, uint32_t clearbits, + uint32_t setbits) { - modifyreg32(STM32_PWR_BASE + (uint32_t)offset, (uint32_t)clearbits, (uint32_t)setbits); + modifyreg32(STM32_PWR_BASE + (uint32_t)offset, clearbits, setbits); } /************************************************************************************ @@ -372,4 +373,43 @@ void stm32_pwr_disablepvd(void) #endif /* CONFIG_STM32_ENERGYLITE */ +/************************************************************************************ + * Name: stm32_pwr_enableoverdrive + * + * Description: + * Enable or disable the overdrive mode, allowing clock rates up to 180 MHz. + * If not enabled, the max allowed frequency is 168 MHz. + * + ************************************************************************************/ + +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +void stm32_pwr_enableoverdrive(bool state) +{ + + /* Switch overdrive state */ + + if (state) + { + stm32_pwr_modifyreg(STM32_PWR_CR_OFFSET, 0, PWR_CR_ODEN); + } + else + { + stm32_pwr_modifyreg(STM32_PWR_CR_OFFSET, PWR_CR_ODEN, 0); + } + + /* Wait for overdrive ready */ + + while ((stm32_pwr_getreg(STM32_PWR_CSR_OFFSET) & PWR_CSR_ODRDY) == 0); + + /* Set ODSWEN to switch to this new state*/ + + stm32_pwr_modifyreg(STM32_PWR_CR_OFFSET, 0, PWR_CR_ODSWEN); + + /* Wait for completion */ + + while ((stm32_pwr_getreg(STM32_PWR_CSR_OFFSET) & PWR_CSR_ODSWRDY) == 0); +} +#endif + #endif /* CONFIG_STM32_PWR */ diff --git a/arch/arm/src/stm32/stm32_pwr.h b/arch/arm/src/stm32/stm32_pwr.h index ab33eb9b2c..19af928f14 100644 --- a/arch/arm/src/stm32/stm32_pwr.h +++ b/arch/arm/src/stm32/stm32_pwr.h @@ -215,6 +215,20 @@ void stm32_pwr_disablepvd(void); #endif /* CONFIG_STM32_ENERGYLITE */ +/************************************************************************************ + * Name: stm32_pwr_enableoverdrive + * + * Description: + * Enable or disable the overdrive mode, allowing clock rates up to 180 MHz. + * If not enabled, the max allowed frequency is 168 MHz. + * + ************************************************************************************/ + +#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \ + defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469) +void stm32_pwr_enableoverdrive(bool state); +#endif + #undef EXTERN #if defined(__cplusplus) } diff --git a/arch/arm/src/stm32/stm32f33xxx_rcc.c b/arch/arm/src/stm32/stm32f33xxx_rcc.c index 6254294f5e..76e19858f4 100644 --- a/arch/arm/src/stm32/stm32f33xxx_rcc.c +++ b/arch/arm/src/stm32/stm32f33xxx_rcc.c @@ -342,129 +342,13 @@ static inline void rcc_enableapb2(void) * Name: stm32_stdclockconfig * * Description: - * Called to change to new clock based on settings in board.h. This - * version is for the Connectivity Line parts. + * Called to change to new clock based on settings in board.h. * * NOTE: This logic would need to be extended if you need to select low- * power clocking modes! ****************************************************************************/ -#if !defined(CONFIG_ARCH_BOARD_STM32_CUSTOM_CLOCKCONFIG) && defined(CONFIG_STM32_CONNECTIVITYLINE) -static void stm32_stdclockconfig(void) -{ - uint32_t regval; - - /* Enable HSE */ - - regval = getreg32(STM32_RCC_CR); - regval &= ~RCC_CR_HSEBYP; /* Disable HSE clock bypass */ - regval |= RCC_CR_HSEON; /* Enable HSE */ - putreg32(regval, STM32_RCC_CR); - - /* Set flash wait states - * Sysclk runs with 72MHz -> 2 waitstates. - * 0WS from 0-24MHz - * 1WS from 24-48MHz - * 2WS from 48-72MHz - */ - - regval = getreg32(STM32_FLASH_ACR); - regval &= ~FLASH_ACR_LATENCY_MASK; - regval |= (FLASH_ACR_LATENCY_2 | FLASH_ACR_PRTFBE); - putreg32(regval, STM32_FLASH_ACR); - - /* Set up PLL input scaling (with source = PLL2) */ - - regval = getreg32(STM32_RCC_CFGR2); - regval &= ~(RCC_CFGR2_PREDIV2_MASK | RCC_CFGR2_PLL2MUL_MASK | - RCC_CFGR2_PREDIV1SRC_MASK | RCC_CFGR2_PREDIV1_MASK); - regval |= (STM32_PLL_PREDIV2 | STM32_PLL_PLL2MUL | - RCC_CFGR2_PREDIV1SRC_PLL2 | STM32_PLL_PREDIV1); - putreg32(regval, STM32_RCC_CFGR2); - - /* Set the PCLK2 divider */ - - regval = getreg32(STM32_RCC_CFGR); - regval &= ~(RCC_CFGR_PPRE2_MASK | RCC_CFGR_HPRE_MASK); - regval |= STM32_RCC_CFGR_PPRE2; - regval |= RCC_CFGR_HPRE_SYSCLK; - putreg32(regval, STM32_RCC_CFGR); - - /* Set the PCLK1 divider */ - - regval = getreg32(STM32_RCC_CFGR); - regval &= ~RCC_CFGR_PPRE1_MASK; - regval |= STM32_RCC_CFGR_PPRE1; - putreg32(regval, STM32_RCC_CFGR); - - /* Enable PLL2 */ - - regval = getreg32(STM32_RCC_CR); - regval |= RCC_CR_PLL2ON; - putreg32(regval, STM32_RCC_CR); - - /* Wait for PLL2 ready */ - - while ((getreg32(STM32_RCC_CR) & RCC_CR_PLL2RDY) == 0); - - /* Setup PLL3 for MII/RMII clock on MCO */ - -#if defined(CONFIG_STM32_MII_MCO) || defined(CONFIG_STM32_RMII_MCO) - regval = getreg32(STM32_RCC_CFGR2); - regval &= ~(RCC_CFGR2_PLL3MUL_MASK); - regval |= STM32_PLL_PLL3MUL; - putreg32(regval, STM32_RCC_CFGR2); - - /* Switch PLL3 on */ - - regval = getreg32(STM32_RCC_CR); - regval |= RCC_CR_PLL3ON; - putreg32(regval, STM32_RCC_CR); - - while ((getreg32(STM32_RCC_CR) & RCC_CR_PLL3RDY) == 0); -#endif - - /* Set main PLL source and multiplier */ - - regval = getreg32(STM32_RCC_CFGR); - regval &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMUL_MASK); - regval |= (RCC_CFGR_PLLSRC | STM32_PLL_PLLMUL); - putreg32(regval, STM32_RCC_CFGR); - - /* Switch main PLL on */ - - regval = getreg32(STM32_RCC_CR); - regval |= RCC_CR_PLLON; - putreg32(regval, STM32_RCC_CR); - - while ((getreg32(STM32_RCC_CR) & RCC_CR_PLLRDY) == 0); - - /* Select PLL as system clock source */ - - regval = getreg32(STM32_RCC_CFGR); - regval &= ~RCC_CFGR_SW_MASK; - regval |= RCC_CFGR_SW_PLL; - putreg32(regval, STM32_RCC_CFGR); - - /* Wait until PLL is used as the system clock source */ - - while ((getreg32(STM32_RCC_CFGR) & RCC_CFGR_SWS_PLL) == 0); -} -#endif - -/**************************************************************************** - * Name: stm32_stdclockconfig - * - * Description: - * Called to change to new clock based on settings in board.h. This - * version is for the non-Connectivity Line parts. - * - * NOTE: This logic would need to be extended if you need to select low- - * power clocking modes! - ****************************************************************************/ - -#if !defined(CONFIG_ARCH_BOARD_STM32_CUSTOM_CLOCKCONFIG) && \ - !defined(CONFIG_STM32_CONNECTIVITYLINE) +#if !defined(CONFIG_ARCH_BOARD_STM32_CUSTOM_CLOCKCONFIG) static void stm32_stdclockconfig(void) { uint32_t regval; @@ -507,29 +391,6 @@ static void stm32_stdclockconfig(void) } } -# if defined(CONFIG_STM32_VALUELINE) && (STM32_CFGR_PLLSRC == RCC_CFGR_PLLSRC) - /* If this is a value-line part and we are using the HSE as the PLL */ - -# if (STM32_CFGR_PLLXTPRE >> 17) != (STM32_CFGR2_PREDIV1 & 1) -# error STM32_CFGR_PLLXTPRE must match the LSB of STM32_CFGR2_PREDIV1 -# endif - - /* Set the HSE prescaler */ - - regval = STM32_CFGR2_PREDIV1; - putreg32(regval, STM32_RCC_CFGR2); - -# endif -#endif - -#ifndef CONFIG_STM32_VALUELINE - /* Value-line devices don't implement flash prefetch/waitstates */ - /* Enable FLASH prefetch buffer and 2 wait states */ - - regval = getreg32(STM32_FLASH_ACR); - regval &= ~FLASH_ACR_LATENCY_MASK; - regval |= (FLASH_ACR_LATENCY_2 | FLASH_ACR_PRTFBE); - putreg32(regval, STM32_FLASH_ACR); #endif /* Set the HCLK source/divider */ @@ -607,6 +468,12 @@ static void stm32_stdclockconfig(void) stm32_rcc_enablelse(); #endif + +#ifdef CONFIG_STM32_HRTIM_CLK_FROM_PLL + regval = getreg32(STM32_RCC_CFGR3); + regval |= RCC_CFGR3_HRTIM1SW; + putreg32(regval, STM32_RCC_CFGR3); +#endif } #endif diff --git a/arch/arm/src/stm32f7/chip/stm32f74xx75xx_pinmap.h b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_pinmap.h index efc3b1c3d5..aaa3875ff2 100644 --- a/arch/arm/src/stm32f7/chip/stm32f74xx75xx_pinmap.h +++ b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_pinmap.h @@ -552,12 +552,12 @@ #define GPIO_I2C3_SMBA_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN9) #define GPIO_I2C3_SMBA_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN9) -#define GPIO_I2C4_SCL_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN12) -#define GPIO_I2C4_SCL_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN14) -#define GPIO_I2C4_SCL_3 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN11) -#define GPIO_I2C4_SDA_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN13) -#define GPIO_I2C4_SDA_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN15) -#define GPIO_I2C4_SDA_3 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN12) +#define GPIO_I2C4_SCL_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTD|GPIO_PIN12) +#define GPIO_I2C4_SCL_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTF|GPIO_PIN14) +#define GPIO_I2C4_SCL_3 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTH|GPIO_PIN11) +#define GPIO_I2C4_SDA_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTD|GPIO_PIN13) +#define GPIO_I2C4_SDA_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTF|GPIO_PIN15) +#define GPIO_I2C4_SDA_3 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTH|GPIO_PIN12) #define GPIO_I2C4_SMBA_1 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN11) #define GPIO_I2C4_SMBA_2 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN13) #define GPIO_I2C4_SMBA_3 (GPIO_ALT|GPIO_AF4|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN10) diff --git a/arch/arm/src/stm32f7/chip/stm32f76xx77xx_pinmap.h b/arch/arm/src/stm32f7/chip/stm32f76xx77xx_pinmap.h index c5d1b50a16..e951a8f904 100644 --- a/arch/arm/src/stm32f7/chip/stm32f76xx77xx_pinmap.h +++ b/arch/arm/src/stm32f7/chip/stm32f76xx77xx_pinmap.h @@ -622,15 +622,15 @@ #define GPIO_I2C3_SMBA_1 (GPIO_ALT|GPIO_AF4 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN9) #define GPIO_I2C3_SMBA_2 (GPIO_ALT|GPIO_AF4 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN9) -#define GPIO_I2C4_SCL_1 (GPIO_ALT|GPIO_AF4 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN12) -#define GPIO_I2C4_SCL_2 (GPIO_ALT|GPIO_AF4 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN14) -#define GPIO_I2C4_SCL_3 (GPIO_ALT|GPIO_AF4 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN11) -#define GPIO_I2C4_SCL_4 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN6) -#define GPIO_I2C4_SCL_5 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN8) -#define GPIO_I2C4_SDA_1 (GPIO_ALT|GPIO_AF4 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN13) -#define GPIO_I2C4_SDA_2 (GPIO_ALT|GPIO_AF4 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN15) -#define GPIO_I2C4_SDA_3 (GPIO_ALT|GPIO_AF4 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN12) -#define GPIO_I2C4_SDA_4 (GPIO_ALT|GPIO_AF4 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN9) +#define GPIO_I2C4_SCL_1 (GPIO_ALT|GPIO_AF4 |GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTD|GPIO_PIN12) +#define GPIO_I2C4_SCL_2 (GPIO_ALT|GPIO_AF4 |GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTF|GPIO_PIN14) +#define GPIO_I2C4_SCL_3 (GPIO_ALT|GPIO_AF4 |GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTH|GPIO_PIN11) +#define GPIO_I2C4_SCL_4 (GPIO_ALT|GPIO_AF11|GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN6) +#define GPIO_I2C4_SCL_5 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN8) +#define GPIO_I2C4_SDA_1 (GPIO_ALT|GPIO_AF4 |GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTD|GPIO_PIN13) +#define GPIO_I2C4_SDA_2 (GPIO_ALT|GPIO_AF4 |GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTF|GPIO_PIN15) +#define GPIO_I2C4_SDA_3 (GPIO_ALT|GPIO_AF4 |GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTH|GPIO_PIN12) +#define GPIO_I2C4_SDA_4 (GPIO_ALT|GPIO_AF4 |GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN9) #define GPIO_I2C4_SMBA_1 (GPIO_ALT|GPIO_AF4 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN11) #define GPIO_I2C4_SMBA_2 (GPIO_ALT|GPIO_AF4 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN13) #define GPIO_I2C4_SMBA_3 (GPIO_ALT|GPIO_AF4 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN10) diff --git a/arch/arm/src/stm32l4/Kconfig b/arch/arm/src/stm32l4/Kconfig index 09f5d9860f..29086d5706 100644 --- a/arch/arm/src/stm32l4/Kconfig +++ b/arch/arm/src/stm32l4/Kconfig @@ -3414,6 +3414,18 @@ config UART5_RXDMA ---help--- In high data rate usage, Rx DMA may eliminate Rx overrun errors +config STM32L4_SERIAL_RXDMA_BUFFER_SIZE + int "Rx DMA buffer size" + default 32 + depends on USART1_RXDMA || USART2_RXDMA || USART3_RXDMA || UART4_RXDMA || UART5_RXDMA + ---help--- + The DMA buffer size when using RX DMA to emulate a FIFO. + + When streaming data, the generic serial layer will be called + every time the FIFO receives half this number of bytes. + + Value given here will be rounded up to next multiple of 32 bytes. + config SERIAL_DISABLE_REORDERING bool "Disable reordering of ttySx devices." depends on STM32L4_USART1 || STM32L4_USART2 || STM32L4_USART3 || STM32L4_UART4 || STM32L4_UART5 diff --git a/arch/arm/src/stm32l4/chip/stm32l4_i2c.h b/arch/arm/src/stm32l4/chip/stm32l4_i2c.h index a28dad8728..398073514a 100644 --- a/arch/arm/src/stm32l4/chip/stm32l4_i2c.h +++ b/arch/arm/src/stm32l4/chip/stm32l4_i2c.h @@ -259,5 +259,5 @@ #define I2C_TXDR_MASK (0xff) -#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32F30XXX_I2C_H */ +#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_I2C_H */ diff --git a/arch/arm/src/stm32l4/chip/stm32l4x3xx_dma.h b/arch/arm/src/stm32l4/chip/stm32l4x3xx_dma.h index 166562c9c5..e312e0f9e8 100644 --- a/arch/arm/src/stm32l4/chip/stm32l4x3xx_dma.h +++ b/arch/arm/src/stm32l4/chip/stm32l4x3xx_dma.h @@ -449,7 +449,7 @@ #define DMACHAN_USART2_RX DMACHAN_SETTING(STM32L4_DMA1_CHAN6, 2) #define DMACHAN_USART2_TX DMACHAN_SETTING(STM32L4_DMA1_CHAN7, 2) -#define DMACHAN_USART3_RX DMACHAN_SETTING(STM32L4_DMA1_CHAN3, 1) +#define DMACHAN_USART3_RX DMACHAN_SETTING(STM32L4_DMA1_CHAN3, 2) #define DMACHAN_USART3_TX DMACHAN_SETTING(STM32L4_DMA1_CHAN2, 2) #define DMACHAN_UART4_RX DMACHAN_SETTING(STM32L4_DMA2_CHAN5, 2) diff --git a/arch/arm/src/stm32l4/chip/stm32l4x3xx_pinmap.h b/arch/arm/src/stm32l4/chip/stm32l4x3xx_pinmap.h index bf92bcf54b..40f4076cd8 100644 --- a/arch/arm/src/stm32l4/chip/stm32l4x3xx_pinmap.h +++ b/arch/arm/src/stm32l4/chip/stm32l4x3xx_pinmap.h @@ -160,34 +160,34 @@ /* I2C */ -#define GPIO_I2C1_SDA_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN7) -#define GPIO_I2C1_SDA_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN9) -#define GPIO_I2C1_SCL_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN6) -#define GPIO_I2C1_SCL_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN8) +#define GPIO_I2C1_SDA_1 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN7) +#define GPIO_I2C1_SDA_2 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN9) +#define GPIO_I2C1_SCL_1 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN6) +#define GPIO_I2C1_SCL_2 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN8) #define GPIO_I2C1_SMBA_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTA|GPIO_PIN1) #define GPIO_I2C1_SMBA_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTA|GPIO_PIN14) #define GPIO_I2C1_SMBA_3 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN5) -#define GPIO_I2C2_SDA_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN11) -#define GPIO_I2C2_SDA_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN14) -#define GPIO_I2C2_SCL_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN10) -#define GPIO_I2C2_SCL_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN13) +#define GPIO_I2C2_SDA_1 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN11) +#define GPIO_I2C2_SDA_2 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN14) +#define GPIO_I2C2_SCL_1 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN10) +#define GPIO_I2C2_SCL_2 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN13) #define GPIO_I2C2_SMBA_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN12) -#define GPIO_I2C3_SDA_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN4) -#define GPIO_I2C3_SDA_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTC|GPIO_PIN1) -#define GPIO_I2C3_SCL_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTA|GPIO_PIN7) -#define GPIO_I2C3_SCL_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTC|GPIO_PIN0) +#define GPIO_I2C3_SDA_1 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN4) +#define GPIO_I2C3_SDA_2 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTC|GPIO_PIN1) +#define GPIO_I2C3_SCL_1 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTA|GPIO_PIN7) +#define GPIO_I2C3_SCL_2 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTC|GPIO_PIN0) #define GPIO_I2C3_SMBA_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN2) -#define GPIO_I2C4_SDA_1 (GPIO_ALT|GPIO_AF5 |GPIO_PORTB|GPIO_PIN7) -#define GPIO_I2C4_SDA_2 (GPIO_ALT|GPIO_AF3 |GPIO_PORTB|GPIO_PIN11) -#define GPIO_I2C4_SDA_3 (GPIO_ALT|GPIO_AF2 |GPIO_PORTC|GPIO_PIN1) -#define GPIO_I2C4_SDA_4 (GPIO_ALT|GPIO_AF4 |GPIO_PORTD|GPIO_PIN13) -#define GPIO_I2C4_SCL_1 (GPIO_ALT|GPIO_AF5 |GPIO_PORTB|GPIO_PIN6) -#define GPIO_I2C4_SCL_2 (GPIO_ALT|GPIO_AF3 |GPIO_PORTB|GPIO_PIN10) -#define GPIO_I2C4_SCL_3 (GPIO_ALT|GPIO_AF2 |GPIO_PORTC|GPIO_PIN0) -#define GPIO_I2C4_SCL_4 (GPIO_ALT|GPIO_AF4 |GPIO_PORTD|GPIO_PIN12) +#define GPIO_I2C4_SDA_1 (GPIO_ALT|GPIO_AF5 |GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN7) +#define GPIO_I2C4_SDA_2 (GPIO_ALT|GPIO_AF3 |GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN11) +#define GPIO_I2C4_SDA_3 (GPIO_ALT|GPIO_AF2 |GPIO_OPENDRAIN|GPIO_PORTC|GPIO_PIN1) +#define GPIO_I2C4_SDA_4 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTD|GPIO_PIN13) +#define GPIO_I2C4_SCL_1 (GPIO_ALT|GPIO_AF5 |GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN6) +#define GPIO_I2C4_SCL_2 (GPIO_ALT|GPIO_AF3 |GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN10) +#define GPIO_I2C4_SCL_3 (GPIO_ALT|GPIO_AF2 |GPIO_OPENDRAIN|GPIO_PORTC|GPIO_PIN0) +#define GPIO_I2C4_SCL_4 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTD|GPIO_PIN12) #define GPIO_I2C4_SMBA_1 (GPIO_ALT|GPIO_AF5 |GPIO_PORTA|GPIO_PIN14) #define GPIO_I2C4_SMBA_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTD|GPIO_PIN11) diff --git a/arch/arm/src/stm32l4/chip/stm32l4x3xx_rcc.h b/arch/arm/src/stm32l4/chip/stm32l4x3xx_rcc.h index f05fec85cc..4f6af7e206 100644 --- a/arch/arm/src/stm32l4/chip/stm32l4x3xx_rcc.h +++ b/arch/arm/src/stm32l4/chip/stm32l4x3xx_rcc.h @@ -109,7 +109,7 @@ #define STM32L4_RCC_APB1ENR2 (STM32L4_RCC_BASE+STM32L4_RCC_APB1ENR2_OFFSET) #define STM32L4_RCC_APB2ENR (STM32L4_RCC_BASE+STM32L4_RCC_APB2ENR_OFFSET) #define STM32L4_RCC_AHB1SMENR (STM32L4_RCC_BASE+STM32L4_RCC_AHB1SMENR_OFFSET) -#define STM32L4_RCC_AHB2SMENR (STM32L4_RCC_BASE+STM32L4_RCC_AHB2SMENR) +#define STM32L4_RCC_AHB2SMENR (STM32L4_RCC_BASE+STM32L4_RCC_AHB2SMENR_OFFSET) #define STM32L4_RCC_AHB3SMENR (STM32L4_RCC_BASE+STM32L4_RCC_AHB3SMENR_OFFSET) #define STM32L4_RCC_APB1SMENR1 (STM32L4_RCC_BASE+STM32L4_RCC_APB1SMENR1_OFFSET) #define STM32L4_RCC_APB1SMENR2 (STM32L4_RCC_BASE+STM32L4_RCC_APB1SMENR2_OFFSET) diff --git a/arch/arm/src/stm32l4/chip/stm32l4x5xx_pinmap.h b/arch/arm/src/stm32l4/chip/stm32l4x5xx_pinmap.h index d6f6d1cf50..0a20355ca9 100644 --- a/arch/arm/src/stm32l4/chip/stm32l4x5xx_pinmap.h +++ b/arch/arm/src/stm32l4/chip/stm32l4x5xx_pinmap.h @@ -257,28 +257,28 @@ * I2C1-3 that are not defined here. */ -#define GPIO_I2C1_SDA_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN7) -#define GPIO_I2C1_SDA_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN9) -#define GPIO_I2C1_SDA_3 (GPIO_ALT|GPIO_AF4 |GPIO_PORTG|GPIO_PIN13) -#define GPIO_I2C1_SCL_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN6) -#define GPIO_I2C1_SCL_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN8) -#define GPIO_I2C1_SCL_3 (GPIO_ALT|GPIO_AF4 |GPIO_PORTG|GPIO_PIN14) +#define GPIO_I2C1_SDA_1 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN7) +#define GPIO_I2C1_SDA_2 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN9) +#define GPIO_I2C1_SDA_3 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTG|GPIO_PIN13) +#define GPIO_I2C1_SCL_1 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN6) +#define GPIO_I2C1_SCL_2 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN8) +#define GPIO_I2C1_SCL_3 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTG|GPIO_PIN14) #define GPIO_I2C1_SMBA_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN5) #define GPIO_I2C1_SMBA_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTG|GPIO_PIN15) -#define GPIO_I2C2_SDA_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN11) -#define GPIO_I2C2_SDA_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN14) -#define GPIO_I2C2_SDA_3 (GPIO_ALT|GPIO_AF4 |GPIO_PORTF|GPIO_PIN0) -#define GPIO_I2C2_SCL_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN10) -#define GPIO_I2C2_SCL_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN13) -#define GPIO_I2C2_SCL_3 (GPIO_ALT|GPIO_AF4 |GPIO_PORTF|GPIO_PIN1) +#define GPIO_I2C2_SDA_1 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN11) +#define GPIO_I2C2_SDA_2 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN14) +#define GPIO_I2C2_SDA_3 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTF|GPIO_PIN0) +#define GPIO_I2C2_SCL_1 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN10) +#define GPIO_I2C2_SCL_2 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN13) +#define GPIO_I2C2_SCL_3 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTF|GPIO_PIN1) #define GPIO_I2C2_SMBA_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN12) #define GPIO_I2C2_SMBA_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTF|GPIO_PIN2) -#define GPIO_I2C3_SDA_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTC|GPIO_PIN1) -#define GPIO_I2C3_SDA_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTG|GPIO_PIN8) -#define GPIO_I2C3_SCL_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTC|GPIO_PIN0) -#define GPIO_I2C3_SCL_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTG|GPIO_PIN7) +#define GPIO_I2C3_SDA_1 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTC|GPIO_PIN1) +#define GPIO_I2C3_SDA_2 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTG|GPIO_PIN8) +#define GPIO_I2C3_SCL_1 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTC|GPIO_PIN0) +#define GPIO_I2C3_SCL_2 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTG|GPIO_PIN7) #define GPIO_I2C3_SMBA_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN2) #define GPIO_I2C3_SMBA_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTG|GPIO_PIN6) diff --git a/arch/arm/src/stm32l4/chip/stm32l4x5xx_rcc.h b/arch/arm/src/stm32l4/chip/stm32l4x5xx_rcc.h index 8177609e26..ee49a2720b 100644 --- a/arch/arm/src/stm32l4/chip/stm32l4x5xx_rcc.h +++ b/arch/arm/src/stm32l4/chip/stm32l4x5xx_rcc.h @@ -107,7 +107,7 @@ #define STM32L4_RCC_APB1ENR2 (STM32L4_RCC_BASE+STM32L4_RCC_APB1ENR2_OFFSET) #define STM32L4_RCC_APB2ENR (STM32L4_RCC_BASE+STM32L4_RCC_APB2ENR_OFFSET) #define STM32L4_RCC_AHB1SMENR (STM32L4_RCC_BASE+STM32L4_RCC_AHB1SMENR_OFFSET) -#define STM32L4_RCC_AHB2SMENR (STM32L4_RCC_BASE+STM32L4_RCC_AHB2SMENR) +#define STM32L4_RCC_AHB2SMENR (STM32L4_RCC_BASE+STM32L4_RCC_AHB2SMENR_OFFSET) #define STM32L4_RCC_AHB3SMENR (STM32L4_RCC_BASE+STM32L4_RCC_AHB3SMENR_OFFSET) #define STM32L4_RCC_APB1SMENR1 (STM32L4_RCC_BASE+STM32L4_RCC_APB1SMENR1_OFFSET) #define STM32L4_RCC_APB1SMENR2 (STM32L4_RCC_BASE+STM32L4_RCC_APB1SMENR2_OFFSET) diff --git a/arch/arm/src/stm32l4/chip/stm32l4x6xx_dma.h b/arch/arm/src/stm32l4/chip/stm32l4x6xx_dma.h index 173e0adbe7..8ff0edfca2 100644 --- a/arch/arm/src/stm32l4/chip/stm32l4x6xx_dma.h +++ b/arch/arm/src/stm32l4/chip/stm32l4x6xx_dma.h @@ -489,7 +489,7 @@ #define DMACHAN_USART2_RX DMACHAN_SETTING(STM32L4_DMA1_CHAN6, 2) #define DMACHAN_USART2_TX DMACHAN_SETTING(STM32L4_DMA1_CHAN7, 2) -#define DMACHAN_USART3_RX DMACHAN_SETTING(STM32L4_DMA1_CHAN3, 1) +#define DMACHAN_USART3_RX DMACHAN_SETTING(STM32L4_DMA1_CHAN3, 2) #define DMACHAN_USART3_TX DMACHAN_SETTING(STM32L4_DMA1_CHAN2, 2) #define DMACHAN_UART5_RX DMACHAN_SETTING(STM32L4_DMA2_CHAN2, 2) diff --git a/arch/arm/src/stm32l4/chip/stm32l4x6xx_pinmap.h b/arch/arm/src/stm32l4/chip/stm32l4x6xx_pinmap.h index c149e1dd01..64ae763081 100644 --- a/arch/arm/src/stm32l4/chip/stm32l4x6xx_pinmap.h +++ b/arch/arm/src/stm32l4/chip/stm32l4x6xx_pinmap.h @@ -299,41 +299,41 @@ * I2C1-3 that are not defined here. */ -#define GPIO_I2C1_SDA_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN7) -#define GPIO_I2C1_SDA_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN9) -#define GPIO_I2C1_SDA_3 (GPIO_ALT|GPIO_AF4 |GPIO_PORTG|GPIO_PIN13) -#define GPIO_I2C1_SCL_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN6) -#define GPIO_I2C1_SCL_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN8) -#define GPIO_I2C1_SCL_3 (GPIO_ALT|GPIO_AF4 |GPIO_PORTG|GPIO_PIN14) +#define GPIO_I2C1_SDA_1 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN7) +#define GPIO_I2C1_SDA_2 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN9) +#define GPIO_I2C1_SDA_3 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTG|GPIO_PIN13) +#define GPIO_I2C1_SCL_1 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN6) +#define GPIO_I2C1_SCL_2 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN8) +#define GPIO_I2C1_SCL_3 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTG|GPIO_PIN14) #define GPIO_I2C1_SMBA_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN5) #define GPIO_I2C1_SMBA_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTG|GPIO_PIN15) -#define GPIO_I2C2_SDA_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN11) -#define GPIO_I2C2_SDA_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN14) -#define GPIO_I2C2_SDA_3 (GPIO_ALT|GPIO_AF4 |GPIO_PORTF|GPIO_PIN0) -#define GPIO_I2C2_SCL_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN10) -#define GPIO_I2C2_SCL_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN13) -#define GPIO_I2C2_SCL_3 (GPIO_ALT|GPIO_AF4 |GPIO_PORTF|GPIO_PIN1) +#define GPIO_I2C2_SDA_1 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN11) +#define GPIO_I2C2_SDA_2 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN14) +#define GPIO_I2C2_SDA_3 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTF|GPIO_PIN0) +#define GPIO_I2C2_SCL_1 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN10) +#define GPIO_I2C2_SCL_2 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN13) +#define GPIO_I2C2_SCL_3 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTF|GPIO_PIN1) #define GPIO_I2C2_SMBA_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN12) #define GPIO_I2C2_SMBA_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTF|GPIO_PIN2) -#define GPIO_I2C3_SDA_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTC|GPIO_PIN1) -#define GPIO_I2C3_SDA_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTG|GPIO_PIN8) -#define GPIO_I2C3_SCL_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTC|GPIO_PIN0) -#define GPIO_I2C3_SCL_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTG|GPIO_PIN7) +#define GPIO_I2C3_SDA_1 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTC|GPIO_PIN1) +#define GPIO_I2C3_SDA_2 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTG|GPIO_PIN8) +#define GPIO_I2C3_SCL_1 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTC|GPIO_PIN0) +#define GPIO_I2C3_SCL_2 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTG|GPIO_PIN7) #define GPIO_I2C3_SMBA_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN2) #define GPIO_I2C3_SMBA_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTG|GPIO_PIN6) -#define GPIO_I2C4_SDA_1 (GPIO_ALT|GPIO_AF5 |GPIO_PORTB|GPIO_PIN7) -#define GPIO_I2C4_SDA_2 (GPIO_ALT|GPIO_AF3 |GPIO_PORTB|GPIO_PIN11) -#define GPIO_I2C4_SDA_3 (GPIO_ALT|GPIO_AF2 |GPIO_PORTC|GPIO_PIN1) -#define GPIO_I2C4_SDA_4 (GPIO_ALT|GPIO_AF4 |GPIO_PORTD|GPIO_PIN13) -#define GPIO_I2C4_SDA_5 (GPIO_ALT|GPIO_AF4 |GPIO_PORTF|GPIO_PIN15) -#define GPIO_I2C4_SCL_1 (GPIO_ALT|GPIO_AF5 |GPIO_PORTB|GPIO_PIN6) -#define GPIO_I2C4_SCL_2 (GPIO_ALT|GPIO_AF3 |GPIO_PORTB|GPIO_PIN10) -#define GPIO_I2C4_SCL_3 (GPIO_ALT|GPIO_AF2 |GPIO_PORTC|GPIO_PIN0) -#define GPIO_I2C4_SCL_4 (GPIO_ALT|GPIO_AF4 |GPIO_PORTD|GPIO_PIN12) -#define GPIO_I2C4_SCL_5 (GPIO_ALT|GPIO_AF4 |GPIO_PORTF|GPIO_PIN14) +#define GPIO_I2C4_SDA_1 (GPIO_ALT|GPIO_AF5 |GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN7) +#define GPIO_I2C4_SDA_2 (GPIO_ALT|GPIO_AF3 |GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN11) +#define GPIO_I2C4_SDA_3 (GPIO_ALT|GPIO_AF2 |GPIO_OPENDRAIN|GPIO_PORTC|GPIO_PIN1) +#define GPIO_I2C4_SDA_4 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTD|GPIO_PIN13) +#define GPIO_I2C4_SDA_5 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTF|GPIO_PIN15) +#define GPIO_I2C4_SCL_1 (GPIO_ALT|GPIO_AF5 |GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN6) +#define GPIO_I2C4_SCL_2 (GPIO_ALT|GPIO_AF3 |GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN10) +#define GPIO_I2C4_SCL_3 (GPIO_ALT|GPIO_AF2 |GPIO_OPENDRAIN|GPIO_PORTC|GPIO_PIN0) +#define GPIO_I2C4_SCL_4 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTD|GPIO_PIN12) +#define GPIO_I2C4_SCL_5 (GPIO_ALT|GPIO_AF4 |GPIO_OPENDRAIN|GPIO_PORTF|GPIO_PIN14) #define GPIO_I2C4_SMBA_1 (GPIO_ALT|GPIO_AF5 |GPIO_PORTA|GPIO_PIN14) #define GPIO_I2C4_SMBA_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTD|GPIO_PIN11) #define GPIO_I2C4_SMBA_3 (GPIO_ALT|GPIO_AF4 |GPIO_PORTF|GPIO_PIN13) diff --git a/arch/arm/src/stm32l4/chip/stm32l4x6xx_rcc.h b/arch/arm/src/stm32l4/chip/stm32l4x6xx_rcc.h index 7a8f97a3b2..237c34a548 100644 --- a/arch/arm/src/stm32l4/chip/stm32l4x6xx_rcc.h +++ b/arch/arm/src/stm32l4/chip/stm32l4x6xx_rcc.h @@ -109,7 +109,7 @@ #define STM32L4_RCC_APB1ENR2 (STM32L4_RCC_BASE+STM32L4_RCC_APB1ENR2_OFFSET) #define STM32L4_RCC_APB2ENR (STM32L4_RCC_BASE+STM32L4_RCC_APB2ENR_OFFSET) #define STM32L4_RCC_AHB1SMENR (STM32L4_RCC_BASE+STM32L4_RCC_AHB1SMENR_OFFSET) -#define STM32L4_RCC_AHB2SMENR (STM32L4_RCC_BASE+STM32L4_RCC_AHB2SMENR) +#define STM32L4_RCC_AHB2SMENR (STM32L4_RCC_BASE+STM32L4_RCC_AHB2SMENR_OFFSET) #define STM32L4_RCC_AHB3SMENR (STM32L4_RCC_BASE+STM32L4_RCC_AHB3SMENR_OFFSET) #define STM32L4_RCC_APB1SMENR1 (STM32L4_RCC_BASE+STM32L4_RCC_APB1SMENR1_OFFSET) #define STM32L4_RCC_APB1SMENR2 (STM32L4_RCC_BASE+STM32L4_RCC_APB1SMENR2_OFFSET) diff --git a/arch/arm/src/stm32l4/stm32l4_i2c.c b/arch/arm/src/stm32l4/stm32l4_i2c.c index 892cde5f69..47597c875b 100644 --- a/arch/arm/src/stm32l4/stm32l4_i2c.c +++ b/arch/arm/src/stm32l4/stm32l4_i2c.c @@ -1273,7 +1273,7 @@ static inline void stm32l4_i2c_sendstop(FAR struct stm32l4_i2c_priv_s *priv) * Name: stm32l4_i2c_getstatus * * Description: - * Get 32-bit status (SR1 and SR2 combined) + * Get 32-bit status (ISR register) * ************************************************************************************/ @@ -1556,9 +1556,20 @@ static int stm32l4_i2c_init(FAR struct stm32l4_i2c_priv_s *priv) /* Enable power and reset the peripheral */ - modifyreg32(STM32L4_RCC_APB1ENR1, 0, priv->config->clk_bit); - modifyreg32(STM32L4_RCC_APB1RSTR1, 0, priv->config->reset_bit); - modifyreg32(STM32L4_RCC_APB1RSTR1, priv->config->reset_bit, 0); +#ifdef CONFIG_STM32L4_I2C4 + if (priv->config->base == STM32L4_I2C4_BASE) + { + modifyreg32(STM32L4_RCC_APB1ENR2, 0, priv->config->clk_bit); + modifyreg32(STM32L4_RCC_APB1RSTR2, 0, priv->config->reset_bit); + modifyreg32(STM32L4_RCC_APB1RSTR2, priv->config->reset_bit, 0); + } + else +#endif + { + modifyreg32(STM32L4_RCC_APB1ENR1, 0, priv->config->clk_bit); + modifyreg32(STM32L4_RCC_APB1RSTR1, 0, priv->config->reset_bit); + modifyreg32(STM32L4_RCC_APB1RSTR1, priv->config->reset_bit, 0); + } /* Configure pins */ @@ -1631,7 +1642,16 @@ static int stm32l4_i2c_deinit(FAR struct stm32l4_i2c_priv_s *priv) /* Disable clocking */ - modifyreg32(STM32L4_RCC_APB1ENR1, priv->config->clk_bit, 0); +#ifdef CONFIG_STM32L4_I2C4 + if (priv->config->base == STM32L4_I2C4_BASE) + { + modifyreg32(STM32L4_RCC_APB1ENR2, priv->config->clk_bit, 0); + } + else +#endif + { + modifyreg32(STM32L4_RCC_APB1ENR1, priv->config->clk_bit, 0); + } return OK; } diff --git a/arch/arm/src/stm32l4/stm32l4_serial.c b/arch/arm/src/stm32l4/stm32l4_serial.c index f1a5550212..2c8e9f1ae3 100644 --- a/arch/arm/src/stm32l4/stm32l4_serial.c +++ b/arch/arm/src/stm32l4/stm32l4_serial.c @@ -133,9 +133,18 @@ * * When streaming data, the generic serial layer will be called * every time the FIFO receives half this number of bytes. + * + * If there ever is a STM32L4 with D-cache, the buffer size + * should be an even multiple of ARMV7M_DCACHE_LINESIZE, so that it + * can be individually invalidated. */ -# define RXDMA_BUFFER_SIZE 32 +# if !defined(CONFIG_STM32L4_SERIAL_RXDMA_BUFFER_SIZE) || \ + CONFIG_STM32L4_SERIAL_RXDMA_BUFFER_SIZE == 0 +# define RXDMA_BUFFER_SIZE 32 +# else +# define RXDMA_BUFFER_SIZE ((CONFIG_STM32L4_SERIAL_RXDMA_BUFFER_SIZE + 31) & ~31) +# endif /* DMA priority */ diff --git a/configs/c5471evm/nettest/defconfig b/configs/c5471evm/nettest/defconfig index 45f9e58c62..875ac33c00 100644 --- a/configs/c5471evm/nettest/defconfig +++ b/configs/c5471evm/nettest/defconfig @@ -28,6 +28,7 @@ CONFIG_RRLOAD_BINARY=y # CONFIG_MOTOROLA_SREC is not set # CONFIG_RAW_BINARY is not set # CONFIG_UBOOT_UIMAGE is not set +# CONFIG_DFU_BINARY is not set # # Customize Header Files @@ -123,7 +124,6 @@ CONFIG_ARCH_ARM7TDMI=y # CONFIG_ARCH_CORTEXR7F is not set CONFIG_ARCH_FAMILY="arm" CONFIG_ARCH_CHIP="c5471" -# CONFIG_ARCH_TOOLCHAIN_IAR is not set # CONFIG_ARCH_HAVE_FPU is not set # CONFIG_ARCH_HAVE_DPFPU is not set # CONFIG_ARCH_HAVE_TRUSTZONE is not set @@ -170,6 +170,8 @@ CONFIG_C5471_AUTONEGOTIATION=y # CONFIG_C5471_BASET100 is not set # CONFIG_C5471_BASET10 is not set CONFIG_C5471_HPWORK=y +# CONFIG_ARCH_TOOLCHAIN_IAR is not set +# CONFIG_ARCH_TOOLCHAIN_GNU is not set # # Architecture Options @@ -190,6 +192,7 @@ CONFIG_ARCH_HAVE_VFORK=y # CONFIG_ARCH_HAVE_EXTCLK is not set # CONFIG_ARCH_HAVE_POWEROFF is not set # CONFIG_ARCH_HAVE_RESET is not set +# CONFIG_ARCH_HAVE_RTC_SUBSECONDS is not set CONFIG_ARCH_STACKDUMP=y # CONFIG_ENDIAN_BIG is not set # CONFIG_ARCH_IDLE_CUSTOM is not set @@ -353,14 +356,6 @@ CONFIG_DEV_NULL=y # # Buffering # - -# -# Common I/O Buffer Support -# -CONFIG_MM_IOB=y -CONFIG_IOB_NBUFFERS=24 -CONFIG_IOB_BUFSIZE=196 -CONFIG_IOB_NCHAINS=8 # CONFIG_DRVR_WRITEBUFFER is not set # CONFIG_DRVR_READAHEAD is not set # CONFIG_RAMDISK is not set @@ -466,7 +461,9 @@ CONFIG_OTHER_SERIAL_CONSOLE=y # System Logging # # CONFIG_ARCH_SYSLOG is not set +CONFIG_SYSLOG_WRITE=y # CONFIG_RAMLOG is not set +# CONFIG_SYSLOG_BUFFER is not set # CONFIG_SYSLOG_INTBUFFER is not set # CONFIG_SYSLOG_TIMESTAMP is not set CONFIG_SYSLOG_SERIAL_CONSOLE=y @@ -619,6 +616,15 @@ CONFIG_MM_REGIONS=1 # CONFIG_ARCH_HAVE_HEAP2 is not set # CONFIG_GRAN is not set +# +# Common I/O Buffer Support +# +CONFIG_MM_IOB=y +CONFIG_IOB_NBUFFERS=24 +CONFIG_IOB_BUFSIZE=196 +CONFIG_IOB_NCHAINS=8 +CONFIG_IOB_THROTTLE=0 + # # Audio Support # @@ -627,6 +633,7 @@ CONFIG_MM_REGIONS=1 # # Wireless Support # +# CONFIG_WIRELESS is not set # # Binary Loader @@ -773,9 +780,9 @@ CONFIG_LIB_SENDFILE_BUFSIZE=512 # CONFIG_EXAMPLES_MODBUS is not set # CONFIG_EXAMPLES_MOUNT is not set CONFIG_EXAMPLES_NETTEST=y -CONFIG_EXAMPLES_NETTEST_STACKSIZE=2048 -CONFIG_EXAMPLES_NETTEST_PRIORITY=100 -# CONFIG_EXAMPLES_NETTEST_SERVER is not set +CONFIG_EXAMPLES_NETTEST_STACKSIZE1=2048 +CONFIG_EXAMPLES_NETTEST_PRIORITY1=100 +CONFIG_EXAMPLES_NETTEST_DEVNAME="eth0" # CONFIG_EXAMPLES_NETTEST_PERFORMANCE is not set CONFIG_EXAMPLES_NETTEST_IPv4=y CONFIG_EXAMPLES_NETTEST_INIT=y @@ -787,7 +794,8 @@ CONFIG_EXAMPLES_NETTEST_NOMAC=y CONFIG_EXAMPLES_NETTEST_IPADDR=0x0a000002 CONFIG_EXAMPLES_NETTEST_DRIPADDR=0x0a000001 CONFIG_EXAMPLES_NETTEST_NETMASK=0xffffff00 -CONFIG_EXAMPLES_NETTEST_CLIENTIP=0x0a000001 +CONFIG_EXAMPLES_NETTEST_SERVERIP=0x0a000001 +CONFIG_EXAMPLES_NETTEST_SERVER_PORTNO=5471 # CONFIG_EXAMPLES_NSH is not set # CONFIG_EXAMPLES_NULL is not set # CONFIG_EXAMPLES_NX is not set @@ -898,3 +906,10 @@ CONFIG_NETUTILS_NETLIB=y # # Wireless Libraries and NSH Add-Ons # + +# +# IEEE 802.15.4 applications +# +# CONFIG_IEEE802154_LIBMAC is not set +# CONFIG_IEEE802154_LIBUTILS is not set +# CONFIG_IEEE802154_I8SAK is not set diff --git a/configs/clicker2-stm32/README.txt b/configs/clicker2-stm32/README.txt index 49b645204a..4b9693414a 100644 --- a/configs/clicker2-stm32/README.txt +++ b/configs/clicker2-stm32/README.txt @@ -447,12 +447,100 @@ Configurations The ifconfig command will show the IP address of the server. Then on the client node use this IP address to start the client: - nsh> udpserver & + nsh> udpclient & Where is the IP address of the server that you got above. NOTE: There is no way to stop the UDP test once it has been started other than by resetting the board. + Cheat Sheet. Here is a concise summary of all all the steps needed to + run the UDP test (C=Coordinator; E=Endpoint): + + C: nsh> i8 /dev/ieee0 startpan + C: nsh> 8 acceptassoc + E: nsh> i8 assoc + C: nsh> ifup wpan0 + C: nsh> ifconfig <-- To get the + E: nsh> ifup wpan0 + C: nsh> udpserver & + E: nsh> udpclient & + E: nsh> dmesg + + 6. examples/nettest is enabled. This will allow two MRF24J40 nodes to + exchange TCP packets. Basic instructions: + + On the server node: + + nsh> ifconfig wpan0 + nsh> tcpserver & + + The ifconfig command will show the IP address of the server. Then on + the client node use this IP address to start the client: + + nsh> tcpclient & + + Where is the IP address of the server that you got above. + NOTE: There is no way to stop the UDP test once it has been started + other than by resetting the board. + + Cheat Sheet. Here is a concise summary of all all the steps needed to + run the UDP test (C=Coordinator; E=Endpoint): + + C: nsh> i8 /dev/ieee0 startpan + C: nsh> 8 acceptassoc + E: nsh> i8 assoc + C: nsh> ifup wpan0 + C: nsh> ifconfig <-- To get the + E: nsh> ifup wpan0 + C: nsh> tcpserver & + E: nsh> tcpclient & + E: nsh> dmesg + + STATUS: + 2017-06-19: The Telnet Daemon does not start. This is simply because + the daemon is started too early in the sequence... before the network + has been brought up: + + telnetd_daemon: ERROR: socket failure: 106 + + 2017-06-21: Basic UDP functionality has been achieved with HC06 + compression and short address. Additional testing is required for + other configurations (see text matrix below). + + 2017-06-23: Added test for TCP functionality. As of yet unverified. + + 2017-06-24: There are significant problems with the 6LoWPAN TCP send + logic. A major redesign was done to better handle ACKs and + retransmissions, and to work with TCP dynamic windowing. + + 2017-05-25: After some rather extensive debug, the TCP test was made + to with (HC06 and short addressing). + + 2017-06-26: Verified with HC06 and extended addressing and HC1 with + both addressing modes. + + Test Matrix: + The following configurations have been tested: + + TEST DATE + COMPRESSION ADDRESSING UDP TCP + ----------- ---------- ---- ---- + hc06 short 6/21 6/25 + extended 6/22 6/26 + hc1 short 6/23 6/26 + extended 6/23 6/26 + ipv6 short --- --- + extended --- --- + + Other configuration options have not been specifically addressed + (such non-compressable ports, non-MAC based IPv6 addresses, etc.) + + One limitation of this test is that it only tests NuttX 6LoWPAN + against NuttX 6LoWPAN. It does not prove that NuttX 6LoWPAN is + compatible with other implementations of 6LoWPAN. The tests could + potentially be verifying only that the design is implemented + incorrectly in compatible way on both the client and server sides. + nsh: Configures the NuttShell (nsh) located at examples/nsh. This @@ -509,10 +597,10 @@ Configurations emptied and dumped to the system logging device (USART3 in this configuration): - CONFIG_USBDEV_TRACE=y : Enable USB trace feature - CONFIG_USBDEV_TRACE_NRECORDS=128 : Buffer 128 records in memory - CONFIG_NSH_USBDEV_TRACE=n : No builtin tracing from NSH - CONFIG_NSH_ARCHINIT=y : Automatically start the USB monitor + CONFIG_USBDEV_TRACE=y : Enable USB trace feature + CONFIG_USBDEV_TRACE_NRECORDS=128 : Buffer 128 records in memory + CONFIG_NSH_USBDEV_TRACE=n : No builtin tracing from NSH + CONFIG_NSH_ARCHINIT=y : Automatically start the USB monitor CONFIG_USBMONITOR=y : Enable the USB monitor daemon CONFIG_USBMONITOR_STACKSIZE=2048 : USB monitor daemon stack size CONFIG_USBMONITOR_PRIORITY=50 : USB monitor daemon priority diff --git a/configs/clicker2-stm32/mrf24j40-6lowpan/defconfig b/configs/clicker2-stm32/mrf24j40-6lowpan/defconfig index 9619d02170..2db84d87d7 100644 --- a/configs/clicker2-stm32/mrf24j40-6lowpan/defconfig +++ b/configs/clicker2-stm32/mrf24j40-6lowpan/defconfig @@ -717,7 +717,11 @@ CONFIG_SCHED_HPWORK=y CONFIG_SCHED_HPWORKPRIORITY=192 CONFIG_SCHED_HPWORKPERIOD=50000 CONFIG_SCHED_HPWORKSTACKSIZE=2048 -# CONFIG_SCHED_LPWORK is not set +CONFIG_SCHED_LPWORK=y +CONFIG_SCHED_LPNTHREADS=1 +CONFIG_SCHED_LPWORKPRIORITY=160 +CONFIG_SCHED_LPWORKPERIOD=50000 +CONFIG_SCHED_LPWORKSTACKSIZE=2048 # # Stack and heap information @@ -1076,6 +1080,7 @@ CONFIG_NET_HOSTNAME="MRF24J40" # CONFIG_PSEUDOFS_SOFTLINKS is not set CONFIG_FS_READABLE=y CONFIG_FS_WRITABLE=y +# CONFIG_FS_AIO is not set # CONFIG_FS_NAMED_SEMAPHORES is not set CONFIG_FS_MQUEUE_MPATH="/var/mqueue" # CONFIG_FS_RAMMAP is not set @@ -1138,14 +1143,17 @@ CONFIG_WIRELESS=y CONFIG_WIRELESS_IEEE802154=y CONFIG_IEEE802154_DEFAULT_EADDR=0x00fade00deadbeef CONFIG_MAC802154_HPWORK=y -CONFIG_IEEE802154_NTXDESC=3 -CONFIG_IEEE802154_IND_PREALLOC=20 +# CONFIG_MAC802154_LPWORK is not set +CONFIG_MAC802154_NTXDESC=32 +CONFIG_MAC802154_NNOTIF=48 +CONFIG_IEEE802154_IND_PREALLOC=32 CONFIG_IEEE802154_IND_IRQRESERVE=10 CONFIG_IEEE802154_MACDEV=y CONFIG_IEEE802154_MACDEV_RECVRPRIO=0 CONFIG_IEEE802154_NETDEV=y CONFIG_IEEE802154_NETDEV_RECVRPRIO=1 -CONFIG_IEEE802154_NETDEV_HPWORK=y +# CONFIG_IEEE802154_NETDEV_HPWORK is not set +CONFIG_IEEE802154_NETDEV_LPWORK=y # CONFIG_IEEE802154_LOOPBACK is not set # @@ -1321,7 +1329,36 @@ CONFIG_BUILTIN_PROXY_STACKSIZE=1024 # CONFIG_EXAMPLES_MM is not set # CONFIG_EXAMPLES_MODBUS is not set # CONFIG_EXAMPLES_MOUNT is not set -# CONFIG_EXAMPLES_NETTEST is not set +CONFIG_EXAMPLES_NETTEST=y +CONFIG_EXAMPLES_NETTEST_STACKSIZE1=2048 +CONFIG_EXAMPLES_NETTEST_PRIORITY1=100 +# CONFIG_EXAMPLES_NETTEST_SERVER1 is not set +CONFIG_EXAMPLES_NETTEST_TARGET2=y +CONFIG_EXAMPLES_NETTEST_PRIORITY2=100 +CONFIG_EXAMPLES_NETTEST_STACKSIZE2=2048 +CONFIG_EXAMPLES_NETTEST_DAEMON_STACKSIZE=2048 +CONFIG_EXAMPLES_NETTEST_DEAMON_PRIORITY=100 +CONFIG_EXAMPLES_NETTEST_DEVNAME="wpan0" +# CONFIG_EXAMPLES_NETTEST_PERFORMANCE is not set +CONFIG_EXAMPLES_NETTEST_IPv6=y +# CONFIG_EXAMPLES_NETTEST_INIT is not set + +# +# Target IPv6 address +# + +# +# Server IPv6 address +# +CONFIG_EXAMPLES_NETTEST_SERVERIPv6ADDR_1=0xfe80 +CONFIG_EXAMPLES_NETTEST_SERVERIPv6ADDR_2=0x0000 +CONFIG_EXAMPLES_NETTEST_SERVERIPv6ADDR_3=0x0000 +CONFIG_EXAMPLES_NETTEST_SERVERIPv6ADDR_4=0x0000 +CONFIG_EXAMPLES_NETTEST_SERVERIPv6ADDR_5=0x0000 +CONFIG_EXAMPLES_NETTEST_SERVERIPv6ADDR_6=0x00ff +CONFIG_EXAMPLES_NETTEST_SERVERIPv6ADDR_7=0xfe00 +CONFIG_EXAMPLES_NETTEST_SERVERIPv6ADDR_8=0x0800 +CONFIG_EXAMPLES_NETTEST_SERVER_PORTNO=61616 # CONFIG_EXAMPLES_NRF24L01TERM is not set CONFIG_EXAMPLES_NSH=y CONFIG_EXAMPLES_NSH_CXXINITIALIZE=y @@ -1364,7 +1401,7 @@ CONFIG_EXAMPLES_UDP_DEVNAME="wpan0" CONFIG_EXAMPLES_UDP_IPv6=y # -# Server IPv6 address +# Default Server IPv6 address # CONFIG_EXAMPLES_UDP_SERVERIPv6ADDR_1=0xfe80 CONFIG_EXAMPLES_UDP_SERVERIPv6ADDR_2=0x0000 @@ -1374,6 +1411,8 @@ CONFIG_EXAMPLES_UDP_SERVERIPv6ADDR_5=0x0000 CONFIG_EXAMPLES_UDP_SERVERIPv6ADDR_6=0x00ff CONFIG_EXAMPLES_UDP_SERVERIPv6ADDR_7=0xfe00 CONFIG_EXAMPLES_UDP_SERVERIPv6ADDR_8=0x0d00 +CONFIG_EXAMPLES_UDP_SERVER_PORTNO=61616 +CONFIG_EXAMPLES_UDP_CLIENT_PORTNO=61617 # CONFIG_EXAMPLES_UDPBLASTER is not set # CONFIG_EXAMPLES_USBSERIAL is not set # CONFIG_EXAMPLES_WATCHDOG is not set diff --git a/configs/clicker2-stm32/mrf24j40-mac/defconfig b/configs/clicker2-stm32/mrf24j40-mac/defconfig index d6ba224b4e..7ee79a1d4a 100644 --- a/configs/clicker2-stm32/mrf24j40-mac/defconfig +++ b/configs/clicker2-stm32/mrf24j40-mac/defconfig @@ -984,7 +984,9 @@ CONFIG_WIRELESS=y CONFIG_WIRELESS_IEEE802154=y CONFIG_IEEE802154_DEFAULT_EADDR=0x00fade00deadbeef CONFIG_MAC802154_HPWORK=y -CONFIG_IEEE802154_NTXDESC=3 +CONFIG_MAC802154_NTXDESC=3 +CONFIG_MAC802154_NNOTIF=6 +CONFIG_MAC802154_NPANDESC=5 CONFIG_IEEE802154_IND_PREALLOC=20 CONFIG_IEEE802154_IND_IRQRESERVE=10 CONFIG_IEEE802154_MACDEV=y @@ -1166,10 +1168,10 @@ CONFIG_BUILTIN_PROXY_STACKSIZE=1024 CONFIG_EXAMPLES_NSH=y CONFIG_EXAMPLES_NSH_CXXINITIALIZE=y # CONFIG_EXAMPLES_NULL is not set -# CONFIG_EXAMPLES_NX is not set # CONFIG_EXAMPLES_NXFFS is not set # CONFIG_EXAMPLES_NXHELLO is not set # CONFIG_EXAMPLES_NXIMAGE is not set +# CONFIG_EXAMPLES_NX is not set # CONFIG_EXAMPLES_NXLINES is not set # CONFIG_EXAMPLES_NXTERM is not set # CONFIG_EXAMPLES_NXTEXT is not set diff --git a/configs/eagle100/nettest/defconfig b/configs/eagle100/nettest/defconfig index 228d044b6d..fa12e7dfb6 100644 --- a/configs/eagle100/nettest/defconfig +++ b/configs/eagle100/nettest/defconfig @@ -34,6 +34,7 @@ CONFIG_BUILD_FLAT=y # CONFIG_MOTOROLA_SREC is not set CONFIG_RAW_BINARY=y # CONFIG_UBOOT_UIMAGE is not set +# CONFIG_DFU_BINARY is not set # # Customize Header Files @@ -129,8 +130,6 @@ CONFIG_ARCH_CORTEXM3=y # CONFIG_ARCH_CORTEXR7F is not set CONFIG_ARCH_FAMILY="armv7-m" CONFIG_ARCH_CHIP="tiva" -# CONFIG_ARCH_TOOLCHAIN_IAR is not set -CONFIG_ARCH_TOOLCHAIN_GNU=y # CONFIG_ARMV7M_USEBASEPRI is not set CONFIG_ARCH_HAVE_CMNVECTOR=y # CONFIG_ARMV7M_CMNVECTOR is not set @@ -271,6 +270,8 @@ CONFIG_TIVA_BOARDMAC=y # CONFIG_SSI_POLLWAIT=y CONFIG_SSI_TXLIMIT=4 +# CONFIG_ARCH_TOOLCHAIN_IAR is not set +CONFIG_ARCH_TOOLCHAIN_GNU=y # # Architecture Options @@ -291,6 +292,7 @@ CONFIG_ARCH_HAVE_MPU=y # CONFIG_ARCH_HAVE_EXTCLK is not set # CONFIG_ARCH_HAVE_POWEROFF is not set CONFIG_ARCH_HAVE_RESET=y +# CONFIG_ARCH_HAVE_RTC_SUBSECONDS is not set # CONFIG_ARCH_USE_MPU is not set # CONFIG_ARCH_IRQPRIO is not set CONFIG_ARCH_STACKDUMP=y @@ -458,14 +460,6 @@ CONFIG_DEV_NULL=y # # Buffering # - -# -# Common I/O Buffer Support -# -CONFIG_MM_IOB=y -CONFIG_IOB_NBUFFERS=24 -CONFIG_IOB_BUFSIZE=196 -CONFIG_IOB_NCHAINS=8 # CONFIG_DRVR_WRITEBUFFER is not set # CONFIG_DRVR_READAHEAD is not set # CONFIG_RAMDISK is not set @@ -600,7 +594,9 @@ CONFIG_UART0_2STOP=0 # System Logging # # CONFIG_ARCH_SYSLOG is not set +CONFIG_SYSLOG_WRITE=y # CONFIG_RAMLOG is not set +# CONFIG_SYSLOG_BUFFER is not set # CONFIG_SYSLOG_INTBUFFER is not set # CONFIG_SYSLOG_TIMESTAMP is not set CONFIG_SYSLOG_SERIAL_CONSOLE=y @@ -753,6 +749,15 @@ CONFIG_MM_REGIONS=1 # CONFIG_ARCH_HAVE_HEAP2 is not set # CONFIG_GRAN is not set +# +# Common I/O Buffer Support +# +CONFIG_MM_IOB=y +CONFIG_IOB_NBUFFERS=24 +CONFIG_IOB_BUFSIZE=196 +CONFIG_IOB_NCHAINS=8 +CONFIG_IOB_THROTTLE=0 + # # Audio Support # @@ -761,6 +766,7 @@ CONFIG_MM_REGIONS=1 # # Wireless Support # +# CONFIG_WIRELESS is not set # # Binary Loader @@ -906,9 +912,9 @@ CONFIG_LIB_SENDFILE_BUFSIZE=512 # CONFIG_EXAMPLES_MODBUS is not set # CONFIG_EXAMPLES_MOUNT is not set CONFIG_EXAMPLES_NETTEST=y -CONFIG_EXAMPLES_NETTEST_STACKSIZE=2048 -CONFIG_EXAMPLES_NETTEST_PRIORITY=100 -# CONFIG_EXAMPLES_NETTEST_SERVER is not set +CONFIG_EXAMPLES_NETTEST_STACKSIZE1=2048 +CONFIG_EXAMPLES_NETTEST_PRIORITY1=100 +CONFIG_EXAMPLES_NETTEST_DEVNAME="eth0" # CONFIG_EXAMPLES_NETTEST_PERFORMANCE is not set CONFIG_EXAMPLES_NETTEST_IPv4=y CONFIG_EXAMPLES_NETTEST_INIT=y @@ -920,7 +926,8 @@ CONFIG_EXAMPLES_NETTEST_INIT=y CONFIG_EXAMPLES_NETTEST_IPADDR=0x0a000002 CONFIG_EXAMPLES_NETTEST_DRIPADDR=0x0a000001 CONFIG_EXAMPLES_NETTEST_NETMASK=0xffffff00 -CONFIG_EXAMPLES_NETTEST_CLIENTIP=0x0a000001 +CONFIG_EXAMPLES_NETTEST_SERVERIP=0x0a000001 +CONFIG_EXAMPLES_NETTEST_SERVER_PORTNO=5471 # CONFIG_EXAMPLES_NSH is not set # CONFIG_EXAMPLES_NULL is not set # CONFIG_EXAMPLES_NX is not set @@ -1031,3 +1038,10 @@ CONFIG_NETUTILS_NETLIB=y # # Wireless Libraries and NSH Add-Ons # + +# +# IEEE 802.15.4 applications +# +# CONFIG_IEEE802154_LIBMAC is not set +# CONFIG_IEEE802154_LIBUTILS is not set +# CONFIG_IEEE802154_I8SAK is not set diff --git a/configs/ez80f910200zco/nettest/defconfig b/configs/ez80f910200zco/nettest/defconfig index 2430277422..ef875a9f6e 100644 --- a/configs/ez80f910200zco/nettest/defconfig +++ b/configs/ez80f910200zco/nettest/defconfig @@ -34,6 +34,7 @@ CONFIG_BUILD_FLAT=y # CONFIG_MOTOROLA_SREC is not set # CONFIG_RAW_BINARY is not set # CONFIG_UBOOT_UIMAGE is not set +# CONFIG_DFU_BINARY is not set # # Customize Header Files @@ -152,6 +153,8 @@ CONFIG_EZ80_TXPOLLTIMERMS=10 # CONFIG_ARCH_MCFILTER is not set CONFIG_EZ80_EMAC_HPWORK=y CONFIG_ARCH_TIMERHOOK=y +# CONFIG_ARCH_TOOLCHAIN_IAR is not set +# CONFIG_ARCH_TOOLCHAIN_GNU is not set # # Architecture Options @@ -172,6 +175,7 @@ CONFIG_ARCH_TIMERHOOK=y # CONFIG_ARCH_HAVE_EXTCLK is not set # CONFIG_ARCH_HAVE_POWEROFF is not set # CONFIG_ARCH_HAVE_RESET is not set +# CONFIG_ARCH_HAVE_RTC_SUBSECONDS is not set # CONFIG_ARCH_STACKDUMP is not set # CONFIG_ENDIAN_BIG is not set # CONFIG_ARCH_IDLE_CUSTOM is not set @@ -337,14 +341,6 @@ CONFIG_DEV_NULL=y # # Buffering # - -# -# Common I/O Buffer Support -# -CONFIG_MM_IOB=y -CONFIG_IOB_NBUFFERS=24 -CONFIG_IOB_BUFSIZE=196 -CONFIG_IOB_NCHAINS=8 # CONFIG_DRVR_WRITEBUFFER is not set # CONFIG_DRVR_READAHEAD is not set # CONFIG_RAMDISK is not set @@ -498,7 +494,9 @@ CONFIG_UART0_2STOP=0 # System Logging # # CONFIG_ARCH_SYSLOG is not set +CONFIG_SYSLOG_WRITE=y # CONFIG_RAMLOG is not set +# CONFIG_SYSLOG_BUFFER is not set # CONFIG_SYSLOG_INTBUFFER is not set # CONFIG_SYSLOG_TIMESTAMP is not set CONFIG_SYSLOG_SERIAL_CONSOLE=y @@ -653,6 +651,15 @@ CONFIG_HEAP2_BASE=0x00000000 CONFIG_HEAP2_SIZE=0 # CONFIG_GRAN is not set +# +# Common I/O Buffer Support +# +CONFIG_MM_IOB=y +CONFIG_IOB_NBUFFERS=24 +CONFIG_IOB_BUFSIZE=196 +CONFIG_IOB_NCHAINS=8 +CONFIG_IOB_THROTTLE=0 + # # Audio Support # @@ -661,6 +668,7 @@ CONFIG_HEAP2_SIZE=0 # # Wireless Support # +# CONFIG_WIRELESS is not set # # Binary Loader @@ -801,9 +809,9 @@ CONFIG_LIB_SENDFILE_BUFSIZE=512 # CONFIG_EXAMPLES_MODBUS is not set # CONFIG_EXAMPLES_MOUNT is not set CONFIG_EXAMPLES_NETTEST=y -CONFIG_EXAMPLES_NETTEST_STACKSIZE=2048 -CONFIG_EXAMPLES_NETTEST_PRIORITY=100 -# CONFIG_EXAMPLES_NETTEST_SERVER is not set +CONFIG_EXAMPLES_NETTEST_STACKSIZE1=2048 +CONFIG_EXAMPLES_NETTEST_PRIORITY1=100 +CONFIG_EXAMPLES_NETTEST_DEVNAME="eth0" # CONFIG_EXAMPLES_NETTEST_PERFORMANCE is not set CONFIG_EXAMPLES_NETTEST_IPv4=y CONFIG_EXAMPLES_NETTEST_INIT=y @@ -815,7 +823,8 @@ CONFIG_EXAMPLES_NETTEST_NOMAC=y CONFIG_EXAMPLES_NETTEST_IPADDR=0x0a000002 CONFIG_EXAMPLES_NETTEST_DRIPADDR=0x0a000001 CONFIG_EXAMPLES_NETTEST_NETMASK=0xffffff00 -CONFIG_EXAMPLES_NETTEST_CLIENTIP=0x0a000001 +CONFIG_EXAMPLES_NETTEST_SERVERIP=0x0a000001 +CONFIG_EXAMPLES_NETTEST_SERVER_PORTNO=5471 # CONFIG_EXAMPLES_NSH is not set # CONFIG_EXAMPLES_NULL is not set # CONFIG_EXAMPLES_NX is not set @@ -926,3 +935,10 @@ CONFIG_NETUTILS_NETLIB=y # # Wireless Libraries and NSH Add-Ons # + +# +# IEEE 802.15.4 applications +# +# CONFIG_IEEE802154_LIBMAC is not set +# CONFIG_IEEE802154_LIBUTILS is not set +# CONFIG_IEEE802154_I8SAK is not set diff --git a/configs/misoc/hello/defconfig b/configs/misoc/hello/defconfig index 19f64a538d..309c8e01c8 100644 --- a/configs/misoc/hello/defconfig +++ b/configs/misoc/hello/defconfig @@ -28,6 +28,7 @@ CONFIG_BUILD_FLAT=y # CONFIG_MOTOROLA_SREC is not set CONFIG_RAW_BINARY=y # CONFIG_UBOOT_UIMAGE is not set +# CONFIG_DFU_BINARY is not set # # Customize Header Files @@ -111,6 +112,8 @@ CONFIG_MISOC_UART_RX_BUF_SIZE=64 CONFIG_MISOC_UART_TX_BUF_SIZE=64 # CONFIG_LM32_TOOLCHAIN_BUILDROOT is not set CONFIG_LM32_TOOLCHAIN_GNUL=y +# CONFIG_ARCH_TOOLCHAIN_IAR is not set +CONFIG_ARCH_TOOLCHAIN_GNU=y # # Architecture Options @@ -131,6 +134,7 @@ CONFIG_LM32_TOOLCHAIN_GNUL=y # CONFIG_ARCH_HAVE_EXTCLK is not set # CONFIG_ARCH_HAVE_POWEROFF is not set # CONFIG_ARCH_HAVE_RESET is not set +# CONFIG_ARCH_HAVE_RTC_SUBSECONDS is not set CONFIG_ARCH_STACKDUMP=y CONFIG_ENDIAN_BIG=y # CONFIG_ARCH_IDLE_CUSTOM is not set @@ -318,16 +322,6 @@ CONFIG_DEV_NULL=y # # Buffering # - -# -# Common I/O Buffer Support -# -CONFIG_MM_IOB=y -CONFIG_IOB_NBUFFERS=24 -CONFIG_IOB_BUFSIZE=196 -CONFIG_IOB_NCHAINS=8 -CONFIG_IOB_THROTTLE=8 -# CONFIG_IOB_DEBUG is not set # CONFIG_DRVR_WRITEBUFFER is not set # CONFIG_DRVR_READAHEAD is not set # CONFIG_RAMDISK is not set @@ -486,7 +480,9 @@ CONFIG_UART1_2STOP=0 # System Logging # # CONFIG_ARCH_SYSLOG is not set +CONFIG_SYSLOG_WRITE=y # CONFIG_RAMLOG is not set +# CONFIG_SYSLOG_BUFFER is not set # CONFIG_SYSLOG_INTBUFFER is not set # CONFIG_SYSLOG_TIMESTAMP is not set CONFIG_SYSLOG_SERIAL_CONSOLE=y @@ -643,6 +639,16 @@ CONFIG_MM_REGIONS=1 # CONFIG_ARCH_HAVE_HEAP2 is not set # CONFIG_GRAN is not set +# +# Common I/O Buffer Support +# +CONFIG_MM_IOB=y +CONFIG_IOB_NBUFFERS=24 +CONFIG_IOB_BUFSIZE=196 +CONFIG_IOB_NCHAINS=8 +CONFIG_IOB_THROTTLE=8 +# CONFIG_IOB_DEBUG is not set + # # Audio Support # @@ -651,6 +657,7 @@ CONFIG_MM_REGIONS=1 # # Wireless Support # +# CONFIG_WIRELESS is not set # # Binary Loader @@ -774,7 +781,6 @@ CONFIG_LIB_SENDFILE_BUFSIZE=512 # # CONFIG_C99_BOOL8 is not set CONFIG_HAVE_CXX=y -# CONFIG_HAVE_CXXINITIALIZE is not set # CONFIG_CXX_NEWLONG is not set # @@ -825,9 +831,9 @@ CONFIG_EXAMPLES_HELLO_STACKSIZE=2048 # CONFIG_EXAMPLES_MODBUS is not set # CONFIG_EXAMPLES_MOUNT is not set CONFIG_EXAMPLES_NETTEST=y -CONFIG_EXAMPLES_NETTEST_STACKSIZE=2048 -CONFIG_EXAMPLES_NETTEST_PRIORITY=100 -# CONFIG_EXAMPLES_NETTEST_SERVER is not set +CONFIG_EXAMPLES_NETTEST_STACKSIZE1=2048 +CONFIG_EXAMPLES_NETTEST_PRIORITY1=100 +CONFIG_EXAMPLES_NETTEST_DEVNAME="eth0" CONFIG_EXAMPLES_NETTEST_PERFORMANCE=y CONFIG_EXAMPLES_NETTEST_IPv4=y CONFIG_EXAMPLES_NETTEST_INIT=y @@ -839,7 +845,8 @@ CONFIG_EXAMPLES_NETTEST_NOMAC=y CONFIG_EXAMPLES_NETTEST_IPADDR=0xc0a80132 CONFIG_EXAMPLES_NETTEST_DRIPADDR=0xc0a80101 CONFIG_EXAMPLES_NETTEST_NETMASK=0xffffff00 -CONFIG_EXAMPLES_NETTEST_CLIENTIP=0xc0a8023b +CONFIG_EXAMPLES_NETTEST_SERVERIP=0x0a000001 +CONFIG_EXAMPLES_NETTEST_SERVER_PORTNO=5471 CONFIG_EXAMPLES_NSH=y # CONFIG_EXAMPLES_NULL is not set # CONFIG_EXAMPLES_NX is not set @@ -1053,6 +1060,7 @@ CONFIG_NSH_CONSOLE=y # Networking Configuration # CONFIG_NSH_NETINIT=y +# CONFIG_NSH_NETLOCAL is not set CONFIG_NSH_NETINIT_THREAD=y CONFIG_NSH_NETINIT_THREAD_STACKSIZE=1568 CONFIG_NSH_NETINIT_THREAD_PRIORITY=80 @@ -1090,6 +1098,7 @@ CONFIG_NSH_MAX_ROUNDTRIP=20 # Platform-specific Support # # CONFIG_PLATFORM_CONFIGDATA is not set +# CONFIG_HAVE_CXXINITIALIZE is not set # # System Libraries and NSH Add-Ons @@ -1097,11 +1106,13 @@ CONFIG_NSH_MAX_ROUNDTRIP=20 CONFIG_SYSTEM_CLE=y CONFIG_SYSTEM_CLE_DEBUGLEVEL=0 # CONFIG_SYSTEM_CUTERM is not set +# CONFIG_SYSTEM_DHCPC_RENEW is not set # CONFIG_SYSTEM_FREE is not set # CONFIG_SYSTEM_HEX2BIN is not set # CONFIG_SYSTEM_HEXED is not set # CONFIG_SYSTEM_INSTALL is not set # CONFIG_SYSTEM_NETDB is not set +# CONFIG_SYSTEM_NTPC is not set # CONFIG_SYSTEM_RAMTEST is not set CONFIG_READLINE_HAVE_EXTMATCH=y CONFIG_SYSTEM_READLINE=y @@ -1118,3 +1129,10 @@ CONFIG_READLINE_ECHO=y # # Wireless Libraries and NSH Add-Ons # + +# +# IEEE 802.15.4 applications +# +# CONFIG_IEEE802154_LIBMAC is not set +# CONFIG_IEEE802154_LIBUTILS is not set +# CONFIG_IEEE802154_I8SAK is not set diff --git a/configs/ntosd-dm320/nettest/defconfig b/configs/ntosd-dm320/nettest/defconfig index f93ba341f0..c8823b76ea 100644 --- a/configs/ntosd-dm320/nettest/defconfig +++ b/configs/ntosd-dm320/nettest/defconfig @@ -28,6 +28,7 @@ CONFIG_BUILD_FLAT=y # CONFIG_MOTOROLA_SREC is not set CONFIG_RAW_BINARY=y # CONFIG_UBOOT_UIMAGE is not set +# CONFIG_DFU_BINARY is not set # # Customize Header Files @@ -123,7 +124,6 @@ CONFIG_ARCH_ARM926EJS=y # CONFIG_ARCH_CORTEXR7F is not set CONFIG_ARCH_FAMILY="arm" CONFIG_ARCH_CHIP="dm320" -# CONFIG_ARCH_TOOLCHAIN_IAR is not set # CONFIG_ARCH_HAVE_FPU is not set # CONFIG_ARCH_HAVE_DPFPU is not set # CONFIG_ARCH_HAVE_TRUSTZONE is not set @@ -149,6 +149,8 @@ CONFIG_ARM_TOOLCHAIN_CODESOURCERYL=y # CONFIG_DM320_UART0=y CONFIG_DM320_UART1=y +# CONFIG_ARCH_TOOLCHAIN_IAR is not set +# CONFIG_ARCH_TOOLCHAIN_GNU is not set # # Architecture Options @@ -169,6 +171,7 @@ CONFIG_ARCH_HAVE_MMU=y # CONFIG_ARCH_HAVE_EXTCLK is not set # CONFIG_ARCH_HAVE_POWEROFF is not set # CONFIG_ARCH_HAVE_RESET is not set +# CONFIG_ARCH_HAVE_RTC_SUBSECONDS is not set CONFIG_ARCH_USE_MMU=y # CONFIG_PAGING is not set # CONFIG_ARCH_STACKDUMP is not set @@ -335,14 +338,6 @@ CONFIG_DEV_NULL=y # # Buffering # - -# -# Common I/O Buffer Support -# -CONFIG_MM_IOB=y -CONFIG_IOB_NBUFFERS=24 -CONFIG_IOB_BUFSIZE=196 -CONFIG_IOB_NCHAINS=8 # CONFIG_DRVR_WRITEBUFFER is not set # CONFIG_DRVR_READAHEAD is not set # CONFIG_RAMDISK is not set @@ -505,7 +500,9 @@ CONFIG_UART1_2STOP=0 # System Logging # # CONFIG_ARCH_SYSLOG is not set +CONFIG_SYSLOG_WRITE=y # CONFIG_RAMLOG is not set +# CONFIG_SYSLOG_BUFFER is not set # CONFIG_SYSLOG_INTBUFFER is not set # CONFIG_SYSLOG_TIMESTAMP is not set CONFIG_SYSLOG_SERIAL_CONSOLE=y @@ -659,6 +656,15 @@ CONFIG_MM_REGIONS=1 # CONFIG_GRAN is not set # CONFIG_MM_PGALLOC is not set +# +# Common I/O Buffer Support +# +CONFIG_MM_IOB=y +CONFIG_IOB_NBUFFERS=24 +CONFIG_IOB_BUFSIZE=196 +CONFIG_IOB_NCHAINS=8 +CONFIG_IOB_THROTTLE=0 + # # Audio Support # @@ -667,6 +673,7 @@ CONFIG_MM_REGIONS=1 # # Wireless Support # +# CONFIG_WIRELESS is not set # # Binary Loader @@ -813,9 +820,9 @@ CONFIG_LIB_SENDFILE_BUFSIZE=512 # CONFIG_EXAMPLES_MODBUS is not set # CONFIG_EXAMPLES_MOUNT is not set CONFIG_EXAMPLES_NETTEST=y -CONFIG_EXAMPLES_NETTEST_STACKSIZE=2048 -CONFIG_EXAMPLES_NETTEST_PRIORITY=100 -# CONFIG_EXAMPLES_NETTEST_SERVER is not set +CONFIG_EXAMPLES_NETTEST_STACKSIZE1=2048 +CONFIG_EXAMPLES_NETTEST_PRIORITY1=100 +CONFIG_EXAMPLES_NETTEST_DEVNAME="eth0" # CONFIG_EXAMPLES_NETTEST_PERFORMANCE is not set CONFIG_EXAMPLES_NETTEST_IPv4=y CONFIG_EXAMPLES_NETTEST_INIT=y @@ -827,7 +834,8 @@ CONFIG_EXAMPLES_NETTEST_INIT=y CONFIG_EXAMPLES_NETTEST_IPADDR=0x0a000002 CONFIG_EXAMPLES_NETTEST_DRIPADDR=0x0a000001 CONFIG_EXAMPLES_NETTEST_NETMASK=0xffffff00 -CONFIG_EXAMPLES_NETTEST_CLIENTIP=0x0a000001 +CONFIG_EXAMPLES_NETTEST_SERVERIP=0x0a000001 +CONFIG_EXAMPLES_NETTEST_SERVER_PORTNO=5471 # CONFIG_EXAMPLES_NSH is not set # CONFIG_EXAMPLES_NULL is not set # CONFIG_EXAMPLES_NX is not set @@ -938,3 +946,10 @@ CONFIG_NETUTILS_NETLIB=y # # Wireless Libraries and NSH Add-Ons # + +# +# IEEE 802.15.4 applications +# +# CONFIG_IEEE802154_LIBMAC is not set +# CONFIG_IEEE802154_LIBUTILS is not set +# CONFIG_IEEE802154_I8SAK is not set diff --git a/configs/ntosd-dm320/udp/defconfig b/configs/ntosd-dm320/udp/defconfig index fbaa76ca41..157aeb1d3b 100644 --- a/configs/ntosd-dm320/udp/defconfig +++ b/configs/ntosd-dm320/udp/defconfig @@ -928,7 +928,7 @@ CONFIG_NETUTILS_NETLIB=y # # CONFIG_SYSTEM_CLE is not set # CONFIG_SYSTEM_CUTERM is not set -# CONFIG_SYSTEM_DHCPC is not set +# CONFIG_SYSTEM_DHCPC_RENEW is not set # CONFIG_SYSTEM_FREE is not set # CONFIG_SYSTEM_HEX2BIN is not set # CONFIG_SYSTEM_HEXED is not set diff --git a/configs/olimex-lpc1766stk/nettest/defconfig b/configs/olimex-lpc1766stk/nettest/defconfig index 1c1ce57c62..53650379ac 100644 --- a/configs/olimex-lpc1766stk/nettest/defconfig +++ b/configs/olimex-lpc1766stk/nettest/defconfig @@ -28,6 +28,7 @@ CONFIG_INTELHEX_BINARY=y # CONFIG_MOTOROLA_SREC is not set # CONFIG_RAW_BINARY is not set # CONFIG_UBOOT_UIMAGE is not set +# CONFIG_DFU_BINARY is not set # # Customize Header Files @@ -123,8 +124,6 @@ CONFIG_ARCH_CORTEXM3=y # CONFIG_ARCH_CORTEXR7F is not set CONFIG_ARCH_FAMILY="armv7-m" CONFIG_ARCH_CHIP="lpc17xx" -# CONFIG_ARCH_TOOLCHAIN_IAR is not set -CONFIG_ARCH_TOOLCHAIN_GNU=y # CONFIG_ARMV7M_USEBASEPRI is not set CONFIG_ARCH_HAVE_CMNVECTOR=y # CONFIG_ARMV7M_CMNVECTOR is not set @@ -237,6 +236,8 @@ CONFIG_NET_NRXDESC=6 # CONFIG_NET_HASH is not set # CONFIG_LPC17_MULTICAST is not set CONFIG_LPC17_ETHERNET_HPWORK=y +# CONFIG_ARCH_TOOLCHAIN_IAR is not set +CONFIG_ARCH_TOOLCHAIN_GNU=y # # Architecture Options @@ -257,6 +258,7 @@ CONFIG_ARCH_HAVE_MPU=y # CONFIG_ARCH_HAVE_EXTCLK is not set # CONFIG_ARCH_HAVE_POWEROFF is not set CONFIG_ARCH_HAVE_RESET=y +# CONFIG_ARCH_HAVE_RTC_SUBSECONDS is not set # CONFIG_ARCH_USE_MPU is not set # CONFIG_ARCH_IRQPRIO is not set CONFIG_ARCH_STACKDUMP=y @@ -427,14 +429,6 @@ CONFIG_DEV_NULL=y # # Buffering # - -# -# Common I/O Buffer Support -# -CONFIG_MM_IOB=y -CONFIG_IOB_NBUFFERS=24 -CONFIG_IOB_BUFSIZE=196 -CONFIG_IOB_NCHAINS=8 # CONFIG_DRVR_WRITEBUFFER is not set # CONFIG_DRVR_READAHEAD is not set # CONFIG_RAMDISK is not set @@ -588,7 +582,9 @@ CONFIG_UART0_2STOP=0 # System Logging # # CONFIG_ARCH_SYSLOG is not set +CONFIG_SYSLOG_WRITE=y # CONFIG_RAMLOG is not set +# CONFIG_SYSLOG_BUFFER is not set # CONFIG_SYSLOG_INTBUFFER is not set # CONFIG_SYSLOG_TIMESTAMP is not set CONFIG_SYSLOG_SERIAL_CONSOLE=y @@ -741,6 +737,15 @@ CONFIG_MM_REGIONS=2 # CONFIG_ARCH_HAVE_HEAP2 is not set # CONFIG_GRAN is not set +# +# Common I/O Buffer Support +# +CONFIG_MM_IOB=y +CONFIG_IOB_NBUFFERS=24 +CONFIG_IOB_BUFSIZE=196 +CONFIG_IOB_NCHAINS=8 +CONFIG_IOB_THROTTLE=0 + # # Audio Support # @@ -749,6 +754,7 @@ CONFIG_MM_REGIONS=2 # # Wireless Support # +# CONFIG_WIRELESS is not set # # Binary Loader @@ -895,9 +901,9 @@ CONFIG_LIB_SENDFILE_BUFSIZE=512 # CONFIG_EXAMPLES_MODBUS is not set # CONFIG_EXAMPLES_MOUNT is not set CONFIG_EXAMPLES_NETTEST=y -CONFIG_EXAMPLES_NETTEST_STACKSIZE=2048 -CONFIG_EXAMPLES_NETTEST_PRIORITY=100 -# CONFIG_EXAMPLES_NETTEST_SERVER is not set +CONFIG_EXAMPLES_NETTEST_STACKSIZE1=2048 +CONFIG_EXAMPLES_NETTEST_PRIORITY1=100 +CONFIG_EXAMPLES_NETTEST_DEVNAME="eth0" # CONFIG_EXAMPLES_NETTEST_PERFORMANCE is not set CONFIG_EXAMPLES_NETTEST_IPv4=y CONFIG_EXAMPLES_NETTEST_INIT=y @@ -909,7 +915,8 @@ CONFIG_EXAMPLES_NETTEST_NOMAC=y CONFIG_EXAMPLES_NETTEST_IPADDR=0x0a000002 CONFIG_EXAMPLES_NETTEST_DRIPADDR=0x0a000001 CONFIG_EXAMPLES_NETTEST_NETMASK=0xffffff00 -CONFIG_EXAMPLES_NETTEST_CLIENTIP=0x0a000001 +CONFIG_EXAMPLES_NETTEST_SERVERIP=0x0a000001 +CONFIG_EXAMPLES_NETTEST_SERVER_PORTNO=5471 # CONFIG_EXAMPLES_NSH is not set # CONFIG_EXAMPLES_NULL is not set # CONFIG_EXAMPLES_NX is not set @@ -1020,3 +1027,10 @@ CONFIG_NETUTILS_NETLIB=y # # Wireless Libraries and NSH Add-Ons # + +# +# IEEE 802.15.4 applications +# +# CONFIG_IEEE802154_LIBMAC is not set +# CONFIG_IEEE802154_LIBUTILS is not set +# CONFIG_IEEE802154_I8SAK is not set diff --git a/configs/olimex-strp711/nettest/defconfig b/configs/olimex-strp711/nettest/defconfig index 1ffde23af6..33ad0c8cc1 100644 --- a/configs/olimex-strp711/nettest/defconfig +++ b/configs/olimex-strp711/nettest/defconfig @@ -28,6 +28,7 @@ CONFIG_BUILD_FLAT=y # CONFIG_MOTOROLA_SREC is not set CONFIG_RAW_BINARY=y # CONFIG_UBOOT_UIMAGE is not set +# CONFIG_DFU_BINARY is not set # # Customize Header Files @@ -123,7 +124,6 @@ CONFIG_ARCH_ARM7TDMI=y # CONFIG_ARCH_CORTEXR7F is not set CONFIG_ARCH_FAMILY="arm" CONFIG_ARCH_CHIP="str71x" -# CONFIG_ARCH_TOOLCHAIN_IAR is not set # CONFIG_ARCH_HAVE_FPU is not set # CONFIG_ARCH_HAVE_DPFPU is not set # CONFIG_ARCH_HAVE_TRUSTZONE is not set @@ -178,6 +178,8 @@ CONFIG_STR71X_XTI=y # CONFIG_STR71X_BANK2 is not set # CONFIG_STR71X_BANK3 is not set # CONFIG_STR71X_HAVE_EXTMEM is not set +# CONFIG_ARCH_TOOLCHAIN_IAR is not set +# CONFIG_ARCH_TOOLCHAIN_GNU is not set # # Architecture Options @@ -198,6 +200,7 @@ CONFIG_ARCH_HAVE_VFORK=y # CONFIG_ARCH_HAVE_EXTCLK is not set # CONFIG_ARCH_HAVE_POWEROFF is not set # CONFIG_ARCH_HAVE_RESET is not set +# CONFIG_ARCH_HAVE_RTC_SUBSECONDS is not set CONFIG_ARCH_STACKDUMP=y # CONFIG_ENDIAN_BIG is not set # CONFIG_ARCH_IDLE_CUSTOM is not set @@ -381,14 +384,6 @@ CONFIG_DEV_NULL=y # # Buffering # - -# -# Common I/O Buffer Support -# -CONFIG_MM_IOB=y -CONFIG_IOB_NBUFFERS=24 -CONFIG_IOB_BUFSIZE=196 -CONFIG_IOB_NCHAINS=8 # CONFIG_DRVR_WRITEBUFFER is not set # CONFIG_DRVR_READAHEAD is not set # CONFIG_RAMDISK is not set @@ -551,7 +546,9 @@ CONFIG_UART1_2STOP=0 # System Logging # # CONFIG_ARCH_SYSLOG is not set +CONFIG_SYSLOG_WRITE=y # CONFIG_RAMLOG is not set +# CONFIG_SYSLOG_BUFFER is not set # CONFIG_SYSLOG_INTBUFFER is not set # CONFIG_SYSLOG_TIMESTAMP is not set CONFIG_SYSLOG_SERIAL_CONSOLE=y @@ -705,6 +702,15 @@ CONFIG_MM_REGIONS=1 # CONFIG_ARCH_HAVE_HEAP2 is not set # CONFIG_GRAN is not set +# +# Common I/O Buffer Support +# +CONFIG_MM_IOB=y +CONFIG_IOB_NBUFFERS=24 +CONFIG_IOB_BUFSIZE=196 +CONFIG_IOB_NCHAINS=8 +CONFIG_IOB_THROTTLE=0 + # # Audio Support # @@ -713,6 +719,7 @@ CONFIG_MM_REGIONS=1 # # Wireless Support # +# CONFIG_WIRELESS is not set # # Binary Loader @@ -860,9 +867,9 @@ CONFIG_LIB_SENDFILE_BUFSIZE=512 # CONFIG_EXAMPLES_MODBUS is not set # CONFIG_EXAMPLES_MOUNT is not set CONFIG_EXAMPLES_NETTEST=y -CONFIG_EXAMPLES_NETTEST_STACKSIZE=2048 -CONFIG_EXAMPLES_NETTEST_PRIORITY=100 -# CONFIG_EXAMPLES_NETTEST_SERVER is not set +CONFIG_EXAMPLES_NETTEST_STACKSIZE1=2048 +CONFIG_EXAMPLES_NETTEST_PRIORITY1=100 +CONFIG_EXAMPLES_NETTEST_DEVNAME="eth0" # CONFIG_EXAMPLES_NETTEST_PERFORMANCE is not set CONFIG_EXAMPLES_NETTEST_IPv4=y CONFIG_EXAMPLES_NETTEST_INIT=y @@ -874,7 +881,8 @@ CONFIG_EXAMPLES_NETTEST_NOMAC=y CONFIG_EXAMPLES_NETTEST_IPADDR=0x0a000002 CONFIG_EXAMPLES_NETTEST_DRIPADDR=0x0a000001 CONFIG_EXAMPLES_NETTEST_NETMASK=0xffffff00 -CONFIG_EXAMPLES_NETTEST_CLIENTIP=0x0a000001 +CONFIG_EXAMPLES_NETTEST_SERVERIP=0x0a000001 +CONFIG_EXAMPLES_NETTEST_SERVER_PORTNO=5471 # CONFIG_EXAMPLES_NSH is not set # CONFIG_EXAMPLES_NULL is not set # CONFIG_EXAMPLES_NX is not set @@ -985,3 +993,10 @@ CONFIG_NETUTILS_NETLIB=y # # Wireless Libraries and NSH Add-Ons # + +# +# IEEE 802.15.4 applications +# +# CONFIG_IEEE802154_LIBMAC is not set +# CONFIG_IEEE802154_LIBUTILS is not set +# CONFIG_IEEE802154_I8SAK is not set diff --git a/configs/pic32mx7mmb/nsh/defconfig b/configs/pic32mx7mmb/nsh/defconfig index e2164c01ca..ae8475e651 100644 --- a/configs/pic32mx7mmb/nsh/defconfig +++ b/configs/pic32mx7mmb/nsh/defconfig @@ -1338,7 +1338,7 @@ CONFIG_NSH_IOBUFFER_SIZE=512 # # CONFIG_SYSTEM_CLE is not set # CONFIG_SYSTEM_CUTERM is not set -# CONFIG_SYSTEM_DHCPC is not set +# CONFIG_SYSTEM_DHCPC_RENEW is not set # CONFIG_SYSTEM_FLASH_ERASEALL is not set # CONFIG_SYSTEM_FREE is not set # CONFIG_SYSTEM_HEX2BIN is not set diff --git a/configs/sim/README.txt b/configs/sim/README.txt index 6183b452bf..c4a86191be 100644 --- a/configs/sim/README.txt +++ b/configs/sim/README.txt @@ -810,7 +810,7 @@ sixlowpan This configuration includes apps/examples/nettest and apps/examples/udpblaster. Neither are truly functional. The only intent of this configuration is to verify that the 6LoWPAN stack correctly encodes IEEE802.15.4 - packets on output to the loopback device and correct decodes the + packets on output to the loopback device and correctly decodes the returned packet. touchscreen diff --git a/configs/sim/nettest/defconfig b/configs/sim/nettest/defconfig index 491923f77e..cd7d850534 100644 --- a/configs/sim/nettest/defconfig +++ b/configs/sim/nettest/defconfig @@ -28,6 +28,7 @@ CONFIG_BUILD_FLAT=y # CONFIG_MOTOROLA_SREC is not set # CONFIG_RAW_BINARY is not set # CONFIG_UBOOT_UIMAGE is not set +# CONFIG_DFU_BINARY is not set # # Customize Header Files @@ -83,6 +84,8 @@ CONFIG_SIM_NET_HOST_ROUTE=y # CONFIG_SIM_FRAMEBUFFER is not set # CONFIG_SIM_SPIFLASH is not set # CONFIG_SIM_QSPIFLASH is not set +# CONFIG_ARCH_TOOLCHAIN_IAR is not set +# CONFIG_ARCH_TOOLCHAIN_GNU is not set # # Architecture Options @@ -103,6 +106,7 @@ CONFIG_ARCH_HAVE_MULTICPU=y # CONFIG_ARCH_HAVE_EXTCLK is not set CONFIG_ARCH_HAVE_POWEROFF=y # CONFIG_ARCH_HAVE_RESET is not set +# CONFIG_ARCH_HAVE_RTC_SUBSECONDS is not set # CONFIG_ARCH_STACKDUMP is not set # CONFIG_ENDIAN_BIG is not set # CONFIG_ARCH_IDLE_CUSTOM is not set @@ -279,14 +283,6 @@ CONFIG_DEV_NULL=y # # Buffering # - -# -# Common I/O Buffer Support -# -CONFIG_MM_IOB=y -CONFIG_IOB_NBUFFERS=24 -CONFIG_IOB_BUFSIZE=196 -CONFIG_IOB_NCHAINS=8 # CONFIG_DRVR_WRITEBUFFER is not set # CONFIG_DRVR_READAHEAD is not set # CONFIG_RAMDISK is not set @@ -388,7 +384,9 @@ CONFIG_SERIAL_CONSOLE=y # System Logging # # CONFIG_ARCH_SYSLOG is not set +CONFIG_SYSLOG_WRITE=y # CONFIG_RAMLOG is not set +# CONFIG_SYSLOG_BUFFER is not set # CONFIG_SYSLOG_INTBUFFER is not set # CONFIG_SYSLOG_TIMESTAMP is not set CONFIG_SYSLOG_SERIAL_CONSOLE=y @@ -555,6 +553,15 @@ CONFIG_MM_REGIONS=1 # CONFIG_ARCH_HAVE_HEAP2 is not set # CONFIG_GRAN is not set +# +# Common I/O Buffer Support +# +CONFIG_MM_IOB=y +CONFIG_IOB_NBUFFERS=24 +CONFIG_IOB_BUFSIZE=196 +CONFIG_IOB_NCHAINS=8 +CONFIG_IOB_THROTTLE=0 + # # Audio Support # @@ -563,6 +570,7 @@ CONFIG_MM_REGIONS=1 # # Wireless Support # +# CONFIG_WIRELESS is not set # # Binary Loader @@ -716,9 +724,9 @@ CONFIG_LIB_SENDFILE_BUFSIZE=512 # CONFIG_EXAMPLES_MODBUS is not set # CONFIG_EXAMPLES_MOUNT is not set CONFIG_EXAMPLES_NETTEST=y -CONFIG_EXAMPLES_NETTEST_STACKSIZE=2048 -CONFIG_EXAMPLES_NETTEST_PRIORITY=100 -# CONFIG_EXAMPLES_NETTEST_SERVER is not set +CONFIG_EXAMPLES_NETTEST_STACKSIZE1=2048 +CONFIG_EXAMPLES_NETTEST_PRIORITY1=100 +CONFIG_EXAMPLES_NETTEST_DEVNAME="eth0" # CONFIG_EXAMPLES_NETTEST_PERFORMANCE is not set CONFIG_EXAMPLES_NETTEST_IPv4=y CONFIG_EXAMPLES_NETTEST_INIT=y @@ -730,7 +738,8 @@ CONFIG_EXAMPLES_NETTEST_INIT=y CONFIG_EXAMPLES_NETTEST_IPADDR=0xc0a80080 CONFIG_EXAMPLES_NETTEST_DRIPADDR=0xc0a80001 CONFIG_EXAMPLES_NETTEST_NETMASK=0xffffff00 -CONFIG_EXAMPLES_NETTEST_CLIENTIP=0xc0a8006a +CONFIG_EXAMPLES_NETTEST_SERVERIP=0x0a000001 +CONFIG_EXAMPLES_NETTEST_SERVER_PORTNO=5471 # CONFIG_EXAMPLES_NSH is not set # CONFIG_EXAMPLES_NULL is not set # CONFIG_EXAMPLES_NX is not set @@ -843,3 +852,10 @@ CONFIG_NETUTILS_NETLIB=y # # Wireless Libraries and NSH Add-Ons # + +# +# IEEE 802.15.4 applications +# +# CONFIG_IEEE802154_LIBMAC is not set +# CONFIG_IEEE802154_LIBUTILS is not set +# CONFIG_IEEE802154_I8SAK is not set diff --git a/configs/sim/sixlowpan/defconfig b/configs/sim/sixlowpan/defconfig index 3c2ac60369..8cfb733c96 100644 --- a/configs/sim/sixlowpan/defconfig +++ b/configs/sim/sixlowpan/defconfig @@ -694,8 +694,8 @@ CONFIG_MM_REGIONS=1 # Common I/O Buffer Support # CONFIG_MM_IOB=y -CONFIG_IOB_NBUFFERS=36 -CONFIG_IOB_BUFSIZE=196 +CONFIG_IOB_NBUFFERS=48 +CONFIG_IOB_BUFSIZE=128 CONFIG_IOB_NCHAINS=8 CONFIG_IOB_THROTTLE=8 @@ -711,7 +711,8 @@ CONFIG_WIRELESS=y CONFIG_WIRELESS_IEEE802154=y CONFIG_IEEE802154_DEFAULT_EADDR=0x00fade00deadbeef CONFIG_MAC802154_HPWORK=y -CONFIG_IEEE802154_NTXDESC=3 +CONFIG_MAC802154_NTXDESC=3 +CONFIG_MAC802154_NNOTIF=3 CONFIG_IEEE802154_IND_PREALLOC=20 CONFIG_IEEE802154_IND_IRQRESERVE=10 # CONFIG_IEEE802154_MACDEV is not set @@ -893,11 +894,12 @@ CONFIG_BUILTIN_PROXY_STACKSIZE=2048 # CONFIG_EXAMPLES_MODBUS is not set # CONFIG_EXAMPLES_MOUNT is not set CONFIG_EXAMPLES_NETTEST=y -CONFIG_EXAMPLES_NETTEST_STACKSIZE=4096 -CONFIG_EXAMPLES_NETTEST_PRIORITY=100 +CONFIG_EXAMPLES_NETTEST_STACKSIZE1=4096 +CONFIG_EXAMPLES_NETTEST_PRIORITY1=100 CONFIG_EXAMPLES_NETTEST_LOOPBACK=y -CONFIG_EXAMPLES_NETTEST_SERVER_STACKSIZE=4096 -CONFIG_EXAMPLES_NETTEST_SERVER_PRIORITY=100 +CONFIG_EXAMPLES_NETTEST_DAEMON_STACKSIZE=4096 +CONFIG_EXAMPLES_NETTEST_DAEMON_PRIORITY=100 +CONFIG_EXAMPLES_NETTEST_DEVNAME="eth0" # CONFIG_EXAMPLES_NETTEST_PERFORMANCE is not set CONFIG_EXAMPLES_NETTEST_IPv6=y @@ -906,16 +908,17 @@ CONFIG_EXAMPLES_NETTEST_IPv6=y # # -# Client IPv6 address +# Server IPv6 address # -CONFIG_EXAMPLES_NETTEST_CLIENTIPv6ADDR_1=0xfe80 -CONFIG_EXAMPLES_NETTEST_CLIENTIPv6ADDR_2=0x0000 -CONFIG_EXAMPLES_NETTEST_CLIENTIPv6ADDR_3=0x0000 -CONFIG_EXAMPLES_NETTEST_CLIENTIPv6ADDR_4=0x0000 -CONFIG_EXAMPLES_NETTEST_CLIENTIPv6ADDR_5=0x0000 -CONFIG_EXAMPLES_NETTEST_CLIENTIPv6ADDR_6=0x00ff -CONFIG_EXAMPLES_NETTEST_CLIENTIPv6ADDR_7=0xfe00 -CONFIG_EXAMPLES_NETTEST_CLIENTIPv6ADDR_8=0x1034 +CONFIG_EXAMPLES_NETTEST_SERVERIPv6ADDR_1=0xfe80 +CONFIG_EXAMPLES_NETTEST_SERVERIPv6ADDR_2=0x0000 +CONFIG_EXAMPLES_NETTEST_SERVERIPv6ADDR_3=0x0000 +CONFIG_EXAMPLES_NETTEST_SERVERIPv6ADDR_4=0x0000 +CONFIG_EXAMPLES_NETTEST_SERVERIPv6ADDR_5=0x0000 +CONFIG_EXAMPLES_NETTEST_SERVERIPv6ADDR_6=0x00ff +CONFIG_EXAMPLES_NETTEST_SERVERIPv6ADDR_7=0xfe00 +CONFIG_EXAMPLES_NETTEST_SERVERIPv6ADDR_8=0xcda9 +CONFIG_EXAMPLES_NETTEST_SERVER_PORTNO=61616 # CONFIG_EXAMPLES_NRF24L01TERM is not set CONFIG_EXAMPLES_NSH=y # CONFIG_EXAMPLES_NULL is not set @@ -1165,13 +1168,7 @@ CONFIG_NSH_MAX_ROUNDTRIP=20 # CONFIG_SYSTEM_FREE is not set # CONFIG_SYSTEM_HEX2BIN is not set # CONFIG_SYSTEM_HEXED is not set -CONFIG_SYSTEM_I2CTOOL=y -CONFIG_I2CTOOL_MINBUS=0 -CONFIG_I2CTOOL_MAXBUS=0 -CONFIG_I2CTOOL_MINADDR=0x03 -CONFIG_I2CTOOL_MAXADDR=0x77 -CONFIG_I2CTOOL_MAXREGADDR=0xff -CONFIG_I2CTOOL_DEFFREQ=400000 +# CONFIG_SYSTEM_I2CTOOL is not set # CONFIG_SYSTEM_INSTALL is not set # CONFIG_SYSTEM_MDIO is not set # CONFIG_SYSTEM_NETDB is not set diff --git a/configs/stm3220g-eval/nettest/defconfig b/configs/stm3220g-eval/nettest/defconfig index db3c65568c..df5782fe87 100644 --- a/configs/stm3220g-eval/nettest/defconfig +++ b/configs/stm3220g-eval/nettest/defconfig @@ -131,7 +131,6 @@ CONFIG_ARCH_CORTEXM3=y # CONFIG_ARCH_CORTEXR7F is not set CONFIG_ARCH_FAMILY="armv7-m" CONFIG_ARCH_CHIP="stm32" -# CONFIG_ARCH_TOOLCHAIN_IAR is not set # CONFIG_ARMV7M_USEBASEPRI is not set CONFIG_ARCH_HAVE_CMNVECTOR=y # CONFIG_ARMV7M_CMNVECTOR is not set @@ -403,6 +402,7 @@ CONFIG_STM32_HAVE_I2C2=y CONFIG_STM32_HAVE_I2C3=y CONFIG_STM32_HAVE_SPI2=y CONFIG_STM32_HAVE_SPI3=y +# CONFIG_STM32_HAVE_I2S3 is not set # CONFIG_STM32_HAVE_SPI4 is not set # CONFIG_STM32_HAVE_SPI5 is not set # CONFIG_STM32_HAVE_SPI6 is not set @@ -552,6 +552,7 @@ CONFIG_STM32_ETHMAC_HPWORK=y # # USB Device Configuration # +# CONFIG_ARCH_TOOLCHAIN_IAR is not set CONFIG_ARCH_TOOLCHAIN_GNU=y # @@ -1061,6 +1062,7 @@ CONFIG_MM_IOB=y CONFIG_IOB_NBUFFERS=24 CONFIG_IOB_BUFSIZE=196 CONFIG_IOB_NCHAINS=8 +CONFIG_IOB_THROTTLE=0 # # Audio Support @@ -1187,7 +1189,6 @@ CONFIG_LIB_SENDFILE_BUFSIZE=512 # # CONFIG_C99_BOOL8 is not set CONFIG_HAVE_CXX=y -CONFIG_HAVE_CXXINITIALIZE=y # CONFIG_CXX_NEWLONG is not set # @@ -1231,9 +1232,9 @@ CONFIG_HAVE_CXXINITIALIZE=y # CONFIG_EXAMPLES_MODBUS is not set # CONFIG_EXAMPLES_MOUNT is not set CONFIG_EXAMPLES_NETTEST=y -CONFIG_EXAMPLES_NETTEST_STACKSIZE=2048 -CONFIG_EXAMPLES_NETTEST_PRIORITY=100 -# CONFIG_EXAMPLES_NETTEST_SERVER is not set +CONFIG_EXAMPLES_NETTEST_STACKSIZE1=2048 +CONFIG_EXAMPLES_NETTEST_PRIORITY1=100 +CONFIG_EXAMPLES_NETTEST_DEVNAME="eth0" CONFIG_EXAMPLES_NETTEST_PERFORMANCE=y CONFIG_EXAMPLES_NETTEST_IPv4=y CONFIG_EXAMPLES_NETTEST_INIT=y @@ -1245,7 +1246,8 @@ CONFIG_EXAMPLES_NETTEST_NOMAC=y CONFIG_EXAMPLES_NETTEST_IPADDR=0x0a000002 CONFIG_EXAMPLES_NETTEST_DRIPADDR=0x0a000001 CONFIG_EXAMPLES_NETTEST_NETMASK=0xffffff00 -CONFIG_EXAMPLES_NETTEST_CLIENTIP=0x0a000001 +CONFIG_EXAMPLES_NETTEST_SERVERIP=0x0a000001 +CONFIG_EXAMPLES_NETTEST_SERVER_PORTNO=5471 # CONFIG_EXAMPLES_NSH is not set # CONFIG_EXAMPLES_NULL is not set # CONFIG_EXAMPLES_NX is not set @@ -1334,6 +1336,7 @@ CONFIG_NETUTILS_NETLIB=y # Platform-specific Support # # CONFIG_PLATFORM_CONFIGDATA is not set +CONFIG_HAVE_CXXINITIALIZE=y # # System Libraries and NSH Add-Ons diff --git a/configs/stm3240g-eval/nettest/defconfig b/configs/stm3240g-eval/nettest/defconfig index de9bc2113b..1e890f329c 100644 --- a/configs/stm3240g-eval/nettest/defconfig +++ b/configs/stm3240g-eval/nettest/defconfig @@ -131,7 +131,6 @@ CONFIG_ARCH_CORTEXM4=y # CONFIG_ARCH_CORTEXR7F is not set CONFIG_ARCH_FAMILY="armv7-m" CONFIG_ARCH_CHIP="stm32" -# CONFIG_ARCH_TOOLCHAIN_IAR is not set # CONFIG_ARMV7M_USEBASEPRI is not set CONFIG_ARCH_HAVE_CMNVECTOR=y # CONFIG_ARMV7M_CMNVECTOR is not set @@ -404,6 +403,7 @@ CONFIG_STM32_HAVE_I2C2=y CONFIG_STM32_HAVE_I2C3=y CONFIG_STM32_HAVE_SPI2=y CONFIG_STM32_HAVE_SPI3=y +CONFIG_STM32_HAVE_I2S3=y # CONFIG_STM32_HAVE_SPI4 is not set # CONFIG_STM32_HAVE_SPI5 is not set # CONFIG_STM32_HAVE_SPI6 is not set @@ -442,6 +442,7 @@ CONFIG_STM32_ETHMAC=y # CONFIG_STM32_SPI1 is not set # CONFIG_STM32_SPI2 is not set # CONFIG_STM32_SPI3 is not set +# CONFIG_STM32_I2S3 is not set CONFIG_STM32_SYSCFG=y # CONFIG_STM32_TIM1 is not set # CONFIG_STM32_TIM2 is not set @@ -556,6 +557,7 @@ CONFIG_STM32_ETHMAC_HPWORK=y # # USB Device Configuration # +# CONFIG_ARCH_TOOLCHAIN_IAR is not set CONFIG_ARCH_TOOLCHAIN_GNU=y # @@ -1065,6 +1067,7 @@ CONFIG_MM_IOB=y CONFIG_IOB_NBUFFERS=24 CONFIG_IOB_BUFSIZE=196 CONFIG_IOB_NCHAINS=8 +CONFIG_IOB_THROTTLE=0 # # Audio Support @@ -1191,7 +1194,6 @@ CONFIG_LIB_SENDFILE_BUFSIZE=512 # # CONFIG_C99_BOOL8 is not set CONFIG_HAVE_CXX=y -CONFIG_HAVE_CXXINITIALIZE=y # CONFIG_CXX_NEWLONG is not set # @@ -1235,9 +1237,9 @@ CONFIG_HAVE_CXXINITIALIZE=y # CONFIG_EXAMPLES_MODBUS is not set # CONFIG_EXAMPLES_MOUNT is not set CONFIG_EXAMPLES_NETTEST=y -CONFIG_EXAMPLES_NETTEST_STACKSIZE=2048 -CONFIG_EXAMPLES_NETTEST_PRIORITY=100 -# CONFIG_EXAMPLES_NETTEST_SERVER is not set +CONFIG_EXAMPLES_NETTEST_STACKSIZE1=2048 +CONFIG_EXAMPLES_NETTEST_PRIORITY1=100 +CONFIG_EXAMPLES_NETTEST_DEVNAME="eth0" CONFIG_EXAMPLES_NETTEST_PERFORMANCE=y CONFIG_EXAMPLES_NETTEST_IPv4=y CONFIG_EXAMPLES_NETTEST_INIT=y @@ -1249,7 +1251,8 @@ CONFIG_EXAMPLES_NETTEST_NOMAC=y CONFIG_EXAMPLES_NETTEST_IPADDR=0x0a000002 CONFIG_EXAMPLES_NETTEST_DRIPADDR=0x0a000001 CONFIG_EXAMPLES_NETTEST_NETMASK=0xffffff00 -CONFIG_EXAMPLES_NETTEST_CLIENTIP=0x0a000001 +CONFIG_EXAMPLES_NETTEST_SERVERIP=0x0a000001 +CONFIG_EXAMPLES_NETTEST_SERVER_PORTNO=5471 # CONFIG_EXAMPLES_NSH is not set # CONFIG_EXAMPLES_NULL is not set # CONFIG_EXAMPLES_NX is not set @@ -1338,6 +1341,7 @@ CONFIG_NETUTILS_NETLIB=y # Platform-specific Support # # CONFIG_PLATFORM_CONFIGDATA is not set +CONFIG_HAVE_CXXINITIALIZE=y # # System Libraries and NSH Add-Ons diff --git a/configs/stm3240g-eval/webserver/defconfig b/configs/stm3240g-eval/webserver/defconfig index c438b53b40..8d4e93adb5 100644 --- a/configs/stm3240g-eval/webserver/defconfig +++ b/configs/stm3240g-eval/webserver/defconfig @@ -125,7 +125,6 @@ CONFIG_ARCH_CORTEXM4=y # CONFIG_ARCH_CORTEXR7F is not set CONFIG_ARCH_FAMILY="armv7-m" CONFIG_ARCH_CHIP="stm32" -# CONFIG_ARCH_TOOLCHAIN_IAR is not set # CONFIG_ARMV7M_USEBASEPRI is not set CONFIG_ARCH_HAVE_CMNVECTOR=y # CONFIG_ARMV7M_CMNVECTOR is not set @@ -394,6 +393,7 @@ CONFIG_STM32_HAVE_I2C2=y CONFIG_STM32_HAVE_I2C3=y CONFIG_STM32_HAVE_SPI2=y CONFIG_STM32_HAVE_SPI3=y +CONFIG_STM32_HAVE_I2S3=y # CONFIG_STM32_HAVE_SPI4 is not set # CONFIG_STM32_HAVE_SPI5 is not set # CONFIG_STM32_HAVE_SPI6 is not set @@ -432,6 +432,7 @@ CONFIG_STM32_PWR=y # CONFIG_STM32_SPI1 is not set # CONFIG_STM32_SPI2 is not set # CONFIG_STM32_SPI3 is not set +# CONFIG_STM32_I2S3 is not set CONFIG_STM32_SYSCFG=y # CONFIG_STM32_TIM1 is not set # CONFIG_STM32_TIM2 is not set @@ -563,6 +564,7 @@ CONFIG_STM32_ETHMAC_HPWORK=y # # USB Device Configuration # +# CONFIG_ARCH_TOOLCHAIN_IAR is not set CONFIG_ARCH_TOOLCHAIN_GNU=y # @@ -1154,6 +1156,7 @@ CONFIG_MM_IOB=y CONFIG_IOB_NBUFFERS=24 CONFIG_IOB_BUFSIZE=196 CONFIG_IOB_NCHAINS=8 +CONFIG_IOB_THROTTLE=0 # # Audio Support @@ -1289,7 +1292,6 @@ CONFIG_LIB_SENDFILE_BUFSIZE=512 # # CONFIG_C99_BOOL8 is not set CONFIG_HAVE_CXX=y -CONFIG_HAVE_CXXINITIALIZE=y # CONFIG_CXX_NEWLONG is not set # @@ -1335,9 +1337,9 @@ CONFIG_HAVE_CXXINITIALIZE=y # CONFIG_EXAMPLES_MODBUS is not set # CONFIG_EXAMPLES_MOUNT is not set CONFIG_EXAMPLES_NETTEST=y -CONFIG_EXAMPLES_NETTEST_STACKSIZE=2048 -CONFIG_EXAMPLES_NETTEST_PRIORITY=100 -# CONFIG_EXAMPLES_NETTEST_SERVER is not set +CONFIG_EXAMPLES_NETTEST_STACKSIZE1=2048 +CONFIG_EXAMPLES_NETTEST_PRIORITY1=100 +CONFIG_EXAMPLES_NETTEST_DEVNAME="eth0" # CONFIG_EXAMPLES_NETTEST_PERFORMANCE is not set CONFIG_EXAMPLES_NETTEST_IPv4=y CONFIG_EXAMPLES_NETTEST_INIT=y @@ -1349,7 +1351,8 @@ CONFIG_EXAMPLES_NETTEST_NOMAC=y CONFIG_EXAMPLES_NETTEST_IPADDR=0x0a000002 CONFIG_EXAMPLES_NETTEST_DRIPADDR=0x0a000001 CONFIG_EXAMPLES_NETTEST_NETMASK=0xffffff00 -CONFIG_EXAMPLES_NETTEST_CLIENTIP=0x0a000001 +CONFIG_EXAMPLES_NETTEST_SERVERIP=0x0a000001 +CONFIG_EXAMPLES_NETTEST_SERVER_PORTNO=5471 # CONFIG_EXAMPLES_NSH is not set # CONFIG_EXAMPLES_NULL is not set # CONFIG_EXAMPLES_NX is not set @@ -1551,6 +1554,7 @@ CONFIG_NSH_CONSOLE=y # Networking Configuration # CONFIG_NSH_NETINIT=y +# CONFIG_NSH_NETLOCAL is not set # CONFIG_NSH_NETINIT_THREAD is not set # @@ -1590,6 +1594,7 @@ CONFIG_NSH_IOBUFFER_SIZE=512 # Platform-specific Support # # CONFIG_PLATFORM_CONFIGDATA is not set +CONFIG_HAVE_CXXINITIALIZE=y # # System Libraries and NSH Add-Ons @@ -1602,6 +1607,7 @@ CONFIG_NSH_IOBUFFER_SIZE=512 # CONFIG_SYSTEM_I2CTOOL is not set # CONFIG_SYSTEM_INSTALL is not set # CONFIG_SYSTEM_NETDB is not set +# CONFIG_SYSTEM_NTPC is not set # CONFIG_SYSTEM_RAMTEST is not set CONFIG_READLINE_HAVE_EXTMATCH=y CONFIG_SYSTEM_READLINE=y diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 4451d52b0a..c9425d8c40 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -667,8 +667,9 @@ static int tun_ifup(struct net_driver_s *dev) static int tun_ifdown(struct net_driver_s *dev) { FAR struct tun_device_s *priv = (FAR struct tun_device_s *)dev->d_private; + irqstate_t flags; - tun_lock(priv); + flags = enter_critical_section(); /* Cancel the TX poll timer */ @@ -677,7 +678,8 @@ static int tun_ifdown(struct net_driver_s *dev) /* Mark the device "down" */ priv->bifup = false; - tun_unlock(priv); + + leave_critical_section(flags); return OK; } diff --git a/drivers/wireless/ieee802154/at86rf23x.c b/drivers/wireless/ieee802154/at86rf23x.c index 2da26d3da9..3e4cd0ce11 100644 --- a/drivers/wireless/ieee802154/at86rf23x.c +++ b/drivers/wireless/ieee802154/at86rf23x.c @@ -1533,22 +1533,22 @@ FAR struct ieee802154_radio_s *at86rf23x_init(FAR struct spi_dev_s *spi, /* Configure the Pan id */ - //at86rf23x_setpanid (&dev->ieee, IEEE802154_PAN_DEFAULT); + //at86rf23x_setpanid(&dev->ieee, IEEE802154_PAN_DEFAULT); /* Configure the Short Addr */ - //at86rf23x_setsaddr (&dev->ieee, IEEE802154_SADDR_UNSPEC); + //at86rf23x_setsaddr(&dev->ieee, IEEE802154_SADDR_UNSPEC); /* Configure the IEEE Addr */ - //at86rf23x_seteaddr (&dev->ieee, IEEE802154_EADDR_UNSPEC); + //at86rf23x_seteaddr(&dev->ieee, IEEE802154_EADDR_UNSPEC); /* Default device params at86rf23x defaults to energy detect only */ cca.use_ed = 1; cca.use_cs = 0; - cca.edth = 0x60; /* CCA mode ED, no carrier sense, recommenced ED - * threshold -69 dBm */ + cca.edth = 0x60; /* CCA mode ED, no carrier sense, recommenced ED + * threshold -69 dBm */ at86rf23x_setcca(&dev->ieee, &cca); /* Put the Device to RX ON Mode */ diff --git a/drivers/wireless/ieee802154/mrf24j40.c b/drivers/wireless/ieee802154/mrf24j40.c index 89ff1e69c1..7f91a09e20 100644 --- a/drivers/wireless/ieee802154/mrf24j40.c +++ b/drivers/wireless/ieee802154/mrf24j40.c @@ -103,6 +103,24 @@ #define MRF24J40_GTS_SLOTS 2 +/* Clock configuration macros */ + +#define MRF24J40_SLPCLKPER_100KHZ ((1000 * 1000 * 1000)/100000) /* 10ns */ +#define MRF24J40_SLPCLKPER_32KHZ ((1000 * 1000 * 1000)/32000) /* 31.25ns */ + +#define MRF24J40_BEACONINTERVAL_NSEC(beaconorder) \ + (IEEE802154_BASE_SUPERFRAME_DURATION * (1 << beaconorder) * (16 *1000)) + +/* For now I am just setting the REMCNT to the maximum while staying in multiples + * of 10000 (100khz period) */ + +#define MRF24J40_REMCNT 60000 +#define MRF24J40_REMCNT_NSEC (MRF24J40_REMCNT * 50) + +#define MRF24J40_MAINCNT(bo, clkper) \ + ((MRF24J40_BEACONINTERVAL_NSEC(bo) - MRF24J40_REMCNT_NSEC) / \ + clkper) + /* Formula for calculating default macMaxFrameWaitTime is on pg. 130 * * For PHYs other than CSS and UWB, the attribute phyMaxFrameDuration is given by: @@ -146,7 +164,7 @@ struct mrf24j40_radio_s struct ieee802154_addr_s addr; - uint8_t channel; /* 11 to 26 for the 2.4 GHz band */ + uint8_t chan; /* 11 to 26 for the 2.4 GHz band */ uint8_t devmode; /* device mode: device, coord, pancoord */ uint8_t paenabled; /* enable usage of PA */ uint8_t rxmode; /* Reception mode: Main, no CRC, promiscuous */ @@ -163,6 +181,8 @@ struct mrf24j40_radio_s bool csma_busy : 1; bool reschedule_csma : 1; + bool rxenabled : 1; + struct ieee802154_txdesc_s *gts_desc[MRF24J40_GTS_SLOTS]; bool gts_busy[MRF24J40_GTS_SLOTS]; }; @@ -197,12 +217,12 @@ static int mrf24j40_interrupt(int irq, FAR void *context, FAR void *arg); static void mrf24j40_dopoll_csma(FAR void *arg); static void mrf24j40_dopoll_gts(FAR void *arg); -static int mrf24j40_norm_setup(FAR struct mrf24j40_radio_s *dev, +static void mrf24j40_norm_setup(FAR struct mrf24j40_radio_s *dev, FAR struct iob_s *frame, bool csma); -static int mrf24j40_gts_setup(FAR struct mrf24j40_radio_s *dev, uint8_t gts, +static void mrf24j40_gts_setup(FAR struct mrf24j40_radio_s *dev, uint8_t gts, FAR struct iob_s *frame); -static int mrf24j40_setup_fifo(FAR struct mrf24j40_radio_s *dev, - FAR struct iob_s *frame, uint32_t fifo_addr); +static void mrf24j40_setup_fifo(FAR struct mrf24j40_radio_s *dev, + FAR const uint8_t *buf, uint8_t length, uint32_t fifo_addr); static inline void mrf24j40_norm_trigger(FAR struct mrf24j40_radio_s *dev); @@ -214,6 +234,10 @@ static int mrf24j40_setsaddr(FAR struct mrf24j40_radio_s *dev, FAR const uint8_t *saddr); static int mrf24j40_seteaddr(FAR struct mrf24j40_radio_s *dev, FAR const uint8_t *eaddr); +static int mrf24j40_setcoordsaddr(FAR struct mrf24j40_radio_s *dev, + FAR const uint8_t *saddr); +static int mrf24j40_setcoordeaddr(FAR struct mrf24j40_radio_s *dev, + FAR const uint8_t *eaddr); static int mrf24j40_setdevmode(FAR struct mrf24j40_radio_s *dev, uint8_t mode); static int mrf24j40_settxpower(FAR struct mrf24j40_radio_s *dev, @@ -242,11 +266,24 @@ static int mrf24j40_set_attr(FAR struct ieee802154_radio_s *radio, static int mrf24j40_rxenable(FAR struct ieee802154_radio_s *dev, bool enable); static int mrf24j40_req_rxenable(FAR struct ieee802154_radio_s *radio, FAR struct ieee802154_rxenable_req_s *req); +static int mrf24j40_beaconstart(FAR struct ieee802154_radio_s *radio, + FAR const struct ieee802154_superframespec_s *sfspec, + FAR struct ieee802154_beaconframe_s *beacon); +static int mrf24j40_beaconupdate(FAR struct ieee802154_radio_s *radio, + FAR struct ieee802154_beaconframe_s *beacon); +static int mrf24j40_beaconstop(FAR struct ieee802154_radio_s *radio); +static int mrf24j40_sfupdate(FAR struct ieee802154_radio_s *radio, + FAR const struct ieee802154_superframespec_s *sfspec); /**************************************************************************** * Private Data ****************************************************************************/ +static const uint8_t g_allones[8] = +{ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + /**************************************************************************** * Radio Interface Functions ****************************************************************************/ @@ -418,7 +455,7 @@ static int mrf24j40_get_attr(FAR struct ieee802154_radio_s *radio, switch (attr) { - case IEEE802154_ATTR_MAC_EXTENDED_ADDR: + case IEEE802154_ATTR_MAC_EADDR: { memcpy(&attrval->mac.eaddr[0], &dev->addr.eaddr[0], 8); ret = IEEE802154_STATUS_SUCCESS; @@ -438,6 +475,12 @@ static int mrf24j40_get_attr(FAR struct ieee802154_radio_s *radio, ret = IEEE802154_STATUS_SUCCESS; } break; + + case IEEE802154_ATTR_PHY_CHAN: + { + attrval->phy.chan = dev->chan; + ret = IEEE802154_STATUS_SUCCESS; + } default: ret = IEEE802154_STATUS_UNSUPPORTED_ATTRIBUTE; @@ -462,16 +505,30 @@ static int mrf24j40_set_attr(FAR struct ieee802154_radio_s *radio, } break; - case IEEE802154_ATTR_MAC_SHORT_ADDRESS: + case IEEE802154_ATTR_MAC_SADDR: { mrf24j40_setsaddr(dev, attrval->mac.saddr); ret = IEEE802154_STATUS_SUCCESS; } break; - case IEEE802154_ATTR_MAC_EXTENDED_ADDR: + case IEEE802154_ATTR_MAC_EADDR: { - mrf24j40_seteaddr(dev, &attrval->mac.eaddr[0]); + mrf24j40_seteaddr(dev, attrval->mac.eaddr); + ret = IEEE802154_STATUS_SUCCESS; + } + break; + + case IEEE802154_ATTR_MAC_COORD_SADDR: + { + mrf24j40_setcoordsaddr(dev, attrval->mac.coordsaddr); + ret = IEEE802154_STATUS_SUCCESS; + } + break; + + case IEEE802154_ATTR_MAC_COORD_EADDR: + { + mrf24j40_setcoordeaddr(dev, attrval->mac.coordeaddr); ret = IEEE802154_STATUS_SUCCESS; } break; @@ -498,6 +555,13 @@ static int mrf24j40_set_attr(FAR struct ieee802154_radio_s *radio, ret = IEEE802154_STATUS_SUCCESS; } break; + + case IEEE802154_ATTR_PHY_CHAN: + { + mrf24j40_setchannel(dev, attrval->phy.chan); + ret = IEEE802154_STATUS_SUCCESS; + } + break; default: ret = IEEE802154_STATUS_UNSUPPORTED_ATTRIBUTE; @@ -513,6 +577,185 @@ static int mrf24j40_req_rxenable(FAR struct ieee802154_radio_s *radio, return -ENOTTY; } +static int mrf24j40_beaconstart(FAR struct ieee802154_radio_s *radio, + FAR const struct ieee802154_superframespec_s *sfspec, + FAR struct ieee802154_beaconframe_s *beacon) +{ + FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)radio; + uint32_t maincnt = 0; + uint32_t slpcal = 0; + int reg; + + if (sfspec->pancoord) + { + /* Set the PANCOORD (RXMCR 0x00<3>) bit = 1to configure as PAN coordinator */ + + reg = mrf24j40_getreg(dev->spi, MRF24J40_RXMCR); + reg |= MRF24J40_RXMCR_PANCOORD; + mrf24j40_setreg(dev->spi, MRF24J40_RXMCR, reg); + + /* Set the SLOTTED (TXMCR 0x11<5>) bit = 1 to use Slotted CSMA-CA mode */ + + reg = mrf24j40_getreg(dev->spi, MRF24J40_TXMCR); + reg |= MRF24J40_TXMCR_SLOTTED; + mrf24j40_setreg(dev->spi, MRF24J40_TXMCR, reg); + + /* Load the beacon frame into the TXBFIFO (0x080-0x0FF). */ + + mrf24j40_setup_fifo(dev, beacon->bf_data, beacon->bf_len, MRF24J40_BEACON_FIFO); + + /* Set the TXBMSK (TXBCON1 0x25<7>) bit = 1 to mask the beacon interrupt + * mask + */ + + reg = mrf24j40_getreg(dev->spi, MRF24J40_TXBCON1); + reg |= MRF24J40_TXBCON1_TXBMSK; + mrf24j40_setreg(dev->spi, MRF24J40_TXBCON1, reg); + + /* Set INTL (WAKECON 0x22<5:0>) value to 0x03. */ + + reg = mrf24j40_getreg(dev->spi, MRF24J40_WAKECON); + reg &= ~MRF24J40_WAKECON_INTL; + reg |= 0x03 & MRF24J40_WAKECON_INTL; + mrf24j40_setreg(dev->spi, MRF24J40_WAKECON, reg); + + /* Program the CAP end slot (ESLOTG1 0x13<3:0>) value. */ + + reg = mrf24j40_getreg(dev->spi, MRF24J40_ESLOTG1); + reg &= ~MRF24J40_ESLOTG1_CAP; + reg |= sfspec->final_capslot & MRF24J40_ESLOTG1_CAP; + mrf24j40_setreg(dev->spi, MRF24J40_ESLOTG1, reg); + + /* TODO: Add GTS related code. See pg 100 of datasheet */ + + /* Calibrate the Sleep Clock (SLPCLK) frequency. Refer to Section 3.15.1.2 + * “Sleep Clock Calibration”. + */ + + /* If the Sleep Clock Selection, SLPCLKSEL (0x207<7:6), is the internal + * oscillator (100 kHz), set SLPCLKDIV to a minimum value of 0x01. + */ + + mrf24j40_setreg(dev->spi, MRF24J40_SLPCON1, 0x01); + + /* Select the source of SLPCLK (internal 100kHz) */ + + mrf24j40_setreg(dev->spi, MRF24J40_RFCON7, MRF24J40_RFCON7_SEL_100KHZ); + + /* Begin calibration by setting the SLPCALEN bit (SLPCAL2 0x20B<4>) to + * ‘1’. Sixteen samples of the SLPCLK are counted and stored in the + * SLPCAL register. No need to mask, this is the only writable bit + */ + + mrf24j40_setreg(dev->spi, MRF24J40_SLPCAL2, MRF24J40_SLPCAL2_SLPCALEN); + + /* Calibration is complete when the SLPCALRDY bit (SLPCAL2 0x20B<7>) is + * set to ‘1’. + */ + + while (!(mrf24j40_getreg(dev->spi, MRF24J40_SLPCAL2) & + MRF24J40_SLPCAL2_SLPCALRDY)) + { + usleep(1); + } + + slpcal = mrf24j40_getreg(dev->spi, MRF24J40_SLPCAL0); + slpcal |= (mrf24j40_getreg(dev->spi, MRF24J40_SLPCAL1) << 8); + slpcal |= ((mrf24j40_getreg(dev->spi, MRF24J40_SLPCAL2) << 16) & 0x0F); + + /* Set WAKECNT (SLPACK 0x35<6:0>) value = 0x5F to set the main oscillator + * (20 MHz) start-up timer value. + */ + + mrf24j40_setreg(dev->spi, MRF24J40_SLPACK, 0x5F); + + /* Program the Beacon Interval into the Main Counter, MAINCNT (0x229<1:0>, + * 0x228, 0x227, 0x226), and Remain Counter, REMCNT (0x225, 0x224), + * according to BO and SO values. Refer to Section 3.15.1.3 “Sleep Mode + * Counters” + */ + + mrf24j40_setreg(dev->spi, MRF24J40_REMCNTL, (MRF24J40_REMCNT & 0xFF)); + mrf24j40_setreg(dev->spi, MRF24J40_REMCNTH, ((MRF24J40_REMCNT >> 8) & 0xFF)); + + maincnt = MRF24J40_MAINCNT(sfspec->beaconorder, (slpcal * 50 / 16)); + + mrf24j40_setreg(dev->spi, MRF24J40_MAINCNT0, (maincnt & 0xFF)); + mrf24j40_setreg(dev->spi, MRF24J40_MAINCNT1, ((maincnt >> 8) & 0xFF)); + mrf24j40_setreg(dev->spi, MRF24J40_MAINCNT2, ((maincnt >> 16) & 0xFF)); + mrf24j40_setreg(dev->spi, MRF24J40_MAINCNT3, ((maincnt >> 24) & 0x03)); + + /* Enable the SLPIF and WAKEIF flags */ + + reg = mrf24j40_getreg(dev->spi, MRF24J40_INTCON); + reg &= ~(MRF24J40_INTCON_SLPIE | MRF24J40_INTCON_WAKEIE); + mrf24j40_setreg(dev->spi, MRF24J40_INTCON, reg); + + /* Configure the BO (ORDER 0x10<7:4>) and SO (ORDER 0x10<3:0>) values. + * After configuring BO and SO, the beacon frame will be sent immediately. + */ + + mrf24j40_setreg(dev->spi, MRF24J40_ORDER, + ((sfspec->beaconorder << 4) & 0xF0) | (sfspec->sforder & 0x0F)); + } + else + { + return -ENOTTY; + } + + return OK; +} + +static int mrf24j40_beaconupdate(FAR struct ieee802154_radio_s *radio, + FAR struct ieee802154_beaconframe_s *beacon) +{ + FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)radio; + + mrf24j40_setup_fifo(dev, beacon->bf_data, beacon->bf_len, MRF24J40_BEACON_FIFO); + + return OK; +} + +static int mrf24j40_beaconstop(FAR struct ieee802154_radio_s *radio) +{ + return -ENOTTY; +} + +static int mrf24j40_sfupdate(FAR struct ieee802154_radio_s *radio, + FAR const struct ieee802154_superframespec_s *sfspec) +{ + FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)radio; + int reg; + + reg = mrf24j40_getreg(dev->spi, MRF24J40_RXMCR); + + if (sfspec->pancoord) + { + reg |= MRF24J40_RXMCR_PANCOORD; + } + else + { + reg &= ~MRF24J40_RXMCR_PANCOORD; + } + mrf24j40_setreg(dev->spi, MRF24J40_RXMCR, reg); + + /* Program the CAP end slot (ESLOTG1 0x13<3:0>) value. */ + + reg = mrf24j40_getreg(dev->spi, MRF24J40_ESLOTG1); + reg &= ~MRF24J40_ESLOTG1_CAP; + reg |= sfspec->final_capslot & MRF24J40_ESLOTG1_CAP; + mrf24j40_setreg(dev->spi, MRF24J40_ESLOTG1, reg); + + /* Configure the BO (ORDER 0x10<7:4>) and SO (ORDER 0x10<3:0>) values. + * After configuring BO and SO, the beacon frame will be sent immediately. + */ + + mrf24j40_setreg(dev->spi, MRF24J40_ORDER, + ((sfspec->beaconorder << 4) & 0xF0) | (sfspec->sforder & 0x0F)); + + return OK; +} + /**************************************************************************** * Internal Functions ****************************************************************************/ @@ -726,7 +969,7 @@ static void mrf24j40_setreg(FAR struct spi_dev_s *spi, uint32_t addr, * Name: mrf24j40_getreg * * Description: - * Return the value of an MRF24J40 device register + * Return the value of an MRF24J40 device register* * ****************************************************************************/ @@ -944,8 +1187,8 @@ static int mrf24j40_setchannel(FAR struct mrf24j40_radio_s *dev, uint8_t chan) mrf24j40_resetrfsm(dev); - dev->channel = chan; - //wlinfo("%u\n", (unsigned)chan); + dev->chan = chan; + wlinfo("%u\n", (unsigned)chan); return OK; } @@ -1015,6 +1258,51 @@ static int mrf24j40_seteaddr(FAR struct mrf24j40_radio_s *dev, return OK; } +/**************************************************************************** + * Name: mrf24j40_setcoordsaddr + * + * Description: + * Define the coordinator short address. The following addresses are special: + * FFFEh : Broadcast + * FFFFh : Unspecified + * + ****************************************************************************/ + +static int mrf24j40_setcoordsaddr(FAR struct mrf24j40_radio_s *dev, + FAR const uint8_t *saddr) +{ + mrf24j40_setreg(dev->spi, MRF24J40_ASSOSADR0, saddr[0]); + mrf24j40_setreg(dev->spi, MRF24J40_ASSOSADR1, saddr[1]); + + IEEE802154_SADDRCOPY(dev->addr.saddr, saddr); + + wlinfo("%02X:%02X\n", saddr[1], saddr[0]); + return OK; +} + +/**************************************************************************** + * Name: mrf24j40_setcoordeaddr + * + * Description: + * Define the coordinator extended address. The following addresses are special: + * FFFFFFFFFFFFFFFFh : Unspecified + * + ****************************************************************************/ + +static int mrf24j40_setcoordeaddr(FAR struct mrf24j40_radio_s *dev, + FAR const uint8_t *eaddr) +{ + int i; + + for (i = 0; i < 8; i++) + { + mrf24j40_setreg(dev->spi, MRF24J40_ASSOEADR0 + i, eaddr[i]); + dev->addr.eaddr[i] = eaddr[i]; + } + + return OK; +} + /**************************************************************************** * Name: mrf24j40_setdevmode * @@ -1298,11 +1586,10 @@ static int mrf24j40_energydetect(FAR struct mrf24j40_radio_s *dev, * ****************************************************************************/ -static int mrf24j40_norm_setup(FAR struct mrf24j40_radio_s *dev, - FAR struct iob_s *frame, bool csma) +static void mrf24j40_norm_setup(FAR struct mrf24j40_radio_s *dev, + FAR struct iob_s *frame, bool csma) { uint8_t reg; - int ret; /* Enable tx int */ @@ -1327,7 +1614,7 @@ static int mrf24j40_norm_setup(FAR struct mrf24j40_radio_s *dev, /* Setup the FIFO */ - ret = mrf24j40_setup_fifo(dev, frame, MRF24J40_TXNORM_FIFO); + mrf24j40_setup_fifo(dev, frame->io_data, frame->io_len, MRF24J40_TXNORM_FIFO); /* If the frame control field contains an acknowledgment request, set the * TXNACKREQ bit. See IEEE 802.15.4/2003 7.2.1.1 page 112 for info. @@ -1345,8 +1632,6 @@ static int mrf24j40_norm_setup(FAR struct mrf24j40_radio_s *dev, } mrf24j40_setreg(dev->spi, MRF24J40_TXNCON, reg); - - return ret; } /**************************************************************************** @@ -1376,10 +1661,10 @@ static inline void mrf24j40_norm_trigger(FAR struct mrf24j40_radio_s *dev) * ****************************************************************************/ -static int mrf24j40_gts_setup(FAR struct mrf24j40_radio_s *dev, uint8_t fifo, - FAR struct iob_s *frame) +static void mrf24j40_gts_setup(FAR struct mrf24j40_radio_s *dev, uint8_t fifo, + FAR struct iob_s *frame) { - return -ENOTTY; + } /**************************************************************************** @@ -1389,17 +1674,18 @@ static int mrf24j40_gts_setup(FAR struct mrf24j40_radio_s *dev, uint8_t fifo, * ****************************************************************************/ -static int mrf24j40_setup_fifo(FAR struct mrf24j40_radio_s *dev, - FAR struct iob_s *frame, uint32_t fifo_addr) +static void mrf24j40_setup_fifo(FAR struct mrf24j40_radio_s *dev, + FAR const uint8_t *buf, uint8_t length, + uint32_t fifo_addr) { - int ret; - int hlen = 3; /* Include frame control and seq number */ + int hlen = 3; /* Include frame control and seq number */ + int i; uint16_t frame_ctrl; /* Analyze frame control to compute header length */ - frame_ctrl = frame->io_data[0]; - frame_ctrl |= (frame->io_data[1] << 8); + frame_ctrl = buf[0]; + frame_ctrl |= (buf[1] << 8); if ((frame_ctrl & IEEE802154_FRAMECTRL_DADDR)== IEEE802154_ADDRMODE_SHORT) { @@ -1430,16 +1716,14 @@ static int mrf24j40_setup_fifo(FAR struct mrf24j40_radio_s *dev, /* Frame length */ - mrf24j40_setreg(dev->spi, fifo_addr++, frame->io_len); + mrf24j40_setreg(dev->spi, fifo_addr++, length); /* Frame data */ - for (ret = 0; ret < frame->io_len; ret++) /* this sets the correct val for ret */ + for (i = 0; i < length; i++) { - mrf24j40_setreg(dev->spi, fifo_addr++, frame->io_data[ret]); + mrf24j40_setreg(dev->spi, fifo_addr++, buf[i]); } - - return ret; } /**************************************************************************** @@ -1594,13 +1878,30 @@ static int mrf24j40_rxenable(FAR struct ieee802154_radio_s *radio, bool enable) FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)radio; uint8_t reg; + dev->rxenabled = enable; + + if (enable) { + /* Disable packet reception. See pg. 109 of datasheet */ + + mrf24j40_setreg(dev->spi, MRF24J40_BBREG1, MRF24J40_BBREG1_RXDECINV); + /* Enable rx int */ reg = mrf24j40_getreg(dev->spi, MRF24J40_INTCON); reg &= ~MRF24J40_INTCON_RXIE; mrf24j40_setreg(dev->spi, MRF24J40_INTCON, reg); + + /* Purge the RX buffer */ + + reg = mrf24j40_getreg(dev->spi, MRF24J40_RXFLUSH); + reg |= MRF24J40_RXFLUSH_RXFLUSH; + mrf24j40_setreg(dev->spi, MRF24J40_RXFLUSH, reg); + + /* Re-enable packet reception. See pg. 109 of datasheet */ + + mrf24j40_setreg(dev->spi, MRF24J40_BBREG1, 0); } else { @@ -1684,14 +1985,14 @@ done: mrf24j40_setreg(dev->spi, MRF24J40_RXFLUSH, 1); - /* Enable packet reception */ - - mrf24j40_setreg(dev->spi, MRF24J40_BBREG1, 0); - /* Only enable RX interrupt if we are to be listening when IDLE */ - if (dev->rxonidle) + if (dev->rxenabled) { + /* Enable packet reception */ + + mrf24j40_setreg(dev->spi, MRF24J40_BBREG1, 0); + reg = mrf24j40_getreg(dev->spi, MRF24J40_INTCON); reg &= ~MRF24J40_INTCON_RXIE; mrf24j40_setreg(dev->spi, MRF24J40_INTCON, reg); @@ -1718,7 +2019,8 @@ done: static void mrf24j40_irqworker(FAR void *arg) { FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)arg; - uint8_t intstat, intcon; + uint8_t intstat; + uint8_t reg; DEBUGASSERT(dev); DEBUGASSERT(dev->spi); @@ -1730,7 +2032,6 @@ static void mrf24j40_irqworker(FAR void *arg) /* Read and store INTSTAT - this clears the register. */ intstat = mrf24j40_getreg(dev->spi, MRF24J40_INTSTAT); - wlinfo("INT%02X\n", intstat); /* Do work according to the pending interrupts */ @@ -1744,12 +2045,12 @@ static void mrf24j40_irqworker(FAR void *arg) /* Timers are one-shot, so disable the interrupt */ - intcon = mrf24j40_getreg(dev->spi, MRF24J40_INTCON); - intcon |= MRF24J40_INTCON_HSYMTMRIE; - mrf24j40_setreg(dev->spi, MRF24J40_INTCON, intcon); + reg = mrf24j40_getreg(dev->spi, MRF24J40_INTCON); + reg |= MRF24J40_INTCON_HSYMTMRIE; + mrf24j40_setreg(dev->spi, MRF24J40_INTCON, reg); } - if ((intstat & MRF24J40_INTSTAT_RXIF)) + if ((intstat & MRF24J40_INTSTAT_RXIF) && dev->rxenabled) { /* A packet was received, retrieve it */ @@ -1777,6 +2078,17 @@ static void mrf24j40_irqworker(FAR void *arg) mrf24j40_irqwork_txgts(dev, 1); } + if ((intstat & MRF24J40_INTSTAT_SLPIF)) + { + dev->radiocb->sfevent(dev->radiocb, IEEE802154_SFEVENT_ENDOFACTIVE); + + /* Acknowledge the alert and put the device to sleep */ + + reg = mrf24j40_getreg(dev->spi, MRF24J40_SLPACK); + reg |= MRF24J40_SLPACK_SLPACK; + mrf24j40_setreg(dev->spi, MRF24J40_SLPACK, reg); + } + /* Unlock the radio device */ sem_post(&dev->exclsem); @@ -1873,22 +2185,28 @@ FAR struct ieee802154_radio_s *mrf24j40_init(FAR struct spi_dev_s *spi, dev->radio.set_attr = mrf24j40_set_attr; dev->radio.rxenable = mrf24j40_rxenable; dev->radio.req_rxenable = mrf24j40_req_rxenable; + dev->radio.beaconstart = mrf24j40_beaconstart; + dev->radio.beaconupdate = mrf24j40_beaconupdate; + dev->radio.beaconstop = mrf24j40_beaconstop; + dev->radio.sfupdate = mrf24j40_sfupdate; dev->lower = lower; dev->spi = spi; + + dev->rxenabled = false; mrf24j40_initialize(dev); mrf24j40_setchannel(dev, 11); - mrf24j40_setpanid (dev, 0xFFFF); - mrf24j40_setsaddr (dev, 0xFFFF); - mrf24j40_seteaddr (dev, (uint8_t*)"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"); + mrf24j40_setpanid(dev, g_allones); + mrf24j40_setsaddr(dev, g_allones); + mrf24j40_seteaddr(dev, g_allones); /* Default device params */ cca.use_ed = 1; cca.use_cs = 0; - cca.edth = 0x60; /* CCA mode ED, no carrier sense, recommenced ED threshold -69 dBm */ + cca.edth = 0x60; /* CCA mode ED, no carrier sense, recommenced ED threshold -69 dBm */ mrf24j40_setcca(dev, &cca); mrf24j40_setrxmode(dev, MRF24J40_RXMODE_NORMAL); diff --git a/drivers/wireless/ieee802154/mrf24j40.h b/drivers/wireless/ieee802154/mrf24j40.h index 397b9f4e39..e4e4e8ba5e 100644 --- a/drivers/wireless/ieee802154/mrf24j40.h +++ b/drivers/wireless/ieee802154/mrf24j40.h @@ -118,41 +118,41 @@ #define MRF24J40_SLPCAL1 (MRF24J40_LONGREG_BASE + 0x0A) #define MRF24J40_SLPCAL2 (MRF24J40_LONGREG_BASE + 0x0B) #define MRF24J40_RFSTATE (MRF24J40_LONGREG_BASE + 0x0F) -#define MRF24J40_RSSI 0x80000210 -#define MRF24J40_SLPCON0 0x80000211 -#define MRF24J40_SLPCON1 0x80000220 -#define MRF24J40_WAKETIMEL 0x80000222 -#define MRF24J40_WAKETIMEH 0x80000223 -#define MRF24J40_REMCNTL 0x80000224 -#define MRF24J40_REMCNTH 0x80000225 -#define MRF24J40_MAINCNT0 0x80000226 -#define MRF24J40_MAINCNT1 0x80000227 -#define MRF24J40_MAINCNT2 0x80000228 -#define MRF24J40_MAINCNT3 0x80000229 -#define MRF24J40_TESTMODE 0x8000022F -#define MRF24J40_ASSOEADR0 0x80000230 -#define MRF24J40_ASSOEADR1 0x80000231 -#define MRF24J40_ASSOEADR2 0x80000232 -#define MRF24J40_ASSOEADR3 0x80000233 -#define MRF24J40_ASSOEADR4 0x80000234 -#define MRF24J40_ASSOEADR5 0x80000235 -#define MRF24J40_ASSOEADR6 0x80000236 -#define MRF24J40_ASSOEADR7 0x80000237 -#define MRF24J40_ASSOSADR0 0x80000238 -#define MRF24J40_ASSOSADR1 0x80000239 -#define MRF24J40_UPNONCE0 0x80000240 -#define MRF24J40_UPNONCE1 0x80000241 -#define MRF24J40_UPNONCE2 0x80000242 -#define MRF24J40_UPNONCE3 0x80000243 -#define MRF24J40_UPNONCE4 0x80000244 -#define MRF24J40_UPNONCE5 0x80000245 -#define MRF24J40_UPNONCE6 0x80000246 -#define MRF24J40_UPNONCE7 0x80000247 -#define MRF24J40_UPNONCE8 0x80000248 -#define MRF24J40_UPNONCE9 0x80000249 -#define MRF24J40_UPNONCE10 0x8000024A -#define MRF24J40_UPNONCE11 0x8000024B -#define MRF24J40_UPNONCE12 0x8000024C +#define MRF24J40_RSSI (MRF24J40_LONGREG_BASE + 0x10) +#define MRF24J40_SLPCON0 (MRF24J40_LONGREG_BASE + 0x11) +#define MRF24J40_SLPCON1 (MRF24J40_LONGREG_BASE + 0x20) +#define MRF24J40_WAKETIMEL (MRF24J40_LONGREG_BASE + 0x22) +#define MRF24J40_WAKETIMEH (MRF24J40_LONGREG_BASE + 0x23) +#define MRF24J40_REMCNTL (MRF24J40_LONGREG_BASE + 0x24) +#define MRF24J40_REMCNTH (MRF24J40_LONGREG_BASE + 0x25) +#define MRF24J40_MAINCNT0 (MRF24J40_LONGREG_BASE + 0x26) +#define MRF24J40_MAINCNT1 (MRF24J40_LONGREG_BASE + 0x27) +#define MRF24J40_MAINCNT2 (MRF24J40_LONGREG_BASE + 0x28) +#define MRF24J40_MAINCNT3 (MRF24J40_LONGREG_BASE + 0x29) +#define MRF24J40_TESTMODE (MRF24J40_LONGREG_BASE + 0x2F) +#define MRF24J40_ASSOEADR0 (MRF24J40_LONGREG_BASE + 0x30) +#define MRF24J40_ASSOEADR1 (MRF24J40_LONGREG_BASE + 0x31) +#define MRF24J40_ASSOEADR2 (MRF24J40_LONGREG_BASE + 0x32) +#define MRF24J40_ASSOEADR3 (MRF24J40_LONGREG_BASE + 0x33) +#define MRF24J40_ASSOEADR4 (MRF24J40_LONGREG_BASE + 0x34) +#define MRF24J40_ASSOEADR5 (MRF24J40_LONGREG_BASE + 0x35) +#define MRF24J40_ASSOEADR6 (MRF24J40_LONGREG_BASE + 0x36) +#define MRF24J40_ASSOEADR7 (MRF24J40_LONGREG_BASE + 0x37) +#define MRF24J40_ASSOSADR0 (MRF24J40_LONGREG_BASE + 0x38) +#define MRF24J40_ASSOSADR1 (MRF24J40_LONGREG_BASE + 0x39) +#define MRF24J40_UPNONCE0 (MRF24J40_LONGREG_BASE + 0x40) +#define MRF24J40_UPNONCE1 (MRF24J40_LONGREG_BASE + 0x41) +#define MRF24J40_UPNONCE2 (MRF24J40_LONGREG_BASE + 0x42) +#define MRF24J40_UPNONCE3 (MRF24J40_LONGREG_BASE + 0x43) +#define MRF24J40_UPNONCE4 (MRF24J40_LONGREG_BASE + 0x44) +#define MRF24J40_UPNONCE5 (MRF24J40_LONGREG_BASE + 0x45) +#define MRF24J40_UPNONCE6 (MRF24J40_LONGREG_BASE + 0x46) +#define MRF24J40_UPNONCE7 (MRF24J40_LONGREG_BASE + 0x47) +#define MRF24J40_UPNONCE8 (MRF24J40_LONGREG_BASE + 0x48) +#define MRF24J40_UPNONCE9 (MRF24J40_LONGREG_BASE + 0x49) +#define MRF24J40_UPNONCE10 (MRF24J40_LONGREG_BASE + 0x4A) +#define MRF24J40_UPNONCE11 (MRF24J40_LONGREG_BASE + 0x4B) +#define MRF24J40_UPNONCE12 (MRF24J40_LONGREG_BASE + 0x4C) /* INTSTAT bits */ @@ -226,4 +226,59 @@ #define MRF24J40_TXSTAT_X_SHIFT 6 #define MRF24J40_TXSTAT_X_MASK (3 << MRF24J40_TXSTAT_X_SHIFT) +/* TXBCON1 bits */ + +#define MRF24J40_TXBCON1_RSSINUM 0x30 +#define MRF24J40_TXBCON1_NWU_BCN 0x40 +#define MRF24J40_TXBCON1_TXBMSK 0x80 + +/* WAKECON bits */ + +#define MRF24J40_WAKECON_INTL 0x3F +#define MRF24J40_WAKECON_REGWAKE 0x40 +#define MRF24J40_WAKECON_IMMWAKE 0x80 + +/* WAKECON bits */ + +#define MRF24J40_WAKECON_INTL 0x3F +#define MRF24J40_WAKECON_REGWAKE 0x40 +#define MRF24J40_WAKECON_IMMWAKE 0x80 + +/* ESLOTG1 bits */ + +#define MRF24J40_ESLOTG1_CAP 0x0F +#define MRF24J40_ESLOTG1_GTS1 0xF0 + +/* SLPCAL2 bits */ + +#define MRF24J40_SLPCAL2_SLPCAL 0x0F +#define MRF24J40_SLPCAL2_SLPCALEN 0x10 +#define MRF24J40_SLPCAL2_SLPCALRDY 0x80 + +/* RFCON7 bits */ + +#define MRF24J40_RFCON7_SEL_32KHZ 0x40 +#define MRF24J40_RFCON7_SEL_100KHZ 0x80 + +/* SLPACK bits */ + +#define MRF24J40_SLPACK_WAKECNT0_6 0x7F +#define MRF24J40_SLPACK_SLPACK 0x80 + +/* RXFLUSH bits */ + +#define MRF24J40_RXFLUSH_RXFLUSH 0x01 +#define MRF24J40_RXFLUSH_BCNONLY 0x02 +#define MRF24J40_RXFLUSH_DATAONLY 0x04 +#define MRF24J40_RXFLUSH_CMDONLY 0x08 +#define MRF24J40_RXFLUSH_WAKEPAD 0x20 +#define MRF24J40_RXFLUSH_WAKEPOL 0x40 + +#define MRF24J40_RXFLUSH_SHIFT_RXFLUSH 0 +#define MRF24J40_RXFLUSH_SHIFT_BCNONLY 1 +#define MRF24J40_RXFLUSH_SHIFT_DATAONLY 2 +#define MRF24J40_RXFLUSH_SHIFT_CMDONLY 3 +#define MRF24J40_RXFLUSH_SHIFT_WAKEPAD 5 +#define MRF24J40_RXFLUSH_SHIFT_WAKEPOL 6 + #endif /* __DRIVERS_WIRELESS_IEEE802154_MRF24J40_H */ diff --git a/include/nuttx/net/ieee802154.h b/include/nuttx/net/ieee802154.h index 736141a351..eba830024d 100644 --- a/include/nuttx/net/ieee802154.h +++ b/include/nuttx/net/ieee802154.h @@ -78,6 +78,10 @@ #define SIXLOWPAN_MAC_STDFRAME 127 +/* Space for a two byte FCS must be reserved at the end of the frame */ + +#define SIXLOWPAN_MAC_FCSSIZE 2 + /**************************************************************************** * Public Types ****************************************************************************/ diff --git a/include/nuttx/net/ip.h b/include/nuttx/net/ip.h index 84df352074..9950ea1744 100644 --- a/include/nuttx/net/ip.h +++ b/include/nuttx/net/ip.h @@ -553,7 +553,7 @@ bool net_ipv6addr_maskcmp(const net_ipv6addr_t addr1, * Name: net_is_addr_unspecified * * Description: - * Is Ithe Pv6 address the unspecified address? + * Is Ithe IPv6 address the unspecified address? * ****************************************************************************/ diff --git a/include/nuttx/net/netdev.h b/include/nuttx/net/netdev.h index 18ea237945..7c34217ae9 100644 --- a/include/nuttx/net/netdev.h +++ b/include/nuttx/net/netdev.h @@ -3,7 +3,7 @@ * Defines architecture-specific device driver interfaces to the NuttX * network. * - * Copyright (C) 2007, 2009, 2011-2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2011-2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Derived largely from portions of uIP with has a similar BSD-styple license: diff --git a/include/nuttx/net/sixlowpan.h b/include/nuttx/net/sixlowpan.h index 986472c962..a1f6b23ed1 100644 --- a/include/nuttx/net/sixlowpan.h +++ b/include/nuttx/net/sixlowpan.h @@ -126,15 +126,39 @@ #define SIXLOWPAN_DISPATCH_FRAGN 0xe0 /* 11100xxx Fragmentation header (subsequent) */ #define SIXLOWPAN_DISPATCH_FRAG_MASK 0xf8 /* 11111000 */ -/* HC1 encoding */ +/* HC1 encoding (RFC4944) + * + * PI: Prefix carried in-line + * PC: Prefix compressed (link-local prefix assumed) + * II: Interface identifier carried in-line + * IC: Interface identifier elided (derivable from the corresponding + * link-layer address). + */ -#define SIXLOWPAN_HC1_NH_UDP 0x02 -#define SIXLOWPAN_HC1_NH_TCP 0x06 -#define SIXLOWPAN_HC1_NH_ICMP6 0x04 +#define SIXLOWPAN_HC1_SRCADDR_MASK 0xc0 /* Bits 0-1: IPv6 source address */ +# define SIXLOWPAN_HC1_SRCADDR_PIII 0x00 /* PI,II */ +# define SIXLOWPAN_HC1_SRCADDR_PIIC 0x40 /* PI,IC */ +# define SIXLOWPAN_HC1_SRCADDR_PCII 0x80 /* PC,II */ +# define SIXLOWPAN_HC1_SRCADDR_PCIC 0xc0 /* PC,IC */ +#define SIXLOWPAN_HC1_DESTADDR_MASK 0x30 /* Bits 2-3: IPv6 destination address */ +# define SIXLOWPAN_HC1_DESTADDR_PIII 0x00 /* PI,II */ +# define SIXLOWPAN_HC1_DESTADDR_PIIC 0x10 /* PI,IC */ +# define SIXLOWPAN_HC1_DESTADDR_PCII 0x20 /* PC,II */ +# define SIXLOWPAN_HC1_DESTADDR_PCIC 0x30 /* PC,IC */ +#define SIXLOWPAN_HC1_TCFL_C 0x08 /* Bit 4: Traffic class and flow label are zero */ +#define SIXLOWPAN_HC1_NH_MASK 0x06 /* Bits 5-6: Next HC1 header type */ +# define SIXLOWPAN_HC1_NH_NC 0x00 /* Not compressed */ +# define SIXLOWPAN_HC1_NH_UDP 0x02 /* UDP */ +# define SIXLOWPAN_HC1_NH_ICMPv6 0x04 /* ICMPv6 */ +# define SIXLOWPAN_HC1_NH_TCP 0x06 /* TCP */ +#define SIXLOWPAN_HC1_H2ENCODE 0x01 /* Bit 0: HC2 encoding follows */ /* HC_UDP encoding (works together with HC1) */ -#define SIXLOWPAN_HC_UDP_ALL_C 0xe0 +#define SIXLOWPAN_HC_UDP_SRCPORT_C 0x80 /* Source port compressed to 4 bits */ +#define SIXLOWPAN_HC_UDP_DESTPORT_C 0x40 /* Destination port compressed to 4 bits */ +#define SIXLOWPAN_HC_UDP_LENGTH _C 0x20 /* Elided, compute from IPv6 length */ +#define SIXLOWPAN_HC_UDP_ALL_C 0xe0 /* All commpressed */ /* IPHC encoding * @@ -146,7 +170,7 @@ # define SIXLOWPAN_IPHC_TC_00 0x00 /* ECN+DSCP+4-bit Pad+Flow Label (4 bytes) */ # define SIXLOWPAN_IPHC_TC_01 0x08 /* ECN+2-bit Pad+ Flow Label (3 bytes), DSCP is elided. */ # define SIXLOWPAN_IPHC_TC_10 0x10 /* ECN+DSCP (1 byte), Flow Label is elided */ -# define SIXLOWPAN_IPHC_TC_11 0x11 /* Traffic Class and Flow Label are elided */ +# define SIXLOWPAN_IPHC_TC_11 0x18 /* Traffic Class and Flow Label are elided */ #define SIXLOWPAN_IPHC_NH 0x04 /* Bit 5: Next Header Compressed */ #define SIXLOWPAN_IPHC_HLIM_MASK 0x03 /* Bits 6-7: Hop Limit */ # define SIXLOWPAN_IPHC_HLIM_INLINE 0x00 /* Carried in-line */ diff --git a/include/nuttx/wireless/ieee802154/ieee802154_mac.h b/include/nuttx/wireless/ieee802154/ieee802154_mac.h index e128bdc1ab..b079a32902 100644 --- a/include/nuttx/wireless/ieee802154/ieee802154_mac.h +++ b/include/nuttx/wireless/ieee802154/ieee802154_mac.h @@ -60,6 +60,14 @@ /**************************************************************************** * Pre-Processor Definitions ****************************************************************************/ +/* Configuration ************************************************************/ + +#if !defined(CONFIG_MAC802154_NPANDESC) || CONFIG_MAC802154_NPANDESC <= 0 +# undef CONFIG_MAC802154_NPANDESC +# define CONFIG_MAC802154_NPANDESC 5 +#endif + +#define MAC802154_NPANDESC CONFIG_MAC802154_NPANDESC /* IEEE 802.15.4 address macros */ /* Copy a an IEEE 802.15.4 address */ @@ -97,8 +105,6 @@ #define IEEE802154_SADDR_BCAST ((uint8_t[]){0xFE,0xFF}) #define IEEE802154_EADDR_UNSPEC ((uint8_t[]){0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}) -/* Configuration ************************************************************/ -/* None at the moment */ /* IEEE 802.15.4 MAC Character Driver IOCTL Commands ************************/ @@ -111,9 +117,9 @@ * - Response * - Confirm * - * Of these, Request and Response primitives are sent from the next highest layer - * to the MLME. Indication and Confirm primitives are used to notify the next - * highest layer of changes or actions that have taken place. + * Of these, Request and Response primitives are sent from the next highest + * layer to the MLME. Indication and Confirm primitives are used to notify the + * next highest layer of changes or actions that have taken place. * * The MAC802154 character driver exposed here provides IOCTL hooks for all * Request and Response primitives. @@ -160,8 +166,53 @@ #define IEEE802154_FRAMECTRL_SHIFT_VERSION 12 /* Source addressing mode, bits 12-13 */ #define IEEE802154_FRAMECTRL_SHIFT_SADDR 14 /* Source addressing mode, bits 14-15 */ +/* Superframe Specification field masks, 2 bytes + * Seee IEEE 802.15.4/2011 5.2.2.1.2 page 62 + */ + +#define IEEE802154_SFSPEC_BEACONORDER 0x000F /* Beacon order, bits 0-3 */ +#define IEEE802154_SFSPEC_SFORDER 0x00F0 /* Superframe Order, bit 4-7 */ +#define IEEE802154_SFSPEC_FINCAPSLOT 0x0F00 /* Final CAP Slot, bit 8-11 */ +#define IEEE802154_SFSPEC_BLE 0x1000 /* Battery Life Ext, bit 12 */ +#define IEEE802154_SFSPEC_PANCOORD 0x4000 /* PAN Coordinator, bit 14 */ +#define IEEE802154_SFSPEC_ASSOCPERMIT 0x8000 /* Association Permit, bit 15 */ + +#define IEEE802154_SFSPEC_SHIFT_BEACONORDER 0 /* Beacon order, bits 0-3 */ +#define IEEE802154_SFSPEC_SHIFT_SFORDER 4 /* Superframe order, bit 4-7 */ +#define IEEE802154_SFSPEC_SHIFT_FINCAPSLOT 8 /* Final CAP Slot, bit 8-11 */ +#define IEEE802154_SFSPEC_SHIFT_BLE 12 /* Battery Life Ext, bit 12 */ +#define IEEE802154_SFSPEC_SHIFT_PANCOORD 14 /* PAN Coordinator, bit 14 */ +#define IEEE802154_SFSPEC_SHIFT_ASSOCPERMIT 15 /* Association Permit, bit 15 */ + +/* GTS Specification field masks, 1 byte + * Seee IEEE 802.15.4/2011 5.2.2.1.3 page 63 + */ + +#define IEEE802154_GTSSPEC_DESCCOUNT 0x07 /* GTS Desc. count, bits 0-2 */ +#define IEEE802154_GTSSPEC_PERMIT 0x80 /* GTS Desc. count, bit 7 */ + +#define IEEE802154_GTSSPEC_SHIFT_DESCCOUNT 0 /* GTS Desc. count, bits 0-2 */ +#define IEEE802154_GTSSPEC_SHIFT_PERMIT 7 /* GTS Desc. count, bit 7 */ + +/* GTS Directions field masks, 1 byte + * Seee IEEE 802.15.4/2011 5.2.2.1.3 page 63 + */ + +#define IEEE802154_GTSDIR_MASK 0x7F /* GTS Directions Mask, bits 0-6 */ + +#define IEEE802154_GTSDIR_SHIFT_MASK 0 /* GTS Directions Mask, bits 0-6 */ + +/* Pending address specifications field masks, 1 byte + * See IEEE 802.15.4/2011 5.2.2.1.6 page 64 + */ + +#define IEEE802154_PENDADDR_NSADDR 0x07 /* # of short addresses, bits 0-2 */ +#define IEEE802154_PENDADDR_NEADDR 0x70 /* # of extended addresses, bits 4-6 */ + +#define IEEE802154_PENDADDR_SHIFT_NSADDR 0 /* # of short addresses, bits 0-2 */ +#define IEEE802154_PENDADDR_SHIFT_NEADDR 4 /* # of extended addresses, bits 4-6 */ + /* Capability Information Bitfield - * */ #define IEEE802154_CAPABILITY_DEVTYPE 0x02 @@ -203,7 +254,6 @@ #define IEEE802154_MAX_MPDU_UNSEC_OVERHEAD \ (IEEE802154_MAX_UNSEC_MHR_OVERHEAD + IEEE802154_MFR_LENGTH) - #define IEEE802154_MAX_SAFE_MAC_PAYLOAD_SIZE \ (IEEE802154_MAX_PHY_PACKET_SIZE - IEEE802154_MAX_MPDU_UNSEC_OVERHEAD) @@ -220,7 +270,6 @@ #define MAX_ORPHAN_ADDR 32 /* REVISIT */ - /**************************************************************************** * Public Types ****************************************************************************/ @@ -232,7 +281,7 @@ enum ieee802154_status_e /* This first section of enums is defined in the standard. [1] pg. 70 * They must be in this order */ - + IEEE802154_STATUS_SUCCESS = 0, IEEE802154_STATUS_OUT_OF_CAPACITY, IEEE802154_STATUS_DENIED, @@ -265,6 +314,7 @@ enum ieee802154_status_e IEEE802154_STATUS_TX_ACTIVE, IEEE802154_STATUS_UNAVAILABLE_KEY, IEEE802154_STATUS_UNSUPPORTED_ATTRIBUTE, + IEEE802154_STATUS_LIMITREACHED, }; static const char *IEEE802154_STATUS_STRING[] = @@ -292,6 +342,7 @@ static const char *IEEE802154_STATUS_STRING[] = "Tx active", "Unavailable key", "Unsupported attribute", + "Limit reached", }; /* IEEE 802.15.4 PHY/MAC PIB attributes IDs */ @@ -300,7 +351,7 @@ enum ieee802154_attr_e { /* PHY PIB Attributes */ - IEEE802154_ATTR_PHY_CURRENT_CHANNEL = 0x00, + IEEE802154_ATTR_PHY_CHAN = 0x00, IEEE802154_ATTR_PHY_CHANNELS_SUPPORTED, IEEE802154_ATTR_PHY_TX_POWER_TOLERANCE, IEEE802154_ATTR_PHY_TX_POWER, @@ -340,7 +391,7 @@ enum ieee802154_attr_e /* MAC PIB Attributes */ - IEEE802154_ATTR_MAC_EXTENDED_ADDR = 0x40, + IEEE802154_ATTR_MAC_EADDR = 0x40, IEEE802154_ATTR_MAC_ACK_WAIT_DUR, IEEE802154_ATTR_MAC_ASSOCIATED_PANCOORD, IEEE802154_ATTR_MAC_ASSOCIATION_PERMIT, @@ -352,8 +403,8 @@ enum ieee802154_attr_e IEEE802154_ATTR_MAC_BEACON_ORDER, IEEE802154_ATTR_MAC_BEACON_TX_TIME, IEEE802154_ATTR_MAC_BSN, - IEEE802154_ATTR_MAC_COORD_EXT_ADDR, - IEEE802154_ATTR_MAC_COORD_SHORT_ADDR, + IEEE802154_ATTR_MAC_COORD_EADDR, + IEEE802154_ATTR_MAC_COORD_SADDR, IEEE802154_ATTR_MAC_DSN, IEEE802154_ATTR_MAC_GTS_PERMIT, IEEE802154_ATTR_MAC_MAX_BE, @@ -369,7 +420,7 @@ enum ieee802154_attr_e IEEE802154_ATTR_MAC_RESPONSE_WAIT_TIME, IEEE802154_ATTR_MAC_RX_ON_WHEN_IDLE, IEEE802154_ATTR_MAC_SECURITY_ENABLED, - IEEE802154_ATTR_MAC_SHORT_ADDRESS, + IEEE802154_ATTR_MAC_SADDR, IEEE802154_ATTR_MAC_SUPERFRAME_ORDER, IEEE802154_ATTR_MAC_SYNC_SYMBOL_OFFSET, IEEE802154_PIB_MAC_TIMESTAMP_SUPPORT, @@ -511,31 +562,31 @@ struct ieee802154_capability_info_s * 0=otherwise */ }; -struct ieee802154_superframe_spec_s +struct ieee802154_superframespec_s { - uint16_t beacon_order : 4; /* Transmission interval of beacon */ - uint16_t superframe_order : 4; /* Length of superframe */ - uint16_t final_cap_slot : 4; /* Last slot utilized by CAP */ - uint16_t ble : 1; /* Battery Life Extension (BLE) */ - uint16_t reserved : 1; /* Reserved bit */ - uint16_t pan_coordinator : 1; /* 1 if beacon sent by pan coordinator */ - uint16_t assoc_permit : 1; /* 1 if coordinator is accepting associaton */ + uint16_t beaconorder : 4; /* Transmission interval of beacon */ + uint16_t sforder : 4; /* Length of active portion of superframe */ + uint16_t final_capslot : 4; /* Last slot utilized by CAP */ + uint16_t ble : 1; /* Battery Life Extension (BLE) */ + uint16_t reserved : 1; /* Reserved bit */ + uint16_t pancoord : 1; /* 1 if beacon sent by pan coordinator */ + uint16_t assocpermit : 1; /* 1 if coordinator is accepting associaton */ }; -struct ieee802154_pan_desc_s +struct ieee802154_pandesc_s { /* The coordinator address of the received beacon frame */ - struct ieee802154_addr_s coord_addr; + struct ieee802154_addr_s coordaddr; - uint8_t channel; /* current channel occupied by the network */ - uint8_t channel_page; /* current channel page occupied by the network */ + uint8_t chan; /* current channel occupied by the network */ + uint8_t chpage; /* current channel page occupied by the network */ /* The superframe specifications received in the beacon frame */ - struct ieee802154_superframe_spec_s superframe_spec; + struct ieee802154_superframespec_s sfspec; - uint8_t gts_permit; /* 0=No GTS requests allowed + uint8_t gtspermit; /* 0=No GTS requests allowed * 1=GTS request allowed */ uint8_t lqi; /* Link Quality Indication of the beacon */ uint32_t timestamp; /* Time at which the beacon frame was received @@ -574,13 +625,13 @@ union ieee802154_macattr_u uint8_t saddr[IEEE802154_SADDRSIZE]; uint8_t panid[IEEE802154_PANIDSIZE]; - uint8_t coord_eaddr[IEEE802154_EADDRSIZE]; - uint8_t coord_saddr[IEEE802154_SADDRSIZE]; + uint8_t coordeaddr[IEEE802154_EADDRSIZE]; + uint8_t coordsaddr[IEEE802154_SADDRSIZE]; enum ieee802154_devmode_e devmode; bool is_assoc; - bool assoc_permit; + bool assocpermit; bool auto_req; bool batt_life_ext; bool gts_permit; @@ -611,7 +662,7 @@ union ieee802154_macattr_u uint8_t beacon_order; uint32_t beacon_tx_time : 24; - uint8_t superframe_order; + uint8_t superframeorder; uint8_t bsn; uint8_t dsn; @@ -619,7 +670,7 @@ union ieee802154_macattr_u union ieee802154_phyattr_u { - uint8_t channel; + uint8_t chan; int32_t txpwr; uint32_t symdur_picosec; /* TODO: Fill this out as we implement supported get/set commands */ @@ -845,8 +896,38 @@ struct ieee802154_purge_req_s struct ieee802154_assoc_req_s { - uint8_t chnum; /* Channel number to attempt association */ - uint8_t chpage; /* Channel page to attempt association */ + uint8_t chan; /* Channel number to attempt association */ + uint8_t chpage; /* Channel page to attempt association */ + + /* TODO: + * This is a non-standard field. I believe there is a catch 22 in the + * standard and until I can figure it out, I'm adding this boolean to let the + * application tell the MAC whether it is trying to assocaite with a beacon + * enabled PAN or non-beacon enabled PAN. If it is beacon-enabled, the MAC + * will track the beacon first before transmitting the association. This can + * take some time depending on the beacon interval. If the PAN is non-beacon + * enabled, the association request is sent immediately via CSMA. + * + * The catch 22: The standard outlines the procedure for associating: reset + * the MAC, scan to find PAN's and pass coordinator address info to + * application, application calls associate passing address info of + * coordinator. Which sounds good. The problem is that the primitive has no + * field for determining if the PAN we are trying to join is beacon enabled + * or not. Which means we don't know whether to tranmsit immediately or try + * to track the beacon. The standard does say that ALL command frames should + * be sent during the Contention Access Period (CAP), but how could you send + * it at the rigth tiem, if you are not tracking the beacon. What's worse is + * in the association section, it says if you are tracking the beacon, to + * send the association request during the CAP. But how can you track the + * beacon if you are not associated. Normally tracking the beacon would be + * triggered by the SYNC.request primitive. But from my understanding that + * primitive is intended to be used AFTER association since it requires the + * MAC to already have a coordinator address and PAN ID so that it can track + * the beacon frames properly. Which, of course, how could the MAC have that + * info if it is not associated. + */ + + bool beacon; /* Coordinator Address with which to associate */ @@ -1037,7 +1118,7 @@ struct ieee802154_beaconnotify_ind_s /* PAN descriptor for the received beacon */ - struct ieee802154_pan_desc_s pan_desc; + struct ieee802154_pandesc_s pandesc; /* Beacon pending addresses */ @@ -1238,20 +1319,17 @@ struct ieee802154_scan_req_s { enum ieee802154_scantype_e type; uint8_t duration; - uint8_t ch_page; + uint8_t chpage; + uint8_t channels[15]; + uint8_t numchan; #ifdef CONFIG_IEEE802154_SECURITY /* Security information if enabled */ struct ieee802154_security_s security; #endif - - uint8_t channels[1]; }; -#define SIZEOF_IEEE802154_SCAN_REQ_S(n) \ - (sizeof(struct ieee802154_scan_req_s) + (n) - 1) - /***************************************************************************** * Primitive: MLME-SCAN.confirm * @@ -1264,10 +1342,12 @@ struct ieee802154_scan_conf_s { enum ieee802154_status_e status; enum ieee802154_scantype_e type; - uint8_t ch_page; - uint8_t num_channels; - - /* TODO: Figure out how to handle missing primitive semantics. See standard. */ + uint8_t chpage; + uint8_t unscanned[15]; + uint8_t numunscanned; + uint8_t numdesc; + struct ieee802154_pandesc_s pandescs[MAC802154_NPANDESC]; + uint8_t edlist[MAC802154_NPANDESC]; }; /***************************************************************************** @@ -1318,7 +1398,7 @@ struct ieee802154_set_req_s struct ieee802154_start_req_s { uint8_t panid[IEEE802154_PANIDSIZE]; - uint8_t chnum; + uint8_t chan; uint8_t chpage; uint32_t starttime : 24; diff --git a/include/nuttx/wireless/ieee802154/ieee802154_radio.h b/include/nuttx/wireless/ieee802154/ieee802154_radio.h index 7e9cd14653..8f851ffe72 100644 --- a/include/nuttx/wireless/ieee802154/ieee802154_radio.h +++ b/include/nuttx/wireless/ieee802154/ieee802154_radio.h @@ -89,6 +89,18 @@ struct ieee802154_txdesc_s /* TODO: Add slotting information for GTS transactions */ }; +struct ieee802154_beaconframe_s +{ + uint8_t bf_data[IEEE802154_MAX_PHY_PACKET_SIZE]; + uint8_t bf_len; + uint8_t bf_offset; +}; + +enum ieee802154_sfevent_e +{ + IEEE802154_SFEVENT_ENDOFACTIVE, +}; + /* IEEE802.15.4 Radio Interface Operations **********************************/ struct ieee802154_radiocb_s @@ -99,6 +111,8 @@ struct ieee802154_radiocb_s FAR struct ieee802154_txdesc_s *tx_desc); CODE void (*rxframe) (FAR const struct ieee802154_radiocb_s *radiocb, FAR struct ieee802154_data_ind_s *ind); + CODE void (*sfevent) (FAR const struct ieee802154_radiocb_s *radiocb, + enum ieee802154_sfevent_e sfevent); }; struct ieee802154_radio_s @@ -119,6 +133,14 @@ struct ieee802154_radio_s CODE int (*rxenable) (FAR struct ieee802154_radio_s *radio, bool enable); CODE int (*req_rxenable)(FAR struct ieee802154_radio_s *radio, FAR struct ieee802154_rxenable_req_s *req); + CODE int (*beaconstart)(FAR struct ieee802154_radio_s *radio, + FAR const struct ieee802154_superframespec_s *sfspec, + FAR struct ieee802154_beaconframe_s *beacon); + CODE int (*beaconupdate)(FAR struct ieee802154_radio_s *radio, + FAR struct ieee802154_beaconframe_s *beacon); + CODE int (*beaconstop)(FAR struct ieee802154_radio_s *radio); + CODE int (*sfupdate)(FAR struct ieee802154_radio_s *radio, + FAR const struct ieee802154_superframespec_s *sfspec); }; #ifdef __cplusplus diff --git a/libc/netdb/lib_dnsquery.c b/libc/netdb/lib_dnsquery.c index 59196206b6..073ff7ee13 100644 --- a/libc/netdb/lib_dnsquery.c +++ b/libc/netdb/lib_dnsquery.c @@ -64,9 +64,14 @@ #define MAX_RETRIES 8 -/* Buffer sizes */ +/* Buffer sizes + * + * The SEND_BUFFER_SIZE depends the configured DNS name size, + * sizeof(DNS query0 = Header (12 bytes) + DNS Name (Variable) + + * Query type (2 bytes) + Query Class (2 bytes) + */ -#define SEND_BUFFER_SIZE 64 +#define SEND_BUFFER_SIZE (32 + CONFIG_NETDB_DNSCLIENT_NAMESIZE) #define RECV_BUFFER_SIZE CONFIG_NETDB_DNSCLIENT_MAXRESPONSE /**************************************************************************** diff --git a/net/devif/devif_poll.c b/net/devif/devif_poll.c index 900d1aaa1c..41475cb9b5 100644 --- a/net/devif/devif_poll.c +++ b/net/devif/devif_poll.c @@ -122,6 +122,7 @@ static void devif_packet_conversion(FAR struct net_driver_s *dev, if (dev->d_len > 0) #endif { +#ifdef CONFIG_NET_TCP if (pkttype == DEVIF_TCP) { FAR struct ipv6_hdr_s *ipv6 = (FAR struct ipv6_hdr_s *)dev->d_buf; @@ -145,6 +146,7 @@ static void devif_packet_conversion(FAR struct net_driver_s *dev, } } else +#endif { nerr("ERROR: Non-TCP packet dropped. Packet type: %u\n", pkttype); } diff --git a/net/sixlowpan/Make.defs b/net/sixlowpan/Make.defs index d1faae0eac..749d821656 100644 --- a/net/sixlowpan/Make.defs +++ b/net/sixlowpan/Make.defs @@ -40,15 +40,14 @@ ifeq ($(CONFIG_NET_6LOWPAN),y) # Include IEEE 802.15.4 file in the build NET_CSRCS += sixlowpan_initialize.c sixlowpan_globals.c sixlowpan_utils.c -NET_CSRCS += sixlowpan_input.c sixlowpan_send.c sixlowpan_framer.c -NET_CSRCS += sixlowpan_framelist.c +NET_CSRCS += sixlowpan_input.c sixlowpan_framer.c sixlowpan_framelist.c ifeq ($(CONFIG_NET_TCP),y) NET_CSRCS += sixlowpan_tcpsend.c endif ifeq ($(CONFIG_NET_UDP),y) -NET_CSRCS += sixlowpan_udpsend.c +NET_CSRCS += sixlowpan_udpsend.c sixlowpan_send.c endif ifeq ($(CONFIG_NET_6LOWPAN_COMPRESSION_HC1),y) diff --git a/net/sixlowpan/README.txt b/net/sixlowpan/README.txt index 775357260b..4c654caef1 100644 --- a/net/sixlowpan/README.txt +++ b/net/sixlowpan/README.txt @@ -82,7 +82,8 @@ Optimal 6LoWPAN Configuration fe80 0000 0000 0000 0000 00ff fe00 MMMM 2-byte short address IEEE 48-bit MAC fe80 0000 0000 0000 NNNN NNNN NNNN NNNN 8-byte extended address IEEE EUI-64 -4. Compressable port numbers in the rangs 0xf0b0-0xf0bf +4. To be compressable, port numbers must be in the range 0xf0b0-0xf0bf, + hexadecimal. That is 61616-61631 decimal. 5. IOBs: Must be big enough to hold one IEEE802.15.4 frame (CONFIG_NET_6LOWPAN_FRAMELEN, typically 127). There must be enough IOBs to decompose the largest IPv6 diff --git a/net/sixlowpan/sixlowpan_framelist.c b/net/sixlowpan/sixlowpan_framelist.c index 0b17e6dbab..53921963ac 100644 --- a/net/sixlowpan/sixlowpan_framelist.c +++ b/net/sixlowpan/sixlowpan_framelist.c @@ -73,6 +73,18 @@ # error IOBs must be large enough to hold full IEEE802.14.5 frame #endif +/* A IOB must also be big enought to hold the maximum MAC header (25 bytes?) + * plus the FCS and have some amount of space left for the payload. + */ + +#if CONFIG_NET_6LOWPAN_FRAMELEN < (SIXLOWPAN_MAC_FCSSIZE + 25) +# error CONFIG_NET_6LOWPAN_FRAMELEN too small to hold a IEEE802.14.5 frame +#endif + +/* We must reserve space at the end of the frame for a 2-byte FCS */ + +#define SIXLOWPAN_FRAMELEN (CONFIG_NET_6LOWPAN_FRAMELEN - SIXLOWPAN_MAC_FCSSIZE) + /* There must be at least enough IOBs to hold the full MTU. Probably still * won't work unless there are a few more. */ @@ -110,11 +122,9 @@ * ****************************************************************************/ -static void sixlowpan_compress_ipv6hdr(FAR const struct ipv6_hdr_s *ipv6hdr, - FAR uint8_t *fptr) +static int sixlowpan_compress_ipv6hdr(FAR const struct ipv6_hdr_s *ipv6hdr, + FAR uint8_t *fptr) { - uint16_t protosize; - /* Indicate the IPv6 dispatch and length */ fptr[g_frame_hdrlen] = SIXLOWPAN_DISPATCH_IPV6; @@ -122,52 +132,65 @@ static void sixlowpan_compress_ipv6hdr(FAR const struct ipv6_hdr_s *ipv6hdr, /* Copy the IPv6 header and adjust pointers */ - memcpy(&fptr[g_frame_hdrlen] , ipv6hdr, IPv6_HDRLEN); + memcpy(&fptr[g_frame_hdrlen], ipv6hdr, IPv6_HDRLEN); g_frame_hdrlen += IPv6_HDRLEN; g_uncomp_hdrlen += IPv6_HDRLEN; + return COMPRESS_HDR_INLINE; +} + +/**************************************************************************** + * Name: sixlowpan_protosize + * + * Description: + * Get the size of any uncompresssed protocol header that follows the + * IPv6 header. + * + ****************************************************************************/ + +static uint16_t sixlowpan_protosize(FAR const struct ipv6_hdr_s *ipv6hdr, + FAR uint8_t *fptr) +{ + uint16_t protosize; + /* Copy the following protocol header, */ switch (ipv6hdr->proto) { #ifdef CONFIG_NET_TCP - case IP_PROTO_TCP: - { - FAR struct tcp_hdr_s *tcp = &((FAR struct ipv6tcp_hdr_s *)ipv6hdr)->tcp; + case IP_PROTO_TCP: + { + FAR struct tcp_hdr_s *tcp = + &((FAR struct ipv6tcp_hdr_s *)ipv6hdr)->tcp; - /* The TCP header length is encoded in the top 4 bits of the - * tcpoffset field (in units of 32-bit words). - */ + /* The TCP header length is encoded in the top 4 bits of the + * tcpoffset field (in units of 32-bit words). + */ - protosize = ((uint16_t)tcp->tcpoffset >> 4) << 2; - } - break; + protosize = ((uint16_t)tcp->tcpoffset >> 4) << 2; + } + break; #endif #ifdef CONFIG_NET_UDP - case IP_PROTO_UDP: - protosize = sizeof(struct udp_hdr_s); - break; + case IP_PROTO_UDP: + protosize = UDP_HDRLEN; + break; #endif #ifdef CONFIG_NET_ICMPv6 - case IP_PROTO_ICMP6: - protosize = sizeof(struct icmpv6_hdr_s); - break; + case IP_PROTO_ICMP6: + protosize = ICMPv6_HDRLEN; + break; #endif - default: - nwarn("WARNING: Unrecognized proto: %u\n", ipv6hdr->proto); - return; + default: + nwarn("WARNING: Unrecognized proto: %u\n", ipv6hdr->proto); + protosize = 0; + break; } - /* Copy the protocol header. */ - - memcpy(fptr + g_frame_hdrlen, (FAR uint8_t *)ipv6hdr + g_uncomp_hdrlen, - protosize); - - g_frame_hdrlen += protosize; - g_uncomp_hdrlen += protosize; + return protosize; } /**************************************************************************** @@ -222,14 +245,18 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee, #ifdef CONFIG_NET_6LOWPAN_FRAG uint16_t outlen = 0; #endif + uint8_t protosize; int ret; + ninfo("buflen=%lu\n", (unsigned long)buflen); + /* Initialize global data. Locking the network guarantees that we have * exclusive use of the global values for intermediate calculations. */ g_uncomp_hdrlen = 0; g_frame_hdrlen = 0; + protosize = 0; /* Reset frame meta data */ @@ -350,9 +377,9 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee, /* Try to compress the headers */ #if defined(CONFIG_NET_6LOWPAN_COMPRESSION_HC1) - sixlowpan_compresshdr_hc1(ieee, destip, destmac, fptr); + ret = sixlowpan_compresshdr_hc1(ieee, destip, destmac, fptr); #elif defined(CONFIG_NET_6LOWPAN_COMPRESSION_HC06) - sixlowpan_compresshdr_hc06(ieee, destip, destmac, fptr); + ret = sixlowpan_compresshdr_hc06(ieee, destip, destmac, fptr); #else # error No compression specified #endif @@ -362,14 +389,21 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee, { /* Small.. use IPv6 dispatch (no compression) */ - sixlowpan_compress_ipv6hdr(destip, fptr); + ret = sixlowpan_compress_ipv6hdr(destip, fptr); } - ninfo("Header of length %d\n", g_frame_hdrlen); + /* Get the size of any uncompressed protocol headers */ + + if (ret == COMPRESS_HDR_INLINE) + { + protosize = sixlowpan_protosize(destip, fptr); + } + + ninfo("Header of length=%u protosize=%u\n", g_frame_hdrlen, protosize); /* Check if we need to fragment the packet into several frames */ - if (buflen > (CONFIG_NET_6LOWPAN_FRAMELEN - g_frame_hdrlen)) + if (buflen > (SIXLOWPAN_FRAMELEN - g_frame_hdrlen - protosize)) { #ifdef CONFIG_NET_6LOWPAN_FRAG /* qhead will hold the generated frame list; frames will be @@ -406,29 +440,39 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee, * The fragment header contains three fields: Datagram size, datagram * tag and datagram offset: * - * 1. Datagram size describes the total (un-fragmented) payload. - * 2. Datagram tag identifies the set of fragments and is used to - * match fragments of the same payload. - * 3. Datagram offset identifies the fragment’s offset within the un- - * fragmented payload. + * 1. Datagram size describes the total (un-fragmented) payload. + * 2. Datagram tag identifies the set of fragments and is used to + * match fragments of the same payload. + * 3. Datagram offset identifies the fragment’s offset within the un- + * fragmented payload. * * The fragment header length is 4 bytes for the first header and 5 * bytes for all subsequent headers. */ - pktlen = buflen + g_uncomp_hdrlen; + pktlen = buflen + g_uncomp_hdrlen + protosize; PUTHOST16(fragptr, SIXLOWPAN_FRAG_DISPATCH_SIZE, ((SIXLOWPAN_DISPATCH_FRAG1 << 8) | pktlen)); PUTHOST16(fragptr, SIXLOWPAN_FRAG_TAG, ieee->i_dgramtag); g_frame_hdrlen += SIXLOWPAN_FRAG1_HDR_LEN; + /* Copy any uncompressed protocol headers that must appear only in th + * first fragment. + */ + + if (protosize > 0) + { + FAR uint8_t *src = (FAR uint8_t *)destip + IPv6_HDRLEN; + memcpy(fptr + g_frame_hdrlen, src, protosize); + } + /* Copy payload and enqueue. NOTE that the size is a multiple of eight * bytes. */ - paysize = (CONFIG_NET_6LOWPAN_FRAMELEN - g_frame_hdrlen) & ~7; - memcpy(fptr + g_frame_hdrlen, buf, paysize); + paysize = (SIXLOWPAN_FRAMELEN - g_frame_hdrlen) & ~7; + memcpy(fptr + g_frame_hdrlen + protosize, buf, paysize - protosize); /* Set outlen to what we already sent from the IP payload */ @@ -442,6 +486,9 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee, /* Add the first frame to the IOB queue */ + ninfo("Queuing frame io_len=%u io_offset=%u\n", + iob->io_len, iob->io_offset); + qhead = iob; qtail = iob; @@ -454,7 +501,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee, frame1 = iob->io_data; frag1_hdrlen = g_frame_hdrlen; - while (outlen < buflen) + while (outlen < (buflen + protosize)) { uint16_t fragn_hdrlen; @@ -496,16 +543,16 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee, /* Copy payload and enqueue */ /* Check for the last fragment */ - paysize = (CONFIG_NET_6LOWPAN_FRAMELEN - fragn_hdrlen) & + paysize = (SIXLOWPAN_FRAMELEN - fragn_hdrlen) & SIXLOWPAN_DISPATCH_FRAG_MASK; - if (buflen - outlen < paysize) + if (paysize > buflen - outlen + protosize) { /* Last fragment, truncate to the correct length */ - paysize = buflen - outlen; + paysize = buflen - outlen + protosize; } - memcpy(fptr + fragn_hdrlen, buf + outlen, paysize); + memcpy(fptr + fragn_hdrlen, buf + outlen - protosize, paysize); /* Set outlen to what we already sent from the IP payload */ @@ -520,6 +567,9 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee, /* Add the next frame to the tail of the IOB queue */ + ninfo("Queuing frame io_len=%u io_offset=%u\n", + iob->io_len, iob->io_offset); + qtail->io_flink = iob; qtail = iob; @@ -542,6 +592,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee, /* And submit the frame to the MAC */ + ninfo("Submitting frame\n"); ret = sixlowpan_frame_submit(ieee, &meta, iob); if (ret < 0) { @@ -566,10 +617,20 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee, * and send in one frame. */ + /* Copy any uncompressed protocol headers that must appear only in th + * first fragment. + */ + + if (protosize > 0) + { + FAR uint8_t *src = (FAR uint8_t *)destip + IPv6_HDRLEN; + memcpy(fptr + g_frame_hdrlen, src, protosize); + } + /* Copy the payload into the frame. */ - memcpy(fptr + g_frame_hdrlen, buf, buflen); - iob->io_len = buflen + g_frame_hdrlen; + memcpy(fptr + g_frame_hdrlen + protosize, buf, buflen); + iob->io_len = buflen + g_frame_hdrlen + protosize; iob->io_pktlen = iob->io_len; ninfo("Non-fragmented: length %d\n", iob->io_len); @@ -578,6 +639,9 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee, /* And submit the frame to the MAC */ + ninfo("Submitting frame length=%u io_offset=%u\n", + iob->io_len, iob->io_offset); + ret = sixlowpan_frame_submit(ieee, &meta, iob); if (ret < 0) { diff --git a/net/sixlowpan/sixlowpan_hc06.c b/net/sixlowpan/sixlowpan_hc06.c index e066da19b5..ec9577e1dc 100644 --- a/net/sixlowpan/sixlowpan_hc06.c +++ b/net/sixlowpan/sixlowpan_hc06.c @@ -68,13 +68,6 @@ #ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06 -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#define UDPIPv6BUF(ieee) \ - ((FAR struct udp_hdr_s *)&((ieee)->i_dev.d_buf[IPv6_HDRLEN])) - /**************************************************************************** * Private Types ****************************************************************************/ @@ -116,43 +109,58 @@ static FAR uint8_t *g_hc06ptr; /* Uncompression of linklocal * * 0 -> 16 bytes from packet - * 1 -> 2 bytes from prefix - bunch of zeroes and 8 from packet - * 2 -> 2 bytes from prefix - 0000::00ff:fe00:XXXX from packet - * 3 -> 2 bytes from prefix - infer 8 bytes from MAC address + * 1 -> 2 bytes from prefix - 16 bytes from packet + * 2 -> 2 bytes from prefix - 0000::00ff:fe00:XXXX and 2 bytes from packet + * 3 -> 2 bytes from prefix - Infer 2 or 8 bytes from MAC address * - * NOTE: => the uncompress function does change 0xf to 0x10 - * NOTE: 0x00 => no-autoconfig => unspecified + * NOTE: ipaddr=the uncompress function does change 0xf to 0x10 + * NOTE: 0x00 ipaddr=no-autoconfig ipaddr=unspecified */ -static const uint8_t g_unc_llconf[] = { 0x0f, 0x28, 0x22, 0x20 }; +static const uint16_t g_unc_llconf[] = +{ + 0x000f, 0x0028, 0x0022, 0x0120 +}; /* Uncompression of ctx-based * * 0 -> 0 bits from packet [unspecified / reserved] - * 1 -> 8 bytes from prefix - bunch of zeroes and 8 from packet - * 2 -> 8 bytes from prefix - 0000::00ff:fe00:XXXX + 2 from packet - * 3 -> 8 bytes from prefix - infer 8 bytes from MAC address + * 1 -> 8 bytes from prefix - Bunch of zeroes and 8 bytes from packet + * 2 -> 8 bytes from prefix - 0000::00ff:fe00:XXXX and 2 bytes from packet + * 3 -> 8 bytes from prefix - Infer 2 or 8 bytes from MAC address */ -static const uint8_t g_unc_ctxconf[] = { 0x00, 0x88, 0x82, 0x80 }; +static const uint16_t g_unc_ctxconf[] = +{ + 0x0000, 0x0088, 0x0082, 0x0180 +}; /* Uncompression of ctx-based * * 0 -> 0 bits from packet - * 1 -> 2 bytes from prefix - bunch of zeroes 5 from packet - * 2 -> 2 bytes from prefix - zeroes + 3 from packet - * 3 -> 2 bytes from prefix - infer 1 bytes from MAC address + * 1 -> 2 bytes from prefix - Bunch of zeroes 5 bytes from packet + * 2 -> 2 bytes from prefix - Zeroes + 3 bytes from packet + * 3 -> 2 bytes from prefix - Infer 1 bytes from MAC address */ -static const uint8_t g_unc_mxconf[] = { 0x0f, 0x25, 0x23, 0x21 }; +static const uint16_t g_unc_mxconf[] = +{ + 0x000f, 0x0025, 0x0023, 0x0121 +}; /* Link local prefix */ -static const uint8_t g_llprefix[] = { 0xfe, 0x80 }; +static const uint8_t g_llprefix[] = +{ + 0xfe, 0x80 +}; /* TTL uncompression values */ -static const uint8_t g_ttl_values[] = { 0, 1, 64, 255 }; +static const uint8_t g_ttl_values[] = +{ + 0, 1, 64, 255 +}; /**************************************************************************** @@ -191,7 +199,7 @@ static FAR struct sixlowpan_addrcontext_s * } /**************************************************************************** - * Name: find_addrcontext_bynumber + * Name: find_addrcontext_byprefix * * Description: * Find the address context corresponding to the prefix ipaddr. @@ -220,7 +228,7 @@ static FAR struct sixlowpan_addrcontext_s * } /**************************************************************************** - * Name: comporess_ipaddr, compress_tagaddr, and compress_laddr + * Name: compress_ipaddr, compress_tagaddr, and compress_laddr * * Description: * Uncompress addresses based on a prefix and a postfix with zeroes in @@ -228,7 +236,7 @@ static FAR struct sixlowpan_addrcontext_s * * to configure the IP address (autoconf style). * * prefpost takes a byte where the first nibble specify prefix count - * and the second postfix count (NOTE: 15/0xf => 16 bytes copy). + * and the second postfix count (NOTE: 15/0xf ipaddr=16 bytes copy). * * compress_tagaddr() accepts a remote, variable length, taged MAC address; * compress_laddr() accepts a local, fixed length MAC address. @@ -261,34 +269,71 @@ static uint8_t compress_tagaddr(FAR const net_ipv6addr_t ipaddr, FAR const struct sixlowpan_tagaddr_s *macaddr, uint8_t bitpos) { - ninfo("ipaddr=%p macaddr=%p extended=%u bitpos=%u g_hc06ptr=%p\n", - ipaddr, macaddr, macaddr->extended, bitpos, g_hc06ptr); + uint8_t tag; - if (sixlowpan_ismacbased(ipaddr, macaddr)) + ninfo("Compressing bitpos=%u extended=%u\n", bitpos, macaddr->extended); + ninfo(" ipaddr=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", + ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3], + ipaddr[4], ipaddr[5], ipaddr[6], ipaddr[7]); + + if (macaddr->extended) { - return 3 << bitpos; /* 0-bits */ + ninfo(" eaddr=%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", + macaddr->u.eaddr.u8[0], macaddr->u.eaddr.u8[1], + macaddr->u.eaddr.u8[2], macaddr->u.eaddr.u8[3], + macaddr->u.eaddr.u8[4], macaddr->u.eaddr.u8[5], + macaddr->u.eaddr.u8[6], macaddr->u.eaddr.u8[7]); } else { - return compress_ipaddr(ipaddr, bitpos); + ninfo(" saddr=%02x:%02x\n", + macaddr->u.saddr.u8[0], macaddr->u.saddr.u8[1]); } + + if (sixlowpan_ismacbased(ipaddr, macaddr)) + { + tag = (3 << bitpos); /* 0-bits */ + } + else + { + tag = compress_ipaddr(ipaddr, bitpos); + } + + ninfo("Tag=%02x\n", tag); + return tag; } static uint8_t compress_laddr(FAR const net_ipv6addr_t ipaddr, FAR const struct sixlowpan_addr_s *macaddr, uint8_t bitpos) { - ninfo("ipaddr=%p macaddr=%p bitpos=%u g_hc06ptr=%p\n", - ipaddr, macaddr, bitpos, g_hc06ptr); + uint8_t tag; + + ninfo("Compressing bitpos=%u\n", bitpos); + ninfo(" ipaddr=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", + ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3], + ipaddr[4], ipaddr[5], ipaddr[6], ipaddr[7]); + +#ifdef CONFIG_NET_6LOWPAN_EXTENDEDADDR + ninfo(" eaddr=%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", + macaddr->u8[0], macaddr->u8[1], macaddr->u8[2], macaddr->u8[3], + macaddr->u8[4], macaddr->u8[5], macaddr->u8[6], macaddr->u8[7]); +#else + ninfo(" saddr=%02x:%02x\n", + macaddr->u8[0], macaddr->u8[1]); +#endif if (sixlowpan_isaddrbased(ipaddr, macaddr)) { - return 3 << bitpos; /* 0-bits */ + tag = (3 << bitpos); /* 0-bits */ } else { - return compress_ipaddr(ipaddr, bitpos); + tag = compress_ipaddr(ipaddr, bitpos); } + + ninfo("Tag=%02x\n", tag); + return tag; } /**************************************************************************** @@ -300,58 +345,130 @@ static uint8_t compress_laddr(FAR const net_ipv6addr_t ipaddr, * to configure the IP address (autoconf style). * * prefpost takes a byte where the first nibble specify prefix count - * and the second postfix count (NOTE: 15/0xf => 16 bytes copy). + * and the second postfix count (NOTE: 15/0xf ipaddr=16 bytes copy). * ****************************************************************************/ -static void uncompress_addr(FAR net_ipv6addr_t ipaddr, uint8_t const prefix[], - uint8_t prefpost) +static void uncompress_addr(FAR const struct ieee802154_addr_s *addr, + FAR const uint8_t *prefix, uint16_t prefpost, + FAR net_ipv6addr_t ipaddr) { - uint8_t prefcount = prefpost >> 4; - uint8_t postcount = prefpost & 0x0f; + FAR const uint8_t *srcptr; + bool fullmac = false; + bool usemac = (prefpost & 0x0100) != 0; + uint8_t prefcount = (prefpost >> 4) & 0xf; + uint8_t postcount = prefpost & 0x0f; - /* Full nibble 15 => 16 */ + /* The value 16 is encoded as 0xf in the 4 bit-fields. */ prefcount = prefcount == 15 ? 16 : prefcount; postcount = postcount == 15 ? 16 : postcount; + /* Select the data source */ + + srcptr = g_hc06ptr; + if (usemac) + { + bool saddr = (addr->mode == IEEE802154_ADDRMODE_SHORT); + uint16_t addrsize = saddr ? NET_6LOWPAN_SADDRSIZE: NET_6LOWPAN_EADDRSIZE; + + /* Select the source the address data */ + + srcptr = saddr ? addr->saddr : addr->eaddr; + + /* If the provided postcount is zero and we are taking data from the + * MAC address, set postcount to the address length. + */ + + if (postcount == 0) + { + postcount = addrsize; + } + + /* If we are converting the entire MAC address, then we need to some some + * special bit operations. + */ + + fullmac = (postcount == addrsize); + } + + /* Copy any prefix */ + if (prefcount > 0) { memcpy(ipaddr, prefix, prefcount); } + /* Clear bytes between int prefcount and postcount */ + if (prefcount + postcount < 16) { - FAR uint8_t *iptr = (FAR uint8_t *)&ipaddr[0]; + FAR uint8_t *destptr = (FAR uint8_t *)&ipaddr[0]; - memset(&iptr[prefcount], 0, 16 - (prefcount + postcount)); + memset(&destptr[prefcount], 0, 16 - (prefcount + postcount)); } + /* Copy the remaining data from the source */ + if (postcount > 0) { - FAR uint8_t *iptr = (FAR uint8_t *)&ipaddr[0]; - - memcpy(&iptr[16 - postcount], g_hc06ptr, postcount); if (postcount == 2 && prefcount < 11) { - /* 16 bits uncompression => 0000:00ff:fe00:XXXX */ + /* 16 bits uncompression ipaddr=0000:00ff:fe00:XXXX */ - iptr[11] = 0xff; - iptr[12] = 0xfe; + ipaddr[5] = HTONS(0x00ff); + ipaddr[6] = HTONS(0xfe00); } - g_hc06ptr += postcount; + /* If the postcount is even then take extra care with endian-ness */ + + if ((postcount & 1) == 0) + { + int destndx = 8 - (postcount >> 1); + int i; + + for (i = destndx; i < 8; i++) + { + ipaddr[i] = (uint16_t)srcptr[0] << 8 | (uint16_t)srcptr[1]; + srcptr += 2; + } + + /* If the was a standard MAC based address then toggle */ + + if (fullmac) + { + ipaddr[destndx] ^= 0x200; + } + } + + /* postcount is odd... */ + + else + { + FAR uint8_t *destptr = (FAR uint8_t *)&ipaddr[0]; + int offset = 16 - postcount; + + memcpy(&destptr[offset], srcptr, postcount); + } + + /* If we took the data from packet, then update the packet pointer */ + + if (!usemac) + { + g_hc06ptr += postcount; + } } else if (prefcount > 0) { - /* No IID based configuration if no prefix and no data => unspec */ + /* No IID based configuration if no prefix and no data ipaddr=unspec */ nwarn("WARNING: No IID based configuration\n"); } - ninfo("Uncompressing %d + %d => %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", - prefcount, postcount, ipaddr[0], ipaddr[2], ipaddr[3], ipaddr[5], - ipaddr[5], ipaddr[6], ipaddr[7]); + ninfo("Uncompressing %d + %d ipaddr=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", + prefcount, postcount, + ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3], + ipaddr[4], ipaddr[5], ipaddr[6], ipaddr[7]); } /**************************************************************************** @@ -470,20 +587,22 @@ void sixlowpan_hc06_initialize(void) * fptr - Pointer to frame to be compressed. * * Returned Value: - * None + * On success the indications of the defines COMPRESS_HDR_* are returned. + * A negated errno value is returned on failure. * ****************************************************************************/ -void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, - FAR const struct ipv6_hdr_s *ipv6, - FAR const struct sixlowpan_tagaddr_s *destmac, - FAR uint8_t *fptr) +int sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, + FAR const struct ipv6_hdr_s *ipv6, + FAR const struct sixlowpan_tagaddr_s *destmac, + FAR uint8_t *fptr) { FAR uint8_t *iphc = fptr + g_frame_hdrlen; FAR struct sixlowpan_addrcontext_s *addrcontext; uint8_t iphc0; uint8_t iphc1; uint8_t tmp; + int ret = COMPRESS_HDR_INLINE; ninfo("fptr=%p g_frame_hdrlen=%u iphc=%p\n", fptr, g_frame_hdrlen, iphc); @@ -579,10 +698,9 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, } /* Note that the payload length is always compressed */ - /* Next header. We compress it if UDP */ -#if CONFIG_NET_UDP || UIP_CONF_ROUTER +#ifdef CONFIG_NET_UDP if (ipv6->proto == IP_PROTO_UDP) { iphc0 |= SIXLOWPAN_IPHC_NH; @@ -627,7 +745,7 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, if (net_is_addr_unspecified(ipv6->srcipaddr)) { - ninfo("Compressing unspecified. Setting SAC\n"); + ninfo("Compressing unspecified srcipaddr. Setting SAC\n"); iphc1 |= SIXLOWPAN_IPHC_SAC; iphc1 |= SIXLOWPAN_IPHC_SAM_128; @@ -649,11 +767,11 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, SIXLOWPAN_IPHC_SAM_BIT); } - /* No address context found for this address */ + /* No address context found for the source address */ else if (net_is_addr_linklocal(ipv6->srcipaddr) && - ipv6->destipaddr[1] == 0 && ipv6->destipaddr[2] == 0 && - ipv6->destipaddr[3] == 0) + ipv6->srcipaddr[1] == 0 && ipv6->srcipaddr[2] == 0 && + ipv6->srcipaddr[3] == 0) { iphc1 |= compress_laddr(ipv6->srcipaddr, &ieee->i_dev.d_mac.ieee802154, @@ -661,7 +779,12 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, } else { - /* Send the full address => SAC = 0, SAM = 00 */ + /* Send the full source address ipaddr: SAC = 0, SAM = 00 */ + + ninfo("Uncompressable srcipaddr=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", + ipv6->srcipaddr[0], ipv6->srcipaddr[1], ipv6->srcipaddr[2], + ipv6->srcipaddr[3], ipv6->srcipaddr[4], ipv6->srcipaddr[5], + ipv6->srcipaddr[6], ipv6->srcipaddr[7]); iphc1 |= SIXLOWPAN_IPHC_SAM_128; /* 128-bits */ memcpy(g_hc06ptr, ipv6->srcipaddr, 16); @@ -733,9 +856,10 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, iphc1 |= compress_tagaddr(ipv6->destipaddr, destmac, SIXLOWPAN_IPHC_DAM_BIT); - - /* No address context found for this address */ } + + /* No address context found for this address */ + else if (net_is_addr_linklocal(ipv6->destipaddr) && ipv6->destipaddr[1] == 0 && ipv6->destipaddr[2] == 0 && ipv6->destipaddr[3] == 0) @@ -743,10 +867,11 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, iphc1 |= compress_tagaddr(ipv6->destipaddr, destmac, SIXLOWPAN_IPHC_DAM_BIT); } + + /* Send the full address */ + else { - /* Send the full address */ - iphc1 |= SIXLOWPAN_IPHC_DAM_128; /* 128-bits */ memcpy(g_hc06ptr, ipv6->destipaddr, 16); g_hc06ptr += 16; @@ -755,14 +880,17 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, g_uncomp_hdrlen = IPv6_HDRLEN; -#if CONFIG_NET_UDP +#ifdef CONFIG_NET_UDP /* UDP header compression */ if (ipv6->proto == IP_PROTO_UDP) { - FAR struct udp_hdr_s *udp = UDPIPv6BUF(ieee); + /* The UDP header will follow the IPv6 header */ - ninfo("Uncompressed UDP ports on send side: %x, %x\n", + FAR struct udp_hdr_s *udp = + (FAR struct udp_hdr_s *)((FAR uint8_t *)ipv6 + IPv6_HDRLEN); + + ninfo("Uncompressed UDP ports: srcport=%04x destport=%04x\n", ntohs(udp->srcport), ntohs(udp->destport)); /* Mask out the last 4 bits can be used as a mask */ @@ -774,7 +902,7 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, *g_hc06ptr = SIXLOWPAN_NHC_UDP_CS_P_11; - ninfo("Remove 12b of both source & dest with prefix 0xfob\n"); + ninfo("Remove 12b of both source & dest with prefix 0xf0b*\n"); *(g_hc06ptr + 1) = (uint8_t)((ntohs(udp->srcport) - SIXLOWPAN_UDP_4_BIT_PORT_MIN) << 4) + @@ -827,13 +955,10 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, /* Always inline the checksum */ - if (1) - { - memcpy(g_hc06ptr, &udp->udpchksum, 2); - g_hc06ptr += 2; - } - + memcpy(g_hc06ptr, &udp->udpchksum, 2); + g_hc06ptr += 2; g_uncomp_hdrlen += UDP_HDRLEN; + ret = COMPRESS_HDR_ELIDED; } #endif /* CONFIG_NET_UDP */ @@ -847,7 +972,7 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, ninfo("fptr=%p g_frame_hdrlen=%u iphc=%02x:%02x:%02x g_hc06ptr=%p\n", fptr, g_frame_hdrlen, iphc[0], iphc[1], iphc[2], g_hc06ptr); - return; + return ret; } /**************************************************************************** @@ -864,20 +989,22 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, * appropriate values * * Input Parmeters: - * 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 first - * fragment. - * iob - Pointer to the IOB containing the received frame. - * fptr - Pointer to frame to be compressed. - * bptr - Output goes here. Normally this is a known offset into d_buf, - * may be redirected to a "bitbucket" on the case of FRAGN frames. + * ind - MAC header meta data including node addressing information. + * 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 first + * fragment. + * iob - Pointer to the IOB containing the received frame. + * fptr - Pointer to frame to be compressed. + * bptr - Output goes here. Normally this is a known offset into d_buf, + * may be redirected to a "bitbucket" on the case of FRAGN frames. * * Returned Value: * None * ****************************************************************************/ -void sixlowpan_uncompresshdr_hc06(uint16_t iplen, FAR struct iob_s *iob, +void sixlowpan_uncompresshdr_hc06(FAR const struct ieee802154_data_ind_s *ind, + uint16_t iplen, FAR struct iob_s *iob, FAR uint8_t *fptr, FAR uint8_t *bptr) { FAR struct ipv6_hdr_s *ipv6 = (FAR struct ipv6_hdr_s *)bptr; @@ -1018,8 +1145,9 @@ void sixlowpan_uncompresshdr_hc06(uint16_t iplen, FAR struct iob_s *iob, * address. */ - uncompress_addr(ipv6->srcipaddr, - tmp != 0 ? addrcontext->prefix : NULL, g_unc_ctxconf[tmp]); + uncompress_addr(&ind->src, + tmp != 0 ? addrcontext->prefix : NULL, + g_unc_ctxconf[tmp], ipv6->srcipaddr); } else { @@ -1028,7 +1156,8 @@ void sixlowpan_uncompresshdr_hc06(uint16_t iplen, FAR struct iob_s *iob, * address. */ - uncompress_addr(ipv6->srcipaddr, g_llprefix, g_unc_llconf[tmp]); + uncompress_addr(&ind->src, g_llprefix, g_unc_llconf[tmp], + ipv6->srcipaddr); } /* Destination address */ @@ -1063,12 +1192,13 @@ void sixlowpan_uncompresshdr_hc06(uint16_t iplen, FAR struct iob_s *iob, g_hc06ptr++; } - uncompress_addr(ipv6->destipaddr, prefix, g_unc_mxconf[tmp]); + uncompress_addr(&ind->dest, prefix, g_unc_mxconf[tmp], + ipv6->destipaddr); } } else { - /* no multicast */ + /* No multicast */ /* Context based */ if ((iphc1 & SIXLOWPAN_IPHC_DAC) != 0) @@ -1086,13 +1216,17 @@ void sixlowpan_uncompresshdr_hc06(uint16_t iplen, FAR struct iob_s *iob, return; } - uncompress_addr(ipv6->destipaddr, addrcontext->prefix, g_unc_ctxconf[tmp]); + uncompress_addr(&ind->dest, addrcontext->prefix, + g_unc_ctxconf[tmp], ipv6->destipaddr); } else { - /* Not address context based => link local M = 0, DAC = 0 - same as SAC */ + /* Not address context based ipaddr=link local M = 0, DAC = 0 - same + * as SAC. + */ - uncompress_addr(ipv6->destipaddr, g_llprefix, g_unc_llconf[tmp]); + uncompress_addr(&ind->dest,g_llprefix, g_unc_llconf[tmp], + ipv6->destipaddr); } } diff --git a/net/sixlowpan/sixlowpan_hc1.c b/net/sixlowpan/sixlowpan_hc1.c index c6b2f4a137..7f24654262 100644 --- a/net/sixlowpan/sixlowpan_hc1.c +++ b/net/sixlowpan/sixlowpan_hc1.c @@ -50,6 +50,7 @@ #include #include +#include #include #include @@ -57,6 +58,31 @@ #ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC1 +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sixlowpan_uncompress_addr + * + * Description: + * Uncompress a link-local, MAC-based IPv6 address. + * + ****************************************************************************/ + +static void sixlowpan_uncompress_addr(FAR const struct ieee802154_addr_s *addr, + FAR net_ipv6addr_t ipaddr) +{ + if (addr->mode == IEEE802154_ADDRMODE_SHORT) + { + sixlowpan_ipfromsaddr(addr->saddr, ipaddr); + } + else + { + sixlowpan_ipfromeaddr(addr->eaddr, ipaddr); + } +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -82,21 +108,21 @@ * - 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 + * This is feasible is both ports are between F0B0 and F0B0 + 15 * * Resulting header structure: * - For ICMP, TCP, non compressed UDP\n - * HC1 encoding = 11111010 (UDP) 11111110 (TCP) 11111100 (ICMP)\n + * HC1 encoding = 11111010 (UDP) 11111110 (TCP) 11111100 (ICMP) * 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 + * HC1 encoding = 11111011, HC_UDP encoding = 11100000 * 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 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -114,16 +140,18 @@ * fptr - Pointer to frame to be compressed. * * Returned Value: - * None + * On success the indications of the defines COMPRESS_HDR_* are returned. + * A negated errno value is returned on failure. * ****************************************************************************/ -void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee, - FAR const struct ipv6_hdr_s *ipv6, - FAR const struct sixlowpan_tagaddr_s *destmac, - FAR uint8_t *fptr) +int sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee, + FAR const struct ipv6_hdr_s *ipv6, + FAR const struct sixlowpan_tagaddr_s *destmac, + FAR uint8_t *fptr) { FAR uint8_t *hc1 = fptr + g_frame_hdrlen; + int ret = COMPRESS_HDR_INLINE; /* Check if all the assumptions for full compression are valid */ @@ -132,14 +160,25 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee, !sixlowpan_isaddrbased(ipv6->srcipaddr, &ieee->i_dev.d_mac.ieee802154) || !sixlowpan_islinklocal(ipv6->destipaddr) || !sixlowpan_ismacbased(ipv6->destipaddr, destmac) || - (ipv6->proto != IP_PROTO_ICMP6 && ipv6->proto != IP_PROTO_UDP && - ipv6->proto != IP_PROTO_TCP)) + ( 1 +#ifdef CONFIG_NET_TCP + && ipv6->proto != IP_PROTO_TCP +#endif +#ifdef CONFIG_NET_UDP + && ipv6->proto != IP_PROTO_UDP +#endif +#ifdef CONFIG_NET_ICMPv6 + && ipv6->proto != IP_PROTO_ICMP6 +#endif + )) { /* IPV6 DISPATCH * Something cannot be compressed, use IPV6 DISPATCH, compress * nothing, copy IPv6 header into the frame buffer */ + nwarn("WARNING: Fall back to IPv6 dispatch\n"); + /* IPv6 dispatch header (1 byte) */ hc1[SIXLOWPAN_HC1_DISPATCH] = SIXLOWPAN_DISPATCH_IPV6; @@ -160,25 +199,29 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee, g_uncomp_hdrlen += IPv6_HDRLEN; switch (ipv6->proto) { +#ifdef CONFIG_NET_ICMPv6 case IP_PROTO_ICMP6: - /* HC1 encoding and ttl */ + { + /* HC1 encoding and ttl */ - hc1[SIXLOWPAN_HC1_ENCODING] = 0xfc; - hc1[SIXLOWPAN_HC1_TTL] = ipv6->ttl; - g_frame_hdrlen += SIXLOWPAN_HC1_HDR_LEN; + hc1[SIXLOWPAN_HC1_ENCODING] = 0xfc; + hc1[SIXLOWPAN_HC1_TTL] = ipv6->ttl; + g_frame_hdrlen += SIXLOWPAN_HC1_HDR_LEN; + } break; - -#if CONFIG_NET_TCP +#endif +#ifdef CONFIG_NET_TCP case IP_PROTO_TCP: - /* HC1 encoding and ttl */ + { + /* HC1 encoding and ttl */ - hc1[SIXLOWPAN_HC1_ENCODING] = 0xfe; - hc1[SIXLOWPAN_HC1_TTL] = ipv6->ttl; - g_frame_hdrlen += SIXLOWPAN_HC1_HDR_LEN; + hc1[SIXLOWPAN_HC1_ENCODING] = 0xfe; + hc1[SIXLOWPAN_HC1_TTL] = ipv6->ttl; + g_frame_hdrlen += SIXLOWPAN_HC1_HDR_LEN; + } break; -#endif /* CONFIG_NET_TCP */ - -#if CONFIG_NET_UDP +#endif +#ifdef CONFIG_NET_UDP case IP_PROTO_UDP: { FAR struct udp_hdr_s *udp = @@ -190,7 +233,7 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee, * 15 */ - ninfo("local/remote port %u/%u\n", udp->srcport, udp->destport); + ninfo("local/remote port %04x/%04x\n", udp->srcport, udp->destport); if (ntohs(udp->srcport) >= CONFIG_NET_6LOWPAN_MINPORT && ntohs(udp->srcport) < (CONFIG_NET_6LOWPAN_MINPORT + 16) && @@ -213,8 +256,8 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee, memcpy(&hcudp[SIXLOWPAN_HC1_HC_UDP_CHKSUM], &udp->udpchksum, 2); - g_frame_hdrlen += SIXLOWPAN_HC1_HC_UDP_HDR_LEN; - g_uncomp_hdrlen += UDP_HDRLEN; + g_frame_hdrlen += SIXLOWPAN_HC1_HC_UDP_HDR_LEN; + g_uncomp_hdrlen += UDP_HDRLEN; } else { @@ -222,13 +265,26 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee, hc1[SIXLOWPAN_HC1_ENCODING] = 0xfa; hc1[SIXLOWPAN_HC1_TTL] = ipv6->ttl; - g_frame_hdrlen += SIXLOWPAN_HC1_HDR_LEN; + g_frame_hdrlen += SIXLOWPAN_HC1_HDR_LEN; } + + ret = COMPRESS_HDR_ELIDED; } break; #endif /* CONFIG_NET_UDP */ + + default: + { + /* Test above assures that this will never happen */ + + nerr("ERROR: Unhandled protocol\n"); + DEBUGPANIC(); + } + break; } } + + return ret; } /**************************************************************************** @@ -244,6 +300,7 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee, * are set to the appropriate values * * Input Parameters: + * ind - MAC header meta data including node addressing information. * 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. @@ -258,18 +315,23 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee, * ****************************************************************************/ -int sixlowpan_uncompresshdr_hc1(uint16_t iplen, FAR struct iob_s *iob, +int sixlowpan_uncompresshdr_hc1(FAR const struct ieee802154_data_ind_s *ind, + uint16_t iplen, FAR struct iob_s *iob, FAR uint8_t *fptr, FAR uint8_t *bptr) { FAR struct ipv6_hdr_s *ipv6 = (FAR struct ipv6_hdr_s *)bptr; FAR uint8_t *hc1 = fptr + g_frame_hdrlen; - /* Format the IPv6 header in the device d_buf */ - /* Set version, traffic clase, and flow label */ + ninfo("fptr=%p g_frame_hdrlen=%u\n", fptr, g_frame_hdrlen); - ipv6->vtc = 0x60; /* Bits 0-3: version, bits 4-7: traffic class (MS) */ - ipv6->tcf = 0; /* Bits 0-3: traffic class (LS), 4-bits: flow label (MS) */ - ipv6->flow = 0; /* 16-bit flow label (LS) */ + /* Format the IPv6 header in the device d_buf */ + /* Set version, traffic clase, and flow label. This assumes that Bit 4 is + * set in HC1. + */ + + ipv6->vtc = 0x60; /* Bits 0-3: version, bits 4-7: traffic class (MS) */ + ipv6->tcf = 0; /* Bits 0-3: traffic class (LS), 4-bits: flow label (MS) */ + ipv6->flow = 0; /* 16-bit flow label (LS) */ g_uncomp_hdrlen += IPv6_HDRLEN; @@ -277,27 +339,30 @@ int sixlowpan_uncompresshdr_hc1(uint16_t iplen, FAR struct iob_s *iob, switch (hc1[SIXLOWPAN_HC1_ENCODING] & 0x06) { - case SIXLOWPAN_HC1_NH_ICMP6: +#ifdef CONFIG_NET_ICMPv6 + case SIXLOWPAN_HC1_NH_ICMPv6: ipv6->proto = IP_PROTO_ICMP6; ipv6->ttl = hc1[SIXLOWPAN_HC1_TTL]; g_frame_hdrlen += SIXLOWPAN_HC1_HDR_LEN; break; - -#if CONFIG_NET_TCP +#endif +#ifdef CONFIG_NET_TCP case SIXLOWPAN_HC1_NH_TCP: ipv6->proto = IP_PROTO_TCP; ipv6->ttl = hc1[SIXLOWPAN_HC1_TTL]; g_frame_hdrlen += SIXLOWPAN_HC1_HDR_LEN; break; -#endif /* CONFIG_NET_TCP */ - -#if CONFIG_NET_UDP +#endif +#ifdef CONFIG_NET_UDP case SIXLOWPAN_HC1_NH_UDP: { FAR struct udp_hdr_s *udp = (FAR struct udp_hdr_s *)(bptr + IPv6_HDRLEN); FAR uint8_t *hcudp = fptr + g_frame_hdrlen; ipv6->proto = IP_PROTO_UDP; + + /* Check for HC_UDP encoding */ + if ((hcudp[SIXLOWPAN_HC1_HC_UDP_HC1_ENCODING] & 0x01) != 0) { /* UDP header is compressed with HC_UDP */ @@ -320,6 +385,8 @@ int sixlowpan_uncompresshdr_hc1(uint16_t iplen, FAR struct iob_s *iob, udp->destport = htons(CONFIG_NET_6LOWPAN_MINPORT + (hcudp[SIXLOWPAN_HC1_HC_UDP_PORTS] & 0x0F)); + ninfo("UDP srcport=%04x destport=%04x\n", udp->srcport, udp->destport); + memcpy(&udp->udpchksum, &hcudp[SIXLOWPAN_HC1_HC_UDP_CHKSUM], 2); g_uncomp_hdrlen += UDP_HDRLEN; @@ -337,6 +404,46 @@ int sixlowpan_uncompresshdr_hc1(uint16_t iplen, FAR struct iob_s *iob, return -EPROTONOSUPPORT; } + /* Re-create the link-local, mac-based IP address from src/dest node + * addresses. + * + * PC: Prefix compressed (link-local prefix assumed) + * IC: Interface identifier elided (derivable from the corresponding + * link-layer address). + */ + + if ((hc1[SIXLOWPAN_HC1_ENCODING] & SIXLOWPAN_HC1_SRCADDR_MASK) == + SIXLOWPAN_HC1_SRCADDR_PCIC) + { + sixlowpan_uncompress_addr(&ind->src, ipv6->srcipaddr); + } + else + { + nwarn("HC1 srcipaddr encoding not supported: %02x\n", + hc1[SIXLOWPAN_HC1_ENCODING]); + } + + ninfo("srcipaddr=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", + ipv6->srcipaddr[0], ipv6->srcipaddr[1], ipv6->srcipaddr[2], + ipv6->srcipaddr[3], ipv6->srcipaddr[4], ipv6->srcipaddr[5], + ipv6->srcipaddr[6], ipv6->srcipaddr[7]); + + if ((hc1[SIXLOWPAN_HC1_ENCODING] & SIXLOWPAN_HC1_DESTADDR_MASK) == + SIXLOWPAN_HC1_DESTADDR_PCIC) + { + sixlowpan_uncompress_addr(&ind->dest, ipv6->destipaddr); + } + else + { + nwarn("HC1 destipaddr encoding not supported: %02x\n", + hc1[SIXLOWPAN_HC1_ENCODING]); + } + + ninfo("destipaddr=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", + ipv6->destipaddr[0], ipv6->destipaddr[1], ipv6->destipaddr[2], + ipv6->destipaddr[3], ipv6->destipaddr[4], ipv6->destipaddr[5], + ipv6->destipaddr[6], ipv6->destipaddr[7]); + /* IP length field. */ if (iplen == 0) @@ -355,13 +462,17 @@ int sixlowpan_uncompresshdr_hc1(uint16_t iplen, FAR struct iob_s *iob, ipv6->len[1] = (iplen - IPv6_HDRLEN) & 0x00FF; } -#if CONFIG_NET_UDP + ninfo("IPv6 len=%02x:%02x\n", ipv6->len[0], ipv6->len[1]); + +#ifdef CONFIG_NET_UDP /* Length field in UDP header */ if (ipv6->proto == IP_PROTO_UDP) { FAR struct udp_hdr_s *udp = (FAR struct udp_hdr_s *)(bptr + IPv6_HDRLEN); memcpy(&udp->udplen, &ipv6->len[0], 2); + + ninfo("IPv6 len=%04x\n", udp->udplen); } #endif diff --git a/net/sixlowpan/sixlowpan_input.c b/net/sixlowpan/sixlowpan_input.c index 9f1490bce2..d9074fab27 100644 --- a/net/sixlowpan/sixlowpan_input.c +++ b/net/sixlowpan/sixlowpan_input.c @@ -98,7 +98,7 @@ #elif defined(CONFIG_NET_UDP) /* The UDP header length is always 8 bytes */ -# define UNCOMP_MAXHDR (IPv6_HDRLEN + TCP_HDRLEN) +# define UNCOMP_MAXHDR (IPv6_HDRLEN + UDP_HDRLEN) #elif defined(CONFIG_NET_ICMPv6) /* The ICMPv6 header length is a mere 4 bytes */ @@ -227,7 +227,8 @@ static void sixlowpan_uncompress_ipv6hdr(FAR uint8_t *fptr, FAR uint8_t *bptr) #ifdef CONFIG_NET_TCP case IP_PROTO_TCP: { - FAR struct tcp_hdr_s *tcp = &((FAR struct ipv6tcp_hdr_s *)ipv6)->tcp; + FAR struct tcp_hdr_s *tcp = + (FAR struct tcp_hdr_s *)(fptr + g_frame_hdrlen); /* The TCP header length is encoded in the top 4 bits of the * tcpoffset field (in units of 32-bit words). @@ -289,7 +290,13 @@ static void sixlowpan_uncompress_ipv6hdr(FAR uint8_t *fptr, FAR uint8_t *bptr) * iob - The IOB containing the frame. * * Returned Value: - * Ok is returned on success; Othewise a negated errno value is returned. + * On success, a value greater than equal to zero is returned, either: + * + * INPUT_PARTIAL Frame processed successful, packet incomplete + * INPUT_COMPLETE Frame processed successful, packet complete + * + * Othewise a negated errno value is returned to indicate the nature of the + * failure. * * Assumptions: * Network is locked @@ -323,11 +330,8 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee, fptr = iob->io_data; /* Frame data is in I/O buffer */ hdrsize = iob->io_offset; /* Offset past the MAC header */ - if (hdrsize < 0) - { - nwarn("Invalid IEEE802.15.2 header: %d\n", hdrsize); - return hdrsize; - } + + DEBUGASSERT((unsigned)hdrsize < iob->io_len); /* Initialize global data. Locking the network guarantees that we have * exclusive use of the global values for intermediate calculations. @@ -343,7 +347,7 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee, */ fragptr = fptr + hdrsize; - switch ((GETHOST16(fragptr, SIXLOWPAN_FRAG_DISPATCH_SIZE) & 0xf800) >> 8) + switch ((GETUINT16(fragptr, SIXLOWPAN_FRAG_DISPATCH_SIZE) & 0xf800) >> 8) { /* First fragment of new reassembly */ @@ -351,8 +355,8 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee, { /* Set up for the reassembly */ - fragsize = GETHOST16(fragptr, SIXLOWPAN_FRAG_DISPATCH_SIZE) & 0x07ff; - fragtag = GETHOST16(fragptr, SIXLOWPAN_FRAG_TAG); + fragsize = GETUINT16(fragptr, SIXLOWPAN_FRAG_DISPATCH_SIZE) & 0x07ff; + fragtag = GETUINT16(fragptr, SIXLOWPAN_FRAG_TAG); g_frame_hdrlen += SIXLOWPAN_FRAG1_HDR_LEN; ninfo("FRAG1: fragsize=%d fragtag=%d fragoffset=%d\n", @@ -370,8 +374,8 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee, /* Set offset, tag, size. Offset is in units of 8 bytes. */ fragoffset = fragptr[SIXLOWPAN_FRAG_OFFSET]; - fragtag = GETHOST16(fragptr, SIXLOWPAN_FRAG_TAG); - fragsize = GETHOST16(fragptr, SIXLOWPAN_FRAG_DISPATCH_SIZE) & 0x07ff; + fragtag = GETUINT16(fragptr, SIXLOWPAN_FRAG_TAG); + fragsize = GETUINT16(fragptr, SIXLOWPAN_FRAG_DISPATCH_SIZE) & 0x07ff; g_frame_hdrlen += SIXLOWPAN_FRAGN_HDR_LEN; ninfo("FRAGN: fragsize=%d fragtag=%d fragoffset=%d\n", @@ -462,7 +466,7 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee, nwarn("WARNING: Dropping 6LoWPAN packet that is not a fragment of " "the packet currently being reassembled\n"); - return INPUT_PARTIAL; + return -EPERM; } else { @@ -488,7 +492,7 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee, if (!isfirstfrag) { nwarn("WARNING: FRAGN 6LoWPAN fragment while not reassembling\n"); - return OK; + return -EPERM; } /* Drop the packet if it cannot fit into the d_buf */ @@ -496,7 +500,7 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee, if (fragsize > CONFIG_NET_6LOWPAN_MTU) { nwarn("WARNING: Reassembled packet size exeeds CONFIG_NET_6LOWPAN_MTU\n"); - return OK; + return -ENOSPC; } ieee->i_pktlen = fragsize; @@ -532,7 +536,7 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee, if ((hc1[SIXLOWPAN_HC1_DISPATCH] & SIXLOWPAN_DISPATCH_IPHC_MASK) == SIXLOWPAN_DISPATCH_IPHC) { ninfo("IPHC Dispatch\n"); - sixlowpan_uncompresshdr_hc06(fragsize, iob, fptr, bptr); + sixlowpan_uncompresshdr_hc06(ind, fragsize, iob, fptr, bptr); } else #endif /* CONFIG_NET_6LOWPAN_COMPRESSION_HC06 */ @@ -541,7 +545,7 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee, if (hc1[SIXLOWPAN_HC1_DISPATCH] == SIXLOWPAN_DISPATCH_HC1) { ninfo("HC1 Dispatch\n"); - sixlowpan_uncompresshdr_hc1(fragsize, iob, fptr, bptr); + sixlowpan_uncompresshdr_hc1(ind, fragsize, iob, fptr, bptr); } else #endif /* CONFIG_NET_6LOWPAN_COMPRESSION_HC1 */ @@ -556,7 +560,7 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee, /* Unknown or unsupported header */ nwarn("WARNING: Unknown dispatch: %u\n", hc1[SIXLOWPAN_HC1_DISPATCH]); - return OK; + return -ENOSYS; } #ifdef CONFIG_NET_6LOWPAN_FRAG @@ -581,9 +585,6 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee, g_uncomp_hdrlen = ieee->i_boffset; } - - - #endif /* CONFIG_NET_6LOWPAN_FRAG */ /* Copy "payload" from the frame buffer to the IEEE802.15.4 MAC driver's @@ -597,7 +598,7 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee, { nwarn("WARNING: Packet dropped due to payload (%u) > packet buffer (%u)\n", paysize, CONFIG_NET_6LOWPAN_MTU); - return OK; + return -ENOSPC; } /* Sanity-check size of incoming packet to avoid buffer overflow */ @@ -689,7 +690,7 @@ static int sixlowpan_dispatch(FAR struct ieee802154_driver_s *ieee) /* We only accept IPv6 packets. */ - ninfo("Iv6 packet dispatch\n"); + ninfo("IPv6 packet dispatch\n"); NETDEV_RXIPV6(&ieee->i_dev); /* Give the IPv6 packet to the network layer. NOTE: If there is a @@ -835,32 +836,44 @@ int sixlowpan_input(FAR struct ieee802154_driver_s *ieee, * the protocol header. */ - if (ipv6hdr->proto != IP_PROTO_TCP) + switch (ipv6hdr->proto) { - FAR struct tcp_hdr_s *tcp = TCPBUF(&ieee->i_dev); - uint16_t tcplen; +#ifdef CONFIG_NET_TCP + case IP_PROTO_TCP: + { + FAR struct tcp_hdr_s *tcp = TCPBUF(&ieee->i_dev); + uint16_t tcplen; - /* The TCP header length is encoded in the top 4 bits - * of the tcpoffset field (in units of 32-bit words). - */ + /* The TCP header length is encoded in the top 4 bits + * of the tcpoffset field (in units of 32-bit words). + */ - tcplen = ((uint16_t)tcp->tcpoffset >> 4) << 2; - hdrlen = IPv6_HDRLEN + tcplen; - } - else if (ipv6hdr->proto != IP_PROTO_UDP) - { - hdrlen = IPv6_HDRLEN + UDP_HDRLEN; - } - else if (ipv6hdr->proto != IP_PROTO_ICMP6) - { - hdrlen = IPv6_HDRLEN + ICMPv6_HDRLEN; - } - else - { - nwarn("WARNING: Unsupported protoype: %u\n", - ipv6hdr->proto); - ret = -EPROTO; - goto drop; + tcplen = ((uint16_t)tcp->tcpoffset >> 4) << 2; + hdrlen = IPv6_HDRLEN + tcplen; + } + break; +#endif +#ifdef CONFIG_NET_UDP + case IP_PROTO_UDP: + { + hdrlen = IPv6_HDRLEN + UDP_HDRLEN; + } + break; +#endif +#ifdef CONFIG_NET_ICMPv6 + case IP_PROTO_ICMP6: + { + hdrlen = IPv6_HDRLEN + ICMPv6_HDRLEN; + } + break; +#endif + default: + { + nwarn("WARNING: Unsupported protoype: %u\n", + ipv6hdr->proto); + ret = -EPROTO; + goto drop; + } } if (hdrlen < ieee->i_dev.d_len) diff --git a/net/sixlowpan/sixlowpan_internal.h b/net/sixlowpan/sixlowpan_internal.h index 397f2863a9..0c94d05dba 100644 --- a/net/sixlowpan/sixlowpan_internal.h +++ b/net/sixlowpan/sixlowpan_internal.h @@ -58,7 +58,9 @@ ****************************************************************************/ #include + #include +#include #include #include @@ -102,16 +104,11 @@ /* General helper macros ****************************************************/ -/* GET 16-bit data: source in network order, result in host order */ +/* GET 16-bit data: source in network order */ -#define GETHOST16(ptr,index) \ +#define GETUINT16(ptr,index) \ ((((uint16_t)((ptr)[index])) << 8) | ((uint16_t)(((ptr)[(index) + 1])))) -/* GET 16-bit data: source in network order, result in network order */ - -#define GETNET16(ptr,index) \ - ((((uint16_t)((ptr)[(index) + 1])) << 8) | ((uint16_t)(((ptr)[index])))) - /* PUT 16-bit data: source in host order, result in newtwork order */ #define PUTHOST16(ptr,index,value) \ @@ -122,6 +119,13 @@ } \ while(0) +/* Return values ************************************************************/ + +/* Sucessful return values from header compression logic */ + +#define COMPRESS_HDR_INLINE 0 /* L2 header not compressed */ +#define COMPRESS_HDR_ELIDED 1 /* L2 header compressed */ + /* Debug ********************************************************************/ #ifdef CONFIG_NET_6LOWPAN_DUMPBUFFER @@ -231,9 +235,9 @@ struct iob_s; /* Forward reference */ * Name: sixlowpan_send * * Description: - * Process an outgoing UDP or TCP packet. Takes an IP packet and formats + * Process an outgoing UDP or ICMPv6 packet. Takes an IP packet and formats * it to be sent on an 802.15.4 network using 6lowpan. Called from common - * UDP/TCP send logic. + * UDP/ICMPv6 send logic. * * The payload data is in the caller 'buf' and is of length 'buflen'. * Compressed headers will be added and if necessary the packet is @@ -243,16 +247,16 @@ struct iob_s; /* Forward reference */ * Input Parameters: * dev - The IEEE802.15.4 MAC network driver interface. * list - Head of callback list for send interrupt - * ipv6hdr - IPv6 plus TCP or UDP headers. + * ipv6hdr - IPv6 header followed by UDP or ICMPv6 header. * buf - Data to send * len - Length of data to send - * raddr - The MAC address of the destination + * destmac - The IEEE802.15.4 MAC address of the destination * timeout - Send timeout in deciseconds * * 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 + * MAC network driver. In that case, the logic will fall back to normal * IPv4/IPv6 formatting. * * Assumptions: @@ -421,15 +425,16 @@ void sixlowpan_hc06_initialize(void); * fptr - Pointer to frame to be compressed. * * Returned Value: - * None + * On success the indications of the defines COMPRESS_HDR_* are returned. + * A negated errno value is returned on failure. * ****************************************************************************/ #ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06 -void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, - FAR const struct ipv6_hdr_s *ipv6, - FAR const struct sixlowpan_tagaddr_s *destmac, - FAR uint8_t *fptr); +int sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, + FAR const struct ipv6_hdr_s *ipv6, + FAR const struct sixlowpan_tagaddr_s *destmac, + FAR uint8_t *fptr); #endif /**************************************************************************** @@ -446,13 +451,14 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, * appropriate values * * Input Parmeters: - * 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 first - * fragment. - * iob - Pointer to the IOB containing the received frame. - * fptr - Pointer to frame to be compressed. - * bptr - Output goes here. Normally this is a known offset into d_buf, - * may be redirected to a "bitbucket" on the case of FRAGN frames. + * ind - MAC header meta data including node addressing information. + * 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 first + * fragment. + * iob - Pointer to the IOB containing the received frame. + * fptr - Pointer to frame to be compressed. + * bptr - Output goes here. Normally this is a known offset into d_buf, + * may be redirected to a "bitbucket" on the case of FRAGN frames. * * Returned Value: * None @@ -460,7 +466,8 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, ****************************************************************************/ #ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06 -void sixlowpan_uncompresshdr_hc06(uint16_t iplen, FAR struct iob_s *iob, +void sixlowpan_uncompresshdr_hc06(FAR const struct ieee802154_data_ind_s *ind, + uint16_t iplen, FAR struct iob_s *iob, FAR uint8_t *fptr, FAR uint8_t *bptr); #endif @@ -482,15 +489,16 @@ void sixlowpan_uncompresshdr_hc06(uint16_t iplen, FAR struct iob_s *iob, * fptr - Pointer to frame to be compressed. * * Returned Value: - * None + * On success the indications of the defines COMPRESS_HDR_* are returned. + * A negated errno value is returned on failure. * ****************************************************************************/ #ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC1 -void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee, - FAR const struct ipv6_hdr_s *ipv6, - FAR const struct sixlowpan_tagaddr_s *destmac, - FAR uint8_t *fptr); +int sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee, + FAR const struct ipv6_hdr_s *ipv6, + FAR const struct sixlowpan_tagaddr_s *destmac, + FAR uint8_t *fptr); #endif /**************************************************************************** @@ -506,6 +514,7 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee, * are set to the appropriate values * * Input Parameters: + * ind - MAC header meta data including node addressing information. * 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. @@ -521,7 +530,8 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee, ****************************************************************************/ #ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC1 -int sixlowpan_uncompresshdr_hc1(uint16_t iplen, FAR struct iob_s *iob, +int sixlowpan_uncompresshdr_hc1(FAR const struct ieee802154_data_ind_s *ind, + uint16_t iplen, FAR struct iob_s *iob, FAR uint8_t *fptr, FAR uint8_t *bptr); #endif @@ -530,11 +540,14 @@ int sixlowpan_uncompresshdr_hc1(uint16_t iplen, FAR struct iob_s *iob, * sixlowpan_ismacbased * * Description: - * sixlowpan_addrfromip(): Extract the IEEE 802.15.14 address from a MAC - * based IPv6 address. sixlowpan_addrfromip() is intended to handle a - * tagged address or any size; sixlowpan_saddrfromip() and - * sixlowpan_eaddrfromip() specifically handle short and extended - * addresses. + * sixlowpan_{s|e]addrfromip(): Extract the IEEE 802.15.14 address from a + * MAC-based IPv6 address. sixlowpan_addrfromip() is intended to handle a + * tagged address; sixlowpan_saddrfromip() and sixlowpan_eaddrfromip() + * specifically handle short and extended addresses, respectively. + * + * sixlowpan_ipfrom[s|e]addr(): Create a link-local, MAC-based IPv6 + * address from an IEEE802.15.4 short address (saddr) or extended address + * (eaddr). * * sixlowpan_islinklocal() and sixlowpan_ismacbased() will return true for * address created in this fashion. sixlowpan_addrfromip() is intended to @@ -553,12 +566,17 @@ int sixlowpan_uncompresshdr_hc1(uint16_t iplen, FAR struct iob_s *iob, #define sixlowpan_islinklocal(ipaddr) ((ipaddr)[0] == NTOHS(0xfe80)) void sixlowpan_saddrfromip(const net_ipv6addr_t ipaddr, - FAR struct sixlowpan_saddr_s *saddr); + FAR struct sixlowpan_saddr_s *saddr); void sixlowpan_eaddrfromip(const net_ipv6addr_t ipaddr, - FAR struct sixlowpan_eaddr_s *eaddr); + FAR struct sixlowpan_eaddr_s *eaddr); void sixlowpan_addrfromip(const net_ipv6addr_t ipaddr, FAR struct sixlowpan_tagaddr_s *addr); +void sixlowpan_ipfromsaddr(FAR const uint8_t *saddr, + FAR net_ipv6addr_t ipaddr); +void sixlowpan_ipfromeaddr(FAR const uint8_t *eaddr, + FAR net_ipv6addr_t ipaddr); + bool sixlowpan_issaddrbased(const net_ipv6addr_t ipaddr, FAR const struct sixlowpan_saddr_s *saddr); bool sixlowpan_iseaddrbased(const net_ipv6addr_t ipaddr, diff --git a/net/sixlowpan/sixlowpan_send.c b/net/sixlowpan/sixlowpan_send.c index a8fcdea983..527e2f5277 100644 --- a/net/sixlowpan/sixlowpan_send.c +++ b/net/sixlowpan/sixlowpan_send.c @@ -82,7 +82,7 @@ struct sixlowpan_send_s int s_result; /* The result of the transfer */ uint16_t s_timeout; /* Send timeout in deciseconds */ systime_t s_time; /* Last send time for determining timeout */ - FAR const struct ipv6_hdr_s *s_ipv6hdr; /* IPv6 header, followed by UDP or TCP header. */ + FAR const struct ipv6_hdr_s *s_ipv6hdr; /* IPv6 header, followed by UDP or ICMP header. */ FAR const struct sixlowpan_tagaddr_s *s_destmac; /* Destination MAC address */ FAR const void *s_buf; /* Data to send */ size_t s_len; /* Length of data in buf */ @@ -182,7 +182,7 @@ static uint16_t send_interrupt(FAR struct net_driver_s *dev, if ((flags & NETDEV_DOWN) != 0) { - ninfo("Device is down\n"); + nwarn("WARNING: Device is down\n"); sinfo->s_result = -ENOTCONN; goto end_wait; } @@ -242,9 +242,9 @@ end_wait: * Name: sixlowpan_send * * Description: - * Process an outgoing UDP or TCP packet. Takes an IP packet and formats + * Process an outgoing UDP or ICMPv6 packet. Takes an IP packet and formats * it to be sent on an 802.15.4 network using 6lowpan. Called from common - * UDP/TCP send logic. + * UDP/ICMPv6 send logic. * * The payload data is in the caller 'buf' and is of length 'buflen'. * Compressed headers will be added and if necessary the packet is @@ -254,7 +254,7 @@ end_wait: * Input Parameters: * dev - The IEEE802.15.4 MAC network driver interface. * list - Head of callback list for send interrupt - * ipv6hdr - IPv6 header followed by TCP or UDP header. + * ipv6hdr - IPv6 header followed by UDP or ICMPv6 header. * buf - Data to send * len - Length of data to send * destmac - The IEEE802.15.4 MAC address of the destination @@ -263,7 +263,7 @@ end_wait: * 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 + * MAC network driver. In that case, the logic will fall back to normal * IPv4/IPv6 formatting. * * Assumptions: @@ -279,6 +279,8 @@ int sixlowpan_send(FAR struct net_driver_s *dev, { struct sixlowpan_send_s sinfo; + ninfo("len=%lu timeout=%u\n", (unsigned long)len, timeout); + /* Initialize the send state structure */ sem_init(&sinfo.s_waitsem, 0, 0); @@ -301,16 +303,16 @@ int sixlowpan_send(FAR struct net_driver_s *dev, * device related events, no connect-related events. */ - sinfo.s_cb = devif_callback_alloc(dev, list); + sinfo.s_cb = devif_callback_alloc(dev, list); if (sinfo.s_cb != NULL) { int ret; /* Set up the callback in the connection */ - sinfo.s_cb->flags = (NETDEV_DOWN | WPAN_POLL); - sinfo.s_cb->priv = (FAR void *)&sinfo; - sinfo.s_cb->event = send_interrupt; + sinfo.s_cb->flags = (NETDEV_DOWN | WPAN_POLL); + sinfo.s_cb->priv = (FAR void *)&sinfo; + sinfo.s_cb->event = send_interrupt; /* Notify the IEEE802.15.4 MAC that we have data to send. */ @@ -322,6 +324,8 @@ int sixlowpan_send(FAR struct net_driver_s *dev, * automatically re-enabled when the task restarts. */ + ninfo("Wait for send complete\n"); + ret = net_lockedwait(&sinfo.s_waitsem); if (ret < 0) { diff --git a/net/sixlowpan/sixlowpan_tcpsend.c b/net/sixlowpan/sixlowpan_tcpsend.c index 7ce5064b89..4e3701e6fe 100644 --- a/net/sixlowpan/sixlowpan_tcpsend.c +++ b/net/sixlowpan/sixlowpan_tcpsend.c @@ -44,10 +44,12 @@ #include #include +#include "nuttx/semaphore.h" #include "nuttx/net/netdev.h" #include "nuttx/net/netstats.h" #include "netdev/netdev.h" +#include "devif/devif.h" #include "socket/socket.h" #include "tcp/tcp.h" #include "utils/utils.h" @@ -62,6 +64,43 @@ /* Buffer access helpers */ #define IPv6BUF(dev) ((FAR struct ipv6_hdr_s *)((dev)->d_buf)) +#define TCPBUF(dev) ((FAR struct tcp_hdr_s *)(&(dev)->d_buf[IPv6_HDRLEN])) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* These are temporary stubs. Something like this would be needed to + * monitor the health of a IPv6 neighbor. + */ + +#define neighbor_reachable(dev) +#define neighbor_notreachable(dev) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This is the state data provided to the send interrupt logic. No actions + * can be taken until the until we receive the TX poll, then we can call + * sixlowpan_queue_frames() with this data strurcture. + */ + +struct sixlowpan_send_s +{ + FAR struct socket *s_sock; /* Internal socket reference */ + FAR struct devif_callback_s *s_cb; /* Reference to callback instance */ + sem_t s_waitsem; /* Supports waiting for driver events */ + int s_result; /* The result of the transfer */ + uint16_t s_timeout; /* Send timeout in deciseconds */ + systime_t s_time; /* Last send time for determining timeout */ + FAR const struct sixlowpan_tagaddr_s *s_destmac; /* Destination MAC address */ + FAR const uint8_t *s_buf; /* Data to send */ + size_t s_buflen; /* Length of data in buf */ + ssize_t s_sent; /* The number of bytes sent */ + uint32_t s_isn; /* Initial sequence number */ + uint32_t s_acked; /* The number of bytes acked */ +}; /**************************************************************************** * Private Functions @@ -84,7 +123,7 @@ * ****************************************************************************/ -static uint16_t sixlowpan_tcp_chksum(FAR struct ipv6tcp_hdr_s *ipv6tcp, +static uint16_t sixlowpan_tcp_chksum(FAR const struct ipv6tcp_hdr_s *ipv6tcp, FAR const uint8_t *buf, uint16_t buflen) { uint16_t upperlen; @@ -131,6 +170,558 @@ static uint16_t sixlowpan_tcp_chksum(FAR struct ipv6tcp_hdr_s *ipv6tcp, return (sum == 0) ? 0xffff : htons(sum); } +/**************************************************************************** + * Name: sixlowpan_tcp_header + * + * Description: + * sixlowpan_tcp_header() will construct the IPv6 and TCP headers + * + * Parameters: + * conn - An instance of the TCP connection structure. + * dev - The network device that will route the packet + * buf - Data to send + * bulen - Length of data to send + * ipv6tcp - The location to save the IPv6 + TCP header + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * failure. + * + * Assumptions: + * Called with the network locked. + * + ****************************************************************************/ + +static int sixlowpan_tcp_header(FAR struct tcp_conn_s *conn, + FAR struct net_driver_s *dev, + FAR const void *buf, size_t buflen, + FAR struct ipv6tcp_hdr_s *ipv6tcp) +{ + uint16_t iplen; + + /* Initialize the IPv6/TCP headers */ + + ipv6tcp->ipv6.vtc = 0x60; + ipv6tcp->ipv6.tcf = 0x00; + ipv6tcp->ipv6.flow = 0x00; + ipv6tcp->ipv6.proto = IP_PROTO_TCP; + ipv6tcp->ipv6.ttl = IP_TTL; + + /* The IPv6 header length field does not include the size of IPv6 IP + * header. + */ + + iplen = buflen + TCP_HDRLEN; + ipv6tcp->ipv6.len[0] = (iplen >> 8); + ipv6tcp->ipv6.len[1] = (iplen & 0xff); + + /* Copy the source and destination addresses */ + + net_ipv6addr_hdrcopy(ipv6tcp->ipv6.destipaddr, conn->u.ipv6.raddr); +#ifdef CONFIG_NETDEV_MULTINIC + if (!net_ipv6addr_cmp(conn->u.ipv6.laddr, g_ipv6_allzeroaddr)) + { + net_ipv6addr_hdrcopy(ipv6tcp->ipv6.srcipaddr, conn->u.ipv6.laddr); + } + else +#endif + { + net_ipv6addr_hdrcopy(ipv6tcp->ipv6.srcipaddr, dev->d_ipv6addr); + } + + ninfo("IPv6 length: %d\n", + ((int)ipv6tcp->ipv6.len[0] << 8) + ipv6tcp->ipv6.len[1]); + +#ifdef CONFIG_NET_STATISTICS + g_netstats.ipv6.sent++; +#endif + + /* Initialize the TCP header */ + + ipv6tcp->tcp.srcport = conn->lport; /* Local port */ + ipv6tcp->tcp.destport = conn->rport; /* Connected remote port */ + + ipv6tcp->tcp.tcpoffset = (TCP_HDRLEN / 4) << 4; /* No optdata */ + ipv6tcp->tcp.flags = 0; /* No urgent data */ + ipv6tcp->tcp.urgp[0] = 0; /* No urgent data */ + ipv6tcp->tcp.urgp[1] = 0; + + /* Set the sequency number information */ + /* REVISIT: There is currently no wait for the data to be ACKed and, + * hence, no mechanism to retransmit the packet. + */ + + memcpy(ipv6tcp->tcp.ackno, conn->rcvseq, 4); /* ACK number */ + memcpy(ipv6tcp->tcp.seqno, conn->sndseq, 4); /* Sequence number */ + + /* Set the TCP window */ + + if (conn->tcpstateflags & TCP_STOPPED) + { + /* If the connection has issued TCP_STOPPED, we advertise a zero + * window so that the remote host will stop sending data. + */ + + ipv6tcp->tcp.wnd[0] = 0; + ipv6tcp->tcp.wnd[1] = 0; + } + else + { + ipv6tcp->tcp.wnd[0] = ((NET_DEV_RCVWNDO(dev)) >> 8); + ipv6tcp->tcp.wnd[1] = ((NET_DEV_RCVWNDO(dev)) & 0xff); + } + + /* Calculate TCP checksum. */ + + ipv6tcp->tcp.tcpchksum = 0; + ipv6tcp->tcp.tcpchksum = ~sixlowpan_tcp_chksum(ipv6tcp, buf, buflen); + + ninfo("Outgoing TCP packet length: %d bytes\n", iplen + IPv6_HDRLEN); + return OK; +} + +/**************************************************************************** + * Name: send_timeout + * + * Description: + * Check for send timeout. + * + * Input Parameters: + * sinfo - Send state structure reference + * + * Returned Value: + * TRUE:timeout FALSE:no timeout + * + * Assumptions: + * The network is locked + * + ****************************************************************************/ + +static inline bool send_timeout(FAR struct sixlowpan_send_s *sinfo) +{ + /* Check for a timeout. Zero means none and, in that case, we will let + * the send wait forever. + */ + + if (sinfo->s_timeout != 0) + { + /* Check if the configured timeout has elapsed */ + + systime_t timeo_ticks = DSEC2TICK(sinfo->s_timeout); + systime_t elapsed = clock_systimer() - sinfo->s_time; + + if (elapsed >= timeo_ticks) + { + return true; + } + } + + /* No timeout */ + + return false; +} + +/**************************************************************************** + * Name: tcp_send_interrupt + * + * Description: + * This function is called from the interrupt level to perform the actual + * TCP send operation when polled by the lower, device interfacing layer. + * + * Parameters: + * dev - The structure of the network driver that caused the interrupt + * pvconn - The connection structure associated with the socket + * pvpriv - The interrupt handler's private data argument + * flags - Set of events describing why the callback was invoked + * + * Returned Value: + * None + * + * Assumptions: + * The network is locked. + * + ****************************************************************************/ + +static uint16_t tcp_send_interrupt(FAR struct net_driver_s *dev, + FAR void *pvconn, + FAR void *pvpriv, uint16_t flags) +{ + FAR struct sixlowpan_send_s *sinfo = (FAR struct sixlowpan_send_s *)pvpriv; + FAR struct tcp_conn_s *conn = (FAR struct tcp_conn_s *)pvconn; + struct ipv6tcp_hdr_s ipv6tcp; + int ret; + +#ifdef CONFIG_NET_MULTILINK + /* Verify that this is an IEEE802.15.4 network driver. */ + + if (dev->d_lltype != NET_LL_IEEE802154) + { + ninfo("Not a NET_LL_IEEE802154 device\n"); + return flags; + } +#endif + +#ifdef CONFIG_NETDEV_MULTINIC + /* The TCP socket is connected and, hence, should be bound to a device. + * Make sure that the polling device is the one that we are bound to. + */ + + DEBUGASSERT(conn->dev != NULL); + if (dev != conn->dev) + { + ninfo("Not the connecte device\n"); + return flags; + } +#endif + + /* Check if the IEEE802.15.4 network driver went down */ + + if ((flags & NETDEV_DOWN) != 0) + { + nwarn("WARNING: Device is down\n"); + sinfo->s_result = -ENOTCONN; + goto end_wait; + } + + ninfo("flags: %04x acked: %u sent: %u\n", + flags, sinfo->s_acked, sinfo->s_sent); + + /* If this packet contains an acknowledgement, then update the count of + * acknowledged bytes. + */ + + if ((flags & TCP_ACKDATA) != 0) + { + FAR struct tcp_hdr_s *tcp = TCPBUF(dev); + +#ifdef CONFIG_NET_SOCKOPTS + /* Update the timeout */ + + sinfo->s_time = clock_systimer(); +#endif + + /* The current acknowledgement number number is the (relative) offset + * of the of the next byte needed by the receiver. The s_isn is the + * offset of the first byte to send to the receiver. The difference + * is the number of bytes to be acknowledged. + */ + + sinfo->s_acked = tcp_getsequence(tcp->ackno) - sinfo->s_isn; + ninfo("ACK: acked=%d sent=%d buflen=%d\n", + sinfo->s_acked, sinfo->s_sent, sinfo->s_buflen); + + /* Have all of the bytes in the buffer been sent and acknowledged? */ + + if (sinfo->s_acked >= sinfo->s_buflen) + { + /* Yes. Then sinfo->s_buflen should hold the number of bytes + * actually sent. + */ + + goto end_wait; + } + + /* No.. fall through to send more data if necessary */ + } + + /* Check if we are being asked to retransmit data */ + + else if ((flags & TCP_REXMIT) != 0) + { + /* Yes.. in this case, reset the number of bytes that have been sent + * to the number of bytes that have been ACKed. + */ + + sinfo->s_sent = sinfo->s_acked; + + /* Fall through to re-send data from the last that was ACKed */ + } + + /* Check for a loss of connection */ + + else if ((flags & TCP_DISCONN_EVENTS) != 0) + { + /* Report not connected */ + + ninfo("Lost connection\n"); + + net_lostconnection(sinfo->s_sock, flags); + sinfo->s_result = -ENOTCONN; + goto end_wait; + } + + /* Check if the outgoing packet is available (it may have been claimed + * by a sendto interrupt serving a different thread). + */ + +#if 0 /* We can't really support multiple senders on the same TCP socket */ + else if (dev->d_sndlen > 0) + { + /* Another thread has beat us sending data, wait for the next poll */ + + return flags; + } +#endif + + /* We get here if (1) not all of the data has been ACKed, (2) we have been + * asked to retransmit data, (3) the connection is still healthy, and (4) + * the outgoing packet is available for our use. In this case, we are + * now free to send more data to receiver -- UNLESS the buffer contains + * unprocessed incoming data. In that event, we will have to wait for the + * next polling cycle. + */ + + if ((flags & WPAN_NEWDATA) == 0 && sinfo->s_sent < sinfo->s_buflen) + { + uint32_t seqno; + uint16_t winleft; + uint16_t sndlen; + + /* Get the amount of TCP payload data that we can send in the next + * packet. + */ + + sndlen = sinfo->s_buflen - sinfo->s_sent; + if (sndlen > conn->mss) + { + sndlen = conn->mss; + } + + winleft = conn->winsize - sinfo->s_sent + sinfo->s_acked; + if (sndlen > winleft) + { + sndlen = winleft; + } + + ninfo("s_buflen=%u s_sent=%u mss=%u winsize=%u sndlen=%d\n", + sinfo->s_buflen, sinfo->s_sent, conn->mss, conn->winsize, sndlen); + + if (sndlen > 0) + { + /* Set the sequence number for this packet. NOTE: The network updates + * sndseq on receipt of ACK *before* this function is called. In that + * case sndseq will point to the next unacknowledged byte (which might + * have already been sent). We will overwrite the value of sndseq + * here before the packet is sent. + */ + + seqno = sinfo->s_sent + sinfo->s_isn; + ninfo("Sending: sndseq %08lx->%08x\n", + (unsigned long)tcp_getsequence(conn->sndseq), seqno); + + tcp_setsequence(conn->sndseq, seqno); + + /* Create the IPv6 + TCP header */ + + ret = sixlowpan_tcp_header(conn, dev, &sinfo->s_buf[sinfo->s_sent], + sndlen, &ipv6tcp); + if (ret < 0) + { + nerr("ERROR: sixlowpan_tcp_header failed: %d\n", ret); + sinfo->s_result = ret; + goto end_wait; + } + + /* Transfer the frame list to the IEEE802.15.4 MAC device */ + + ret = sixlowpan_queue_frames((FAR struct ieee802154_driver_s *)dev, + &ipv6tcp.ipv6, + &sinfo->s_buf[sinfo->s_sent], sndlen, + sinfo->s_destmac); + if (ret < 0) + { + nerr("ERROR: sixlowpan_queue_frames failed: %d\n", ret); + sinfo->s_result = ret; + goto end_wait; + } + + /* Increment the count of bytes sent, the number of unacked bytes, + * and the total count of TCP packets sent. + * + * NOTE: tcp_appsend() normally increments conn->unacked based on + * the value of dev->d_sndlen. However, dev->d_len is always + * zero for 6LoWPAN since it does no send via the dev->d_bufuse + * but, rather, uses a backdoor frame interface with the IEEE + * 802.15.4 MAC. + */ + + sinfo->s_sent += sndlen; + conn->unacked += sndlen; + +#ifdef CONFIG_NET_TCP_WRITE_BUFFERS + /* For compability with buffered send logic */ + + conn->sndseq_max = tcp_addsequence(conn->sndseq, conn->unacked); +#endif + +#ifdef CONFIG_NET_STATISTICS + g_netstats.tcp.sent++; +#endif + + ninfo("Sent: acked=%d sent=%d buflen=%d unacked=%d\n", + sinfo->s_acked, sinfo->s_sent, sinfo->s_buflen, + conn->unacked); + } + } + +#ifdef CONFIG_NET_SOCKOPTS + /* All data has been sent and we are just waiting for ACK or re-transmit + * indications to complete the send. Check for a timeout. + */ + + if (send_timeout(sinfo)) + { + /* Yes.. report the timeout */ + + nwarn("WARNING: SEND timeout\n"); + sinfo->s_sent = -ETIMEDOUT; + goto end_wait; + } +#endif /* CONFIG_NET_SOCKOPTS */ + + /* Continue waiting */ + + return flags; + +end_wait: + /* Do not allow any further callbacks */ + + sinfo->s_cb->flags = 0; + sinfo->s_cb->priv = NULL; + sinfo->s_cb->event = NULL; + + /* There are no outstanding, unacknowledged bytes */ + + conn->unacked = 0; + + /* Wake up the waiting thread */ + + sem_post(&sinfo->s_waitsem); + return flags; +} + +/**************************************************************************** + * Name: sixlowpan_send_packet + * + * Description: + * Process an outgoing TCP packet. Takes an IP packet and formats it to + * be sent on an 802.15.4 network using 6lowpan. Called from common TCP + * send logic. + * + * The payload data is in the caller 'buf' and is of length 'buflen'. + * Compressed headers will be added and if necessary the packet is + * fragmented. The resulting packet/fragments are submitted to the MAC + * via the network driver i_req_data method. + * + * Input Parameters: + * psock - An instance of the internal socket structure. + * dev - The IEEE802.15.4 MAC network driver interface. + * conn - TCP connection structure + * buf - Data to send + * len - Length of data to send + * destmac - The IEEE802.15.4 MAC address of the destination + * timeout - Send timeout in deciseconds + * + * 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 logic will fall back to normal + * IPv4/IPv6 formatting. + * + * Assumptions: + * Called with the network locked. + * + ****************************************************************************/ + +static int sixlowpan_send_packet(FAR struct socket *psock, + FAR struct net_driver_s *dev, + FAR struct tcp_conn_s *conn, + FAR const uint8_t *buf, size_t len, + FAR const struct sixlowpan_tagaddr_s *destmac, + uint16_t timeout) +{ + struct sixlowpan_send_s sinfo; + + ninfo("len=%lu timeout=%u\n", (unsigned long)len, timeout); + DEBUGASSERT(psock != NULL && dev != NULL && conn != NULL && buf != NULL && + destmac != NULL); + + memset(&sinfo, 0, sizeof(struct sixlowpan_send_s)); + + net_lock(); + if (len > 0) + { + /* Allocate resources to receive a callback. + * + * The second parameter is NULL meaning that we can get only + * device related events, no connect-related events. + */ + + sinfo.s_cb = tcp_callback_alloc(conn); + if (sinfo.s_cb != NULL) + { + int ret; + + /* Initialize the send state structure */ + + sem_init(&sinfo.s_waitsem, 0, 0); + (void)sem_setprotocol(&sinfo.s_waitsem, SEM_PRIO_NONE); + + sinfo.s_sock = psock; + sinfo.s_result = -EBUSY; + sinfo.s_timeout = timeout; + sinfo.s_time = clock_systimer(); + sinfo.s_destmac = destmac; + sinfo.s_buf = buf; + sinfo.s_buflen = len; + + /* Set up the initial sequence number */ + + sinfo.s_isn = tcp_getsequence(conn->sndseq); + + /* Set up the callback in the connection */ + + sinfo.s_cb->flags = (NETDEV_DOWN | TCP_ACKDATA | TCP_REXMIT | + TCP_DISCONN_EVENTS | WPAN_POLL); + sinfo.s_cb->priv = (FAR void *)&sinfo; + sinfo.s_cb->event = tcp_send_interrupt; + + /* There is no outstanding, unacknowledged data after this + * initial sequence number. + */ + + conn->unacked = 0; + + /* Notify the IEEE802.15.4 MAC that we have data to send. */ + + netdev_txnotify_dev(dev); + + /* Wait for the send to complete or an error to occur: NOTES: (1) + * net_lockedwait will also terminate if a signal is received, (2) + * interrupts may be disabled! They will be re-enabled while the + * task sleeps and automatically re-enabled when the task restarts. + */ + + ninfo("Wait for send complete\n"); + + ret = net_lockedwait(&sinfo.s_waitsem); + if (ret < 0) + { + sinfo.s_result = -get_errno(); + } + + /* Make sure that no further interrupts are processed */ + + tcp_callback_free(conn, sinfo.s_cb); + } + } + + sem_destroy(&sinfo.s_waitsem); + net_unlock(); + + return (sinfo.s_result < 0 ? sinfo.s_result : len); +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -163,10 +754,8 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf, { FAR struct tcp_conn_s *conn; FAR struct net_driver_s *dev; - struct ipv6tcp_hdr_s ipv6tcp; struct sixlowpan_tagaddr_s destmac; uint16_t timeout; - uint16_t iplen; int ret; ninfo("buflen %lu\n", (unsigned long)buflen); @@ -177,7 +766,7 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf, /* Make sure that this is a valid socket */ - if (psock != NULL || psock->s_crefs <= 0) + if (psock == NULL || psock->s_crefs <= 0) { nerr("ERROR: Invalid socket\n"); return (ssize_t)-EBADF; @@ -243,90 +832,19 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf, } #endif - /* Initialize the IPv6/TCP headers */ - - /* Initialize the IPv6/UDP headers */ - - ipv6tcp.ipv6.vtc = 0x60; - ipv6tcp.ipv6.tcf = 0x00; - ipv6tcp.ipv6.flow = 0x00; - ipv6tcp.ipv6.proto = IP_PROTO_TCP; - ipv6tcp.ipv6.ttl = IP_TTL; - - /* The IPv6 header length field does not include the size of IPv6 IP - * header. - */ - - iplen = buflen + TCP_HDRLEN; - ipv6tcp.ipv6.len[0] = (iplen >> 8); - ipv6tcp.ipv6.len[1] = (iplen & 0xff); - - /* Copy the source and destination addresses */ - -#ifdef CONFIG_NETDEV_MULTINIC - net_ipv6addr_hdrcopy(ipv6tcp.ipv6.srcipaddr, conn->u.ipv6.laddr); -#endif - net_ipv6addr_hdrcopy(ipv6tcp.ipv6.destipaddr, conn->u.ipv6.raddr); - - ninfo("IPv6 length: %d\n", - ((int)ipv6tcp.ipv6.len[0] << 8) + ipv6tcp.ipv6.len[1]); - -#ifdef CONFIG_NET_STATISTICS - g_netstats.ipv6.sent++; -#endif - - /* Initialize the TCP header */ - - ipv6tcp.tcp.srcport = conn->lport; /* Local port */ - ipv6tcp.tcp.destport = conn->rport; /* Connected remote port */ - - memcpy(ipv6tcp.tcp.ackno, conn->rcvseq, 4); /* ACK number */ - memcpy(ipv6tcp.tcp.seqno, conn->sndseq, 4); /* Sequence number */ - - ipv6tcp.tcp.tcpoffset = (TCP_HDRLEN / 4) << 4; /* No optdata */ - ipv6tcp.tcp.urgp[0] = 0; /* No urgent data */ - ipv6tcp.tcp.urgp[1] = 0; - - /* Set the TCP window */ - - if (conn->tcpstateflags & TCP_STOPPED) - { - /* If the connection has issued TCP_STOPPED, we advertise a zero - * window so that the remote host will stop sending data. - */ - - ipv6tcp.tcp.wnd[0] = 0; - ipv6tcp.tcp.wnd[1] = 0; - } - else - { - ipv6tcp.tcp.wnd[0] = ((NET_DEV_RCVWNDO(dev)) >> 8); - ipv6tcp.tcp.wnd[1] = ((NET_DEV_RCVWNDO(dev)) & 0xff); - } - - /* Calculate TCP checksum. */ - - ipv6tcp.tcp.tcpchksum = 0; - ipv6tcp.tcp.tcpchksum = ~sixlowpan_tcp_chksum(&ipv6tcp, buf, buflen); - - ninfo("Outgoing TCP packet length: %d bytes\n", iplen + IPv6_HDRLEN); - -#ifdef CONFIG_NET_STATISTICS - g_netstats.tcp.sent++; -#endif - - /* Set the socket state to sending */ - - psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_SEND); - /* Get the IEEE 802.15.4 MAC address of the destination. This assumes * an encoding of the MAC address in the IPv6 address. */ sixlowpan_addrfromip(conn->u.ipv6.raddr, &destmac); - /* If routable, then call sixlowpan_send() to format and send the 6LoWPAN - * packet. + /* Set the socket state to sending */ + + psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_SEND); + + /* Send the TCP packets, breaking down the potential large user buffer + * into smaller packets that can be reassembled in the allocated MTU + * packet buffer. */ #ifdef CONFIG_NET_SOCKOPTS @@ -335,18 +853,20 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf, timeout = 0; #endif - ret = sixlowpan_send(dev, &conn->list, - (FAR const struct ipv6_hdr_s *)&ipv6tcp, - buf, buflen, &destmac, timeout); + ret = sixlowpan_send_packet(psock, dev, conn, buf, buflen, &destmac, + timeout); if (ret < 0) { - nerr("ERROR: sixlowpan_send() failed: %d\n", ret); + nerr("ERROR: sixlowpan_send_packet() failed: %d\n", ret); + + psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_IDLE); + return (ssize_t)buflen; } /* Set the socket state to idle */ psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_IDLE); - return ret; + return (ssize_t)buflen; } /**************************************************************************** @@ -356,7 +876,7 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf, * TCP output comes through three different mechansims. Either from: * * 1. TCP socket output. For the case of TCP output to an - * IEEE802.15.4, the TCP output is caught in the socket + * IEEE802.15.4 device, the TCP output is caught in the socket * send()/sendto() logic and and redirected to psock_6lowpan_tcp_send(). * 2. TCP output from the TCP state machine. That will occur * during TCP packet processing by the TCP state meachine. diff --git a/net/sixlowpan/sixlowpan_udpsend.c b/net/sixlowpan/sixlowpan_udpsend.c index f4324d1694..75b4b2ba43 100644 --- a/net/sixlowpan/sixlowpan_udpsend.c +++ b/net/sixlowpan/sixlowpan_udpsend.c @@ -223,7 +223,7 @@ ssize_t psock_6lowpan_udp_sendto(FAR struct socket *psock, if (dev == NULL) #endif { - nwarn("WARNING: Not routable\n"); + nwarn("WARNING: Not routable or not IEEE802.15.4 MAC\n"); return (ssize_t)-ENETUNREACH; } #endif @@ -259,8 +259,15 @@ ssize_t psock_6lowpan_udp_sendto(FAR struct socket *psock, net_ipv6addr_hdrcopy(ipv6udp.ipv6.destipaddr, to6->sin6_addr.in6_u.u6_addr16); #ifdef CONFIG_NETDEV_MULTINIC - net_ipv6addr_hdrcopy(ipv6udp.ipv6.srcipaddr, conn->u.ipv6.laddr); + if (!net_ipv6addr_cmp(conn->u.ipv6.laddr, g_ipv6_allzeroaddr)) + { + net_ipv6addr_hdrcopy(ipv6udp.ipv6.srcipaddr, conn->u.ipv6.laddr); + } + else #endif + { + net_ipv6addr_hdrcopy(ipv6udp.ipv6.srcipaddr, dev->d_ipv6addr); + } ninfo("IPv6 length: %d\n", ((int)ipv6udp.ipv6.len[0] << 8) + ipv6udp.ipv6.len[1]); diff --git a/net/sixlowpan/sixlowpan_utils.c b/net/sixlowpan/sixlowpan_utils.c index a7e80bc09d..4772302a7b 100644 --- a/net/sixlowpan/sixlowpan_utils.c +++ b/net/sixlowpan/sixlowpan_utils.c @@ -68,14 +68,13 @@ ****************************************************************************/ /**************************************************************************** - * Name: sixlowpan_addrfromip + * Name: sixlowpan_{s|e]addrfromip * * Description: - * sixlowpan_addrfromip(): Extract the IEEE 802.15.14 address from a MAC - * based IPv6 address. sixlowpan_addrfromip() is intended to handle a - * tagged address or and size; sixlowpan_saddrfromip() and - * sixlowpan_eaddrfromip() specifically handler short and extended - * addresses. + * sixlowpan_{s|e]addrfromip(): Extract the IEEE 802.15.14 address from a + * MAC-based IPv6 address. sixlowpan_addrfromip() is intended to handle a + * tagged address; sixlowpan_saddrfromip() and sixlowpan_eaddrfromip() + * specifically handle short and extended addresses, respectively. * * 128 112 96 80 64 48 32 16 * ---- ---- ---- ---- ---- ---- ---- ---- @@ -89,16 +88,29 @@ void sixlowpan_saddrfromip(const net_ipv6addr_t ipaddr, { DEBUGASSERT(ipaddr[0] == HTONS(0xfe80)); - memcpy(saddr, &ipaddr[7], NET_6LOWPAN_SADDRSIZE); + /* Big-endian uint16_t to byte order */ + + saddr->u8[0] = ipaddr[7] >> 8; + saddr->u8[1] = ipaddr[7] & 0xff; saddr->u8[0] ^= 0x02; } void sixlowpan_eaddrfromip(const net_ipv6addr_t ipaddr, FAR struct sixlowpan_eaddr_s *eaddr) { + FAR uint8_t *eptr = eaddr->u8; + int i; + DEBUGASSERT(ipaddr[0] == HTONS(0xfe80)); - memcpy(eaddr, &ipaddr[4], NET_6LOWPAN_EADDRSIZE); + for (i = 4; i < 8; i++) + { + /* Big-endian uint16_t to byte order */ + + *eptr++ = ipaddr[i] >> 8; + *eptr++ = ipaddr[i] & 0xff; + } + eaddr->u8[0] ^= 0x02; } @@ -119,6 +131,49 @@ void sixlowpan_addrfromip(const net_ipv6addr_t ipaddr, } } +/**************************************************************************** + * Name: sixlowpan_ipfrom[s|e]addr + * + * Description: + * sixlowpan_ipfrom[s|e]addr(): Create a link-local, MAC-based IPv6 + * address from an IEEE802.15.4 short address (saddr) or extended address + * (eaddr). + * + * 128 112 96 80 64 48 32 16 + * ---- ---- ---- ---- ---- ---- ---- ---- + * fe80 0000 0000 0000 0000 00ff fe00 xxxx 2-byte short address IEEE 48-bit MAC + * fe80 0000 0000 0000 xxxx xxxx xxxx xxxx 8-byte extended address IEEE EUI-64 + * + ****************************************************************************/ + +void sixlowpan_ipfromsaddr(FAR const uint8_t *saddr, + FAR net_ipv6addr_t ipaddr) +{ + ipaddr[0] = HTONS(0xfe80); + ipaddr[1] = 0; + ipaddr[2] = 0; + ipaddr[3] = 0; + ipaddr[4] = 0; + ipaddr[5] = HTONS(0x00ff); + ipaddr[6] = HTONS(0xfe00); + ipaddr[7] = (uint16_t)saddr[0] << 8 | (uint16_t)saddr[1]; + ipaddr[7] ^= 0x200; +} + +void sixlowpan_ipfromeaddr(FAR const uint8_t *eaddr, + FAR net_ipv6addr_t ipaddr) +{ + ipaddr[0] = HTONS(0xfe80); + ipaddr[1] = 0; + ipaddr[2] = 0; + ipaddr[3] = 0; + ipaddr[4] = (uint16_t)eaddr[0] << 8 | (uint16_t)eaddr[1]; + ipaddr[5] = (uint16_t)eaddr[2] << 8 | (uint16_t)eaddr[3]; + ipaddr[6] = (uint16_t)eaddr[4] << 8 | (uint16_t)eaddr[5]; + ipaddr[7] = (uint16_t)eaddr[6] << 8 | (uint16_t)eaddr[7]; + ipaddr[4] ^= 0x200; +} + /**************************************************************************** * Name: sixlowpan_ismacbased * @@ -143,8 +198,9 @@ bool sixlowpan_issaddrbased(const net_ipv6addr_t ipaddr, { FAR const uint8_t *byteptr = saddr->u8; - return (ipaddr[5] == HTONS(0x00ff) && ipaddr[6] == HTONS(0xfe00) && - ipaddr[7] == (GETNET16(byteptr, 0) ^ HTONS(0x0200))); + return (ipaddr[5] == HTONS(0x00ff) && + ipaddr[6] == HTONS(0xfe00) && + ipaddr[7] == (GETUINT16(byteptr, 0) ^ 0x0200)); } bool sixlowpan_iseaddrbased(const net_ipv6addr_t ipaddr, @@ -152,10 +208,10 @@ bool sixlowpan_iseaddrbased(const net_ipv6addr_t ipaddr, { FAR const uint8_t *byteptr = eaddr->u8; - return (ipaddr[4] == (GETNET16(byteptr, 0) ^ HTONS(0x0200)) && - ipaddr[5] == GETNET16(byteptr, 2) && - ipaddr[6] == GETNET16(byteptr, 4) && - ipaddr[7] == GETNET16(byteptr, 6)); + return (ipaddr[4] == (GETUINT16(byteptr, 0) ^ 0x0200) && + ipaddr[5] == GETUINT16(byteptr, 2) && + ipaddr[6] == GETUINT16(byteptr, 4) && + ipaddr[7] == GETUINT16(byteptr, 6)); } bool sixlowpan_ismacbased(const net_ipv6addr_t ipaddr, diff --git a/net/socket/getsockname.c b/net/socket/getsockname.c index e19d48b45c..2356509de8 100644 --- a/net/socket/getsockname.c +++ b/net/socket/getsockname.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/socket/getsockname.c * - * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2011-2012, 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -148,11 +148,23 @@ int ipv4_getsockname(FAR struct socket *psock, FAR struct sockaddr *addr, return -EOPNOTSUPP; } +#ifdef CONFIG_NETDEV_MULTINIC /* The socket/connection does not know its IP address unless * CONFIG_NETDEV_MULTINIC is selected. Otherwise the design supports only * a single network device and only the network device knows the IP address. */ + if (lipaddr == 0) + { +#if defined(CONFIG_NET_TCP) || defined(CONFIG_NET_UDP) + outaddr->sin_family = AF_INET; + outaddr->sin_addr.s_addr = 0; + *addrlen = sizeof(struct sockaddr_in); +#endif + return OK; + } +#endif + net_lock(); #ifdef CONFIG_NETDEV_MULTINIC @@ -160,7 +172,7 @@ int ipv4_getsockname(FAR struct socket *psock, FAR struct sockaddr *addr, * NOTE: listening sockets have no ripaddr. Work around is to use the * lipaddr when ripaddr is not available. */ -` + if (ripaddr == 0) { ripaddr = lipaddr; @@ -279,11 +291,23 @@ int ipv6_getsockname(FAR struct socket *psock, FAR struct sockaddr *addr, return -EOPNOTSUPP; } +#ifdef CONFIG_NETDEV_MULTINIC /* The socket/connection does not know its IP address unless * CONFIG_NETDEV_MULTINIC is selected. Otherwise the design supports only * a single network device and only the network device knows the IP address. */ + if (net_ipv6addr_cmp(lipaddr, g_ipv6_allzeroaddr)) + { +#if defined(NET_TCP_HAVE_STACK) || defined(NET_UDP_HAVE_STACK) + outaddr->sin6_family = AF_INET6; + memcpy(outaddr->sin6_addr.in6_u.u6_addr8, g_ipv6_allzeroaddr, 16); + *addrlen = sizeof(struct sockaddr_in6); +#endif + return OK; + } +#endif + net_lock(); #ifdef CONFIG_NETDEV_MULTINIC diff --git a/net/tcp/tcp_input.c b/net/tcp/tcp_input.c index 5200f1a601..8b34988401 100644 --- a/net/tcp/tcp_input.c +++ b/net/tcp/tcp_input.c @@ -145,6 +145,7 @@ static void tcp_input(FAR struct net_driver_s *dev, uint8_t domain, if ((conn->tcpstateflags & TCP_STATE_MASK) != TCP_SYN_RCVD && (tcp->flags & TCP_CTL) == TCP_SYN) { + nwarn("WARNING: SYN in TCP_SYN_RCVD\n"); goto reset; } else @@ -155,7 +156,7 @@ static void tcp_input(FAR struct net_driver_s *dev, uint8_t domain, /* If we didn't find an active connection that expected the packet, * either (1) this packet is an old duplicate, or (2) this is a SYN packet - * destined for a connection in LISTEN. If the SYN flag isn't set, + * destined for a connection in LISTEN. If the SYN flag isn't set, * it is an old packet and we send a RST. */ @@ -284,6 +285,8 @@ static void tcp_input(FAR struct net_driver_s *dev, uint8_t domain, } } + nwarn("WARNING: Old packet .. reset\n"); + /* This is (1) an old duplicate packet or (2) a SYN packet but with * no matching listener found. Send RST packet in either case. */ @@ -448,8 +451,10 @@ found: if ((conn->tcpstateflags & TCP_STATE_MASK) == TCP_ESTABLISHED) { - nwarn("WARNING: conn->sndseq %d, conn->unacked %d\n", - tcp_getsequence(conn->sndseq), conn->unacked); + nwarn("WARNING: ackseq > unackseq\n"); + nwarn(" sndseq=%u unacked=%u unackseq=%u ackseq=%u\n", + tcp_getsequence(conn->sndseq), conn->unacked, unackseq, + ackseq); goto reset; } } @@ -527,8 +532,8 @@ found: * handshake is not complete */ - nerr("Listen canceled while waiting for ACK on port %d\n", - tcp->destport); + nwarn("WARNING: Listen canceled while waiting for ACK on port %d\n", + tcp->destport); /* Free the connection structure */ diff --git a/net/tcp/tcp_send_unbuffered.c b/net/tcp/tcp_send_unbuffered.c index 2ad73a02d4..6bb13f593d 100644 --- a/net/tcp/tcp_send_unbuffered.c +++ b/net/tcp/tcp_send_unbuffered.c @@ -340,10 +340,10 @@ static uint16_t tcpsend_interrupt(FAR struct net_driver_s *dev, } #endif /* CONFIG_NET_IPv6 */ - /* The current acknowledgement number number is the (relative) offset - * of the of the next byte needed by the receiver. The snd_isn is the - * offset of the first byte to send to the receiver. The difference - * is the number of bytes to be acknowledged. + /* The current acknowledgement number is the (relative) offset of the + * next byte needed by the receiver. The snd_isn is the offset of the + * first byte to send to the receiver. The difference is the number + * of bytes to be acknowledged. */ pstate->snd_acked = tcp_getsequence(tcp->ackno) - pstate->snd_isn; diff --git a/sched/pthread/pthread_mutexunlock.c b/sched/pthread/pthread_mutexunlock.c index 6a9bab3f8a..3dd7d09683 100644 --- a/sched/pthread/pthread_mutexunlock.c +++ b/sched/pthread/pthread_mutexunlock.c @@ -42,11 +42,45 @@ #include #include #include +#include #include #include #include "pthread/pthread.h" +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pthread_mutex_islocked + * + * Description: + * Return true is the mutex is locked. + * + * Parameters: + * None + * + * Return Value: + * Returns true if the mutex is locked + * + ****************************************************************************/ + +static inline bool pthread_mutex_islocked(FAR struct pthread_mutex_s *mutex) +{ + int semcount = mutex->sem.semcount; + + /* The underlying semaphore should have a count less than 2: + * + * 1 == mutex is unlocked. + * 0 == mutex is locked with no waiters + * -n == mutex is locked with 'n' waiters. + */ + + DEBUGASSERT(semcount < 2); + return semcount < 1; +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -80,17 +114,29 @@ int pthread_mutex_unlock(FAR pthread_mutex_t *mutex) { - int ret = EINVAL; + int ret = EPERM; sinfo("mutex=0x%p\n", mutex); DEBUGASSERT(mutex != NULL); + if (mutex == NULL) + { + return EINVAL; + } /* Make sure the semaphore is stable while we make the following checks. * This all needs to be one atomic action. */ sched_lock(); - if (mutex != NULL) + + /* The unlock operation is only performed if the mutex is actually locked. + * EPERM *must* be returned if the mutex type is PTHREAD_MUTEX_ERRORCHECK + * or PTHREAD_MUTEX_RECURSIVE, or the mutex is a robust mutex, and the + * current thread does not own the mutex. Behavior is undefined for the + * remaining case. + */ + + if (pthread_mutex_islocked(mutex)) { #if !defined(CONFIG_PTHREAD_MUTEX_UNSAFE) || defined(CONFIG_PTHREAD_MUTEX_TYPES) /* Does the calling thread own the semaphore? If no, should we return diff --git a/wireless/ieee802154/Kconfig b/wireless/ieee802154/Kconfig index d06ed743c1..f01ae562d7 100644 --- a/wireless/ieee802154/Kconfig +++ b/wireless/ieee802154/Kconfig @@ -23,14 +23,23 @@ config IEEE802154_DEFAULT_EADDR choice prompt "IEEE 802.15.4 work queue" - default MAC802154_LPWORK if SCHED_LPWORK - default MAC802154_HPWORK if !SCHED_LPWORK && SCHED_HPWORK + default MAC802154_HPWORK if SCHED_HPWORK + default MAC802154_LPWORK if !SCHED_HPWORK && SCHED_LPWORK depends on SCHED_WORKQUEUE ---help--- Work queue support is required to use the IEEE 802.15.4 MAC layer. - If the low priority work queue is available, then it should be used by + If the high priority work queue is available, then it should be used by the driver. + WARNING!! The IEEE802.15.4 network device must never run on the same + work queue as does the IEEE 802.15.4 MAC. That configuration will + cause deadlocks: The network logic may be blocked on the work queue + waiting on resources that can only be freed by the MAC logic but the + MAC is unable to run because the work queue is blocked. The + recommended configuration is: Network on the LP work queue; MAC on HP + work queue. Blocking on the HP work queue is a very bad thing in + any case. + config MAC802154_HPWORK bool "High priority" depends on SCHED_HPWORK @@ -41,12 +50,39 @@ config MAC802154_LPWORK endchoice # Work queue -config IEEE802154_NTXDESC +config MAC802154_NTXDESC int "Number or TX descriptors" default 3 ---help--- Configured number of Tx descriptors. Default: 3 - + + When used with 6LoWPAN, the descriptor allocator runs on a work + and must avoid blocking if possible. Each frame will be provided in + an IOB and each TX frame will need a TX descriptor. So the safe + thing to do is set CONFIG_MAC802154_NTXDESC to CONFIG_IOB_NBUFFERS. + Then there should be the maximum pre-allocated buffers for each + possible TX frame. + +config MAC802154_NNOTIF + int "Number or notification structures" + default 3 + ---help--- + Configured number of notification strucures Default: 3 + + When various MAC management events occur, the MAC notifies the registered + receiver with an allocated notification structure indicating the event. The + events are primitives such as Association Indication etc. + +config MAC802154_NPANDESC + int "Number of PAN descriptors" + default 5 + ---help--- + Configured number of PAN descriptors Default: 5 + + When performing a scan to find a suitable PAN, the MAC must store + information for all unique beacons received. This is the number of unique + descriptors that can be held before the scan cancels with LIMIT_REACHED. + config IEEE802154_IND_PREALLOC int "Number of pre-allocated meta-data structures" default 20 @@ -56,7 +92,7 @@ config IEEE802154_IND_PREALLOC from either from tasking logic or from interrupt level logic. config IEEE802154_IND_IRQRESERVE - int "Rserved pre-allocated meta-data structures" + int "Reserved pre-allocated meta-data structures" default 10 ---help--- If meta-data structures can be allocated from interrupt handlers, @@ -75,7 +111,7 @@ config IEEE802154_IND_IRQRESERVE Non-interrupt logic will also first attempt to allocate from the general, pre-allocated structure pool. If that fails, it will dynamically allocate the meta data structure with an additional cost in performance. - + config IEEE802154_MACDEV bool "Character driver for IEEE 802.15.4 MAC layer" default n @@ -142,9 +178,18 @@ choice depends on SCHED_WORKQUEUE ---help--- Work queue support is required to use the IEEE802.15.4 network - driver. If the low priority work queue is available, then it shoul + driver. If the low priority work queue is available, then it should be used by the loopback driver. + WARNING!! The IEEE802.15.4 network device must never run on the same + work queue as does the IEEE 802.15.4 MAC. That configuration will + cause deadlocks: The network logic may be blocked on the work queue + waiting on resources that can only be freed by the MAC logic but the + MAC is unable to run because the work queue is blocked. The + recommended configuration is: Network on the LP work queue; MAC on HP + work queue. Blocking on the HP work queue is a very bad thing in + any case. + config IEEE802154_NETDEV_HPWORK bool "High priority" depends on SCHED_HPWORK diff --git a/wireless/ieee802154/README.txt b/wireless/ieee802154/README.txt new file mode 100644 index 0000000000..e1f7691ca4 --- /dev/null +++ b/wireless/ieee802154/README.txt @@ -0,0 +1,8 @@ +This will eventually hold some general documentation for the IEEE 802.15.4 +MAC implementation. + +NOTE: Throughout the code, excerpts from the standard are quoted as to make +the code thoroughly readable. I have tried, to always put a reference [1] and +page number. Below is the references that correspond with the reference number + +[1] \ No newline at end of file diff --git a/wireless/ieee802154/mac802154.c b/wireless/ieee802154/mac802154.c index c7d53fd265..af5e4523f7 100644 --- a/wireless/ieee802154/mac802154.c +++ b/wireless/ieee802154/mac802154.c @@ -59,6 +59,7 @@ #include "mac802154_notif.h" #include "mac802154_internal.h" #include "mac802154_assoc.h" +#include "mac802154_scan.h" #include "mac802154_data.h" #include "mac802154_poll.h" @@ -86,10 +87,8 @@ static void mac802154_rxframe(FAR const struct ieee802154_radiocb_s *radiocb, FAR struct ieee802154_data_ind_s *ind); static void mac802154_rxframe_worker(FAR void *arg); -static void mac802154_rx_datareq(FAR struct ieee802154_privmac_s *priv, - FAR struct ieee802154_data_ind_s *ind); -static void mac802154_rx_dataframe(FAR struct ieee802154_privmac_s *priv, - FAR struct ieee802154_data_ind_s *ind); +static void mac802154_sfevent(FAR const struct ieee802154_radiocb_s *radiocb, + enum ieee802154_sfevent_e sfevent); static void mac802154_purge_worker(FAR void *arg); @@ -100,6 +99,13 @@ static void mac802154_timeout_expiry(int argc, wdparm_t arg, ...); static uint32_t mac802154_symtoticks(FAR struct ieee802154_privmac_s *priv, uint32_t symbols); +static void mac802154_rxdatareq(FAR struct ieee802154_privmac_s *priv, + FAR struct ieee802154_data_ind_s *ind); +static void mac802154_rxdataframe(FAR struct ieee802154_privmac_s *priv, + FAR struct ieee802154_data_ind_s *ind); +static void mac802154_rxbeaconframe(FAR struct ieee802154_privmac_s *priv, + FAR struct ieee802154_data_ind_s *ind); + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -130,6 +136,7 @@ static void mac802154_resetqueues(FAR struct ieee802154_privmac_s *priv) { sq_addlast((FAR sq_entry_t *)&priv->txdesc_pool[i], &priv->txdesc_queue); } + sem_init(&priv->txdesc_sem, 0, CONFIG_MAC802154_NTXDESC); /* Initialize the notifcation allocation pool */ @@ -169,7 +176,6 @@ int mac802154_txdesc_alloc(FAR struct ieee802154_privmac_s *priv, */ ret = sem_trywait(&priv->txdesc_sem); - if (ret == OK) { *txdesc = (FAR struct ieee802154_txdesc_s *)sq_remfirst(&priv->txdesc_queue); @@ -189,6 +195,7 @@ int mac802154_txdesc_alloc(FAR struct ieee802154_privmac_s *priv, { /* MAC is already released */ + wlwarn("WARNING: mac802154_takesem failed: %d\n", ret); return -EINTR; } @@ -200,6 +207,8 @@ int mac802154_txdesc_alloc(FAR struct ieee802154_privmac_s *priv, ret = mac802154_takesem(&priv->exclsem, allow_interrupt); if (ret < 0) { + wlwarn("WARNING: mac802154_takesem failed: %d\n", ret); + mac802154_givesem(&priv->txdesc_sem); return -EINTR; } @@ -228,12 +237,11 @@ int mac802154_txdesc_alloc(FAR struct ieee802154_privmac_s *priv, } (*txdesc)->conf = ¬if->u.dataconf; - return OK; } /**************************************************************************** - * Name: mac802154_create_datareq + * Name: mac802154_createdatareq * * Description: * Internal function used by various parts of the MAC layer. This function @@ -245,13 +253,12 @@ int mac802154_txdesc_alloc(FAR struct ieee802154_privmac_s *priv, * ****************************************************************************/ -void mac802154_create_datareq(FAR struct ieee802154_privmac_s *priv, - FAR struct ieee802154_addr_s *coordaddr, - enum ieee802154_addrmode_e srcmode, - FAR struct ieee802154_txdesc_s *txdesc) +void mac802154_createdatareq(FAR struct ieee802154_privmac_s *priv, + FAR struct ieee802154_addr_s *coordaddr, + enum ieee802154_addrmode_e srcmode, + FAR struct ieee802154_txdesc_s *txdesc) { FAR struct iob_s *iob; - FAR uint16_t *u16; /* The only node allowed to use a source address of none is the PAN Coordinator. * PAN coordinators should not be sending data request commans. @@ -269,16 +276,16 @@ void mac802154_create_datareq(FAR struct ieee802154_privmac_s *priv, iob->io_offset = 0; iob->io_pktlen = 0; - /* Get a uin16_t reference to the first two bytes. ie frame control field */ + /* Set the frame control fields */ - u16 = (FAR uint16_t *)&iob->io_data[iob->io_len]; + iob->io_data[0] = 0; + iob->io_data[1] = 0; + IEEE802154_SETACKREQ(iob->io_data, 0); + IEEE802154_SETFTYPE(iob->io_data, 0, IEEE802154_FRAME_COMMAND); + IEEE802154_SETDADDRMODE(iob->io_data, 0, coordaddr->mode); + IEEE802154_SETSADDRMODE(iob->io_data, 0, srcmode); iob->io_len = 2; - *u16 = (IEEE802154_FRAME_COMMAND << IEEE802154_FRAMECTRL_SHIFT_FTYPE); - *u16 |= IEEE802154_FRAMECTRL_ACKREQ; - *u16 |= (coordaddr->mode << IEEE802154_FRAMECTRL_SHIFT_DADDR); - *u16 |= (srcmode << IEEE802154_FRAMECTRL_SHIFT_SADDR); - /* Each time a data or a MAC command frame is generated, the MAC sublayer * shall copy the value of macDSN into the Sequence Number field of the * MHR of the outgoing frame and then increment it by one. [1] pg. 40. @@ -304,8 +311,6 @@ void mac802154_create_datareq(FAR struct ieee802154_privmac_s *priv, } } - *u16 |= (coordaddr->mode << IEEE802154_FRAMECTRL_SHIFT_DADDR); - /* If the Destination Addressing Mode field is set to indicate that * destination addressing information is not present, the PAN ID Compression * field shall be set to zero and the source PAN identifier shall contain the @@ -318,7 +323,7 @@ void mac802154_create_datareq(FAR struct ieee802154_privmac_s *priv, if (coordaddr->mode != IEEE802154_ADDRMODE_NONE && IEEE802154_PANIDCMP(coordaddr->panid, priv->addr.panid)) { - *u16 |= IEEE802154_FRAMECTRL_PANIDCOMP; + IEEE802154_SETPANIDCOMP(iob->io_data, 0); } else { @@ -354,6 +359,163 @@ void mac802154_create_datareq(FAR struct ieee802154_privmac_s *priv, txdesc->frame = iob; } +/**************************************************************************** + * Name: mac802154_updatebeacon + * + * Description: + * This function is called in the following scenarios: + * - The MAC receives a START.request primitive + * - Upon receiving the IEEE802154_SFEVENT_ENDOFACTIVE event from the + * radio layer, the MAC checks the bf_update flag and if set calls this + * function. The bf_update flag is set when various attributes that + * effect the beacon are updated. + * + * Internal function used by various parts of the MAC layer. This function + * uses the various MAC attributes to update the beacon frame. It loads the + * inactive beacon frame structure and then notifies the radio layer of the + * new frame. the provided tx descriptor in the indirect list and manages the + * scheduling for purging the transaction if it does not get extracted in + * time. + * + * Assumptions: + * Called with the MAC locked + * + ****************************************************************************/ + +void mac802154_updatebeacon(FAR struct ieee802154_privmac_s *priv) +{ + FAR struct ieee802154_txdesc_s *txdesc; + uint8_t pendaddrspec_ind; + uint8_t pendeaddr = 0; + uint8_t pendsaddr = 0; + + /* Switch the buffer */ + + priv->bf_ind = !priv->bf_ind; + + /* Get a local reference to the beacon frame */ + + FAR struct ieee802154_beaconframe_s *beacon = &priv->beaconframe[priv->bf_ind]; + + /* Clear the frame control fields */ + + beacon->bf_data[0] = 0; + beacon->bf_data[1] = 0; + beacon->bf_len = 2; + + IEEE802154_SETFTYPE(beacon->bf_data, 0, IEEE802154_FRAME_BEACON); + + /* Check if there is a broadcast message pending, if there is, we must set + * the frame pending bit to 1. + */ + + /* TODO: handle broadcast frame */ + + DEBUGASSERT(priv->addr.mode != IEEE802154_ADDRMODE_NONE); + + IEEE802154_SETDADDRMODE(beacon->bf_data, 0, IEEE802154_ADDRMODE_NONE); + IEEE802154_SETSADDRMODE(beacon->bf_data, 0, priv->addr.mode); + IEEE802154_SETVERSION(beacon->bf_data, 0, 1); + + /* Copy in and increment the beacon sequence number */ + + beacon->bf_data[beacon->bf_len++] = priv->bsn++; + + IEEE802154_PANIDCOPY(&beacon->bf_data[beacon->bf_len], priv->addr.panid); + beacon->bf_len += IEEE802154_PANIDSIZE; + + if (priv->addr.mode == IEEE802154_ADDRMODE_SHORT) + { + IEEE802154_SADDRCOPY(&beacon->bf_data[beacon->bf_len], priv->addr.saddr); + beacon->bf_len += IEEE802154_SADDRSIZE; + } + else + { + IEEE802154_EADDRCOPY(&beacon->bf_data[beacon->bf_len], priv->addr.eaddr); + beacon->bf_len += IEEE802154_EADDRSIZE; + } + + /* Clear the superframe specification, then set the appropriate bits */ + + beacon->bf_data[beacon->bf_len] = 0; + beacon->bf_data[beacon->bf_len + 1] = 0; + + IEEE802154_SETBEACONORDER(beacon->bf_data, beacon->bf_len, + priv->sfspec.beaconorder); + IEEE802154_SETSFORDER(beacon->bf_data, beacon->bf_len, + priv->sfspec.sforder); + IEEE802154_SETFINCAPSLOT(beacon->bf_data, beacon->bf_len, + priv->sfspec.final_capslot); + if (priv->sfspec.ble) + { + IEEE802154_SETBLE(beacon->bf_data, beacon->bf_len); + } + if (priv->sfspec.pancoord) + { + IEEE802154_SETPANCOORD(beacon->bf_data, beacon->bf_len); + } + if (priv->sfspec.assocpermit) + { + IEEE802154_SETASSOCPERMIT(beacon->bf_data, beacon->bf_len); + } + + beacon->bf_len += 2; + + /* TODO: Handle GTS properly, for now, we just set the descriptor count to + * zero and specify that we do not permit GTS requests */ + + beacon->bf_data[beacon->bf_len++] = 0; + + /* TODO: Add GTS List here */ + + /* Skip the pending address specification field for now */ + + pendaddrspec_ind = beacon->bf_len++; + + txdesc = (FAR struct ieee802154_txdesc_s *)sq_peek(&priv->indirect_queue); + + while(txdesc != NULL) + { + if (txdesc->destaddr.mode == IEEE802154_ADDRMODE_SHORT) + { + pendsaddr++; + IEEE802154_SADDRCOPY(&beacon->bf_data[beacon->bf_len], txdesc->destaddr.saddr); + beacon->bf_len += IEEE802154_SADDRSIZE; + } + else if (txdesc->destaddr.mode == IEEE802154_ADDRMODE_EXTENDED) + { + pendeaddr++; + IEEE802154_EADDRCOPY(&beacon->bf_data[beacon->bf_len], txdesc->destaddr.eaddr); + beacon->bf_len += IEEE802154_EADDRSIZE; + } + + /* Check if we are up to 7 addresses yet */ + + if ((pendsaddr + pendeaddr) == 7) + { + break; + } + + /* Get the next pending indirect transation */ + + txdesc = (FAR struct ieee802154_txdesc_s *)sq_next((FAR sq_entry_t *)txdesc); + } + + /* At this point, we know how many of each transaction we have, we can setup + * the Pending Address Specification field + */ + + beacon->bf_data[pendaddrspec_ind] = (pendsaddr & 0x07) | ((pendeaddr << 4) & 0x70); + + /* Copy in the beacon payload */ + + memcpy(&beacon->bf_data[beacon->bf_len], priv->beaconpayload, + priv->beaconpayloadlength); + beacon->bf_len += priv->beaconpayloadlength; + + priv->beaconupdate = false; +} + /**************************************************************************** * Name: mac802154_setupindirect * @@ -387,10 +549,10 @@ void mac802154_setupindirect(FAR struct ieee802154_privmac_s *priv, * aBaseSuperframeDuration. [1] pg. 129 */ - if (priv->beaconorder < 15) + if (priv->sfspec.beaconorder < 15) { symbols = priv->trans_persisttime * - (IEEE802154_BASE_SUPERFRAME_DURATION * (1 << priv->beaconorder)); + (IEEE802154_BASE_SUPERFRAME_DURATION * (1 << priv->sfspec.beaconorder)); } else { @@ -401,6 +563,13 @@ void mac802154_setupindirect(FAR struct ieee802154_privmac_s *priv, txdesc->purge_time = clock_systimer() + ticks; + /* Make sure the beacon gets updated */ + + if (priv->sfspec.beaconorder < 15) + { + priv->beaconupdate = true; + } + /* Check to see if the purge indirect timer is scheduled. If it is, when the * timer fires, it will schedule the next purge timer event. Inherently, the * queue will be in order of which transaction needs to be purged next. @@ -470,6 +639,7 @@ static void mac802154_purge_worker(FAR void *arg) ((FAR struct mac802154_notif_s *)txdesc->conf)->flink = priv->notif_free; priv->notif_free = ((FAR struct mac802154_notif_s *)txdesc->conf); mac802154_txdesc_free(priv, txdesc); + priv->beaconupdate = true; wlinfo("Indirect TX purged"); } @@ -865,7 +1035,7 @@ static void mac802154_rxframe_worker(FAR void *arg) { /* The source PAN ID is equal to the destination PAN ID */ - IEEE802154_PANIDCOPY(ind->src.panid, ind->dest.panid); + IEEE802154_PANIDCOPY(ind->src.panid, ind->dest.panid); } else { @@ -889,7 +1059,7 @@ static void mac802154_rxframe_worker(FAR void *arg) { case IEEE802154_FRAME_DATA: { - mac802154_rx_dataframe(priv, ind); + mac802154_rxdataframe(priv, ind); } break; @@ -905,33 +1075,43 @@ static void mac802154_rxframe_worker(FAR void *arg) switch (cmdtype) { case IEEE802154_CMD_ASSOC_REQ: + wlinfo("Assoc request received\n"); mac802154_rx_assocreq(priv, ind); break; case IEEE802154_CMD_ASSOC_RESP: + wlinfo("Assoc response received\n"); mac802154_rx_assocresp(priv, ind); break; case IEEE802154_CMD_DISASSOC_NOT: + wlinfo("Disassoc notif received\n"); break; case IEEE802154_CMD_DATA_REQ: - mac802154_rx_datareq(priv, ind); + wlinfo("Data request received\n"); + mac802154_rxdatareq(priv, ind); break; case IEEE802154_CMD_PANID_CONF_NOT: + wlinfo("PAN ID Conflict notif received\n"); break; case IEEE802154_CMD_ORPHAN_NOT: + wlinfo("Orphan notif received\n"); + break; break; case IEEE802154_CMD_BEACON_REQ: + wlinfo("Beacon request received\n"); break; case IEEE802154_CMD_COORD_REALIGN: + wlinfo("Coord realign received\n"); break; case IEEE802154_CMD_GTS_REQ: + wlinfo("GTS request received\n"); break; } @@ -943,15 +1123,9 @@ static void mac802154_rxframe_worker(FAR void *arg) case IEEE802154_FRAME_BEACON: { - /* TODO: Add logic here to handle extracting association response from - * coordinator if beacon tracking was enabled during the Association - * operation. - * - * mac802154_txdesc_alloc(priv, &respdec, false); - * mac802154_create_datareq(priv, &req->coordaddr, - * IEEE802154_ADDRMODE_EXTENDED, respdesc); - * sq_addlast((FAR sq_entry_t *)respdesc, &priv->csma_queue); - */ + wlinfo("Beacon frame received\n"); + mac802154_rxbeaconframe(priv, ind); + ieee802154_ind_free(ind); } break; @@ -970,7 +1144,7 @@ static void mac802154_rxframe_worker(FAR void *arg) } /**************************************************************************** - * Name: mac802154_rx_dataframe + * Name: mac802154_rxdataframe * * Description: * Function called from the generic RX Frame worker to parse and handle the @@ -978,8 +1152,8 @@ static void mac802154_rxframe_worker(FAR void *arg) * ****************************************************************************/ -static void mac802154_rx_dataframe(FAR struct ieee802154_privmac_s *priv, - FAR struct ieee802154_data_ind_s *ind) +static void mac802154_rxdataframe(FAR struct ieee802154_privmac_s *priv, + FAR struct ieee802154_data_ind_s *ind) { FAR struct ieee802154_notif_s *notif; @@ -1097,7 +1271,7 @@ static void mac802154_rx_dataframe(FAR struct ieee802154_privmac_s *priv, priv->curr_op = MAC802154_OP_NONE; priv->cmd_desc = NULL; - mac802154_givesem(&priv->op_sem); + mac802154_givesem(&priv->opsem); /* Release the MAC */ @@ -1159,7 +1333,7 @@ notify_without_lock: } /**************************************************************************** - * Name: mac802154_rx_datareq + * Name: mac802154_rxdatareq * * Description: * Function called from the generic RX Frame worker to parse and handle the @@ -1167,7 +1341,7 @@ notify_without_lock: * ****************************************************************************/ -static void mac802154_rx_datareq(FAR struct ieee802154_privmac_s *priv, +static void mac802154_rxdatareq(FAR struct ieee802154_privmac_s *priv, FAR struct ieee802154_data_ind_s *ind) { FAR struct ieee802154_txdesc_s *txdesc; @@ -1190,12 +1364,7 @@ static void mac802154_rx_datareq(FAR struct ieee802154_privmac_s *priv, txdesc = (FAR struct ieee802154_txdesc_s *)sq_peek(&priv->indirect_queue); - if (txdesc == NULL) - { - goto no_data; - } - - do + while(txdesc != NULL) { if (txdesc->destaddr.mode == ind->src.mode) { @@ -1210,7 +1379,9 @@ static void mac802154_rx_datareq(FAR struct ieee802154_privmac_s *priv, /* The addresses match, send the transaction immediately */ priv->radio->txdelayed(priv->radio, txdesc, 0); - break; + priv->beaconupdate = true; + mac802154_givesem(&priv->exclsem); + return; } } else if (txdesc->destaddr.mode == IEEE802154_ADDRMODE_EXTENDED) @@ -1225,7 +1396,9 @@ static void mac802154_rx_datareq(FAR struct ieee802154_privmac_s *priv, /* The addresses match, send the transaction immediately */ priv->radio->txdelayed(priv->radio, txdesc, 0); - break; + priv->beaconupdate = true; + mac802154_givesem(&priv->exclsem); + return; } } else @@ -1235,18 +1408,7 @@ static void mac802154_rx_datareq(FAR struct ieee802154_privmac_s *priv, } txdesc = (FAR struct ieee802154_txdesc_s *)sq_next((FAR sq_entry_t *)txdesc); - - if (txdesc == NULL) - { - goto no_data; - } } - while (1); - - mac802154_givesem(&priv->exclsem); - return; - -no_data: /* If there is no data frame pending for the requesting device, the coordinator * shall send a data frame without requesting acknowledgment to the device @@ -1346,6 +1508,217 @@ no_data: priv->radio->txdelayed(priv->radio, txdesc, 0); } +static void mac802154_sfevent(FAR const struct ieee802154_radiocb_s *radiocb, + enum ieee802154_sfevent_e sfevent) +{ + FAR struct mac802154_radiocb_s *cb = + (FAR struct mac802154_radiocb_s *)radiocb; + FAR struct ieee802154_privmac_s *priv; + + DEBUGASSERT(cb != NULL && cb->priv != NULL); + priv = cb->priv; + + /* Get exclusive access to the driver structure. We don't care about any + * signals so if we see one, just go back to trying to get access again. + */ + + mac802154_takesem(&priv->exclsem, false); + + /* Check if there is any reason to update the beacon */ + + if (priv->beaconupdate) + { + mac802154_updatebeacon(priv); + + priv->radio->beaconupdate(priv->radio, &priv->beaconframe[priv->bf_ind]); + } + + mac802154_givesem(&priv->exclsem); +} + +/**************************************************************************** + * Name: mac802154_rxbeaconframe + * + * Description: + * Function called from the generic RX Frame worker to parse and handle the + * reception of a beacon frame. + * + ****************************************************************************/ + +static void mac802154_rxbeaconframe(FAR struct ieee802154_privmac_s *priv, + FAR struct ieee802154_data_ind_s *ind) +{ + FAR struct iob_s *iob = ind->frame; + struct ieee802154_pandesc_s pandesc; + FAR struct ieee802154_txdesc_s *respdesc; + uint8_t numgtsdesc; + uint8_t gtsdirmask; + uint8_t npendsaddr; + uint8_t npendeaddr; + int i; + + /* Copy the coordinator address and channel info into the pan descriptor */ + + memcpy(&pandesc.coordaddr, &ind->src, sizeof(struct ieee802154_addr_s)); + pandesc.chan = priv->currscan.channels[priv->scanindex]; + pandesc.chpage = priv->currscan.chpage; + pandesc.lqi = ind->lqi; + pandesc.timestamp = ind->timestamp; + + /* Parse the superframe specification field */ + + pandesc.sfspec.beaconorder = IEEE802154_GETBEACONORDER(iob->io_data, + iob->io_offset); + + pandesc.sfspec.sforder = IEEE802154_GETSFORDER(iob->io_data, iob->io_offset); + pandesc.sfspec.final_capslot = IEEE802154_GETFINCAPSLOT(iob->io_data, + iob->io_offset); + pandesc.sfspec.ble = IEEE802154_GETBLE(iob->io_data, iob->io_offset); + pandesc.sfspec.pancoord = IEEE802154_GETPANCOORD(iob->io_data, iob->io_offset); + pandesc.sfspec.assocpermit = IEEE802154_GETASSOCPERMIT(iob->io_data, + iob->io_offset); + iob->io_offset += 2; + + /* Parse the GTS Specification field */ + + numgtsdesc = IEEE802154_GETGTSDESCCOUNT(iob->io_data, iob->io_offset); + pandesc.gtspermit = IEEE802154_GETGTSPERMIT(iob->io_data, iob->io_offset); + iob->io_offset++; + + /* We only need to parse the rest of the frame if we are not performing a + * scan + */ + + if (priv->curr_op == MAC802154_OP_SCAN) + { + /* Check to see if we already have a frame from this coordinator */ + + for (i = 0; i < priv->npandesc; i++) + { + if (priv->currscan.channels[priv->scanindex] != priv->pandescs[i].chan) + { + continue; + } + + if (memcmp(&ind->src, &priv->pandescs[i].coordaddr, + sizeof(struct ieee802154_addr_s))) + { + continue; + } + + /* The beacon is the same as another, so discard it */ + + return; + } + + /* Copy the pan desc to the list of pan desc */ + + memcpy(&priv->pandescs[priv->npandesc], &pandesc, + sizeof(struct ieee802154_pandesc_s)); + priv->npandesc++; + + if (priv->npandesc == MAC802154_NPANDESC) + { + mac802154_scanfinish(priv, IEEE802154_STATUS_LIMITREACHED); + } + } + else + { + /* If there are any GTS descriptors, handle the GTS Directions and + * GTS List fields + */ + + if (numgtsdesc > 0) + { + gtsdirmask = IEEE802154_GETGTSDIRMASK(iob->io_data, iob->io_offset); + iob->io_offset++; + + for (i = 0; i < numgtsdesc; i++) + { + /* For now we just discard the data by skipping over it */ + + iob->io_offset += 3; + } + } + + /* Pending address fields. Min 1 byte, the Pending Address Specification */ + + npendsaddr = IEEE802154_GETNPENDSADDR(iob->io_data, iob->io_offset); + npendeaddr = IEEE802154_GETNPENDEADDR(iob->io_data, iob->io_offset); + iob->io_offset++; + + /* The pending address field tells us whether or not there is any data + * pending for us. + */ + + for (i = 0; i < npendsaddr; i++) + { + /* If the short address matches our short address */ + + if (IEEE802154_SADDRCMP(&iob->io_data[iob->io_offset], priv->addr.saddr)) + { + /* TODO: Handle data pending in coordinator for us */ + } + iob->io_offset += IEEE802154_SADDRSIZE; + } + + for (i = 0; i < npendeaddr; i++) + { + /* If the extended address matches our extended address */ + + if (IEEE802154_EADDRCMP(&iob->io_data[iob->io_offset], priv->addr.eaddr)) + { + /* If we are associating, polling, or if macAutoRequest is TRUE, + * extract the data. + */ + + if ((priv->autoreq) || (priv->curr_op == MAC802154_OP_ASSOC) || + (priv->curr_op == MAC802154_OP_POLL)) + { + mac802154_txdesc_alloc(priv, &respdesc, false); + + mac802154_createdatareq(priv, &priv->pandesc.coordaddr, + IEEE802154_ADDRMODE_EXTENDED, respdesc); + + if (priv->curr_op == MAC802154_OP_ASSOC || + priv->curr_op == MAC802154_OP_POLL) + { + priv->curr_cmd = IEEE802154_CMD_DATA_REQ; + } + + /* Link the transaction into the CSMA transaction list */ + + sq_addlast((FAR sq_entry_t *)respdesc, &priv->csma_queue); + + /* Notify the radio driver that there is data available */ + + priv->radio->txnotify(priv->radio, false); + } + } + iob->io_offset += IEEE802154_EADDRSIZE; + } + + /* TODO: Process incoming beacon payload + * If there is anything left in the frame, process it as the beacon payload + */ + + /* Check the superframe structure and update the appropriate attributes. */ + + if (memcmp(&priv->sfspec, &pandesc.sfspec, + sizeof(struct ieee802154_superframespec_s)) != 0) + { + /* Copy in the new superframe spec */ + + memcpy(&priv->sfspec, &pandesc.sfspec, + sizeof(struct ieee802154_superframespec_s)); + + /* Tell the radio layer about the superframe spec update */ + + priv->radio->sfupdate(priv->radio, &pandesc.sfspec); + } + } +} + /**************************************************************************** * Name: mac802154_symtoticks * @@ -1515,7 +1888,7 @@ MACHANDLE mac802154_create(FAR struct ieee802154_radio_s *radiodev) /* Allow exclusive access to the dedicated command transaction */ - sem_init(&mac->op_sem, 0, 1); + sem_init(&mac->opsem, 0, 1); /* Setup watchdog for extraction timeout */ @@ -1535,6 +1908,7 @@ MACHANDLE mac802154_create(FAR struct ieee802154_radio_s *radiodev) radiocb->poll = mac802154_radiopoll; radiocb->txdone = mac802154_txdone; radiocb->rxframe = mac802154_rxframe; + radiocb->sfevent = mac802154_sfevent; /* Bind our callback structure */ @@ -1553,7 +1927,7 @@ MACHANDLE mac802154_create(FAR struct ieee802154_radio_s *radiodev) } IEEE802154_EADDRCOPY(mac->addr.eaddr, eaddr); - mac->radio->set_attr(mac->radio, IEEE802154_ATTR_MAC_EXTENDED_ADDR, + mac->radio->set_attr(mac->radio, IEEE802154_ATTR_MAC_EADDR, (union ieee802154_attr_u *)&eaddr[0]); return (MACHANDLE)mac; diff --git a/wireless/ieee802154/mac802154_assoc.c b/wireless/ieee802154/mac802154_assoc.c index c6c2135fc0..2027013b7a 100644 --- a/wireless/ieee802154/mac802154_assoc.c +++ b/wireless/ieee802154/mac802154_assoc.c @@ -58,7 +58,7 @@ * Private Function Prototypes ****************************************************************************/ -static void mac802154_timeout_assoc(FAR struct ieee802154_privmac_s *priv); +static void mac802154_assoctimeout(FAR struct ieee802154_privmac_s *priv); /**************************************************************************** * Public MAC Functions @@ -86,7 +86,6 @@ int mac802154_req_associate(MACHANDLE mac, (FAR struct ieee802154_privmac_s *)mac; FAR struct ieee802154_txdesc_s *txdesc; FAR struct iob_s *iob; - FAR uint16_t *u16; bool rxonidle; int ret; @@ -101,7 +100,7 @@ int mac802154_req_associate(MACHANDLE mac, * needs access to the MAC in order to unlock it. */ - ret = mac802154_takesem(&priv->op_sem, true); + ret = mac802154_takesem(&priv->opsem, true); if (ret < 0) { return ret; @@ -115,28 +114,24 @@ int mac802154_req_associate(MACHANDLE mac, ret = mac802154_takesem(&priv->exclsem, true); if (ret < 0) { - mac802154_givesem(&priv->op_sem); + mac802154_givesem(&priv->opsem); return ret; } /* Set the channel and channel page of the PHY layer */ - priv->radio->set_attr(priv->radio, IEEE802154_ATTR_PHY_CURRENT_CHANNEL, - (FAR const union ieee802154_attr_u *)&req->chnum); - - priv->radio->set_attr(priv->radio, IEEE802154_ATTR_PHY_CURRENT_PAGE, - (FAR const union ieee802154_attr_u *)&req->chpage); + mac802154_setchannel(priv, req->chan); + mac802154_setchpage(priv, req->chpage); /* Set the coordinator address attributes */ - memcpy(&priv->coordaddr, &req->coordaddr, sizeof(struct ieee802154_addr_s)); + mac802154_setcoordaddr(priv, &req->coordaddr); + + /* TODO: Need to send coordinator address to radio layer */ /* Copy the coordinator PAN ID to our PAN ID */ - IEEE802154_PANIDCOPY(priv->addr.panid, req->coordaddr.panid); - - priv->radio->set_attr(priv->radio, IEEE802154_ATTR_MAC_PANID, - (FAR const union ieee802154_attr_u *)req->coordaddr.panid); + mac802154_setpanid(priv, req->coordaddr.panid); /* Copy in the capabilities information bitfield */ @@ -171,18 +166,19 @@ int mac802154_req_associate(MACHANDLE mac, { iob_free(iob); mac802154_givesem(&priv->exclsem); - mac802154_givesem(&priv->op_sem); + mac802154_givesem(&priv->opsem); return ret; } /* Get a uin16_t reference to the first two bytes. ie frame control field */ - u16 = (FAR uint16_t *)&iob->io_data[0]; + iob->io_data[0] = 0; + iob->io_data[1] = 0; - *u16 = (IEEE802154_FRAME_COMMAND << IEEE802154_FRAMECTRL_SHIFT_FTYPE); - *u16 |= IEEE802154_FRAMECTRL_ACKREQ; - *u16 |= (priv->coordaddr.mode << IEEE802154_FRAMECTRL_SHIFT_DADDR); - *u16 |= (IEEE802154_ADDRMODE_EXTENDED << IEEE802154_FRAMECTRL_SHIFT_SADDR); + IEEE802154_SETACKREQ(iob->io_data, 0); + IEEE802154_SETFTYPE(iob->io_data, 0, IEEE802154_FRAME_COMMAND); + IEEE802154_SETDADDRMODE(iob->io_data, 0, priv->pandesc.coordaddr.mode); + IEEE802154_SETSADDRMODE(iob->io_data, 0, IEEE802154_ADDRMODE_EXTENDED); iob->io_len = 2; @@ -197,20 +193,20 @@ int mac802154_req_associate(MACHANDLE mac, * PAN to which to associate. [1] pg. 68 */ - mac802154_putpanid(iob, priv->coordaddr.panid); + mac802154_putpanid(iob, priv->pandesc.coordaddr.panid); /* The Destination Address field shall contain the address from the beacon * frame that was transmitted by the coordinator to which the association * request command is being sent. [1] pg. 68 */ - if (priv->coordaddr.mode == IEEE802154_ADDRMODE_SHORT) + if (priv->pandesc.coordaddr.mode == IEEE802154_ADDRMODE_SHORT) { - mac802154_putsaddr(iob, priv->coordaddr.saddr); + mac802154_putsaddr(iob, priv->pandesc.coordaddr.saddr); } - else if (priv->coordaddr.mode == IEEE802154_ADDRMODE_EXTENDED) + else if (priv->pandesc.coordaddr.mode == IEEE802154_ADDRMODE_EXTENDED) { - mac802154_puteaddr(iob, priv->coordaddr.eaddr); + mac802154_puteaddr(iob, priv->pandesc.coordaddr.eaddr); } /* The Source PAN Identifier field shall contain the broadcast PAN identifier.*/ @@ -258,7 +254,7 @@ int mac802154_req_associate(MACHANDLE mac, mac802154_givesem(&priv->exclsem); - /* Association Request commands get sent out immediately */ + /* Association Request command gets sent out immediately */ priv->radio->txdelayed(priv->radio, txdesc, 0); @@ -281,7 +277,6 @@ int mac802154_resp_associate(MACHANDLE mac, (FAR struct ieee802154_privmac_s *)mac; FAR struct ieee802154_txdesc_s *txdesc; FAR struct iob_s *iob; - FAR uint16_t *u16; int ret; /* Allocate an IOB to put the frame in */ @@ -294,10 +289,6 @@ int mac802154_resp_associate(MACHANDLE mac, iob->io_offset = 0; iob->io_pktlen = 0; - /* Get a uin16_t reference to the first two bytes. ie frame control field */ - - u16 = (FAR uint16_t *)&iob->io_data[0]; - /* The Destination Addressing Mode and Source Addressing Mode fields shall * each be set to indicate extended addressing. * @@ -307,12 +298,13 @@ int mac802154_resp_associate(MACHANDLE mac, * The PAN ID Compression field shall be set to one. [1] pg. 69 */ - *u16 = (IEEE802154_FRAME_COMMAND << IEEE802154_FRAMECTRL_SHIFT_FTYPE); - *u16 |= IEEE802154_FRAMECTRL_ACKREQ; - *u16 |= IEEE802154_FRAMECTRL_PANIDCOMP; - *u16 |= (IEEE802154_ADDRMODE_EXTENDED << IEEE802154_FRAMECTRL_SHIFT_DADDR); - *u16 |= (IEEE802154_ADDRMODE_EXTENDED << IEEE802154_FRAMECTRL_SHIFT_SADDR); - + iob->io_data[0] = 0; + iob->io_data[1] = 0; + IEEE802154_SETACKREQ(iob->io_data, 0); + IEEE802154_SETPANIDCOMP(iob->io_data, 0); + IEEE802154_SETFTYPE(iob->io_data, 0, IEEE802154_FRAME_COMMAND); + IEEE802154_SETDADDRMODE(iob->io_data, 0, IEEE802154_ADDRMODE_EXTENDED); + IEEE802154_SETSADDRMODE(iob->io_data, 0, IEEE802154_ADDRMODE_EXTENDED); iob->io_len = 2; /* Each time a data or a MAC command frame is generated, the MAC sublayer @@ -326,9 +318,9 @@ int mac802154_resp_associate(MACHANDLE mac, * Destination PAN Identifier field shall contain the value of macPANId, while * the Source PAN Identifier field shall be omitted. [1] pg. 69 */ - + mac802154_putpanid(iob, priv->addr.panid); - + /* The Destination Address field shall contain the extended address of the * device requesting association. [1] pg. 69 */ @@ -445,7 +437,7 @@ void mac802154_txdone_assocreq(FAR struct ieee802154_privmac_s *priv, priv->curr_op = MAC802154_OP_NONE; priv->cmd_desc = NULL; - mac802154_givesem(&priv->op_sem); + mac802154_givesem(&priv->opsem); /* Release the MAC, call the callback, get exclusive access again */ @@ -468,7 +460,7 @@ void mac802154_txdone_assocreq(FAR struct ieee802154_privmac_s *priv, * the coordinator after macResponseWaitTime. [1] pg. 34 */ - if (priv->trackingbeacon) + if (priv->sfspec.beaconorder < 15) { /* We are tracking the beacon, so we should see our address in the * beacon frame within macResponseWaitTime if the coordinator is going @@ -479,7 +471,7 @@ void mac802154_txdone_assocreq(FAR struct ieee802154_privmac_s *priv, mac802154_timerstart(priv, (priv->resp_waittime * IEEE802154_BASE_SUPERFRAME_DURATION), - mac802154_timeout_assoc); + mac802154_assoctimeout); } else { @@ -488,7 +480,7 @@ void mac802154_txdone_assocreq(FAR struct ieee802154_privmac_s *priv, * extended */ - DEBUGASSERT(priv->coordaddr.mode != IEEE802154_ADDRMODE_NONE); + DEBUGASSERT(priv->pandesc.coordaddr.mode != IEEE802154_ADDRMODE_NONE); /* Send the Data Request MAC command after macResponseWaitTime to * extract the data from the coordinator. @@ -496,8 +488,8 @@ void mac802154_txdone_assocreq(FAR struct ieee802154_privmac_s *priv, mac802154_txdesc_alloc(priv, &respdesc, false); - mac802154_create_datareq(priv, &priv->coordaddr, - IEEE802154_ADDRMODE_EXTENDED, respdesc); + mac802154_createdatareq(priv, &priv->pandesc.coordaddr, + IEEE802154_ADDRMODE_EXTENDED, respdesc); priv->curr_cmd = IEEE802154_CMD_DATA_REQ; @@ -577,7 +569,7 @@ void mac802154_txdone_datareq_assoc(FAR struct ieee802154_privmac_s *priv, priv->curr_op = MAC802154_OP_NONE; priv->cmd_desc = NULL; - mac802154_givesem(&priv->op_sem); + mac802154_givesem(&priv->opsem); /* Release the MAC, call the callback, get exclusive access again */ @@ -593,7 +585,7 @@ void mac802154_txdone_datareq_assoc(FAR struct ieee802154_privmac_s *priv, * the corresponding data frame from the coordinator. [1] pg.43 */ - priv->radio->rxenable(priv->radio, true); + mac802154_rxenable(priv); /* Start a timer, if we receive the data frame, we will cancel * the timer, otherwise it will expire and we will notify the @@ -601,7 +593,7 @@ void mac802154_txdone_datareq_assoc(FAR struct ieee802154_privmac_s *priv, */ mac802154_timerstart(priv, priv->max_frame_waittime, - mac802154_timeout_assoc); + mac802154_assoctimeout); /* We can deallocate the data conf notification as it is no longer * needed. We can't use the public function here since we already @@ -728,7 +720,7 @@ void mac802154_rx_assocresp(FAR struct ieee802154_privmac_s *priv, /* Inform the radio of the address change */ - priv->radio->set_attr(priv->radio, IEEE802154_ATTR_MAC_SHORT_ADDRESS, + priv->radio->set_attr(priv->radio, IEEE802154_ATTR_MAC_SADDR, (FAR union ieee802154_attr_u *)priv->addr.saddr); /* A Short Address field value equal to 0xfffe shall indicate that the device @@ -767,7 +759,7 @@ void mac802154_rx_assocresp(FAR struct ieee802154_privmac_s *priv, priv->curr_op = MAC802154_OP_NONE; priv->cmd_desc = NULL; - mac802154_givesem(&priv->op_sem); + mac802154_givesem(&priv->opsem); /* Notify the next highest layer of the association status */ @@ -779,7 +771,7 @@ void mac802154_rx_assocresp(FAR struct ieee802154_privmac_s *priv, ****************************************************************************/ /**************************************************************************** - * Name: mac802154_timeout_assoc + * Name: mac802154_assoctimeout * * Description: * Function registered with MAC timer that gets called via the work queue to @@ -787,7 +779,7 @@ void mac802154_rx_assocresp(FAR struct ieee802154_privmac_s *priv, * ****************************************************************************/ -static void mac802154_timeout_assoc(FAR struct ieee802154_privmac_s *priv) +static void mac802154_assoctimeout(FAR struct ieee802154_privmac_s *priv) { FAR struct ieee802154_notif_s *notif; @@ -809,8 +801,8 @@ static void mac802154_timeout_assoc(FAR struct ieee802154_privmac_s *priv) /* We are no longer performing the association operation */ priv->curr_op = MAC802154_OP_NONE; - priv->cmd_desc = NULL; - mac802154_givesem(&priv->op_sem); + priv->cmd_desc = NULL; + mac802154_givesem(&priv->opsem); /* Release the MAC */ diff --git a/wireless/ieee802154/mac802154_data.c b/wireless/ieee802154/mac802154_data.c index c97d55eddb..171751169b 100644 --- a/wireless/ieee802154/mac802154_data.c +++ b/wireless/ieee802154/mac802154_data.c @@ -82,12 +82,15 @@ int mac802154_req_data(MACHANDLE mac, uint8_t mhr_len = 3; int ret; + wlinfo("Received frame io_len=%u io_offset=%u\n", + frame->io_len, frame->io_offset); + /* Check the required frame size */ if (frame->io_len > IEEE802154_MAX_PHY_PACKET_SIZE) - { - return -E2BIG; - } + { + return -E2BIG; + } /* Cast the first two bytes of the IOB to a uint16_t frame control field */ @@ -147,6 +150,9 @@ int mac802154_req_data(MACHANDLE mac, ret = mac802154_takesem(&priv->exclsem, true); if (ret < 0) { + /* Should only fail if interrupted by a signal */ + + wlwarn("WARNING: mac802154_takesem failed: %d\n", ret); return ret; } @@ -201,7 +207,8 @@ int mac802154_req_data(MACHANDLE mac, if (priv->devmode != IEEE802154_DEVMODE_PANCOORD) { - return -EINVAL; + ret = -EINVAL; + goto errout_with_sem; } } @@ -222,18 +229,32 @@ int mac802154_req_data(MACHANDLE mac, * here that created the header */ + wlinfo("mhr_len=%u\n", mhr_len); DEBUGASSERT(mhr_len == frame->io_offset); - frame->io_offset = 0; /* Set the offset to 0 to include the header */ - /* Allocate the txdesc, waiting if necessary, allow interruptions */ ret = mac802154_txdesc_alloc(priv, &txdesc, true); if (ret < 0) { + /* Should only fail if interrupted by a signal while re-acquiring + * exclsem. So the lock is not held if a failure is returned. + */ + + wlwarn("WARNING: mac802154_txdesc_alloc failed: %d\n", ret); return ret; } + /* Set the offset to 0 to include the header ( we do not want to + * modify the frame until AFTER the last place that -EINTR could + * be returned and could generate a retry. Subsequent error returns + * are fatal and no retry should occur. + */ + + frame->io_offset = 0; + + /* Then initialize the TX descriptor */ + txdesc->conf->handle = meta->msdu_handle; txdesc->frame = frame; txdesc->frametype = IEEE802154_FRAME_DATA; @@ -259,11 +280,8 @@ int mac802154_req_data(MACHANDLE mac, * don't have to try and kick-off any transmission here. */ - /* We no longer need to have the MAC layer locked. */ - - mac802154_givesem(&priv->exclsem); - - return -ENOTSUP; + ret = -ENOTSUP; + goto errout_with_txdesc; } else { @@ -299,8 +317,8 @@ int mac802154_req_data(MACHANDLE mac, } else { - mac802154_givesem(&priv->exclsem); - return -EINVAL; + ret = -EINVAL; + goto errout_with_txdesc; } } else @@ -320,6 +338,16 @@ int mac802154_req_data(MACHANDLE mac, } return OK; + +errout_with_txdesc: + /* Free TX the descriptor, but preserve the IOB. */ + + txdesc->frame = NULL; + mac802154_txdesc_free(priv, txdesc); + +errout_with_sem: + mac802154_givesem(&priv->exclsem); + return ret; } /**************************************************************************** diff --git a/wireless/ieee802154/mac802154_getset.c b/wireless/ieee802154/mac802154_getset.c index 083086b66b..ba0f5f676a 100644 --- a/wireless/ieee802154/mac802154_getset.c +++ b/wireless/ieee802154/mac802154_getset.c @@ -86,10 +86,10 @@ int mac802154_req_get(MACHANDLE mac, enum ieee802154_attr_e attr, case IEEE802154_ATTR_MAC_PANID: IEEE802154_PANIDCOPY(attrval->mac.panid, priv->addr.panid); break; - case IEEE802154_ATTR_MAC_SHORT_ADDRESS: + case IEEE802154_ATTR_MAC_SADDR: IEEE802154_SADDRCOPY(attrval->mac.saddr, priv->addr.saddr); break; - case IEEE802154_ATTR_MAC_EXTENDED_ADDR: + case IEEE802154_ATTR_MAC_EADDR: IEEE802154_EADDRCOPY(attrval->mac.eaddr, priv->addr.eaddr); break; case IEEE802154_ATTR_MAC_DEVMODE: @@ -100,7 +100,7 @@ int mac802154_req_get(MACHANDLE mac, enum ieee802154_attr_e attr, * it along. */ - ret = priv->radio->set_attr(priv->radio, attr, attrval); + ret = priv->radio->get_attr(priv->radio, attr, attrval); break; } @@ -133,36 +133,38 @@ int mac802154_req_set(MACHANDLE mac, enum ieee802154_attr_e attr, { case IEEE802154_ATTR_MAC_PANID: { - IEEE802154_PANIDCOPY(priv->addr.panid, attrval->mac.panid); - - /* Tell the radio about the attribute */ - - priv->radio->set_attr(priv->radio, attr, attrval); - + mac802154_setpanid(priv, attrval->mac.panid); ret = IEEE802154_STATUS_SUCCESS; } break; - case IEEE802154_ATTR_MAC_SHORT_ADDRESS: + case IEEE802154_ATTR_MAC_SADDR: { - IEEE802154_SADDRCOPY(priv->addr.saddr, attrval->mac.saddr); - - /* Tell the radio about the attribute */ - - priv->radio->set_attr(priv->radio, attr, attrval); - + mac802154_setsaddr(priv, attrval->mac.saddr); ret = IEEE802154_STATUS_SUCCESS; } break; - case IEEE802154_ATTR_MAC_EXTENDED_ADDR: + case IEEE802154_ATTR_MAC_EADDR: { - /* Set the MAC copy of the address in the table */ - - IEEE802154_EADDRCOPY(priv->addr.eaddr, attrval->mac.eaddr); - - /* Tell the radio about the attribute */ - - priv->radio->set_attr(priv->radio, attr, attrval); - + mac802154_seteaddr(priv, attrval->mac.eaddr); + ret = IEEE802154_STATUS_SUCCESS; + } + break; + case IEEE802154_ATTR_MAC_COORD_SADDR: + { + mac802154_setcoordsaddr(priv, attrval->mac.coordsaddr); + ret = IEEE802154_STATUS_SUCCESS; + } + break; + case IEEE802154_ATTR_MAC_COORD_EADDR: + { + mac802154_setcoordeaddr(priv, attrval->mac.coordeaddr); + ret = IEEE802154_STATUS_SUCCESS; + } + break; + case IEEE802154_ATTR_MAC_ASSOCIATION_PERMIT: + { + priv->sfspec.assocpermit = attrval->mac.assocpermit; + priv->beaconupdate = true; ret = IEEE802154_STATUS_SUCCESS; } break; diff --git a/wireless/ieee802154/mac802154_internal.h b/wireless/ieee802154/mac802154_internal.h index 2fa01eda5b..aa19f79f60 100644 --- a/wireless/ieee802154/mac802154_internal.h +++ b/wireless/ieee802154/mac802154_internal.h @@ -1,483 +1,706 @@ -/**************************************************************************** - * wireless/ieee802154/mac802154_internal.h - * - * Copyright (C) 2016 Sebastien Lorquet. All rights reserved. - * Copyright (C) 2017 Verge Inc. All rights reserved. - * Copyright (C) 2017 Gregory Nutt. All rights reserved. - * - * Author: Sebastien Lorquet - * Author: Anthony Merlino - * - * The naming and comments for various fields are taken directly - * from the IEEE 802.15.4 2011 standard. - * - * 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 __WIRELESS_IEEE802154__MAC802154_INTERNAL_H -#define __WIRELESS_IEEE802154__MAC802154_INTERNAL_H - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include "mac802154_notif.h" - -#include -#include - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#define mac802154_putpanid(iob, panid) \ - do \ - { \ - IEEE802154_PANIDCOPY(&iob->io_data[iob->io_len], panid); \ - iob->io_len += IEEE802154_PANIDSIZE; \ - } \ - while(0) - -#define mac802154_putsaddr(iob, saddr) \ - do \ - { \ - IEEE802154_SADDRCOPY(&iob->io_data[iob->io_len], saddr); \ - iob->io_len += IEEE802154_SADDRSIZE; \ - } \ - while(0) - -#define mac802154_puteaddr(iob, eaddr) \ - do \ - { \ - IEEE802154_EADDRCOPY(&iob->io_data[iob->io_len], eaddr); \ - iob->io_len += IEEE802154_EADDRSIZE; \ - } \ - while(0) - -#define mac802154_takepanid(iob, panid) \ - do \ - { \ - IEEE802154_PANIDCOPY(panid, &iob->io_data[iob->io_offset]); \ - iob->io_offset += IEEE802154_PANIDSIZE; \ - } \ - while(0) - -#define mac802154_takesaddr(iob, saddr) \ - do \ - { \ - IEEE802154_SADDRCOPY(saddr, &iob->io_data[iob->io_offset]); \ - iob->io_offset += IEEE802154_SADDRSIZE; \ - } \ - while(0) - -#define mac802154_takeeaddr(iob, eaddr) \ - do \ - { \ - IEEE802154_EADDRCOPY(eaddr, &iob->io_data[iob->io_offset]); \ - iob->io_offset += IEEE802154_EADDRSIZE; \ - } \ - while(0) - -/* General helper macros ****************************************************/ - -/* GET 16-bit data: source in network order, result in host order */ - -#define GETHOST16(ptr,index) \ - ((((uint16_t)((ptr)[index])) << 8) | ((uint16_t)(((ptr)[(index) + 1])))) - -/* GET 16-bit data: source in network order, result in network order */ - -#define GETNET16(ptr,index) \ - ((((uint16_t)((ptr)[(index) + 1])) << 8) | ((uint16_t)(((ptr)[index])))) - -/* PUT 16-bit data: source in host order, result in newtwork order */ - -#define PUTHOST16(ptr,index,value) \ - do \ - { \ - (ptr)[index] = ((uint16_t)(value) >> 8) & 0xff; \ - (ptr)[index + 1] = (uint16_t)(value) & 0xff; \ - } \ - while(0) - -/* Configuration ************************************************************/ -/* If processing is not done at the interrupt level, then work queue support - * is required. - */ - -#if !defined(CONFIG_SCHED_WORKQUEUE) -# error Work queue support is required in this configuration (CONFIG_SCHED_WORKQUEUE) -#else - - /* Use the low priority work queue if possible */ - -# if defined(CONFIG_MAC802154_HPWORK) -# define MAC802154_WORK HPWORK -# elif defined(CONFIG_MAC802154_LPWORK) -# define MAC802154_WORK LPWORK -# else -# error Neither CONFIG_MAC802154_HPWORK nor CONFIG_MAC802154_LPWORK defined -# endif -#endif - -#if !defined(CONFIG_MAC802154_NNOTIF) || CONFIG_MAC802154_NNOTIF <= 0 -# undef CONFIG_MAC802154_NNOTIF -# define CONFIG_MAC802154_NNOTIF 6 -#endif - -#if !defined(CONFIG_MAC802154_NTXDESC) || CONFIG_MAC802154_NTXDESC <= 0 -# undef CONFIG_MAC802154_NTXDESC -# define CONFIG_MAC802154_NTXDESC 3 -#endif - -#if CONFIG_MAC802154_NTXDESC > CONFIG_MAC802154_NNOTIF -#error CONFIG_MAC802154_NNOTIF must be greater than CONFIG_MAC802154_NTXDESC -#endif - -#if !defined(CONFIG_IEEE802154_DEFAULT_EADDR) -#define CONFIG_IEEE802154_DEFAULT_EADDR 0xFFFFFFFFFFFFFFFF -#endif - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/* Map between ieee802154_addrmode_e enum and actual address length */ - -static const uint8_t mac802154_addr_length[4] = {0, 0, 2, 8}; - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -struct mac802154_radiocb_s -{ - struct ieee802154_radiocb_s cb; - FAR struct ieee802154_privmac_s *priv; -}; - -/* Enumeration for representing what operation the MAC layer is currently doing. - * There can only be one command being handled at any given time, but certain - * operations such as association requires more than one command to be sent. - * Therefore, the need to track not only what command is currently active, but - * also, what overall operation the command is apart of is necessary. - */ - -enum mac802154_operation_e -{ - MAC802154_OP_NONE, - MAC802154_OP_ASSOC, - MAC802154_OP_POLL -}; - -struct ieee802154_privmac_s; /* Forward Reference */ -typedef void (*mac802154_worker_t)(FAR struct ieee802154_privmac_s *priv); - -/* The privmac structure holds the internal state of the MAC and is the - * underlying represention of the opaque MACHANDLE. It contains storage for - * the IEEE802.15.4 MIB attributes. - */ - -struct ieee802154_privmac_s -{ - FAR struct ieee802154_radio_s *radio; /* Contained IEEE802.15.4 radio dev */ - FAR struct mac802154_maccb_s *cb; /* Head of a list of MAC callbacks */ - FAR struct mac802154_radiocb_s radiocb; /* Interface to bind to radio */ - - sem_t exclsem; /* Support exclusive access */ - uint8_t nclients; /* Number of notification clients */ - uint8_t nnotif; /* Number of remaining notifications */ - - /* Only support a single command at any given time. As of now I see no - * condition where you need to have more than one command frame simultaneously - */ - - sem_t op_sem; /* Exclusive operations */ - enum mac802154_operation_e curr_op; /* The current overall operation */ - enum ieee802154_cmdid_e curr_cmd; /* Type of the current cmd */ - FAR struct ieee802154_txdesc_s *cmd_desc; /* TX descriptor for current cmd */ - - /* Pre-allocated notifications to be passed to the registered callback. These - * need to be freed by the application using mac802154_xxxxnotif_free when - * the callee layer is finished with it's use. - */ - - FAR struct mac802154_notif_s *notif_free; - struct mac802154_notif_s notif_pool[CONFIG_MAC802154_NNOTIF]; - sem_t notif_sem; - - struct ieee802154_txdesc_s txdesc_pool[CONFIG_IEEE802154_NTXDESC]; - sem_t txdesc_sem; - sq_queue_t txdesc_queue; - sq_queue_t txdone_queue; - - - /* Support a singly linked list of transactions that will be sent using the - * CSMA algorithm. On a non-beacon enabled PAN, these transactions will be - * sent whenever. On a beacon-enabled PAN, these transactions will be sent - * during the CAP of the Coordinator's superframe. - */ - - sq_queue_t csma_queue; - sq_queue_t gts_queue; - - /* Support a singly linked list of transactions that will be sent indirectly. - * This list should only be used by a MAC acting as a coordinator. These - * transactions will stay here until the data is extracted by the destination - * device sending a Data Request MAC command or if too much time passes. This - * list should also be used to populate the address list of the outgoing - * beacon frame. - */ - - sq_queue_t indirect_queue; - - /* Support a singly linked list of frames received */ - - sq_queue_t dataind_queue; - - /* Work structures for offloading aynchronous work */ - - struct work_s tx_work; - struct work_s rx_work; - - struct work_s timeout_work; - WDOG_ID timeout; /* Timeout watchdog */ - mac802154_worker_t timeout_worker; - - struct work_s purge_work; - - /* MAC PIB attributes, grouped to save memory */ - - /* Holds all address information (Extended, Short, and PAN ID) for the MAC. */ - - struct ieee802154_addr_s addr; - - /* Holds all address information (Extended, Short) for Coordinator */ - - struct ieee802154_addr_s coordaddr; - - /* The maximum number of symbols to wait for an acknowledgement frame to - * arrive following a transmitted data frame. [1] pg. 126 - * - * NOTE: This may be able to be a 16-bit or even an 8-bit number. I wasn't - * sure at the time what the range of reasonable values was. - */ - - uint32_t ack_waitdur; - - /* The maximum time to wait either for a frame intended as a response to a - * data request frame or for a broadcast frame following a beacon with the - * Frame Pending field set to one. [1] pg. 127 - * - * NOTE: This may be able to be a 16-bit or even an 8-bit number. I wasn't - * sure at the time what the range of reasonable values was. - */ - - uint32_t max_frame_waittime; - - /* The maximum time (in unit periods) that a transaction is stored by a - * coordinator and indicated in its beacon. - */ - - uint16_t trans_persisttime; - - /* Contents of beacon payload */ - - uint8_t beacon_payload[IEEE802154_MAX_BEACON_PAYLOAD_LEN]; - uint8_t beacon_payload_len; /* Length of beacon payload */ - - uint8_t battlifeext_periods; /* # of backoff periods during which rx is - * enabled after the IFS following beacon */ - - uint8_t bsn; /* Seq. num added to tx beacon frame */ - uint8_t dsn; /* Seq. num added to tx data or MAC frame */ - uint8_t maxretries; /* Max # of retries alloed after tx failure */ - - /* The maximum time, in multiples of aBaseSuperframeDuration, a device shall - * wait for a response command frame to be available following a request - * command frame. [1] 128. - */ - - uint8_t resp_waittime; - - /* The total transmit duration (including PHY header and FCS) specified in - * symbols. [1] pg. 129. - */ - - uint32_t tx_totaldur; - - /* Start of 32-bit bitfield */ - - uint32_t trackingbeacon : 1; /* Are we tracking the beacon */ - uint32_t isassoc : 1; /* Are we associated to the PAN */ - uint32_t assocpermit : 1; /* Are we allowing assoc. as a coord. */ - uint32_t autoreq : 1; /* Automatically send data req. if addr - * addr is in the beacon frame */ - - uint32_t battlifeext : 1; /* Is BLE enabled */ - uint32_t gtspermit : 1; /* Is PAN Coord. accepting GTS reqs. */ - uint32_t promisc : 1; /* Is promiscuous mode on? */ - uint32_t rngsupport : 1; /* Does MAC sublayer support ranging */ - uint32_t sec_enabled : 1; /* Does MAC sublayer have security en. */ - uint32_t timestamp_support : 1; /* Does MAC layer supports timestamping */ - - /* 2 available bits */ - - uint32_t beaconorder : 4; /* Freq. that beacon is transmitted */ - - uint32_t superframeorder : 4; /* Length of active portion of outgoing - * superframe, including the beacon */ - - /* The offset, measured is symbols, between the symbol boundary at which the - * MLME captures the timestamp of each transmitted and received frame, and - * the onset of the first symbol past the SFD, namely the first symbol of - * the frames [1] pg. 129. - */ - - uint32_t sync_symboffset : 12; - - /* End of 32-bit bitfield */ - - /* Start of 32-bit bitfield */ - - uint32_t beacon_txtime : 24; /* Time of last beacon transmit */ - uint32_t minbe : 4; /* Min value of backoff exponent (BE) */ - uint32_t maxbe : 4; /* Max value of backoff exponent (BE) */ - - /* End of 32-bit bitfield */ - - /* Start of 32-bit bitfield */ - - uint32_t txctrl_activedur : 17; /* Duration for which tx is permitted to - * be active */ - uint32_t txctrl_pausedur : 1; /* Duration after tx before another tx is - * permitted. 0=2000, 1= 10000 */ - - /* What type of device is this node acting as */ - - enum ieee802154_devmode_e devmode : 2; - - uint32_t max_csmabackoffs : 3; /* Max num backoffs for CSMA algorithm - * before declaring ch access failure */ - - /* 9-bits remaining */ - - /* End of 32-bit bitfield. */ - - /* TODO: Add Security-related MAC PIB attributes */ -}; - -/**************************************************************************** - * Inline Functions - ****************************************************************************/ - -#define mac802154_givesem(s) sem_post(s); - -static inline int mac802154_takesem(sem_t *sem, bool allowinterrupt) -{ - int ret; - do - { - /* Take a count from the semaphore, possibly waiting */ - - ret = sem_wait(sem); - if (ret < 0) - { - /* EINTR is the only error that we expect */ - - DEBUGASSERT(get_errno() == EINTR); - - if (allowinterrupt) - { - return -EINTR; - } - } - } - while (ret != OK); - - return OK; -} - -static inline void mac802154_txdesc_free(FAR struct ieee802154_privmac_s *priv, - FAR struct ieee802154_txdesc_s *txdesc) -{ - sq_addlast((FAR sq_entry_t *)txdesc, &priv->txdesc_queue); - mac802154_givesem(&priv->txdesc_sem); -} - -/**************************************************************************** - * Name: mac802154_timercancel - * - * Description: - * Cancel timer and remove reference to callback function - * - * Assumptions: - * priv MAC struct is locked when calling. - * - ****************************************************************************/ - -static inline int mac802154_timercancel(FAR struct ieee802154_privmac_s *priv) -{ - wd_cancel(priv->timeout); - priv->timeout_worker = NULL; - return OK; -} - -/**************************************************************************** - * Function Prototypes - ****************************************************************************/ - - -int mac802154_txdesc_alloc(FAR struct ieee802154_privmac_s *priv, - FAR struct ieee802154_txdesc_s **txdesc, - bool allow_interrupt); - -int mac802154_timerstart(FAR struct ieee802154_privmac_s *priv, - uint32_t numsymbols, mac802154_worker_t); - -void mac802154_setupindirect(FAR struct ieee802154_privmac_s *priv, - FAR struct ieee802154_txdesc_s *txdesc); - -void mac802154_create_datareq(FAR struct ieee802154_privmac_s *priv, - FAR struct ieee802154_addr_s *coordaddr, - enum ieee802154_addrmode_e srcmode, - FAR struct ieee802154_txdesc_s *txdesc); - -#endif /* __WIRELESS_IEEE802154__MAC802154_INTERNAL_H */ +/**************************************************************************** + * wireless/ieee802154/mac802154_internal.h + * + * Copyright (C) 2016 Sebastien Lorquet. All rights reserved. + * Copyright (C) 2017 Verge Inc. All rights reserved. + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * + * Author: Sebastien Lorquet + * Author: Anthony Merlino + * + * The naming and comments for various fields are taken directly + * from the IEEE 802.15.4 2011 standard. + * + * 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 __WIRELESS_IEEE802154__MAC802154_INTERNAL_H +#define __WIRELESS_IEEE802154__MAC802154_INTERNAL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "mac802154_notif.h" + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ +/* If processing is not done at the interrupt level, then work queue support + * is required. + */ + +#if !defined(CONFIG_SCHED_WORKQUEUE) +# error Work queue support is required in this configuration (CONFIG_SCHED_WORKQUEUE) +#else + + /* Use the low priority work queue if possible */ + +# if defined(CONFIG_MAC802154_HPWORK) +# define MAC802154_WORK HPWORK +# elif defined(CONFIG_MAC802154_LPWORK) +# define MAC802154_WORK LPWORK +# else +# error Neither CONFIG_MAC802154_HPWORK nor CONFIG_MAC802154_LPWORK defined +# endif +#endif + +#if !defined(CONFIG_MAC802154_NNOTIF) || CONFIG_MAC802154_NNOTIF <= 0 +# undef CONFIG_MAC802154_NNOTIF +# define CONFIG_MAC802154_NNOTIF 6 +#endif + +#if !defined(CONFIG_MAC802154_NTXDESC) || CONFIG_MAC802154_NTXDESC <= 0 +# undef CONFIG_MAC802154_NTXDESC +# define CONFIG_MAC802154_NTXDESC 3 +#endif + +#if CONFIG_MAC802154_NTXDESC > CONFIG_MAC802154_NNOTIF +# error CONFIG_MAC802154_NNOTIF must be greater than CONFIG_MAC802154_NTXDESC +#endif + +#if !defined(CONFIG_IEEE802154_DEFAULT_EADDR) +# define CONFIG_IEEE802154_DEFAULT_EADDR 0xFFFFFFFFFFFFFFFF +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Map between ieee802154_addrmode_e enum and actual address length */ + +static const uint8_t mac802154_addr_length[4] = {0, 0, 2, 8}; + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct mac802154_radiocb_s +{ + struct ieee802154_radiocb_s cb; + FAR struct ieee802154_privmac_s *priv; +}; + +/* Enumeration for representing what operation the MAC layer is currently doing. + * There can only be one command being handled at any given time, but certain + * operations such as association requires more than one command to be sent. + * Therefore, the need to track not only what command is currently active, but + * also, what overall operation the command is apart of is necessary. + */ + +enum mac802154_operation_e +{ + MAC802154_OP_NONE, + MAC802154_OP_ASSOC, + MAC802154_OP_POLL, + MAC802154_OP_SCAN +}; + +struct ieee802154_privmac_s; /* Forward Reference */ +typedef void (*mac802154_worker_t)(FAR struct ieee802154_privmac_s *priv); + +/* The privmac structure holds the internal state of the MAC and is the + * underlying represention of the opaque MACHANDLE. It contains storage for + * the IEEE802.15.4 MIB attributes. + */ + +struct ieee802154_privmac_s +{ + /*************************** General Fields *********************************/ + + FAR struct ieee802154_radio_s *radio; /* Contained IEEE802.15.4 radio dev */ + FAR struct mac802154_maccb_s *cb; /* Head of a list of MAC callbacks */ + FAR struct mac802154_radiocb_s radiocb; /* Interface to bind to radio */ + + sem_t exclsem; /* Support exclusive access */ + uint8_t nclients; /* Number of notification clients */ + uint8_t nnotif; /* Number of remaining notifications */ + + /* Only support a single command at any given time. As of now I see no + * condition where you need to have more than one command frame simultaneously + */ + + sem_t opsem; /* Exclusive operations */ + + /******************* Fields related to MAC operations ***********************/ + + enum mac802154_operation_e curr_op; /* The current overall operation */ + enum ieee802154_cmdid_e curr_cmd; /* Type of the current cmd */ + FAR struct ieee802154_txdesc_s *cmd_desc; /* TX descriptor for current cmd */ + uint8_t nrxusers; + + /******************* Fields related to SCAN operation ***********************/ + + /* List of PAN descriptors to track during scan procedures */ + + uint8_t scanindex; + uint8_t npandesc; + struct ieee802154_pandesc_s pandescs[MAC802154_NPANDESC]; + uint8_t panidbeforescan[IEEE802154_PANIDSIZE]; + struct ieee802154_scan_req_s currscan; + uint32_t scansymdur; + + /******************* Fields related to notifications ************************/ + + /* Pre-allocated notifications to be passed to the registered callback. These + * need to be freed by the application using mac802154_xxxxnotif_free when + * the callee layer is finished with it's use. + */ + + FAR struct mac802154_notif_s *notif_free; + struct mac802154_notif_s notif_pool[CONFIG_MAC802154_NNOTIF]; + sem_t notif_sem; + + /******************* Tx descriptor queues and pools *************************/ + + struct ieee802154_txdesc_s txdesc_pool[CONFIG_MAC802154_NTXDESC]; + sem_t txdesc_sem; + sq_queue_t txdesc_queue; + sq_queue_t txdone_queue; + + /* Support a singly linked list of transactions that will be sent using the + * CSMA algorithm. On a non-beacon enabled PAN, these transactions will be + * sent whenever. On a beacon-enabled PAN, these transactions will be sent + * during the CAP of the Coordinator's superframe. + */ + + sq_queue_t csma_queue; + sq_queue_t gts_queue; + + /* Support a singly linked list of transactions that will be sent indirectly. + * This list should only be used by a MAC acting as a coordinator. These + * transactions will stay here until the data is extracted by the destination + * device sending a Data Request MAC command or if too much time passes. This + * list should also be used to populate the address list of the outgoing + * beacon frame. + */ + + sq_queue_t indirect_queue; + + /* Support a singly linked list of frames received */ + + sq_queue_t dataind_queue; + + /************* Fields related to addressing and coordinator *****************/ + + /* Holds all address information (Extended, Short, and PAN ID) for the MAC. */ + + struct ieee802154_addr_s addr; + + struct ieee802154_pandesc_s pandesc; + + /*************** Fields related to beacon-enabled networks ******************/ + + uint8_t bsn; /* Seq. num added to tx beacon frame */ + + /* Holds attributes pertaining to the superframe specification */ + + struct ieee802154_superframespec_s sfspec; + + /* We use 2 beacon frame structures so that we can ping-pong between them + * while updating the beacon + */ + + struct ieee802154_beaconframe_s beaconframe[2]; + + /* Contents of beacon payload */ + + uint8_t beaconpayload[IEEE802154_MAX_BEACON_PAYLOAD_LEN]; + uint8_t beaconpayloadlength; + + /****************** Fields related to offloading work ***********************/ + + /* Work structures for offloading aynchronous work */ + + struct work_s tx_work; + struct work_s rx_work; + + struct work_s timeout_work; + WDOG_ID timeout; /* Timeout watchdog */ + mac802154_worker_t timeout_worker; + + struct work_s purge_work; + + /****************** Uncategorized MAC PIB attributes ***********************/ + + /* The maximum number of symbols to wait for an acknowledgement frame to + * arrive following a transmitted data frame. [1] pg. 126 + * + * NOTE: This may be able to be a 16-bit or even an 8-bit number. I wasn't + * sure at the time what the range of reasonable values was. + */ + + uint32_t ack_waitdur; + + /* The maximum time to wait either for a frame intended as a response to a + * data request frame or for a broadcast frame following a beacon with the + * Frame Pending field set to one. [1] pg. 127 + * + * NOTE: This may be able to be a 16-bit or even an 8-bit number. I wasn't + * sure at the time what the range of reasonable values was. + */ + + uint32_t max_frame_waittime; + + /* The maximum time (in unit periods) that a transaction is stored by a + * coordinator and indicated in its beacon. + */ + + uint16_t trans_persisttime; + + uint8_t dsn; /* Seq. num added to tx data or MAC frame */ + + /* The maximum time, in multiples of aBaseSuperframeDuration, a device shall + * wait for a response command frame to be available following a request + * command frame. [1] 128. + */ + + uint8_t resp_waittime; + + /* The total transmit duration (including PHY header and FCS) specified in + * symbols. [1] pg. 129. + */ + + uint32_t tx_totaldur; + + /* Start of 8-bit bitfield */ + + uint32_t trackingbeacon : 1; /* Are we tracking the beacon */ + uint32_t isassoc : 1; /* Are we associated to the PAN */ + uint32_t autoreq : 1; /* Automatically send data req. if addr + * addr is in the beacon frame */ + + uint32_t gtspermit : 1; /* Is PAN Coord. accepting GTS reqs. */ + uint32_t promisc : 1; /* Is promiscuous mode on? */ + uint32_t rngsupport : 1; /* Does MAC sublayer support ranging */ + uint32_t sec_enabled : 1; /* Does MAC sublayer have security en. */ + uint32_t timestamp_support : 1; /* Does MAC layer supports timestamping */ + + /* End of 8-bit bitfield */ + + /* Start of 32-bit bitfield */ + + /* The offset, measured is symbols, between the symbol boundary at which the + * MLME captures the timestamp of each transmitted and received frame, and + * the onset of the first symbol past the SFD, namely the first symbol of + * the frames [1] pg. 129. + */ + + uint32_t sync_symboffset : 12; + + uint32_t txctrl_activedur : 17; /* Duration for which tx is permitted to + * be active */ + uint32_t txctrl_pausedur : 1; /* Duration after tx before another tx is + * permitted. 0=2000, 1= 10000 */ + + /* What type of device is this node acting as */ + + enum ieee802154_devmode_e devmode : 2; + + /* End of 32-bit bitfield */ + + /* Start of 32-bit bitfield */ + + uint32_t beacon_txtime : 24; /* Time of last beacon transmit */ + uint32_t minbe : 4; /* Min value of backoff exponent (BE) */ + uint32_t maxbe : 4; /* Max value of backoff exponent (BE) */ + + /* End of 32-bit bitfield */ + + /* Start of 8-bit bitfield */ + + uint8_t bf_ind : 1; /* Ping-pong index for beacon frame */ + uint8_t beaconupdate : 1; /* Does the beacon frame need to be updated */ + uint8_t max_csmabackoffs : 3; /* Max num backoffs for CSMA algorithm + * before declaring ch access failure */ + uint8_t maxretries : 3; /* Max # of retries allowed after tx fail */ + /* End of 8-bit bitfield. */ + + /* TODO: Add Security-related MAC PIB attributes */ +}; + +/**************************************************************************** + * Function Prototypes + ****************************************************************************/ + +int mac802154_txdesc_alloc(FAR struct ieee802154_privmac_s *priv, + FAR struct ieee802154_txdesc_s **txdesc, + bool allow_interrupt); + +int mac802154_timerstart(FAR struct ieee802154_privmac_s *priv, + uint32_t numsymbols, mac802154_worker_t); + +void mac802154_setupindirect(FAR struct ieee802154_privmac_s *priv, + FAR struct ieee802154_txdesc_s *txdesc); + +void mac802154_createdatareq(FAR struct ieee802154_privmac_s *priv, + FAR struct ieee802154_addr_s *coordaddr, + enum ieee802154_addrmode_e srcmode, + FAR struct ieee802154_txdesc_s *txdesc); + +void mac802154_updatebeacon(FAR struct ieee802154_privmac_s *priv); + + + +/**************************************************************************** + * Helper Macros/Inline Functions + ****************************************************************************/ + +#define mac802154_putpanid(iob, panid) \ + do \ + { \ + IEEE802154_PANIDCOPY(&iob->io_data[iob->io_len], panid); \ + iob->io_len += IEEE802154_PANIDSIZE; \ + } \ + while(0) + +#define mac802154_putsaddr(iob, saddr) \ + do \ + { \ + IEEE802154_SADDRCOPY(&iob->io_data[iob->io_len], saddr); \ + iob->io_len += IEEE802154_SADDRSIZE; \ + } \ + while(0) + +#define mac802154_puteaddr(iob, eaddr) \ + do \ + { \ + IEEE802154_EADDRCOPY(&iob->io_data[iob->io_len], eaddr); \ + iob->io_len += IEEE802154_EADDRSIZE; \ + } \ + while(0) + +#define mac802154_takepanid(iob, panid) \ + do \ + { \ + IEEE802154_PANIDCOPY(panid, &iob->io_data[iob->io_offset]); \ + iob->io_offset += IEEE802154_PANIDSIZE; \ + } \ + while(0) + +#define mac802154_takesaddr(iob, saddr) \ + do \ + { \ + IEEE802154_SADDRCOPY(saddr, &iob->io_data[iob->io_offset]); \ + iob->io_offset += IEEE802154_SADDRSIZE; \ + } \ + while(0) + +#define mac802154_takeeaddr(iob, eaddr) \ + do \ + { \ + IEEE802154_EADDRCOPY(eaddr, &iob->io_data[iob->io_offset]); \ + iob->io_offset += IEEE802154_EADDRSIZE; \ + } \ + while(0) + +/* General helper macros ****************************************************/ + +/* GET 16-bit data: source in network order, result in host order */ + +#define GETHOST16(ptr,index) \ + ((((uint16_t)((ptr)[(index) + 1])) << 8) | ((uint16_t)(((ptr)[index])))) + +/* GET 16-bit data: source in network order, result in network order */ + +#define GETNET16(ptr,index) \ + ((((uint16_t)((ptr)[index])) << 8) | ((uint16_t)(((ptr)[(index) + 1])))) + +/* PUT 16-bit data: source in host order, result in network order */ + +#define PUTHOST16(ptr,index,value) \ + do \ + { \ + (ptr)[index] = (uint16_t)(value) & 0xff; \ + (ptr)[index + 1] = ((uint16_t)(value) >> 8) & 0xff; \ + } \ + while(0) + +/* Set bit in 16-bit value: source in host order, result in network order. */ + +#define IEEE802154_SETBITS_U16(ptr,index,value) \ + do \ + { \ + (ptr)[index] |= (uint16_t)(value) & 0xff; \ + (ptr)[index + 1] |= ((uint16_t)(value) >> 8) & 0xff; \ + } \ + while(0) + +/* Helper macros for setting/receiving bits for frame control field */ + +#define IEEE802154_SETFTYPE(ptr, index, ftype) \ + IEEE802154_SETBITS_U16(ptr, index, (ftype << IEEE802154_FRAMECTRL_SHIFT_FTYPE)) + +#define IEEE802154_SETACKREQ(ptr, index) \ + IEEE802154_SETBITS_U16(ptr, index, IEEE802154_FRAMECTRL_ACKREQ) + +#define IEEE802154_SETDADDRMODE(ptr, index, mode) \ + IEEE802154_SETBITS_U16(ptr, index, (mode << IEEE802154_FRAMECTRL_SHIFT_DADDR)) + +#define IEEE802154_SETSADDRMODE(ptr, index, mode) \ + IEEE802154_SETBITS_U16(ptr, index, (mode << IEEE802154_FRAMECTRL_SHIFT_SADDR)) + +#define IEEE802154_SETPANIDCOMP(ptr, index) \ + IEEE802154_SETBITS_U16(ptr, index, IEEE802154_FRAMECTRL_PANIDCOMP) + +#define IEEE802154_SETVERSION(ptr, index, version) \ + IEEE802154_SETBITS_U16(ptr, index, (version << IEEE802154_FRAMECTRL_SHIFT_VERSION)) + +/* Helper macros for setting/receiving bits for superframe specification */ + +#define IEEE802154_SETBEACONORDER(ptr, index, val) \ + IEEE802154_SETBITS_U16(ptr, index, (val << IEEE802154_SFSPEC_SHIFT_BEACONORDER)) + +#define IEEE802154_SETSFORDER(ptr, index, val) \ + IEEE802154_SETBITS_U16(ptr, index, (val << IEEE802154_SFSPEC_SHIFT_SFORDER)) + +#define IEEE802154_SETFINCAPSLOT(ptr, index, val) \ + IEEE802154_SETBITS_U16(ptr, index, (val << IEEE802154_SFSPEC_SHIFT_FINCAPSLOT)) + +#define IEEE802154_SETBLE(ptr, index) \ + IEEE802154_SETBITS_U16(ptr, index, IEEE802154_SFSPEC_BLE) + +#define IEEE802154_SETPANCOORD(ptr, index) \ + IEEE802154_SETBITS_U16(ptr, index, IEEE802154_SFSPEC_PANCOORD) + +#define IEEE802154_SETASSOCPERMIT(ptr, index) \ + IEEE802154_SETBITS_U16(ptr, index, IEEE802154_SFSPEC_ASSOCPERMIT) + +#define IEEE802154_GETBEACONORDER(ptr, index) \ + ((GETHOST16(ptr, index) & IEEE802154_SFSPEC_BEACONORDER) >> \ + IEEE802154_SFSPEC_SHIFT_BEACONORDER) + +#define IEEE802154_GETSFORDER(ptr, index) \ + ((GETHOST16(ptr, index) & IEEE802154_SFSPEC_SFORDER) >> \ + IEEE802154_SFSPEC_SHIFT_SFORDER) + +#define IEEE802154_GETFINCAPSLOT(ptr, index) \ + ((GETHOST16(ptr, index) & IEEE802154_SFSPEC_FINCAPSLOT) >> \ + IEEE802154_SFSPEC_SHIFT_FINCAPSLOT) + +#define IEEE802154_GETBLE(ptr, index) \ + ((GETHOST16(ptr, index) & IEEE802154_SFSPEC_BLE) >> \ + IEEE802154_SFSPEC_SHIFT_BLE) + +#define IEEE802154_GETPANCOORD(ptr, index) \ + ((GETHOST16(ptr, index) & IEEE802154_SFSPEC_PANCOORD) >> \ + IEEE802154_SFSPEC_SHIFT_PANCOORD) + +#define IEEE802154_GETASSOCPERMIT(ptr, index) \ + ((GETHOST16(ptr, index) & IEEE802154_SFSPEC_ASSOCPERMIT) >> \ + IEEE802154_SFSPEC_SHIFT_ASSOCPERMIT) + +/* Helper macros for setting/receiving bits for GTS specification */ + +#define IEEE802154_GETGTSDESCCOUNT(ptr, index) \ + ((GETHOST16(ptr, index) & IEEE802154_GTSSPEC_DESCCOUNT) >> \ + IEEE802154_GTSSPEC_SHIFT_DESCCOUNT) + +#define IEEE802154_GETGTSPERMIT(ptr, index) \ + ((GETHOST16(ptr, index) & IEEE802154_GTSSPEC_PERMIT) >> \ + IEEE802154_GTSSPEC_SHIFT_PERMIT) + +/* Helper macros for setting/receiving bits for GTS Directions */ + +#define IEEE802154_GETGTSDIRMASK(ptr, index) \ + ((GETHOST16(ptr, index) & IEEE802154_GTSDIR_MASK) >> \ + IEEE802154_GTSDIR_SHIFT_MASK) + +/* Helper macros for setting/receiving bits for Pending Address Specification */ + +#define IEEE802154_GETNPENDSADDR(ptr, index) \ + ((GETHOST16(ptr, index) & IEEE802154_PENDADDR_NSADDR) >> \ + IEEE802154_PENDADDR_SHIFT_NSADDR) + +#define IEEE802154_GETNPENDEADDR(ptr, index) \ + ((GETHOST16(ptr, index) & IEEE802154_PENDADDR_NEADDR) >> \ + IEEE802154_PENDADDR_SHIFT_NEADDR) + +/* General helper macros ****************************************************/ + +#define mac802154_givesem(s) sem_post(s); + +static inline int mac802154_takesem(sem_t *sem, bool allowinterrupt) +{ + int ret; + do + { + /* Take a count from the semaphore, possibly waiting */ + + ret = sem_wait(sem); + if (ret < 0) + { + /* EINTR is the only error that we expect */ + + DEBUGASSERT(get_errno() == EINTR); + + if (allowinterrupt) + { + return -EINTR; + } + } + } + while (ret != OK); + + return OK; +} + +static inline void mac802154_txdesc_free(FAR struct ieee802154_privmac_s *priv, + FAR struct ieee802154_txdesc_s *txdesc) +{ + sq_addlast((FAR sq_entry_t *)txdesc, &priv->txdesc_queue); + mac802154_givesem(&priv->txdesc_sem); +} + +/**************************************************************************** + * Name: mac802154_timercancel + * + * Description: + * Cancel timer and remove reference to callback function + * + * Assumptions: + * priv MAC struct is locked when calling. + * + ****************************************************************************/ + +static inline int mac802154_timercancel(FAR struct ieee802154_privmac_s *priv) +{ + wd_cancel(priv->timeout); + priv->timeout_worker = NULL; + return OK; +} + +static inline void mac802154_rxenable(FAR struct ieee802154_privmac_s *priv) +{ + priv->nrxusers++; + + /* If this is the first user, actually enable the receiver */ + + if (priv->nrxusers == 1) + { + wlinfo("receiver enabled\n"); + priv->radio->rxenable(priv->radio, true); + } +} + +static inline void mac802154_rxdisable(FAR struct ieee802154_privmac_s *priv) +{ + priv->nrxusers--; + + /* If this is the first user, actually enable the receiver */ + + if (priv->nrxusers == 0) + { + wlinfo("receiver disabled\n"); + priv->radio->rxenable(priv->radio, true); + priv->radio->rxenable(priv->radio, false); + } +} + +static inline void mac802154_setchannel(FAR struct ieee802154_privmac_s *priv, + uint8_t channel) +{ + priv->radio->set_attr(priv->radio, IEEE802154_ATTR_PHY_CHAN, + (FAR const union ieee802154_attr_u *)&channel); +} + +static inline void mac802154_setchpage(FAR struct ieee802154_privmac_s *priv, + uint8_t chpage) +{ + priv->radio->set_attr(priv->radio, IEEE802154_ATTR_PHY_CURRENT_PAGE, + (FAR const union ieee802154_attr_u *)&chpage); +} + +static inline void mac802154_setpanid(FAR struct ieee802154_privmac_s *priv, + const uint8_t *panid) +{ + IEEE802154_PANIDCOPY(priv->addr.panid, panid); + priv->radio->set_attr(priv->radio, IEEE802154_ATTR_MAC_PANID, + (FAR const union ieee802154_attr_u *)panid); +} + +static inline void mac802154_setsaddr(FAR struct ieee802154_privmac_s *priv, + const uint8_t *saddr) +{ + IEEE802154_SADDRCOPY(priv->addr.saddr, saddr); + priv->radio->set_attr(priv->radio, IEEE802154_ATTR_MAC_SADDR, + (FAR const union ieee802154_attr_u *)saddr); +} + +static inline void mac802154_seteaddr(FAR struct ieee802154_privmac_s *priv, + const uint8_t *eaddr) +{ + IEEE802154_EADDRCOPY(priv->addr.eaddr, eaddr); + priv->radio->set_attr(priv->radio, IEEE802154_ATTR_MAC_EADDR, + (FAR const union ieee802154_attr_u *)eaddr); +} + +static inline void mac802154_setcoordsaddr(FAR struct ieee802154_privmac_s *priv, + const uint8_t *saddr) +{ + IEEE802154_SADDRCOPY(priv->pandesc.coordaddr.saddr, saddr); + priv->radio->set_attr(priv->radio, IEEE802154_ATTR_MAC_COORD_SADDR, + (FAR const union ieee802154_attr_u *)saddr); +} + +static inline void mac802154_setcoordeaddr(FAR struct ieee802154_privmac_s *priv, + const uint8_t *eaddr) +{ + IEEE802154_EADDRCOPY(priv->pandesc.coordaddr.eaddr, eaddr); + priv->radio->set_attr(priv->radio, IEEE802154_ATTR_MAC_COORD_EADDR, + (FAR const union ieee802154_attr_u *)eaddr); +} + +static inline void mac802154_setcoordaddr(FAR struct ieee802154_privmac_s *priv, + FAR const struct ieee802154_addr_s *addr) +{ + memcpy(&priv->pandesc.coordaddr, addr, sizeof(struct ieee802154_addr_s)); + priv->radio->set_attr(priv->radio, IEEE802154_ATTR_MAC_COORD_EADDR, + (FAR const union ieee802154_attr_u *)addr->eaddr); + priv->radio->set_attr(priv->radio, IEEE802154_ATTR_MAC_COORD_SADDR, + (FAR const union ieee802154_attr_u *)addr->saddr); +} + +#endif /* __WIRELESS_IEEE802154__MAC802154_INTERNAL_H */ diff --git a/wireless/ieee802154/mac802154_loopback.c b/wireless/ieee802154/mac802154_loopback.c index 3e3b7c1123..f0bf2c70d6 100644 --- a/wireless/ieee802154/mac802154_loopback.c +++ b/wireless/ieee802154/mac802154_loopback.c @@ -118,7 +118,7 @@ static uint8_t g_iobuffer[CONFIG_NET_6LOWPAN_MTU + CONFIG_NET_GUARDSIZE]; static uint8_t g_eaddr[IEEE802154_EADDRSIZE] = { - 0x00, 0xfa, 0xde, 0x00, 0xde, 0xad, 0xbe, 0xef + 0x0c, 0xfa, 0xde, 0x00, 0xde, 0xad, 0xbe, 0xef }; static uint8_t g_saddr[IEEE802154_SADDRSIZE] = @@ -190,19 +190,31 @@ static int lo_req_data(FAR struct ieee802154_driver_s *netdev, #ifdef CONFIG_NET_6LOWPAN_EXTENDEDADDR static void lo_addr2ip(FAR struct net_driver_s *dev) { + /* Set the MAC address as the eaddr */ + + IEEE802154_EADDRCOPY(dev->d_mac.ieee802154.u8, g_eaddr); + + /* Set the IP address based on the eaddr */ + dev->d_ipv6addr[0] = HTONS(0xfe80); dev->d_ipv6addr[1] = 0; dev->d_ipv6addr[2] = 0; dev->d_ipv6addr[3] = 0; - dev->d_ipv6addr[4] = (uint16_t)g_eaddr[0] << 8 | (uint16_t)g_eaddr[1]; - dev->d_ipv6addr[5] = (uint16_t)g_eaddr[2] << 8 | (uint16_t)g_eaddr[3]; - dev->d_ipv6addr[6] = (uint16_t)g_eaddr[4] << 8 | (uint16_t)g_eaddr[5]; - dev->d_ipv6addr[7] = (uint16_t)g_eaddr[6] << 8 | (uint16_t)g_eaddr[6]; + dev->d_ipv6addr[4] = (uint16_t)g_eaddr[0] << 8 | (uint16_t)g_eaddr[1]; + dev->d_ipv6addr[5] = (uint16_t)g_eaddr[2] << 8 | (uint16_t)g_eaddr[3]; + dev->d_ipv6addr[6] = (uint16_t)g_eaddr[4] << 8 | (uint16_t)g_eaddr[5]; + dev->d_ipv6addr[7] = (uint16_t)g_eaddr[6] << 8 | (uint16_t)g_eaddr[7]; dev->d_ipv6addr[4] ^= 0x200; } #else static void lo_addr2ip(FAR struct net_driver_s *dev) { + /* Set the MAC address as the saddr */ + + IEEE802154_SADDRCOPY(dev->d_mac.ieee802154.u8, g_saddr); + + /* Set the IP address based on the saddr */ + dev->d_ipv6addr[0] = HTONS(0xfe80); dev->d_ipv6addr[1] = 0; dev->d_ipv6addr[2] = 0; @@ -210,7 +222,7 @@ static void lo_addr2ip(FAR struct net_driver_s *dev) dev->d_ipv6addr[4] = 0; dev->d_ipv6addr[5] = HTONS(0x00ff); dev->d_ipv6addr[6] = HTONS(0xfe00); - dev->d_ipv6addr[7] = (uint16_t)g_saddr[0] << 8 | (uint16_t)g_saddr[1]; + dev->d_ipv6addr[7] = (uint16_t)g_saddr[0] << 8 | (uint16_t)g_saddr[1]; dev->d_ipv6addr[7] ^= 0x200; } #endif @@ -275,8 +287,28 @@ static int lo_loopback(FAR struct net_driver_s *dev) FAR struct iob_s *iob; int ret; + /* Create some fake metadata */ + memset(&ind, 0, sizeof(struct ieee802154_data_ind_s)); +#ifdef CONFIG_NET_6LOWPAN_EXTENDEDADDR + ind.src.mode = IEEE802154_ADDRMODE_EXTENDED; + ind.dest.mode = IEEE802154_ADDRMODE_EXTENDED; +#else + ind.src.mode = IEEE802154_ADDRMODE_SHORT; + ind.dest.mode = IEEE802154_ADDRMODE_SHORT; +#endif + + /* On loopback the local address is both the source and destination. */ + + IEEE802154_PANIDCOPY(ind.src.panid, g_panid); + IEEE802154_SADDRCOPY(ind.src.saddr, g_saddr); + IEEE802154_EADDRCOPY(ind.src.eaddr, g_eaddr); + + IEEE802154_PANIDCOPY(ind.dest.panid, g_panid); + IEEE802154_SADDRCOPY(ind.dest.saddr, g_saddr); + IEEE802154_EADDRCOPY(ind.dest.eaddr, g_eaddr); + /* Loop while there framelist to be sent, i.e., while the freme list is not * emtpy. Sending, of course, just means relaying back through the network * for this driver. @@ -701,14 +733,14 @@ static int lo_ioctl(FAR struct net_driver_s *dev, int cmd, IEEE802154_PANIDCOPY(g_panid, setreq->attrval.mac.panid); break; - case IEEE802154_ATTR_MAC_EXTENDED_ADDR: + case IEEE802154_ATTR_MAC_EADDR: IEEE802154_EADDRCOPY(g_eaddr, setreq->attrval.mac.eaddr); #ifdef CONFIG_NET_6LOWPAN_EXTENDEDADDR lo_addr2ip(dev); #endif break; - case IEEE802154_ATTR_MAC_SHORT_ADDRESS: + case IEEE802154_ATTR_MAC_SADDR: IEEE802154_SADDRCOPY(g_saddr, setreq->attrval.mac.saddr); #ifndef CONFIG_NET_6LOWPAN_EXTENDEDADDR lo_addr2ip(dev); @@ -731,11 +763,11 @@ static int lo_ioctl(FAR struct net_driver_s *dev, int cmd, IEEE802154_PANIDCOPY(getreq->attrval.mac.panid, g_panid); break; - case IEEE802154_ATTR_MAC_EXTENDED_ADDR: + case IEEE802154_ATTR_MAC_EADDR: IEEE802154_EADDRCOPY(getreq->attrval.mac.eaddr, g_eaddr); break; - case IEEE802154_ATTR_MAC_SHORT_ADDRESS: + case IEEE802154_ATTR_MAC_SADDR: IEEE802154_SADDRCOPY(getreq->attrval.mac.saddr, g_saddr); break; diff --git a/wireless/ieee802154/mac802154_netdev.c b/wireless/ieee802154/mac802154_netdev.c index d30320efb7..0f49102c5e 100644 --- a/wireless/ieee802154/mac802154_netdev.c +++ b/wireless/ieee802154/mac802154_netdev.c @@ -248,7 +248,7 @@ static int macnet_advertise(FAR struct net_driver_s *dev) /* Get the eaddr from the MAC */ memcpy(arg.ifr_name, dev->d_ifname, IFNAMSIZ); - arg.u.getreq.attr = IEEE802154_ATTR_MAC_EXTENDED_ADDR; + arg.u.getreq.attr = IEEE802154_ATTR_MAC_EADDR; ret = dev->d_ioctl(dev, MAC802154IOC_MLME_GET_REQUEST, (unsigned long)((uintptr_t)&arg)); if (ret < 0) @@ -258,11 +258,13 @@ static int macnet_advertise(FAR struct net_driver_s *dev) } else { - /* Set the IP address based on the eaddr */ + /* Set the MAC address as the eaddr */ eaddr = arg.u.getreq.attrval.mac.eaddr; IEEE802154_EADDRCOPY(dev->d_mac.ieee802154.u8, eaddr); + /* Set the IP address based on the eaddr */ + dev->d_ipv6addr[0] = HTONS(0xfe80); dev->d_ipv6addr[1] = 0; dev->d_ipv6addr[2] = 0; @@ -270,7 +272,7 @@ static int macnet_advertise(FAR struct net_driver_s *dev) dev->d_ipv6addr[4] = (uint16_t)eaddr[0] << 8 | (uint16_t)eaddr[1]; dev->d_ipv6addr[5] = (uint16_t)eaddr[2] << 8 | (uint16_t)eaddr[3]; dev->d_ipv6addr[6] = (uint16_t)eaddr[4] << 8 | (uint16_t)eaddr[5]; - dev->d_ipv6addr[7] = (uint16_t)eaddr[6] << 8 | (uint16_t)eaddr[6]; + dev->d_ipv6addr[7] = (uint16_t)eaddr[6] << 8 | (uint16_t)eaddr[7]; dev->d_ipv6addr[4] ^= 0x200; return OK; } @@ -281,7 +283,7 @@ static int macnet_advertise(FAR struct net_driver_s *dev) /* Get the saddr from the MAC */ memcpy(arg.ifr_name, dev->d_ifname, IFNAMSIZ); - arg.u.getreq.attr = IEEE802154_ATTR_MAC_SHORT_ADDRESS; + arg.u.getreq.attr = IEEE802154_ATTR_MAC_SADDR; ret = dev->d_ioctl(dev, MAC802154IOC_MLME_GET_REQUEST, (unsigned long)((uintptr_t)&arg)); if (ret < 0) @@ -291,6 +293,8 @@ static int macnet_advertise(FAR struct net_driver_s *dev) } else { + /* Set the MAC address as the saddr */ + saddr = arg.u.getreq.attrval.mac.saddr; IEEE802154_SADDRCOPY(dev->d_mac.ieee802154.u8, saddr); @@ -405,6 +409,7 @@ static int macnet_rxframe(FAR struct mac802154_maccb_s *maccb, if (!priv->md_bifup) { + wlwarn("WARNING: Dropped... Network is down\n"); return -ENETDOWN; } @@ -421,9 +426,16 @@ static int macnet_rxframe(FAR struct mac802154_maccb_s *maccb, if ((iob->io_data[iob->io_offset] & SIXLOWPAN_DISPATCH_NALP_MASK) == SIXLOWPAN_DISPATCH_NALP) { + wlwarn("WARNING: Dropped... Not a 6LoWPAN frame: %02x\n", + iob->io_data[iob->io_offset]); return -EINVAL; } + /* Increment statistics */ + + NETDEV_RXPACKETS(&priv->md_dev.i_dev); + NETDEV_RXIPV6(&priv->md_dev.i_dev); + /* Remove the IOB containing the frame. */ ind->frame = NULL; @@ -676,27 +688,6 @@ static int macnet_txpoll_callback(FAR struct net_driver_s *dev) return 0; } -/**************************************************************************** - * Name: macnet_txpoll_process - * - * Description: - * Perform the periodic poll. This may be called either from watchdog - * timer logic or from the worker thread, depending upon the configuration. - * - * Parameters: - * priv - Reference to the driver state structure - * - * Returned Value: - * None - * - * Assumptions: - * - ****************************************************************************/ - -static inline void macnet_txpoll_process(FAR struct macnet_driver_s *priv) -{ -} - /**************************************************************************** * Name: macnet_txpoll_work * @@ -792,20 +783,20 @@ static int macnet_ifup(FAR struct net_driver_s *dev) ret = macnet_advertise(dev); if (ret >= 0) { - ninfo("Bringing up: %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", - dev->d_ipv6addr[0], dev->d_ipv6addr[1], dev->d_ipv6addr[2], - dev->d_ipv6addr[3], dev->d_ipv6addr[4], dev->d_ipv6addr[5], - dev->d_ipv6addr[6], dev->d_ipv6addr[7]); + wlinfo("Bringing up: %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", + dev->d_ipv6addr[0], dev->d_ipv6addr[1], dev->d_ipv6addr[2], + dev->d_ipv6addr[3], dev->d_ipv6addr[4], dev->d_ipv6addr[5], + dev->d_ipv6addr[6], dev->d_ipv6addr[7]); #ifdef CONFIG_NET_6LOWPAN_EXTENDEDADDR - ninfo(" Node: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", - dev->d_mac.ieee802154.u8[0], dev->d_mac.ieee802154.u8[1], - dev->d_mac.ieee802154.u8[2], dev->d_mac.ieee802154.u8[3], - dev->d_mac.ieee802154.u8[4], dev->d_mac.ieee802154.u8[5], - dev->d_mac.ieee802154.u8[6], dev->d_mac.ieee802154.u8[7]); + wlinfo(" Node: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", + dev->d_mac.ieee802154.u8[0], dev->d_mac.ieee802154.u8[1], + dev->d_mac.ieee802154.u8[2], dev->d_mac.ieee802154.u8[3], + dev->d_mac.ieee802154.u8[4], dev->d_mac.ieee802154.u8[5], + dev->d_mac.ieee802154.u8[6], dev->d_mac.ieee802154.u8[7]); #else - ninfo(" Node: %02x:%02x\n", - dev->d_mac.ieee802154.u8[0], dev->d_mac.ieee802154.u8[1]); + wlinfo(" Node: %02x:%02x\n", + dev->d_mac.ieee802154.u8[0], dev->d_mac.ieee802154.u8[1]); #endif /* Set and activate a timer process */ @@ -884,6 +875,8 @@ static void macnet_txavail_work(FAR void *arg) { FAR struct macnet_driver_s *priv = (FAR struct macnet_driver_s *)arg; + wlinfo("ifup=%u\n", priv->md_bifup); + /* Lock the network and serialize driver operations if necessary. * NOTE: Serialization is only required in the case where the driver work * is performed on an LP worker thread and where more than one LP worker @@ -929,6 +922,8 @@ static int macnet_txavail(FAR struct net_driver_s *dev) { FAR struct macnet_driver_s *priv = (FAR struct macnet_driver_s *)dev->d_private; + wlinfo("Available=%u\n", work_available(&priv->md_pollwork)); + /* Is our single work structure available? It may not be if there are * pending interrupt actions and we will have to ignore the Tx * availability action. @@ -1111,6 +1106,8 @@ static int macnet_req_data(FAR struct ieee802154_driver_s *netdev, FAR struct iob_s *iob; int ret; + wlinfo("Received framelist\n"); + DEBUGASSERT(netdev != NULL && netdev->i_dev.d_private != NULL); priv = (FAR struct macnet_driver_s *)netdev->i_dev.d_private; @@ -1129,9 +1126,17 @@ static int macnet_req_data(FAR struct ieee802154_driver_s *netdev, framelist = iob->io_flink; iob->io_flink = NULL; - /* Transfer the frame to the MAC */ + /* Transfer the frame to the MAC. mac802154_req_data will return + * -EINTR if a signal is received during certain phases of processing. + * In this context we just need to ignore -EINTR errors and try again. + */ + + do + { + ret = mac802154_req_data(priv->md_mac, meta, iob); + } + while (ret == -EINTR); - ret = mac802154_req_data(priv->md_mac, meta, iob); if (ret < 0) { wlerr("ERROR: mac802154_req_data failed: %d\n", ret); @@ -1145,8 +1150,11 @@ static int macnet_req_data(FAR struct ieee802154_driver_s *netdev, iob_free(iob); } + NETDEV_TXERRORS(&priv->md_dev.i_dev); return ret; } + + NETDEV_TXDONE(&priv->md_dev.i_dev); } return OK; diff --git a/wireless/ieee802154/mac802154_poll.c b/wireless/ieee802154/mac802154_poll.c index 7f5251fdc9..e2881a397a 100644 --- a/wireless/ieee802154/mac802154_poll.c +++ b/wireless/ieee802154/mac802154_poll.c @@ -60,7 +60,7 @@ * Private Function Prototypes ****************************************************************************/ -static void mac802154_timeout_poll(FAR struct ieee802154_privmac_s *priv); +static void mac802154_polltimeout(FAR struct ieee802154_privmac_s *priv); /**************************************************************************** * Public MAC Functions @@ -98,7 +98,7 @@ int mac802154_req_poll(MACHANDLE mac, FAR struct ieee802154_poll_req_s *req) * needs access to the MAC in order to unlock it. */ - ret = mac802154_takesem(&priv->op_sem, true); + ret = mac802154_takesem(&priv->opsem, true); if (ret < 0) { return ret; @@ -109,7 +109,7 @@ int mac802154_req_poll(MACHANDLE mac, FAR struct ieee802154_poll_req_s *req) ret = mac802154_takesem(&priv->exclsem, true); if (ret < 0) { - mac802154_givesem(&priv->op_sem); + mac802154_givesem(&priv->opsem); return ret; } @@ -122,7 +122,7 @@ int mac802154_req_poll(MACHANDLE mac, FAR struct ieee802154_poll_req_s *req) if (ret < 0) { mac802154_givesem(&priv->exclsem); - mac802154_givesem(&priv->op_sem); + mac802154_givesem(&priv->opsem); return ret; } @@ -133,15 +133,21 @@ int mac802154_req_poll(MACHANDLE mac, FAR struct ieee802154_poll_req_s *req) if (IEEE802154_SADDRCMP(priv->addr.saddr, &IEEE802154_SADDR_BCAST)) { - mac802154_create_datareq(priv, &req->coordaddr, IEEE802154_ADDRMODE_EXTENDED, - txdesc); + mac802154_createdatareq(priv, &req->coordaddr, IEEE802154_ADDRMODE_EXTENDED, + txdesc); } else { - mac802154_create_datareq(priv, &req->coordaddr, IEEE802154_ADDRMODE_SHORT, - txdesc); + mac802154_createdatareq(priv, &req->coordaddr, IEEE802154_ADDRMODE_SHORT, + txdesc); } + /* Save a copy of the destination addressing infromation into the tx descriptor. + * We only do this for commands to help with handling their progession. + */ + + memcpy(&txdesc->destaddr, &req->coordaddr, sizeof(struct ieee802154_addr_s)); + /* Save a reference of the tx descriptor */ priv->cmd_desc = txdesc; @@ -213,7 +219,7 @@ void mac802154_txdone_datareq_poll(FAR struct ieee802154_privmac_s *priv, priv->curr_op = MAC802154_OP_NONE; priv->cmd_desc = NULL; - mac802154_givesem(&priv->op_sem); + mac802154_givesem(&priv->opsem); /* Release the MAC, call the callback, get exclusive access again */ @@ -229,7 +235,7 @@ void mac802154_txdone_datareq_poll(FAR struct ieee802154_privmac_s *priv, * the corresponding data frame from the coordinator. [1] pg.43 */ - priv->radio->rxenable(priv->radio, true); + mac802154_rxenable(priv); /* Start a timer, if we receive the data frame, we will cancel * the timer, otherwise it will expire and we will notify the @@ -237,7 +243,7 @@ void mac802154_txdone_datareq_poll(FAR struct ieee802154_privmac_s *priv, */ mac802154_timerstart(priv, priv->max_frame_waittime, - mac802154_timeout_poll); + mac802154_polltimeout); /* We can deallocate the data conf notification as it is no longer * needed. We can't use the public function here since we already @@ -250,7 +256,7 @@ void mac802154_txdone_datareq_poll(FAR struct ieee802154_privmac_s *priv, } /**************************************************************************** - * Name: mac802154_timeout_poll + * Name: mac802154_polltimeout * * Description: * Function registered with MAC timer that gets called via the work queue to @@ -258,7 +264,7 @@ void mac802154_txdone_datareq_poll(FAR struct ieee802154_privmac_s *priv, * ****************************************************************************/ -void mac802154_timeout_poll(FAR struct ieee802154_privmac_s *priv) +void mac802154_polltimeout(FAR struct ieee802154_privmac_s *priv) { FAR struct ieee802154_notif_s *notif; @@ -274,7 +280,7 @@ void mac802154_timeout_poll(FAR struct ieee802154_privmac_s *priv) /* We are no longer performing the association operation */ priv->curr_op = MAC802154_OP_NONE; priv->cmd_desc = NULL; - mac802154_givesem(&priv->op_sem); + mac802154_givesem(&priv->opsem); /* Release the MAC */ diff --git a/wireless/ieee802154/mac802154_reset.c b/wireless/ieee802154/mac802154_reset.c index 23b9706dc7..759a44e31e 100644 --- a/wireless/ieee802154/mac802154_reset.c +++ b/wireless/ieee802154/mac802154_reset.c @@ -86,15 +86,15 @@ int mac802154_req_reset(MACHANDLE mac, bool rst_pibattr) if (rst_pibattr) { - priv->isassoc = false; /* Not associated with a PAN */ - priv->trackingbeacon = false; /* Not tracking beacon by default */ - priv->assocpermit = false; /* Device (if coord) not accepting ssociation */ - priv->autoreq = true; /* Auto send data req if addr. in beacon */ - priv->battlifeext = false; /* BLE disabled */ - priv->beacon_payload_len = 0; /* Beacon payload NULL */ - priv->beaconorder = 15; /* Non-beacon enabled network */ - priv->superframeorder = 15; /* Length of active portion of outgoing SF */ - priv->beacon_txtime = 0; /* Device never sent a beacon */ + priv->isassoc = false; /* Not associated with a PAN */ + priv->trackingbeacon = false; /* Not tracking beacon by default */ + priv->sfspec.assocpermit = false; /* Device (if coord) not accepting ssociation */ + priv->autoreq = true; /* Auto send data req if addr. in beacon */ + priv->sfspec.ble = false; /* BLE disabled */ + priv->beaconpayloadlength = 0; /* Beacon payload NULL */ + priv->sfspec.beaconorder = 15; /* Non-beacon enabled network */ + priv->sfspec.sforder = 15; /* Length of active portion of outgoing SF */ + priv->beacon_txtime = 0; /* Device never sent a beacon */ #warning Set BSN and DSN to random values! priv->bsn = 0; priv->dsn = 0; @@ -113,10 +113,10 @@ int mac802154_req_reset(MACHANDLE mac, bool rst_pibattr) /* Reset the Coordinator address */ - priv->coordaddr.mode = IEEE802154_ADDRMODE_NONE; - IEEE802154_PANIDCOPY(priv->coordaddr.panid, &IEEE802154_PANID_UNSPEC); - IEEE802154_SADDRCOPY(priv->coordaddr.saddr, &IEEE802154_SADDR_UNSPEC); - IEEE802154_EADDRCOPY(priv->coordaddr.eaddr, &IEEE802154_EADDR_UNSPEC); + priv->pandesc.coordaddr.mode = IEEE802154_ADDRMODE_NONE; + IEEE802154_PANIDCOPY(priv->pandesc.coordaddr.panid, &IEEE802154_PANID_UNSPEC); + IEEE802154_SADDRCOPY(priv->pandesc.coordaddr.saddr, &IEEE802154_SADDR_UNSPEC); + IEEE802154_EADDRCOPY(priv->pandesc.coordaddr.eaddr, &IEEE802154_EADDR_UNSPEC); /* Reset the device's address */ diff --git a/wireless/ieee802154/mac802154_scan.c b/wireless/ieee802154/mac802154_scan.c index 1ba9932288..d333d72d3c 100644 --- a/wireless/ieee802154/mac802154_scan.c +++ b/wireless/ieee802154/mac802154_scan.c @@ -51,9 +51,17 @@ #include #include "mac802154.h" +#include "mac802154_internal.h" +#include "mac802154_scan.h" #include +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static void mac802154_scantimeout(FAR struct ieee802154_privmac_s *priv); + /**************************************************************************** * Public MAC Functions ****************************************************************************/ @@ -77,6 +85,200 @@ int mac802154_req_scan(MACHANDLE mac, FAR struct ieee802154_scan_req_s *req) { FAR struct ieee802154_privmac_s *priv = (FAR struct ieee802154_privmac_s *)mac; - return -ENOTTY; + int ret; + + if (req->duration > 15 || req->numchan < 0 || req->numchan > 15) + { + ret = -EINVAL; + goto errout; + } + + /* Need to get access to the ops semaphore since operations are serial. This + * must be done before locking the MAC so that we don't hold the MAC + */ + + ret = mac802154_takesem(&priv->opsem, true); + if (ret < 0) + { + ret = -EINTR; + goto errout; + } + + priv->curr_op = MAC802154_OP_SCAN; + + /* Get exclusive access to the MAC */ + + ret = mac802154_takesem(&priv->exclsem, true); + if (ret < 0) + { + mac802154_givesem(&priv->opsem); + ret = -EINTR; + goto errout; + } + + /* Copy the request so we have a reference */ + + memcpy(&priv->currscan, req, sizeof(struct ieee802154_scan_req_s)); + priv->scanindex = 0; + priv->npandesc = 0; + + switch (req->type) + { + case IEEE802154_SCANTYPE_PASSIVE: + { + /* Set the channel to the first channel in the list */ + + mac802154_setchannel(priv, req->channels[priv->scanindex]); + mac802154_setchpage(priv, req->chpage); + + /* Before commencing an active or passive scan, the MAC sublayer shall + * store the value of macPANId and then set it to 0xffff for the + * duration of the scan. This enables the receive filter to accept all + * beacons rather than just the beacons from its current PAN, as + * described in 5.1.6.2. On completion of the scan, the MAC sublayer + * shall restore the value of macPANId to the value stored before the + * scan began. [1] pg. 24 + */ + + IEEE802154_PANIDCOPY(priv->panidbeforescan, priv->addr.panid); + mac802154_setpanid(priv, (const uint8_t *)&IEEE802154_PANID_UNSPEC); + + /* ...after switching to the channel for a passive scan, the device + * shall enable its receiver for at most + * [aBaseSuperframeDuration × (2 * n + 1)], + * where n is the value of the ScanDuration parameter. [1] pg. 25 + */ + + mac802154_rxenable(priv); + + priv->scansymdur = IEEE802154_BASE_SUPERFRAME_DURATION * + ((1 << req->duration) + 1); + mac802154_timerstart(priv, priv->scansymdur, mac802154_scantimeout); + } + break; + case IEEE802154_SCANTYPE_ACTIVE: + { + ret = -ENOTTY; + goto errout_with_sem; + } + break; + case IEEE802154_SCANTYPE_ED: + { + ret = -ENOTTY; + goto errout_with_sem; + } + break; + case IEEE802154_SCANTYPE_ORPHAN: + { + ret = -ENOTTY; + goto errout_with_sem; + } + break; + default: + { + ret = -EINVAL; + goto errout_with_sem; + } + break; + } + + mac802154_givesem(&priv->exclsem); +return OK; + +errout_with_sem: + mac802154_givesem(&priv->exclsem); + mac802154_givesem(&priv->opsem); +errout: + return ret; } +/**************************************************************************** + * Internal MAC Functions + ****************************************************************************/ + +void mac802154_scanfinish(FAR struct ieee802154_privmac_s *priv, + enum ieee802154_status_e status) +{ + FAR struct ieee802154_notif_s * notif; + + mac802154_takesem(&priv->exclsem, false); + mac802154_notif_alloc(priv, ¬if, false); + + priv->curr_op = MAC802154_OP_NONE; + mac802154_givesem(&priv->opsem); + + notif->notiftype = IEEE802154_NOTIFY_CONF_SCAN; + notif->u.scanconf.type = priv->currscan.type; + notif->u.scanconf.chpage = priv->currscan.chpage; + + /* Copy in the channels that did not get scanned */ + + if (priv->scanindex != priv->currscan.numchan) + { + notif->u.scanconf.numunscanned = priv->currscan.numchan - priv->scanindex; + memcpy(notif->u.scanconf.unscanned, &priv->currscan.channels[priv->scanindex], + notif->u.scanconf.numunscanned); + } + + notif->u.scanconf.numdesc = priv->npandesc; + memcpy(notif->u.scanconf.pandescs, priv->pandescs, + sizeof(struct ieee802154_pandesc_s) * priv->npandesc); + notif->u.scanconf.status = status; + + /* Reset the PAN ID to the setting before the scan started */ + + mac802154_setpanid(priv, priv->panidbeforescan); + + mac802154_givesem(&priv->exclsem); + + mac802154_notify(priv, notif); +} + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mac802154_scantimeout + * + * Description: + * Function registered with MAC timer that gets called via the work queue to + * handle a timeout for performing a scan operation. + * + ****************************************************************************/ + +static void mac802154_scantimeout(FAR struct ieee802154_privmac_s *priv) +{ + DEBUGASSERT(priv->curr_op == MAC802154_OP_SCAN); + + /* If we got here it means we are done scanning that channel */ + + mac802154_rxdisable(priv); + priv->scanindex++; + + /* Check to see if this was the last channel to scan */ + + if (priv->scanindex == priv->currscan.numchan) + { + if (priv->npandesc > 0) + { + mac802154_scanfinish(priv, IEEE802154_STATUS_SUCCESS); + } + else + { + mac802154_scanfinish(priv, IEEE802154_STATUS_NO_BEACON); + } + return; + } + + mac802154_setchannel(priv, priv->currscan.channels[priv->scanindex]); + + /* ...after switching to the channel for a passive scan, the device + * shall enable its receiver for at most + * [aBaseSuperframeDuration × (2 * n + 1)], + * where n is the value of the ScanDuration parameter. [1] pg. 25 + */ + + mac802154_rxenable(priv); + mac802154_timerstart(priv, priv->scansymdur, mac802154_scantimeout); +} diff --git a/wireless/ieee802154/mac802154_scan.h b/wireless/ieee802154/mac802154_scan.h new file mode 100644 index 0000000000..985d0953d5 --- /dev/null +++ b/wireless/ieee802154/mac802154_scan.h @@ -0,0 +1,66 @@ +/**************************************************************************** + * wireless/ieee802154/mac802154_scan.h + * + * Copyright (C) 2017 Verge Inc. All rights reserved. + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * + * Author: Anthony Merlino + * Author: Gregory Nutt + * + * The naming and comments for various fields are taken directly + * from the IEEE 802.15.4 2011 standard. + * + * 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 __WIRELESS_IEEE802154__MAC802154_SCAN_H +#define __WIRELESS_IEEE802154__MAC802154_SCAN_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +/**************************************************************************** + * Function Prototypes + ****************************************************************************/ + +struct ieee802154_privmac_s; /* Forward Reference */ + +void mac802154_scanfinish(FAR struct ieee802154_privmac_s *priv, + enum ieee802154_status_e status); + +#endif /* __WIRELESS_IEEE802154__MAC802154_SCAN_H */ \ No newline at end of file diff --git a/wireless/ieee802154/mac802154_start.c b/wireless/ieee802154/mac802154_start.c index 16e33484db..b3675393e2 100644 --- a/wireless/ieee802154/mac802154_start.c +++ b/wireless/ieee802154/mac802154_start.c @@ -97,17 +97,28 @@ int mac802154_req_start(MACHANDLE mac, FAR struct ieee802154_start_req_s *req) /* Set the PANID attribute */ - IEEE802154_PANIDCOPY(priv->addr.panid, req->panid); - priv->radio->set_attr(priv->radio, IEEE802154_ATTR_MAC_PANID, - (FAR const union ieee802154_attr_u *)req->panid); + mac802154_setpanid(priv, req->panid); - /* Set the radio attributes */ - priv->radio->set_attr(priv->radio, IEEE802154_ATTR_PHY_CURRENT_CHANNEL, - (FAR const union ieee802154_attr_u *)&req->chnum); + /* Tell the radio layer to set the channel number and channel page */ + priv->radio->set_attr(priv->radio, IEEE802154_ATTR_PHY_CHAN, + (FAR const union ieee802154_attr_u *)&req->chan); priv->radio->set_attr(priv->radio, IEEE802154_ATTR_PHY_CURRENT_PAGE, (FAR const union ieee802154_attr_u *)&req->chpage); + /* The address used in the Source Address field of the beacon frame shall + * contain the value of macExtendedAddress if macShortAddress is equal to + * 0xfffe or macShortAddress otherwise. [1] pg. 32 + */ + + if (IEEE802154_SADDRCMP(priv->addr.saddr, &IEEE802154_SADDR_BCAST)) + { + priv->addr.mode = IEEE802154_ADDRMODE_EXTENDED; + } + else + { + priv->addr.mode = IEEE802154_ADDRMODE_SHORT; + } /* Set the beacon order */ @@ -117,11 +128,11 @@ int mac802154_req_start(MACHANDLE mac, FAR struct ieee802154_start_req_s *req) goto errout; } - priv->beaconorder = req->beaconorder; + priv->sfspec.beaconorder = req->beaconorder; /* The value of macSuperframeOrder shall be ignored if macBeaconOrder = 15. pg. 19 */ - if (priv->beaconorder < 15) + if (priv->sfspec.beaconorder < 15) { /* Set the superframe order */ @@ -131,7 +142,7 @@ int mac802154_req_start(MACHANDLE mac, FAR struct ieee802154_start_req_s *req) goto errout; } - priv->superframeorder = req->superframeorder; + priv->sfspec.sforder = req->superframeorder; } if (req->pancoord) @@ -143,18 +154,44 @@ int mac802154_req_start(MACHANDLE mac, FAR struct ieee802154_start_req_s *req) priv->devmode = IEEE802154_DEVMODE_COORD; } - /* If the BeaconOrder parameter is less than 15, the MLME sets macBattLifeExt to - * the value of the BatteryLifeExtension parameter. If the BeaconOrder parameter - * equals 15, the value of the BatteryLifeExtension parameter is ignored. - * [1] pg. 106 - */ + priv->sfspec.pancoord = req->pancoord; - if (priv->beaconorder < 15) + if (priv->sfspec.beaconorder < 15) { - priv->battlifeext = req->battlifeext; + /* If the BeaconOrder parameter is less than 15, the MLME sets macBattLifeExt to + * the value of the BatteryLifeExtension parameter. If the BeaconOrder parameter + * equals 15, the value of the BatteryLifeExtension parameter is ignored. + * [1] pg. 106 + */ - /* TODO: Finish starting beacon enabled network */ - return -ENOTTY; + priv->sfspec.ble = req->battlifeext; + + /* For now we just set the CAP Slot to 15 */ + + priv->sfspec.final_capslot = 15; + + /* If the PAN coordinator parameter is set to TRUE, the MLME ignores the + * StartTime parameter and begins beacon transmissions immediately. + */ + + if (req->pancoord) + { + /* Update the beacon frame to start sending */ + + mac802154_updatebeacon(priv); + + /* Tell the radio to start transmitting beacon frames */ + + priv->radio->beaconstart(priv->radio, &priv->sfspec, + &priv->beaconframe[priv->bf_ind]); + } + else + { + /* TODO: Finish non-PAN coordinator delayed start */ + + ret = -ENOTTY; + goto errout; + } } mac802154_givesem(&priv->exclsem);