Merge branch 'ieee802154'

This commit is contained in:
Gregory Nutt 2017-05-08 14:35:26 -06:00
commit 3ab89d20b3
55 changed files with 12552 additions and 2039 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View 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 =

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -47,6 +47,7 @@
#include <arch/board/board.h>
#include "stm32_gpio.h"
#include "stm32_exti.h"
#include "clicker2-stm32.h"

View 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 */

View File

@ -70,9 +70,8 @@ void WriteWlanEnablePin(uint8_t val);
void AssertWlanCS(void);
/*
* Deassert CC3000 CS
*/
/* Deassert CC3000 CS */
void DeassertWlanCS(void);
/* Setup needed pins */

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

View 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

View File

@ -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 */

View File

@ -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)

View File

@ -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];
};
/****************************************************************************

View File

@ -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
/****************************************************************************

View File

@ -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 */

View 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 */

View File

@ -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 */

File diff suppressed because it is too large Load Diff

View File

@ -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 */

View File

@ -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

View File

@ -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 */
/****************************************************************************

View File

@ -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

View File

@ -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 */

View File

@ -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",

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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 *)&params->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 *)&params->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, &params);
/* Return the length of the header */
return sixlowpan_802154_hdrlen(&params);
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, &params);
/* Get the length of the header */
hdrlen = sixlowpan_802154_hdrlen(&params);
/* Then create the frame */
sixlowpan_802154_framecreate(&params, 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 */

View File

@ -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 */

View File

@ -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]);
}
}

View File

@ -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;

View File

@ -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.

View File

@ -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 */

View File

@ -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;

View File

@ -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

View File

@ -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.

View File

@ -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 */

View File

@ -6,7 +6,6 @@
config WIRELESS
bool "Wireless Support"
default n
depends on EXPERIMENTAL
---help---
Enables overall support for Wireless library.

View File

@ -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))

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

View 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 */

File diff suppressed because it is too large Load Diff

View 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
}

View File

@ -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.
*/

File diff suppressed because it is too large Load Diff