Merge branch 'ieee802154'
This commit is contained in:
commit
3ab89d20b3
2
Kconfig
2
Kconfig
@ -756,7 +756,7 @@ config DEBUG_WIRELESS
|
||||
default n
|
||||
depends on WIRELESS || DRIVERS_WIRELESS
|
||||
---help---
|
||||
Enable DEBUG_WIRELESS debug features.
|
||||
Enable wireless debug features.
|
||||
|
||||
if DEBUG_WIRELESS
|
||||
|
||||
|
@ -19,4 +19,20 @@ config CLICKER2_STM32_MB2_SPI
|
||||
---help---
|
||||
Enable SPI support on mikroBUS1 (STM32 SPI2)
|
||||
|
||||
config CLICKER2_STM32_MB1_BEE
|
||||
bool "mikroBUS1 MRF24J40 BEE"
|
||||
default y
|
||||
depends on IEEE802154_MRF24J40
|
||||
select CLICKER2_STM32_MB1_SPI
|
||||
---help---
|
||||
Enable support for MRF24J40 BEE on mikroBUS1
|
||||
|
||||
config CLICKER2_STM32_MB2_BEE
|
||||
bool "mikroBUS2 MRF24J40 BEE"
|
||||
default n
|
||||
depends on IEEE802154_MRF24J40
|
||||
select CLICKER2_STM32_MB2_SPI
|
||||
---help---
|
||||
Enable support for MRF24J40 BEE on mikroBUS2
|
||||
|
||||
endif # ARCH_BOARD_CLICKER2_STM32
|
||||
|
@ -304,6 +304,48 @@ Configurations
|
||||
If you do this a lot, you will probably want to invest a little time
|
||||
to develop a tool to automate these steps.
|
||||
|
||||
mrf24j40-radio
|
||||
|
||||
This is a version of nsh that was used for testing the MRF24J40 be as a
|
||||
character device. The most important configuration differences are
|
||||
summarized below:
|
||||
|
||||
1. Support for the BEE click and SPI are in enabled in the mikroBUS1 slot:
|
||||
|
||||
CONFIG_CLICKER2_STM32_MB1_BEE=y
|
||||
CONFIG_CLICKER2_STM32_MB1_SPI=y
|
||||
|
||||
2. SPI support and STM32 SPI3, in particular, are enabled:
|
||||
|
||||
CONFIG_SPI=y
|
||||
CONFIG_SPI_EXCHANGE=y
|
||||
|
||||
CONFIG_STM32_SPI=y
|
||||
CONFIG_STM32_SPI3=y
|
||||
|
||||
4. Support for the IEEE802.15.4 "upper half" character driver is enabled:
|
||||
|
||||
CONFIG_WIRELESS=y
|
||||
CONFIG_WIRELESS_IEEE802154=y
|
||||
CONFIG_IEEE802154_DEV=y
|
||||
|
||||
5. Support for the lower half MRF24J40 character driver is enabled
|
||||
|
||||
CONFIG_DRIVERS_WIRELESS=y
|
||||
CONFIG_DRIVERS_IEEE802154=y
|
||||
CONFIG_IEEE802154_MRF24J40=y
|
||||
|
||||
6. Support for the test program at apps/ieee802154 is enabled:
|
||||
|
||||
CONFIG_IEEE802154_COMMON=y
|
||||
CONFIG_IEEE802154_COORD=y
|
||||
CONFIG_IEEE802154_I8SAK=y
|
||||
|
||||
7. Initialization hooks are provided to enable the MRF24J40 and to
|
||||
register the radio character driver.
|
||||
|
||||
CONFIG_NSH_ARCHINIT=y
|
||||
|
||||
nsh:
|
||||
|
||||
Configures the NuttShell (nsh) located at examples/nsh. This
|
||||
|
122
configs/clicker2-stm32/mrf24j40-radio/Make.defs
Normal file
122
configs/clicker2-stm32/mrf24j40-radio/Make.defs
Normal file
@ -0,0 +1,122 @@
|
||||
############################################################################
|
||||
# configs/clicker2-stm32/mrf24j40-radio/Make.defs
|
||||
#
|
||||
# Copyright (C) 2017 Gregory Nutt. All rights reserved.
|
||||
# Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# 3. Neither the name NuttX nor the names of its contributors may be
|
||||
# used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
include ${TOPDIR}/.config
|
||||
include ${TOPDIR}/tools/Config.mk
|
||||
include ${TOPDIR}/arch/arm/src/armv7-m/Toolchain.defs
|
||||
|
||||
LDSCRIPT = flash.ld
|
||||
|
||||
ifeq ($(WINTOOL),y)
|
||||
# Windows-native toolchains
|
||||
DIRLINK = $(TOPDIR)/tools/copydir.sh
|
||||
DIRUNLINK = $(TOPDIR)/tools/unlink.sh
|
||||
MKDEP = $(TOPDIR)/tools/mkwindeps.sh
|
||||
ARCHINCLUDES = -I. -isystem "${shell cygpath -w $(TOPDIR)/include}"
|
||||
ARCHXXINCLUDES = -I. -isystem "${shell cygpath -w $(TOPDIR)/include}" -isystem "${shell cygpath -w $(TOPDIR)/include/cxx}"
|
||||
ARCHSCRIPT = -T "${shell cygpath -w $(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/$(LDSCRIPT)}"
|
||||
else
|
||||
# Linux/Cygwin-native toolchain
|
||||
MKDEP = $(TOPDIR)/tools/mkdeps$(HOSTEXEEXT)
|
||||
ARCHINCLUDES = -I. -isystem $(TOPDIR)/include
|
||||
ARCHXXINCLUDES = -I. -isystem $(TOPDIR)/include -isystem $(TOPDIR)/include/cxx
|
||||
ARCHSCRIPT = -T$(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/$(LDSCRIPT)
|
||||
endif
|
||||
|
||||
CC = $(CROSSDEV)gcc
|
||||
CXX = $(CROSSDEV)g++
|
||||
CPP = $(CROSSDEV)gcc -E
|
||||
LD = $(CROSSDEV)ld
|
||||
AR = $(CROSSDEV)ar rcs
|
||||
NM = $(CROSSDEV)nm
|
||||
OBJCOPY = $(CROSSDEV)objcopy
|
||||
OBJDUMP = $(CROSSDEV)objdump
|
||||
|
||||
ARCHCCVERSION = ${shell $(CC) -v 2>&1 | sed -n '/^gcc version/p' | sed -e 's/^gcc version \([0-9\.]\)/\1/g' -e 's/[-\ ].*//g' -e '1q'}
|
||||
ARCHCCMAJOR = ${shell echo $(ARCHCCVERSION) | cut -d'.' -f1}
|
||||
|
||||
ifeq ($(CONFIG_DEBUG_SYMBOLS),y)
|
||||
ARCHOPTIMIZATION = -g
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_DEBUG_NOOPT),y)
|
||||
ARCHOPTIMIZATION += $(MAXOPTIMIZATION) -fno-strict-aliasing -fno-strength-reduce -fomit-frame-pointer
|
||||
endif
|
||||
|
||||
ARCHCFLAGS = -fno-builtin
|
||||
ARCHCXXFLAGS = -fno-builtin -fno-exceptions -fcheck-new -fno-rtti
|
||||
ARCHWARNINGS = -Wall -Wstrict-prototypes -Wshadow -Wundef
|
||||
ARCHWARNINGSXX = -Wall -Wshadow -Wundef
|
||||
ARCHDEFINES =
|
||||
ARCHPICFLAGS = -fpic -msingle-pic-base -mpic-register=r10
|
||||
|
||||
CFLAGS = $(ARCHCFLAGS) $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) -pipe
|
||||
CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS)
|
||||
CXXFLAGS = $(ARCHCXXFLAGS) $(ARCHWARNINGSXX) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) -pipe
|
||||
CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS)
|
||||
CPPFLAGS = $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES)
|
||||
AFLAGS = $(CFLAGS) -D__ASSEMBLY__
|
||||
|
||||
NXFLATLDFLAGS1 = -r -d -warn-common
|
||||
NXFLATLDFLAGS2 = $(NXFLATLDFLAGS1) -T$(TOPDIR)/binfmt/libnxflat/gnu-nxflat-gotoff.ld -no-check-sections
|
||||
LDNXFLATFLAGS = -e main -s 2048
|
||||
|
||||
# Loadable module definitions
|
||||
|
||||
CMODULEFLAGS = $(CFLAGS) -mlong-calls # --target1-abs
|
||||
|
||||
LDMODULEFLAGS = -r -e module_initialize
|
||||
ifeq ($(WINTOOL),y)
|
||||
LDMODULEFLAGS += -T "${shell cygpath -w $(TOPDIR)/libc/modlib/gnu-elf.ld}"
|
||||
else
|
||||
LDMODULEFLAGS += -T $(TOPDIR)/libc/modlib/gnu-elf.ld
|
||||
endif
|
||||
|
||||
ASMEXT = .S
|
||||
OBJEXT = .o
|
||||
LIBEXT = .a
|
||||
EXEEXT =
|
||||
|
||||
ifneq ($(CROSSDEV),arm-nuttx-elf-)
|
||||
LDFLAGS += -nostartfiles -nodefaultlibs
|
||||
endif
|
||||
ifeq ($(CONFIG_DEBUG_SYMBOLS),y)
|
||||
LDFLAGS += -g
|
||||
endif
|
||||
|
||||
HOSTCC = gcc
|
||||
HOSTINCLUDES = -I.
|
||||
HOSTCFLAGS = -Wall -Wstrict-prototypes -Wshadow -Wundef -g -pipe
|
||||
HOSTLDFLAGS =
|
1355
configs/clicker2-stm32/mrf24j40-radio/defconfig
Normal file
1355
configs/clicker2-stm32/mrf24j40-radio/defconfig
Normal file
File diff suppressed because it is too large
Load Diff
@ -56,6 +56,10 @@ ifeq ($(CONFIG_LIB_BOARDCTL),y)
|
||||
CSRCS += stm32_appinit.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_IEEE802154_MRF24J40),y)
|
||||
CSRCS += stm32_mrf24j40.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ADC),y)
|
||||
CSRCS += stm32_adc.c
|
||||
endif
|
||||
|
@ -297,5 +297,21 @@ int stm32_adc_setup(void);
|
||||
int stm32_can_setup(void);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_mrf24j40_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the MRF24J40 device.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero is returned on success. Otherwise, a negated errno value is
|
||||
* returned to indicate the nature of the failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_CLICKER2_STM32_MB1_BEE) || defined(CONFIG_CLICKER2_STM32_MB2_BEE)
|
||||
int stm32_mrf24j40_initialize(void);
|
||||
#endif
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* __CONFIGS_CLICKER2_STM32_SRC_CLICKER2_H */
|
||||
|
@ -153,6 +153,16 @@ int stm32_bringup(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_CLICKER2_STM32_MB1_BEE) || defined(CONFIG_CLICKER2_STM32_MB2_BEE)
|
||||
/* Configure MRF24J40 wireless */
|
||||
|
||||
ret = stm32_mrf24j40_initialize();
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: stm32_mrf24j40_initialize() failed: %d\n", ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BUTTONS
|
||||
/* Register the BUTTON driver */
|
||||
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#include "stm32_gpio.h"
|
||||
#include "stm32_exti.h"
|
||||
|
||||
#include "clicker2-stm32.h"
|
||||
|
||||
|
336
configs/clicker2-stm32/src/stm32_mrf24j40.c
Normal file
336
configs/clicker2-stm32/src/stm32_mrf24j40.c
Normal file
@ -0,0 +1,336 @@
|
||||
/****************************************************************************
|
||||
* configs/freedom-kl25z/src/stm32_mrf24j40.c
|
||||
*
|
||||
* Copyright (C) 2017 Gregory Nutt, All rights reserver
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/wireless/ieee802154/ieee802154_mac.h>
|
||||
#include <nuttx/wireless/ieee802154/mrf24j40.h>
|
||||
|
||||
#include "stm32_gpio.h"
|
||||
#include "stm32_exti.h"
|
||||
#include "stm32_spi.h"
|
||||
|
||||
#include "clicker2-stm32.h"
|
||||
|
||||
#ifdef CONFIG_IEEE802154_MRF24J40
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_DRIVERS_WIRELESS
|
||||
# error Wireless support requires CONFIG_DRIVERS_WIRELESS
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_CLICKER2_STM32_MB1_BEE) && \
|
||||
!defined(CONFIG_CLICKER2_STM32_MB2_BEE)
|
||||
# error Only the Mikroe BEE board is supported
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CLICKER2_STM32_MB1_BEE
|
||||
# ifndef CONFIG_STM32_SPI3
|
||||
# error Mikroe BEE on mikroBUS1 requires CONFIG_STM32_SPI3
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CLICKER2_STM32_MB2_BEE
|
||||
# ifndef CONFIG_STM32_SPI2
|
||||
# error Mikroe BEE on mikroBUS1 requires CONFIG_STM32_SPI2
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct stm32_priv_s
|
||||
{
|
||||
struct mrf24j40_lower_s dev;
|
||||
xcpt_t handler;
|
||||
FAR void *arg;
|
||||
uint32_t intcfg;
|
||||
uint8_t spidev;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* IRQ/GPIO access callbacks. These operations all hidden behind callbacks
|
||||
* to isolate the MRF24J40 driver from differences in GPIO interrupt handling
|
||||
* varying boards and MCUs.
|
||||
*
|
||||
* irq_attach - Attach the MRF24J40 interrupt handler to the GPIO
|
||||
interrupt
|
||||
* irq_enable - Enable or disable the GPIO interrupt
|
||||
*/
|
||||
|
||||
static int stm32_attach_irq(FAR const struct mrf24j40_lower_s *lower,
|
||||
xcpt_t handler, FAR void *arg);
|
||||
static void stm32_enable_irq(FAR const struct mrf24j40_lower_s *lower,
|
||||
bool state);
|
||||
static int stm32_mrf24j40_devsetup(FAR struct stm32_priv_s *priv);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* A reference to a structure of this type must be passed to the MRF24J40
|
||||
* driver. This structure provides information about the configuration
|
||||
* of the MRF24J40 and provides some board-specific hooks.
|
||||
*
|
||||
* Memory for this structure is provided by the caller. It is not copied
|
||||
* by the driver and is presumed to persist while the driver is active. The
|
||||
* memory must be writable because, under certain circumstances, the driver
|
||||
* may modify frequency or X plate resistance values.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_CLICKER2_STM32_MB1_BEE
|
||||
static struct stm32_priv_s g_mrf24j40_mb1_priv =
|
||||
{
|
||||
.dev.attach = stm32_attach_irq,
|
||||
.dev.enable = stm32_enable_irq,
|
||||
.handler = NULL,
|
||||
.intcfg = GPIO_MB1_INT,
|
||||
.spidev = 3,
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CLICKER2_STM32_MB2_BEE
|
||||
static struct stm32_priv_s g_mrf24j40_mb2_priv =
|
||||
{
|
||||
.dev.attach = stm32_attach_irq,
|
||||
.dev.enable = stm32_enable_irq,
|
||||
.uint32_t = GPIO_MB2_INT,
|
||||
.spidev = 2,
|
||||
};
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/* IRQ/GPIO access callbacks. These operations all hidden behind
|
||||
* callbacks to isolate the MRF24J40 driver from differences in GPIO
|
||||
* interrupt handling by varying boards and MCUs. If possible,
|
||||
* interrupts should be configured on both rising and falling edges
|
||||
* so that contact and loss-of-contact events can be detected.
|
||||
*
|
||||
* irq_attach - Attach the MRF24J40 interrupt handler to the GPIO
|
||||
* interrupt
|
||||
* irq_enable - Enable or disable the GPIO interrupt
|
||||
*/
|
||||
|
||||
static int stm32_attach_irq(FAR const struct mrf24j40_lower_s *lower,
|
||||
xcpt_t handler, FAR void *arg)
|
||||
{
|
||||
FAR struct stm32_priv_s *priv = (FAR struct stm32_priv_s *)lower;
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
|
||||
/* Just save the handler for use when the interrupt is enabled */
|
||||
|
||||
priv->handler = handler;
|
||||
priv->arg = arg;
|
||||
return OK;
|
||||
}
|
||||
|
||||
static void stm32_enable_irq(FAR const struct mrf24j40_lower_s *lower,
|
||||
bool state)
|
||||
{
|
||||
FAR struct stm32_priv_s *priv = (FAR struct stm32_priv_s *)lower;
|
||||
|
||||
/* The caller should not attempt to enable interrupts if the handler
|
||||
* has not yet been 'attached'
|
||||
*/
|
||||
|
||||
DEBUGASSERT(priv != NULL && (priv->handler != NULL || !state));
|
||||
|
||||
/* Attach and enable, or detach and disable */
|
||||
|
||||
wlinfo("state:%d\n", (int)state);
|
||||
if (state)
|
||||
{
|
||||
(void)stm32_gpiosetevent(priv->intcfg, true, true, true,
|
||||
priv->handler, priv->arg);
|
||||
}
|
||||
else
|
||||
{
|
||||
(void)stm32_gpiosetevent(priv->intcfg, false, false, false,
|
||||
NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_mrf24j40_devsetup
|
||||
*
|
||||
* Description:
|
||||
* Initialize one the MRF24J40 device in one mikroBUS slot
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero is returned on success. Otherwise, a negated errno value is
|
||||
* returned to indicate the nature of the failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int stm32_mrf24j40_devsetup(FAR struct stm32_priv_s *priv)
|
||||
{
|
||||
FAR struct ieee802154_radio_s *radio;
|
||||
#ifdef CONFIG_IEEE802154_MAC
|
||||
MACHANDLE mac;
|
||||
#endif
|
||||
FAR struct spi_dev_s *spi;
|
||||
int ret;
|
||||
|
||||
/* Configure the interrupt pin */
|
||||
|
||||
stm32_configgpio(priv->intcfg);
|
||||
|
||||
/* Initialize the SPI bus and get an instance of the SPI interface */
|
||||
|
||||
spi = stm32_spibus_initialize(priv->spidev);
|
||||
if (spi == NULL)
|
||||
{
|
||||
wlerr("ERROR: Failed to initialize SPI bus %d\n", priv->spidev);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Initialize and register the SPI MRF24J40 device */
|
||||
|
||||
radio = mrf24j40_init(spi, &priv->dev);
|
||||
if (radio == NULL)
|
||||
{
|
||||
wlerr("ERROR: Failed to initialize SPI bus %d\n", priv->spidev);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_IEEE802154_MAC)
|
||||
/* Create a 802.15.4 MAC device from a 802.15.4 compatible radio device. */
|
||||
|
||||
mac = mac802154_create(radio);
|
||||
if (mac == NULL)
|
||||
{
|
||||
wlerr("ERROR: Failed to initialize IEEE802.15.4 MAC\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_IEEE802154_NETDEV)
|
||||
/* Use the IEEE802.15.4 MAC interface instance to create a 6loWPAN
|
||||
* network interface by wrapping the MAC intrface instance in a
|
||||
* network device driver via mac802154dev_register().
|
||||
*/
|
||||
|
||||
ret = mac802154netdev_register(mac);
|
||||
if (ret < 0)
|
||||
{
|
||||
wlerr("ERROR: Failed to register the MAC network driver wpan%d: %d\n",
|
||||
0, ret);
|
||||
return ret;
|
||||
}
|
||||
#elif defined(CONFIG_IEEE802154_MAC_DEV)
|
||||
/* If want to call these APIs from userspace, you have to wrap the MAC
|
||||
* interface in a character device viamac802154dev_register().
|
||||
*/
|
||||
|
||||
ret = mac802154dev_register(mac, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
wlerr("ERROR: Failed to register the MAC character driver /dev/ieee%d: %d\n",
|
||||
0, ret);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_IEEE802154_MAC */
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_mrf24j40_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the MRF24J40 device.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero is returned on success. Otherwise, a negated errno value is
|
||||
* returned to indicate the nature of the failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int stm32_mrf24j40_initialize(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
#ifdef CONFIG_CLICKER2_STM32_MB1_BEE
|
||||
wlinfo("Configuring BEE in mikroBUS1\n");
|
||||
|
||||
ret = stm32_mrf24j40_devsetup(&g_mrf24j40_mb1_priv);
|
||||
if (ret < 0)
|
||||
{
|
||||
wlerr("ERROR: Failed to initialize BD in mikroBUS1: %d\n", ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CLICKER2_STM32_MB2_BEE
|
||||
wlinfo("Configuring BEE in mikroBUS2\n");
|
||||
|
||||
ret = stm32_mrf24j40_devsetup(&g_mrf24j40_mb2_priv);
|
||||
if (ret < 0)
|
||||
{
|
||||
wlerr("ERROR: Failed to initialize BD in mikroBUS2: %d\n", ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
UNUSED(ret);
|
||||
return OK;
|
||||
}
|
||||
#endif /* CONFIG_IEEE802154_MRF24J40 */
|
@ -70,9 +70,8 @@ void WriteWlanEnablePin(uint8_t val);
|
||||
|
||||
void AssertWlanCS(void);
|
||||
|
||||
/*
|
||||
* Deassert CC3000 CS
|
||||
*/
|
||||
/* Deassert CC3000 CS */
|
||||
|
||||
void DeassertWlanCS(void);
|
||||
|
||||
/* Setup needed pins */
|
||||
|
@ -548,7 +548,7 @@ CONFIG_NET_6LOWPAN_MAXADDRCONTEXT=1
|
||||
CONFIG_NET_6LOWPAN_MAXADDRCONTEXT_PREFIX_0_0=0xaa
|
||||
CONFIG_NET_6LOWPAN_MAXADDRCONTEXT_PREFIX_0_1=0xaa
|
||||
# CONFIG_NET_6LOWPAN_MAXADDRCONTEXT_PREINIT_1 is not set
|
||||
# CONFIG_NET_6LOWPAN_RIMEADDR_EXTENDED is not set
|
||||
# CONFIG_NET_6LOWPAN_EXTENDEDADDR is not set
|
||||
CONFIG_NET_6LOWPAN_MAXAGE=20
|
||||
CONFIG_NET_6LOWPAN_MAX_MACTRANSMITS=4
|
||||
CONFIG_NET_6LOWPAN_MTU=1294
|
||||
|
@ -20,7 +20,6 @@ source drivers/wireless/cc3000/Kconfig
|
||||
menuconfig DRIVERS_IEEE802154
|
||||
bool "IEEE 802.15.4 Device Support"
|
||||
default n
|
||||
depends on EXPERIMENTAL
|
||||
---help---
|
||||
This directory holds implementations of IEEE802.15.4 device drivers.
|
||||
|
||||
@ -29,7 +28,6 @@ source drivers/wireless/ieee802154/Kconfig
|
||||
menuconfig DRIVERS_IEEE80211
|
||||
bool "IEEE 802.11 Device Support"
|
||||
default n
|
||||
depends on EXPERIMENTAL
|
||||
---help---
|
||||
This directory holds implementations of IEEE802.11 device drivers.
|
||||
|
||||
|
@ -11,4 +11,10 @@ config IEEE802154_MRF24J40
|
||||
---help---
|
||||
This selection enables support for the Microchip MRF24J40 device.
|
||||
|
||||
config IEEE802154_AT86RF233
|
||||
bool "ATMEL RF233 IEEE 802.15.4 transceiver"
|
||||
default n
|
||||
---help---
|
||||
This selection enables support for the Atmel RF233 device.
|
||||
|
||||
endif # DRIVERS_IEEE802154
|
||||
|
@ -45,6 +45,10 @@ ifeq ($(CONFIG_IEEE802154_MRF24J40),y)
|
||||
CSRCS += mrf24j40.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_IEEE802154_AT86RF233),y)
|
||||
CSRCS += at86rf23x.c
|
||||
endif
|
||||
|
||||
# Include IEEE 802.15.4 build support
|
||||
|
||||
DEPPATH += --dep-path wireless$(DELIM)ieee802154
|
||||
|
1561
drivers/wireless/ieee802154/at86rf23x.c
Normal file
1561
drivers/wireless/ieee802154/at86rf23x.c
Normal file
File diff suppressed because it is too large
Load Diff
221
drivers/wireless/ieee802154/at86rf23x.h
Normal file
221
drivers/wireless/ieee802154/at86rf23x.h
Normal file
@ -0,0 +1,221 @@
|
||||
/****************************************************************************
|
||||
* drivers/wireless/ieee802154/at86rf23x.c
|
||||
*
|
||||
* Copyright (C) 2016 Matt Poppe. All rights reserved.
|
||||
* Author: Matt Poppe <matt@poppe.me>
|
||||
*
|
||||
* 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 __DRIVERS_WIRELESS_IEEE802154_AT86RF23X_H
|
||||
#define __DRIVERS_WIRELESS_IEEE802154_AT86RF23X_H
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define RF23X_SPI_REG_READ 0x80
|
||||
#define RF23X_SPI_REG_WRITE 0xc0
|
||||
#define RF23X_SPI_FRAME_WRITE 0x60
|
||||
#define RF23X_SPI_FRAME_READ 0x20
|
||||
#define RF23X_SPI_SRAM_READ 0x00
|
||||
#define RF23X_SPI_SRAM_WRITE 0x40
|
||||
|
||||
/* US Times Constants for the RF233 */
|
||||
|
||||
#define RF23X_TIME_RESET_BOOT 510
|
||||
#define RF23X_TIME_FORCE_TRXOFF 100
|
||||
#define RF23X_TIME_P_ON_TO_TRXOFF 510
|
||||
#define RF23X_TIME_SLEEP_TO_TRXOFF 1200
|
||||
#define RF23X_TIME_RESET 6
|
||||
#define RF23X_TIME_ED_MEASUREMENT 140
|
||||
#define RF23X_TIME_CCA 140
|
||||
#define RF23X_TIME_PLL_LOCK 150
|
||||
#define RF23X_TIME_FTN_TUNNING 25
|
||||
#define RF23X_TIME_NOCLK_TO_WAKE 6
|
||||
#define RF23X_TIME_CMD_FORCE_TRX_OFF 1
|
||||
#define RF23X_TIME_TRXOFF_TO_PLL 180
|
||||
#define RF23X_TIME_TRANSITION_PLL_ACTIVE 1
|
||||
#define RF23X_TIME_TRXOFF_TO_SLEEP 1200
|
||||
|
||||
#define RF23X_MAX_RETRY_RESET_TO_TRX_OFF 5
|
||||
|
||||
#define RF23X_REG_TRXSTATUS 0x01
|
||||
#define RF23X_REG_TRXSTATE 0x02
|
||||
#define RF23X_REG_TRXCTRL0 0x03
|
||||
#define RF23X_REG_TRXCTRL1 0x04
|
||||
#define RF23X_REG_TXPWR 0x05
|
||||
#define RF23X_REG_RSSI 0x06
|
||||
#define RF23X_REG_EDLEVEL 0x07
|
||||
#define RF23X_REG_CCA 0x08
|
||||
#define RF23X_REG_THRES 0x09
|
||||
#define RF23X_REG_RXCTRL 0x0a
|
||||
#define RF23X_REG_SFD 0x0b
|
||||
#define RF23X_REG_TRXCTRL2 0x0c
|
||||
#define RF23X_REG_ANT_DIV 0x0d
|
||||
#define RF23X_REG_IRQ_MASK 0x0e
|
||||
#define RF23X_REG_IRQ_STATUS 0x0f
|
||||
#define RF23X_REG_VREG_CTRL 0x10
|
||||
#define RF23X_REG_BATMON 0x11
|
||||
#define RF23X_REG_XOSC_CTRL 0x12
|
||||
#define RF23X_REG_CCCTRL0 0x13
|
||||
#define RF23X_REG_CCCTRL1 0x14
|
||||
#define RF23X_REG_RXSYN 0x15
|
||||
#define RF23X_REG_TRXRPC 0x16
|
||||
#define RF23X_REG_XAHCTRL1 0x17
|
||||
#define RF23X_REG_FTNCTRL 0x18
|
||||
#define RF23X_REG_XAHCTRL2 0x19
|
||||
#define RF23X_REG_PLLCF 0x1a
|
||||
#define RF23X_REG_PLLDCU 0x1b
|
||||
#define RF23X_REG_PART 0x1c
|
||||
#define RF23X_REG_VERSION 0x1d
|
||||
#define RF23X_REG_MANID0 0x1e
|
||||
#define RF23X_REG_MANID1 0x1f
|
||||
#define RF23X_REG_SADDR0 0x20
|
||||
#define RF23X_REG_SADDR1 0x21
|
||||
#define RF23X_REG_PANID0 0x22
|
||||
#define RF23X_REG_PANID1 0x23
|
||||
#define RF23X_REG_IEEEADDR0 0x24
|
||||
#define RF23X_REG_IEEEADDR1 0x25
|
||||
#define RF23X_REG_IEEEADDR2 0x26
|
||||
#define RF23X_REG_IEEEADDR3 0x27
|
||||
#define RF23X_REG_IEEEADDR4 0x28
|
||||
#define RF23X_REG_IEEEADDR5 0x29
|
||||
#define RF23X_REG_IEEEADDR6 0x2a
|
||||
#define RF23X_REG_IEEEADDR7 0x2b
|
||||
#define RF23X_REG_XAHCTRL0 0x2c
|
||||
#define RF23X_REG_CSMASEED0 0x2d
|
||||
#define RF23X_REG_CSMASEED1 0x2e
|
||||
#define RF23X_REG_CSMABE 0x2f
|
||||
#define RF23X_REG_TSTCTRLDIGI 0x36
|
||||
#define RF23X_REG_TSTAGC 0x3c
|
||||
#define RF23X_REG_SDM 0x3d
|
||||
#define RF23X_REG_PHYTXTIME 0x3b
|
||||
#define RF23X_REG_PHYPMUVALUE 0x3b
|
||||
|
||||
#define RF23X_TRXSTATUS_POS 0
|
||||
#define RF23X_TRXSTATUS_MASK 0x1f
|
||||
#define RF23X_TRXSTATUS_STATUS RF23X_REG_TRXSTATUS, RF23X_TRXSTATUS_POS, RF23X_TRXSTATUS_MASK
|
||||
|
||||
#define RF23X_TRXCMD_POS 0
|
||||
#define RF23X_TRXCMD_MASK 0x1f
|
||||
#define RF23X_TRXCMD_STATE RF23X_REG_TRXSTATE, RF23X_TRXCMD_POS, RF23X_TRXCMD_MASK
|
||||
|
||||
#define RF23X_TXPWR_POS_4 0x00
|
||||
#define RF23X_TXPWR_POS_3_7 0x01
|
||||
#define RF23X_TXPWR_POS_3_4 0x02
|
||||
#define RF23X_TXPWR_POS_3 0x03
|
||||
#define RF23X_TXPWR_POS_2_5 0x04
|
||||
#define RF23X_TXPWR_POS_2 0x05
|
||||
#define RF23X_TXPWR_POS_1 0x06
|
||||
#define RF23X_TXPWR_0 0x07
|
||||
#define RF23X_TXPWR_NEG_1 0x08
|
||||
#define RF23X_TXPWR_NEG_2 0x09
|
||||
#define RF23X_TXPWR_NEG_3 0x0a
|
||||
#define RF23X_TXPWR_NEG_4 0x0b
|
||||
#define RF23X_TXPWR_NEG_6 0x0c
|
||||
#define RF23X_TXPWR_NEG_8 0x0d
|
||||
#define RF23X_TXPWR_NEG_12 0x0e
|
||||
#define RF23X_TXPWR_NEG_17 0x0f
|
||||
|
||||
/* CCA_STATUS */
|
||||
|
||||
#define RF23X_CCA_MODE_CS_OR_ED 0x00
|
||||
#define RF23X_CCA_MODE_ED 0x01
|
||||
#define RF23X_CCA_MODE_CS 0x02
|
||||
#define RF23X_CCA_MODE_CS_AND_ED 0x03
|
||||
|
||||
#define RF23X_CCA_CHANNEL_POS 0
|
||||
#define RF23X_CCA_CHANNEL_MASK 0x1f
|
||||
#define RF23X_CCA_BITS_CHANNEL RF23X_REG_CCA, RF23X_CCA_CHANNEL_POS, RF23X_CCA_CHANNEL_MASK
|
||||
#define RF23X_CCA_MODE_POS 5
|
||||
#define RF23X_CCA_MODE_MASK 0x03
|
||||
#define RF23X_CCA_BITS_MODE RF23X_REG_CCA, RF23X_CCA_MODE_POS, RF23X_CCA_MODE_MASK
|
||||
|
||||
/* XAH CTRL 1 */
|
||||
|
||||
#define RF23X_XAHCTRL1_PROM_MODE_POS 1
|
||||
#define RF23X_XAHCTRL1_PROM_MODE_MASK 0x01
|
||||
#define RF23X_XAHCTRL1_BITS_PROM_MODE RF23X_REG_XAHCTRL1, RF23X_XAHCTRL1_PROM_MODE_POS, RF23X_XAHCTRL1_PROM_MODE_MASK
|
||||
|
||||
/* CSMA SEED 0 */
|
||||
|
||||
/* CSMA SEED 1 */
|
||||
|
||||
#define RF23X_CSMASEED1_IAMCOORD_POS 3
|
||||
#define RF23X_CSMASEED1_IAMCOORD_MASK 0x1
|
||||
#define RF23X_CSMASEED1_IAMCOORD_BITS RF23X_REG_CSMASEED1, RF23X_CSMASEED1_IAMCOORD_POS, RF23X_CSMASEED1_IAMCOORD_MASK
|
||||
|
||||
#define RF23X_CSMASEED1_AACK_DIS_ACK_POS
|
||||
#define RF23X_CSMASEED1_AACK_SET_PD_POS
|
||||
#define RF23X_CSMASEED1_AACK_FVN_MODE_POS
|
||||
|
||||
/* TRX Status */
|
||||
|
||||
#define TRX_STATUS_PON 0x00
|
||||
#define TRX_STATUS_BUSYRX 0x01
|
||||
#define TRX_STATUS_BUSYTX 0x02
|
||||
#define TRX_STATUS_RXON 0x06
|
||||
#define TRX_STATUS_TRXOFF 0x08
|
||||
#define TRX_STATUS_PLLON 0x09
|
||||
#define TRX_STATUS_SLEEP 0x0f
|
||||
#define TRX_STATUS_DEEPSLEEP 0x10
|
||||
#define TRX_STATUS_BUSYRXACK 0x11
|
||||
#define TRX_STATUS_BUSYTXARET 0x12
|
||||
#define TRX_STATUS_RXAACKON 0x16
|
||||
#define TRX_STATUS_TXARETON 0x19
|
||||
#define TRX_STATUS_STATEINTRANS 0x1f
|
||||
|
||||
/* TRX Command */
|
||||
|
||||
#define TRX_CMD_NOP 0x00
|
||||
#define TRX_CMD_TX 0x02
|
||||
#define TRX_CMD_FORCETRXOFF 0x03
|
||||
#define TRX_CMD_FORCE_PLLON 0x04
|
||||
#define TRX_CMD_RX_ON 0x06
|
||||
#define TRX_CMD_TRXOFF 0x08
|
||||
#define TRX_CMD_PLL_ON 0x09
|
||||
#define TRX_CMD_PREP_DEEPSLEEP 0x10
|
||||
#define TRX_CMD_RX_AACK_ON 0x16
|
||||
#define TRX_CMD_TX_ARET_ON 0x19
|
||||
|
||||
/* IRQ MASK 0x0e */
|
||||
|
||||
#define RF23X_IRQ_MASK_LOCK_PLL (1 << 0)
|
||||
#define RF23X_IRQ_MASK_UNLOCK_PLL (1 << 1)
|
||||
#define RF23X_IRQ_MASK_RX_START (1 << 2)
|
||||
#define RF23X_IRQ_MASK_TRX_END (1 << 3)
|
||||
#define RF23X_IRQ_MASK_CCA_ED_DONE (1 << 4)
|
||||
#define RF23X_IRQ_MASK_AMI (1 << 5)
|
||||
#define RF23X_IRQ_MASK_TRX_UR (1 << 6)
|
||||
#define RF23X_IRQ_MASK_BAT_LOW (1 << 7)
|
||||
|
||||
#define RF23X_IRQ_MASK_DEFAULT (RF23X_IRQ_MASK_TRX_END)
|
||||
|
||||
#endif /* __DRIVERS_WIRELESS_IEEE802154_AT86RF23X_H */
|
File diff suppressed because it is too large
Load Diff
@ -33,8 +33,8 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __DRIVERS_IEEE802154_MRF24J40_H
|
||||
#define __DRIVERS_IEEE802154_MRF24J40_H
|
||||
#ifndef __DRIVERS_WIRELESS_IEEE802154_MRF24J40_H
|
||||
#define __DRIVERS_WIRELESS_IEEE802154_MRF24J40_H
|
||||
|
||||
/* MRF24J40 Registers *******************************************************/
|
||||
|
||||
@ -97,18 +97,27 @@
|
||||
#define MRF24J40_BBREG6 0x3E
|
||||
#define MRF24J40_CCAEDTH 0x3F
|
||||
|
||||
#define MRF24J40_RFCON0 0x80000200
|
||||
#define MRF24J40_RFCON1 0x80000201
|
||||
#define MRF24J40_RFCON2 0x80000202
|
||||
#define MRF24J40_RFCON3 0x80000203
|
||||
#define MRF24J40_RFCON5 0x80000205
|
||||
#define MRF24J40_RFCON6 0x80000206
|
||||
#define MRF24J40_RFCON7 0x80000207
|
||||
#define MRF24J40_RFCON8 0x80000208
|
||||
#define MRF24J40_SLPCAL0 0x80000209
|
||||
#define MRF24J40_SLPCAL1 0x8000020A
|
||||
#define MRF24J40_SLPCAL2 0x8000020B
|
||||
#define MRF24J40_RFSTATE 0x8000020F
|
||||
#define MRF24J40_FIFO_BASE 0x80000000
|
||||
#define MRF24J40_LONGREG_BASE 0x80000200
|
||||
#define MRF24J40_RXBUF_BASE 0x80000300
|
||||
|
||||
#define MRF24J40_TXNORM_FIFO (MRF24J40_FIFO_BASE + 0x000)
|
||||
#define MRF24J40_BEACON_FIFO (MRF24J40_FIFO_BASE + 0x080)
|
||||
#define MRF24J40_GTS1_FIFO (MRF24J40_FIFO_BASE + 0x100)
|
||||
#define MRF24J40_GTS2_FIFO (MRF24J40_FIFO_BASE + 0x180)
|
||||
|
||||
#define MRF24J40_RFCON0 (MRF24J40_LONGREG_BASE + 0x00)
|
||||
#define MRF24J40_RFCON1 (MRF24J40_LONGREG_BASE + 0x01)
|
||||
#define MRF24J40_RFCON2 (MRF24J40_LONGREG_BASE + 0x02)
|
||||
#define MRF24J40_RFCON3 (MRF24J40_LONGREG_BASE + 0x03)
|
||||
#define MRF24J40_RFCON5 (MRF24J40_LONGREG_BASE + 0x05)
|
||||
#define MRF24J40_RFCON6 (MRF24J40_LONGREG_BASE + 0x06)
|
||||
#define MRF24J40_RFCON7 (MRF24J40_LONGREG_BASE + 0x07)
|
||||
#define MRF24J40_RFCON8 (MRF24J40_LONGREG_BASE + 0x08)
|
||||
#define MRF24J40_SLPCAL0 (MRF24J40_LONGREG_BASE + 0x09)
|
||||
#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
|
||||
@ -147,18 +156,18 @@
|
||||
|
||||
/* INTSTAT bits */
|
||||
|
||||
#define MRF24J40_INTSTAT_SLPIF 0x80
|
||||
#define MRF24J40_INTSTAT_WAKEIF 0x40
|
||||
#define MRF24J40_INTSTAT_HSYMTMRIF 0x20
|
||||
#define MRF24J40_INTSTAT_SECIF 0x10
|
||||
#define MRF24J40_INTSTAT_RXIF 0x08
|
||||
#define MRF24J40_INTSTAT_TXG2IF 0x04
|
||||
#define MRF24J40_INTSTAT_TXG1IF 0x02
|
||||
#define MRF24J40_INTSTAT_TXNIF 0x01
|
||||
#define MRF24J40_INTSTAT_TXNIF (1 << 0)
|
||||
#define MRF24J40_INTSTAT_TXG1IF (1 << 1)
|
||||
#define MRF24J40_INTSTAT_TXG2IF (1 << 2)
|
||||
#define MRF24J40_INTSTAT_RXIF (1 << 3)
|
||||
#define MRF24J40_INTSTAT_SECIF (1 << 4)
|
||||
#define MRF24J40_INTSTAT_HSYMTMRIF (1 << 5)
|
||||
#define MRF24J40_INTSTAT_WAKEIF (1 << 6)
|
||||
#define MRF24J40_INTSTAT_SLPIF (1 << 7)
|
||||
|
||||
/* RXMCR bits */
|
||||
|
||||
#define MRF24J40_RXMCR_PROMI 0x01 /* Enable promisc mode (rx all valid packets) */
|
||||
#define MRF24J40_RXMCR_PROMI (1 << 0) /* Enable promisc mode (rx all valid packets) */
|
||||
#define MRF24J40_RXMCR_ERRPKT 0x02 /* Do not check CRC */
|
||||
#define MRF24J40_RXMCR_COORD 0x04 /* Enable coordinator mode ??? DIFFERENCE ??? - not used in datasheet! */
|
||||
#define MRF24J40_RXMCR_PANCOORD 0x08 /* Enable PAN coordinator mode ??? DIFFERENCE ??? */
|
||||
@ -166,7 +175,7 @@
|
||||
|
||||
/* TXMCR bits */
|
||||
|
||||
#define MRF24J40_TXMCR_CSMABF0 0x01
|
||||
#define MRF24J40_TXMCR_CSMABF0 (1 << 0)
|
||||
#define MRF24J40_TXMCR_CSMABF1 0x02
|
||||
#define MRF24J40_TXMCR_CSMABF2 0x04
|
||||
#define MRF24J40_TXMCR_MACMINBE0 0x08
|
||||
@ -184,7 +193,7 @@
|
||||
#define MRF24J40_INTCON_RXIE 0x08
|
||||
#define MRF24J40_INTCON_TXG2IE 0x04
|
||||
#define MRF24J40_INTCON_TXG1IE 0x02
|
||||
#define MRF24J40_INTCON_TXNIE 0x01
|
||||
#define MRF24J40_INTCON_TXNIE (1 << 0)
|
||||
|
||||
/* BBREG1 bits */
|
||||
|
||||
@ -197,10 +206,19 @@
|
||||
|
||||
/* TXNCON bits */
|
||||
|
||||
#define MRF24J40_TXNCON_TXNTRIG 0x01 /* Trigger packet tx, automatically cleared */
|
||||
#define MRF24J40_TXNCON_TXNTRIG (1 << 0) /* Trigger packet tx, automatically cleared */
|
||||
#define MRF24J40_TXNCON_TXNSECEN 0x02 /* Enable security */
|
||||
#define MRF24J40_TXNCON_TXNACKREQ 0x04 /* An ACK is requested for this pkt */
|
||||
#define MRF24J40_TXNCON_INDIRECT 0x08 /* Activate indirect tx bit (for coordinators) */
|
||||
#define MRF24J40_TXNCON_FPSTAT 0x10 /* Status of the frame pending big in txed acks */
|
||||
|
||||
#endif /* __DRIVERS_IEEE802154_MRF24J40_H */
|
||||
/* TXSTAT bits */
|
||||
|
||||
#define MRF24J40_TXSTAT_TXNSTAT (1 << 0)
|
||||
#define MRF24J40_TXSTAT_TXG1STAT (1 << 1)
|
||||
#define MRF24J40_TXSTAT_TXG2STAT (1 << 2)
|
||||
#define MRF24J40_TXSTAT_CCAFAIL (1 << 5)
|
||||
#define MRF24J40_TXSTAT_X_SHIFT 6
|
||||
#define MRF24J40_TXSTAT_X_MASK (3 << MRF24J40_TXSTAT_X_SHIFT)
|
||||
|
||||
#endif /* __DRIVERS_WIRELESS_IEEE802154_MRF24J40_H */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* include/nuttx/fs/ioctl.h
|
||||
*
|
||||
* Copyright (C) 2008, 2009, 2011-2014 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2008, 2009, 2011-2014, 2017 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -88,6 +88,7 @@
|
||||
#define _GPIOBASE (0x2300) /* GPIO driver commands */
|
||||
#define _CLIOCBASE (0x2400) /* Contactless modules ioctl commands */
|
||||
#define _USBCBASE (0x2500) /* USB-C controller ioctl commands */
|
||||
#define _MAC802154BASE (0x2600) /* 802.15.4 MAC ioctl commands */
|
||||
|
||||
/* boardctl() commands share the same number space */
|
||||
|
||||
@ -421,6 +422,12 @@
|
||||
#define _USBCIOCVALID(c) (_IOC_TYPE(c)==_USBCBASE)
|
||||
#define _USBCIOC(nr) _IOC(_USBCBASE,nr)
|
||||
|
||||
/* 802.15.4 MAC driver ioctl definitions ************************************/
|
||||
/* (see nuttx/include/wireless/ieee802154/ieee802154_mac.h */
|
||||
|
||||
#define _MAC802154IOCVALID(c) (_IOC_TYPE(c)==_MAC802154BASE)
|
||||
#define _MAC802154IOC(nr) _IOC(_MAC802154BASE,nr)
|
||||
|
||||
/* boardctl() command definitions *******************************************/
|
||||
|
||||
#define _BOARDIOCVALID(c) (_IOC_TYPE(c)==_BOARDBASE)
|
||||
|
@ -58,61 +58,20 @@
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* By default, a 2-byte Rime address is used for the IEEE802.15.4 MAC
|
||||
* device's link layer address. If CONFIG_NET_6LOWPAN_RIMEADDR_EXTENDED
|
||||
* is selected, then an 8-byte Rime address will be used.
|
||||
/* By default, a 2-byte short address is used for the IEEE802.15.4 MAC
|
||||
* device's link layer address. If CONFIG_NET_6LOWPAN_EXTENDEDADDR
|
||||
* is selected, then an 8-byte extended address will be used.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_NET_6LOWPAN_RIMEADDR_EXTENDED
|
||||
# define NET_6LOWPAN_RIMEADDR_SIZE 8
|
||||
#define NET_6LOWPAN_SADDRSIZE 2
|
||||
#define NET_6LOWPAN_EADDRSIZE 8
|
||||
|
||||
#ifdef CONFIG_NET_6LOWPAN_EXTENDEDADDR
|
||||
# define NET_6LOWPAN_ADDRSIZE NET_6LOWPAN_EADDRSIZE
|
||||
#else
|
||||
# define NET_6LOWPAN_RIMEADDR_SIZE 2
|
||||
# define NET_6LOWPAN_ADDRSIZE NET_6LOWPAN_SADDRSIZE
|
||||
#endif
|
||||
|
||||
/* Frame format definitions *************************************************/
|
||||
/* These are some definitions of element values used in the FCF. See the
|
||||
* IEEE802.15.4 spec for details.
|
||||
*/
|
||||
|
||||
#define FRAME802154_FRAMETYPE_SHIFT (0) /* Bits 0-2: Frame type */
|
||||
#define FRAME802154_FRAMETYPE_MASK (7 << FRAME802154_FRAMETYPE_SHIFT)
|
||||
#define FRAME802154_SECENABLED_SHIFT (3) /* Bit 3: Security enabled */
|
||||
#define FRAME802154_FRAMEPENDING_SHIFT (4) /* Bit 4: Frame pending */
|
||||
#define FRAME802154_ACKREQUEST_SHIFT (5) /* Bit 5: ACK request */
|
||||
#define FRAME802154_PANIDCOMP_SHIFT (6) /* Bit 6: PANID compression */
|
||||
/* Bits 7-9: Reserved */
|
||||
#define FRAME802154_DSTADDR_SHIFT (2) /* Bits 10-11: Dest address mode */
|
||||
#define FRAME802154_DSTADDR_MASK (3 << FRAME802154_DSTADDR_SHIFT)
|
||||
#define FRAME802154_VERSION_SHIFT (4) /* Bit 12-13: Frame version */
|
||||
#define FRAME802154_VERSION_MASK (3 << FRAME802154_VERSION_SHIFT)
|
||||
#define FRAME802154_SRCADDR_SHIFT (6) /* Bits 14-15: Source address mode */
|
||||
#define FRAME802154_SRCADDR_MASK (3 << FRAME802154_SRCADDR_SHIFT)
|
||||
|
||||
/* Unshifted values for use in struct frame802154_fcf_s */
|
||||
|
||||
#define FRAME802154_BEACONFRAME (0)
|
||||
#define FRAME802154_DATAFRAME (1)
|
||||
#define FRAME802154_ACKFRAME (2)
|
||||
#define FRAME802154_CMDFRAME (3)
|
||||
|
||||
#define FRAME802154_BEACONREQ (7)
|
||||
|
||||
#define FRAME802154_IEEERESERVED (0)
|
||||
#define FRAME802154_NOADDR (0) /* Only valid for ACK or Beacon frames */
|
||||
#define FRAME802154_SHORTADDRMODE (2)
|
||||
#define FRAME802154_LONGADDRMODE (3)
|
||||
|
||||
#define FRAME802154_NOBEACONS 0x0f
|
||||
|
||||
#define FRAME802154_BROADCASTADDR 0xffff
|
||||
#define FRAME802154_BROADCASTPANDID 0xffff
|
||||
|
||||
#define FRAME802154_IEEE802154_2003 (0)
|
||||
#define FRAME802154_IEEE802154_2006 (1)
|
||||
|
||||
#define FRAME802154_SECURITY_LEVEL_NONE (0)
|
||||
#define FRAME802154_SECURITY_LEVEL_128 (3)
|
||||
|
||||
/* This maximum size of an IEEE802.15.4 frame. Certain, non-standard
|
||||
* devices may exceed this value, however.
|
||||
*/
|
||||
@ -123,11 +82,35 @@
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/* Rime address representation */
|
||||
/* IEEE 802.15.4 address representations */
|
||||
|
||||
struct rimeaddr_s
|
||||
struct sixlowpan_saddr_s
|
||||
{
|
||||
uint8_t u8[NET_6LOWPAN_RIMEADDR_SIZE];
|
||||
uint8_t u8[NET_6LOWPAN_SADDRSIZE];
|
||||
};
|
||||
|
||||
struct sixlowpan_eaddr_s
|
||||
{
|
||||
uint8_t u8[NET_6LOWPAN_EADDRSIZE];
|
||||
};
|
||||
|
||||
union sixlowpan_anyaddr_u
|
||||
{
|
||||
struct sixlowpan_saddr_s saddr;
|
||||
struct sixlowpan_eaddr_s eaddr;
|
||||
};
|
||||
|
||||
struct sixlowpan_tagaddr_s
|
||||
{
|
||||
bool extended;
|
||||
union sixlowpan_anyaddr_u u;
|
||||
};
|
||||
|
||||
/* Represents the configured address size */
|
||||
|
||||
struct sixlowpan_addr_s
|
||||
{
|
||||
uint8_t u8[NET_6LOWPAN_ADDRSIZE];
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -224,7 +224,7 @@ struct net_driver_s
|
||||
#ifdef CONFIG_NET_6LOWPAN
|
||||
/* The address assigned to an IEEE 802.15.4 radio. */
|
||||
|
||||
struct rimeaddr_s ieee802154; /* IEEE 802.15.4 Radio address */
|
||||
struct sixlowpan_addr_s ieee802154; /* IEEE 802.15.4 Radio address */
|
||||
#endif
|
||||
} d_mac;
|
||||
#endif
|
||||
@ -436,8 +436,12 @@ int ipv6_input(FAR struct net_driver_s *dev);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_6LOWPAN
|
||||
struct ieee802154_driver_s; /* See sixlowpan.h */
|
||||
int sixlowpan_input(FAR struct ieee802154_driver_s *ieee);
|
||||
struct ieee802154_driver_s; /* See sixlowpan.h */
|
||||
struct ieee802154_data_ind_s; /* See ieee8021454_mac.h */
|
||||
struct iob_s; /* See iob.h */
|
||||
int sixlowpan_input(FAR struct ieee802154_driver_s *ieee,
|
||||
FAR struct iob_s *framelist,
|
||||
FAR const struct ieee802154_data_ind_s *ind);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -1,6 +1,7 @@
|
||||
/****************************************************************************
|
||||
* include/nuttx/net/sixlowpan.h
|
||||
* Header file for the 6lowpan implementation (RFC4944 and draft-hui-6lowpan-hc-01)
|
||||
* Header file for the 6lowpan implementation (RFC4944 and
|
||||
* draft-hui-6lowpan-hc-01)
|
||||
*
|
||||
* Copyright (C) 2017, Gregory Nutt, all rights reserved
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
@ -81,132 +82,132 @@
|
||||
* bytes for all subsequent headers.
|
||||
*/
|
||||
|
||||
#define RIME_FRAG_DISPATCH_SIZE 0 /* 16 bit */
|
||||
#define RIME_FRAG_TAG 2 /* 16 bit */
|
||||
#define RIME_FRAG_OFFSET 4 /* 8 bit */
|
||||
#define SIXLOWPAN_FRAG_DISPATCH_SIZE 0 /* 16 bit */
|
||||
#define SIXLOWPAN_FRAG_TAG 2 /* 16 bit */
|
||||
#define SIXLOWPAN_FRAG_OFFSET 4 /* 8 bit */
|
||||
|
||||
/* Define the Rime buffer as a byte array */
|
||||
/* Define the frame buffer as a byte array */
|
||||
|
||||
#define RIME_HC1_DISPATCH 0 /* 8 bit */
|
||||
#define RIME_HC1_ENCODING 1 /* 8 bit */
|
||||
#define RIME_HC1_TTL 2 /* 8 bit */
|
||||
#define SIXLOWPAN_HC1_DISPATCH 0 /* 8 bit */
|
||||
#define SIXLOWPAN_HC1_ENCODING 1 /* 8 bit */
|
||||
#define SIXLOWPAN_HC1_TTL 2 /* 8 bit */
|
||||
|
||||
#define RIME_HC1_HC_UDP_DISPATCH 0 /* 8 bit */
|
||||
#define RIME_HC1_HC_UDP_HC1_ENCODING 1 /* 8 bit */
|
||||
#define RIME_HC1_HC_UDP_UDP_ENCODING 2 /* 8 bit */
|
||||
#define RIME_HC1_HC_UDP_TTL 3 /* 8 bit */
|
||||
#define RIME_HC1_HC_UDP_PORTS 4 /* 8 bit */
|
||||
#define RIME_HC1_HC_UDP_CHKSUM 5 /* 16 bit */
|
||||
#define SIXLOWPAN_HC1_HC_UDP_DISPATCH 0 /* 8 bit */
|
||||
#define SIXLOWPAN_HC1_HC_UDP_HC1_ENCODING 1 /* 8 bit */
|
||||
#define SIXLOWPAN_HC1_HC_UDP_UDP_ENCODING 2 /* 8 bit */
|
||||
#define SIXLOWPAN_HC1_HC_UDP_TTL 3 /* 8 bit */
|
||||
#define SIXLOWPAN_HC1_HC_UDP_PORTS 4 /* 8 bit */
|
||||
#define SIXLOWPAN_HC1_HC_UDP_CHKSUM 5 /* 16 bit */
|
||||
|
||||
/* Min and Max compressible UDP ports - HC06 */
|
||||
|
||||
#define SIXLOWPAN_UDP_4_BIT_PORT_MIN 0xf0b0
|
||||
#define SIXLOWPAN_UDP_4_BIT_PORT_MAX 0xf0bf /* f0b0 + 15 */
|
||||
#define SIXLOWPAN_UDP_8_BIT_PORT_MIN 0xf000
|
||||
#define SIXLOWPAN_UDP_8_BIT_PORT_MAX 0xf0ff /* f000 + 255 */
|
||||
#define SIXLOWPAN_UDP_4_BIT_PORT_MIN 0xf0b0
|
||||
#define SIXLOWPAN_UDP_4_BIT_PORT_MAX 0xf0bf /* f0b0 + 15 */
|
||||
#define SIXLOWPAN_UDP_8_BIT_PORT_MIN 0xf000
|
||||
#define SIXLOWPAN_UDP_8_BIT_PORT_MAX 0xf0ff /* f000 + 255 */
|
||||
|
||||
/* 6lowpan dispatches */
|
||||
|
||||
#define SIXLOWPAN_DISPATCH_NALP 0x00 /* 00xxxxxx Not a LoWPAN packet */
|
||||
#define SIXLOWPAN_DISPATCH_NALP_MASK 0xc0 /* 11000000 */
|
||||
#define SIXLOWPAN_DISPATCH_NALP 0x00 /* 00xxxxxx Not a LoWPAN packet */
|
||||
#define SIXLOWPAN_DISPATCH_NALP_MASK 0xc0 /* 11000000 */
|
||||
|
||||
#define SIXLOWPAN_DISPATCH_IPV6 0x41 /* 01000001 Uncompressed IPv6 addresses */
|
||||
#define SIXLOWPAN_DISPATCH_HC1 0x42 /* 01000010 HC1 Compressed IPv6 header */
|
||||
#define SIXLOWPAN_DISPATCH_BC0 0x50 /* 01010000 BC0 Broadcast header */
|
||||
#define SIXLOWPAN_DISPATCH_ESC 0x7f /* 01111111 Additional Dispatch octet follows */
|
||||
#define SIXLOWPAN_DISPATCH_IPV6 0x41 /* 01000001 Uncompressed IPv6 addresses */
|
||||
#define SIXLOWPAN_DISPATCH_HC1 0x42 /* 01000010 HC1 Compressed IPv6 header */
|
||||
#define SIXLOWPAN_DISPATCH_BC0 0x50 /* 01010000 BC0 Broadcast header */
|
||||
#define SIXLOWPAN_DISPATCH_ESC 0x7f /* 01111111 Additional Dispatch octet follows */
|
||||
|
||||
#define SIXLOWPAN_DISPATCH_IPHC 0x60 /* 011xxxxx IP Header Compression (IPHC)*/
|
||||
#define SIXLOWPAN_DISPATCH_IPHC_MASK 0xe0 /* 11100000 */
|
||||
#define SIXLOWPAN_DISPATCH_IPHC 0x60 /* 011xxxxx IP Header Compression (IPHC)*/
|
||||
#define SIXLOWPAN_DISPATCH_IPHC_MASK 0xe0 /* 11100000 */
|
||||
|
||||
#define SIXLOWPAN_DISPATCH_MESH 0x80 /* 10xxxxxx Mesh routing header */
|
||||
#define SIXLOWPAN_DISPATCH_MESH_MASK 0xc0 /* 11000000 */
|
||||
#define SIXLOWPAN_DISPATCH_MESH 0x80 /* 10xxxxxx Mesh routing header */
|
||||
#define SIXLOWPAN_DISPATCH_MESH_MASK 0xc0 /* 11000000 */
|
||||
|
||||
#define SIXLOWPAN_DISPATCH_FRAG1 0xc0 /* 11000xxx Fragmentation header (first) */
|
||||
#define SIXLOWPAN_DISPATCH_FRAGN 0xe0 /* 11100xxx Fragmentation header (subsequent) */
|
||||
#define SIXLOWPAN_DISPATCH_FRAG_MASK 0xf8 /* 11111000 */
|
||||
#define SIXLOWPAN_DISPATCH_FRAG1 0xc0 /* 11000xxx Fragmentation header (first) */
|
||||
#define SIXLOWPAN_DISPATCH_FRAGN 0xe0 /* 11100xxx Fragmentation header (subsequent) */
|
||||
#define SIXLOWPAN_DISPATCH_FRAG_MASK 0xf8 /* 11111000 */
|
||||
|
||||
/* HC1 encoding */
|
||||
|
||||
#define SIXLOWPAN_HC1_NH_UDP 0x02
|
||||
#define SIXLOWPAN_HC1_NH_TCP 0x06
|
||||
#define SIXLOWPAN_HC1_NH_ICMP6 0x04
|
||||
#define SIXLOWPAN_HC1_NH_UDP 0x02
|
||||
#define SIXLOWPAN_HC1_NH_TCP 0x06
|
||||
#define SIXLOWPAN_HC1_NH_ICMP6 0x04
|
||||
|
||||
/* HC_UDP encoding (works together with HC1) */
|
||||
|
||||
#define SIXLOWPAN_HC_UDP_ALL_C 0xe0
|
||||
#define SIXLOWPAN_HC_UDP_ALL_C 0xe0
|
||||
|
||||
/* IPHC encoding
|
||||
*
|
||||
* Values of fields within the IPHC encoding first byte
|
||||
* (Using MS-to-LS bit numbering of the draft RFC)
|
||||
*/
|
||||
/* Bits 0-2: 011 */
|
||||
#define SIXLOWPAN_IPHC_TC_MASK 0x18 /* Bits 3-4: Traffic Class, Flow Label */
|
||||
# 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_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 */
|
||||
# define SIXLOWPAN_IPHC_HLIM_1 0x01 /* Compressed hop limit of 1 */
|
||||
# define SIXLOWPAN_IPHC_HLIM_64 0x02 /* Compressed hop limit of 64 */
|
||||
# define SIXLOWPAN_IPHC_HLIM_255 0x03 /* Compressed hop limit of 255 */
|
||||
/* Bits 0-2: 011 */
|
||||
#define SIXLOWPAN_IPHC_TC_MASK 0x18 /* Bits 3-4: Traffic Class, Flow Label */
|
||||
# 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_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 */
|
||||
# define SIXLOWPAN_IPHC_HLIM_1 0x01 /* Compressed hop limit of 1 */
|
||||
# define SIXLOWPAN_IPHC_HLIM_64 0x02 /* Compressed hop limit of 64 */
|
||||
# define SIXLOWPAN_IPHC_HLIM_255 0x03 /* Compressed hop limit of 255 */
|
||||
|
||||
/* Values of fields within the IPHC encoding second byte */
|
||||
|
||||
#define SIXLOWPAN_IPHC_CID 0x80 /* Bit 8: Context identifier extension */
|
||||
#define SIXLOWPAN_IPHC_SAC 0x40 /* Bit 9: Source address compression */
|
||||
#define SIXLOWPAN_IPHC_SAM_MASK 0x30 /* Bits 10-11: Source address mode */
|
||||
# define SIXLOWPAN_IPHC_SAM_128 0x00 /* 128-bits */
|
||||
# define SIXLOWPAN_IPHC_SAM_64 0x10 /* 64-bits */
|
||||
# define SIXLOWPAN_IPHC_SAM_16 0x20 /* 16-bits */
|
||||
# define SIXLOWPAN_IPHC_SAM_0 0x30 /* 0-bits */
|
||||
#define SIXLOWPAN_IPHC_M 0x08 /* Bit 12: Multicast compression */
|
||||
#define SIXLOWPAN_IPHC_DAC 0x04 /* Bit 13: Destination address compression */
|
||||
#define SIXLOWPAN_IPHC_DAM_MASK 0x03 /* Bits 14-15: Destination address mode */
|
||||
# define SIXLOWPAN_IPHC_DAM_128 0x00 /* 128-bits */
|
||||
# define SIXLOWPAN_IPHC_DAM_64 0x01 /* 64-bits */
|
||||
# define SIXLOWPAN_IPHC_DAM_16 0x02 /* 16-bits */
|
||||
# define SIXLOWPAN_IPHC_DAM_0 0x03 /* 0-bits */
|
||||
#define SIXLOWPAN_IPHC_CID 0x80 /* Bit 8: Context identifier extension */
|
||||
#define SIXLOWPAN_IPHC_SAC 0x40 /* Bit 9: Source address compression */
|
||||
#define SIXLOWPAN_IPHC_SAM_MASK 0x30 /* Bits 10-11: Source address mode */
|
||||
# define SIXLOWPAN_IPHC_SAM_128 0x00 /* 128-bits */
|
||||
# define SIXLOWPAN_IPHC_SAM_64 0x10 /* 64-bits */
|
||||
# define SIXLOWPAN_IPHC_SAM_16 0x20 /* 16-bits */
|
||||
# define SIXLOWPAN_IPHC_SAM_0 0x30 /* 0-bits */
|
||||
#define SIXLOWPAN_IPHC_M 0x08 /* Bit 12: Multicast compression */
|
||||
#define SIXLOWPAN_IPHC_DAC 0x04 /* Bit 13: Destination address compression */
|
||||
#define SIXLOWPAN_IPHC_DAM_MASK 0x03 /* Bits 14-15: Destination address mode */
|
||||
# define SIXLOWPAN_IPHC_DAM_128 0x00 /* 128-bits */
|
||||
# define SIXLOWPAN_IPHC_DAM_64 0x01 /* 64-bits */
|
||||
# define SIXLOWPAN_IPHC_DAM_16 0x02 /* 16-bits */
|
||||
# define SIXLOWPAN_IPHC_DAM_0 0x03 /* 0-bits */
|
||||
|
||||
#define SIXLOWPAN_IPHC_SAM_BIT 4
|
||||
#define SIXLOWPAN_IPHC_DAM_BIT 0
|
||||
#define SIXLOWPAN_IPHC_SAM_BIT 4
|
||||
#define SIXLOWPAN_IPHC_DAM_BIT 0
|
||||
|
||||
/* Link local context number */
|
||||
|
||||
#define SIXLOWPAN_IPHC_ADDR_CONTEXT_LL 0
|
||||
#define SIXLOWPAN_IPHC_ADDR_CONTEXT_LL 0
|
||||
|
||||
/* 16-bit multicast addresses compression */
|
||||
|
||||
#define SIXLOWPAN_IPHC_MCAST_RANGE 0xa0
|
||||
#define SIXLOWPAN_IPHC_MCAST_RANGE 0xa0
|
||||
|
||||
/* NHC_EXT_HDR */
|
||||
|
||||
#define SIXLOWPAN_NHC_MASK 0xf0
|
||||
#define SIXLOWPAN_NHC_EXT_HDR 0xe0
|
||||
#define SIXLOWPAN_NHC_MASK 0xf0
|
||||
#define SIXLOWPAN_NHC_EXT_HDR 0xe0
|
||||
|
||||
/* LOWPAN_UDP encoding (works together with IPHC) */
|
||||
|
||||
#define SIXLOWPAN_NHC_UDP_MASK 0xf8
|
||||
#define SIXLOWPAN_NHC_UDP_ID 0xf0
|
||||
#define SIXLOWPAN_NHC_UDP_CHECKSUMC 0x04
|
||||
#define SIXLOWPAN_NHC_UDP_CHECKSUMI 0x00
|
||||
#define SIXLOWPAN_NHC_UDP_MASK 0xf8
|
||||
#define SIXLOWPAN_NHC_UDP_ID 0xf0
|
||||
#define SIXLOWPAN_NHC_UDP_CHECKSUMC 0x04
|
||||
#define SIXLOWPAN_NHC_UDP_CHECKSUMI 0x00
|
||||
|
||||
/* Values for port compression, _with checksum_ ie bit 5 set to 0 */
|
||||
|
||||
#define SIXLOWPAN_NHC_UDP_CS_P_00 0xf0 /* All inline */
|
||||
#define SIXLOWPAN_NHC_UDP_CS_P_01 0xf1 /* Source 16bit inline, dest = 0xf0 + 8 bit inline */
|
||||
#define SIXLOWPAN_NHC_UDP_CS_P_10 0xf2 /* Source = 0xf0 + 8bit inline, dest = 16 bit inline */
|
||||
#define SIXLOWPAN_NHC_UDP_CS_P_11 0xf3 /* Source & dest = 0xf0b + 4bit inline */
|
||||
#define SIXLOWPAN_NHC_UDP_CS_P_00 0xf0 /* All inline */
|
||||
#define SIXLOWPAN_NHC_UDP_CS_P_01 0xf1 /* Source 16bit inline, dest = 0xf0 + 8 bit inline */
|
||||
#define SIXLOWPAN_NHC_UDP_CS_P_10 0xf2 /* Source = 0xf0 + 8bit inline, dest = 16 bit inline */
|
||||
#define SIXLOWPAN_NHC_UDP_CS_P_11 0xf3 /* Source & dest = 0xf0b + 4bit inline */
|
||||
|
||||
/* The 6lowpan "headers" length */
|
||||
|
||||
#define SIXLOWPAN_IPV6_HDR_LEN 1 /* One byte */
|
||||
#define SIXLOWPAN_HC1_HDR_LEN 3
|
||||
#define SIXLOWPAN_HC1_HC_UDP_HDR_LEN 7
|
||||
#define SIXLOWPAN_FRAG1_HDR_LEN 4
|
||||
#define SIXLOWPAN_FRAGN_HDR_LEN 5
|
||||
#define SIXLOWPAN_IPV6_HDR_LEN 1 /* One byte */
|
||||
#define SIXLOWPAN_HC1_HDR_LEN 3
|
||||
#define SIXLOWPAN_HC1_HC_UDP_HDR_LEN 7
|
||||
#define SIXLOWPAN_FRAG1_HDR_LEN 4
|
||||
#define SIXLOWPAN_FRAGN_HDR_LEN 5
|
||||
|
||||
/* Address compressibility test macros **************************************/
|
||||
|
||||
@ -227,7 +228,7 @@
|
||||
|
||||
#define SIXLOWPAN_IS_IID_16BIT_COMPRESSABLE(a) \
|
||||
((((a)[4]) == 0x0000) && (((a)[5]) == HTONS(0x00ff)) && \
|
||||
(((a)[6]) == 0xfe00))
|
||||
(((a)[6]) == HTONS(0xfe00)))
|
||||
|
||||
/* Check whether the 9-bit group-id of the compressed multicast address is
|
||||
* known. It is true if the 9-bit group is the all nodes or all routers
|
||||
@ -271,61 +272,6 @@
|
||||
(a)[4] == 0 && (a)[5] == 0 && (a)[6] == 0 && \
|
||||
(((a)[7] & HTONS(0xff00)) == 0x0000))
|
||||
|
||||
/* Frame buffer helper macros ***********************************************/
|
||||
/* The IEEE802.15.4 MAC driver structures includes a list of IOB
|
||||
* structures, i_framelist, containing frames to be sent by the driver or
|
||||
* that were received by the driver. The IOB structure is defined in
|
||||
* include/nuttx/drivers/iob.h. The length of data in the IOB is provided by
|
||||
* the io_len field of the IOB structure.
|
||||
*
|
||||
* NOTE that IOBs must be configured such that CONFIG_IOB_BUFSIZE >=
|
||||
* CONFIG_NET_6LOWPAN_FRAMELEN
|
||||
*
|
||||
* 1. On a TX poll, the IEEE802.15.4 MAC driver should provide its driver
|
||||
* structure with i_framelist set to NULL. At the conclusion of the
|
||||
* poll, if there are frames to be sent, they will have been added to
|
||||
* the i_framelist. The non-empty frame list is the indication that
|
||||
* there is data to be sent.
|
||||
*
|
||||
* The IEEE802.15.4 may use the FRAME_IOB_EMPTY() macro to determine
|
||||
* if there there frames to be sent. If so, it should remove each
|
||||
* frame from the frame list using the FRAME_IOB_REMOVE() macro and send
|
||||
* it. That macro will return NULL when all of the frames have been
|
||||
* sent.
|
||||
*
|
||||
* After sending each frame, the driver must return the IOB to the pool
|
||||
* of free IOBs using the FROM_IOB_FREE() macro.
|
||||
*/
|
||||
|
||||
|
||||
#define FRAME_IOB_EMPTY(ieee) ((ieee)->i_framelist == NULL)
|
||||
#define FRAME_IOB_REMOVE(ieee, iob) \
|
||||
do \
|
||||
{ \
|
||||
(iob) = (ieee)->i_framelist; \
|
||||
(ieee)->i_framelist = (iob)->io_flink; \
|
||||
(iob)->io_flink = NULL; \
|
||||
} \
|
||||
while (0)
|
||||
#define FRAME_IOB_FREE(iob) iob_free(iob)
|
||||
|
||||
/* 2. When receiving data, the IEEE802.15.4 MAC driver should receive the
|
||||
* frame data directly into the payload area of an IOB structure. That
|
||||
* IOB structure may be obtained using the FRAME_IOB_ALLOC() macro. The
|
||||
* single frame should be added to the frame list using FRAME_IOB_ADD()
|
||||
* (it will be a list of length one) . The MAC driver should then inform
|
||||
* the network of the by calling sixlowpan_input().
|
||||
*/
|
||||
|
||||
#define FRAME_IOB_ALLOC() iob_alloc(false)
|
||||
#define FRAME_IOB_ADD(ieee, iob) \
|
||||
do \
|
||||
{ \
|
||||
(iob)->io_flink = (ieee)->i_framelist; \
|
||||
(ieee)->i_framelist = (iob); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
@ -335,18 +281,21 @@
|
||||
* difference is that fragmentation must be supported.
|
||||
*
|
||||
* The IEEE802.15.4 MAC does not use the d_buf packet buffer directly.
|
||||
* Rather, it uses a list smaller frame buffers, i_framelist.
|
||||
* Rather, it uses a list smaller frame buffers.
|
||||
*
|
||||
* - The packet fragment data is provided to an IOB in the i_framelist
|
||||
* buffer each time that the IEEE802.15.4 MAC needs to send more data.
|
||||
* The length of the frame is provided in the io_len field of the IOB.
|
||||
* - The packet fragment data is provided in an IOB in the via the
|
||||
* i_req_data() interface method each time that the IEEE802.15.4 MAC
|
||||
* needs to send more data. The length of the frame is provided in the
|
||||
* io_len field of the IOB.
|
||||
*
|
||||
* In this case, the d_buf is not used at all and, if fact, may be
|
||||
* NULL.
|
||||
*
|
||||
* - Received frames are provided by IEEE802.15.4 MAC to the network
|
||||
* via and IOB in i_framelist with length io_len for reassembly in
|
||||
* d_buf; d_len will hold the size of the reassembled packet.
|
||||
* via an IOB parameter in the sixlowpan_submit() interface. The
|
||||
* length of the frawme is io_len and will be uncompressed and possibly
|
||||
* reassembled in the d_buf; d_len will hold the size of the
|
||||
* reassembled packet.
|
||||
*
|
||||
* In this case, a d_buf of size CONFIG_NET_6LOWPAN_MTU must be provided.
|
||||
*
|
||||
@ -360,51 +309,42 @@
|
||||
* this structure. In general, all fields must be set to NULL. In
|
||||
* addtion:
|
||||
*
|
||||
* 1. i_panid must be set to identify the network. It may be set to 0xfff
|
||||
* if the device is not associated.
|
||||
* 1. On a TX poll, the IEEE802.15.4 MAC driver should provide its driver
|
||||
* structure. During the course of the poll, the networking layer may
|
||||
* generate outgoing frames. These frames will by provided to the MAC
|
||||
* driver via the req_data() method.
|
||||
*
|
||||
* 2. i_dsn must be set to a random value. After that, it will be managed
|
||||
* by the network.
|
||||
* After sending each frame through the radio, the MAC driver must
|
||||
* return the frame to the pool of free IOBs using the iob_free().
|
||||
*
|
||||
* 3. On a TX poll, the IEEE802.15.4 MAC driver should provide its driver
|
||||
* structure with i_framelist set to NULL. At the conclusion of the
|
||||
* poll, if there are frames to be sent, they will have been added to
|
||||
* the i_framelist. The non-empty frame list at the conclusion of the
|
||||
* TX poll is the indication that is data to be sent.
|
||||
*
|
||||
* The IEEE802.15.4 may use the FRAME_IOB_EMPTY() macro to determine
|
||||
* if there there frames to be sent. If so, it should remove each
|
||||
* frame from the frame list using the FRAME_IOB_REMOVE() macro and send
|
||||
* it. That macro will return NULL when all of the frames have been
|
||||
* sent.
|
||||
*
|
||||
* After sending each frame, the driver must return the IOB to the pool
|
||||
* of free IOBs using the FROM_IOB_FREE() macro.
|
||||
*
|
||||
* 4. When receiving data both buffers must be provided:
|
||||
* 2. When receiving data both buffers must be provided:
|
||||
*
|
||||
* The IEEE802.15.4 MAC driver should receive the frame data directly
|
||||
* into the payload area of an IOB structure. That IOB structure may be
|
||||
* obtained using the FRAME_IOB_ALLOC() macro. The single frame should
|
||||
* be added to the frame list using FRAME_IOB_ADD() (it will be a list of
|
||||
* length one).
|
||||
* into the payload area of an IOB frame structure. That IOB structure
|
||||
* may be obtained using the iob_alloc() function.
|
||||
*
|
||||
* The larger dev.d_buf must have a size of at least the advertised MTU
|
||||
* of the protocol, CONFIG_NET_6LOWPAN_MTU. If fragmentation is enabled,
|
||||
* then the logical packet size may be significantly larger than the
|
||||
* size of the frame buffer. The dev.d_buf is used for de-compressing
|
||||
* each frame and reassembling any fragmented packets to create the full
|
||||
* input packet that is provided to the application.
|
||||
* of the protocol, CONFIG_NET_6LOWPAN_MTU, plus CONFIG_NET_GUARDSIZE.
|
||||
* If fragmentation is enabled, then the logical packet size may be
|
||||
* significantly larger than the size of the frame buffer. The dev.d_buf
|
||||
* is used for de-compressing each frame and reassembling any fragmented
|
||||
* packets to create the full input packet that is provided to the
|
||||
* application.
|
||||
*
|
||||
* The MAC driver should then inform the network of the by calling
|
||||
* sixlowpan_input().
|
||||
* sixlowpan_input(). That single frame (or, perhaps, list of frames)
|
||||
* should be provided as second argument of that call.
|
||||
*
|
||||
* Normally, the network will free the IOB and will nullify the frame
|
||||
* list. But ss a complexity, the result of receiving a frame may be
|
||||
* that the network may respond provide an outgoing frames in the
|
||||
* frame list.
|
||||
* The network will free the IOB by calling iob_free after it has
|
||||
* processed the incoming frame. As a complexity, the result of
|
||||
* receiving a frame may be that the network may respond provide an
|
||||
* outgoing frames in the via a nested calle to the req_data() method.
|
||||
*/
|
||||
|
||||
struct ieee802154_frame_meta_s; /* Forward reference */
|
||||
struct ieee802154_data_ind_s; /* Forward reference */
|
||||
struct iob_s; /* Forward reference */
|
||||
|
||||
struct ieee802154_driver_s
|
||||
{
|
||||
/* This definitiona must appear first in the structure definition to
|
||||
@ -415,43 +355,22 @@ struct ieee802154_driver_s
|
||||
|
||||
/* IEEE802.15.4 MAC-specific definitions follow. */
|
||||
|
||||
/* The i_framelist is used to hold a outgoing frames contained in IOB
|
||||
* structures. When the IEEE802.15.4 device polls for new TX data, the
|
||||
* outgoing frame(s) containing the packet fragments are placed in IOBs
|
||||
* and queued in i_framelist.
|
||||
/* The msdu_handle is basically an id for the frame. The standard just
|
||||
* says that the next highest layer should determine it. It is used in
|
||||
* three places
|
||||
*
|
||||
* The i_framelist is similary used to hold incoming frames in IOB
|
||||
* structures. The IEEE802.15.4 MAC driver must receive frames in an IOB,
|
||||
* place the IOB in the i_framelist, and call sixlowpan_input().
|
||||
* 1. When you do that data request
|
||||
* 2. When the transmission is complete, the conf_data is called with
|
||||
* that handle so that the user can be notified of the frames success/
|
||||
* failure
|
||||
* 3. For a req_purge, to basically "cancel" the transaction. This is
|
||||
* often particularly useful on a coordinator that has indirect data
|
||||
* waiting to be requested from another device
|
||||
*
|
||||
* The IEEE802.15.4 MAC driver design may be concurrently sending and
|
||||
* requesting new frames using lists of IOBs. That IOB frame buffer
|
||||
* management must be managed by the IEEE802.15.4 MAC driver.
|
||||
* Here is a simple frame counter.
|
||||
*/
|
||||
|
||||
FAR struct iob_s *i_framelist;
|
||||
|
||||
/* Driver Configuration ***************************************************/
|
||||
/* i_panid. The PAN ID is 16-bit number that identifies the network. It
|
||||
* must be unique to differentiate a network. All the nodes in the same
|
||||
* network should have the same PAN ID. This value must be provided to
|
||||
* the network from the IEEE802.15.4 MAC driver.
|
||||
*
|
||||
* If this value is 0xffff, the device is not associated.
|
||||
*/
|
||||
|
||||
uint16_t i_panid;
|
||||
|
||||
/* i_dsn. The sequence number in the range 0x00-0xff added to the
|
||||
* transmitted data or MAC command frame. The default is a random value
|
||||
* within that range.
|
||||
*
|
||||
* This field must be initialized to a random number by the IEEE802.15.4
|
||||
* MAC driver. It sill be subsequently incremented on each frame by the
|
||||
* network logic.
|
||||
*/
|
||||
|
||||
uint8_t i_dsn;
|
||||
uint8_t i_msdu_handle;
|
||||
|
||||
#if CONFIG_NET_6LOWPAN_FRAG
|
||||
/* Fragmentation Support *************************************************/
|
||||
@ -502,7 +421,7 @@ struct ieee802154_driver_s
|
||||
|
||||
/* The source MAC address of the fragments being merged */
|
||||
|
||||
struct rimeaddr_s i_fragsrc;
|
||||
struct sixlowpan_tagaddr_s i_fragsrc;
|
||||
|
||||
/* That time at which reassembly was started. If the elapsed time
|
||||
* exceeds CONFIG_NET_6LOWPAN_MAXAGE, then the reassembly will
|
||||
@ -511,6 +430,47 @@ struct ieee802154_driver_s
|
||||
|
||||
systime_t i_time;
|
||||
#endif /* CONFIG_NET_6LOWPAN_FRAG */
|
||||
|
||||
/* MAC network driver callback functions **********************************/
|
||||
/**************************************************************************
|
||||
* Name: mac802154_get_mhrlen
|
||||
*
|
||||
* Description:
|
||||
* Calculate the MAC header length given the frame meta-data.
|
||||
*
|
||||
* Input parameters:
|
||||
* netdev - The networkd device that will mediate the MAC interface
|
||||
* meta - Meta data needed to recreate the MAC header
|
||||
*
|
||||
* Returned Value:
|
||||
* A non-negative MAC headeer length is returned on success; a negated
|
||||
* errno value is returned on any failure.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
CODE int (*i_get_mhrlen)(FAR struct ieee802154_driver_s *netdev,
|
||||
FAR const struct ieee802154_frame_meta_s *meta);
|
||||
|
||||
/**************************************************************************
|
||||
* Name: mac802154_req_data
|
||||
*
|
||||
* Description:
|
||||
* Requests the transfer of a list of frames to the MAC.
|
||||
*
|
||||
* Input parameters:
|
||||
* netdev - The networkd device that will mediate the MAC interface
|
||||
* meta - Meta data needed to recreate the MAC header
|
||||
* framelist - Head of a list of frames to be transferred.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) returned on success; a negated errno value is returned on
|
||||
* any failure.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
CODE int (*i_req_data)(FAR struct ieee802154_driver_s *netdev,
|
||||
FAR const struct ieee802154_frame_meta_s *meta,
|
||||
FAR struct iob_s *framelist);
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
@ -523,25 +483,32 @@ struct ieee802154_driver_s
|
||||
* Description:
|
||||
* Process an incoming 6loWPAN frame.
|
||||
*
|
||||
* This function is called when the device driver has received a 6loWPAN
|
||||
* frame from the network. The frame from the device driver must be
|
||||
* provided in a IOB present in the i_framelist: The frame data is in the
|
||||
* IOB io_data[] buffer and the length of the frame is in the IOB io_len
|
||||
* field. Only a single IOB is expected in the i_framelist. This incoming
|
||||
* data will be processed one frame at a time.
|
||||
* This function is called when the device driver has received an
|
||||
* IEEE802.15.4 frame from the network. The frame from the device
|
||||
* driver must be provided in by the IOB frame argument of the
|
||||
* function call:
|
||||
*
|
||||
* An non-NULL d_buf of size CONFIG_NET_6LOWPAN_MTU must also be provided.
|
||||
* The frame will be decompressed and placed in the d_buf. Fragmented
|
||||
* packets will also be reassembled in the d_buf as they are received
|
||||
* (meaning for the driver, that two packet buffers are required: One for
|
||||
* reassembly of RX packets and one used for TX polling).
|
||||
* - The frame data is in the IOB io_data[] buffer,
|
||||
* - The length of the frame is in the IOB io_len field, and
|
||||
* - The offset past the IEEE802.15.4 MAC header is provided in the
|
||||
* io_offset field.
|
||||
*
|
||||
* After each frame is processed into d_buf, the IOB is removed and
|
||||
* deallocated. i_framelist will be nullified. If reassembly is
|
||||
* incomplete, this function will return to called with i_framelist
|
||||
* equal to NULL. The partially reassembled packet must be preserved by
|
||||
* the IEEE802.15.4 MAC and provided again when the next frame is
|
||||
* received.
|
||||
* The frame argument may refer to a single frame (a list of length one)
|
||||
* or may it be the head of a list of multiple frames.
|
||||
*
|
||||
* - The io_flink field points to the next frame in the list (if enable)
|
||||
* - The last frame in the list will have io_flink == NULL.
|
||||
*
|
||||
* An non-NULL d_buf of size CONFIG_NET_6LOWPAN_MTU + CONFIG_NET_GUARDSIZE
|
||||
* must also be provided. The frame will be decompressed and placed in
|
||||
* the d_buf. Fragmented packets will also be reassembled in the d_buf as
|
||||
* they are received (meaning for the driver, that two packet buffers are
|
||||
* required: One for reassembly of RX packets and one used for TX polling).
|
||||
*
|
||||
* After each frame is processed into d_buf, the IOB is deallocated. If
|
||||
* reassembly is incomplete, the partially reassembled packet must be
|
||||
* preserved by the IEEE802.15.4 MAC network drvier sand provided again
|
||||
* when the next frame is received.
|
||||
*
|
||||
* When the packet in the d_buf is fully reassembled, it will be provided
|
||||
* to the network as with any other received packet. d_len will be set
|
||||
@ -549,28 +516,31 @@ struct ieee802154_driver_s
|
||||
*
|
||||
* After the network processes the packet, d_len will be set to zero.
|
||||
* Network logic may also decide to send a response to the packet. In
|
||||
* that case, the outgoing network packet will be placed in d_buf the
|
||||
* d_buf and d_len will be set to a non-zero value. That case is handled
|
||||
* by this function.
|
||||
* that case, the outgoing network packet will be placed in d_buf and
|
||||
* d_len will be set to a non-zero value. That case is handled by this
|
||||
* function.
|
||||
*
|
||||
* If that case occurs, the packet will be converted to a list of
|
||||
* compressed and possibly fragmented frames in i_framelist as with other
|
||||
* TX operations.
|
||||
*
|
||||
* So from the standpoint of the IEEE802.15.4 MAC driver, there are two
|
||||
* possible results: (1) i_framelist is NULL meaning that the frame
|
||||
* was fully processed and freed, or (2) i_framelist is non-NULL meaning
|
||||
* that there are outgoing frame(s) to be sent.
|
||||
* compressed and possibly fragmented frames and provided to the MAC
|
||||
* network driver via the req_data() method as with other TX operations.
|
||||
*
|
||||
* Input Parameters:
|
||||
* ieee - The IEEE802.15.4 MAC network driver interface.
|
||||
* ieee - The IEEE802.15.4 MAC network driver interface.
|
||||
* framelist - The head of an incoming list of frames. Normally this
|
||||
* would be a single frame. A list may be provided if
|
||||
* appropriate, however.
|
||||
* ind - Meta data characterizing the received packet. If there are
|
||||
* multilple frames in the list, this meta data must apply to
|
||||
* all of the frames!
|
||||
*
|
||||
* Returned Value:
|
||||
* Ok is returned on success; Othewise a negated errno value is returned.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sixlowpan_input(FAR struct ieee802154_driver_s *ieee);
|
||||
int sixlowpan_input(FAR struct ieee802154_driver_s *ieee,
|
||||
FAR struct iob_s *framelist,
|
||||
FAR const struct ieee802154_data_ind_s *ind);
|
||||
|
||||
#endif /* CONFIG_NET_6LOWPAN */
|
||||
#endif /* __INCLUDE_NUTTX_NET_SIXLOWPAN_H */
|
||||
|
114
include/nuttx/wireless/ieee802154/at86rf23x.h
Normal file
114
include/nuttx/wireless/ieee802154/at86rf23x.h
Normal file
@ -0,0 +1,114 @@
|
||||
/****************************************************************************
|
||||
* include/nuttx/ieee802154/at86rf23x.h
|
||||
*
|
||||
* Copyright (C) 2014-2015 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2014-2015 Sebastien Lorquet. All rights reserved.
|
||||
* Author: Sebastien Lorquet <sebastien@lorquet.fr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __INCLUDE_NUTTX_IEEE802154_AT86RF23X_H
|
||||
#define __INCLUDE_NUTTX_IEEE802154_AT86RF23X_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/* The at86rf23x provides interrupts to the MCU via a GPIO pin. The
|
||||
* following structure provides an MCU-independent mechanixm for controlling
|
||||
* the at86rf23x GPIO interrupt.
|
||||
*
|
||||
* The at86rf23x interrupt is an active low, *level* interrupt. From Datasheet:
|
||||
* "Note 1: The INTEDGE polarity defaults to: 0 = Falling Edge. Ensure that
|
||||
* the interrupt polarity matches the interrupt pin polarity of the host
|
||||
* microcontroller.
|
||||
* "Note 2: The INT pin will remain high or low, depending on INTEDGE polarity
|
||||
* setting, until INTSTAT register is read."
|
||||
*/
|
||||
|
||||
struct at86rf23x_lower_s
|
||||
{
|
||||
int (*attach)(FAR const struct at86rf23x_lower_s *lower, xcpt_t handler,
|
||||
FAR void *arg);
|
||||
void (*enable)(FAR const struct at86rf23x_lower_s *lower, bool state);
|
||||
void (*slptr)(FAR const struct at86rf23x_lower_s *lower, bool state);
|
||||
void (*reset)(FAR const struct at86rf23x_lower_s *lower, bool state);
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Function: at86rf23x_init
|
||||
*
|
||||
* Description:
|
||||
* Initialize the IEEE802.15.4 driver. The at86rf23x device is assumed to be
|
||||
* in the post-reset state upon entry to this function.
|
||||
*
|
||||
* Parameters:
|
||||
* spi - A reference to the platform's SPI driver for the at86rf23x
|
||||
* lower - The MCU-specific interrupt used to control low-level MCU
|
||||
* functions (i.e., at86rf23x GPIO interrupts).
|
||||
* devno - If more than one at86rf23x is supported, then this is the
|
||||
* zero based number that identifies the at86rf23x;
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success; Negated errno on failure.
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct ieee802154_radio_s *
|
||||
at86rf23x_init(FAR struct spi_dev_s *spi,
|
||||
FAR const struct at86rf23x_lower_s *lower);
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __INCLUDE_NUTTX_IEEE802154__AT86RF23X_H */
|
@ -1,11 +1,9 @@
|
||||
/****************************************************************************
|
||||
* include/nuttx/net/ieee802154.h
|
||||
/************************************************************************************
|
||||
* include/nuttx/wireless/ieee802154/ieee802154_ioctl.h
|
||||
* IEEE802.15.4 character driver IOCTL commands
|
||||
*
|
||||
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Includes some definitions that a compatible with the LGPL GNU C Library
|
||||
* header file of the same name.
|
||||
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -34,29 +32,61 @@
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
************************************************************************************/
|
||||
|
||||
#ifndef __INCLUDE_NUTTX_WIRELESS_IEEE802154_IEEE802154_H
|
||||
#define __INCLUDE_NUTTX_WIRELESS_IEEE802154_IEEE802154_H
|
||||
/* This file includes common definitions to be used in all wireless character drivers
|
||||
* (when applicable).
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
#ifndef __INCLUDE_NUTTX_WIRELESS_IEEE802154_IEEE802154_IOCTL_H
|
||||
#define __INCLUDE_NUTTX_WIRELESS_IEEE802154_IEEE802154_IOCTL_H
|
||||
|
||||
/************************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
************************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/wireless/ioctl.h>
|
||||
|
||||
#include <nuttx/net/netconfig.h>
|
||||
#include <nuttx/wireless/ieee802154/ieee802154_mac.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Public Type Definitions
|
||||
****************************************************************************/
|
||||
#ifdef CONFIG_WIRELESS_IEEE802154
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
/************************************************************************************
|
||||
* Pre-processor Definitions
|
||||
************************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
/* IEEE 802.15.4 Radio Character Driver IOCTL commands ******************************/
|
||||
/* None defined */
|
||||
|
||||
#endif /* __INCLUDE_NUTTX_WIRELESS_IEEE802154_IEEE802154_H */
|
||||
/* IEEE 802.15.4 MAC Character Driver IOCTL commands ********************************/
|
||||
|
||||
|
||||
#define MAC802154IOC_MCPS_REGISTER _WLCIOC(IEEE802154_FIRST)
|
||||
#define MAC802154IOC_MLME_REGISTER _WLCIOC(IEEE802154_FIRST+1)
|
||||
|
||||
/************************************************************************************
|
||||
* Public Types
|
||||
************************************************************************************/
|
||||
|
||||
struct mac802154dev_notify_s
|
||||
{
|
||||
uint8_t mn_signo; /* Signal number to use in the notification */
|
||||
};
|
||||
|
||||
struct mac802154dev_txframe_s
|
||||
{
|
||||
struct ieee802154_frame_meta_s meta;
|
||||
FAR uint8_t *payload;
|
||||
uint16_t length;
|
||||
};
|
||||
|
||||
struct mac802154dev_rxframe_s
|
||||
{
|
||||
struct ieee802154_data_ind_s meta;
|
||||
uint8_t payload[IEEE802154_MAX_MAC_PAYLOAD_SIZE];
|
||||
uint16_t length;
|
||||
};
|
||||
|
||||
#endif /* CONFIG_WIRELESS_IEEE802154 */
|
||||
#endif /* __INCLUDE_NUTTX_WIRELESS_IEEE802154_IEEE802154_IOCTL_H */
|
1566
include/nuttx/wireless/ieee802154/ieee802154_mac.h
Normal file
1566
include/nuttx/wireless/ieee802154/ieee802154_mac.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,9 @@
|
||||
* include/nuttx/wireless/ieee802154/ieee802154_radio.h
|
||||
*
|
||||
* Copyright (C) 2014-2016 Sebastien Lorquet. All rights reserved.
|
||||
* Copyright (C) 2017 Verge Inc. All rights reserved.
|
||||
* Author: Sebastien Lorquet <sebastien@lorquet.fr>
|
||||
* Author: Anthony Merlino <anthony@vergeaero.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -33,175 +35,64 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __INCLUDE_NUTTX_WIRELESS_IEEE802154_IEEE802154_H
|
||||
#define __INCLUDE_NUTTX_WIRELESS_IEEE802154_IEEE802154_H
|
||||
#ifndef __INCLUDE_NUTTX_WIRELESS_IEEE802154_IEEE802154_RADIO_H
|
||||
#define __INCLUDE_NUTTX_WIRELESS_IEEE802154_IEEE802154_RADIO_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <semaphore.h>
|
||||
|
||||
#include <nuttx/wireless/ieee802154/ieee802154_mac.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-Processor Definitions
|
||||
****************************************************************************/
|
||||
/* Configuration ************************************************************/
|
||||
/* None at the moment */
|
||||
|
||||
/* IEEE 802.15.4 MAC Interface **********************************************/
|
||||
|
||||
/* Frame control field masks, 2 bytes
|
||||
* Seee IEEE 802.15.4/2003 7.2.1.1 page 112
|
||||
*/
|
||||
|
||||
#define IEEE802154_FC1_FTYPE 0x03 /* Frame type, bits 0-2 */
|
||||
#define IEEE802154_FC1_SEC 0x08 /* Security Enabled, bit 3 */
|
||||
#define IEEE802154_FC1_PEND 0x10 /* Frame pending, bit 4 */
|
||||
#define IEEE802154_FC1_ACKREQ 0x20 /* Acknowledge request, bit 5 */
|
||||
#define IEEE802154_FC1_INTRA 0x40 /* Intra PAN, bit 6 */
|
||||
#define IEEE802154_FC2_DADDR 0x0C /* Dest addressing mode, bits 10-11 */
|
||||
#define IEEE802154_FC2_VERSION 0x30 /* Source addressing mode, bits 12-13 */
|
||||
#define IEEE802154_FC2_SADDR 0xC0 /* Source addressing mode, bits 14-15 */
|
||||
|
||||
/* Frame Type */
|
||||
|
||||
#define IEEE802154_FRAME_BEACON 0x00
|
||||
#define IEEE802154_FRAME_DATA 0x01
|
||||
#define IEEE802154_FRAME_ACK 0x02
|
||||
#define IEEE802154_FRAME_COMMAND 0x03
|
||||
|
||||
/* Security Enabled */
|
||||
|
||||
#define IEEE802154_SEC_OFF 0x00
|
||||
#define IEEE802154_SEC_ON 0x08
|
||||
|
||||
/* Flags */
|
||||
|
||||
#define IEEE802154_PEND 0x10
|
||||
#define IEEE802154_ACK_REQ 0x20
|
||||
#define IEEE802154_INTRA 0x40
|
||||
|
||||
/* Dest Addressing modes */
|
||||
|
||||
#define IEEE802154_DADDR_NONE 0x00
|
||||
#define IEEE802154_DADDR_SHORT 0x08
|
||||
#define IEEE802154_DADDR_EXT 0x0A
|
||||
|
||||
/* Src Addressing modes */
|
||||
|
||||
#define IEEE802154_SADDR_NONE 0x00
|
||||
#define IEEE802154_SADDR_SHORT 0x80
|
||||
#define IEEE802154_SADDR_EXT 0xA0
|
||||
|
||||
/* Some addresses */
|
||||
|
||||
#define IEEE802154_PAN_DEFAULT (uint16_t)0xFFFF
|
||||
#define IEEE802154_SADDR_UNSPEC (uint16_t)0xFFFF
|
||||
#define IEEE802154_SADDR_BCAST (uint16_t)0xFFFE
|
||||
#define IEEE802154_EADDR_UNSPEC (uint8_t*)"\xff\xff\xff\xff\xff\xff\xff\xff"
|
||||
|
||||
#define IEEE802154_CMD_ASSOC_REQ 0x01
|
||||
#define IEEE802154_CMD_ASSOC_RSP 0x02
|
||||
#define IEEE802154_CMD_DIS_NOT 0x03
|
||||
#define IEEE802154_CMD_DATA_REQ 0x04
|
||||
#define IEEE802154_CMD_PANID_CONF_NOT 0x05
|
||||
#define IEEE802154_CMD_ORPHAN_NOT 0x06
|
||||
#define IEEE802154_CMD_BEACON_REQ 0x07
|
||||
#define IEEE802154_CMD_COORD_REALIGN 0x08
|
||||
#define IEEE802154_CMD_GTS_REQ 0x09
|
||||
|
||||
/* Device modes */
|
||||
|
||||
#define IEEE802154_MODE_DEVICE 0x00
|
||||
#define IEEE802154_MODE_COORD 0x01 /* avail in mrf24j40, but why? */
|
||||
#define IEEE802154_MODE_PANCOORD 0x02
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
struct ieee802154_packet_s
|
||||
/* IEEE802.15.4 Radio Interface Operations **********************************/
|
||||
|
||||
struct ieee802154_radiocb_s
|
||||
{
|
||||
uint8_t len;
|
||||
uint8_t data[127];
|
||||
uint8_t lqi;
|
||||
uint8_t rssi;
|
||||
CODE int (*poll_csma) (FAR const struct ieee802154_radiocb_s *radiocb,
|
||||
FAR struct ieee802154_txdesc_s *tx_desc,
|
||||
FAR struct iob_s **frame);
|
||||
CODE int (*poll_gts) (FAR const struct ieee802154_radiocb_s *radiocb,
|
||||
FAR struct ieee802154_txdesc_s *tx_desc,
|
||||
FAR struct iob_s **frame);
|
||||
CODE void (*txdone) (FAR const struct ieee802154_radiocb_s *radiocb,
|
||||
FAR const struct ieee802154_txdesc_s *tx_desc);
|
||||
CODE void (*rxframe) (FAR const struct ieee802154_radiocb_s *radiocb,
|
||||
FAR struct ieee802154_data_ind_s *ind);
|
||||
};
|
||||
|
||||
struct ieee802154_cca_s
|
||||
struct ieee802154_radio_s; /* Forward reference */
|
||||
|
||||
struct ieee802154_radioops_s
|
||||
{
|
||||
uint8_t use_ed : 1; /* CCA using ED */
|
||||
uint8_t use_cs : 1; /* CCA using carrier sense */
|
||||
uint8_t edth; /* Energy detection threshold for CCA */
|
||||
uint8_t csth; /* Carrier sense threshold for CCA */
|
||||
CODE int (*bind) (FAR struct ieee802154_radio_s *radio,
|
||||
FAR struct ieee802154_radiocb_s *radiocb);
|
||||
CODE int (*txnotify_csma)(FAR struct ieee802154_radio_s *radio);
|
||||
CODE int (*txnotify_gts)(FAR struct ieee802154_radio_s *radio);
|
||||
CODE int (*get_attr) (FAR struct ieee802154_radio_s *radio,
|
||||
enum ieee802154_pib_attr_e pib_attr,
|
||||
FAR union ieee802154_attr_val_u *attr_value);
|
||||
CODE int (*set_attr) (FAR struct ieee802154_radio_s *radio,
|
||||
enum ieee802154_pib_attr_e pib_attr,
|
||||
FAR const union ieee802154_attr_val_u *attr_value);
|
||||
};
|
||||
|
||||
struct ieee802154_dev_s;
|
||||
|
||||
struct ieee802154_devops_s
|
||||
struct ieee802154_radio_s
|
||||
{
|
||||
CODE int (*setchannel)(FAR struct ieee802154_dev_s *dev, uint8_t channel);
|
||||
CODE int (*getchannel)(FAR struct ieee802154_dev_s *dev,
|
||||
FAR uint8_t *channel);
|
||||
|
||||
CODE int (*setpanid)(FAR struct ieee802154_dev_s *dev, uint16_t panid);
|
||||
CODE int (*getpanid)(FAR struct ieee802154_dev_s *dev,
|
||||
FAR uint16_t *panid);
|
||||
|
||||
CODE int (*setsaddr)(FAR struct ieee802154_dev_s *dev, uint16_t saddr);
|
||||
CODE int (*getsaddr)(FAR struct ieee802154_dev_s *dev,
|
||||
FAR uint16_t *saddr);
|
||||
|
||||
CODE int (*seteaddr)(FAR struct ieee802154_dev_s *dev,
|
||||
FAR uint8_t *laddr);
|
||||
CODE int (*geteaddr)(FAR struct ieee802154_dev_s *dev,
|
||||
FAR uint8_t *laddr);
|
||||
|
||||
CODE int (*setpromisc)(FAR struct ieee802154_dev_s *dev, bool promisc);
|
||||
CODE int (*getpromisc)(FAR struct ieee802154_dev_s *dev,
|
||||
FAR bool *promisc);
|
||||
|
||||
CODE int (*setdevmode)(FAR struct ieee802154_dev_s *dev, uint8_t devmode);
|
||||
CODE int (*getdevmode)(FAR struct ieee802154_dev_s *dev,
|
||||
FAR uint8_t *devmode);
|
||||
|
||||
CODE int (*settxpower)(FAR struct ieee802154_dev_s *dev,
|
||||
int32_t txpwr); /* unit = 1 mBm = 1/100 dBm */
|
||||
CODE int (*gettxpower)(FAR struct ieee802154_dev_s *dev,
|
||||
FAR int32_t *txpwr);
|
||||
|
||||
CODE int (*setcca)(FAR struct ieee802154_dev_s *dev,
|
||||
FAR struct ieee802154_cca_s *cca);
|
||||
CODE int (*getcca)(FAR struct ieee802154_dev_s *dev,
|
||||
FAR struct ieee802154_cca_s *cca);
|
||||
|
||||
CODE int (*ioctl)(FAR struct ieee802154_dev_s *ieee, int cmd,
|
||||
unsigned long arg);
|
||||
CODE int (*energydetect)(FAR struct ieee802154_dev_s *dev,
|
||||
FAR uint8_t *energy);
|
||||
CODE int (*rxenable)(FAR struct ieee802154_dev_s *dev, bool state,
|
||||
FAR struct ieee802154_packet_s *packet);
|
||||
CODE int (*transmit)(FAR struct ieee802154_dev_s *dev,
|
||||
FAR struct ieee802154_packet_s *packet);
|
||||
|
||||
/*TODO beacon/sf order*/
|
||||
};
|
||||
|
||||
struct ieee802154_dev_s
|
||||
{
|
||||
FAR const struct ieee802154_devops_s *ops;
|
||||
|
||||
/* Packet reception management */
|
||||
|
||||
struct ieee802154_packet_s *rxbuf;
|
||||
sem_t rxsem;
|
||||
|
||||
/* Packet transmission management */
|
||||
|
||||
sem_t txsem;
|
||||
FAR const struct ieee802154_radioops_s *ops;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -221,4 +112,4 @@ extern "C"
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __INCLUDE_NUTTX_WIRELESS_IEEE802154_MRF24J40_H */
|
||||
#endif /* __INCLUDE_NUTTX_WIRELESS_IEEE802154_IEEE802154_RADIO_H */
|
||||
|
@ -40,6 +40,8 @@
|
||||
* Included files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <stdbool.h>
|
||||
#include <nuttx/arch.h>
|
||||
|
||||
/****************************************************************************
|
||||
@ -52,18 +54,19 @@
|
||||
*
|
||||
* The MRF24J40 interrupt is an active low, *level* interrupt. From Datasheet:
|
||||
* "Note 1: The INTEDGE polarity defaults to:
|
||||
* 0 = Falling Edge. Ensure that the inter-
|
||||
* rupt polarity matches the interrupt pin
|
||||
* polarity of the host microcontroller.
|
||||
* Note 2: The INT pin will remain high or low,
|
||||
* depending on INTEDGE polarity setting,
|
||||
* until INTSTAT register is read."
|
||||
*
|
||||
* 0 = Falling Edge. Ensure that the interrupt polarity matches the
|
||||
* interrupt pin polarity of the host microcontroller.
|
||||
*
|
||||
* Note 2: The INT pin will remain high or low, depending on INTEDGE
|
||||
* polarity setting, until INTSTAT register is read."
|
||||
*/
|
||||
|
||||
struct mrf24j40_lower_s
|
||||
{
|
||||
int (*attach)(FAR const struct mrf24j40_lower_s *lower, xcpt_t handler);
|
||||
void (*enable)(FAR const struct mrf24j40_lower_s *lower, int state);
|
||||
int (*attach)(FAR const struct mrf24j40_lower_s *lower, xcpt_t handler,
|
||||
FAR void *arg);
|
||||
void (*enable)(FAR const struct mrf24j40_lower_s *lower, bool state);
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -100,8 +103,9 @@ extern "C"
|
||||
****************************************************************************/
|
||||
|
||||
struct spi_dev_s; /* Forward reference */
|
||||
FAR struct ieee802154_dev_s *mrf24j40_init(FAR struct spi_dev_s *spi,
|
||||
FAR const struct mrf24j40_lower_s *lower);
|
||||
FAR struct ieee802154_radio_s *
|
||||
mrf24j40_init(FAR struct spi_dev_s *spi,
|
||||
FAR const struct mrf24j40_lower_s *lower);
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
|
@ -63,6 +63,22 @@
|
||||
|
||||
# include <nuttx/wireless/ioctl.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_WIRELESS_IEEE802154
|
||||
|
||||
#ifdef CONFIG_IEEE802154_MAC
|
||||
/* Include ieee802.15.4 MAC IOCTL definitions */
|
||||
|
||||
# include <nuttx/wireless/ieee802154/ieee802154_mac.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IEEE802154_MAC_DEV
|
||||
/* Include ieee802.15.4 character driver IOCTL definitions */
|
||||
|
||||
# include <nuttx/wireless/ieee802154/ieee802154_ioctl.h>
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_WIRELESS_IEEE802154 */
|
||||
#endif /* CONFIG_NSOCKET_DESCRIPTORS > 0 */
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -136,6 +136,7 @@ config NET_6LOWPAN
|
||||
default n
|
||||
select NETDEV_MULTINIC if NET_ETHERNET || NET_LOOPBACK || NET_SLIP || NET_TUN
|
||||
select NET_MULTILINK if NET_ETHERNET || NET_LOOPBACK || NET_SLIP || NET_TUN
|
||||
select NETDEV_IOCTL
|
||||
depends on EXPERIMENTAL && NET_IPv6
|
||||
---help---
|
||||
Enable support for IEEE 802.15.4 Low power Wireless Personal Area
|
||||
|
@ -72,6 +72,10 @@
|
||||
# include <nuttx/wireless/wireless.h>
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_NETDEV_IOCTL) && defined(CONFIG_NET_6LOWPAN)
|
||||
# include <nuttx/wireless/ieee802154/ieee802154_mac.h>
|
||||
#endif
|
||||
|
||||
#include "arp/arp.h"
|
||||
#include "socket/socket.h"
|
||||
#include "netdev/netdev.h"
|
||||
@ -320,6 +324,67 @@ static void ioctl_set_ipv6addr(FAR net_ipv6addr_t outaddr,
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netdev_iee802154_ioctl
|
||||
*
|
||||
* Description:
|
||||
* Perform IEEE802.15.4 network device specific operations.
|
||||
*
|
||||
* Parameters:
|
||||
* psock Socket structure
|
||||
* dev Ethernet driver device structure
|
||||
* cmd The ioctl command
|
||||
* req The argument of the ioctl cmd
|
||||
*
|
||||
* Return:
|
||||
* >=0 on success (positive non-zero values are cmd-specific)
|
||||
* Negated errno returned on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_NETDEV_IOCTL) && defined(CONFIG_NET_6LOWPAN)
|
||||
static int netdev_iee802154_ioctl(FAR struct socket *psock, int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
FAR struct net_driver_s *dev;
|
||||
FAR char *ifname;
|
||||
int ret = -ENOTTY;
|
||||
|
||||
if (arg != 0ul)
|
||||
{
|
||||
if (_MAC802154IOCVALID(cmd))
|
||||
{
|
||||
/* Get the IEEE802.15.4 MAC device to receive the radio IOCTL
|
||||
* commdand
|
||||
*/
|
||||
|
||||
FAR struct ieee802154_netmac_s *netmac =
|
||||
(FAR struct ieee802154_netmac_s *)((uintptr_t)arg);
|
||||
|
||||
ifname = netmac->ifr_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The IOCTL command is neither */
|
||||
|
||||
return -ENOTTY;
|
||||
}
|
||||
|
||||
/* Find the device with this name */
|
||||
|
||||
dev = netdev_findbyname(ifname);
|
||||
if (dev != NULL)
|
||||
{
|
||||
/* Perform the device IOCTL */
|
||||
|
||||
ret = dev->d_ioctl(dev, cmd, arg);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netdev_wifr_ioctl
|
||||
*
|
||||
@ -709,7 +774,7 @@ static int netdev_ifr_ioctl(FAR struct socket *psock, int cmd,
|
||||
{
|
||||
req->ifr_hwaddr.sa_family = AF_INETX;
|
||||
memcpy(req->ifr_hwaddr.sa_data,
|
||||
dev->d_mac.ieee802154.u8, NET_6LOWPAN_RIMEADDR_SIZE);
|
||||
dev->d_mac.ieee802154.u8, NET_6LOWPAN_ADDRSIZE);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@ -747,7 +812,7 @@ static int netdev_ifr_ioctl(FAR struct socket *psock, int cmd,
|
||||
#endif
|
||||
{
|
||||
memcpy(dev->d_mac.ieee802154.u8,
|
||||
req->ifr_hwaddr.sa_data, NET_6LOWPAN_RIMEADDR_SIZE);
|
||||
req->ifr_hwaddr.sa_data, NET_6LOWPAN_ADDRSIZE);
|
||||
ret = OK;
|
||||
}
|
||||
else
|
||||
@ -1192,6 +1257,15 @@ int psock_ioctl(FAR struct socket *psock, int cmd, unsigned long arg)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_NETDEV_IOCTL) && defined(CONFIG_NET_6LOWPAN)
|
||||
/* Check for a IEEE802.15.4 network device command */
|
||||
|
||||
if (ret == -ENOTTY)
|
||||
{
|
||||
ret = netdev_iee802154_ioctl(psock, cmd, arg);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_IGMP
|
||||
/* Check for address filtering commands */
|
||||
|
||||
|
@ -151,7 +151,7 @@ static int netprocfs_linklayer(FAR struct netprocfs_file_s *netfile)
|
||||
#ifdef CONFIG_NET_6LOWPAN
|
||||
case NET_LL_IEEE802154:
|
||||
{
|
||||
#ifdef CONFIG_NET_6LOWPAN_RIMEADDR_EXTENDED
|
||||
#ifdef CONFIG_NET_6LOWPAN_EXTENDEDADDR
|
||||
len += snprintf(&netfile->line[len], NET_LINELEN - len,
|
||||
"%s\tLink encap:6loWPAN HWaddr "
|
||||
"%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
@ -213,7 +213,7 @@ static int netprocfs_linklayer(FAR struct netprocfs_file_s *netfile)
|
||||
dev->d_ifname, ether_ntoa(&dev->d_mac.ether), status);
|
||||
|
||||
#elif defined(CONFIG_NET_6LOWPAN)
|
||||
#ifdef CONFIG_NET_6LOWPAN_RIMEADDR_EXTENDED
|
||||
#ifdef CONFIG_NET_6LOWPAN_EXTENDEDADDR
|
||||
len += snprintf(&netfile->line[len], NET_LINELEN - len,
|
||||
"%s\tLink encap:6loWPAN HWaddr "
|
||||
"%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x at %s\n",
|
||||
|
@ -133,13 +133,13 @@ config NET_6LOWPAN_MAXADDRCONTEXT_PREFIX_2_1
|
||||
endif # NET_6LOWPAN_MAXADDRCONTEXT_PREINIT_0
|
||||
endif # NET_6LOWPAN_COMPRESSION_HC06
|
||||
|
||||
config NET_6LOWPAN_RIMEADDR_EXTENDED
|
||||
bool "Extended Rime address"
|
||||
config NET_6LOWPAN_EXTENDEDADDR
|
||||
bool "Extended IEEE 802.15.4 address"
|
||||
default n
|
||||
---help---
|
||||
By default, a 2-byte Rime address is used for the IEEE802.15.4 MAC
|
||||
By default, a 2-byte short address is used for the IEEE802.15.4 MAC
|
||||
device's link layer address. If this option is selected, then an
|
||||
8-byte Rime address will be used.
|
||||
8-byte extended address will be used.
|
||||
|
||||
config NET_6LOWPAN_MAXAGE
|
||||
int "Packet reassembly timeout"
|
||||
@ -151,6 +151,7 @@ config NET_6LOWPAN_MAXAGE
|
||||
config NET_6LOWPAN_MAX_MACTRANSMITS
|
||||
int "Max MAC transmissions"
|
||||
default 4
|
||||
range 1 255
|
||||
---help---
|
||||
CONFIG_NET_6LOWPAN_MAX_MACTRANSMITS specifies how many times the MAC
|
||||
layer should resend packets if no link-layer ACK wasreceived. This
|
||||
|
@ -10,12 +10,12 @@ Optimal 6loWPAN Configuration
|
||||
|
||||
128 112 96 80 64 48 32 16
|
||||
---- ---- ---- ---- ---- ---- ---- ----
|
||||
AAAA xxxx xxxx xxxx xxxx 00ff fe00 MMMM 2-byte Rime address IEEE 48-bit MAC
|
||||
AAAA 0000 0000 0000 NNNN NNNN NNNN NNNN 8-byte Rime address IEEE EUI-64
|
||||
AAAA xxxx xxxx xxxx xxxx 00ff fe00 MMMM 2-byte short address IEEE 48-bit MAC
|
||||
AAAA 0000 0000 0000 NNNN NNNN NNNN NNNN 8-byte extended address IEEE EUI-64
|
||||
|
||||
Where MMM is the 2-byte rime address XORed 0x0200. For example, the MAC
|
||||
Where MMM is the 2-byte short address XORed 0x0200. For example, the MAC
|
||||
address of 0xabcd would be 0xa9cd. And NNNN NNNN NNNN NNNN is the 8-byte
|
||||
rime address address XOR 02000 0000 0000 0000.
|
||||
extended address address XOR 02000 0000 0000 0000.
|
||||
|
||||
For link-local address, AAAA is 0xfe80
|
||||
|
||||
@ -23,8 +23,8 @@ Optimal 6loWPAN Configuration
|
||||
|
||||
128 112 96 80 64 48 32 16
|
||||
---- ---- ---- ---- ---- ---- ---- ----
|
||||
fe80 0000 0000 0000 0000 00ff fe00 MMMM 2-byte Rime address IEEE 48-bit MAC
|
||||
fe80 0000 0000 0000 NNNN NNNN NNNN NNNN 8-byte Rime address IEEE EUI-64
|
||||
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
|
||||
|
||||
@ -52,11 +52,11 @@ this is a HC1 compressed first frame of a packet
|
||||
41 88 2a cefa 3412 cdab ### 9-byte MAC header
|
||||
c50e 000b ### 4-byte FRAG1 header
|
||||
42 ### SIXLOWPAN_DISPATCH_HC1
|
||||
fb ### RIME_HC1_HC_UDP_HC1_ENCODING
|
||||
e0 ### RIME_HC1_HC_UDP_UDP_ENCODING
|
||||
00 ### RIME_HC1_HC_UDP_TTL
|
||||
10 ### RIME_HC1_HC_UDP_PORTS
|
||||
0000 ### RIME_HC1_HC_UDP_CHKSUM
|
||||
fb ### SIXLOWPAN_HC1_HC_UDP_HC1_ENCODING
|
||||
e0 ### SIXLOWPAN_HC1_HC_UDP_UDP_ENCODING
|
||||
00 ### SIXLOWPAN_HC1_HC_UDP_TTL
|
||||
10 ### SIXLOWPAN_HC1_HC_UDP_PORTS
|
||||
0000 ### SIXLOWPAN_HC1_HC_UDP_CHKSUM
|
||||
|
||||
104 byte Payload follows:
|
||||
4f4e452064617920 48656e6e792d7065 6e6e792077617320 7069636b696e6720
|
||||
@ -69,11 +69,11 @@ This is the second frame of the same transfer:
|
||||
41 88 2b cefa 3412 cdab ### 9-byte MAC header
|
||||
e50e 000b 0d ### 5 byte FRAGN header
|
||||
42 ### SIXLOWPAN_DISPATCH_HC1
|
||||
fb ### RIME_HC1_HC_UDP_HC1_ENCODING
|
||||
e0 ### RIME_HC1_HC_UDP_UDP_ENCODING
|
||||
00 ### RIME_HC1_HC_UDP_TTL
|
||||
10 ### RIME_HC1_HC_UDP_PORTS
|
||||
0000 ### RIME_HC1_HC_UDP_CHKSUM
|
||||
fb ### SIXLOWPAN_HC1_HC_UDP_HC1_ENCODING
|
||||
e0 ### SIXLOWPAN_HC1_HC_UDP_UDP_ENCODING
|
||||
00 ### SIXLOWPAN_HC1_HC_UDP_TTL
|
||||
10 ### SIXLOWPAN_HC1_HC_UDP_PORTS
|
||||
0000 ### SIXLOWPAN_HC1_HC_UDP_CHKSUM
|
||||
|
||||
104 byte Payload follows:
|
||||
476f6f646e657373 2067726163696f75 73206d6521272073 6169642048656e6e
|
||||
|
@ -55,6 +55,7 @@
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/net/netdev.h>
|
||||
#include <nuttx/wireless/ieee802154/ieee802154_mac.h>
|
||||
|
||||
#include "sixlowpan/sixlowpan_internal.h"
|
||||
|
||||
@ -77,7 +78,7 @@
|
||||
*/
|
||||
|
||||
#if CONFIG_NET_6LOWPAN_MTU > (CONFIG_IOB_BUFSIZE * CONFIG_IOB_NBUFFERS)
|
||||
# error Not enough IOBs to hold one full IEEE802.14.5 packet
|
||||
# error Not enough IOBs to hold one full 6LoWPAN packet
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
@ -183,9 +184,8 @@ static void sixlowpan_compress_ipv6hdr(FAR const struct ipv6_hdr_s *ipv6hdr,
|
||||
*
|
||||
* 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 put in ieee->i_framelist
|
||||
* and the entire list of frames will be delivered to the 802.15.4 MAC via
|
||||
* ieee->i_framelist.
|
||||
* fragmented. The resulting packet/fragments are submitted to the MAC
|
||||
* where they are queue for transfer.
|
||||
*
|
||||
* Input Parameters:
|
||||
* ieee - The IEEE802.15.4 MAC driver instance
|
||||
@ -209,17 +209,20 @@ static void sixlowpan_compress_ipv6hdr(FAR const struct ipv6_hdr_s *ipv6hdr,
|
||||
int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
|
||||
FAR const struct ipv6_hdr_s *destip,
|
||||
FAR const void *buf, size_t buflen,
|
||||
FAR const struct rimeaddr_s *destmac)
|
||||
FAR const struct sixlowpan_tagaddr_s *destmac)
|
||||
{
|
||||
struct packet_metadata_s pktmeta;
|
||||
struct ieee802154_frame_meta_s meta;
|
||||
FAR struct iob_s *iob;
|
||||
FAR uint8_t *fptr;
|
||||
int framer_hdrlen;
|
||||
struct rimeaddr_s bcastmac;
|
||||
struct sixlowpan_tagaddr_s bcastmac;
|
||||
uint16_t pktlen;
|
||||
uint16_t paysize;
|
||||
#ifdef CONFIG_NET_6LOWPAN_FRAG
|
||||
uint16_t outlen = 0;
|
||||
#endif
|
||||
int ret;
|
||||
|
||||
/* Initialize global data. Locking the network guarantees that we have
|
||||
* exclusive use of the global values for intermediate calculations.
|
||||
@ -228,16 +231,14 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
|
||||
g_uncomp_hdrlen = 0;
|
||||
g_frame_hdrlen = 0;
|
||||
|
||||
/* Reset rime buffer, packet buffer metatadata */
|
||||
/* Reset frame meta data */
|
||||
|
||||
memset(g_pktattrs, 0, PACKETBUF_NUM_ATTRS * sizeof(uint16_t));
|
||||
memset(g_pktaddrs, 0, PACKETBUF_NUM_ADDRS * sizeof(struct rimeaddr_s));
|
||||
|
||||
g_pktattrs[PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS] =
|
||||
CONFIG_NET_6LOWPAN_MAX_MACTRANSMITS;
|
||||
memset(&pktmeta, 0, sizeof(struct packet_metadata_s));
|
||||
pktmeta.xmits = CONFIG_NET_6LOWPAN_MAX_MACTRANSMITS;
|
||||
|
||||
/* Set stream mode for all TCP packets, except FIN packets. */
|
||||
|
||||
#if 0 /* Currently the frame type is always data */
|
||||
if (destip->proto == IP_PROTO_TCP)
|
||||
{
|
||||
FAR const struct tcp_hdr_s *tcp =
|
||||
@ -246,13 +247,14 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
|
||||
if ((tcp->flags & TCP_FIN) == 0 &&
|
||||
(tcp->flags & TCP_CTL) != TCP_ACK)
|
||||
{
|
||||
g_pktattrs[PACKETBUF_ATTR_PACKET_TYPE] = PACKETBUF_ATTR_PACKET_TYPE_STREAM;
|
||||
pktmeta.type = FRAME_ATTR_TYPE_STREAM;
|
||||
}
|
||||
else if ((tcp->flags & TCP_FIN) == TCP_FIN)
|
||||
{
|
||||
g_pktattrs[PACKETBUF_ATTR_PACKET_TYPE] = PACKETBUF_ATTR_PACKET_TYPE_STREAM_END;
|
||||
pktmeta.type = FRAME_ATTR_TYPE_STREAM_END;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* The destination address will be tagged to each outbound packet. If the
|
||||
* argument destmac is NULL, we are sending a broadcast packet.
|
||||
@ -260,7 +262,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
|
||||
|
||||
if (destmac == NULL)
|
||||
{
|
||||
memset(&bcastmac, 0, sizeof(struct rimeaddr_s));
|
||||
memset(&bcastmac, 0, sizeof(struct sixlowpan_tagaddr_s));
|
||||
destmac = &bcastmac;
|
||||
}
|
||||
|
||||
@ -281,24 +283,67 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
|
||||
|
||||
ninfo("Sending packet length %d\n", buflen);
|
||||
|
||||
/* Set the source and destination address */
|
||||
/* Set the source and destination address. The source MAC address
|
||||
* is a fixed size, determined by a configuration setting. The
|
||||
* destination MAC address many be either short or extended.
|
||||
*/
|
||||
|
||||
rimeaddr_copy(&g_pktaddrs[PACKETBUF_ADDR_SENDER],
|
||||
&ieee->i_dev.d_mac.ieee802154);
|
||||
rimeaddr_copy(&g_pktaddrs[PACKETBUF_ADDR_RECEIVER], destmac);
|
||||
#ifdef CONFIG_NET_6LOWPAN_EXTENDEDADDR
|
||||
pktmeta.sextended = TRUE;
|
||||
sixlowpan_eaddrcopy(pktmeta.source.eaddr.u8,
|
||||
&ieee->i_dev.d_mac.ieee802154);
|
||||
#else
|
||||
sixlowpan_saddrcopy(pktmeta.source.saddr.u8,
|
||||
&ieee->i_dev.d_mac.ieee802154);
|
||||
#endif
|
||||
|
||||
if (destmac->extended)
|
||||
{
|
||||
pktmeta.dextended = TRUE;
|
||||
sixlowpan_eaddrcopy(pktmeta.dest.eaddr.u8, destmac->u.eaddr.u8);
|
||||
}
|
||||
else
|
||||
{
|
||||
sixlowpan_saddrcopy(pktmeta.dest.saddr.u8, destmac->u.saddr.u8);
|
||||
}
|
||||
|
||||
/* Get the destination PAN ID.
|
||||
*
|
||||
* REVISIT: For now I am assuming that the source and destination
|
||||
* PAN IDs are the same.
|
||||
*/
|
||||
|
||||
pktmeta.dpanid = 0xffff;
|
||||
(void)sixlowpan_src_panid(ieee, &pktmeta.dpanid);
|
||||
|
||||
/* Based on the collected attributes and addresses, construct the MAC meta
|
||||
* data structure that we need to interface with the IEEE802.15.4 MAC (we
|
||||
* will update the MSDU payload size when the IOB has been setup).
|
||||
*/
|
||||
|
||||
ret = sixlowpan_meta_data(ieee, &pktmeta, &meta, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
nerr("ERROR: sixlowpan_meta_data() failed: %d\n", ret);
|
||||
}
|
||||
|
||||
/* Pre-calculate frame header length. */
|
||||
|
||||
framer_hdrlen = sixlowpan_send_hdrlen(ieee, ieee->i_panid);
|
||||
framer_hdrlen = sixlowpan_frame_hdrlen(ieee, &meta);
|
||||
if (framer_hdrlen < 0)
|
||||
{
|
||||
/* Failed to determine the size of the header failed. */
|
||||
|
||||
nerr("ERROR: sixlowpan_send_hdrlen() failed: %d\n", framer_hdrlen);
|
||||
nerr("ERROR: sixlowpan_frame_hdrlen() failed: %d\n", framer_hdrlen);
|
||||
return framer_hdrlen;
|
||||
}
|
||||
|
||||
g_frame_hdrlen = framer_hdrlen;
|
||||
/* This sill be the initial offset into io_data. Valid data begins at
|
||||
* this offset and must be reflected in io_offset.
|
||||
*/
|
||||
|
||||
g_frame_hdrlen = framer_hdrlen;
|
||||
iob->io_offset = framer_hdrlen;
|
||||
|
||||
#ifndef CONFIG_NET_6LOWPAN_COMPRESSION_IPv6
|
||||
if (buflen >= CONFIG_NET_6LOWPAN_COMPRESSION_THRESHOLD)
|
||||
@ -328,15 +373,15 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
|
||||
if (buflen > (CONFIG_NET_6LOWPAN_FRAMELEN - g_frame_hdrlen))
|
||||
{
|
||||
#ifdef CONFIG_NET_6LOWPAN_FRAG
|
||||
/* ieee->i_framelist will hold the generated frames; frames will be
|
||||
/* qhead will hold the generated frame list; frames will be
|
||||
* added at qtail.
|
||||
*/
|
||||
|
||||
FAR struct iob_s *qhead;
|
||||
FAR struct iob_s *qtail;
|
||||
FAR uint8_t *frame1;
|
||||
FAR uint8_t *fragptr;
|
||||
uint16_t frag1_hdrlen;
|
||||
int verify;
|
||||
|
||||
/* The outbound IPv6 packet is too large to fit into a single 15.4
|
||||
* packet, so we fragment it into multiple packets and send them.
|
||||
@ -348,13 +393,6 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
|
||||
ninfo("Sending fragmented packet length %d\n", buflen);
|
||||
|
||||
/* Create 1st Fragment */
|
||||
/* Add the frame header using the pre-allocated IOB using the DSN
|
||||
* selected by sixlowpan_send_hdrlen().
|
||||
*/
|
||||
|
||||
verify = sixlowpan_framecreate(ieee, iob, ieee->i_panid);
|
||||
DEBUGASSERT(verify == framer_hdrlen);
|
||||
UNUSED(verify);
|
||||
|
||||
/* Move HC1/HC06/IPv6 header to make space for the FRAG1 header at the
|
||||
* beginning of the frame.
|
||||
@ -380,9 +418,9 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
|
||||
*/
|
||||
|
||||
pktlen = buflen + g_uncomp_hdrlen;
|
||||
PUTINT16(fragptr, RIME_FRAG_DISPATCH_SIZE,
|
||||
((SIXLOWPAN_DISPATCH_FRAG1 << 8) | pktlen));
|
||||
PUTINT16(fragptr, RIME_FRAG_TAG, ieee->i_dgramtag);
|
||||
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;
|
||||
|
||||
@ -395,8 +433,8 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
|
||||
|
||||
/* Set outlen to what we already sent from the IP payload */
|
||||
|
||||
iob->io_len = paysize + g_frame_hdrlen;
|
||||
outlen = paysize;
|
||||
iob->io_len = paysize + g_frame_hdrlen;
|
||||
outlen = paysize;
|
||||
|
||||
ninfo("First fragment: length %d, tag %d\n",
|
||||
paysize, ieee->i_dgramtag);
|
||||
@ -405,17 +443,17 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
|
||||
|
||||
/* Add the first frame to the IOB queue */
|
||||
|
||||
ieee->i_framelist = iob;
|
||||
qtail = iob;
|
||||
qhead = iob;
|
||||
qtail = iob;
|
||||
|
||||
/* Keep track of the total amount of data queue */
|
||||
|
||||
iob->io_pktlen = iob->io_len;
|
||||
iob->io_pktlen = iob->io_len;
|
||||
|
||||
/* Create following fragments */
|
||||
|
||||
frame1 = iob->io_data;
|
||||
frag1_hdrlen = g_frame_hdrlen;
|
||||
frame1 = iob->io_data;
|
||||
frag1_hdrlen = g_frame_hdrlen;
|
||||
|
||||
while (outlen < buflen)
|
||||
{
|
||||
@ -432,20 +470,10 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
|
||||
|
||||
iob->io_flink = NULL;
|
||||
iob->io_len = 0;
|
||||
iob->io_offset = 0;
|
||||
iob->io_offset = framer_hdrlen;
|
||||
iob->io_pktlen = 0;
|
||||
fptr = iob->io_data;
|
||||
|
||||
/* Add a new frame header to the IOB (same as the first but with a
|
||||
* different DSN).
|
||||
*/
|
||||
|
||||
g_pktattrs[PACKETBUF_ATTR_MAC_SEQNO] = 0;
|
||||
|
||||
verify = sixlowpan_framecreate(ieee, iob, ieee->i_panid);
|
||||
DEBUGASSERT(verify == framer_hdrlen);
|
||||
UNUSED(verify);
|
||||
|
||||
/* Copy the HC1/HC06/IPv6 header the frame header from first
|
||||
* frame, into the correct location after the FRAGN header
|
||||
* of subsequent frames.
|
||||
@ -459,10 +487,10 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
|
||||
|
||||
/* Setup up the FRAGN header after the frame header. */
|
||||
|
||||
PUTINT16(fragptr, RIME_FRAG_DISPATCH_SIZE,
|
||||
((SIXLOWPAN_DISPATCH_FRAGN << 8) | pktlen));
|
||||
PUTINT16(fragptr, RIME_FRAG_TAG, ieee->i_dgramtag);
|
||||
fragptr[RIME_FRAG_OFFSET] = outlen >> 3;
|
||||
PUTHOST16(fragptr, SIXLOWPAN_FRAG_DISPATCH_SIZE,
|
||||
((SIXLOWPAN_DISPATCH_FRAGN << 8) | pktlen));
|
||||
PUTHOST16(fragptr, SIXLOWPAN_FRAG_TAG, ieee->i_dgramtag);
|
||||
fragptr[SIXLOWPAN_FRAG_OFFSET] = outlen >> 3;
|
||||
|
||||
fragn_hdrlen += SIXLOWPAN_FRAGN_HDR_LEN;
|
||||
|
||||
@ -498,7 +526,28 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
|
||||
|
||||
/* Keep track of the total amount of data queue */
|
||||
|
||||
ieee->i_framelist->io_pktlen += iob->io_len;
|
||||
qhead->io_pktlen += iob->io_len;
|
||||
}
|
||||
|
||||
/* Submit all of the fragments to the MAC. We send all frames back-
|
||||
* to-back like this to minimize any possible condition where some
|
||||
* frame which is not a fragment from this sequence from intervening.
|
||||
*/
|
||||
|
||||
for (iob = qhead; iob != NULL; iob = qhead)
|
||||
{
|
||||
/* Remove the IOB containing the frame from the list */
|
||||
|
||||
qhead = iob->io_flink;
|
||||
iob->io_flink = NULL;
|
||||
|
||||
/* And submit the frame to the MAC */
|
||||
|
||||
ret = sixlowpan_frame_submit(ieee, &meta, iob);
|
||||
if (ret < 0)
|
||||
{
|
||||
nerr("ERROR: sixlowpan_frame_submit() failed: %d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
/* Update the datagram TAG value */
|
||||
@ -514,34 +563,27 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
|
||||
}
|
||||
else
|
||||
{
|
||||
int verify;
|
||||
|
||||
/* The packet does not need to be fragmented just copy the "payload"
|
||||
* and send in one frame.
|
||||
*/
|
||||
|
||||
/* Add the frame header to the preallocated IOB. */
|
||||
|
||||
verify = sixlowpan_framecreate(ieee, iob, ieee->i_panid);
|
||||
DEBUGASSERT(verify == framer_hdrlen);
|
||||
UNUSED(verify);
|
||||
|
||||
/* Copy the payload and queue */
|
||||
/* Copy the payload into the frame. */
|
||||
|
||||
memcpy(fptr + g_frame_hdrlen, buf, buflen);
|
||||
iob->io_len = buflen + g_frame_hdrlen;
|
||||
iob->io_len = buflen + g_frame_hdrlen;
|
||||
iob->io_pktlen = iob->io_len;
|
||||
|
||||
ninfo("Non-fragmented: length %d\n", iob->io_len);
|
||||
sixlowpan_dumpbuffer("Outgoing frame",
|
||||
(FAR const uint8_t *)iob->io_data, iob->io_len);
|
||||
|
||||
/* Add the first frame to the IOB queue */
|
||||
/* And submit the frame to the MAC */
|
||||
|
||||
ieee->i_framelist = iob;
|
||||
|
||||
/* Keep track of the total amount of data queue */
|
||||
|
||||
iob->io_pktlen = iob->io_len;
|
||||
ret = sixlowpan_frame_submit(ieee, &meta, iob);
|
||||
if (ret < 0)
|
||||
{
|
||||
nerr("ERROR: sixlowpan_frame_submit() failed: %d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
@ -4,18 +4,6 @@
|
||||
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Derives from Contiki:
|
||||
*
|
||||
* Copyright (c) 2008, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
* Authors: Adam Dunkels <adam@sics.se>
|
||||
* Nicolas Tsiftes <nvt@sics.se>
|
||||
* Niclas Finne <nfi@sics.se>
|
||||
* Mathilde Durvy <mdurvy@cisco.com>
|
||||
* Julien Abeille <jabeille@cisco.com>
|
||||
* Joakim Eriksson <joakime@sics.se>
|
||||
* Joel Hoglund <joel@sics.se>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -23,23 +11,25 @@
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* 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 INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
@ -52,84 +42,41 @@
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include "nuttx/net/net.h"
|
||||
#include "nuttx/wireless/ieee802154/ieee802154_mac.h"
|
||||
|
||||
#include "sixlowpan/sixlowpan_internal.h"
|
||||
|
||||
#ifdef CONFIG_NET_6LOWPAN
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/* Structure that contains the lengths of the various addressing and
|
||||
* security fields in the 802.15.4 header.
|
||||
*/
|
||||
|
||||
struct field_length_s
|
||||
{
|
||||
uint8_t dest_pid_len; /* Length (in bytes) of destination PAN ID field */
|
||||
uint8_t dest_addr_len; /* Length (in bytes) of destination address field */
|
||||
uint8_t src_pid_len; /* Length (in bytes) of source PAN ID field */
|
||||
uint8_t src_addr_len; /* Length (in bytes) of source address field */
|
||||
uint8_t aux_sec_len; /* Length (in bytes) of aux security header field */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sixlowpan_addrlen
|
||||
* Name: sixlowpan_anyaddrnull
|
||||
*
|
||||
* Description:
|
||||
* Return the address length associated with a 2-bit address mode
|
||||
* If the destination address is all zero in the MAC header buf, then it is
|
||||
* broadcast on the 802.15.4 network.
|
||||
*
|
||||
* Input parameters:
|
||||
* addrmode - The address mode
|
||||
* addr - The address to check
|
||||
* addrlen - The length of the address in bytes
|
||||
*
|
||||
* Returned Value:
|
||||
* The address length associated with the address mode.
|
||||
* True if the address is all zero.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint8_t sixlowpan_addrlen(uint8_t addrmode)
|
||||
static bool sixlowpan_anyaddrnull(FAR uint8_t *addr, uint8_t addrlen)
|
||||
{
|
||||
switch (addrmode)
|
||||
while (addrlen-- > 0)
|
||||
{
|
||||
case FRAME802154_SHORTADDRMODE: /* 16-bit address */
|
||||
return 2;
|
||||
case FRAME802154_LONGADDRMODE: /* 64-bit address */
|
||||
return 8;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sixlowpan_addrnull
|
||||
*
|
||||
* Description:
|
||||
* If the output address is NULL in the Rime buf, then it is broadcast
|
||||
* on the 802.15.4 network.
|
||||
*
|
||||
* Input parameters:
|
||||
* addrmode - The address mode
|
||||
*
|
||||
* Returned Value:
|
||||
* The address length associated with the address mode.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static bool sixlowpan_addrnull(FAR uint8_t *addr)
|
||||
{
|
||||
int i = NET_6LOWPAN_RIMEADDR_SIZE;
|
||||
|
||||
while (i-- > 0)
|
||||
{
|
||||
if (addr[i] != 0x00)
|
||||
if (addr[addrlen] != 0x00)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -138,244 +85,44 @@ static bool sixlowpan_addrnull(FAR uint8_t *addr)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sixlowpan_fieldlengths
|
||||
* Name: sixlowpan_saddrnull
|
||||
*
|
||||
* Description:
|
||||
* Return the lengths associated fields of the IEEE802.15.4 header.
|
||||
* If the destination address is all zero in the MAC header buf, then it is
|
||||
* broadcast on the 802.15.4 network.
|
||||
*
|
||||
* Input parameters:
|
||||
* finfo - IEEE802.15.4 header info (input)
|
||||
* flen - Field length info (output)
|
||||
* eaddr - The short address to check
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
* The address length associated with the address mode.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void sixlowpan_fieldlengths(FAR struct frame802154_s *finfo,
|
||||
FAR struct field_length_s *flen)
|
||||
static inline bool sixlowpan_saddrnull(FAR const uint8_t *saddr)
|
||||
{
|
||||
/* Initialize to all zero */
|
||||
|
||||
memset(flen, 0, sizeof(struct field_length_s));
|
||||
|
||||
/* Determine lengths of each field based on fcf and other args */
|
||||
|
||||
if ((finfo->fcf.dest_addr_mode & 3) != 0)
|
||||
{
|
||||
flen->dest_pid_len = 2;
|
||||
}
|
||||
|
||||
if ((finfo->fcf.src_addr_mode & 3) != 0)
|
||||
{
|
||||
flen->src_pid_len = 2;
|
||||
}
|
||||
|
||||
/* Set PAN ID compression bit if src pan id matches dest pan id. */
|
||||
|
||||
if ((finfo->fcf.dest_addr_mode & 3) != 0 &&
|
||||
(finfo->fcf.src_addr_mode & 3) != 0 &&
|
||||
finfo->src_pid == finfo->dest_pid)
|
||||
{
|
||||
/* Indicate source PANID compression */
|
||||
|
||||
finfo->fcf.panid_compression = 1;
|
||||
|
||||
/* Compressed header, only do dest pid.
|
||||
*
|
||||
* REVISIT: This was commented out in corresponding Contiki logic, but
|
||||
* is needed to match sixlowpan_recv_hdrlen().
|
||||
*/
|
||||
|
||||
flen->src_pid_len = 0;
|
||||
}
|
||||
|
||||
/* Determine address lengths */
|
||||
|
||||
flen->dest_addr_len = sixlowpan_addrlen(finfo->fcf.dest_addr_mode & 3);
|
||||
flen->src_addr_len = sixlowpan_addrlen(finfo->fcf.src_addr_mode & 3);
|
||||
|
||||
/* Aux security header */
|
||||
|
||||
#if 0 /* TODO Aux security header not yet implemented */
|
||||
if ((finfo->fcf.security_enabled & 1) != 0)
|
||||
{
|
||||
switch(finfo->aux_hdr.security_control.key_id_mode)
|
||||
{
|
||||
case 0:
|
||||
flen->aux_sec_len = 5; /* Minimum value */
|
||||
break;
|
||||
|
||||
case 1:
|
||||
flen->aux_sec_len = 6;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
flen->aux_sec_len = 10;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
flen->aux_sec_len = 14;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return sixlowpan_anyaddrnull(saddr, NET_6LOWPAN_SADDRSIZE);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sixlowpan_fieldlengths
|
||||
* Name: sixlowpan_eaddrnull
|
||||
*
|
||||
* Description:
|
||||
* Return the lengths associated fields of the IEEE802.15.4 header.
|
||||
* If the destination address is all zero in the MAC header buf, then it is
|
||||
* broadcast on the 802.15.4 network.
|
||||
*
|
||||
* Input parameters:
|
||||
* finfo - IEEE802.15.4 header info (input)
|
||||
* flen - Field length info (output)
|
||||
* eaddr - The extended address to check
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
* The address length associated with the address mode.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int sixlowpan_flen_hdrlen(FAR const struct field_length_s *flen)
|
||||
static inline bool sixlowpan_eaddrnull(FAR const uint8_t *eaddr)
|
||||
{
|
||||
return 3 + flen->dest_pid_len + flen->dest_addr_len +
|
||||
flen->src_pid_len + flen->src_addr_len + flen->aux_sec_len;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sixlowpan_802154_hdrlen
|
||||
*
|
||||
* Description:
|
||||
* Calculates the length of the frame header. This function is meant to
|
||||
* be called by a higher level function, that interfaces to a MAC.
|
||||
*
|
||||
* Input parameters:
|
||||
* finfo - IEEE802.15.4 header info that specifies the frame to send.
|
||||
*
|
||||
* Returned Value:
|
||||
* The length of the frame header.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int sixlowpan_802154_hdrlen(FAR struct frame802154_s *finfo)
|
||||
{
|
||||
struct field_length_s flen;
|
||||
|
||||
sixlowpan_fieldlengths(finfo, &flen);
|
||||
return sixlowpan_flen_hdrlen(&flen);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sixlowpan_setup_params
|
||||
*
|
||||
* Description:
|
||||
* Configure frame parmeters structure.
|
||||
*
|
||||
* Input parameters:
|
||||
* ieee - A reference IEEE802.15.4 MAC network device structure.
|
||||
* iob - The IOB in which to create the frame.
|
||||
* dest_panid - PAN ID of the destination. May be 0xffff if the destination
|
||||
* is not associated.
|
||||
* params - Where to put the parmeters
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void sixlowpan_setup_params(FAR struct ieee802154_driver_s *ieee,
|
||||
uint16_t dest_panid,
|
||||
FAR struct frame802154_s *params)
|
||||
{
|
||||
bool rcvrnull;
|
||||
|
||||
/* Initialize all prameters to all zero */
|
||||
|
||||
memset(params, 0, sizeof(params));
|
||||
|
||||
/* Build the FCF (Only non-zero elements need to be initialized). */
|
||||
|
||||
params->fcf.frame_type = FRAME802154_DATAFRAME;
|
||||
params->fcf.frame_pending = g_pktattrs[PACKETBUF_ATTR_PENDING];
|
||||
|
||||
/* If the output address is NULL in the Rime buf, then it is broadcast
|
||||
* on the 802.15.4 network.
|
||||
*/
|
||||
|
||||
rcvrnull = sixlowpan_addrnull(g_pktaddrs[PACKETBUF_ADDR_RECEIVER].u8);
|
||||
if (rcvrnull)
|
||||
{
|
||||
params->fcf.ack_required = g_pktattrs[PACKETBUF_ATTR_MAC_ACK];
|
||||
}
|
||||
|
||||
/* Insert IEEE 802.15.4 (2003) version bit. */
|
||||
|
||||
params->fcf.frame_version = FRAME802154_IEEE802154_2003;
|
||||
|
||||
/* Increment and set the data sequence number. */
|
||||
|
||||
if (g_pktattrs[PACKETBUF_ATTR_MAC_SEQNO] != 0)
|
||||
{
|
||||
params->seq = g_pktattrs[PACKETBUF_ATTR_MAC_SEQNO] & 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
params->seq = ieee->i_dsn++;
|
||||
g_pktattrs[PACKETBUF_ATTR_MAC_SEQNO] = params->seq | 0x100;
|
||||
}
|
||||
|
||||
/* Complete the addressing fields. */
|
||||
/* Set the source and destination PAN ID. */
|
||||
|
||||
params->src_pid = ieee->i_panid;
|
||||
params->dest_pid = dest_panid;
|
||||
|
||||
/* If the output address is NULL in the Rime buf, then it is broadcast
|
||||
* on the 802.15.4 network.
|
||||
*/
|
||||
|
||||
if (rcvrnull)
|
||||
{
|
||||
/* Broadcast requires short address mode. */
|
||||
|
||||
params->fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE;
|
||||
params->dest_addr[0] = 0xff;
|
||||
params->dest_addr[1] = 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Copy the destination address */
|
||||
|
||||
rimeaddr_copy((struct rimeaddr_s *)¶ms->dest_addr,
|
||||
g_pktaddrs[PACKETBUF_ADDR_RECEIVER].u8);
|
||||
|
||||
/* Use short destination address mode if so configured */
|
||||
|
||||
#ifdef CONFIG_NET_6LOWPAN_RIMEADDR_EXTENDED
|
||||
params->fcf.dest_addr_mode = FRAME802154_LONGADDRMODE;
|
||||
#else
|
||||
params->fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Set the source address to the node address assigned to the device */
|
||||
|
||||
rimeaddr_copy((struct rimeaddr_s *)¶ms->src_addr,
|
||||
&ieee->i_dev.d_mac.ieee802154);
|
||||
|
||||
/* Use short soruce address mode if so configured */
|
||||
|
||||
#ifdef CONFIG_NET_6LOWPAN_RIMEADDR_EXTENDED
|
||||
params->fcf.src_addr_mode = FRAME802154_LONGADDRMODE;
|
||||
#else
|
||||
params->fcf.src_addr_mode = FRAME802154_SHORTADDRMODE;
|
||||
#endif
|
||||
return sixlowpan_anyaddrnull(eaddr, NET_6LOWPAN_EADDRSIZE);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -383,7 +130,115 @@ static void sixlowpan_setup_params(FAR struct ieee802154_driver_s *ieee,
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sixlowpan_send_hdrlen
|
||||
* Name: sixlowpan_meta_data
|
||||
*
|
||||
* Description:
|
||||
* Based on the collected attributes and addresses, construct the MAC meta
|
||||
* data structure that we need to interface with the IEEE802.15.4 MAC.
|
||||
*
|
||||
* Input Parameters:
|
||||
* ieee - IEEE 802.15.4 MAC driver state reference.
|
||||
* pktmeta - Meta-data specific to the current outgoing frame
|
||||
* meta - Location to return the corresponding meta data.
|
||||
* paylen - The size of the data payload to be sent.
|
||||
*
|
||||
* Returned Value:
|
||||
* Ok is returned on success; Othewise a negated errno value is returned.
|
||||
*
|
||||
* Assumptions:
|
||||
* Called with the network locked.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sixlowpan_meta_data(FAR struct ieee802154_driver_s *ieee,
|
||||
FAR const struct packet_metadata_s *pktmeta,
|
||||
FAR struct ieee802154_frame_meta_s *meta,
|
||||
uint16_t paylen)
|
||||
{
|
||||
bool rcvrnull;
|
||||
|
||||
/* Initialize all settings to all zero */
|
||||
|
||||
memset(meta, 0, sizeof(struct ieee802154_frame_meta_s));
|
||||
|
||||
/* Source address mode */
|
||||
|
||||
meta->src_addr_mode = pktmeta->sextended != 0?
|
||||
IEEE802154_ADDRMODE_EXTENDED :
|
||||
IEEE802154_ADDRMODE_SHORT;
|
||||
|
||||
/* Check for a broadcast destination address (all zero) */
|
||||
|
||||
if (pktmeta->dextended != 0)
|
||||
{
|
||||
/* Extended destination address mode */
|
||||
|
||||
rcvrnull = sixlowpan_eaddrnull(pktmeta->dest.eaddr.u8);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Short destination address mode */
|
||||
|
||||
rcvrnull = sixlowpan_saddrnull(pktmeta->dest.saddr.u8);
|
||||
}
|
||||
|
||||
if (rcvrnull)
|
||||
{
|
||||
meta->msdu_flags.ack_tx = TRUE;
|
||||
}
|
||||
|
||||
/* Destination address */
|
||||
|
||||
/* If the output address is NULL, then it is broadcast on the 802.15.4
|
||||
* network.
|
||||
*/
|
||||
|
||||
if (rcvrnull)
|
||||
{
|
||||
/* Broadcast requires short address mode. */
|
||||
|
||||
meta->dest_addr.mode = IEEE802154_ADDRMODE_SHORT;
|
||||
meta->dest_addr.saddr = 0;
|
||||
}
|
||||
else if (pktmeta->dextended != 0)
|
||||
{
|
||||
/* Extended destination address mode */
|
||||
|
||||
meta->dest_addr.mode = IEEE802154_ADDRMODE_EXTENDED;
|
||||
sixlowpan_eaddrcopy(&meta->dest_addr.eaddr, pktmeta->dest.eaddr.u8);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Short destination address mode */
|
||||
|
||||
meta->dest_addr.mode = IEEE802154_ADDRMODE_SHORT;
|
||||
sixlowpan_saddrcopy(&meta->dest_addr.saddr, pktmeta->dest.saddr.u8);
|
||||
}
|
||||
|
||||
meta->dest_addr.panid = pktmeta->dpanid;
|
||||
|
||||
/* Handle associated with MSDU. Will increment once per packet, not
|
||||
* necesarily per frame: The same MSDU handle will be used for each
|
||||
* fragment of a disassembled packet.
|
||||
*/
|
||||
|
||||
meta->msdu_handle = ieee->i_msdu_handle++;
|
||||
|
||||
#ifdef CONFIG_IEEE802154_SECURITY
|
||||
# warning CONFIG_IEEE802154_SECURITY not yet supported
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IEEE802154_UWB
|
||||
# warning CONFIG_IEEE802154_UWB not yet supported
|
||||
#endif
|
||||
|
||||
/* Ranging left zero */
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sixlowpan_frame_hdrlen
|
||||
*
|
||||
* Description:
|
||||
* This function is before the first frame has been sent in order to
|
||||
@ -391,9 +246,8 @@ static void sixlowpan_setup_params(FAR struct ieee802154_driver_s *ieee,
|
||||
* buffer is required to make this determination.
|
||||
*
|
||||
* Input parameters:
|
||||
* ieee - A reference IEEE802.15.4 MAC network device structure.
|
||||
* dest_panid - PAN ID of the destination. May be 0xffff if the destination
|
||||
* is not associated.
|
||||
* ieee - A reference IEEE802.15.4 MAC network device structure.
|
||||
* meta - Meta data that describes the MAC header
|
||||
*
|
||||
* Returned Value:
|
||||
* The frame header length is returnd on success; otherwise, a negated
|
||||
@ -401,171 +255,37 @@ static void sixlowpan_setup_params(FAR struct ieee802154_driver_s *ieee,
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sixlowpan_send_hdrlen(FAR struct ieee802154_driver_s *ieee,
|
||||
uint16_t dest_panid)
|
||||
int sixlowpan_frame_hdrlen(FAR struct ieee802154_driver_s *ieee,
|
||||
FAR const struct ieee802154_frame_meta_s *meta)
|
||||
{
|
||||
struct frame802154_s params;
|
||||
|
||||
/* Set up the frame parameters */
|
||||
|
||||
sixlowpan_setup_params(ieee, dest_panid, ¶ms);
|
||||
|
||||
/* Return the length of the header */
|
||||
|
||||
return sixlowpan_802154_hdrlen(¶ms);
|
||||
return ieee->i_get_mhrlen(ieee, meta);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sixlowpan_802154_framecreate
|
||||
*
|
||||
* Description:
|
||||
* Creates a frame for transmission over the air. This function is meant
|
||||
* to be called by a higher level function, that interfaces to a MAC.
|
||||
*
|
||||
* Input parameters:
|
||||
* finfo - Pointer to struct EEE802.15.4 header structure that specifies
|
||||
* the frame to send.
|
||||
* buf - Pointer to the buffer to use for the frame.
|
||||
* buflen - The length of the buffer to use for the frame.
|
||||
* finfo - Specifies the frame to send.
|
||||
*
|
||||
* Returned Value:
|
||||
* The length of the frame header or 0 if there was insufficient space in
|
||||
* the buffer for the frame headers.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sixlowpan_802154_framecreate(FAR struct frame802154_s *finfo,
|
||||
FAR uint8_t *buf, int buflen)
|
||||
{
|
||||
struct field_length_s flen;
|
||||
uint8_t pos;
|
||||
int hdrlen;
|
||||
int i;
|
||||
|
||||
sixlowpan_fieldlengths(finfo, &flen);
|
||||
|
||||
hdrlen = sixlowpan_flen_hdrlen(&flen);
|
||||
if (hdrlen > buflen)
|
||||
{
|
||||
/* Too little space for headers. */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* OK, now we have field lengths. Time to actually construct the outgoing
|
||||
* frame, and store it in the provided buffer
|
||||
*/
|
||||
|
||||
buf[0] = ((finfo->fcf.frame_type & 7) << FRAME802154_FRAMETYPE_SHIFT) |
|
||||
((finfo->fcf.security_enabled & 1) << FRAME802154_SECENABLED_SHIFT) |
|
||||
((finfo->fcf.frame_pending & 1) << FRAME802154_FRAMEPENDING_SHIFT) |
|
||||
((finfo->fcf.ack_required & 1) << FRAME802154_ACKREQUEST_SHIFT) |
|
||||
((finfo->fcf.panid_compression & 1) << FRAME802154_PANIDCOMP_SHIFT);
|
||||
buf[1] = ((finfo->fcf.dest_addr_mode & 3) << FRAME802154_DSTADDR_SHIFT) |
|
||||
((finfo->fcf.frame_version & 3) << FRAME802154_VERSION_SHIFT) |
|
||||
((finfo->fcf.src_addr_mode & 3) << FRAME802154_SRCADDR_SHIFT);
|
||||
|
||||
/* Sequence number */
|
||||
|
||||
buf[2] = finfo->seq;
|
||||
pos = 3;
|
||||
|
||||
/* Destination PAN ID */
|
||||
|
||||
if (flen.dest_pid_len == 2)
|
||||
{
|
||||
buf[pos++] = finfo->dest_pid & 0xff;
|
||||
buf[pos++] = (finfo->dest_pid >> 8) & 0xff;
|
||||
}
|
||||
|
||||
/* Destination address */
|
||||
|
||||
for (i = flen.dest_addr_len; i > 0; i--)
|
||||
{
|
||||
buf[pos++] = finfo->dest_addr[i - 1];
|
||||
}
|
||||
|
||||
/* Source PAN ID */
|
||||
|
||||
if (flen.src_pid_len == 2)
|
||||
{
|
||||
buf[pos++] = finfo->src_pid & 0xff;
|
||||
buf[pos++] = (finfo->src_pid >> 8) & 0xff;
|
||||
}
|
||||
|
||||
/* Source address */
|
||||
|
||||
for (i = flen.src_addr_len; i > 0; i--)
|
||||
{
|
||||
buf[pos++] = finfo->src_addr[i - 1];
|
||||
}
|
||||
|
||||
/* Aux header */
|
||||
|
||||
#if 0 /* TODO Aux security header not yet implemented */
|
||||
if (flen.aux_sec_len)
|
||||
{
|
||||
pos += flen.aux_sec_len;
|
||||
}
|
||||
#endif
|
||||
|
||||
DEBUGASSERT(pos == hdrlen);
|
||||
return (int)pos;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sixlowpan_framecreate
|
||||
* Name: sixlowpan_frame_submit
|
||||
*
|
||||
* Description:
|
||||
* This function is called after eiether (1) the IEEE802.15.4 MAC driver
|
||||
* polls for TX data or (2) after the IEEE802.15.4 MAC driver provides an
|
||||
* in frame and the network responds with an outgoing packet. It creates
|
||||
* the IEEE802.15.4 header in the frame buffer.
|
||||
* polls for TX data or (2) after the IEEE802.15.4 MAC driver provides a
|
||||
* new incoming frame and the network responds with an outgoing packet. It
|
||||
* submits any new outgoing frame to the MAC.
|
||||
*
|
||||
* Input parameters:
|
||||
* ieee - A reference IEEE802.15.4 MAC network device structure.
|
||||
* iob - The IOB in which to create the frame.
|
||||
* dest_panid - PAN ID of the destination. May be 0xffff if the destination
|
||||
* is not associated.
|
||||
* ieee - A reference IEEE802.15.4 MAC network device structure.
|
||||
* meta - Meta data that describes the MAC header
|
||||
* frame - The IOB containing the frame to be submitted.
|
||||
*
|
||||
* Returned Value:
|
||||
* The frame header length is returnd on success; otherwise, a negated
|
||||
* errno value is return on failure.
|
||||
* Zero (OK) is returned on success; otherwise, a negated errno value is
|
||||
* return on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sixlowpan_framecreate(FAR struct ieee802154_driver_s *ieee,
|
||||
FAR struct iob_s *iob, uint16_t dest_panid)
|
||||
int sixlowpan_frame_submit(FAR struct ieee802154_driver_s *ieee,
|
||||
FAR const struct ieee802154_frame_meta_s *meta,
|
||||
FAR struct iob_s *frame)
|
||||
{
|
||||
struct frame802154_s params;
|
||||
int hdrlen;
|
||||
|
||||
/* Set up the frame parameters */
|
||||
|
||||
sixlowpan_setup_params(ieee, dest_panid, ¶ms);
|
||||
|
||||
/* Get the length of the header */
|
||||
|
||||
hdrlen = sixlowpan_802154_hdrlen(¶ms);
|
||||
|
||||
/* Then create the frame */
|
||||
|
||||
sixlowpan_802154_framecreate(¶ms, iob->io_data, hdrlen);
|
||||
|
||||
wlinfo("Frame type: %02x hdrlen: %d\n",
|
||||
params.fcf.frame_type, hdrlen);
|
||||
#ifdef CONFIG_NET_6LOWPAN_RIMEADDR_EXTENDED
|
||||
wlinfo("Dest address: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
params.dest_addr[0], params.dest_addr[1], params.dest_addr[2],
|
||||
params.dest_addr[3], params.dest_addr[4], params.dest_addr[5],
|
||||
params.dest_addr[6], params.dest_addr[7]);
|
||||
#else
|
||||
wlinfo("Dest address: %02x:%02x\n",
|
||||
params.dest_addr[0], params.dest_addr[1]);
|
||||
#endif
|
||||
|
||||
return hdrlen;
|
||||
return ieee->i_req_data(ieee, meta, frame);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NET_6LOWPAN */
|
||||
|
@ -67,9 +67,4 @@ uint8_t g_uncomp_hdrlen;
|
||||
|
||||
uint8_t g_frame_hdrlen;
|
||||
|
||||
/* Packet buffer metadata: Attributes and addresses */
|
||||
|
||||
uint16_t g_pktattrs[PACKETBUF_NUM_ATTRS];
|
||||
struct rimeaddr_s g_pktaddrs[PACKETBUF_NUM_ADDRS];
|
||||
|
||||
#endif /* CONFIG_NET_6LOWPAN */
|
||||
|
@ -220,7 +220,7 @@ static FAR struct sixlowpan_addrcontext_s *
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: compress_addr_64
|
||||
* Name: comporess_ipaddr, compress_tagaddr, and compress_laddr
|
||||
*
|
||||
* Description:
|
||||
* Uncompress addresses based on a prefix and a postfix with zeroes in
|
||||
@ -230,20 +230,16 @@ static FAR struct sixlowpan_addrcontext_s *
|
||||
* prefpost takes a byte where the first nibble specify prefix count
|
||||
* and the second postfix count (NOTE: 15/0xf => 16 bytes copy).
|
||||
*
|
||||
* compress_tagaddr() accepts a remote, variable length, taged MAC address;
|
||||
* compress_laddr() accepts a local, fixed length MAC address.
|
||||
* compress_ipaddr() is simply the common logic that does not depend on
|
||||
* the size of the MAC address.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint8_t compress_addr_64(FAR const net_ipv6addr_t ipaddr,
|
||||
FAR const struct rimeaddr_s *macaddr,
|
||||
uint8_t bitpos)
|
||||
static uint8_t compress_ipaddr(FAR const net_ipv6addr_t ipaddr, uint8_t bitpos)
|
||||
{
|
||||
ninfo("ipaddr=%p macaddr=%p bitpos=%u g_hc06ptr=%p\n",
|
||||
ipaddr, macaddr, bitpos, g_hc06ptr);
|
||||
|
||||
if (sixlowpan_ismacbased(ipaddr, macaddr))
|
||||
{
|
||||
return 3 << bitpos; /* 0-bits */
|
||||
}
|
||||
else if (SIXLOWPAN_IS_IID_16BIT_COMPRESSABLE(ipaddr))
|
||||
if (SIXLOWPAN_IS_IID_16BIT_COMPRESSABLE(ipaddr))
|
||||
{
|
||||
/* Compress IID to 16 bits: xxxx:xxxx:xxxx:xxxx:0000:00ff:fe00:XXXX */
|
||||
|
||||
@ -261,6 +257,40 @@ static uint8_t compress_addr_64(FAR const net_ipv6addr_t ipaddr,
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (sixlowpan_ismacbased(ipaddr, macaddr))
|
||||
{
|
||||
return 3 << bitpos; /* 0-bits */
|
||||
}
|
||||
else
|
||||
{
|
||||
return compress_ipaddr(ipaddr, bitpos);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (sixlowpan_isaddrbased(ipaddr, macaddr))
|
||||
{
|
||||
return 3 << bitpos; /* 0-bits */
|
||||
}
|
||||
else
|
||||
{
|
||||
return compress_ipaddr(ipaddr, bitpos);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: uncompress_addr
|
||||
*
|
||||
@ -275,7 +305,7 @@ static uint8_t compress_addr_64(FAR const net_ipv6addr_t ipaddr,
|
||||
****************************************************************************/
|
||||
|
||||
static void uncompress_addr(FAR net_ipv6addr_t ipaddr, uint8_t const prefix[],
|
||||
uint8_t prefpost, FAR struct rimeaddr_s *macaddr)
|
||||
uint8_t prefpost)
|
||||
{
|
||||
uint8_t prefcount = prefpost >> 4;
|
||||
uint8_t postcount = prefpost & 0x0f;
|
||||
@ -316,7 +346,7 @@ static void uncompress_addr(FAR net_ipv6addr_t ipaddr, uint8_t const prefix[],
|
||||
{
|
||||
/* No IID based configuration if no prefix and no data => unspec */
|
||||
|
||||
sixlowpan_ipfromrime(macaddr, ipaddr);
|
||||
nwarn("WARNING: No IID based configuration\n");
|
||||
}
|
||||
|
||||
ninfo("Uncompressing %d + %d => %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
|
||||
@ -446,7 +476,7 @@ void sixlowpan_hc06_initialize(void)
|
||||
|
||||
void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
|
||||
FAR const struct ipv6_hdr_s *ipv6,
|
||||
FAR const struct rimeaddr_s *destmac,
|
||||
FAR const struct sixlowpan_tagaddr_s *destmac,
|
||||
FAR uint8_t *fptr)
|
||||
{
|
||||
FAR uint8_t *iphc = fptr + g_frame_hdrlen;
|
||||
@ -614,9 +644,9 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
|
||||
|
||||
/* Compression compare with this nodes address (source) */
|
||||
|
||||
iphc1 |= compress_addr_64(ipv6->srcipaddr,
|
||||
&ieee->i_dev.d_mac.ieee802154,
|
||||
SIXLOWPAN_IPHC_SAM_BIT);
|
||||
iphc1 |= compress_laddr(ipv6->srcipaddr,
|
||||
&ieee->i_dev.d_mac.ieee802154,
|
||||
SIXLOWPAN_IPHC_SAM_BIT);
|
||||
}
|
||||
|
||||
/* No address context found for this address */
|
||||
@ -625,7 +655,7 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
|
||||
ipv6->destipaddr[1] == 0 && ipv6->destipaddr[2] == 0 &&
|
||||
ipv6->destipaddr[3] == 0)
|
||||
{
|
||||
iphc1 |= compress_addr_64(ipv6->srcipaddr,
|
||||
iphc1 |= compress_laddr(ipv6->srcipaddr,
|
||||
&ieee->i_dev.d_mac.ieee802154,
|
||||
SIXLOWPAN_IPHC_SAM_BIT);
|
||||
}
|
||||
@ -701,7 +731,7 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
|
||||
|
||||
/* Compession compare with link adress (destination) */
|
||||
|
||||
iphc1 |= compress_addr_64(ipv6->destipaddr, destmac,
|
||||
iphc1 |= compress_tagaddr(ipv6->destipaddr, destmac,
|
||||
SIXLOWPAN_IPHC_DAM_BIT);
|
||||
|
||||
/* No address context found for this address */
|
||||
@ -710,7 +740,7 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
|
||||
ipv6->destipaddr[1] == 0 && ipv6->destipaddr[2] == 0 &&
|
||||
ipv6->destipaddr[3] == 0)
|
||||
{
|
||||
iphc1 |= compress_addr_64(ipv6->destipaddr, destmac,
|
||||
iphc1 |= compress_tagaddr(ipv6->destipaddr, destmac,
|
||||
SIXLOWPAN_IPHC_DAM_BIT);
|
||||
}
|
||||
else
|
||||
@ -828,8 +858,8 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
|
||||
* sixlowpan_buf
|
||||
*
|
||||
* This function is called by the input function when the dispatch is HC06.
|
||||
* We process the packet in the rime buffer, uncompress the header fields,
|
||||
* and copy the result in the sixlowpan buffer. At the end of the
|
||||
* We process the frame in the IOB buffer, uncompress the header fields,
|
||||
* and copy the result into the driver packet buffer. At the end of the
|
||||
* decompression, g_frame_hdrlen and g_uncompressed_hdrlen are set to the
|
||||
* appropriate values
|
||||
*
|
||||
@ -983,18 +1013,22 @@ void sixlowpan_uncompresshdr_hc06(uint16_t iplen, FAR struct iob_s *iob,
|
||||
}
|
||||
}
|
||||
|
||||
/* If tmp == 0 we do not have a Address context and therefore no prefix */
|
||||
/* If tmp == 0 we do not have a address context and therefore no prefix */
|
||||
/* REVISIT: Source address may not be the same size as the destination
|
||||
* address.
|
||||
*/
|
||||
|
||||
uncompress_addr(ipv6->srcipaddr,
|
||||
tmp != 0 ? addrcontext->prefix : NULL, g_unc_ctxconf[tmp],
|
||||
(FAR struct rimeaddr_s *)&g_pktaddrs[PACKETBUF_ADDR_SENDER]);
|
||||
tmp != 0 ? addrcontext->prefix : NULL, g_unc_ctxconf[tmp]);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No compression and link local */
|
||||
/* REVISIT: Source address may not be the same size as the destination
|
||||
* address.
|
||||
*/
|
||||
|
||||
uncompress_addr(ipv6->srcipaddr, g_llprefix, g_unc_llconf[tmp],
|
||||
(FAR struct rimeaddr_s *)&g_pktaddrs[PACKETBUF_ADDR_SENDER]);
|
||||
uncompress_addr(ipv6->srcipaddr, g_llprefix, g_unc_llconf[tmp]);
|
||||
}
|
||||
|
||||
/* Destination address */
|
||||
@ -1029,7 +1063,7 @@ void sixlowpan_uncompresshdr_hc06(uint16_t iplen, FAR struct iob_s *iob,
|
||||
g_hc06ptr++;
|
||||
}
|
||||
|
||||
uncompress_addr(ipv6->destipaddr, prefix, g_unc_mxconf[tmp], NULL);
|
||||
uncompress_addr(ipv6->destipaddr, prefix, g_unc_mxconf[tmp]);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1052,15 +1086,13 @@ void sixlowpan_uncompresshdr_hc06(uint16_t iplen, FAR struct iob_s *iob,
|
||||
return;
|
||||
}
|
||||
|
||||
uncompress_addr(ipv6->destipaddr, addrcontext->prefix, g_unc_ctxconf[tmp],
|
||||
(FAR struct rimeaddr_s *)&g_pktaddrs[PACKETBUF_ADDR_RECEIVER]);
|
||||
uncompress_addr(ipv6->destipaddr, addrcontext->prefix, g_unc_ctxconf[tmp]);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Not address context based => link local M = 0, DAC = 0 - same as SAC */
|
||||
|
||||
uncompress_addr(ipv6->destipaddr, g_llprefix, g_unc_llconf[tmp],
|
||||
(FAR struct rimeaddr_s *)&g_pktaddrs[PACKETBUF_ADDR_RECEIVER]);
|
||||
uncompress_addr(ipv6->destipaddr, g_llprefix, g_unc_llconf[tmp]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -120,7 +120,7 @@
|
||||
|
||||
void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
|
||||
FAR const struct ipv6_hdr_s *ipv6,
|
||||
FAR const struct rimeaddr_s *destmac,
|
||||
FAR const struct sixlowpan_tagaddr_s *destmac,
|
||||
FAR uint8_t *fptr)
|
||||
{
|
||||
FAR uint8_t *hc1 = fptr + g_frame_hdrlen;
|
||||
@ -129,7 +129,7 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
|
||||
|
||||
if (ipv6->vtc != 0x60 || ipv6->tcf != 0 || ipv6->flow != 0 ||
|
||||
!sixlowpan_islinklocal(ipv6->srcipaddr) ||
|
||||
!sixlowpan_ismacbased(ipv6->srcipaddr, &ieee->i_dev.d_mac.ieee802154) ||
|
||||
!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 &&
|
||||
@ -137,12 +137,12 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
|
||||
{
|
||||
/* IPV6 DISPATCH
|
||||
* Something cannot be compressed, use IPV6 DISPATCH, compress
|
||||
* nothing, copy IPv6 header in rime buffer
|
||||
* nothing, copy IPv6 header into the frame buffer
|
||||
*/
|
||||
|
||||
/* IPv6 dispatch header (1 byte) */
|
||||
|
||||
hc1[RIME_HC1_DISPATCH] = SIXLOWPAN_DISPATCH_IPV6;
|
||||
hc1[SIXLOWPAN_HC1_DISPATCH] = SIXLOWPAN_DISPATCH_IPV6;
|
||||
g_frame_hdrlen += SIXLOWPAN_IPV6_HDR_LEN;
|
||||
|
||||
memcpy(fptr + g_frame_hdrlen, ipv6, IPv6_HDRLEN);
|
||||
@ -156,15 +156,15 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
|
||||
* header is UDP, we compress UDP header using HC2
|
||||
*/
|
||||
|
||||
hc1[RIME_HC1_DISPATCH] = SIXLOWPAN_DISPATCH_HC1;
|
||||
hc1[SIXLOWPAN_HC1_DISPATCH] = SIXLOWPAN_DISPATCH_HC1;
|
||||
g_uncomp_hdrlen += IPv6_HDRLEN;
|
||||
switch (ipv6->proto)
|
||||
{
|
||||
case IP_PROTO_ICMP6:
|
||||
/* HC1 encoding and ttl */
|
||||
|
||||
hc1[RIME_HC1_ENCODING] = 0xfc;
|
||||
hc1[RIME_HC1_TTL] = ipv6->ttl;
|
||||
hc1[SIXLOWPAN_HC1_ENCODING] = 0xfc;
|
||||
hc1[SIXLOWPAN_HC1_TTL] = ipv6->ttl;
|
||||
g_frame_hdrlen += SIXLOWPAN_HC1_HDR_LEN;
|
||||
break;
|
||||
|
||||
@ -172,8 +172,8 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
|
||||
case IP_PROTO_TCP:
|
||||
/* HC1 encoding and ttl */
|
||||
|
||||
hc1[RIME_HC1_ENCODING] = 0xfe;
|
||||
hc1[RIME_HC1_TTL] = ipv6->ttl;
|
||||
hc1[SIXLOWPAN_HC1_ENCODING] = 0xfe;
|
||||
hc1[SIXLOWPAN_HC1_TTL] = ipv6->ttl;
|
||||
g_frame_hdrlen += SIXLOWPAN_HC1_HDR_LEN;
|
||||
break;
|
||||
#endif /* CONFIG_NET_TCP */
|
||||
@ -201,17 +201,17 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
|
||||
|
||||
/* HC1 encoding */
|
||||
|
||||
hcudp[RIME_HC1_HC_UDP_HC1_ENCODING] = 0xfb;
|
||||
hcudp[SIXLOWPAN_HC1_HC_UDP_HC1_ENCODING] = 0xfb;
|
||||
|
||||
/* HC_UDP encoding, ttl, src and dest ports, checksum */
|
||||
|
||||
hcudp[RIME_HC1_HC_UDP_UDP_ENCODING] = 0xe0;
|
||||
hcudp[RIME_HC1_HC_UDP_TTL] = ipv6->ttl;
|
||||
hcudp[RIME_HC1_HC_UDP_PORTS] =
|
||||
hcudp[SIXLOWPAN_HC1_HC_UDP_UDP_ENCODING] = 0xe0;
|
||||
hcudp[SIXLOWPAN_HC1_HC_UDP_TTL] = ipv6->ttl;
|
||||
hcudp[SIXLOWPAN_HC1_HC_UDP_PORTS] =
|
||||
(uint8_t)((ntohs(udp->srcport) - CONFIG_NET_6LOWPAN_MINPORT) << 4) +
|
||||
(uint8_t)((ntohs(udp->destport) - CONFIG_NET_6LOWPAN_MINPORT));
|
||||
|
||||
memcpy(&hcudp[RIME_HC1_HC_UDP_CHKSUM], &udp->udpchksum, 2);
|
||||
memcpy(&hcudp[SIXLOWPAN_HC1_HC_UDP_CHKSUM], &udp->udpchksum, 2);
|
||||
|
||||
g_frame_hdrlen += SIXLOWPAN_HC1_HC_UDP_HDR_LEN;
|
||||
g_uncomp_hdrlen += UDP_HDRLEN;
|
||||
@ -220,8 +220,8 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
|
||||
{
|
||||
/* HC1 encoding and ttl */
|
||||
|
||||
hc1[RIME_HC1_ENCODING] = 0xfa;
|
||||
hc1[RIME_HC1_TTL] = ipv6->ttl;
|
||||
hc1[SIXLOWPAN_HC1_ENCODING] = 0xfa;
|
||||
hc1[SIXLOWPAN_HC1_TTL] = ipv6->ttl;
|
||||
g_frame_hdrlen += SIXLOWPAN_HC1_HDR_LEN;
|
||||
}
|
||||
}
|
||||
@ -238,8 +238,8 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
|
||||
* Uncompress HC1 (and HC_UDP) headers and put them in sixlowpan_buf
|
||||
*
|
||||
* This function is called by the input function when the dispatch is
|
||||
* HC1. It processes the packet in the rime buffer, uncompresses the
|
||||
* header fields, and copies the result in the sixlowpan buffer. At the
|
||||
* HC1. It processes the frame in the IOB buffer, uncompresses the
|
||||
* header fields, and copies the result in the packet buffer. At the
|
||||
* end of the decompression, g_frame_hdrlen and uncompressed_hdr_len
|
||||
* are set to the appropriate values
|
||||
*
|
||||
@ -271,30 +271,22 @@ int sixlowpan_uncompresshdr_hc1(uint16_t iplen, FAR struct iob_s *iob,
|
||||
ipv6->tcf = 0; /* Bits 0-3: traffic class (LS), 4-bits: flow label (MS) */
|
||||
ipv6->flow = 0; /* 16-bit flow label (LS) */
|
||||
|
||||
/* Use stateless auto-configuration to set source and destination IP
|
||||
* addresses.
|
||||
*/
|
||||
|
||||
sixlowpan_ipfromrime(&g_pktaddrs[PACKETBUF_ADDR_SENDER],
|
||||
ipv6->srcipaddr);
|
||||
sixlowpan_ipfromrime(&g_pktaddrs[PACKETBUF_ADDR_RECEIVER],
|
||||
ipv6->destipaddr);
|
||||
g_uncomp_hdrlen += IPv6_HDRLEN;
|
||||
|
||||
/* len[], proto, and ttl depend on the encoding */
|
||||
|
||||
switch (hc1[RIME_HC1_ENCODING] & 0x06)
|
||||
switch (hc1[SIXLOWPAN_HC1_ENCODING] & 0x06)
|
||||
{
|
||||
case SIXLOWPAN_HC1_NH_ICMP6:
|
||||
ipv6->proto = IP_PROTO_ICMP6;
|
||||
ipv6->ttl = hc1[RIME_HC1_TTL];
|
||||
ipv6->ttl = hc1[SIXLOWPAN_HC1_TTL];
|
||||
g_frame_hdrlen += SIXLOWPAN_HC1_HDR_LEN;
|
||||
break;
|
||||
|
||||
#if CONFIG_NET_TCP
|
||||
case SIXLOWPAN_HC1_NH_TCP:
|
||||
ipv6->proto = IP_PROTO_TCP;
|
||||
ipv6->ttl = hc1[RIME_HC1_TTL];
|
||||
ipv6->ttl = hc1[SIXLOWPAN_HC1_TTL];
|
||||
g_frame_hdrlen += SIXLOWPAN_HC1_HDR_LEN;
|
||||
break;
|
||||
#endif /* CONFIG_NET_TCP */
|
||||
@ -306,11 +298,11 @@ int sixlowpan_uncompresshdr_hc1(uint16_t iplen, FAR struct iob_s *iob,
|
||||
FAR uint8_t *hcudp = fptr + g_frame_hdrlen;
|
||||
|
||||
ipv6->proto = IP_PROTO_UDP;
|
||||
if ((hcudp[RIME_HC1_HC_UDP_HC1_ENCODING] & 0x01) != 0)
|
||||
if ((hcudp[SIXLOWPAN_HC1_HC_UDP_HC1_ENCODING] & 0x01) != 0)
|
||||
{
|
||||
/* UDP header is compressed with HC_UDP */
|
||||
|
||||
if (hcudp[RIME_HC1_HC_UDP_UDP_ENCODING] !=
|
||||
if (hcudp[SIXLOWPAN_HC1_HC_UDP_UDP_ENCODING] !=
|
||||
SIXLOWPAN_HC_UDP_ALL_C)
|
||||
{
|
||||
nwarn("WARNING: sixlowpan (uncompress_hdr), packet not supported");
|
||||
@ -319,16 +311,16 @@ int sixlowpan_uncompresshdr_hc1(uint16_t iplen, FAR struct iob_s *iob,
|
||||
|
||||
/* IP TTL */
|
||||
|
||||
ipv6->ttl = hcudp[RIME_HC1_HC_UDP_TTL];
|
||||
ipv6->ttl = hcudp[SIXLOWPAN_HC1_HC_UDP_TTL];
|
||||
|
||||
/* UDP ports, len, checksum */
|
||||
|
||||
udp->srcport =
|
||||
htons(CONFIG_NET_6LOWPAN_MINPORT + (hcudp[RIME_HC1_HC_UDP_PORTS] >> 4));
|
||||
htons(CONFIG_NET_6LOWPAN_MINPORT + (hcudp[SIXLOWPAN_HC1_HC_UDP_PORTS] >> 4));
|
||||
udp->destport =
|
||||
htons(CONFIG_NET_6LOWPAN_MINPORT + (hcudp[RIME_HC1_HC_UDP_PORTS] & 0x0F));
|
||||
htons(CONFIG_NET_6LOWPAN_MINPORT + (hcudp[SIXLOWPAN_HC1_HC_UDP_PORTS] & 0x0F));
|
||||
|
||||
memcpy(&udp->udpchksum, &hcudp[RIME_HC1_HC_UDP_CHKSUM], 2);
|
||||
memcpy(&udp->udpchksum, &hcudp[SIXLOWPAN_HC1_HC_UDP_CHKSUM], 2);
|
||||
|
||||
g_uncomp_hdrlen += UDP_HDRLEN;
|
||||
g_frame_hdrlen += SIXLOWPAN_HC1_HC_UDP_HDR_LEN;
|
||||
|
@ -61,6 +61,7 @@
|
||||
#include "nuttx/net/netdev.h"
|
||||
#include "nuttx/net/ip.h"
|
||||
#include "nuttx/net/sixlowpan.h"
|
||||
#include "nuttx/wireless/ieee802154/ieee802154_mac.h"
|
||||
|
||||
#ifdef CONFIG_NET_PKT
|
||||
# include "pkt/pkt.h"
|
||||
@ -130,89 +131,52 @@ static uint8_t g_bitbucket[UNCOMP_MAXHDR];
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sixlowpan_recv_hdrlen
|
||||
* Name: sixlowpan_compare_fragsrc
|
||||
*
|
||||
* Description:
|
||||
* Get the length of the IEEE802.15.4 FCF header on the received frame.
|
||||
* Check if the fragment that we just received is from the same source as
|
||||
* the previosly received fragements.
|
||||
*
|
||||
* Input Parameters:
|
||||
* ieee - The IEEE802.15.4 MAC network driver interface.
|
||||
* iob - The IOB containing the frame.
|
||||
* ieee - IEEE 802.15.4 MAC driver state reference
|
||||
* ind - Characteristics of the newly received frame
|
||||
*
|
||||
* Returned Value:
|
||||
* Ok is returned on success; Othewise a negated errno value is returned.
|
||||
*
|
||||
* Assumptions:
|
||||
* Network is locked
|
||||
* true if the sources are the same.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sixlowpan_recv_hdrlen(FAR const uint8_t *fptr)
|
||||
static bool sixlowpan_compare_fragsrc(FAR struct ieee802154_driver_s *ieee,
|
||||
FAR const struct ieee802154_data_ind_s *ind)
|
||||
{
|
||||
uint16_t hdrlen;
|
||||
uint8_t addrmode;
|
||||
/* Check for an extended source address */
|
||||
|
||||
/* Minimum header: 2 byte FCF + 1 byte sequence number */
|
||||
|
||||
hdrlen = 3;
|
||||
|
||||
/* Account for destination address size */
|
||||
|
||||
addrmode = (fptr[1] & FRAME802154_DSTADDR_MASK) >> FRAME802154_DSTADDR_SHIFT;
|
||||
if (addrmode == FRAME802154_SHORTADDRMODE)
|
||||
if (ind->src.mode == IEEE802154_ADDRMODE_EXTENDED)
|
||||
{
|
||||
/* 2 byte dest PAN + 2 byte dest short address */
|
||||
/* Was the first source address also extended? */
|
||||
|
||||
hdrlen += 4;
|
||||
}
|
||||
else if (addrmode == FRAME802154_LONGADDRMODE)
|
||||
{
|
||||
/* 2 byte dest PAN + 8 byte dest long address */
|
||||
if (ieee->i_fragsrc.extended)
|
||||
{
|
||||
/* Yes.. perform the extended address comparison */
|
||||
|
||||
hdrlen += 10;
|
||||
}
|
||||
else if (addrmode != FRAME802154_NOADDR)
|
||||
{
|
||||
nwarn("WARNING: Unrecognized address mode\n");
|
||||
|
||||
return -ENOSYS;
|
||||
}
|
||||
else if ((fptr[0] & (1 << FRAME802154_PANIDCOMP_SHIFT)) != 0)
|
||||
{
|
||||
nwarn("WARNING: PAN compression, but no destination address\n");
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Account for source address size */
|
||||
|
||||
addrmode = (fptr[1] & FRAME802154_SRCADDR_MASK) >> FRAME802154_SRCADDR_SHIFT;
|
||||
if (addrmode == FRAME802154_NOADDR)
|
||||
{
|
||||
return hdrlen;
|
||||
return sixlowpan_eaddrcmp(ieee->i_fragsrc.u.eaddr.u8, ind->src.eaddr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Add source PANID if PANIDs are not compressed */
|
||||
/* Short source address. Was the first source address also short? */
|
||||
|
||||
if ((fptr[0] & (1 << FRAME802154_PANIDCOMP_SHIFT)) == 0)
|
||||
if (!ieee->i_fragsrc.extended)
|
||||
{
|
||||
hdrlen += 2;
|
||||
}
|
||||
/* Yes.. perform the extended short comparison */
|
||||
|
||||
/* Add the length of the source address */
|
||||
|
||||
if (addrmode == FRAME802154_SHORTADDRMODE)
|
||||
{
|
||||
return hdrlen + 2;
|
||||
}
|
||||
else if (addrmode == FRAME802154_LONGADDRMODE)
|
||||
{
|
||||
return hdrlen + 8;
|
||||
return sixlowpan_saddrcmp(ieee->i_fragsrc.u.saddr.u8, &ind->src.saddr);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
/* Address are different size and, hence, cannot match */
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -321,6 +285,7 @@ static void sixlowpan_uncompress_ipv6hdr(FAR uint8_t *fptr, FAR uint8_t *bptr)
|
||||
*
|
||||
* Input Parameters:
|
||||
* ieee - The IEEE802.15.4 MAC network driver interface.
|
||||
* ind - Meta data characterizing the received frame.
|
||||
* iob - The IOB containing the frame.
|
||||
*
|
||||
* Returned Value:
|
||||
@ -332,6 +297,7 @@ static void sixlowpan_uncompress_ipv6hdr(FAR uint8_t *fptr, FAR uint8_t *bptr)
|
||||
****************************************************************************/
|
||||
|
||||
static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
|
||||
FAR const struct ieee802154_data_ind_s *ind,
|
||||
FAR struct iob_s *iob)
|
||||
{
|
||||
FAR uint8_t *fptr; /* Convenience pointer to beginning of the frame */
|
||||
@ -355,8 +321,8 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
|
||||
* This size includes both fragmentation and FCF headers.
|
||||
*/
|
||||
|
||||
fptr = iob->io_data;
|
||||
hdrsize = sixlowpan_recv_hdrlen(fptr);
|
||||
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);
|
||||
@ -377,7 +343,7 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
|
||||
*/
|
||||
|
||||
fragptr = fptr + hdrsize;
|
||||
switch ((GETINT16(fragptr, RIME_FRAG_DISPATCH_SIZE) & 0xf800) >> 8)
|
||||
switch ((GETHOST16(fragptr, SIXLOWPAN_FRAG_DISPATCH_SIZE) & 0xf800) >> 8)
|
||||
{
|
||||
/* First fragment of new reassembly */
|
||||
|
||||
@ -385,8 +351,8 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
|
||||
{
|
||||
/* Set up for the reassembly */
|
||||
|
||||
fragsize = GETINT16(fragptr, RIME_FRAG_DISPATCH_SIZE) & 0x07ff;
|
||||
fragtag = GETINT16(fragptr, RIME_FRAG_TAG);
|
||||
fragsize = GETHOST16(fragptr, SIXLOWPAN_FRAG_DISPATCH_SIZE) & 0x07ff;
|
||||
fragtag = GETHOST16(fragptr, SIXLOWPAN_FRAG_TAG);
|
||||
g_frame_hdrlen += SIXLOWPAN_FRAG1_HDR_LEN;
|
||||
|
||||
ninfo("FRAG1: fragsize=%d fragtag=%d fragoffset=%d\n",
|
||||
@ -403,9 +369,9 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
|
||||
{
|
||||
/* Set offset, tag, size. Offset is in units of 8 bytes. */
|
||||
|
||||
fragoffset = fragptr[RIME_FRAG_OFFSET];
|
||||
fragtag = GETINT16(fragptr, RIME_FRAG_TAG);
|
||||
fragsize = GETINT16(fragptr, RIME_FRAG_DISPATCH_SIZE) & 0x07ff;
|
||||
fragoffset = fragptr[SIXLOWPAN_FRAG_OFFSET];
|
||||
fragtag = GETHOST16(fragptr, SIXLOWPAN_FRAG_TAG);
|
||||
fragsize = GETHOST16(fragptr, SIXLOWPAN_FRAG_DISPATCH_SIZE) & 0x07ff;
|
||||
g_frame_hdrlen += SIXLOWPAN_FRAGN_HDR_LEN;
|
||||
|
||||
ninfo("FRAGN: fragsize=%d fragtag=%d fragoffset=%d\n",
|
||||
@ -487,8 +453,8 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
|
||||
|
||||
/* Verify that this fragment is part of that reassembly sequence */
|
||||
|
||||
else if (fragsize != ieee->i_pktlen || ieee->i_reasstag != fragtag ||
|
||||
!rimeaddr_cmp(&ieee->i_fragsrc, &g_pktaddrs[PACKETBUF_ADDR_SENDER]))
|
||||
else if (fragsize != ieee->i_pktlen || ieee->i_reasstag != fragtag ||
|
||||
!sixlowpan_compare_fragsrc(ieee, ind))
|
||||
{
|
||||
/* The packet is a fragment that does not belong to the packet
|
||||
* being reassembled or the packet is not a fragment.
|
||||
@ -540,7 +506,21 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
|
||||
ninfo("Starting reassembly: i_pktlen %u, i_reasstag %d\n",
|
||||
ieee->i_pktlen, ieee->i_reasstag);
|
||||
|
||||
rimeaddr_copy(&ieee->i_fragsrc, &g_pktaddrs[PACKETBUF_ADDR_SENDER]);
|
||||
/* Extract the source address from the 'ind' meta data. NOTE that the
|
||||
* size of the source address may be different that our local, destination
|
||||
* address.
|
||||
*/
|
||||
|
||||
if (ind->src.mode == IEEE802154_ADDRMODE_EXTENDED)
|
||||
{
|
||||
ieee->i_fragsrc.extended = true;
|
||||
sixlowpan_eaddrcopy(ieee->i_fragsrc.u.eaddr.u8, ind->src.eaddr);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(&ieee->i_fragsrc, 0, sizeof(struct sixlowpan_tagaddr_s));
|
||||
sixlowpan_saddrcopy(ieee->i_fragsrc.u.saddr.u8, &ind->src.saddr);
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_NET_6LOWPAN_FRAG */
|
||||
|
||||
@ -549,7 +529,7 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
|
||||
hc1 = fptr + g_frame_hdrlen;
|
||||
|
||||
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06
|
||||
if ((hc1[RIME_HC1_DISPATCH] & SIXLOWPAN_DISPATCH_IPHC_MASK) == SIXLOWPAN_DISPATCH_IPHC)
|
||||
if ((hc1[SIXLOWPAN_HC1_DISPATCH] & SIXLOWPAN_DISPATCH_IPHC_MASK) == SIXLOWPAN_DISPATCH_IPHC)
|
||||
{
|
||||
ninfo("IPHC Dispatch\n");
|
||||
sixlowpan_uncompresshdr_hc06(fragsize, iob, fptr, bptr);
|
||||
@ -558,7 +538,7 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
|
||||
#endif /* CONFIG_NET_6LOWPAN_COMPRESSION_HC06 */
|
||||
|
||||
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC1
|
||||
if (hc1[RIME_HC1_DISPATCH] == SIXLOWPAN_DISPATCH_HC1)
|
||||
if (hc1[SIXLOWPAN_HC1_DISPATCH] == SIXLOWPAN_DISPATCH_HC1)
|
||||
{
|
||||
ninfo("HC1 Dispatch\n");
|
||||
sixlowpan_uncompresshdr_hc1(fragsize, iob, fptr, bptr);
|
||||
@ -566,7 +546,7 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
|
||||
else
|
||||
#endif /* CONFIG_NET_6LOWPAN_COMPRESSION_HC1 */
|
||||
|
||||
if (hc1[RIME_HC1_DISPATCH] == SIXLOWPAN_DISPATCH_IPV6)
|
||||
if (hc1[SIXLOWPAN_HC1_DISPATCH] == SIXLOWPAN_DISPATCH_IPV6)
|
||||
{
|
||||
ninfo("IPv6 Dispatch\n");
|
||||
sixlowpan_uncompress_ipv6hdr(fptr, bptr);
|
||||
@ -575,14 +555,13 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
|
||||
{
|
||||
/* Unknown or unsupported header */
|
||||
|
||||
nwarn("WARNING: Unknown dispatch: %u\n", hc1[RIME_HC1_DISPATCH]);
|
||||
nwarn("WARNING: Unknown dispatch: %u\n", hc1[SIXLOWPAN_HC1_DISPATCH]);
|
||||
return OK;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NET_6LOWPAN_FRAG
|
||||
/* Is this the first fragment is a sequence? */
|
||||
|
||||
|
||||
if (isfirstfrag)
|
||||
{
|
||||
/* Yes.. Remember the offset from the beginning of d_buf where we
|
||||
@ -603,12 +582,14 @@ 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 rime buffer to the IEEE802.15.4 MAC driver's
|
||||
* d_buf. If this frame is a first fragment or not part of a fragmented
|
||||
* packet, we have already copied the compressed headers, g_uncomp_hdrlen
|
||||
* and g_frame_hdrlen are non-zerio, fragoffset is.
|
||||
/* Copy "payload" from the frame buffer to the IEEE802.15.4 MAC driver's
|
||||
* packet buffer, d_buf. If this frame is a first fragment or not part of
|
||||
* a fragmented packet, we have already copied the compressed headers,
|
||||
* g_uncomp_hdrlen and g_frame_hdrlen are non-zerio, fragoffset is.
|
||||
*/
|
||||
|
||||
paysize = iob->io_len - g_frame_hdrlen;
|
||||
@ -729,25 +710,32 @@ static int sixlowpan_dispatch(FAR struct ieee802154_driver_s *ieee)
|
||||
* Description:
|
||||
* Process an incoming 6loWPAN frame.
|
||||
*
|
||||
* This function is called when the device driver has received a 6loWPAN
|
||||
* frame from the network. The frame from the device driver must be
|
||||
* provided in a IOB present in the i_framelist: The frame data is in the
|
||||
* IOB io_data[] buffer and the length of the frame is in the IOB io_len
|
||||
* field. Only a single IOB is expected in the i_framelist. This incoming
|
||||
* data will be processed one frame at a time.
|
||||
* This function is called when the device driver has received an
|
||||
* IEEE802.15.4 frame from the network. The frame from the device
|
||||
* driver must be provided in by the IOB frame argument of the
|
||||
* function call:
|
||||
*
|
||||
* An non-NULL d_buf of size CONFIG_NET_6LOWPAN_MTU must also be provided.
|
||||
* The frame will be decompressed and placed in the d_buf. Fragmented
|
||||
* packets will also be reassembled in the d_buf as they are received
|
||||
* (meaning for the driver, that two packet buffers are required: One for
|
||||
* reassembly of RX packets and one used for TX polling).
|
||||
* - The frame data is in the IOB io_data[] buffer,
|
||||
* - The length of the frame is in the IOB io_len field, and
|
||||
* - The offset past the IEEE802.15.4 MAC header is provided in the
|
||||
* io_offset field.
|
||||
*
|
||||
* After each frame is processed into d_buf, the IOB is removed and
|
||||
* deallocated. i_framelist will be nullified. If reassembly is
|
||||
* incomplete, this function will return to called with i_framelist
|
||||
* equal to NULL. The partially reassembled packet must be preserved by
|
||||
* the IEEE802.15.4 MAC and provided again when the next frame is
|
||||
* received.
|
||||
* The frame argument may refer to a single frame (a list of length one)
|
||||
* or may it be the head of a list of multiple frames.
|
||||
*
|
||||
* - The io_flink field points to the next frame in the list (if enable)
|
||||
* - The last frame in the list will have io_flink == NULL.
|
||||
*
|
||||
* An non-NULL d_buf of size CONFIG_NET_6LOWPAN_MTU + CONFIG_NET_GUARDSIZE
|
||||
* must also be provided. The frame will be decompressed and placed in
|
||||
* the d_buf. Fragmented packets will also be reassembled in the d_buf as
|
||||
* they are received (meaning for the driver, that two packet buffers are
|
||||
* required: One for reassembly of RX packets and one used for TX polling).
|
||||
*
|
||||
* After each frame is processed into d_buf, the IOB is deallocated. If
|
||||
* reassembly is incomplete, the partially reassembled packet must be
|
||||
* preserved by the IEEE802.15.4 MAC network drvier sand provided again
|
||||
* when the next frame is received.
|
||||
*
|
||||
* When the packet in the d_buf is fully reassembled, it will be provided
|
||||
* to the network as with any other received packet. d_len will be set
|
||||
@ -755,49 +743,52 @@ static int sixlowpan_dispatch(FAR struct ieee802154_driver_s *ieee)
|
||||
*
|
||||
* After the network processes the packet, d_len will be set to zero.
|
||||
* Network logic may also decide to send a response to the packet. In
|
||||
* that case, the outgoing network packet will be placed in d_buf the
|
||||
* d_buf and d_len will be set to a non-zero value. That case is handled
|
||||
* by this function.
|
||||
* that case, the outgoing network packet will be placed in d_buf and
|
||||
* d_len will be set to a non-zero value. That case is handled by this
|
||||
* function.
|
||||
*
|
||||
* If that case occurs, the packet will be converted to a list of
|
||||
* compressed and possibly fragmented frames in i_framelist as with other
|
||||
* TX operations.
|
||||
*
|
||||
* So from the standpoint of the IEEE802.15.4 MAC driver, there are two
|
||||
* possible results: (1) i_framelist is NULL meaning that the frame
|
||||
* was fully processed and freed, or (2) i_framelist is non-NULL meaning
|
||||
* that there are outgoing frame(s) to be sent.
|
||||
* compressed and possibly fragmented frames and provided to the MAC
|
||||
* network driver via the req_data() method as with other TX operations.
|
||||
*
|
||||
* Input Parameters:
|
||||
* ieee - The IEEE802.15.4 MAC network driver interface.
|
||||
* ieee - The IEEE802.15.4 MAC network driver interface.
|
||||
* framelist - The head of an incoming list of frames. Normally this
|
||||
* would be a single frame. A list may be provided if
|
||||
* appropriate, however.
|
||||
* ind - Meta data characterizing the received frame. If there are
|
||||
* multilple frames in the list, this meta data must apply to
|
||||
* all of the frames!
|
||||
*
|
||||
* Returned Value:
|
||||
* Ok is returned on success; Othewise a negated errno value is returned.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sixlowpan_input(FAR struct ieee802154_driver_s *ieee)
|
||||
int sixlowpan_input(FAR struct ieee802154_driver_s *ieee,
|
||||
FAR struct iob_s *framelist,
|
||||
FAR const struct ieee802154_data_ind_s *ind)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
|
||||
DEBUGASSERT(ieee != NULL && !FRAME_IOB_EMPTY(ieee));
|
||||
DEBUGASSERT(ieee != NULL && framelist != NULL);
|
||||
|
||||
/* Verify that an IOB is provided in the device structure */
|
||||
/* Verify that an frame has been provided. */
|
||||
|
||||
while (!FRAME_IOB_EMPTY(ieee))
|
||||
while (framelist != NULL)
|
||||
{
|
||||
FAR struct iob_s *iob;
|
||||
|
||||
/* Remove the IOB containing the frame from the device structure */
|
||||
|
||||
FRAME_IOB_REMOVE(ieee, iob);
|
||||
DEBUGASSERT(iob != NULL);
|
||||
iob = framelist;
|
||||
framelist = iob->io_flink;
|
||||
|
||||
sixlowpan_dumpbuffer("Incoming frame", iob->io_data, iob->io_len);
|
||||
|
||||
/* Process the frame, decompressing it into the packet buffer */
|
||||
|
||||
ret = sixlowpan_frame_process(ieee, iob);
|
||||
ret = sixlowpan_frame_process(ieee, ind, iob);
|
||||
|
||||
/* Free the IOB the held the consumed frame */
|
||||
|
||||
@ -822,7 +813,7 @@ int sixlowpan_input(FAR struct ieee802154_driver_s *ieee)
|
||||
{
|
||||
FAR struct ipv6_hdr_s *ipv6hdr;
|
||||
FAR uint8_t *buffer;
|
||||
struct rimeaddr_s destmac;
|
||||
struct sixlowpan_tagaddr_s destmac;
|
||||
size_t hdrlen;
|
||||
size_t buflen;
|
||||
|
||||
@ -833,12 +824,12 @@ int sixlowpan_input(FAR struct ieee802154_driver_s *ieee)
|
||||
|
||||
ipv6hdr = IPv6BUF(&ieee->i_dev);
|
||||
|
||||
/* Get the Rime MAC address of the destination. This
|
||||
* assumes an encoding of the MAC address in the IPv6
|
||||
/* Get the IEEE 802.15.4 MAC address of the destination.
|
||||
* This assumes an encoding of the MAC address in the IPv6
|
||||
* address.
|
||||
*/
|
||||
|
||||
sixlowpan_rimefromip(ipv6hdr->destipaddr, &destmac);
|
||||
sixlowpan_addrfromip(ipv6hdr->destipaddr, &destmac);
|
||||
|
||||
/* The data payload should follow the IPv6 header plus
|
||||
* the protocol header.
|
||||
|
@ -71,79 +71,50 @@
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Rime addres macros */
|
||||
/* Copy a Rime address */
|
||||
/* IEEE 802.15.4 addres macros */
|
||||
/* Copy a an IEEE 802.15.4 address */
|
||||
|
||||
#define rimeaddr_copy(dest,src) \
|
||||
memcpy(dest, src, NET_6LOWPAN_RIMEADDR_SIZE)
|
||||
#define sixlowpan_anyaddrcopy(dest,src,len) \
|
||||
memcpy(dest, src, len)
|
||||
|
||||
/* Compare two Rime addresses */
|
||||
#define sixlowpan_saddrcopy(dest,src) \
|
||||
sixlowpan_anyaddrcopy(dest,src,NET_6LOWPAN_SADDRSIZE)
|
||||
|
||||
#define rimeaddr_cmp(addr1,addr2) \
|
||||
(memcmp(addr1, addr2, NET_6LOWPAN_RIMEADDR_SIZE) == 0)
|
||||
#define sixlowpan_eaddrcopy(dest,src) \
|
||||
sixlowpan_anyaddrcopy(dest,src,NET_6LOWPAN_EADDRSIZE)
|
||||
|
||||
/* Pointers in the Rime buffer */
|
||||
#define sixlowpan_addrcopy(dest,src) \
|
||||
sixlowpan_anyaddrcopy(dest,src,NET_6LOWPAN_ADDRSIZE)
|
||||
|
||||
/* Packet buffer Definitions */
|
||||
/* Compare two IEEE 802.15.4 addresses */
|
||||
|
||||
#define PACKETBUF_ATTR_PACKET_TYPE_DATA 0
|
||||
#define PACKETBUF_ATTR_PACKET_TYPE_ACK 1
|
||||
#define PACKETBUF_ATTR_PACKET_TYPE_STREAM 2
|
||||
#define PACKETBUF_ATTR_PACKET_TYPE_STREAM_END 3
|
||||
#define PACKETBUF_ATTR_PACKET_TYPE_TIMESTAMP 4
|
||||
#define sixlowpan_anyaddrcmp(addr1,addr2,len) \
|
||||
(memcmp(addr1, addr2, len) == 0)
|
||||
|
||||
/* Packet buffer attributes (indices into g_pktattrs) */
|
||||
#define sixlowpan_saddrcmp(addr1,addr2) \
|
||||
sixlowpan_anyaddrcmp(addr1,addr2,NET_6LOWPAN_SADDRSIZE)
|
||||
|
||||
#define PACKETBUF_ATTR_NONE 0
|
||||
#define sixlowpan_eaddrcmp(addr1,addr2) \
|
||||
sixlowpan_anyaddrcmp(addr1,addr2,NET_6LOWPAN_EADDRSIZE)
|
||||
|
||||
/* Scope 0 attributes: used only on the local node. */
|
||||
|
||||
#define PACKETBUF_ATTR_CHANNEL 1
|
||||
#define PACKETBUF_ATTR_NETWORK_ID 2
|
||||
#define PACKETBUF_ATTR_LINK_QUALITY 3
|
||||
#define PACKETBUF_ATTR_RSSI 4
|
||||
#define PACKETBUF_ATTR_TIMESTAMP 5
|
||||
#define PACKETBUF_ATTR_RADIO_TXPOWER 6
|
||||
#define PACKETBUF_ATTR_LISTEN_TIME 7
|
||||
#define PACKETBUF_ATTR_TRANSMIT_TIME 8
|
||||
#define PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS 9
|
||||
#define PACKETBUF_ATTR_MAC_SEQNO 10
|
||||
#define PACKETBUF_ATTR_MAC_ACK 11
|
||||
|
||||
/* Scope 1 attributes: used between two neighbors only. */
|
||||
|
||||
#define PACKETBUF_ATTR_RELIABLE 12
|
||||
#define PACKETBUF_ATTR_PACKET_ID 13
|
||||
#define PACKETBUF_ATTR_PACKET_TYPE 14
|
||||
#define PACKETBUF_ATTR_REXMIT 15
|
||||
#define PACKETBUF_ATTR_MAX_REXMIT 16
|
||||
#define PACKETBUF_ATTR_NUM_REXMIT 17
|
||||
#define PACKETBUF_ATTR_PENDING 18
|
||||
|
||||
/* Scope 2 attributes: used between end-to-end nodes. */
|
||||
|
||||
#define PACKETBUF_ATTR_HOPS 11
|
||||
#define PACKETBUF_ATTR_TTL 20
|
||||
#define PACKETBUF_ATTR_EPACKET_ID 21
|
||||
#define PACKETBUF_ATTR_EPACKET_TYPE 22
|
||||
#define PACKETBUF_ATTR_ERELIABLE 23
|
||||
|
||||
#define PACKETBUF_NUM_ATTRS 24
|
||||
|
||||
/* Addresses (indices into g_pktaddrs) */
|
||||
|
||||
#define PACKETBUF_ADDR_SENDER 0
|
||||
#define PACKETBUF_ADDR_RECEIVER 1
|
||||
#define PACKETBUF_ADDR_ESENDER 2
|
||||
#define PACKETBUF_ADDR_ERECEIVER 3
|
||||
|
||||
#define PACKETBUF_NUM_ADDRS 4
|
||||
#define sixlowpan_addrcmp(addr1,addr2) \
|
||||
sixlowpan_anyaddrcmp(addr1,addr2,NET_6LOWPAN_ADDRSIZE)
|
||||
|
||||
/* General helper macros ****************************************************/
|
||||
|
||||
#define GETINT16(ptr,index) \
|
||||
/* 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]))))
|
||||
#define PUTINT16(ptr,index,value) \
|
||||
|
||||
/* 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; \
|
||||
@ -163,7 +134,9 @@
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/* IPv^ TCP/UDP Definitions *************************************************/
|
||||
/* IPv6 TCP/UDP/ICMPv6 Definitions ******************************************/
|
||||
|
||||
#ifdef CONFIG_NET_TCP
|
||||
/* IPv6 + TCP header. Cast compatible based on IPv6 protocol field. */
|
||||
|
||||
struct ipv6tcp_hdr_s
|
||||
@ -171,7 +144,9 @@ struct ipv6tcp_hdr_s
|
||||
struct ipv6_hdr_s ipv6;
|
||||
struct tcp_hdr_s tcp;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_UDP
|
||||
/* IPv6 + UDP header */
|
||||
|
||||
struct ipv6udp_hdr_s
|
||||
@ -179,7 +154,9 @@ struct ipv6udp_hdr_s
|
||||
struct ipv6_hdr_s ipv6;
|
||||
struct udp_hdr_s udp;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_ICMPv6
|
||||
/* IPv6 + ICMPv6 header */
|
||||
|
||||
struct ipv6icmp_hdr_s
|
||||
@ -187,68 +164,28 @@ struct ipv6icmp_hdr_s
|
||||
struct ipv6_hdr_s ipv6;
|
||||
struct icmpv6_iphdr_s icmp;
|
||||
};
|
||||
#endif
|
||||
|
||||
/* IEEE802.15.4 Frame Definitions *******************************************/
|
||||
/* The IEEE 802.15.4 frame has a number of constant/fixed fields that can be
|
||||
* counted to make frame construction and max payload calculations easier.
|
||||
* These include:
|
||||
/* In order to provide a customizable IEEE 802.15.4 MAC header, a structure
|
||||
* of meta data is passed to the MAC network driver, struct
|
||||
* ieee802154_frame_meta_s. Many of the settings in this meta data are
|
||||
* fixed, deterimined by the 6loWPAN configuration. Other settings depend
|
||||
* on the protocol used in the current packet or on chacteristics of the
|
||||
* destination node.
|
||||
*
|
||||
* 1. FCF - 2 bytes - Fixed
|
||||
* 2. Sequence number - 1 byte - Fixed
|
||||
* 3. Addressing fields - 4 - 20 bytes - Variable
|
||||
* 4. Aux security header - 0 - 14 bytes - Variable
|
||||
* 5. CRC - 2 bytes - Fixed
|
||||
*/
|
||||
|
||||
/* Defines the bitfields of the frame control field (FCF). */
|
||||
|
||||
struct frame802154_fcf_s
|
||||
{
|
||||
uint8_t frame_type; /* 3 bit. Frame type field, see 802.15.4 */
|
||||
uint8_t security_enabled; /* 1 bit. True if security is used in this frame */
|
||||
uint8_t frame_pending; /* 1 bit. True if sender has more data to send */
|
||||
uint8_t ack_required; /* 1 bit. Is an ack frame required? */
|
||||
uint8_t panid_compression; /* 1 bit. Is this a compressed header? */
|
||||
/* 3 bit. Unused bits */
|
||||
uint8_t dest_addr_mode; /* 2 bit. Destination address mode, see 802.15.4 */
|
||||
uint8_t frame_version; /* 2 bit. 802.15.4 frame version */
|
||||
uint8_t src_addr_mode; /* 2 bit. Source address mode, see 802.15.4 */
|
||||
};
|
||||
|
||||
/* 802.15.4 security control bitfield. See section 7.6.2.2.1 in 802.15.4
|
||||
* specification.
|
||||
* The following structure is used to summarize those per-packet
|
||||
* customizations and, along, with the fixed configuratin settings,
|
||||
* determines the full form of that meta data.
|
||||
*/
|
||||
|
||||
struct frame802154_scf_s
|
||||
struct packet_metadata_s
|
||||
{
|
||||
uint8_t security_level; /* 3 bit. security level */
|
||||
uint8_t key_id_mode; /* 2 bit. Key identifier mode */
|
||||
uint8_t reserved; /* 3 bit. Reserved bits */
|
||||
};
|
||||
|
||||
/* 802.15.4 Aux security header */
|
||||
|
||||
struct frame802154_aux_hdr_s
|
||||
{
|
||||
struct frame802154_scf_s security_control; /* Security control bitfield */
|
||||
uint32_t frame_counter; /* Frame counter, used for security */
|
||||
uint8_t key[9]; /* The key itself, or an index to the key */
|
||||
};
|
||||
|
||||
/* Parameters used by the frame802154_create() function. These parameters
|
||||
* are used in the 802.15.4 frame header. See the 802.15.4 specification
|
||||
* for details.
|
||||
*/
|
||||
|
||||
struct frame802154_s
|
||||
{
|
||||
struct frame802154_fcf_s fcf; /* Frame control field */
|
||||
uint8_t seq; /* Sequence number */
|
||||
uint16_t dest_pid; /* Destination PAN ID */
|
||||
uint8_t dest_addr[8]; /* Destination address */
|
||||
uint16_t src_pid; /* Source PAN ID */
|
||||
uint8_t src_addr[8]; /* Source address */
|
||||
struct frame802154_aux_hdr_s aux_hdr; /* Aux security header */
|
||||
uint8_t sextended : 1; /* Extended source address */
|
||||
uint8_t dextended : 1; /* Extended destination address */
|
||||
uint8_t xmits; /* Max MAC transmisstion */
|
||||
uint16_t dpanid; /* Destination PAN ID */
|
||||
union sixlowpan_anyaddr_u source; /* Source IEEE 802.15.4 address */
|
||||
union sixlowpan_anyaddr_u dest; /* Destination IEEE 802.15.4 address */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
@ -262,14 +199,6 @@ struct frame802154_s
|
||||
* during that processing
|
||||
*/
|
||||
|
||||
/* A pointer to the rime buffer.
|
||||
*
|
||||
* We initialize it to the beginning of the rime buffer, then access
|
||||
* different fields by updating the offset ieee->g_frame_hdrlen.
|
||||
*/
|
||||
|
||||
extern FAR uint8_t *g_rimeptr;
|
||||
|
||||
/* g_uncomp_hdrlen is the length of the headers before compression (if HC2
|
||||
* is used this includes the UDP header in addition to the IP header).
|
||||
*/
|
||||
@ -283,11 +212,6 @@ extern uint8_t g_uncomp_hdrlen;
|
||||
|
||||
extern uint8_t g_frame_hdrlen;
|
||||
|
||||
/* Packet buffer metadata: Attributes and addresses */
|
||||
|
||||
extern uint16_t g_pktattrs[PACKETBUF_NUM_ATTRS];
|
||||
extern struct rimeaddr_s g_pktaddrs[PACKETBUF_NUM_ADDRS];
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
@ -300,7 +224,7 @@ struct net_driver_s; /* Forward reference */
|
||||
struct ieee802154_driver_s; /* Forward reference */
|
||||
struct devif_callback_s; /* Forward reference */
|
||||
struct ipv6_hdr_s; /* Forward reference */
|
||||
struct rimeaddr_s; /* Forward reference */
|
||||
struct sixlowpan_addr_s; /* Forward reference */
|
||||
struct iob_s; /* Forward reference */
|
||||
|
||||
/****************************************************************************
|
||||
@ -313,16 +237,15 @@ struct iob_s; /* Forward reference */
|
||||
*
|
||||
* 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 put in ieee->i_framelist
|
||||
* and the entire list of frames will be delivered to the 802.15.4 MAC via
|
||||
* ieee->i_framelist.
|
||||
* fragmented. The resulting packet/fragments are submitted to the MAC
|
||||
* via the network driver i_req_data method.
|
||||
*
|
||||
* 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.
|
||||
* buf - Data to send
|
||||
* buflen - Length of data to send
|
||||
* len - Length of data to send
|
||||
* raddr - The MAC address of the destination
|
||||
* timeout - Send timeout in deciseconds
|
||||
*
|
||||
@ -340,11 +263,37 @@ struct iob_s; /* Forward reference */
|
||||
int sixlowpan_send(FAR struct net_driver_s *dev,
|
||||
FAR struct devif_callback_s **list,
|
||||
FAR const struct ipv6_hdr_s *ipv6hdr, FAR const void *buf,
|
||||
size_t buflen, FAR const struct rimeaddr_s *raddr,
|
||||
size_t len, FAR const struct sixlowpan_tagaddr_s *destmac,
|
||||
uint16_t timeout);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sixlowpan_send_hdrlen
|
||||
* Name: sixlowpan_meta_data
|
||||
*
|
||||
* Description:
|
||||
* Based on the collected attributes and addresses, construct the MAC meta
|
||||
* data structure that we need to interface with the IEEE802.15.4 MAC.
|
||||
*
|
||||
* Input Parameters:
|
||||
* ieee - IEEE 802.15.4 MAC driver state reference.
|
||||
* pktmeta - Meta-data specific to the current outgoing frame
|
||||
* meta - Location to return the corresponding meta data.
|
||||
* paylen - The size of the data payload to be sent.
|
||||
*
|
||||
* Returned Value:
|
||||
* Ok is returned on success; Othewise a negated errno value is returned.
|
||||
*
|
||||
* Assumptions:
|
||||
* Called with the network locked.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sixlowpan_meta_data(FAR struct ieee802154_driver_s *ieee,
|
||||
FAR const struct packet_metadata_s *pktmeta,
|
||||
FAR struct ieee802154_frame_meta_s *meta,
|
||||
uint16_t paylen);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sixlowpan_frame_hdrlen
|
||||
*
|
||||
* Description:
|
||||
* This function is before the first frame has been sent in order to
|
||||
@ -352,9 +301,8 @@ int sixlowpan_send(FAR struct net_driver_s *dev,
|
||||
* buffer is required to make this determination.
|
||||
*
|
||||
* Input parameters:
|
||||
* ieee - A reference IEEE802.15.4 MAC network device structure.
|
||||
* dest_panid - PAN ID of the destination. May be 0xffff if the destination
|
||||
* is not associated.
|
||||
* ieee - A reference IEEE802.15.4 MAC network device structure.
|
||||
* meta - Meta data that describes the MAC header
|
||||
*
|
||||
* Returned Value:
|
||||
* The frame header length is returnd on success; otherwise, a negated
|
||||
@ -362,30 +310,32 @@ int sixlowpan_send(FAR struct net_driver_s *dev,
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sixlowpan_send_hdrlen(FAR struct ieee802154_driver_s *ieee,
|
||||
uint16_t dest_panid);
|
||||
int sixlowpan_frame_hdrlen(FAR struct ieee802154_driver_s *ieee,
|
||||
FAR const struct ieee802154_frame_meta_s *meta);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sixlowpan_framecreate
|
||||
* Name: sixlowpan_frame_submit
|
||||
*
|
||||
* Description:
|
||||
* This function is called after the IEEE802.15.4 MAC driver polls for
|
||||
* TX data. It creates the IEEE802.15.4 header in the frame buffer.
|
||||
* This function is called after eiether (1) the IEEE802.15.4 MAC driver
|
||||
* polls for TX data or (2) after the IEEE802.15.4 MAC driver provides a
|
||||
* new incoming frame and the network responds with an outgoing packet. It
|
||||
* submits any new outgoing frame to the MAC.
|
||||
*
|
||||
* Input parameters:
|
||||
* ieee - A reference IEEE802.15.4 MAC network device structure.
|
||||
* iob - The IOB in which to create the frame.
|
||||
* dest_panid - PAN ID of the destination. May be 0xffff if the destination
|
||||
* is not associated.
|
||||
* ieee - A reference IEEE802.15.4 MAC network device structure.
|
||||
* meta - Meta data that describes the MAC header
|
||||
* frame - The IOB containing the frame to be submitted.
|
||||
*
|
||||
* Returned Value:
|
||||
* The frame header length is returnd on success; otherwise, a negated
|
||||
* errno value is return on failure.
|
||||
* Zero (OK) is returned on success; otherwise, a negated errno value is
|
||||
* return on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sixlowpan_framecreate(FAR struct ieee802154_driver_s *ieee,
|
||||
FAR struct iob_s *iob, uint16_t dest_panid);
|
||||
int sixlowpan_frame_submit(FAR struct ieee802154_driver_s *ieee,
|
||||
FAR const struct ieee802154_frame_meta_s *meta,
|
||||
FAR struct iob_s *frame);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sixlowpan_queue_frames
|
||||
@ -397,9 +347,8 @@ int sixlowpan_framecreate(FAR struct ieee802154_driver_s *ieee,
|
||||
*
|
||||
* 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 put in ieee->i_framelist
|
||||
* and the entire list of frames will be delivered to the 802.15.4 MAC via
|
||||
* ieee->i_framelist.
|
||||
* fragmented. The resulting packet/fragments are submitted to the MAC
|
||||
* via the network driver i_req_data method.
|
||||
*
|
||||
* Input Parameters:
|
||||
* ieee - The IEEE802.15.4 MAC driver instance
|
||||
@ -423,7 +372,7 @@ int sixlowpan_framecreate(FAR struct ieee802154_driver_s *ieee,
|
||||
int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
|
||||
FAR const struct ipv6_hdr_s *ipv6hdr,
|
||||
FAR const void *buf, size_t buflen,
|
||||
FAR const struct rimeaddr_s *destmac);
|
||||
FAR const struct sixlowpan_tagaddr_s *destmac);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sixlowpan_hc06_initialize
|
||||
@ -479,7 +428,7 @@ void sixlowpan_hc06_initialize(void);
|
||||
#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 rimeaddr_s *destmac,
|
||||
FAR const struct sixlowpan_tagaddr_s *destmac,
|
||||
FAR uint8_t *fptr);
|
||||
#endif
|
||||
|
||||
@ -491,8 +440,8 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
|
||||
* sixlowpan_buf
|
||||
*
|
||||
* This function is called by the input function when the dispatch is HC06.
|
||||
* We process the packet in the rime buffer, uncompress the header fields,
|
||||
* and copy the result in the sixlowpan buffer. At the end of the
|
||||
* We process the frame in the IOB buffer, uncompress the header fields,
|
||||
* and copy the result into the driver packet buffer. At the end of the
|
||||
* decompression, g_frame_hdrlen and g_uncompressed_hdrlen are set to the
|
||||
* appropriate values
|
||||
*
|
||||
@ -540,7 +489,7 @@ void sixlowpan_uncompresshdr_hc06(uint16_t iplen, FAR struct iob_s *iob,
|
||||
#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 rimeaddr_s *destmac,
|
||||
FAR const struct sixlowpan_tagaddr_s *destmac,
|
||||
FAR uint8_t *fptr);
|
||||
#endif
|
||||
|
||||
@ -551,8 +500,8 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
|
||||
* Uncompress HC1 (and HC_UDP) headers and put them in sixlowpan_buf
|
||||
*
|
||||
* This function is called by the input function when the dispatch is
|
||||
* HC1. It processes the packet in the rime buffer, uncompresses the
|
||||
* header fields, and copies the result in the sixlowpan buffer. At the
|
||||
* HC1. It processes the frame in the IOB buffer, uncompresses the
|
||||
* header fields, and copies the result in the packet buffer. At the
|
||||
* end of the decompression, g_frame_hdrlen and uncompressed_hdr_len
|
||||
* are set to the appropriate values
|
||||
*
|
||||
@ -577,34 +526,72 @@ int sixlowpan_uncompresshdr_hc1(uint16_t iplen, FAR struct iob_s *iob,
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sixlowpan_islinklocal, sixlowpan_ipfromrime, sixlowpan_rimefromip,
|
||||
* and sixlowpan_ismacbased
|
||||
* Name: sixlowpan_islinklocal, sixlowpan_addrfromip, and
|
||||
* sixlowpan_ismacbased
|
||||
*
|
||||
* Description:
|
||||
* sixlowpan_ipfromrime: Create a link local IPv6 address from a rime
|
||||
* address.
|
||||
* 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_rimefromip: Extract the rime address from a link local IPv6
|
||||
* address.
|
||||
*
|
||||
* sixlowpan_islinklocal and sixlowpan_ismacbased will return true for
|
||||
* address created in this fashion.
|
||||
* sixlowpan_islinklocal() and sixlowpan_ismacbased() will return true for
|
||||
* address created in this fashion. sixlowpan_addrfromip() is intended to
|
||||
* handle a tagged address or any size; sixlowpan_issaddrbased() and
|
||||
* sixlowpan_iseaddrbased() specifically handle short and extended
|
||||
* addresses. Local addresses are of a fixed but configurable size and
|
||||
* sixlowpan_isaddrbased() is for use with such local addresses.
|
||||
*
|
||||
* 128 112 96 80 64 48 32 16
|
||||
* ---- ---- ---- ---- ---- ---- ---- ----
|
||||
* fe80 0000 0000 0000 xxxx 0000 0000 0000 2-byte Rime address (VALID?)
|
||||
* fe80 0000 0000 0000 xxxx xxxx xxxx xxxx 8-byte Rime address
|
||||
* 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
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#define sixlowpan_islinklocal(ipaddr) ((ipaddr)[0] == NTOHS(0xfe80))
|
||||
|
||||
void sixlowpan_ipfromrime(FAR const struct rimeaddr_s *rime,
|
||||
net_ipv6addr_t ipaddr);
|
||||
void sixlowpan_rimefromip(const net_ipv6addr_t ipaddr,
|
||||
FAR struct rimeaddr_s *rime);
|
||||
bool sixlowpan_ismacbased(const net_ipv6addr_t ipaddr,
|
||||
FAR const struct rimeaddr_s *rime);
|
||||
void sixlowpan_saddrfromip(const net_ipv6addr_t ipaddr,
|
||||
FAR struct sixlowpan_saddr_s *saddr);
|
||||
void sixlowpan_eaddrfromip(const net_ipv6addr_t ipaddr,
|
||||
FAR struct sixlowpan_eaddr_s *eaddr);
|
||||
void sixlowpan_addrfromip(const net_ipv6addr_t ipaddr,
|
||||
FAR struct sixlowpan_tagaddr_s *addr);
|
||||
|
||||
bool sixlowpan_issaddrbased(const net_ipv6addr_t ipaddr,
|
||||
FAR const struct sixlowpan_saddr_s *saddr);
|
||||
bool sixlowpan_iseaddrbased(const net_ipv6addr_t ipaddr,
|
||||
FAR const struct sixlowpan_eaddr_s *eaddr);
|
||||
|
||||
#ifdef CONFIG_NET_6LOWPAN_EXTENDEDADDR
|
||||
# define sixlowpan_isaddrbased(ipaddr,addr) \
|
||||
sixlowpan_iseaddrbased(ipaddr,(FAR struct sixlowpan_eaddr_s *)addr)
|
||||
#else
|
||||
# define sixlowpan_isaddrbased(ipaddr,addr) \
|
||||
sixlowpan_issaddrbased(ipaddr,(FAR struct sixlowpan_saddr_s *)addr)
|
||||
#endif
|
||||
|
||||
bool sixlowpan_ismacbased(const net_ipv6addr_t ipaddr,
|
||||
FAR const struct sixlowpan_tagaddr_s *addr);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sixlowpan_src_panid
|
||||
*
|
||||
* Description:
|
||||
* Get the source PAN ID from the IEEE802.15.4 radio.
|
||||
*
|
||||
* Input parameters:
|
||||
* ieee - A reference IEEE802.15.4 MAC network device structure.
|
||||
* panid - The location in which to return the PAN ID. 0xfff may be
|
||||
* returned if the device is not associated.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sixlowpan_src_panid(FAR struct ieee802154_driver_s *ieee,
|
||||
FAR uint16_t *panid);
|
||||
#endif /* CONFIG_NET_6LOWPAN */
|
||||
#endif /* _NET_SIXLOWPAN_SIXLOWPAN_INTERNAL_H */
|
||||
|
@ -83,7 +83,7 @@ struct sixlowpan_send_s
|
||||
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 rimeaddr_s *s_destmac; /* Destination MAC address */
|
||||
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 */
|
||||
};
|
||||
@ -246,11 +246,10 @@ end_wait:
|
||||
* it to be sent on an 802.15.4 network using 6lowpan. Called from common
|
||||
* UDP/TCP send logic.
|
||||
*
|
||||
* The payload data is in the caller 'buf' and is of length 'len'.
|
||||
* 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 put in ieee->i_framelist
|
||||
* and the entire list of frames will be delivered to the 802.15.4 MAC via
|
||||
* ieee->i_framelist.
|
||||
* fragmented. The resulting packet/fragments are submitted to the MAC
|
||||
* via the network driver i_req_data method.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - The IEEE802.15.4 MAC network driver interface.
|
||||
@ -275,7 +274,7 @@ end_wait:
|
||||
int sixlowpan_send(FAR struct net_driver_s *dev,
|
||||
FAR struct devif_callback_s **list,
|
||||
FAR const struct ipv6_hdr_s *ipv6hdr, FAR const void *buf,
|
||||
size_t len, FAR const struct rimeaddr_s *destmac,
|
||||
size_t len, FAR const struct sixlowpan_tagaddr_s *destmac,
|
||||
uint16_t timeout)
|
||||
{
|
||||
struct sixlowpan_send_s sinfo;
|
||||
|
@ -164,7 +164,7 @@ 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 rimeaddr_s destmac;
|
||||
struct sixlowpan_tagaddr_s destmac;
|
||||
uint16_t timeout;
|
||||
uint16_t iplen;
|
||||
int ret;
|
||||
@ -317,11 +317,11 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf,
|
||||
|
||||
psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_SEND);
|
||||
|
||||
/* Get the Rime MAC address of the destination This assumes an encoding
|
||||
* of the MAC address in the IPv6 address.
|
||||
/* Get the IEEE 802.15.4 MAC address of the destination. This assumes
|
||||
* an encoding of the MAC address in the IPv6 address.
|
||||
*/
|
||||
|
||||
sixlowpan_rimefromip(conn->u.ipv6.raddr, &destmac);
|
||||
sixlowpan_addrfromip(conn->u.ipv6.raddr, &destmac);
|
||||
|
||||
/* If routable, then call sixlowpan_send() to format and send the 6loWPAN
|
||||
* packet.
|
||||
@ -409,16 +409,16 @@ void sixlowpan_tcp_send(FAR struct net_driver_s *dev)
|
||||
}
|
||||
else
|
||||
{
|
||||
struct rimeaddr_s destmac;
|
||||
struct sixlowpan_tagaddr_s destmac;
|
||||
FAR uint8_t *buf;
|
||||
uint16_t hdrlen;
|
||||
uint16_t buflen;
|
||||
|
||||
/* Get the Rime MAC address of the destination. This assumes an
|
||||
* encoding of the MAC address in the IPv6 address.
|
||||
/* Get the IEEE 802.15.4 MAC address of the destination. This
|
||||
* assumes an encoding of the MAC address in the IPv6 address.
|
||||
*/
|
||||
|
||||
sixlowpan_rimefromip(ipv6hdr->ipv6.destipaddr, &destmac);
|
||||
sixlowpan_addrfromip(ipv6hdr->ipv6.destipaddr, &destmac);
|
||||
|
||||
/* Get the IPv6 + TCP combined header length. The size of the TCP
|
||||
* header is encoded in the top 4 bits of the tcpoffset field (in
|
||||
|
@ -162,7 +162,7 @@ ssize_t psock_6lowpan_udp_sendto(FAR struct socket *psock,
|
||||
FAR struct udp_conn_s *conn;
|
||||
FAR struct net_driver_s *dev;
|
||||
struct ipv6udp_hdr_s ipv6udp;
|
||||
struct rimeaddr_s destmac;
|
||||
struct sixlowpan_tagaddr_s destmac;
|
||||
uint16_t iplen;
|
||||
uint16_t timeout;
|
||||
int ret;
|
||||
@ -292,11 +292,11 @@ ssize_t psock_6lowpan_udp_sendto(FAR struct socket *psock,
|
||||
|
||||
psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_SEND);
|
||||
|
||||
/* Get the Rime MAC address of the destination This assumes an encoding
|
||||
* of the MAC address in the IPv6 address.
|
||||
/* Get the IEEE 802.15.4 MAC address of the destination This assumes an
|
||||
* encoding of the MAC address in the IPv6 address.
|
||||
*/
|
||||
|
||||
sixlowpan_rimefromip(to6->sin6_addr.in6_u.u6_addr16, &destmac);
|
||||
sixlowpan_addrfromip(to6->sin6_addr.in6_u.u6_addr16, &destmac);
|
||||
|
||||
/* If routable, then call sixlowpan_send() to format and send the 6loWPAN
|
||||
* packet.
|
||||
|
@ -54,8 +54,10 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/net/sixlowpan.h>
|
||||
#include <nuttx/wireless/ieee802154/ieee802154_mac.h>
|
||||
|
||||
#include "sixlowpan/sixlowpan_internal.h"
|
||||
|
||||
@ -66,94 +68,144 @@
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sixlowpan_ipfromrime
|
||||
* Name: sixlowpan_addrfromip
|
||||
*
|
||||
* Description:
|
||||
* Create a link local IPv6 address from a rime address:
|
||||
* 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.
|
||||
*
|
||||
* 128 112 96 80 64 48 32 16
|
||||
* ---- ---- ---- ---- ---- ---- ---- ----
|
||||
* fe80 0000 0000 0000 0000 00ff fe00 xxxx 2-byte Rime address IEEE 48-bit MAC
|
||||
* fe80 0000 0000 0000 xxxx xxxx xxxx xxxx 8-byte Rime address IEEE EUI-64
|
||||
* xxxx 0000 0000 0000 0000 00ff fe00 xxxx 2-byte short address IEEE 48-bit MAC
|
||||
* xxxx 0000 0000 0000 xxxx xxxx xxxx xxxx 8-byte extended address IEEE EUI-64
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void sixlowpan_ipfromrime(FAR const struct rimeaddr_s *rime,
|
||||
net_ipv6addr_t ipaddr)
|
||||
void sixlowpan_saddrfromip(const net_ipv6addr_t ipaddr,
|
||||
FAR struct sixlowpan_saddr_s *saddr)
|
||||
{
|
||||
/* We consider only links with IEEE EUI-64 identifier or IEEE 48-bit MAC
|
||||
* addresses.
|
||||
*/
|
||||
|
||||
memset(ipaddr, 0, sizeof(net_ipv6addr_t));
|
||||
ipaddr[0] = HTONS(0xfe80);
|
||||
|
||||
#ifdef CONFIG_NET_6LOWPAN_RIMEADDR_EXTENDED
|
||||
memcpy(&ipaddr[4], rime, NET_6LOWPAN_RIMEADDR_SIZE);
|
||||
ipaddr[4] ^= HTONS(0x0200);
|
||||
#else
|
||||
ipaddr[5] = HTONS(0x00ff);
|
||||
ipaddr[6] = HTONS(0xfe00);
|
||||
memcpy(&ipaddr[7], rime, NET_6LOWPAN_RIMEADDR_SIZE);
|
||||
ipaddr[7] ^= HTONS(0x0200);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sixlowpan_rimefromip
|
||||
*
|
||||
* Description:
|
||||
* Extract the rime address from a link local IPv6 address:
|
||||
*
|
||||
* 128 112 96 80 64 48 32 16
|
||||
* ---- ---- ---- ---- ---- ---- ---- ----
|
||||
* fe80 0000 0000 0000 0000 00ff fe00 xxxx 2-byte Rime address IEEE 48-bit MAC
|
||||
* fe80 0000 0000 0000 xxxx xxxx xxxx xxxx 8-byte Rime address IEEE EUI-64
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void sixlowpan_rimefromip(const net_ipv6addr_t ipaddr,
|
||||
FAR struct rimeaddr_s *rime)
|
||||
{
|
||||
/* REVISIT: See notes about 2 byte addresses in sixlowpan_ipfromrime() */
|
||||
|
||||
DEBUGASSERT(ipaddr[0] == HTONS(0xfe80));
|
||||
|
||||
#ifdef CONFIG_NET_6LOWPAN_RIMEADDR_EXTENDED
|
||||
memcpy(rime, &ipaddr[4], NET_6LOWPAN_RIMEADDR_SIZE);
|
||||
#else
|
||||
memcpy(rime, &ipaddr[7], NET_6LOWPAN_RIMEADDR_SIZE);
|
||||
#endif
|
||||
rime->u8[0] ^= 0x02;
|
||||
memcpy(saddr, &ipaddr[7], NET_6LOWPAN_SADDRSIZE);
|
||||
saddr->u8[0] ^= 0x02;
|
||||
}
|
||||
|
||||
void sixlowpan_eaddrfromip(const net_ipv6addr_t ipaddr,
|
||||
FAR struct sixlowpan_eaddr_s *eaddr)
|
||||
{
|
||||
DEBUGASSERT(ipaddr[0] == HTONS(0xfe80));
|
||||
|
||||
memcpy(eaddr, &ipaddr[4], NET_6LOWPAN_EADDRSIZE);
|
||||
eaddr->u8[0] ^= 0x02;
|
||||
}
|
||||
|
||||
void sixlowpan_addrfromip(const net_ipv6addr_t ipaddr,
|
||||
FAR struct sixlowpan_tagaddr_s *addr)
|
||||
{
|
||||
DEBUGASSERT(ipaddr[0] == HTONS(0xfe80));
|
||||
|
||||
if (SIXLOWPAN_IS_IID_16BIT_COMPRESSABLE(ipaddr))
|
||||
{
|
||||
memset(addr, 0, sizeof(struct sixlowpan_tagaddr_s));
|
||||
sixlowpan_saddrfromip(ipaddr, &addr->u.saddr);
|
||||
}
|
||||
else
|
||||
{
|
||||
sixlowpan_eaddrfromip(ipaddr, &addr->u.eaddr);
|
||||
addr->extended = true;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sixlowpan_ismacbased
|
||||
*
|
||||
* Description:
|
||||
* Check if the MAC address is encoded in the IP address:
|
||||
* sixlowpan_ismacbased() will return true for IP addresses formed from
|
||||
* IEEE802.15.4 MAC addresses. sixlowpan_addrfromip() is intended to
|
||||
* handle a tagged address or any size; sixlowpan_issaddrbased() and
|
||||
* sixlowpan_iseaddrbased() specifically handle short and extended
|
||||
* addresses. Local addresses are of a fixed but configurable size and
|
||||
* sixlowpan_isaddrbased() is for use with such local addresses.
|
||||
*
|
||||
*
|
||||
* 128 112 96 80 64 48 32 16
|
||||
* ---- ---- ---- ---- ---- ---- ---- ----
|
||||
* fe80 0000 0000 0000 0000 00ff fe00 xxxx 2-byte Rime address IEEE 48-bit MAC
|
||||
* fe80 0000 0000 0000 xxxx xxxx xxxx xxxx 8-byte Rime address IEEE EUI-64
|
||||
* 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
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
bool sixlowpan_ismacbased(const net_ipv6addr_t ipaddr,
|
||||
FAR const struct rimeaddr_s *rime)
|
||||
bool sixlowpan_issaddrbased(const net_ipv6addr_t ipaddr,
|
||||
FAR const struct sixlowpan_saddr_s *saddr)
|
||||
{
|
||||
FAR const uint8_t *rimeptr = rime->u8;
|
||||
FAR const uint8_t *byteptr = saddr->u8;
|
||||
|
||||
#ifdef CONFIG_NET_6LOWPAN_RIMEADDR_EXTENDED
|
||||
return (ipaddr[4] == htons((GETINT16(rimeptr, 0) ^ 0x0200)) &&
|
||||
ipaddr[5] == GETINT16(rimeptr, 2) &&
|
||||
ipaddr[6] == GETINT16(rimeptr, 4) &&
|
||||
ipaddr[7] == GETINT16(rimeptr, 6));
|
||||
#else
|
||||
return (ipaddr[5] == HTONS(0x00ff) && ipaddr[6] == HTONS(0xfe00) &&
|
||||
ipaddr[7] == htons((GETINT16(rimeptr, 0) ^ 0x0200)));
|
||||
#endif
|
||||
ipaddr[7] == (GETNET16(byteptr, 0) ^ HTONS(0x0200)));
|
||||
}
|
||||
|
||||
bool sixlowpan_iseaddrbased(const net_ipv6addr_t ipaddr,
|
||||
FAR const struct sixlowpan_eaddr_s *eaddr)
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
bool sixlowpan_ismacbased(const net_ipv6addr_t ipaddr,
|
||||
FAR const struct sixlowpan_tagaddr_s *addr)
|
||||
{
|
||||
if (addr->extended)
|
||||
{
|
||||
return sixlowpan_iseaddrbased(ipaddr, &addr->u.eaddr);
|
||||
}
|
||||
else
|
||||
{
|
||||
return sixlowpan_issaddrbased(ipaddr, &addr->u.saddr);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sixlowpan_src_panid
|
||||
*
|
||||
* Description:
|
||||
* Get the source PAN ID from the IEEE802.15.4 MAC layer.
|
||||
*
|
||||
* Input parameters:
|
||||
* ieee - A reference IEEE802.15.4 MAC network device structure.
|
||||
* panid - The location in which to return the PAN ID. 0xfff may be
|
||||
* returned if the device is not associated.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sixlowpan_src_panid(FAR struct ieee802154_driver_s *ieee,
|
||||
FAR uint16_t *panid)
|
||||
{
|
||||
FAR struct net_driver_s *dev = &ieee->i_dev;
|
||||
struct ieee802154_netmac_s arg;
|
||||
int ret;
|
||||
|
||||
memcpy(arg.ifr_name, ieee->i_dev.d_ifname, IFNAMSIZ);
|
||||
arg.u.getreq.pib_attr = IEEE802154_PIB_MAC_PAN_ID;
|
||||
ret = dev->d_ioctl(dev, MAC802154IOC_MLME_GET_REQUEST,
|
||||
(unsigned long)((uintptr_t)&arg));
|
||||
if (ret < 0)
|
||||
{
|
||||
wlerr("ERROR: MAC802154IOC_MLME_GET_REQUEST failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
*panid = arg.u.getreq.attr_value.mac.panid;
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NET_6LOWPAN */
|
||||
|
@ -6,7 +6,6 @@
|
||||
config WIRELESS
|
||||
bool "Wireless Support"
|
||||
default n
|
||||
depends on EXPERIMENTAL
|
||||
---help---
|
||||
Enables overall support for Wireless library.
|
||||
|
||||
|
@ -52,14 +52,6 @@ VPATH = .
|
||||
|
||||
include ieee802154$(DELIM)Make.defs
|
||||
|
||||
# Include support for various drivers. Each Make.defs file will add its
|
||||
# files to the source file list, add its DEPPATH info, and will add
|
||||
# the appropriate paths to the VPATH variable
|
||||
|
||||
ifeq ($(CONFIG_WIRELESS_FORMAT_PCM),y)
|
||||
CSRCS += pcm_decode.c
|
||||
endif
|
||||
|
||||
AOBJS = $(ASRCS:.S=$(OBJEXT))
|
||||
COBJS = $(CSRCS:.c=$(OBJEXT))
|
||||
|
||||
|
@ -6,19 +6,128 @@
|
||||
config WIRELESS_IEEE802154
|
||||
bool "IEEE 802.15.4 Wireless Support"
|
||||
default n
|
||||
depends on EXPERIMENTAL
|
||||
select DRIVERS_IOB
|
||||
---help---
|
||||
Enables support for the IEEE 802.14.5 Wireless library.
|
||||
|
||||
if WIRELESS_IEEE802154
|
||||
|
||||
menuconfig IEEE802154_MAC
|
||||
bool "Generic Media Access Control (MAC) layer for 802.15.4 radios"
|
||||
default n
|
||||
depends on WIRELESS_IEEE802154
|
||||
---help---
|
||||
Enables a Media Access Controller for any IEEE802.15.4 radio
|
||||
device. This in turn can be used by higher layer entities
|
||||
such as 6lowpan. It is not required to use 802.15.4 radios,
|
||||
but is strongly suggested to ensure exchange of valid frames.
|
||||
|
||||
if IEEE802154_MAC
|
||||
|
||||
config IEEE802154_MAC_DEV
|
||||
bool "Character driver for IEEE 802.15.4 MAC layer"
|
||||
default n
|
||||
depends on IEEE802154_MAC
|
||||
---help---
|
||||
Enable the device driver to expose the IEEE 802.15.4 MAC layer
|
||||
access to user space as IOCTLs
|
||||
|
||||
choice
|
||||
prompt "IEEE 802.15.4 work queue"
|
||||
default MAC802154_LPWORK if SCHED_LPWORK
|
||||
default MAC802154_HPWORK if !SCHED_LPWORK && SCHED_HPWORK
|
||||
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
|
||||
the driver.
|
||||
|
||||
config MAC802154_HPWORK
|
||||
bool "High priority"
|
||||
depends on SCHED_HPWORK
|
||||
|
||||
config MAC802154_LPWORK
|
||||
bool "Low priority"
|
||||
depends on SCHED_LPWORK
|
||||
|
||||
endchoice # Work queue
|
||||
|
||||
config IEEE802154_NTXDESC
|
||||
int "Number or TX descriptors"
|
||||
default 3
|
||||
---help---
|
||||
Configured number of Tx descriptors. Default: 3
|
||||
|
||||
endif # IEEE802154_MAC
|
||||
|
||||
config IEEE802154_IND_PREALLOC
|
||||
int "Number of pre-allocated meta-data structures"
|
||||
default 20
|
||||
---help---
|
||||
This specifies the total number of preallocated meta data structures
|
||||
must be allocated with each incoming packet. These may be allocated
|
||||
from either from tasking logic or from interrupt level logic.
|
||||
|
||||
config IEEE802154_IND_IRQRESERVE
|
||||
int "Rserved pre-allocated meta-data structures"
|
||||
default 10
|
||||
---help---
|
||||
If meta-data structures can be allocated from interrupt handlers,
|
||||
then this specifies the number of pre-allocatd meta-data structures
|
||||
that are reserved for for use only by interrupt handlers. This may
|
||||
be zero to reserve no meta-data structures for interrupt handlers.
|
||||
In that case, the allocation will fail if tasking logic has
|
||||
allocated them all.
|
||||
|
||||
Interrupt logic will first attempt to allocate from the general,
|
||||
pre-allocated structure pool that will contain up to (size
|
||||
CONFIG_IEEE802154_IND_PREALLOC - CONFIG_IEEE802154_IND_IRQRESERVE)
|
||||
entries. If that fails, then it will try to take a structure from
|
||||
the reserve (size 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_NETDEV
|
||||
bool "IEEE802154 6loWPAN Network Device"
|
||||
default n
|
||||
depends on NET_6LOWPAN && NET_IPv6
|
||||
select ARCH_HAVE_NETDEV_STATISTICS
|
||||
---help---
|
||||
Add support for the IEEE802.15.4 6loWPAN network device built on
|
||||
the common IEEE802.15.4 MAC.
|
||||
|
||||
if IEEE802154_NETDEV
|
||||
|
||||
choice
|
||||
prompt "Work queue"
|
||||
default IEEE802154_NETDEV_LPWORK if SCHED_LPWORK
|
||||
default IEEE802154_NETDEV_HPWORK if !SCHED_LPWORK && SCHED_HPWORK
|
||||
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
|
||||
be used by the loopback driver.
|
||||
|
||||
config IEEE802154_NETDEV_HPWORK
|
||||
bool "High priority"
|
||||
depends on SCHED_HPWORK
|
||||
|
||||
config IEEE802154_NETDEV_LPWORK
|
||||
bool "Low priority"
|
||||
depends on SCHED_LPWORK
|
||||
|
||||
endchoice # Work queue
|
||||
endif # IEEE802154_NETDEV
|
||||
|
||||
config IEEE802154_LOOPBACK
|
||||
bool "IEEE802154 6loWPAN Loopback"
|
||||
default n
|
||||
depends on NET_6LOWPAN && NET_IPv6
|
||||
select ARCH_HAVE_NETDEV_STATISTICS
|
||||
---help---
|
||||
Add support for the IEEE802154 6loWPAN Loopback test device.
|
||||
Add support for the IEEE802.15.4 6loWPAN Loopback test device.
|
||||
|
||||
if IEEE802154_LOOPBACK
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
############################################################################
|
||||
# wireless/ieee802145/Make.defs
|
||||
#
|
||||
# Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
||||
# Copyright (C) 2016-2017 Gregory Nutt. All rights reserved.
|
||||
# Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@ -37,8 +37,26 @@ ifeq ($(CONFIG_WIRELESS_IEEE802154),y)
|
||||
|
||||
# Include IEEE 802.15.4 support
|
||||
|
||||
CSRCS += mac802154_indalloc.c
|
||||
|
||||
# Include wireless devices build support
|
||||
|
||||
ifeq ($(CONFIG_IEEE802154_MAC),y)
|
||||
CSRCS += mac802154.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_IEEE802154_MAC_DEV),y)
|
||||
CSRCS += mac802154_device.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_IEEE802154_DEV),y)
|
||||
CSRCS += radio802154_device.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_IEEE802154_NETDEV),y)
|
||||
CSRCS += mac802154_netdev.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_IEEE802154_LOOPBACK),y)
|
||||
CSRCS += mac802154_loopback.c
|
||||
endif
|
||||
|
1824
wireless/ieee802154/mac802154.c
Normal file
1824
wireless/ieee802154/mac802154.c
Normal file
File diff suppressed because it is too large
Load Diff
345
wireless/ieee802154/mac802154.h
Normal file
345
wireless/ieee802154/mac802154.h
Normal file
@ -0,0 +1,345 @@
|
||||
/****************************************************************************
|
||||
* wireless/ieee802154/mac802154.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 <sebastien@lorquet.fr>
|
||||
* Author: Anthony Merlino <anthony@vergeaero.com>
|
||||
*
|
||||
* 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_H
|
||||
#define __WIRELESS_IEEE802154__MAC802154_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <nuttx/wireless/ieee802154/ieee802154_mac.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
struct iob_s; /* Forward reference */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mac802154_bind
|
||||
*
|
||||
* Description:
|
||||
* Bind the MAC callback table to the MAC state.
|
||||
*
|
||||
* Parameters:
|
||||
* mac - Reference to the MAC driver state structure
|
||||
* cb - MAC callback operations
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success; Negated errno on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mac802154_bind(MACHANDLE mac, FAR const struct ieee802154_maccb_s *cb);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mac802154_ioctl
|
||||
*
|
||||
* Description:
|
||||
* Handle MAC and radio IOCTL commands directed to the MAC.
|
||||
*
|
||||
* Parameters:
|
||||
* mac - Reference to the MAC driver state structure
|
||||
* cmd - The IOCTL command
|
||||
* arg - The argument for the IOCTL command
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success; Negated errno on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mac802154_ioctl(MACHANDLE mac, int cmd, unsigned long arg);
|
||||
|
||||
/****************************************************************************
|
||||
* MAC Interface Operations
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mac802154_get_mhrlen
|
||||
*
|
||||
* Description:
|
||||
* Calculate the MAC header length given the frame meta-data.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mac802154_get_mhrlen(MACHANDLE mac,
|
||||
FAR const struct ieee802154_frame_meta_s *meta);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mac802154_req_data
|
||||
*
|
||||
* Description:
|
||||
* The MCPS-DATA.request primitive requests the transfer of a data SPDU
|
||||
* (i.e., MSDU) from a local SSCS entity to a single peer SSCS entity.
|
||||
* Confirmation is returned via the
|
||||
* struct ieee802154_maccb_s->conf_data callback.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mac802154_req_data(MACHANDLE mac,
|
||||
FAR const struct ieee802154_frame_meta_s *meta,
|
||||
FAR struct iob_s *frame);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mac802154_req_purge
|
||||
*
|
||||
* Description:
|
||||
* The MCPS-PURGE.request primitive allows the next higher layer to purge
|
||||
* an MSDU from the transaction queue. Confirmation is returned via
|
||||
* the struct ieee802154_maccb_s->conf_purge callback.
|
||||
*
|
||||
* NOTE: The standard specifies that confirmation should be indicated via
|
||||
* the asynchronous MLME-PURGE.confirm primitve. However, in our
|
||||
* implementation we synchronously return the status from the request.
|
||||
* Therefore, we merge the functionality of the MLME-PURGE.request and
|
||||
* MLME-PURGE.confirm primitives together.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mac802154_req_purge(MACHANDLE mac, uint8_t msdu_handle);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mac802154_req_associate
|
||||
*
|
||||
* Description:
|
||||
* The MLME-ASSOCIATE.request primitive allows a device to request an
|
||||
* association with a coordinator. Confirmation is returned via the
|
||||
* struct ieee802154_maccb_s->conf_associate callback.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mac802154_req_associate(MACHANDLE mac,
|
||||
FAR struct ieee802154_assoc_req_s *req);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mac802154_req_disassociate
|
||||
*
|
||||
* Description:
|
||||
* The MLME-DISASSOCIATE.request primitive is used by an associated device
|
||||
* to notify the coordinator of its intent to leave the PAN. It is also
|
||||
* used by the coordinator to instruct an associated device to leave the
|
||||
* PAN.
|
||||
*
|
||||
* Confirmation is returned via the
|
||||
* struct ieee802154_maccb_s->conf_disassociate callback.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mac802154_req_disassociate(MACHANDLE mac,
|
||||
FAR struct ieee802154_disassoc_req_s *req);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mac802154_req_gts
|
||||
*
|
||||
* Description:
|
||||
* The MLME-GTS.request primitive allows a device to send a request to the
|
||||
* PAN coordinator to allocate a new GTS or to deallocate an existing GTS.
|
||||
* Confirmation is returned via the
|
||||
* struct ieee802154_maccb_s->conf_gts callback.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mac802154_req_gts(MACHANDLE mac, FAR struct ieee802154_gts_req_s *req);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mac802154_req_reset
|
||||
*
|
||||
* Description:
|
||||
* The MLME-RESET.request primitive allows the next higher layer to request
|
||||
* that the MLME performs a reset operation.
|
||||
*
|
||||
* NOTE: The standard specifies that confirmation should be provided via
|
||||
* via the asynchronous MLME-RESET.confirm primitve. However, in our
|
||||
* implementation we synchronously return the value immediately. Therefore,
|
||||
* we merge the functionality of the MLME-RESET.request and MLME-RESET.confirm
|
||||
* primitives together.
|
||||
*
|
||||
* Input Parameters:
|
||||
* mac - Handle to the MAC layer instance
|
||||
* rst_pibattr - Whether or not to reset the MAC PIB attributes to defaults
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mac802154_req_reset(MACHANDLE mac, bool rst_pibattr);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mac802154_req_rxenable
|
||||
*
|
||||
* Description:
|
||||
* The MLME-RX-ENABLE.request primitive allows the next higher layer to
|
||||
* request that the receiver is enable for a finite period of time.
|
||||
* Confirmation is returned via the
|
||||
* struct ieee802154_maccb_s->conf_rxenable callback.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mac802154_req_rxenable(MACHANDLE mac,
|
||||
FAR struct ieee802154_rxenable_req_s *req);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mac802154_req_scan
|
||||
*
|
||||
* Description:
|
||||
* The MLME-SCAN.request primitive is used to initiate a channel scan over
|
||||
* a given list of channels. A device can use a channel scan to measure
|
||||
* the energy on the channel, search for the coordinator with which it
|
||||
* associated, or search for all coordinators transmitting beacon frames
|
||||
* within the POS of the scanning device. Scan results are returned
|
||||
* via MULTIPLE calls to the struct ieee802154_maccb_s->conf_scan
|
||||
* callback. This is a difference with the official 802.15.4
|
||||
* specification, implemented here to save memory.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mac802154_req_scan(MACHANDLE mac, FAR struct ieee802154_scan_req_s *req);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mac802154_req_get
|
||||
*
|
||||
* Description:
|
||||
* The MLME-GET.request primitive requests information about a given PIB
|
||||
* attribute.
|
||||
*
|
||||
* NOTE: The standard specifies that the attribute value should be returned
|
||||
* via the asynchronous MLME-GET.confirm primitve. However, in our
|
||||
* implementation, we synchronously return the value immediately.Therefore, we
|
||||
* merge the functionality of the MLME-GET.request and MLME-GET.confirm
|
||||
* primitives together.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mac802154_req_get(MACHANDLE mac, enum ieee802154_pib_attr_e pib_attr,
|
||||
FAR union ieee802154_attr_val_u *attr_value);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mac802154_req_set
|
||||
*
|
||||
* Description:
|
||||
* The MLME-SET.request primitive attempts to write the given value to the
|
||||
* indicated MAC PIB attribute.
|
||||
*
|
||||
* NOTE: The standard specifies that confirmation should be indicated via
|
||||
* the asynchronous MLME-SET.confirm primitve. However, in our implementation
|
||||
* we synchronously return the status from the request. Therefore, we do merge
|
||||
* the functionality of the MLME-SET.request and MLME-SET.confirm primitives
|
||||
* together.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mac802154_req_set(MACHANDLE mac, enum ieee802154_pib_attr_e pib_attr,
|
||||
FAR const union ieee802154_attr_val_u *attr_value);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mac802154_req_start
|
||||
*
|
||||
* Description:
|
||||
* The MLME-START.request primitive makes a request for the device to
|
||||
* start using a new superframe configuration. Confirmation is returned
|
||||
* via the struct ieee802154_maccb_s->conf_start callback.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mac802154_req_start(MACHANDLE mac, FAR struct ieee802154_start_req_s *req);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mac802154_req_sync
|
||||
*
|
||||
* Description:
|
||||
* The MLME-SYNC.request primitive requests to synchronize with the
|
||||
* coordinator by acquiring and, if specified, tracking its beacons.
|
||||
* Confirmation is returned via the
|
||||
* struct ieee802154_maccb_s->int_commstatus callback. TOCHECK.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mac802154_req_sync(MACHANDLE mac, FAR struct ieee802154_sync_req_s *req);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mac802154_req_poll
|
||||
*
|
||||
* Description:
|
||||
* The MLME-POLL.request primitive prompts the device to request data from
|
||||
* the coordinator. Confirmation is returned via the
|
||||
* struct ieee802154_maccb_s->conf_poll callback, followed by a
|
||||
* struct ieee802154_maccb_s->ind_data callback.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mac802154_req_poll(MACHANDLE mac, FAR struct ieee802154_poll_req_s *req);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mac802154_resp_associate
|
||||
*
|
||||
* Description:
|
||||
* The MLME-ASSOCIATE.response primitive is used to initiate a response to
|
||||
* an MLME-ASSOCIATE.indication primitive.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mac802154_resp_associate(MACHANDLE mac,
|
||||
FAR struct ieee802154_assoc_resp_s *resp);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mac802154_resp_orphan
|
||||
*
|
||||
* Description:
|
||||
* The MLME-ORPHAN.response primitive allows the next higher layer of a
|
||||
* coordinator to respond to the MLME-ORPHAN.indication primitive.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int mac802154_resp_orphan(MACHANDLE mac,
|
||||
FAR struct ieee802154_orphan_resp_s *resp);
|
||||
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __WIRELESS_IEEE802154__MAC802154_H */
|
1017
wireless/ieee802154/mac802154_device.c
Normal file
1017
wireless/ieee802154/mac802154_device.c
Normal file
File diff suppressed because it is too large
Load Diff
415
wireless/ieee802154/mac802154_indalloc.c
Normal file
415
wireless/ieee802154/mac802154_indalloc.c
Normal file
@ -0,0 +1,415 @@
|
||||
/****************************************************************************
|
||||
* wireless/ieee802154_indalloc.c
|
||||
*
|
||||
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
|
||||
#include <nuttx/drivers/iob.h>
|
||||
|
||||
#include <nuttx/wireless/ieee802154/ieee802154_mac.h>
|
||||
|
||||
#include "mac802154.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#if !defined(CONFIG_IEEE802154_IND_PREALLOC) || CONFIG_IEEE802154_IND_PREALLOC < 0
|
||||
# undef CONFIG_IEEE802154_IND_PREALLOC
|
||||
# define CONFIG_IEEE802154_IND_PREALLOC 20
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_IEEE802154_IND_IRQRESERVE) || CONFIG_IEEE802154_IND_IRQRESERVE < 0
|
||||
# undef CONFIG_IEEE802154_IND_IRQRESERVE
|
||||
# define CONFIG_IEEE802154_IND_IRQRESERVE 10
|
||||
#endif
|
||||
|
||||
#if CONFIG_IEEE802154_IND_IRQRESERVE > CONFIG_IEEE802154_IND_PREALLOC
|
||||
# undef CONFIG_IEEE802154_IND_IRQRESERVE
|
||||
# define CONFIG_IEEE802154_IND_IRQRESERVE CONFIG_IEEE802154_IND_PREALLOC
|
||||
#endif
|
||||
|
||||
/* Memory Pools */
|
||||
|
||||
#define POOL_IND_GENERAL 0
|
||||
#define POOL_IND_IRQ 1
|
||||
#define POOL_IND_DYNAMIC 2
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data Types
|
||||
****************************************************************************/
|
||||
|
||||
/* Private data type that extends the ieee802154_data_ind_s struct */
|
||||
|
||||
struct ieee802154_priv_ind_s
|
||||
{
|
||||
/* Must be first member so we can cast to/from */
|
||||
|
||||
struct ieee802154_data_ind_s pub;
|
||||
FAR struct ieee802154_priv_ind_s *flink;
|
||||
uint8_t pool;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
#if CONFIG_IEEE802154_IND_PREALLOC > 0
|
||||
#if CONFIG_IEEE802154_IND_PREALLOC > CONFIG_IEEE802154_IND_IRQRESERVE
|
||||
/* The g_indfree is a list of meta-data structures that are available for
|
||||
* general use. The number of messages in this list is a system configuration
|
||||
* item.
|
||||
*/
|
||||
|
||||
static struct ieee802154_priv_ind_s *g_indfree;
|
||||
#endif
|
||||
|
||||
#if CONFIG_IEEE802154_IND_IRQRESERVE > 0
|
||||
/* The g_indfree_irq is a list of meta-data structures that are reserved for
|
||||
* use by only by interrupt handlers.
|
||||
*/
|
||||
|
||||
static struct ieee802154_priv_ind_s *g_indfree_irq;
|
||||
#endif
|
||||
|
||||
/* Pool of pre-allocated meta-data stuctures */
|
||||
|
||||
static struct ieee802154_priv_ind_s g_indpool[CONFIG_IEEE802154_IND_PREALLOC];
|
||||
#endif /* CONFIG_IEEE802154_IND_PREALLOC > 0 */
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ieee802154_indpool_initialize
|
||||
*
|
||||
* Description:
|
||||
* This function initializes the meta-data allocator. This function must
|
||||
* be called early in the initialization sequence before any radios
|
||||
* begin operation.
|
||||
*
|
||||
* Inputs:
|
||||
* None
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void ieee802154_indpool_initialize(void)
|
||||
{
|
||||
#if CONFIG_IEEE802154_IND_PREALLOC > 0
|
||||
FAR struct ieee802154_priv_ind_s *pool = g_indpool;
|
||||
int remaining = CONFIG_IEEE802154_IND_PREALLOC;
|
||||
|
||||
#if CONFIG_IEEE802154_IND_PREALLOC > CONFIG_IEEE802154_IND_IRQRESERVE
|
||||
/* Initialize g_indfree, thelist of meta-data structures that are available
|
||||
* for general use.
|
||||
*/
|
||||
|
||||
g_indfree = NULL;
|
||||
while (remaining > CONFIG_IEEE802154_IND_IRQRESERVE)
|
||||
{
|
||||
FAR struct ieee802154_priv_ind_s *ind = pool;
|
||||
|
||||
/* Add the next meta data structure from the pool to the list of
|
||||
* general structures.
|
||||
*/
|
||||
|
||||
ind->flink = g_indfree;
|
||||
g_indfree = ind;
|
||||
|
||||
/* Set up for the next structure from the pool */
|
||||
|
||||
pool++;
|
||||
remaining--;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_IEEE802154_IND_IRQRESERVE > 0
|
||||
/* Initialize g_indfree_irq is a list of meta-data structures reserved for
|
||||
* use by only by interrupt handlers.
|
||||
*/
|
||||
|
||||
g_indfree_irq = NULL;
|
||||
while (remaining > 0)
|
||||
{
|
||||
FAR struct ieee802154_priv_ind_s *ind = pool;
|
||||
|
||||
/* Add the next meta data structure from the pool to the list of
|
||||
* general structures.
|
||||
*/
|
||||
|
||||
ind->flink = g_indfree_irq;
|
||||
g_indfree_irq = ind;
|
||||
|
||||
/* Set up for the next structure from the pool */
|
||||
|
||||
pool++;
|
||||
remaining--;
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_IEEE802154_IND_PREALLOC > 0 */
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ieee802154_ind_allocate
|
||||
*
|
||||
* Description:
|
||||
* The ieee802154_ind_allocate function will get a free meta-data
|
||||
* structure for use by the IEEE 802.15.4 MAC.
|
||||
*
|
||||
* Interrupt handling logic will first attempt to allocate from the
|
||||
* g_indfree list. If that list is empty, it will attempt to allocate
|
||||
* from its reserve, g_indfree_irq. If that list is empty, then the
|
||||
* allocation fails (NULL is returned).
|
||||
*
|
||||
* Non-interrupt handler logic will attempt to allocate from g_indfree
|
||||
* list. If that the list is empty, then the meta-data structure will be
|
||||
* allocated from the dynamic memory pool.
|
||||
*
|
||||
* Inputs:
|
||||
* None
|
||||
*
|
||||
* Return Value:
|
||||
* A reference to the allocated msg structure. All user fields in this
|
||||
* structure have been zeroed. On a failure to allocate, NULL is
|
||||
* returned.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct ieee802154_data_ind_s *ieee802154_ind_allocate(void)
|
||||
{
|
||||
#if CONFIG_IEEE802154_IND_PREALLOC > 0
|
||||
FAR struct ieee802154_priv_ind_s *ind;
|
||||
irqstate_t flags;
|
||||
uint8_t pool;
|
||||
|
||||
/* If we were called from an interrupt handler, then try to get the meta-
|
||||
* data structure from generally available list of messages. If this fails,
|
||||
* then try the list of messages reserved for interrupt handlers
|
||||
*/
|
||||
|
||||
flags = enter_critical_section(); /* Always necessary in SMP mode */
|
||||
if (up_interrupt_context())
|
||||
{
|
||||
#if CONFIG_IEEE802154_IND_PREALLOC > CONFIG_IEEE802154_IND_IRQRESERVE
|
||||
/* Try the general free list */
|
||||
|
||||
if (g_indfree != NULL)
|
||||
{
|
||||
ind = g_indfree;
|
||||
g_indfree = ind->flink;
|
||||
|
||||
leave_critical_section(flags);
|
||||
pool = POOL_IND_GENERAL;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#if CONFIG_IEEE802154_IND_IRQRESERVE > 0
|
||||
/* Try the list list reserved for interrupt handlers */
|
||||
|
||||
if (g_indfree_irq != NULL)
|
||||
{
|
||||
ind = g_indfree_irq;
|
||||
g_indfree_irq = ind->flink;
|
||||
|
||||
leave_critical_section(flags);
|
||||
pool = POOL_IND_IRQ;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
leave_critical_section(flags);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* We were not called from an interrupt handler. */
|
||||
|
||||
else
|
||||
{
|
||||
#if CONFIG_IEEE802154_IND_PREALLOC > CONFIG_IEEE802154_IND_IRQRESERVE
|
||||
/* Try the general free list */
|
||||
|
||||
if (g_indfree != NULL)
|
||||
{
|
||||
ind = g_indfree;
|
||||
g_indfree = ind->flink;
|
||||
|
||||
leave_critical_section(flags);
|
||||
pool = POOL_IND_GENERAL;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* If we cannot a meta-data structure from the free list, then we
|
||||
* will have to allocate one from the kernal memory pool.
|
||||
*/
|
||||
|
||||
leave_critical_section(flags);
|
||||
ind = (FAR struct ieee802154_priv_ind_s *)
|
||||
kmm_malloc((sizeof (struct ieee802154_priv_ind_s)));
|
||||
|
||||
/* Check if we allocated the meta-data structure */
|
||||
|
||||
if (ind != NULL)
|
||||
{
|
||||
/* Yes... remember that this meta-data structure was dynamically allocated */
|
||||
|
||||
pool = POOL_IND_DYNAMIC;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* We have successfully allocated memory from some source.
|
||||
* Zero and tag the alloated meta-data structure.
|
||||
*/
|
||||
|
||||
ind->pool = pool;
|
||||
memset(&ind->pub, 0, sizeof(struct ieee802154_data_ind_s));
|
||||
|
||||
/* Allocate the IOB for the frame */
|
||||
|
||||
ind->pub.frame = iob_alloc(true);
|
||||
if (ind->pub.frame == NULL)
|
||||
{
|
||||
/* Deallocate the ind */
|
||||
|
||||
ieee802154_ind_free(&ind->pub);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ind->pub.frame->io_flink = NULL;
|
||||
ind->pub.frame->io_len = 0;
|
||||
ind->pub.frame->io_offset = 0;
|
||||
ind->pub.frame->io_pktlen = 0;
|
||||
|
||||
return &ind->pub;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ieee802154_ind_free
|
||||
*
|
||||
* Description:
|
||||
* The ieee802154_ind_free function will return a meta-data structure to
|
||||
* the free pool of messages if it was a pre-allocated meta-data
|
||||
* structure. If the meta-data structure was allocated dynamically it will
|
||||
* be deallocated.
|
||||
*
|
||||
* Inputs:
|
||||
* ind - meta-data structure to free
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void ieee802154_ind_free(FAR struct ieee802154_data_ind_s *ind)
|
||||
{
|
||||
#if CONFIG_IEEE802154_IND_PREALLOC > 0
|
||||
irqstate_t flags;
|
||||
FAR struct ieee802154_priv_ind_s *priv =
|
||||
(FAR struct ieee802154_priv_ind_s *)ind;
|
||||
|
||||
/* Check if the IOB is not NULL. The only time it should be NULL is if we
|
||||
* allocated the data_ind, but the IOB allocation failed so we now have to
|
||||
* free the data_ind but not the IOB. This really should happen rarely if at all.
|
||||
*/
|
||||
|
||||
if (ind->frame != NULL)
|
||||
{
|
||||
iob_free(ind->frame);
|
||||
}
|
||||
|
||||
#if CONFIG_IEEE802154_IND_PREALLOC > CONFIG_IEEE802154_IND_IRQRESERVE
|
||||
/* If this is a generally available pre-allocated meta-data structure,
|
||||
* then just put it back in the free list.
|
||||
*/
|
||||
|
||||
if (priv->pool == POOL_IND_GENERAL)
|
||||
{
|
||||
/* Make sure we avoid concurrent access to the free
|
||||
* list from interrupt handlers.
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
priv->flink = g_indfree;
|
||||
g_indfree = priv;
|
||||
leave_critical_section(flags);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
#if CONFIG_IEEE802154_IND_IRQRESERVE > 0
|
||||
/* If this is a meta-data structure pre-allocated for interrupts,
|
||||
* then put it back in the correct free list.
|
||||
*/
|
||||
|
||||
if (priv->pool == POOL_IND_IRQ)
|
||||
{
|
||||
/* Make sure we avoid concurrent access to the free
|
||||
* list from interrupt handlers.
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
priv->flink = g_indfree_irq;
|
||||
g_indfree_irq = priv;
|
||||
leave_critical_section(flags);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
{
|
||||
/* Otherwise, deallocate it. */
|
||||
|
||||
DEBUGASSERT(priv->pool == POOL_IND_DYNAMIC);
|
||||
sched_kfree(priv);
|
||||
}
|
||||
#endif
|
||||
}
|
@ -56,6 +56,8 @@
|
||||
#include <nuttx/net/sixlowpan.h>
|
||||
#include <nuttx/wireless/ieee802154/ieee802154_loopback.h>
|
||||
|
||||
#include "mac802154.h"
|
||||
|
||||
#ifdef CONFIG_IEEE802154_LOOPBACK
|
||||
|
||||
/****************************************************************************
|
||||
@ -80,6 +82,10 @@
|
||||
|
||||
#define LO_WDDELAY (1*CLK_TCK)
|
||||
|
||||
/* Fake value for MAC header length */
|
||||
|
||||
#define MAC_HDRLEN 9
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
@ -91,9 +97,12 @@
|
||||
struct lo_driver_s
|
||||
{
|
||||
bool lo_bifup; /* true:ifup false:ifdown */
|
||||
bool lo_txdone; /* One RX packet was looped back */
|
||||
bool lo_pending; /* True: TX poll pending */
|
||||
uint16_t lo_panid; /* Fake PAN ID for testing */
|
||||
WDOG_ID lo_polldog; /* TX poll timer */
|
||||
struct work_s lo_work; /* For deferring poll work to the work queue */
|
||||
FAR struct iob_s *lo_head; /* Head of IOBs queued for loopback */
|
||||
FAR struct iob_s *lo_tail; /* Tail of IOBs queued for loopback */
|
||||
|
||||
/* This holds the information visible to the NuttX network */
|
||||
|
||||
@ -113,29 +122,39 @@ static uint8_t g_iobuffer[CONFIG_NET_6LOWPAN_MTU + CONFIG_NET_GUARDSIZE];
|
||||
|
||||
/* Polling logic */
|
||||
|
||||
static int lo_txpoll(FAR struct net_driver_s *dev);
|
||||
static int lo_loopback(FAR struct net_driver_s *dev);
|
||||
static void lo_loopback_work(FAR void *arg);
|
||||
static void lo_poll_work(FAR void *arg);
|
||||
static void lo_poll_expiry(int argc, wdparm_t arg, ...);
|
||||
|
||||
/* NuttX callback functions */
|
||||
|
||||
static int lo_ifup(FAR struct net_driver_s *dev);
|
||||
static int lo_ifdown(FAR struct net_driver_s *dev);
|
||||
static int lo_ifup(FAR struct net_driver_s *dev);
|
||||
static int lo_ifdown(FAR struct net_driver_s *dev);
|
||||
static void lo_txavail_work(FAR void *arg);
|
||||
static int lo_txavail(FAR struct net_driver_s *dev);
|
||||
static int lo_txavail(FAR struct net_driver_s *dev);
|
||||
#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6)
|
||||
static int lo_addmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac);
|
||||
static int lo_addmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac);
|
||||
#ifdef CONFIG_NET_IGMP
|
||||
static int lo_rmmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac);
|
||||
static int lo_rmmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac);
|
||||
#endif
|
||||
#endif
|
||||
#ifdef CONFIG_NETDEV_IOCTL
|
||||
static int lo_ioctl(FAR struct net_driver_s *dev, int cmd,
|
||||
unsigned long arg);
|
||||
#endif
|
||||
static int lo_get_mhrlen(FAR struct ieee802154_driver_s *netdev,
|
||||
FAR const struct ieee802154_frame_meta_s *meta);
|
||||
static int lo_req_data(FAR struct ieee802154_driver_s *netdev,
|
||||
FAR const struct ieee802154_frame_meta_s *meta,
|
||||
FAR struct iob_s *framelist);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lo_txpoll
|
||||
* Name: lo_loopback
|
||||
*
|
||||
* Description:
|
||||
* Check if the network has any outgoing packets ready to send. This is
|
||||
@ -154,71 +173,47 @@ static int lo_rmmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac);
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int lo_txpoll(FAR struct net_driver_s *dev)
|
||||
static int lo_loopback(FAR struct net_driver_s *dev)
|
||||
{
|
||||
FAR struct lo_driver_s *priv = (FAR struct lo_driver_s *)dev->d_private;
|
||||
FAR struct iob_s *head;
|
||||
FAR struct iob_s *tail;
|
||||
struct ieee802154_data_ind_s ind;
|
||||
FAR struct iob_s *iob;
|
||||
int ret;
|
||||
|
||||
if (dev->d_len > 0 || priv->lo_ieee.i_framelist != NULL)
|
||||
{
|
||||
ninfo("d_len: %u i_framelist: %p\n",
|
||||
dev->d_len, priv->lo_ieee.i_framelist);
|
||||
memset(&ind, 0, sizeof(struct ieee802154_data_ind_s));
|
||||
|
||||
/* The only two valid settings are:
|
||||
*
|
||||
* 1. Nothing to send:
|
||||
* dev->d_len == 0 && priv->lo_ieee.i_framelist == NULL
|
||||
* 2. Outgoing packet has been converted to IEEE802.15.4 frames:
|
||||
* dev->d_len == 0 && priv->lo_ieee.i_framelist != NULL
|
||||
*/
|
||||
|
||||
DEBUGASSERT(dev->d_len == 0 && priv->lo_ieee.i_framelist != NULL);
|
||||
}
|
||||
|
||||
/* Remove the queued IOBs from driver structure */
|
||||
|
||||
head = priv->lo_ieee.i_framelist;
|
||||
|
||||
/* Find the tail of the IOB queue */
|
||||
|
||||
for (tail = NULL, iob = head;
|
||||
iob != NULL;
|
||||
tail = iob, iob = iob->io_flink);
|
||||
|
||||
/* Loop while there frames to be sent, i.e., while the IOB list is not
|
||||
* emtpy. Sending, of course, just means relaying back through the network
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
while (head != NULL)
|
||||
while (priv->lo_head != NULL)
|
||||
{
|
||||
ninfo("Looping frame IOB %p\n", iob);
|
||||
|
||||
/* Increment statistics */
|
||||
|
||||
NETDEV_RXPACKETS(&priv->lo_ieee.i_dev);
|
||||
|
||||
/* Remove the IOB from the queue */
|
||||
|
||||
iob = head;
|
||||
head = iob->io_flink;
|
||||
iob = priv->lo_head;
|
||||
priv->lo_head = iob->io_flink;
|
||||
iob->io_flink = NULL;
|
||||
|
||||
/* Is the queue now empty? */
|
||||
/* Did the framelist become empty? */
|
||||
|
||||
if (head == NULL)
|
||||
if (priv->lo_head == NULL)
|
||||
{
|
||||
tail = NULL;
|
||||
priv->lo_tail = NULL;
|
||||
}
|
||||
|
||||
/* Return the next frame to the network */
|
||||
|
||||
iob->io_flink = NULL;
|
||||
priv->lo_ieee.i_framelist = iob;
|
||||
ninfo("Send frame %p to the network: Offset=%u Length=%u\n",
|
||||
iob, iob->io_offset, iob->io_len);
|
||||
|
||||
ninfo("Send frame %p to the network. Length=%u\n", iob, iob->io_len);
|
||||
ret = sixlowpan_input(&priv->lo_ieee);
|
||||
ret = sixlowpan_input(&priv->lo_ieee, iob, &ind);
|
||||
|
||||
/* Increment statistics */
|
||||
|
||||
@ -230,38 +225,39 @@ static int lo_txpoll(FAR struct net_driver_s *dev)
|
||||
NETDEV_TXERRORS(&priv->lo_ieee.i_dev);
|
||||
NETDEV_ERRORS(&priv->lo_ieee.i_dev);
|
||||
}
|
||||
|
||||
/* What if the network responds with more frames to send? */
|
||||
|
||||
if (priv->lo_ieee.i_framelist != NULL)
|
||||
{
|
||||
/* Append the new list to the tail of the queue */
|
||||
|
||||
iob = priv->lo_ieee.i_framelist;
|
||||
priv->lo_ieee.i_framelist = NULL;
|
||||
|
||||
if (tail == NULL)
|
||||
{
|
||||
head = iob;
|
||||
}
|
||||
else
|
||||
{
|
||||
tail->io_flink = iob;
|
||||
}
|
||||
|
||||
/* Find the new tail of the IOB queue */
|
||||
|
||||
for (tail = iob, iob = iob->io_flink;
|
||||
iob != NULL;
|
||||
tail = iob, iob = iob->io_flink);
|
||||
}
|
||||
|
||||
priv->lo_txdone = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lo_loopback_work
|
||||
*
|
||||
* Description:
|
||||
* Perform loopback of received framelist.
|
||||
*
|
||||
* Parameters:
|
||||
* arg - The argument passed when work_queue() as called.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* The network is locked
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void lo_loopback_work(FAR void *arg)
|
||||
{
|
||||
FAR struct lo_driver_s *priv = (FAR struct lo_driver_s *)arg;
|
||||
|
||||
/* Perform the loopback */
|
||||
|
||||
net_lock();
|
||||
(void)lo_loopback(&priv->lo_ieee.i_dev);
|
||||
net_unlock();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lo_poll_work
|
||||
*
|
||||
@ -286,18 +282,7 @@ static void lo_poll_work(FAR void *arg)
|
||||
/* Perform the poll */
|
||||
|
||||
net_lock();
|
||||
priv->lo_txdone = false;
|
||||
(void)devif_timer(&priv->lo_ieee.i_dev, lo_txpoll);
|
||||
|
||||
/* Was something received and looped back? */
|
||||
|
||||
while (priv->lo_txdone)
|
||||
{
|
||||
/* Yes, poll again for more TX data */
|
||||
|
||||
priv->lo_txdone = false;
|
||||
(void)devif_poll(&priv->lo_ieee.i_dev, lo_txpoll);
|
||||
}
|
||||
(void)devif_timer(&priv->lo_ieee.i_dev, lo_loopback);
|
||||
|
||||
/* Setup the watchdog poll timer again */
|
||||
|
||||
@ -327,14 +312,18 @@ static void lo_poll_expiry(int argc, wdparm_t arg, ...)
|
||||
{
|
||||
FAR struct lo_driver_s *priv = (FAR struct lo_driver_s *)arg;
|
||||
|
||||
if (!work_available(&priv->lo_work))
|
||||
if (!work_available(&priv->lo_work) || priv->lo_head != NULL)
|
||||
{
|
||||
nwarn("WARNING: lo_work NOT available\n");
|
||||
priv->lo_pending = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Schedule to perform the interrupt processing on the worker thread. */
|
||||
|
||||
/* Schedule to perform the interrupt processing on the worker thread. */
|
||||
|
||||
work_queue(LPBKWORK, &priv->lo_work, lo_poll_work, priv, 0);
|
||||
priv->lo_pending = false;
|
||||
work_queue(LPBKWORK, &priv->lo_work, lo_poll_work, priv, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -363,17 +352,17 @@ static int lo_ifup(FAR struct net_driver_s *dev)
|
||||
dev->d_ipv6addr[3], dev->d_ipv6addr[4], dev->d_ipv6addr[5],
|
||||
dev->d_ipv6addr[6], dev->d_ipv6addr[7]);
|
||||
|
||||
#ifdef CONFIG_NET_6LOWPAN_RIMEADDR_EXTENDED
|
||||
#ifdef CONFIG_NET_6LOWPAN_EXTENDEDADDR
|
||||
ninfo(" Node: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x PANID=%04x\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],
|
||||
priv->lo_ieee.i_panid);
|
||||
priv->lo_panid);
|
||||
#else
|
||||
ninfo(" Node: %02x:%02x PANID=%04x\n",
|
||||
dev->d_mac.ieee802154.u8[0], dev->d_mac.ieee802154.u8[1],
|
||||
priv->lo_ieee.i_panid);
|
||||
priv->lo_panid);
|
||||
#endif
|
||||
|
||||
/* Set and activate a timer process */
|
||||
@ -438,21 +427,16 @@ static void lo_txavail_work(FAR void *arg)
|
||||
{
|
||||
FAR struct lo_driver_s *priv = (FAR struct lo_driver_s *)arg;
|
||||
|
||||
ninfo("IP up: %u\n", priv->lo_bifup);
|
||||
ninfo("TX available work. IP up: %u\n", priv->lo_bifup);
|
||||
|
||||
/* Ignore the notification if the interface is not yet up */
|
||||
|
||||
net_lock();
|
||||
if (priv->lo_bifup)
|
||||
{
|
||||
do
|
||||
{
|
||||
/* If so, then poll the network for new XMIT data */
|
||||
/* If so, then poll the network for new XMIT data */
|
||||
|
||||
priv->lo_txdone = false;
|
||||
(void)devif_poll(&priv->lo_ieee.i_dev, lo_txpoll);
|
||||
}
|
||||
while (priv->lo_txdone);
|
||||
(void)devif_poll(&priv->lo_ieee.i_dev, lo_loopback);
|
||||
}
|
||||
|
||||
net_unlock();
|
||||
@ -484,14 +468,20 @@ static int lo_txavail(FAR struct net_driver_s *dev)
|
||||
ninfo("Available: %u\n", work_available(&priv->lo_work));
|
||||
|
||||
/* 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.
|
||||
* pending actions and we will have to ignore the Tx availability
|
||||
* action.
|
||||
*/
|
||||
|
||||
if (work_available(&priv->lo_work))
|
||||
if (!work_available(&priv->lo_work) || priv->lo_head != NULL)
|
||||
{
|
||||
/* Schedule to serialize the poll on the worker thread. */
|
||||
nwarn("WARNING: lo_work NOT available\n");
|
||||
priv->lo_pending = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Schedule to perform the interrupt processing on the worker thread. */
|
||||
|
||||
priv->lo_pending = false;
|
||||
work_queue(LPBKWORK, &priv->lo_work, lo_txavail_work, priv, 0);
|
||||
}
|
||||
|
||||
@ -519,7 +509,7 @@ static int lo_txavail(FAR struct net_driver_s *dev)
|
||||
#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6)
|
||||
static int lo_addmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac)
|
||||
{
|
||||
#ifdef CONFIG_NET_6LOWPAN_RIMEADDR_EXTENDED
|
||||
#ifdef CONFIG_NET_6LOWPAN_EXTENDEDADDR
|
||||
ninfo("MAC: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], mac[6], mac[7]);
|
||||
#else
|
||||
@ -554,7 +544,7 @@ static int lo_addmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac)
|
||||
#ifdef CONFIG_NET_IGMP
|
||||
static int lo_rmmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac)
|
||||
{
|
||||
#ifdef CONFIG_NET_6LOWPAN_RIMEADDR_EXTENDED
|
||||
#ifdef CONFIG_NET_6LOWPAN_EXTENDEDADDR
|
||||
ninfo("MAC: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], mac[6], mac[7]);
|
||||
#else
|
||||
@ -568,6 +558,138 @@ static int lo_rmmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac)
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: macnet_ioctl
|
||||
*
|
||||
* Description:
|
||||
* Handle network IOCTL commands directed to this device.
|
||||
*
|
||||
* Parameters:
|
||||
* dev - Reference to the NuttX driver state structure
|
||||
* cmd - The IOCTL command
|
||||
* arg - The argument for the IOCTL command
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success; Negated errno on failure.
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NETDEV_IOCTL
|
||||
static int lo_ioctl(FAR struct net_driver_s *dev, int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
#if 0
|
||||
FAR struct lo_driver_s *priv = (FAR struct lo_driver_s *)dev->d_private;
|
||||
|
||||
/* Check for IOCTLs aimed at the IEEE802.15.4 MAC layer */
|
||||
|
||||
if (_MAC802154IOCVALID(cmd))
|
||||
{
|
||||
FAR struct ieee802154_netmac_s *netmac =
|
||||
(FAR struct ieee802154_netmac_s *)arg;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Not a valid IEEE 802.15.4 MAC IOCTL command */
|
||||
|
||||
return -ENOTTY;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lo_get_mhrlen
|
||||
*
|
||||
* Description:
|
||||
* Calculate the MAC header length given the frame meta-data.
|
||||
*
|
||||
* Input parameters:
|
||||
* netdev - The networkd device that will mediate the MAC interface
|
||||
* meta - Meta data needed to recreate the MAC header
|
||||
*
|
||||
* Returned Value:
|
||||
* A non-negative MAC headeer length is returned on success; a negated
|
||||
* errno value is returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int lo_get_mhrlen(FAR struct ieee802154_driver_s *netdev,
|
||||
FAR const struct ieee802154_frame_meta_s *meta)
|
||||
{
|
||||
return MAC_HDRLEN;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lo_req_data
|
||||
*
|
||||
* Description:
|
||||
* Requests the transfer of a list of frames to the MAC.
|
||||
*
|
||||
* Input parameters:
|
||||
* netdev - The networkd device that will mediate the MAC interface
|
||||
* meta - Meta data needed to recreate the MAC header
|
||||
* framelist - Head of a list of frames to be transferred.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) returned on success; a negated errno value is returned on
|
||||
* any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int lo_req_data(FAR struct ieee802154_driver_s *netdev,
|
||||
FAR const struct ieee802154_frame_meta_s *meta,
|
||||
FAR struct iob_s *framelist)
|
||||
{
|
||||
FAR struct lo_driver_s *priv;
|
||||
FAR struct iob_s *iob;
|
||||
|
||||
DEBUGASSERT(netdev != NULL && netdev->i_dev.d_private != NULL &&
|
||||
framelist != NULL);
|
||||
priv = (FAR struct lo_driver_s *)netdev->i_dev.d_private;
|
||||
|
||||
/* Add the incoming list of framelist to queue of framelist to loopback */
|
||||
|
||||
for (iob = framelist; iob != NULL; iob = framelist)
|
||||
{
|
||||
/* Increment statistics */
|
||||
|
||||
NETDEV_RXPACKETS(&priv->lo_ieee.i_dev);
|
||||
|
||||
/* Remove the IOB from the queue */
|
||||
|
||||
framelist = iob->io_flink;
|
||||
iob->io_flink = NULL;
|
||||
|
||||
ninfo("Queuing frame IOB %p\n", iob);
|
||||
|
||||
/* Just zero the MAC header for test purposes */
|
||||
|
||||
DEBUGASSERT(iob->io_offset == MAC_HDRLEN);
|
||||
memset(iob->io_data, 0, MAC_HDRLEN);
|
||||
|
||||
/* Add the IOB to the tail of the queue of framelist to be looped back */
|
||||
|
||||
if (priv->lo_tail == NULL)
|
||||
{
|
||||
priv->lo_head = iob;
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->lo_tail->io_flink = iob;
|
||||
}
|
||||
|
||||
priv->lo_tail = iob;
|
||||
}
|
||||
|
||||
/* Schedule to serialize the poll on the worker thread. */
|
||||
|
||||
work_queue(LPBKWORK, &priv->lo_work, lo_loopback_work, priv, 0);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -590,7 +712,8 @@ static int lo_rmmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac)
|
||||
|
||||
int ieee8021514_loopback(void)
|
||||
{
|
||||
FAR struct lo_driver_s *priv;
|
||||
FAR struct lo_driver_s *priv;
|
||||
FAR struct ieee802154_driver_s *ieee;
|
||||
FAR struct net_driver_s *dev;
|
||||
|
||||
ninfo("Initializing\n");
|
||||
@ -603,26 +726,31 @@ int ieee8021514_loopback(void)
|
||||
|
||||
memset(priv, 0, sizeof(struct lo_driver_s));
|
||||
|
||||
dev = &priv->lo_ieee.i_dev;
|
||||
dev->d_ifup = lo_ifup; /* I/F up (new IP address) callback */
|
||||
dev->d_ifdown = lo_ifdown; /* I/F down callback */
|
||||
dev->d_txavail = lo_txavail; /* New TX data callback */
|
||||
ieee = &priv->lo_ieee;
|
||||
dev = &ieee->i_dev;
|
||||
dev->d_ifup = lo_ifup; /* I/F up (new IP address) callback */
|
||||
dev->d_ifdown = lo_ifdown; /* I/F down callback */
|
||||
dev->d_txavail = lo_txavail; /* New TX data callback */
|
||||
#ifdef CONFIG_NET_IGMP
|
||||
dev->d_addmac = lo_addmac; /* Add multicast MAC address */
|
||||
dev->d_rmmac = lo_rmmac; /* Remove multicast MAC address */
|
||||
dev->d_addmac = lo_addmac; /* Add multicast MAC address */
|
||||
dev->d_rmmac = lo_rmmac; /* Remove multicast MAC address */
|
||||
#endif
|
||||
dev->d_buf = g_iobuffer; /* Attach the IO buffer */
|
||||
dev->d_private = (FAR void *)priv; /* Used to recover private state from dev */
|
||||
#ifdef CONFIG_NETDEV_IOCTL
|
||||
dev->d_ioctl = lo_ioctl; /* Handle network IOCTL commands */
|
||||
#endif
|
||||
dev->d_buf = g_iobuffer; /* Attach the IO buffer */
|
||||
dev->d_private = (FAR void *)priv; /* Used to recover private state from dev */
|
||||
|
||||
/* Initialize the Network frame-related callbacks */
|
||||
|
||||
ieee->i_get_mhrlen = lo_get_mhrlen; /* Get MAC header length */
|
||||
ieee->i_req_data = lo_req_data; /* Enqueue frame for transmission */
|
||||
|
||||
/* Create a watchdog for timing polling for and timing of transmissions */
|
||||
|
||||
priv->lo_polldog = wd_create(); /* Create periodic poll timer */
|
||||
priv->lo_polldog = wd_create(); /* Create periodic poll timer */
|
||||
|
||||
/* Initialize the DSN to a "random" value */
|
||||
|
||||
priv->lo_ieee.i_dsn = 42;
|
||||
|
||||
/* Register the loopabck device with the OS so that socket IOCTLs can b
|
||||
/* Register the loopabck device with the OS so that socket IOCTLs can be
|
||||
* performed.
|
||||
*/
|
||||
|
||||
|
1138
wireless/ieee802154/mac802154_netdev.c
Normal file
1138
wireless/ieee802154/mac802154_netdev.c
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user