diff --git a/configs/clicker2-stm32/README.txt b/configs/clicker2-stm32/README.txt index d2892192e84..da90fdd8ac5 100644 --- a/configs/clicker2-stm32/README.txt +++ b/configs/clicker2-stm32/README.txt @@ -304,10 +304,10 @@ 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 + mrf24j40-mac - This is a version of nsh that was used for testing the MRF24J40 be as a - character device. The most important configuration differences are + This is a version of nsh that was used for testing the MRF24J40 MAC 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: @@ -327,7 +327,11 @@ Configurations CONFIG_WIRELESS=y CONFIG_WIRELESS_IEEE802154=y - CONFIG_IEEE802154_DEV=y + CONFIG_IEEE802154_MAC_DEV=y + CONFIG_IEEE802154_NTXDESC=3 + CONFIG_IEEE802154_IND_PREALLOC=20 + CONFIG_IEEE802154_IND_IRQRESERVE=10 + CONFIG_IEEE802154_DEFAULT_EADDR=0x00fade00deadbeef 5. Support for the lower half MRF24J40 character driver is enabled @@ -335,17 +339,93 @@ Configurations CONFIG_DRIVERS_IEEE802154=y CONFIG_IEEE802154_MRF24J40=y - 6. Support for the test program at apps/ieee802154 is enabled: + 6. Support for the i8sak test program at apps/ieee802154 is enabled: - CONFIG_IEEE802154_COMMON=y - CONFIG_IEEE802154_COORD=y + CONFIG_IEEE802154_LIBMAC=y + CONFIG_IEEE802154_LIBUTILS=y CONFIG_IEEE802154_I8SAK=y + CONFIG_IEEE802154_I8SAK_PRIORITY=100 + CONFIG_IEEE802154_I8SAK_STACKSIZE=2048 7. Initialization hooks are provided to enable the MRF24J40 and to register the radio character driver. CONFIG_NSH_ARCHINIT=y + 8. Configuration instructions: WPAN configuration must be performed + using the i8sak program. Detailed instructions are provided in a + README.txt file at apps/wireless/ieee802154/i8sak. You should make + sure that you are familiar with the content of that README.txt file. + + Here is a quick "cheat sheet" for associated to setting up a + coordinator and associating wth the WPAN: + + 1. Configure the Coordinator. On coordinator device do: + + nsh> i8 /dev/ieee0 startpan + nsh> i8 acceptassoc + + 2. Assocate and endpoint device with the WPAN. On the endpoint + device: + + nsh> i8 /dev/ieee0 assoc + + mrf24j40-6lowpan + + This is another version of nsh that is very similar to the mrf24j40-mac + configuration but is focused on testing the IEEE 802.15.4 MAC + integration with the 6loWPAN network stack. It derives directly from the + mrf24j40-mac and all NOTES provided there apply. Additional differences + are summarized below: + + NOTES: + + 1. This configuration differs from the mrf24j40-mac configuration in + that this configuration, like the usbnsh configuration, uses a USB + serial device for console I/O. Such a configuration is useful on the + Clicker2 STM32 which has no builtin RS-232 drivers and eliminates the + tangle of cables and jumpers needed to debug multi-board setups. + + Most other NOTES for the usbnsh configuration should apply. Specific + differences between the usbnsh or mrf24j40-mac configurations and this + configuration are listed in these NOTES. + + 2. On most serial terminal programs that I have used, the USB + connection will be lost when the target board is reset. When that + happens, you may have to reset your serial terminal program to adapt + to the new USB connection. Using TeraTerm, I actually have to exit + the serial program and restart it in order to detect and select the + re-established USB serial connection. + + 3. This configuration does NOT have USART3 output enabled. This + configuration supports logging of debug output to a circular + buffer in RAM. This feature is discussed fully in this Wiki page: + http://nuttx.org/doku.php?id=wiki:howtos:syslog . Relevant + configuration settings are summarized below: + + Device Drivers: + CONFIG_RAMLOG=y : Enable the RAM-based logging feature. + CONFIG_RAMLOG_CONSOLE=n : (We don't use the RAMLOG console) + CONFIG_RAMLOG_SYSLOG=y : This enables the RAM-based logger as the + system logger. + CONFIG_RAMLOG_NONBLOCKING=y : Needs to be non-blocking for dmesg + CONFIG_RAMLOG_BUFSIZE=8192 : Buffer size is 8KiB + + NOTE: This RAMLOG feature is really only of value if debug output + is enabled. But, by default, no debug output is disabled in this + configuration. Therefore, there is no logic that will add anything + to the RAM buffer. This feature is configured and in place only + to support any future debugging needs that you may have. + + If you don't plan on using the debug features, then by all means + disable this feature and save 16KiB of RAM! + + NOTE: There is an issue with capturing data in the RAMLOG: If + the system crashes, all of the crash dump information will go into + the RAMLOG and you will be unable to access it! You can tell that + the system has crashed because (a) it will be unresponsive and (b) + the LD2 will be blinking at about 2Hz. + nsh: Configures the NuttShell (nsh) located at examples/nsh. This @@ -371,7 +451,6 @@ Configurations CONFIG_EXAMPLES_NSH_CXXINITIALIZE=y usbnsh: - ------- This is another NSH example. If differs from other 'nsh' configurations in that this configurations uses a USB serial device for console I/O. @@ -380,7 +459,14 @@ Configurations NOTES: - 1. This configuration does have USART3 output enabled and set up as + 1. One most serial terminal programs that I have used, the USB + connection will be lost when the target board is reset. When that + happens, you may have to reset your serial terminal program to adapt + to the new USB connection. Using TeraTerm, I actually have to exit + the serial program and restart it in order to detect and select the + re-established USB serial connection. + + 2. This configuration does have USART3 output enabled and set up as the system logging device: CONFIG_SYSLOG_CHAR=y : Use a character device for system logging @@ -390,7 +476,7 @@ Configurations configuration so nothing should appear on USART3 unless you enable some debug output or enable the USB monitor. - 2. Enabling USB monitor SYSLOG output. If tracing is enabled, the USB + 3. Enabling USB monitor SYSLOG output. If tracing is enabled, the USB device will save encoded trace output in in-memory buffer; if the USB monitor is enabled, that trace buffer will be periodically emptied and dumped to the system logging device (USART3 in this diff --git a/configs/clicker2-stm32/mrf24j40-6lowpan/Make.defs b/configs/clicker2-stm32/mrf24j40-6lowpan/Make.defs new file mode 100644 index 00000000000..5d849c96f4c --- /dev/null +++ b/configs/clicker2-stm32/mrf24j40-6lowpan/Make.defs @@ -0,0 +1,122 @@ +############################################################################ +# configs/clicker2-stm32/mrf24j40-6lowpan/Make.defs +# +# Copyright (C) 2017 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +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 = diff --git a/configs/clicker2-stm32/mrf24j40-6lowpan/defconfig b/configs/clicker2-stm32/mrf24j40-6lowpan/defconfig new file mode 100644 index 00000000000..649fd33700d --- /dev/null +++ b/configs/clicker2-stm32/mrf24j40-6lowpan/defconfig @@ -0,0 +1,1395 @@ +# +# Automatically generated file; DO NOT EDIT. +# Nuttx/ Configuration +# + +# +# Build Setup +# +# CONFIG_EXPERIMENTAL is not set +# CONFIG_DEFAULT_SMALL is not set +CONFIG_HOST_LINUX=y +# CONFIG_HOST_OSX is not set +# CONFIG_HOST_WINDOWS is not set +# CONFIG_HOST_OTHER is not set + +# +# Build Configuration +# +# CONFIG_APPS_DIR="../apps" +CONFIG_BUILD_FLAT=y +# CONFIG_BUILD_2PASS is not set + +# +# Binary Output Formats +# +# CONFIG_RRLOAD_BINARY is not set +CONFIG_INTELHEX_BINARY=y +# CONFIG_MOTOROLA_SREC is not set +CONFIG_RAW_BINARY=y +# CONFIG_UBOOT_UIMAGE is not set +# CONFIG_DFU_BINARY is not set + +# +# Customize Header Files +# +# CONFIG_ARCH_STDINT_H is not set +# CONFIG_ARCH_STDBOOL_H is not set +# CONFIG_ARCH_MATH_H is not set +# CONFIG_ARCH_FLOAT_H is not set +# CONFIG_ARCH_STDARG_H is not set +# CONFIG_ARCH_DEBUG_H is not set + +# +# Debug Options +# +CONFIG_DEBUG_ALERT=y +# CONFIG_DEBUG_FEATURES is not set +CONFIG_ARCH_HAVE_STACKCHECK=y +# CONFIG_STACK_COLORATION is not set +CONFIG_ARCH_HAVE_HEAPCHECK=y +# CONFIG_HEAP_COLORATION is not set +# CONFIG_DEBUG_SYMBOLS is not set +CONFIG_ARCH_HAVE_CUSTOMOPT=y +# CONFIG_DEBUG_NOOPT is not set +# CONFIG_DEBUG_CUSTOMOPT is not set +CONFIG_DEBUG_FULLOPT=y + +# +# System Type +# +CONFIG_ARCH_ARM=y +# CONFIG_ARCH_AVR is not set +# CONFIG_ARCH_HC is not set +# CONFIG_ARCH_MIPS is not set +# CONFIG_ARCH_MISOC is not set +# CONFIG_ARCH_RENESAS is not set +# CONFIG_ARCH_RISCV is not set +# CONFIG_ARCH_SIM is not set +# CONFIG_ARCH_X86 is not set +# CONFIG_ARCH_XTENSA is not set +# CONFIG_ARCH_Z16 is not set +# CONFIG_ARCH_Z80 is not set +CONFIG_ARCH="arm" + +# +# ARM Options +# +# CONFIG_ARCH_CHIP_A1X is not set +# CONFIG_ARCH_CHIP_C5471 is not set +# CONFIG_ARCH_CHIP_DM320 is not set +# CONFIG_ARCH_CHIP_EFM32 is not set +# CONFIG_ARCH_CHIP_IMX1 is not set +# CONFIG_ARCH_CHIP_IMX6 is not set +# CONFIG_ARCH_CHIP_KINETIS is not set +# CONFIG_ARCH_CHIP_KL is not set +# CONFIG_ARCH_CHIP_LM is not set +# CONFIG_ARCH_CHIP_TIVA is not set +# CONFIG_ARCH_CHIP_LPC11XX is not set +# CONFIG_ARCH_CHIP_LPC17XX is not set +# CONFIG_ARCH_CHIP_LPC214X is not set +# CONFIG_ARCH_CHIP_LPC2378 is not set +# CONFIG_ARCH_CHIP_LPC31XX is not set +# CONFIG_ARCH_CHIP_LPC43XX is not set +# CONFIG_ARCH_CHIP_MOXART is not set +# CONFIG_ARCH_CHIP_NUC1XX is not set +# CONFIG_ARCH_CHIP_SAMA5 is not set +# CONFIG_ARCH_CHIP_SAMD is not set +# CONFIG_ARCH_CHIP_SAML is not set +# CONFIG_ARCH_CHIP_SAM34 is not set +# CONFIG_ARCH_CHIP_SAMV7 is not set +CONFIG_ARCH_CHIP_STM32=y +# CONFIG_ARCH_CHIP_STM32F0 is not set +# CONFIG_ARCH_CHIP_STM32F7 is not set +# CONFIG_ARCH_CHIP_STM32L4 is not set +# CONFIG_ARCH_CHIP_STR71X is not set +# CONFIG_ARCH_CHIP_TMS570 is not set +# CONFIG_ARCH_CHIP_XMC4 is not set +# CONFIG_ARCH_ARM7TDMI is not set +# CONFIG_ARCH_ARM926EJS is not set +# CONFIG_ARCH_ARM920T is not set +# CONFIG_ARCH_CORTEXM0 is not set +# CONFIG_ARCH_CORTEXM23 is not set +# CONFIG_ARCH_CORTEXM3 is not set +# CONFIG_ARCH_CORTEXM33 is not set +CONFIG_ARCH_CORTEXM4=y +# CONFIG_ARCH_CORTEXM7 is not set +# CONFIG_ARCH_CORTEXA5 is not set +# CONFIG_ARCH_CORTEXA8 is not set +# CONFIG_ARCH_CORTEXA9 is not set +# CONFIG_ARCH_CORTEXR4 is not set +# CONFIG_ARCH_CORTEXR4F is not set +# CONFIG_ARCH_CORTEXR5 is not set +# CONFIG_ARCH_CORTEXR5F is not set +# CONFIG_ARCH_CORTEXR7 is not set +# CONFIG_ARCH_CORTEXR7F is not set +CONFIG_ARCH_FAMILY="armv7-m" +CONFIG_ARCH_CHIP="stm32" +# CONFIG_ARMV7M_USEBASEPRI is not set +CONFIG_ARCH_HAVE_CMNVECTOR=y +# CONFIG_ARMV7M_CMNVECTOR is not set +# CONFIG_ARMV7M_LAZYFPU is not set +CONFIG_ARCH_HAVE_FPU=y +# CONFIG_ARCH_HAVE_DPFPU is not set +CONFIG_ARCH_FPU=y +# CONFIG_ARCH_HAVE_TRUSTZONE is not set +CONFIG_ARM_HAVE_MPU_UNIFIED=y +# CONFIG_ARM_MPU is not set + +# +# ARMV7M Configuration Options +# +# CONFIG_ARMV7M_HAVE_ICACHE is not set +# CONFIG_ARMV7M_HAVE_DCACHE is not set +# CONFIG_ARMV7M_HAVE_ITCM is not set +# CONFIG_ARMV7M_HAVE_DTCM is not set +# CONFIG_ARMV7M_TOOLCHAIN_IARL is not set +# CONFIG_ARMV7M_TOOLCHAIN_BUILDROOT is not set +# CONFIG_ARMV7M_TOOLCHAIN_CODEREDL is not set +# CONFIG_ARMV7M_TOOLCHAIN_CODESOURCERYL is not set +CONFIG_ARMV7M_TOOLCHAIN_GNU_EABIL=y +CONFIG_ARMV7M_HAVE_STACKCHECK=y +# CONFIG_ARMV7M_STACKCHECK is not set +# CONFIG_ARMV7M_ITMSYSLOG is not set + +# +# STM32 Configuration Options +# +# CONFIG_ARCH_CHIP_STM32L151C6 is not set +# CONFIG_ARCH_CHIP_STM32L151C8 is not set +# CONFIG_ARCH_CHIP_STM32L151CB is not set +# CONFIG_ARCH_CHIP_STM32L151R6 is not set +# CONFIG_ARCH_CHIP_STM32L151R8 is not set +# CONFIG_ARCH_CHIP_STM32L151RB is not set +# CONFIG_ARCH_CHIP_STM32L151V6 is not set +# CONFIG_ARCH_CHIP_STM32L151V8 is not set +# CONFIG_ARCH_CHIP_STM32L151VB is not set +# CONFIG_ARCH_CHIP_STM32L152C6 is not set +# CONFIG_ARCH_CHIP_STM32L152C8 is not set +# CONFIG_ARCH_CHIP_STM32L152CB is not set +# CONFIG_ARCH_CHIP_STM32L152R6 is not set +# CONFIG_ARCH_CHIP_STM32L152R8 is not set +# CONFIG_ARCH_CHIP_STM32L152RB is not set +# CONFIG_ARCH_CHIP_STM32L152V6 is not set +# CONFIG_ARCH_CHIP_STM32L152V8 is not set +# CONFIG_ARCH_CHIP_STM32L152VB is not set +# CONFIG_ARCH_CHIP_STM32L152CC is not set +# CONFIG_ARCH_CHIP_STM32L152RC is not set +# CONFIG_ARCH_CHIP_STM32L152VC is not set +# CONFIG_ARCH_CHIP_STM32L162ZD is not set +# CONFIG_ARCH_CHIP_STM32L162VE is not set +# CONFIG_ARCH_CHIP_STM32F100C8 is not set +# CONFIG_ARCH_CHIP_STM32F100CB is not set +# CONFIG_ARCH_CHIP_STM32F100R8 is not set +# CONFIG_ARCH_CHIP_STM32F100RB is not set +# CONFIG_ARCH_CHIP_STM32F100RC is not set +# CONFIG_ARCH_CHIP_STM32F100RD is not set +# CONFIG_ARCH_CHIP_STM32F100RE is not set +# CONFIG_ARCH_CHIP_STM32F100V8 is not set +# CONFIG_ARCH_CHIP_STM32F100VB is not set +# CONFIG_ARCH_CHIP_STM32F100VC is not set +# CONFIG_ARCH_CHIP_STM32F100VD is not set +# CONFIG_ARCH_CHIP_STM32F100VE is not set +# CONFIG_ARCH_CHIP_STM32F102CB is not set +# CONFIG_ARCH_CHIP_STM32F103T8 is not set +# CONFIG_ARCH_CHIP_STM32F103TB is not set +# CONFIG_ARCH_CHIP_STM32F103C4 is not set +# CONFIG_ARCH_CHIP_STM32F103C8 is not set +# CONFIG_ARCH_CHIP_STM32F103CB is not set +# CONFIG_ARCH_CHIP_STM32F103R8 is not set +# CONFIG_ARCH_CHIP_STM32F103RB is not set +# CONFIG_ARCH_CHIP_STM32F103RC is not set +# CONFIG_ARCH_CHIP_STM32F103RD is not set +# CONFIG_ARCH_CHIP_STM32F103RE is not set +# CONFIG_ARCH_CHIP_STM32F103RG is not set +# CONFIG_ARCH_CHIP_STM32F103V8 is not set +# CONFIG_ARCH_CHIP_STM32F103VB is not set +# CONFIG_ARCH_CHIP_STM32F103VC is not set +# CONFIG_ARCH_CHIP_STM32F103VE is not set +# CONFIG_ARCH_CHIP_STM32F103ZE is not set +# CONFIG_ARCH_CHIP_STM32F105VB is not set +# CONFIG_ARCH_CHIP_STM32F105RB is not set +# CONFIG_ARCH_CHIP_STM32F107VC is not set +# CONFIG_ARCH_CHIP_STM32F205RG is not set +# CONFIG_ARCH_CHIP_STM32F207IG is not set +# CONFIG_ARCH_CHIP_STM32F207ZE is not set +# CONFIG_ARCH_CHIP_STM32F302K6 is not set +# CONFIG_ARCH_CHIP_STM32F302K8 is not set +# CONFIG_ARCH_CHIP_STM32F302CB is not set +# CONFIG_ARCH_CHIP_STM32F302CC is not set +# CONFIG_ARCH_CHIP_STM32F302RB is not set +# CONFIG_ARCH_CHIP_STM32F302RC is not set +# CONFIG_ARCH_CHIP_STM32F302VB is not set +# CONFIG_ARCH_CHIP_STM32F302VC is not set +# CONFIG_ARCH_CHIP_STM32F303K6 is not set +# CONFIG_ARCH_CHIP_STM32F303K8 is not set +# CONFIG_ARCH_CHIP_STM32F303C6 is not set +# CONFIG_ARCH_CHIP_STM32F303C8 is not set +# CONFIG_ARCH_CHIP_STM32F303CB is not set +# CONFIG_ARCH_CHIP_STM32F303CC is not set +# CONFIG_ARCH_CHIP_STM32F303RB is not set +# CONFIG_ARCH_CHIP_STM32F303RC is not set +# CONFIG_ARCH_CHIP_STM32F303RD is not set +# CONFIG_ARCH_CHIP_STM32F303RE is not set +# CONFIG_ARCH_CHIP_STM32F303VB is not set +# CONFIG_ARCH_CHIP_STM32F303VC is not set +# CONFIG_ARCH_CHIP_STM32F334K4 is not set +# CONFIG_ARCH_CHIP_STM32F334K6 is not set +# CONFIG_ARCH_CHIP_STM32F334K8 is not set +# CONFIG_ARCH_CHIP_STM32F334C4 is not set +# CONFIG_ARCH_CHIP_STM32F334C6 is not set +# CONFIG_ARCH_CHIP_STM32F334C8 is not set +# CONFIG_ARCH_CHIP_STM32F334R4 is not set +# CONFIG_ARCH_CHIP_STM32F334R6 is not set +# CONFIG_ARCH_CHIP_STM32F334R8 is not set +# CONFIG_ARCH_CHIP_STM32F372C8 is not set +# CONFIG_ARCH_CHIP_STM32F372R8 is not set +# CONFIG_ARCH_CHIP_STM32F372V8 is not set +# CONFIG_ARCH_CHIP_STM32F372CB is not set +# CONFIG_ARCH_CHIP_STM32F372RB is not set +# CONFIG_ARCH_CHIP_STM32F372VB is not set +# CONFIG_ARCH_CHIP_STM32F372CC is not set +# CONFIG_ARCH_CHIP_STM32F372RC is not set +# CONFIG_ARCH_CHIP_STM32F372VC is not set +# CONFIG_ARCH_CHIP_STM32F373C8 is not set +# CONFIG_ARCH_CHIP_STM32F373R8 is not set +# CONFIG_ARCH_CHIP_STM32F373V8 is not set +# CONFIG_ARCH_CHIP_STM32F373CB is not set +# CONFIG_ARCH_CHIP_STM32F373RB is not set +# CONFIG_ARCH_CHIP_STM32F373VB is not set +# CONFIG_ARCH_CHIP_STM32F373CC is not set +# CONFIG_ARCH_CHIP_STM32F373RC is not set +# CONFIG_ARCH_CHIP_STM32F373VC is not set +# CONFIG_ARCH_CHIP_STM32F401RE is not set +# CONFIG_ARCH_CHIP_STM32F410RB is not set +# CONFIG_ARCH_CHIP_STM32F411RE is not set +# CONFIG_ARCH_CHIP_STM32F411VE is not set +# CONFIG_ARCH_CHIP_STM32F405RG is not set +# CONFIG_ARCH_CHIP_STM32F405VG is not set +# CONFIG_ARCH_CHIP_STM32F405ZG is not set +# CONFIG_ARCH_CHIP_STM32F407VE is not set +CONFIG_ARCH_CHIP_STM32F407VG=y +# CONFIG_ARCH_CHIP_STM32F407ZE is not set +# CONFIG_ARCH_CHIP_STM32F407ZG is not set +# CONFIG_ARCH_CHIP_STM32F407IE is not set +# CONFIG_ARCH_CHIP_STM32F407IG is not set +# CONFIG_ARCH_CHIP_STM32F427V is not set +# CONFIG_ARCH_CHIP_STM32F427Z is not set +# CONFIG_ARCH_CHIP_STM32F427I is not set +# CONFIG_ARCH_CHIP_STM32F429V is not set +# CONFIG_ARCH_CHIP_STM32F429Z is not set +# CONFIG_ARCH_CHIP_STM32F429I is not set +# CONFIG_ARCH_CHIP_STM32F429B is not set +# CONFIG_ARCH_CHIP_STM32F429N is not set +# CONFIG_ARCH_CHIP_STM32F446M is not set +# CONFIG_ARCH_CHIP_STM32F446R is not set +# CONFIG_ARCH_CHIP_STM32F446V is not set +# CONFIG_ARCH_CHIP_STM32F446Z is not set +# CONFIG_ARCH_CHIP_STM32F469A is not set +# CONFIG_ARCH_CHIP_STM32F469I is not set +# CONFIG_ARCH_CHIP_STM32F469B is not set +# CONFIG_ARCH_CHIP_STM32F469N is not set +CONFIG_STM32_FLASH_CONFIG_DEFAULT=y +# CONFIG_STM32_FLASH_CONFIG_4 is not set +# CONFIG_STM32_FLASH_CONFIG_6 is not set +# CONFIG_STM32_FLASH_CONFIG_8 is not set +# CONFIG_STM32_FLASH_CONFIG_B is not set +# CONFIG_STM32_FLASH_CONFIG_C is not set +# CONFIG_STM32_FLASH_CONFIG_D is not set +# CONFIG_STM32_FLASH_CONFIG_E is not set +# CONFIG_STM32_FLASH_CONFIG_F is not set +# CONFIG_STM32_FLASH_CONFIG_G is not set +# CONFIG_STM32_FLASH_CONFIG_I is not set +# CONFIG_STM32_STM32L15XX is not set +# CONFIG_STM32_ENERGYLITE is not set +# CONFIG_STM32_STM32F10XX is not set +# CONFIG_STM32_VALUELINE is not set +# CONFIG_STM32_CONNECTIVITYLINE is not set +# CONFIG_STM32_PERFORMANCELINE is not set +# CONFIG_STM32_USBACCESSLINE is not set +# CONFIG_STM32_HIGHDENSITY is not set +# CONFIG_STM32_MEDIUMDENSITY is not set +# CONFIG_STM32_LOWDENSITY is not set +# CONFIG_STM32_STM32F20XX is not set +# CONFIG_STM32_STM32F205 is not set +# CONFIG_STM32_STM32F207 is not set +# CONFIG_STM32_STM32F30XX is not set +# CONFIG_STM32_STM32F302 is not set +# CONFIG_STM32_STM32F303 is not set +# CONFIG_STM32_STM32F33XX is not set +# CONFIG_STM32_STM32F37XX is not set +CONFIG_STM32_STM32F40XX=y +# CONFIG_STM32_STM32F401 is not set +# CONFIG_STM32_STM32F410 is not set +# CONFIG_STM32_STM32F411 is not set +# CONFIG_STM32_STM32F405 is not set +CONFIG_STM32_STM32F407=y +# CONFIG_STM32_STM32F427 is not set +# CONFIG_STM32_STM32F429 is not set +# CONFIG_STM32_STM32F446 is not set +# CONFIG_STM32_STM32F469 is not set +# CONFIG_STM32_DFU is not set + +# +# STM32 Peripheral Support +# +CONFIG_STM32_HAVE_CCM=y +# CONFIG_STM32_HAVE_USBDEV is not set +CONFIG_STM32_HAVE_OTGFS=y +CONFIG_STM32_HAVE_FSMC=y +# CONFIG_STM32_HAVE_HRTIM1 is not set +# CONFIG_STM32_HAVE_LTDC is not set +CONFIG_STM32_HAVE_USART3=y +CONFIG_STM32_HAVE_UART4=y +CONFIG_STM32_HAVE_UART5=y +CONFIG_STM32_HAVE_USART6=y +# CONFIG_STM32_HAVE_UART7 is not set +# CONFIG_STM32_HAVE_UART8 is not set +CONFIG_STM32_HAVE_TIM1=y +CONFIG_STM32_HAVE_TIM2=y +CONFIG_STM32_HAVE_TIM3=y +CONFIG_STM32_HAVE_TIM4=y +CONFIG_STM32_HAVE_TIM5=y +CONFIG_STM32_HAVE_TIM6=y +CONFIG_STM32_HAVE_TIM7=y +CONFIG_STM32_HAVE_TIM8=y +CONFIG_STM32_HAVE_TIM9=y +CONFIG_STM32_HAVE_TIM10=y +CONFIG_STM32_HAVE_TIM11=y +CONFIG_STM32_HAVE_TIM12=y +CONFIG_STM32_HAVE_TIM13=y +CONFIG_STM32_HAVE_TIM14=y +# CONFIG_STM32_HAVE_TIM15 is not set +# CONFIG_STM32_HAVE_TIM16 is not set +# CONFIG_STM32_HAVE_TIM17 is not set +CONFIG_STM32_HAVE_ADC2=y +CONFIG_STM32_HAVE_ADC3=y +# CONFIG_STM32_HAVE_ADC4 is not set +# CONFIG_STM32_HAVE_ADC1_DMA is not set +# CONFIG_STM32_HAVE_ADC2_DMA is not set +# CONFIG_STM32_HAVE_ADC3_DMA is not set +# CONFIG_STM32_HAVE_ADC4_DMA is not set +# CONFIG_STM32_HAVE_SDADC1 is not set +# CONFIG_STM32_HAVE_SDADC2 is not set +# CONFIG_STM32_HAVE_SDADC3 is not set +# CONFIG_STM32_HAVE_SDADC1_DMA is not set +# CONFIG_STM32_HAVE_SDADC2_DMA is not set +# CONFIG_STM32_HAVE_SDADC3_DMA is not set +CONFIG_STM32_HAVE_CAN1=y +CONFIG_STM32_HAVE_CAN2=y +# CONFIG_STM32_HAVE_COMP1 is not set +# CONFIG_STM32_HAVE_COMP2 is not set +# CONFIG_STM32_HAVE_COMP3 is not set +# CONFIG_STM32_HAVE_COMP4 is not set +# CONFIG_STM32_HAVE_COMP5 is not set +# CONFIG_STM32_HAVE_COMP6 is not set +# CONFIG_STM32_HAVE_COMP7 is not set +CONFIG_STM32_HAVE_DAC1=y +CONFIG_STM32_HAVE_DAC2=y +CONFIG_STM32_HAVE_RNG=y +CONFIG_STM32_HAVE_ETHMAC=y +CONFIG_STM32_HAVE_I2C2=y +CONFIG_STM32_HAVE_I2C3=y +CONFIG_STM32_HAVE_SPI2=y +CONFIG_STM32_HAVE_SPI3=y +CONFIG_STM32_HAVE_I2S3=y +# CONFIG_STM32_HAVE_SPI4 is not set +# CONFIG_STM32_HAVE_SPI5 is not set +# CONFIG_STM32_HAVE_SPI6 is not set +# CONFIG_STM32_HAVE_SAIPLL is not set +# CONFIG_STM32_HAVE_I2SPLL is not set +# CONFIG_STM32_HAVE_OPAMP1 is not set +# CONFIG_STM32_HAVE_OPAMP2 is not set +# CONFIG_STM32_HAVE_OPAMP3 is not set +# CONFIG_STM32_HAVE_OPAMP4 is not set +# CONFIG_STM32_ADC1 is not set +# CONFIG_STM32_ADC2 is not set +# CONFIG_STM32_ADC3 is not set +# CONFIG_STM32_BKPSRAM is not set +# CONFIG_STM32_CAN1 is not set +# CONFIG_STM32_CAN2 is not set +# CONFIG_STM32_CCMDATARAM is not set +# CONFIG_STM32_CRC is not set +# CONFIG_STM32_CRYP is not set +# CONFIG_STM32_DMA1 is not set +# CONFIG_STM32_DMA2 is not set +# CONFIG_STM32_DAC1 is not set +# CONFIG_STM32_DAC2 is not set +# CONFIG_STM32_DCMI is not set +# CONFIG_STM32_ETHMAC is not set +# CONFIG_STM32_FSMC is not set +# CONFIG_STM32_HASH is not set +# CONFIG_STM32_I2C1 is not set +# CONFIG_STM32_I2C2 is not set +# CONFIG_STM32_I2C3 is not set +# CONFIG_STM32_OPAMP is not set +CONFIG_STM32_OTGFS=y +# CONFIG_STM32_OTGHS is not set +CONFIG_STM32_PWR=y +# CONFIG_STM32_RNG is not set +# CONFIG_STM32_SDIO is not set +# CONFIG_STM32_SPI1 is not set +# CONFIG_STM32_SPI2 is not set +CONFIG_STM32_SPI3=y +# CONFIG_STM32_I2S3 is not set +CONFIG_STM32_SYSCFG=y +# CONFIG_STM32_TIM1 is not set +# CONFIG_STM32_TIM2 is not set +# CONFIG_STM32_TIM3 is not set +# CONFIG_STM32_TIM4 is not set +# CONFIG_STM32_TIM5 is not set +# CONFIG_STM32_TIM6 is not set +# CONFIG_STM32_TIM7 is not set +# CONFIG_STM32_TIM8 is not set +# CONFIG_STM32_TIM9 is not set +# CONFIG_STM32_TIM10 is not set +# CONFIG_STM32_TIM11 is not set +# CONFIG_STM32_TIM12 is not set +# CONFIG_STM32_TIM13 is not set +# CONFIG_STM32_TIM14 is not set +# CONFIG_STM32_USART1 is not set +# CONFIG_STM32_USART2 is not set +# CONFIG_STM32_USART3 is not set +# CONFIG_STM32_UART4 is not set +# CONFIG_STM32_UART5 is not set +# CONFIG_STM32_USART6 is not set +# CONFIG_STM32_IWDG is not set +# CONFIG_STM32_WWDG is not set +CONFIG_STM32_SPI=y +# CONFIG_STM32_NOEXT_VECTORS is not set + +# +# Alternate Pin Mapping +# +# CONFIG_STM32_FLASH_PREFETCH is not set +# CONFIG_STM32_FLASH_WORKAROUND_DATA_CACHE_CORRUPTION_ON_RWW is not set +# CONFIG_STM32_JTAG_DISABLE is not set +# CONFIG_STM32_JTAG_FULL_ENABLE is not set +# CONFIG_STM32_JTAG_NOJNTRST_ENABLE is not set +CONFIG_STM32_JTAG_SW_ENABLE=y +CONFIG_STM32_DISABLE_IDLE_SLEEP_DURING_DEBUG=y +# CONFIG_STM32_FORCEPOWER is not set +# CONFIG_ARCH_BOARD_STM32_CUSTOM_CLOCKCONFIG is not set +CONFIG_STM32_CCMEXCLUDE=y + +# +# Timer Configuration +# +# CONFIG_STM32_ONESHOT is not set +# CONFIG_STM32_FREERUN is not set +# CONFIG_STM32_TIM1_CAP is not set +# CONFIG_STM32_TIM2_CAP is not set +# CONFIG_STM32_TIM3_CAP is not set +# CONFIG_STM32_TIM4_CAP is not set +# CONFIG_STM32_TIM5_CAP is not set +# CONFIG_STM32_TIM8_CAP is not set +# CONFIG_STM32_TIM9_CAP is not set +# CONFIG_STM32_TIM10_CAP is not set +# CONFIG_STM32_TIM11_CAP is not set +# CONFIG_STM32_TIM12_CAP is not set +# CONFIG_STM32_TIM13_CAP is not set +# CONFIG_STM32_TIM14_CAP is not set + +# +# SPI Configuration +# +# CONFIG_STM32_SPI_INTERRUPTS is not set +# CONFIG_STM32_SPI_DMA is not set +# CONFIG_STM32_HAVE_RTC_COUNTER is not set +# CONFIG_STM32_HAVE_RTC_SUBSECONDS is not set + +# +# USB FS Host Configuration +# + +# +# USB HS Host Configuration +# + +# +# USB Host Debug Configuration +# + +# +# USB Device Configuration +# +# CONFIG_ARCH_TOOLCHAIN_IAR is not set +CONFIG_ARCH_TOOLCHAIN_GNU=y + +# +# Architecture Options +# +# CONFIG_ARCH_NOINTC is not set +# CONFIG_ARCH_VECNOTIRQ is not set +# CONFIG_ARCH_DMA is not set +CONFIG_ARCH_HAVE_IRQPRIO=y +# CONFIG_ARCH_L2CACHE is not set +# CONFIG_ARCH_HAVE_COHERENT_DCACHE is not set +# CONFIG_ARCH_HAVE_ADDRENV is not set +# CONFIG_ARCH_NEED_ADDRENV_MAPPING is not set +# CONFIG_ARCH_HAVE_MULTICPU is not set +CONFIG_ARCH_HAVE_VFORK=y +# CONFIG_ARCH_HAVE_MMU is not set +CONFIG_ARCH_HAVE_MPU=y +# CONFIG_ARCH_NAND_HWECC is not set +# CONFIG_ARCH_HAVE_EXTCLK is not set +# CONFIG_ARCH_HAVE_POWEROFF is not set +CONFIG_ARCH_HAVE_RESET=y +# CONFIG_ARCH_HAVE_RTC_SUBSECONDS is not set +# CONFIG_ARCH_USE_MPU is not set +# CONFIG_ARCH_IRQPRIO is not set +CONFIG_ARCH_STACKDUMP=y +# CONFIG_ENDIAN_BIG is not set +# CONFIG_ARCH_IDLE_CUSTOM is not set +# CONFIG_ARCH_HAVE_RAMFUNCS is not set +CONFIG_ARCH_HAVE_RAMVECTORS=y +# CONFIG_ARCH_RAMVECTORS is not set +# CONFIG_ARCH_MINIMAL_VECTORTABLE is not set + +# +# Board Settings +# +CONFIG_BOARD_LOOPSPERMSEC=16717 +# CONFIG_ARCH_CALIBRATION is not set + +# +# Interrupt options +# +CONFIG_ARCH_HAVE_INTERRUPTSTACK=y +CONFIG_ARCH_INTERRUPTSTACK=0 +CONFIG_ARCH_HAVE_HIPRI_INTERRUPT=y +# CONFIG_ARCH_HIPRI_INTERRUPT is not set + +# +# Boot options +# +# CONFIG_BOOT_RUNFROMEXTSRAM is not set +CONFIG_BOOT_RUNFROMFLASH=y +# CONFIG_BOOT_RUNFROMISRAM is not set +# CONFIG_BOOT_RUNFROMSDRAM is not set +# CONFIG_BOOT_COPYTORAM is not set + +# +# Boot Memory Configuration +# +CONFIG_RAM_START=0x20000000 +CONFIG_RAM_SIZE=131072 +# CONFIG_ARCH_HAVE_SDRAM is not set + +# +# Board Selection +# +CONFIG_ARCH_BOARD_CLICKER2_STM32=y +# CONFIG_ARCH_BOARD_STM32F4_DISCOVERY is not set +# CONFIG_ARCH_BOARD_MIKROE_STM32F4 is not set +# CONFIG_ARCH_BOARD_CUSTOM is not set +CONFIG_ARCH_BOARD="clicker2-stm32" + +# +# Common Board Options +# +CONFIG_ARCH_HAVE_LEDS=y +CONFIG_ARCH_LEDS=y +CONFIG_ARCH_HAVE_BUTTONS=y +CONFIG_ARCH_BUTTONS=y +CONFIG_ARCH_HAVE_IRQBUTTONS=y +CONFIG_ARCH_IRQBUTTONS=y + +# +# Board-Specific Options +# +CONFIG_CLICKER2_STM32_MB1_SPI=y +# CONFIG_CLICKER2_STM32_MB2_SPI is not set +CONFIG_CLICKER2_STM32_MB1_BEE=y +# CONFIG_CLICKER2_STM32_MB2_BEE is not set +# CONFIG_BOARD_CRASHDUMP is not set +CONFIG_LIB_BOARDCTL=y +# CONFIG_BOARDCTL_RESET is not set +# CONFIG_BOARDCTL_UNIQUEID is not set +CONFIG_BOARDCTL_USBDEVCTRL=y +# CONFIG_BOARDCTL_TSCTEST is not set +# CONFIG_BOARDCTL_GRAPHICS is not set +# CONFIG_BOARDCTL_IOCTL is not set + +# +# RTOS Features +# +CONFIG_DISABLE_OS_API=y +# CONFIG_DISABLE_POSIX_TIMERS is not set +# CONFIG_DISABLE_PTHREAD is not set +# CONFIG_DISABLE_SIGNALS is not set +# CONFIG_DISABLE_MQUEUE is not set +# CONFIG_DISABLE_ENVIRON is not set + +# +# Clocks and Timers +# +CONFIG_ARCH_HAVE_TICKLESS=y +# CONFIG_SCHED_TICKLESS is not set +CONFIG_USEC_PER_TICK=10000 +# CONFIG_SYSTEM_TIME64 is not set +# CONFIG_CLOCK_MONOTONIC is not set +CONFIG_ARCH_HAVE_TIMEKEEPING=y +# CONFIG_JULIAN_TIME is not set +CONFIG_START_YEAR=2013 +CONFIG_START_MONTH=1 +CONFIG_START_DAY=1 +CONFIG_MAX_WDOGPARMS=2 +CONFIG_PREALLOC_WDOGS=16 +CONFIG_WDOG_INTRESERVE=4 +CONFIG_PREALLOC_TIMERS=4 + +# +# Tasks and Scheduling +# +# CONFIG_SPINLOCK is not set +# CONFIG_INIT_NONE is not set +CONFIG_INIT_ENTRYPOINT=y +# CONFIG_INIT_FILEPATH is not set +CONFIG_USER_ENTRYPOINT="nsh_main" +CONFIG_RR_INTERVAL=200 +# CONFIG_SCHED_SPORADIC is not set +CONFIG_TASK_NAME_SIZE=32 +CONFIG_MAX_TASKS=16 +# CONFIG_SCHED_HAVE_PARENT is not set +CONFIG_SCHED_WAITPID=y + +# +# Pthread Options +# +# CONFIG_PTHREAD_MUTEX_TYPES is not set +CONFIG_PTHREAD_MUTEX_ROBUST=y +# CONFIG_PTHREAD_MUTEX_UNSAFE is not set +# CONFIG_PTHREAD_MUTEX_BOTH is not set +CONFIG_NPTHREAD_KEYS=4 +# CONFIG_PTHREAD_CLEANUP is not set +# CONFIG_CANCELLATION_POINTS is not set + +# +# Performance Monitoring +# +# CONFIG_SCHED_CPULOAD is not set +# CONFIG_SCHED_INSTRUMENTATION is not set + +# +# Files and I/O +# +# CONFIG_DEV_CONSOLE is not set +# CONFIG_FDCLONE_DISABLE is not set +# CONFIG_FDCLONE_STDIO is not set +CONFIG_SDCLONE_DISABLE=y +CONFIG_NFILE_DESCRIPTORS=8 +CONFIG_NFILE_STREAMS=8 +CONFIG_NAME_MAX=32 +# CONFIG_PRIORITY_INHERITANCE is not set + +# +# RTOS hooks +# +CONFIG_BOARD_INITIALIZE=y +# CONFIG_BOARD_INITTHREAD is not set +# CONFIG_SCHED_STARTHOOK is not set +# CONFIG_SCHED_ATEXIT is not set +# CONFIG_SCHED_ONEXIT is not set +# CONFIG_SIG_EVTHREAD is not set + +# +# Signal Numbers +# +CONFIG_SIG_SIGUSR1=1 +CONFIG_SIG_SIGUSR2=2 +CONFIG_SIG_SIGALARM=3 +CONFIG_SIG_SIGCONDTIMEDOUT=16 +CONFIG_SIG_SIGWORK=17 + +# +# POSIX Message Queue Options +# +CONFIG_PREALLOC_MQ_MSGS=4 +CONFIG_MQ_MAXMSGSIZE=32 +# CONFIG_MODULE is not set + +# +# Work queue support +# +CONFIG_SCHED_WORKQUEUE=y +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_HPWORKPRIORITY=192 +CONFIG_SCHED_HPWORKPERIOD=50000 +CONFIG_SCHED_HPWORKSTACKSIZE=2048 +# CONFIG_SCHED_LPWORK is not set + +# +# Stack and heap information +# +CONFIG_IDLETHREAD_STACKSIZE=1024 +CONFIG_USERMAIN_STACKSIZE=2048 +CONFIG_PTHREAD_STACK_MIN=256 +CONFIG_PTHREAD_STACK_DEFAULT=2048 +# CONFIG_LIB_SYSCALL is not set + +# +# Device Drivers +# +CONFIG_DISABLE_POLL=y +CONFIG_DEV_NULL=y +# CONFIG_DEV_ZERO is not set +# CONFIG_DEV_URANDOM is not set +# CONFIG_DEV_LOOP is not set + +# +# Buffering +# +# CONFIG_DRVR_WRITEBUFFER is not set +# CONFIG_DRVR_READAHEAD is not set +# CONFIG_RAMDISK is not set +# CONFIG_CAN is not set +# CONFIG_ARCH_HAVE_PWM_PULSECOUNT is not set +# CONFIG_ARCH_HAVE_PWM_MULTICHAN is not set +# CONFIG_PWM is not set +CONFIG_ARCH_HAVE_I2CRESET=y +# CONFIG_I2C is not set +# CONFIG_ARCH_HAVE_SPI_CRCGENERATION is not set +# CONFIG_ARCH_HAVE_SPI_CS_CONTROL is not set +CONFIG_ARCH_HAVE_SPI_BITORDER=y +CONFIG_SPI=y +# CONFIG_SPI_SLAVE is not set +CONFIG_SPI_EXCHANGE=y +# CONFIG_SPI_CMDDATA is not set +# CONFIG_SPI_CALLBACK is not set +# CONFIG_SPI_HWFEATURES is not set +# CONFIG_SPI_BITORDER is not set +# CONFIG_SPI_CS_DELAY_CONTROL is not set +# CONFIG_SPI_DRIVER is not set +# CONFIG_SPI_BITBANG is not set +# CONFIG_I2S is not set + +# +# Timer Driver Support +# +# CONFIG_TIMER is not set +# CONFIG_ONESHOT is not set +# CONFIG_RTC is not set +# CONFIG_WATCHDOG is not set +# CONFIG_ANALOG is not set +# CONFIG_AUDIO_DEVICES is not set +# CONFIG_VIDEO_DEVICES is not set +# CONFIG_BCH is not set +# CONFIG_INPUT is not set + +# +# IO Expander/GPIO Support +# +# CONFIG_IOEXPANDER is not set +# CONFIG_DEV_GPIO is not set + +# +# LCD Driver Support +# +# CONFIG_LCD is not set +# CONFIG_SLCD is not set + +# +# LED Support +# +# CONFIG_USERLED is not set +# CONFIG_RGBLED is not set +# CONFIG_PCA9635PW is not set +# CONFIG_NCP5623C is not set +# CONFIG_MMCSD is not set +# CONFIG_MODEM is not set +# CONFIG_MTD is not set +# CONFIG_EEPROM is not set +# CONFIG_PIPES is not set +# CONFIG_PM is not set +# CONFIG_POWER is not set +# CONFIG_SENSORS is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_REMOVABLE=y +# CONFIG_SERIAL_CONSOLE is not set +# CONFIG_16550_UART is not set +# CONFIG_UART_SERIALDRIVER is not set +# CONFIG_UART0_SERIALDRIVER is not set +# CONFIG_UART1_SERIALDRIVER is not set +# CONFIG_UART2_SERIALDRIVER is not set +# CONFIG_UART3_SERIALDRIVER is not set +# CONFIG_UART4_SERIALDRIVER is not set +# CONFIG_UART5_SERIALDRIVER is not set +# CONFIG_UART6_SERIALDRIVER is not set +# CONFIG_UART7_SERIALDRIVER is not set +# CONFIG_UART8_SERIALDRIVER is not set +# CONFIG_SCI0_SERIALDRIVER is not set +# CONFIG_SCI1_SERIALDRIVER is not set +# CONFIG_USART0_SERIALDRIVER is not set +# CONFIG_USART1_SERIALDRIVER is not set +# CONFIG_USART2_SERIALDRIVER is not set +# CONFIG_USART3_SERIALDRIVER is not set +# CONFIG_USART4_SERIALDRIVER is not set +# CONFIG_USART5_SERIALDRIVER is not set +# CONFIG_USART6_SERIALDRIVER is not set +# CONFIG_USART7_SERIALDRIVER is not set +# CONFIG_USART8_SERIALDRIVER is not set +# CONFIG_OTHER_UART_SERIALDRIVER is not set +# CONFIG_MCU_SERIAL is not set +CONFIG_STANDARD_SERIAL=y +# CONFIG_SERIAL_IFLOWCONTROL is not set +# CONFIG_SERIAL_OFLOWCONTROL is not set +# CONFIG_SERIAL_DMA is not set +# CONFIG_ARCH_HAVE_SERIAL_TERMIOS is not set +# CONFIG_PSEUDOTERM is not set +CONFIG_USBDEV=y + +# +# USB Device Controller Driver Options +# +# CONFIG_USBDEV_ISOCHRONOUS is not set +# CONFIG_USBDEV_DUALSPEED is not set +CONFIG_USBDEV_SELFPOWERED=y +# CONFIG_USBDEV_BUSPOWERED is not set +CONFIG_USBDEV_MAXPOWER=100 +# CONFIG_USBDEV_DMA is not set +# CONFIG_ARCH_USBDEV_STALLQUEUE is not set +# CONFIG_USBDEV_TRACE is not set + +# +# USB Device Class Driver Options +# +# CONFIG_USBDEV_COMPOSITE is not set +# CONFIG_PL2303 is not set +CONFIG_CDCACM=y +CONFIG_CDCACM_CONSOLE=y +CONFIG_CDCACM_EP0MAXPACKET=64 +CONFIG_CDCACM_EPINTIN=1 +CONFIG_CDCACM_EPINTIN_FSSIZE=64 +CONFIG_CDCACM_EPINTIN_HSSIZE=64 +CONFIG_CDCACM_EPBULKOUT=3 +CONFIG_CDCACM_EPBULKOUT_FSSIZE=64 +CONFIG_CDCACM_EPBULKOUT_HSSIZE=512 +CONFIG_CDCACM_EPBULKIN=2 +CONFIG_CDCACM_EPBULKIN_FSSIZE=64 +CONFIG_CDCACM_EPBULKIN_HSSIZE=512 +CONFIG_CDCACM_NRDREQS=4 +CONFIG_CDCACM_NWRREQS=4 +CONFIG_CDCACM_BULKIN_REQLEN=96 +CONFIG_CDCACM_RXBUFSIZE=256 +CONFIG_CDCACM_TXBUFSIZE=256 +CONFIG_CDCACM_VENDORID=0x0525 +CONFIG_CDCACM_PRODUCTID=0xa4a7 +CONFIG_CDCACM_VENDORSTR="NuttX" +CONFIG_CDCACM_PRODUCTSTR="CDC/ACM Serial" +# CONFIG_USBMSC is not set +# CONFIG_USBHOST is not set +# CONFIG_USBMISC is not set +# CONFIG_HAVE_USBTRACE is not set +CONFIG_DRIVERS_WIRELESS=y +# CONFIG_WL_CC1101 is not set +# CONFIG_WL_CC3000 is not set +CONFIG_DRIVERS_IEEE802154=y +CONFIG_IEEE802154_MRF24J40=y +# CONFIG_IEEE802154_AT86RF233 is not set +# CONFIG_DRIVERS_IEEE80211 is not set +# CONFIG_WL_NRF24L01 is not set +# CONFIG_DRIVERS_CONTACTLESS is not set + +# +# System Logging +# +# CONFIG_ARCH_SYSLOG is not set +# CONFIG_SYSLOG_WRITE is not set +CONFIG_RAMLOG=y +CONFIG_RAMLOG_BUFSIZE=8192 +# CONFIG_RAMLOG_CRLF is not set +CONFIG_RAMLOG_NONBLOCKING=y +# CONFIG_SYSLOG_INTBUFFER is not set +# CONFIG_SYSLOG_TIMESTAMP is not set +# CONFIG_SYSLOG_SERIAL_CONSOLE is not set +# CONFIG_SYSLOG_CHAR is not set +CONFIG_RAMLOG_SYSLOG=y +# CONFIG_SYSLOG_NONE is not set +# CONFIG_SYSLOG_FILE is not set +# CONFIG_SYSLOG_CHARDEV is not set + +# +# Networking Support +# +# CONFIG_ARCH_HAVE_NET is not set +# CONFIG_ARCH_HAVE_PHY is not set +# CONFIG_NET is not set + +# +# Crypto API +# +# CONFIG_CRYPTO is not set + +# +# File Systems +# + +# +# File system configuration +# +# CONFIG_DISABLE_MOUNTPOINT is not set +# CONFIG_FS_AUTOMOUNTER is not set +# CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set +# CONFIG_PSEUDOFS_SOFTLINKS is not set +CONFIG_FS_READABLE=y +CONFIG_FS_WRITABLE=y +# CONFIG_FS_NAMED_SEMAPHORES is not set +CONFIG_FS_MQUEUE_MPATH="/var/mqueue" +# CONFIG_FS_RAMMAP is not set +CONFIG_FS_FAT=y +CONFIG_FAT_LCNAMES=y +CONFIG_FAT_LFN=y +CONFIG_FAT_MAXFNAME=32 +# CONFIG_FS_FATTIME is not set +# CONFIG_FAT_FORCE_INDIRECT is not set +# CONFIG_FAT_DMAMEMORY is not set +# CONFIG_FAT_DIRECT_RETRY is not set +# CONFIG_FS_NXFFS is not set +# CONFIG_FS_ROMFS is not set +# CONFIG_FS_TMPFS is not set +# CONFIG_FS_SMARTFS is not set +# CONFIG_FS_BINFS is not set +CONFIG_FS_PROCFS=y +# CONFIG_FS_PROCFS_REGISTER is not set + +# +# Exclude individual procfs entries +# +# CONFIG_FS_PROCFS_EXCLUDE_PROCESS is not set +# CONFIG_FS_PROCFS_EXCLUDE_UPTIME is not set +# CONFIG_FS_PROCFS_EXCLUDE_MOUNTS is not set +# CONFIG_FS_UNIONFS is not set + +# +# Graphics Support +# +# CONFIG_NX is not set + +# +# Memory Management +# +# CONFIG_MM_SMALL is not set +CONFIG_MM_REGIONS=1 +# CONFIG_ARCH_HAVE_HEAP2 is not set +# CONFIG_GRAN is not set + +# +# Common I/O Buffer Support +# +CONFIG_MM_IOB=y +CONFIG_IOB_NBUFFERS=8 +CONFIG_IOB_BUFSIZE=196 +CONFIG_IOB_NCHAINS=0 +CONFIG_IOB_THROTTLE=0 + +# +# Audio Support +# +# CONFIG_AUDIO is not set + +# +# Wireless Support +# +CONFIG_WIRELESS=y +CONFIG_WIRELESS_IEEE802154=y +CONFIG_IEEE802154_DEFAULT_EADDR=0x00fade00deadbeef +CONFIG_IEEE802154_MAC_DEV=y +CONFIG_MAC802154_HPWORK=y +CONFIG_IEEE802154_NTXDESC=3 +CONFIG_IEEE802154_IND_PREALLOC=20 +CONFIG_IEEE802154_IND_IRQRESERVE=10 + +# +# Binary Loader +# +# CONFIG_BINFMT_DISABLE is not set +# CONFIG_BINFMT_EXEPATH is not set +# CONFIG_NXFLAT is not set +# CONFIG_ELF is not set +CONFIG_BUILTIN=y +# CONFIG_PIC is not set +# CONFIG_SYMTAB_ORDEREDBYNAME is not set + +# +# Library Routines +# + +# +# Standard C Library Options +# + +# +# Standard C I/O +# +# CONFIG_STDIO_DISABLE_BUFFERING is not set +CONFIG_STDIO_BUFFER_SIZE=64 +CONFIG_STDIO_LINEBUFFER=y +CONFIG_NUNGET_CHARS=2 +# CONFIG_NOPRINTF_FIELDWIDTH is not set +# CONFIG_LIBC_FLOATINGPOINT is not set +CONFIG_LIBC_LONG_LONG=y +# CONFIG_LIBC_SCANSET is not set +# CONFIG_EOL_IS_CR is not set +# CONFIG_EOL_IS_LF is not set +# CONFIG_EOL_IS_BOTH_CRLF is not set +CONFIG_EOL_IS_EITHER_CRLF=y +# CONFIG_MEMCPY_VIK is not set +# CONFIG_LIBM is not set + +# +# Architecture-Specific Support +# +CONFIG_ARCH_LOWPUTC=y +# CONFIG_ARCH_ROMGETC is not set +# CONFIG_LIBC_ARCH_MEMCPY is not set +# CONFIG_LIBC_ARCH_MEMCMP is not set +# CONFIG_LIBC_ARCH_MEMMOVE is not set +# CONFIG_LIBC_ARCH_MEMSET is not set +# CONFIG_LIBC_ARCH_STRCHR is not set +# CONFIG_LIBC_ARCH_STRCMP is not set +# CONFIG_LIBC_ARCH_STRCPY is not set +# CONFIG_LIBC_ARCH_STRNCPY is not set +# CONFIG_LIBC_ARCH_STRLEN is not set +# CONFIG_LIBC_ARCH_STRNLEN is not set +# CONFIG_LIBC_ARCH_ELF is not set +# CONFIG_ARMV7M_MEMCPY is not set + +# +# stdlib Options +# +CONFIG_LIB_RAND_ORDER=1 +CONFIG_LIB_HOMEDIR="/" +CONFIG_LIBC_TMPDIR="/tmp" +CONFIG_LIBC_MAX_TMPFILE=32 + +# +# Program Execution Options +# +# CONFIG_LIBC_EXECFUNCS is not set +CONFIG_POSIX_SPAWN_PROXY_STACKSIZE=1024 +CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE=2048 + +# +# errno Decode Support +# +# CONFIG_LIBC_STRERROR is not set +# CONFIG_LIBC_PERROR_STDOUT is not set + +# +# memcpy/memset Options +# +# CONFIG_MEMSET_OPTSPEED is not set +# CONFIG_LIBC_DLLFCN is not set +# CONFIG_LIBC_MODLIB is not set +# CONFIG_LIBC_WCHAR is not set +# CONFIG_LIBC_LOCALE is not set + +# +# Time/Time Zone Support +# +# CONFIG_LIBC_LOCALTIME is not set +# CONFIG_TIME_EXTENDED is not set +CONFIG_ARCH_HAVE_TLS=y + +# +# Thread Local Storage (TLS) +# +# CONFIG_TLS is not set + +# +# Network-Related Options +# +# CONFIG_LIBC_IPv4_ADDRCONV is not set +# CONFIG_LIBC_IPv6_ADDRCONV is not set +# CONFIG_LIBC_NETDB is not set + +# +# NETDB Support +# +# CONFIG_NETDB_HOSTFILE is not set +# CONFIG_LIBC_IOCTL_VARIADIC is not set +CONFIG_LIB_SENDFILE_BUFSIZE=512 + +# +# Non-standard Library Support +# +# CONFIG_LIB_CRC64_FAST is not set +# CONFIG_LIB_KBDCODEC is not set +# CONFIG_LIB_SLCDCODEC is not set +# CONFIG_LIB_HEX2BIN is not set + +# +# Basic CXX Support +# +# CONFIG_C99_BOOL8 is not set +CONFIG_HAVE_CXX=y +# CONFIG_CXX_NEWLONG is not set + +# +# LLVM C++ Library (libcxx) +# +# CONFIG_LIBCXX is not set + +# +# uClibc++ Standard C++ Library +# +# CONFIG_UCLIBCXX is not set + +# +# Application Configuration +# + +# +# Built-In Applications +# +CONFIG_BUILTIN_PROXY_STACKSIZE=1024 + +# +# CAN Utilities +# + +# +# Examples +# +# CONFIG_EXAMPLES_BUTTONS is not set +# CONFIG_EXAMPLES_CCTYPE is not set +# CONFIG_EXAMPLES_CHAT is not set +# CONFIG_EXAMPLES_CONFIGDATA is not set +# CONFIG_EXAMPLES_CXXTEST is not set +# CONFIG_EXAMPLES_DHCPD is not set +# CONFIG_EXAMPLES_ELF is not set +# CONFIG_EXAMPLES_FSTEST is not set +# CONFIG_EXAMPLES_FTPC is not set +# CONFIG_EXAMPLES_FTPD is not set +# CONFIG_EXAMPLES_HELLO is not set +# CONFIG_EXAMPLES_HELLOXX is not set +# CONFIG_EXAMPLES_HIDKBD is not set +# CONFIG_EXAMPLES_IGMP is not set +# CONFIG_EXAMPLES_JSON is not set +# CONFIG_EXAMPLES_KEYPADTEST is not set +# CONFIG_EXAMPLES_MEDIA is not set +# CONFIG_EXAMPLES_MM is not set +# CONFIG_EXAMPLES_MODBUS is not set +# CONFIG_EXAMPLES_MOUNT is not set +# CONFIG_EXAMPLES_NRF24L01TERM is not set +CONFIG_EXAMPLES_NSH=y +CONFIG_EXAMPLES_NSH_CXXINITIALIZE=y +# CONFIG_EXAMPLES_NULL is not set +# CONFIG_EXAMPLES_NX is not set +# CONFIG_EXAMPLES_NXFFS is not set +# CONFIG_EXAMPLES_NXHELLO is not set +# CONFIG_EXAMPLES_NXIMAGE is not set +# CONFIG_EXAMPLES_NXLINES is not set +# CONFIG_EXAMPLES_NXTERM is not set +# CONFIG_EXAMPLES_NXTEXT is not set +# CONFIG_EXAMPLES_OSTEST is not set +# CONFIG_EXAMPLES_PCA9635 is not set +# CONFIG_EXAMPLES_POSIXSPAWN is not set +# CONFIG_EXAMPLES_PPPD is not set +# CONFIG_EXAMPLES_RFID_READUID is not set +# CONFIG_EXAMPLES_RGBLED is not set +# CONFIG_EXAMPLES_SENDMAIL is not set +# CONFIG_EXAMPLES_SERIALBLASTER is not set +# CONFIG_EXAMPLES_SERIALRX is not set +# CONFIG_EXAMPLES_SERLOOP is not set +# CONFIG_EXAMPLES_SLCD is not set +# CONFIG_EXAMPLES_SMART is not set +# CONFIG_EXAMPLES_SMART_TEST is not set +# CONFIG_EXAMPLES_SMP is not set +# CONFIG_EXAMPLES_STAT is not set +# CONFIG_EXAMPLES_TCPECHO is not set +# CONFIG_EXAMPLES_TELNETD is not set +# CONFIG_EXAMPLES_TIFF is not set +# CONFIG_EXAMPLES_TOUCHSCREEN is not set +# CONFIG_EXAMPLES_USBSERIAL is not set +# CONFIG_EXAMPLES_WATCHDOG is not set +# CONFIG_EXAMPLES_WEBSERVER is not set +# CONFIG_EXAMPLES_XBC_TEST is not set + +# +# File System Utilities +# +# CONFIG_FSUTILS_INIFILE is not set +# CONFIG_FSUTILS_PASSWD is not set + +# +# GPS Utilities +# +# CONFIG_GPSUTILS_MINMEA_LIB is not set + +# +# Graphics Support +# +# CONFIG_TIFF is not set +# CONFIG_GRAPHICS_TRAVELER is not set + +# +# Interpreters +# +# CONFIG_INTERPRETERS_BAS is not set +# CONFIG_INTERPRETERS_FICL is not set +# CONFIG_INTERPRETERS_MICROPYTHON is not set +# CONFIG_INTERPRETERS_MINIBASIC is not set +# CONFIG_INTERPRETERS_PCODE is not set + +# +# FreeModBus +# +# CONFIG_MODBUS is not set + +# +# Network Utilities +# +# CONFIG_NETUTILS_CODECS is not set +# CONFIG_NETUTILS_ESP8266 is not set +# CONFIG_NETUTILS_FTPC is not set +# CONFIG_NETUTILS_JSON is not set +# CONFIG_NETUTILS_SMTP is not set + +# +# NSH Library +# +CONFIG_NSH_LIBRARY=y +# CONFIG_NSH_MOTD is not set + +# +# Command Line Configuration +# +CONFIG_NSH_READLINE=y +# CONFIG_NSH_CLE is not set +CONFIG_NSH_LINELEN=64 +# CONFIG_NSH_DISABLE_SEMICOLON is not set +CONFIG_NSH_CMDPARMS=y +CONFIG_NSH_MAXARGUMENTS=6 +CONFIG_NSH_ARGCAT=y +CONFIG_NSH_NESTDEPTH=3 +# CONFIG_NSH_DISABLEBG is not set +CONFIG_NSH_BUILTIN_APPS=y + +# +# Disable Individual commands +# +# CONFIG_NSH_DISABLE_ADDROUTE is not set +# CONFIG_NSH_DISABLE_BASENAME is not set +# CONFIG_NSH_DISABLE_CAT is not set +# CONFIG_NSH_DISABLE_CD is not set +# CONFIG_NSH_DISABLE_CP is not set +# CONFIG_NSH_DISABLE_CMP is not set +CONFIG_NSH_DISABLE_DATE=y +# CONFIG_NSH_DISABLE_DD is not set +# CONFIG_NSH_DISABLE_DF is not set +# CONFIG_NSH_DISABLE_DELROUTE is not set +# CONFIG_NSH_DISABLE_DIRNAME is not set +# CONFIG_NSH_DISABLE_ECHO is not set +# CONFIG_NSH_DISABLE_EXEC is not set +# CONFIG_NSH_DISABLE_EXIT is not set +# CONFIG_NSH_DISABLE_FREE is not set +CONFIG_NSH_DISABLE_GET=y +# CONFIG_NSH_DISABLE_HELP is not set +# CONFIG_NSH_DISABLE_HEXDUMP is not set +# CONFIG_NSH_DISABLE_IFCONFIG is not set +CONFIG_NSH_DISABLE_IFUPDOWN=y +# CONFIG_NSH_DISABLE_KILL is not set +# CONFIG_NSH_DISABLE_LOSETUP is not set +CONFIG_NSH_DISABLE_LOSMART=y +# CONFIG_NSH_DISABLE_LS is not set +# CONFIG_NSH_DISABLE_MB is not set +# CONFIG_NSH_DISABLE_MKDIR is not set +# CONFIG_NSH_DISABLE_MKFATFS is not set +# CONFIG_NSH_DISABLE_MKRD is not set +# CONFIG_NSH_DISABLE_MH is not set +# CONFIG_NSH_DISABLE_MOUNT is not set +# CONFIG_NSH_DISABLE_MV is not set +# CONFIG_NSH_DISABLE_MW is not set +CONFIG_NSH_DISABLE_PRINTF=y +# CONFIG_NSH_DISABLE_PS is not set +CONFIG_NSH_DISABLE_PUT=y +# CONFIG_NSH_DISABLE_PWD is not set +# CONFIG_NSH_DISABLE_RM is not set +# CONFIG_NSH_DISABLE_RMDIR is not set +# CONFIG_NSH_DISABLE_SET is not set +# CONFIG_NSH_DISABLE_SH is not set +# CONFIG_NSH_DISABLE_SLEEP is not set +# CONFIG_NSH_DISABLE_TIME is not set +# CONFIG_NSH_DISABLE_TEST is not set +# CONFIG_NSH_DISABLE_UMOUNT is not set +# CONFIG_NSH_DISABLE_UNAME is not set +# CONFIG_NSH_DISABLE_UNSET is not set +# CONFIG_NSH_DISABLE_USLEEP is not set +CONFIG_NSH_DISABLE_WGET=y +# CONFIG_NSH_DISABLE_XD is not set +CONFIG_NSH_MMCSDMINOR=0 + +# +# Configure Command Options +# +# CONFIG_NSH_CMDOPT_DF_H is not set +# CONFIG_NSH_CMDOPT_DD_STATS is not set +CONFIG_NSH_CODECS_BUFSIZE=128 +CONFIG_NSH_CMDOPT_HEXDUMP=y +CONFIG_NSH_PROC_MOUNTPOINT="/proc" +CONFIG_NSH_FILEIOSIZE=512 + +# +# Scripting Support +# +# CONFIG_NSH_DISABLESCRIPT is not set +# CONFIG_NSH_DISABLE_ITEF is not set +# CONFIG_NSH_DISABLE_LOOPS is not set + +# +# Console Configuration +# +CONFIG_NSH_CONSOLE=y +# CONFIG_NSH_USBCONSOLE is not set +# CONFIG_NSH_ALTCONDEV is not set +CONFIG_NSH_ARCHINIT=y +# CONFIG_NSH_LOGIN is not set +# CONFIG_NSH_CONSOLE_LOGIN is not set + +# +# NxWidgets/NxWM +# + +# +# Platform-specific Support +# +# CONFIG_PLATFORM_CONFIGDATA is not set +CONFIG_HAVE_CXXINITIALIZE=y + +# +# System Libraries and NSH Add-Ons +# +# CONFIG_SYSTEM_CDCACM is not set +# CONFIG_SYSTEM_CLE is not set +# CONFIG_SYSTEM_CUTERM is not set +# CONFIG_SYSTEM_FREE is not set +# CONFIG_SYSTEM_HEX2BIN is not set +# CONFIG_SYSTEM_HEXED is not set +# CONFIG_SYSTEM_INSTALL is not set +# CONFIG_SYSTEM_RAMTEST is not set +CONFIG_READLINE_HAVE_EXTMATCH=y +CONFIG_SYSTEM_READLINE=y +CONFIG_READLINE_ECHO=y +# CONFIG_READLINE_TABCOMPLETION is not set +# CONFIG_READLINE_CMD_HISTORY is not set +# CONFIG_SYSTEM_SUDOKU is not set +# CONFIG_SYSTEM_SYSTEM is not set +# CONFIG_SYSTEM_TEE is not set +# CONFIG_SYSTEM_UBLOXMODEM is not set +# CONFIG_SYSTEM_VI is not set +# CONFIG_SYSTEM_ZMODEM is not set + +# +# Wireless Libraries and NSH Add-Ons +# + +# +# IEEE 802.15.4 applications +# +CONFIG_IEEE802154_LIBMAC=y +CONFIG_IEEE802154_LIBUTILS=y +CONFIG_IEEE802154_I8SAK=y +CONFIG_IEEE802154_I8SAK_PRIORITY=100 +CONFIG_IEEE802154_I8SAK_STACKSIZE=2048 diff --git a/configs/clicker2-stm32/mrf24j40-radio/Make.defs b/configs/clicker2-stm32/mrf24j40-mac/Make.defs similarity index 98% rename from configs/clicker2-stm32/mrf24j40-radio/Make.defs rename to configs/clicker2-stm32/mrf24j40-mac/Make.defs index 4aa245f38b7..ab1e10dc459 100644 --- a/configs/clicker2-stm32/mrf24j40-radio/Make.defs +++ b/configs/clicker2-stm32/mrf24j40-mac/Make.defs @@ -1,5 +1,5 @@ ############################################################################ -# configs/clicker2-stm32/mrf24j40-radio/Make.defs +# configs/clicker2-stm32/mrf24j40-mac/Make.defs # # Copyright (C) 2017 Gregory Nutt. All rights reserved. # Author: Gregory Nutt diff --git a/configs/clicker2-stm32/mrf24j40-radio/defconfig b/configs/clicker2-stm32/mrf24j40-mac/defconfig similarity index 99% rename from configs/clicker2-stm32/mrf24j40-radio/defconfig rename to configs/clicker2-stm32/mrf24j40-mac/defconfig index 706cddb21ed..8ecd37bd89a 100644 --- a/configs/clicker2-stm32/mrf24j40-radio/defconfig +++ b/configs/clicker2-stm32/mrf24j40-mac/defconfig @@ -16,7 +16,7 @@ CONFIG_HOST_LINUX=y # # Build Configuration # -CONFIG_APPS_DIR="../apps" +# CONFIG_APPS_DIR="../apps" CONFIG_BUILD_FLAT=y # CONFIG_BUILD_2PASS is not set @@ -125,7 +125,6 @@ CONFIG_ARCH_CORTEXM4=y # CONFIG_ARCH_CORTEXR7F is not set CONFIG_ARCH_FAMILY="armv7-m" CONFIG_ARCH_CHIP="stm32" -# CONFIG_ARCH_TOOLCHAIN_IAR is not set # CONFIG_ARMV7M_USEBASEPRI is not set CONFIG_ARCH_HAVE_CMNVECTOR=y # CONFIG_ARMV7M_CMNVECTOR is not set @@ -534,6 +533,7 @@ CONFIG_STM32_USART3_SERIALDRIVER=y # # USB Device Configuration # +# CONFIG_ARCH_TOOLCHAIN_IAR is not set CONFIG_ARCH_TOOLCHAIN_GNU=y # @@ -979,6 +979,7 @@ CONFIG_IOB_NCHAINS=0 # CONFIG_WIRELESS=y CONFIG_WIRELESS_IEEE802154=y +CONFIG_IEEE802154_DEFAULT_EADDR=0x00fade00deadbeef CONFIG_IEEE802154_MAC_DEV=y CONFIG_MAC802154_HPWORK=y CONFIG_IEEE802154_NTXDESC=3 @@ -1109,7 +1110,6 @@ CONFIG_LIB_SENDFILE_BUFSIZE=512 # # CONFIG_C99_BOOL8 is not set CONFIG_HAVE_CXX=y -CONFIG_HAVE_CXXINITIALIZE=y # CONFIG_CXX_NEWLONG is not set # @@ -1340,6 +1340,7 @@ CONFIG_NSH_ARCHINIT=y # Platform-specific Support # # CONFIG_PLATFORM_CONFIGDATA is not set +CONFIG_HAVE_CXXINITIALIZE=y # # System Libraries and NSH Add-Ons diff --git a/configs/clicker2-stm32/nsh/defconfig b/configs/clicker2-stm32/nsh/defconfig index c2dbc420a80..0fb4bd7cdc0 100644 --- a/configs/clicker2-stm32/nsh/defconfig +++ b/configs/clicker2-stm32/nsh/defconfig @@ -125,7 +125,6 @@ CONFIG_ARCH_CORTEXM4=y # CONFIG_ARCH_CORTEXR7F is not set CONFIG_ARCH_FAMILY="armv7-m" CONFIG_ARCH_CHIP="stm32" -# CONFIG_ARCH_TOOLCHAIN_IAR is not set # CONFIG_ARMV7M_USEBASEPRI is not set CONFIG_ARCH_HAVE_CMNVECTOR=y # CONFIG_ARMV7M_CMNVECTOR is not set @@ -394,6 +393,7 @@ CONFIG_STM32_HAVE_I2C2=y CONFIG_STM32_HAVE_I2C3=y CONFIG_STM32_HAVE_SPI2=y CONFIG_STM32_HAVE_SPI3=y +CONFIG_STM32_HAVE_I2S3=y # CONFIG_STM32_HAVE_SPI4 is not set # CONFIG_STM32_HAVE_SPI5 is not set # CONFIG_STM32_HAVE_SPI6 is not set @@ -432,6 +432,7 @@ CONFIG_STM32_PWR=y # CONFIG_STM32_SPI1 is not set # CONFIG_STM32_SPI2 is not set # CONFIG_STM32_SPI3 is not set +# CONFIG_STM32_I2S3 is not set CONFIG_STM32_SYSCFG=y # CONFIG_STM32_TIM1 is not set # CONFIG_STM32_TIM2 is not set @@ -527,6 +528,7 @@ CONFIG_STM32_USART3_SERIALDRIVER=y # # USB Device Configuration # +# CONFIG_ARCH_TOOLCHAIN_IAR is not set CONFIG_ARCH_TOOLCHAIN_GNU=y # @@ -1075,7 +1077,6 @@ CONFIG_LIB_SENDFILE_BUFSIZE=512 # # CONFIG_C99_BOOL8 is not set CONFIG_HAVE_CXX=y -CONFIG_HAVE_CXXINITIALIZE=y # CONFIG_CXX_NEWLONG is not set # @@ -1305,6 +1306,7 @@ CONFIG_NSH_CONSOLE=y # Platform-specific Support # # CONFIG_PLATFORM_CONFIGDATA is not set +CONFIG_HAVE_CXXINITIALIZE=y # # System Libraries and NSH Add-Ons diff --git a/configs/clicker2-stm32/usbnsh/defconfig b/configs/clicker2-stm32/usbnsh/defconfig index 1cf52249ef1..3db2eabaafa 100644 --- a/configs/clicker2-stm32/usbnsh/defconfig +++ b/configs/clicker2-stm32/usbnsh/defconfig @@ -125,7 +125,6 @@ CONFIG_ARCH_CORTEXM4=y # CONFIG_ARCH_CORTEXR7F is not set CONFIG_ARCH_FAMILY="armv7-m" CONFIG_ARCH_CHIP="stm32" -# CONFIG_ARCH_TOOLCHAIN_IAR is not set # CONFIG_ARMV7M_USEBASEPRI is not set CONFIG_ARCH_HAVE_CMNVECTOR=y # CONFIG_ARMV7M_CMNVECTOR is not set @@ -394,6 +393,7 @@ CONFIG_STM32_HAVE_I2C2=y CONFIG_STM32_HAVE_I2C3=y CONFIG_STM32_HAVE_SPI2=y CONFIG_STM32_HAVE_SPI3=y +CONFIG_STM32_HAVE_I2S3=y # CONFIG_STM32_HAVE_SPI4 is not set # CONFIG_STM32_HAVE_SPI5 is not set # CONFIG_STM32_HAVE_SPI6 is not set @@ -432,6 +432,7 @@ CONFIG_STM32_PWR=y # CONFIG_STM32_SPI1 is not set # CONFIG_STM32_SPI2 is not set # CONFIG_STM32_SPI3 is not set +# CONFIG_STM32_I2S3 is not set CONFIG_STM32_SYSCFG=y # CONFIG_STM32_TIM1 is not set # CONFIG_STM32_TIM2 is not set @@ -527,6 +528,7 @@ CONFIG_STM32_USART3_SERIALDRIVER=y # # USB Device Configuration # +# CONFIG_ARCH_TOOLCHAIN_IAR is not set CONFIG_ARCH_TOOLCHAIN_GNU=y # @@ -1124,7 +1126,6 @@ CONFIG_LIB_SENDFILE_BUFSIZE=512 # # CONFIG_C99_BOOL8 is not set CONFIG_HAVE_CXX=y -CONFIG_HAVE_CXXINITIALIZE=y # CONFIG_CXX_NEWLONG is not set # @@ -1356,6 +1357,7 @@ CONFIG_NSH_ARCHINIT=y # Platform-specific Support # # CONFIG_PLATFORM_CONFIGDATA is not set +CONFIG_HAVE_CXXINITIALIZE=y # # System Libraries and NSH Add-Ons diff --git a/configs/sama5d4-ek/README.txt b/configs/sama5d4-ek/README.txt index 839daa66dff..42a3ef0fcd4 100644 --- a/configs/sama5d4-ek/README.txt +++ b/configs/sama5d4-ek/README.txt @@ -4259,8 +4259,6 @@ Configurations http://nuttx.org/doku.php?id=wiki:howtos:syslog . Relevant configuration settings are summarized below: - File System: - Device Drivers: CONFIG_RAMLOG=y : Enable the RAM-based logging feature. CONFIG_RAMLOG_CONSOLE=n : (We don't use the RAMLOG console) diff --git a/drivers/wireless/ieee802154/mrf24j40.c b/drivers/wireless/ieee802154/mrf24j40.c index 903b843c9c8..b08524cd4d3 100644 --- a/drivers/wireless/ieee802154/mrf24j40.c +++ b/drivers/wireless/ieee802154/mrf24j40.c @@ -103,6 +103,21 @@ #define MRF24J40_GTS_SLOTS 2 +/* Formula for calculating default macMaxFrameWaitTime is on pg. 130 + * + * For PHYs other than CSS and UWB, the attribute phyMaxFrameDuration is given by: + * + * phyMaxFrameDuration = phySHRDuration + + * ceiling([aMaxPHYPacketSize + 1] x phySymbolsPerOctet) + * + * where ceiling() is a function that returns the smallest integer value greater + * than or equal to its argument value. [1] pg. 158 +*/ + +#define MRF24J40_DEFAULT_MAX_FRAME_WAITTIME 1824 + +#define MRF24J40_SYMBOL_DURATION_PS 16000000 + /**************************************************************************** * Private Types ****************************************************************************/ @@ -123,27 +138,32 @@ struct mrf24j40_radio_s FAR const struct mrf24j40_lower_s *lower; FAR struct spi_dev_s *spi; /* Saved SPI interface instance */ - struct work_s irqwork; /* For deferring interrupt work to work queue */ - struct work_s pollwork; /* For deferring poll work to the work queue */ - sem_t exclsem; /* Exclusive access to this struct */ + struct work_s irqwork; /* For deferring interrupt work to work queue */ + struct work_s csma_pollwork; /* For deferring poll work to the work queue */ + struct work_s gts_pollwork; /* For deferring poll work to the work queue */ + + sem_t exclsem; /* Exclusive access to this struct */ struct ieee802154_addr_s addr; - uint8_t channel; /* 11 to 26 for the 2.4 GHz band */ - uint8_t devmode; /* device mode: device, coord, pancoord */ - uint8_t paenabled; /* enable usage of PA */ - uint8_t rxmode; /* Reception mode: Main, no CRC, promiscuous */ - int32_t txpower; /* TX power in mBm = dBm/100 */ - struct ieee802154_cca_s cca; /* Clear channel assessement method */ + uint8_t channel; /* 11 to 26 for the 2.4 GHz band */ + uint8_t devmode; /* device mode: device, coord, pancoord */ + uint8_t paenabled; /* enable usage of PA */ + uint8_t rxmode; /* Reception mode: Main, no CRC, promiscuous */ + int32_t txpower; /* TX power in mBm = dBm/100 */ + struct ieee802154_cca_s cca; /* Clear channel assessement method */ - /* Buffer Allocations */ + /* MAC PIB attributes */ + uint32_t max_frame_waittime; + + struct ieee802154_txdesc_s *txdelayed_desc; struct ieee802154_txdesc_s *csma_desc; - FAR struct iob_s *csma_frame; - bool csma_busy; + bool txdelayed_busy : 1; + bool csma_busy : 1; + bool reschedule_csma : 1; struct ieee802154_txdesc_s *gts_desc[MRF24J40_GTS_SLOTS]; - FAR struct iob_s *gts_frame[MRF24J40_GTS_SLOTS]; bool gts_busy[MRF24J40_GTS_SLOTS]; }; @@ -177,13 +197,15 @@ static int mrf24j40_interrupt(int irq, FAR void *context, FAR void *arg); static void mrf24j40_dopoll_csma(FAR void *arg); static void mrf24j40_dopoll_gts(FAR void *arg); -static int mrf24j40_csma_setup(FAR struct mrf24j40_radio_s *dev, - FAR struct iob_s *frame); +static int mrf24j40_norm_setup(FAR struct mrf24j40_radio_s *dev, + FAR struct iob_s *frame, bool csma); static int mrf24j40_gts_setup(FAR struct mrf24j40_radio_s *dev, uint8_t gts, FAR struct iob_s *frame); static int mrf24j40_setup_fifo(FAR struct mrf24j40_radio_s *dev, FAR struct iob_s *frame, uint32_t fifo_addr); +static inline void mrf24j40_norm_trigger(FAR struct mrf24j40_radio_s *dev); + static int mrf24j40_setchannel(FAR struct mrf24j40_radio_s *dev, uint8_t chan); static int mrf24j40_getchannel(FAR struct mrf24j40_radio_s *dev, @@ -214,41 +236,31 @@ static int mrf24j40_getcca(FAR struct mrf24j40_radio_s *dev, FAR struct ieee802154_cca_s *cca); static int mrf24j40_energydetect(FAR struct mrf24j40_radio_s *dev, FAR uint8_t *energy); -static int mrf24j40_rxenable(FAR struct mrf24j40_radio_s *dev, bool enable); +static void mrf24j40_mactimer(FAR struct mrf24j40_radio_s *dev, int numsymbols); /* Driver operations */ static int mrf24j40_bind(FAR struct ieee802154_radio_s *radio, FAR struct ieee802154_radiocb_s *radiocb); -static int mrf24j40_txnotify_csma(FAR struct ieee802154_radio_s *radio); -static int mrf24j40_txnotify_gts(FAR struct ieee802154_radio_s *radio); +static int mrf24j40_txnotify(FAR struct ieee802154_radio_s *radio, bool gts); +static int mrf24j40_txdelayed(FAR struct ieee802154_radio_s *radio, + FAR struct ieee802154_txdesc_s *txdesc, + uint32_t symboldelay); +static int mrf24j40_reset_attrs(FAR struct ieee802154_radio_s *radio); static int mrf24j40_get_attr(FAR struct ieee802154_radio_s *radio, - enum ieee802154_pib_attr_e pib_attr, + enum ieee802154_attr_e attr, FAR union ieee802154_attr_u *attrval); -static int mrf24j40_set_attr(FAR struct ieee802154_radio_s *radio, - enum ieee802154_pib_attr_e pib_attr, +static int mrf24j40_set_attr(FAR struct ieee802154_radio_s *radio, + enum ieee802154_attr_e attr, FAR const union ieee802154_attr_u *attrval); +static int mrf24j40_rxenable(FAR struct ieee802154_radio_s *dev, bool enable); +static int mrf24j40_req_rxenable(FAR struct ieee802154_radio_s *radio, + FAR struct ieee802154_rxenable_req_s *req); /**************************************************************************** * Private Data ****************************************************************************/ -/* These are pointers to ALL registered MRF24J40 devices. - * This table is used during irqs to find the context - * Only one device is supported for now. - * More devices can be supported in the future by lookup them up - * using the IRQ number. See the ENC28J60 or CC3000 drivers for reference. - */ - -static const struct ieee802154_radioops_s mrf24j40_devops = -{ - mrf24j40_bind, - mrf24j40_txnotify_csma, - mrf24j40_txnotify_gts, - mrf24j40_get_attr, - mrf24j40_set_attr -}; - /**************************************************************************** * Radio Interface Functions ****************************************************************************/ @@ -264,7 +276,7 @@ static int mrf24j40_bind(FAR struct ieee802154_radio_s *radio, } /**************************************************************************** - * Function: mrf24j40_txnotify_csma + * Function: mrf24j40_txnotify * * Description: * Driver callback invoked when new TX data is available. This is a @@ -281,32 +293,49 @@ static int mrf24j40_bind(FAR struct ieee802154_radio_s *radio, * ****************************************************************************/ -static int mrf24j40_txnotify_csma(FAR struct ieee802154_radio_s *radio) +static int mrf24j40_txnotify(FAR struct ieee802154_radio_s *radio, bool gts) { FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)radio; - /* 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. - */ - - if (work_available(&dev->pollwork)) + if (gts) { - /* Schedule to serialize the poll on the worker thread. */ + /* 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. + */ - work_queue(HPWORK, &dev->pollwork, mrf24j40_dopoll_csma, dev, 0); + if (work_available(&dev->gts_pollwork)) + { + /* Schedule to serialize the poll on the worker thread. */ + + work_queue(HPWORK, &dev->gts_pollwork, mrf24j40_dopoll_gts, dev, 0); + } + } + else + { + /* 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. + */ + + if (work_available(&dev->csma_pollwork)) + { + /* Schedule to serialize the poll on the worker thread. */ + + work_queue(HPWORK, &dev->csma_pollwork, mrf24j40_dopoll_csma, dev, 0); + } } return OK; } /**************************************************************************** - * Function: mrf24j40_txnotify_gts + * Function: mrf24j40_txdelayed * * Description: - * Driver callback invoked when new TX data is available. This is a - * stimulus perform an out-of-cycle poll and, thereby, reduce the TX - * latency. + * Transmit a packet without regard to supeframe structure after a certain + * number of symbols. This function is used to send Data Request responses. + * It can also be used to send data immediately if the delay is set to 0. * * Parameters: * radio - Reference to the radio driver state structure @@ -318,91 +347,218 @@ static int mrf24j40_txnotify_csma(FAR struct ieee802154_radio_s *radio) * ****************************************************************************/ -static int mrf24j40_txnotify_gts(FAR struct ieee802154_radio_s *radio) +static int mrf24j40_txdelayed(FAR struct ieee802154_radio_s *radio, + FAR struct ieee802154_txdesc_s *txdesc, + uint32_t symboldelay) { FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)radio; + uint8_t reg; - /* 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. + /* Get exclusive access to the radio device */ + + if (sem_wait(&dev->exclsem) != 0) + { + return -EINTR; + } + + /* There should never be more than one of these transactions at once. */ + + DEBUGASSERT(!dev->txdelayed_busy); + + dev->txdelayed_desc = txdesc; + dev->txdelayed_busy = true; + + /* Disable the TX norm interrupt and clear it */ + + reg = mrf24j40_getreg(dev->spi, MRF24J40_INTCON); + reg |= MRF24J40_INTCON_TXNIE; + mrf24j40_setreg(dev->spi, MRF24J40_INTCON, reg); + + /* If after disabling the interrupt, the irqworker is not scheduled, there + * are no interrupts to worry about. However, if there is work scheduled, + * we need to process it before going any further. */ - if (work_available(&dev->pollwork)) + if (!work_available(&dev->irqwork)) { - /* Schedule to serialize the poll on the worker thread. */ + work_cancel(HPWORK, &dev->irqwork); + sem_post(&dev->exclsem); + mrf24j40_irqworker((FAR void *)dev); - work_queue(HPWORK, &dev->pollwork, mrf24j40_dopoll_gts, dev, 0); + /* Get exclusive access to the radio device */ + + if (sem_wait(&dev->exclsem) != 0) + { + return -EINTR; + } } + if (dev->csma_busy) + { + dev->reschedule_csma = true; + } + + mrf24j40_norm_setup(dev, txdesc->frame, false); + + if (symboldelay == 0) + { + mrf24j40_norm_trigger(dev); + } + else + { + mrf24j40_mactimer(dev, symboldelay); + } + + sem_post(&dev->exclsem); + return OK; } -static int mrf24j40_get_attr(FAR struct ieee802154_radio_s *radio, - enum ieee802154_pib_attr_e pib_attr, - FAR union ieee802154_attr_u *attrval) +static int mrf24j40_reset_attrs(FAR struct ieee802154_radio_s *radio) +{ + FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)radio; + + dev->max_frame_waittime = MRF24J40_DEFAULT_MAX_FRAME_WAITTIME; + + return OK; +} + +static int mrf24j40_get_attr(FAR struct ieee802154_radio_s *radio, + enum ieee802154_attr_e attr, + FAR union ieee802154_attr_u *attrval) { FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)radio; int ret; - switch (pib_attr) + switch (attr) { - case IEEE802154_PIB_MAC_EXTENDED_ADDR: + case IEEE802154_ATTR_MAC_EXTENDED_ADDR: { memcpy(&attrval->mac.eaddr[0], &dev->addr.eaddr[0], 8); ret = IEEE802154_STATUS_SUCCESS; } break; + + case IEEE802154_ATTR_MAC_MAX_FRAME_WAITTIME: + { + attrval->mac.max_frame_waittime = dev->max_frame_waittime; + ret = IEEE802154_STATUS_SUCCESS; + } + break; + + case IEEE802154_ATTR_PHY_SYMBOL_DURATION: + { + attrval->phy.symdur_picosec = MRF24J40_SYMBOL_DURATION_PS; + ret = IEEE802154_STATUS_SUCCESS; + } + break; + default: ret = IEEE802154_STATUS_UNSUPPORTED_ATTRIBUTE; } + return ret; } static int mrf24j40_set_attr(FAR struct ieee802154_radio_s *radio, - enum ieee802154_pib_attr_e pib_attr, + enum ieee802154_attr_e attr, FAR const union ieee802154_attr_u *attrval) { FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)radio; int ret; - switch (pib_attr) + switch (attr) { - case IEEE802154_PIB_MAC_EXTENDED_ADDR: + case IEEE802154_ATTR_MAC_PANID: + { + mrf24j40_setpanid(dev, attrval->mac.panid); + ret = IEEE802154_STATUS_SUCCESS; + } + break; + + case IEEE802154_ATTR_MAC_SHORT_ADDRESS: + { + mrf24j40_setsaddr(dev, attrval->mac.saddr); + ret = IEEE802154_STATUS_SUCCESS; + } + break; + + case IEEE802154_ATTR_MAC_EXTENDED_ADDR: { mrf24j40_seteaddr(dev, &attrval->mac.eaddr[0]); ret = IEEE802154_STATUS_SUCCESS; } break; - case IEEE802154_PIB_MAC_PROMISCUOUS_MODE: + + case IEEE802154_ATTR_MAC_PROMISCUOUS_MODE: { if (attrval->mac.promisc_mode) { - mrf24j40_setrxmode(dev, MRF24J40_RXMODE_PROMISC); + mrf24j40_setrxmode(dev, MRF24J40_RXMODE_PROMISC); } else { - mrf24j40_setrxmode(dev, MRF24J40_RXMODE_NORMAL); + mrf24j40_setrxmode(dev, MRF24J40_RXMODE_NORMAL); } ret = IEEE802154_STATUS_SUCCESS; } break; - case IEEE802154_PIB_MAC_RX_ON_WHEN_IDLE: + + case IEEE802154_ATTR_MAC_RX_ON_WHEN_IDLE: { dev->rxonidle = attrval->mac.rxonidle; - mrf24j40_rxenable(dev, dev->rxonidle); + mrf24j40_rxenable(radio, dev->rxonidle); + ret = IEEE802154_STATUS_SUCCESS; } break; + default: ret = IEEE802154_STATUS_UNSUPPORTED_ATTRIBUTE; + break; } + return ret; } +static int mrf24j40_req_rxenable(FAR struct ieee802154_radio_s *radio, + FAR struct ieee802154_rxenable_req_s *req) +{ + return -ENOTTY; +} + /**************************************************************************** * Internal Functions ****************************************************************************/ +static void mrf24j40_mactimer(FAR struct mrf24j40_radio_s *dev, int numsymbols) +{ + uint16_t nhalfsym; + uint8_t reg; + + nhalfsym = (numsymbols << 1); + + /* Disable the interrupt, clear the timer count */ + + reg = mrf24j40_getreg(dev->spi, MRF24J40_INTCON); + reg |= MRF24J40_INTCON_HSYMTMRIE; + mrf24j40_setreg(dev->spi, MRF24J40_INTCON, reg); + + mrf24j40_setreg(dev->spi, MRF24J40_HSYMTMRL, 0x00); + mrf24j40_setreg(dev->spi, MRF24J40_HSYMTMRH, 0x00); + + reg &= ~MRF24J40_INTCON_HSYMTMRIE; + mrf24j40_setreg(dev->spi, MRF24J40_INTCON, reg); + + /* Set the timer count and enable interrupts */ + + reg = (nhalfsym & 0xFF); + mrf24j40_setreg(dev->spi, MRF24J40_HSYMTMRL, reg); + + reg = (nhalfsym >> 8) & 0xFF; + mrf24j40_setreg(dev->spi, MRF24J40_HSYMTMRH, reg); +} + /**************************************************************************** * Function: mrf24j40_dopoll_csma * @@ -411,7 +567,7 @@ static int mrf24j40_set_attr(FAR struct ieee802154_radio_s *radio, * This is done: * * 1. After completion of a transmission (mrf24j40_txdone_csma), - * 2. When new TX data is available (mrf24j40_txnotify_csma), and + * 2. When new TX data is available (mrf24j40_txnotify), and * 3. After a TX timeout to restart the sending process * (mrf24j40_txtimeout_csma). * @@ -438,10 +594,8 @@ static void mrf24j40_dopoll_csma(FAR void *arg) if (!dev->csma_busy) { - /* need to somehow allow for a handle to be passed */ + len = dev->radiocb->poll(dev->radiocb, false, &dev->csma_desc); - len = dev->radiocb->poll_csma(dev->radiocb, &dev->csma_desc, - &dev->csma_frame); if (len > 0) { /* Now the txdesc is in use */ @@ -450,7 +604,8 @@ static void mrf24j40_dopoll_csma(FAR void *arg) /* Setup the transaction on the device in the CSMA FIFO */ - mrf24j40_csma_setup(dev, dev->csma_frame); + mrf24j40_norm_setup(dev, dev->csma_desc->frame, true); + mrf24j40_norm_trigger(dev); } } @@ -465,7 +620,7 @@ static void mrf24j40_dopoll_csma(FAR void *arg) * This is done: * * 1. After completion of a transmission (mrf24j40_txdone_gts), - * 2. When new TX data is available (mrf24j40_txnotify_gts), and + * 2. When new TX data is available (mrf24j40_txnotify), and * 3. After a TX timeout to restart the sending process * (mrf24j40_txtimeout_gts). * @@ -493,8 +648,8 @@ static void mrf24j40_dopoll_gts(FAR void *arg) { if (!dev->gts_busy[gts]) { - len = dev->radiocb->poll_gts(dev->radiocb, &dev->gts_desc[gts], - &dev->gts_frame[0]); + len = dev->radiocb->poll(dev->radiocb, true, &dev->gts_desc[gts]); + if (len > 0) { /* Now the txdesc is in use */ @@ -503,7 +658,7 @@ static void mrf24j40_dopoll_gts(FAR void *arg) /* Setup the transaction on the device in the open GTS FIFO */ - mrf24j40_gts_setup(dev, gts, dev->gts_frame[0]); + mrf24j40_gts_setup(dev, gts, dev->gts_desc[gts]->frame); } } } @@ -1258,15 +1413,15 @@ static int mrf24j40_energydetect(FAR struct mrf24j40_radio_s *dev, } /**************************************************************************** - * Name: mrf24j40_csma_setup + * Name: mrf24j40_norm_setup * * Description: - * Setup a CSMA transaction in the normal TX FIFO + * Setup a transaction in the normal TX FIFO * ****************************************************************************/ -static int mrf24j40_csma_setup(FAR struct mrf24j40_radio_s *dev, - FAR struct iob_s *frame) +static int mrf24j40_norm_setup(FAR struct mrf24j40_radio_s *dev, + FAR struct iob_s *frame, bool csma) { uint8_t reg; int ret; @@ -1277,27 +1432,64 @@ static int mrf24j40_csma_setup(FAR struct mrf24j40_radio_s *dev, reg &= ~MRF24J40_INTCON_TXNIE; mrf24j40_setreg(dev->spi, MRF24J40_INTCON, reg); + /* Enable/Disable CSMA mode */ + + reg = mrf24j40_getreg(dev->spi, MRF24J40_TXMCR); + + if (csma) + { + reg &= ~MRF24J40_TXMCR_NOCSMA; + } + else + { + reg |= MRF24J40_TXMCR_NOCSMA; + } + + mrf24j40_setreg(dev->spi, MRF24J40_TXMCR, reg); + /* Setup the FIFO */ ret = mrf24j40_setup_fifo(dev, frame, MRF24J40_TXNORM_FIFO); - /* If the frame control field contains - * an acknowledgment request, set the TXNACKREQ bit. - * See IEEE 802.15.4/2003 7.2.1.1 page 112 for info. + /* If the frame control field contains an acknowledgment request, set the + * TXNACKREQ bit. See IEEE 802.15.4/2003 7.2.1.1 page 112 for info. */ - reg = MRF24J40_TXNCON_TXNTRIG; + reg = mrf24j40_getreg(dev->spi, MRF24J40_TXNCON); + if (frame->io_data[0] & IEEE802154_FRAMECTRL_ACKREQ) { reg |= MRF24J40_TXNCON_TXNACKREQ; } - - /* Trigger packet emission */ + else + { + reg &= ~MRF24J40_TXNCON_TXNACKREQ; + } mrf24j40_setreg(dev->spi, MRF24J40_TXNCON, reg); + return ret; } +/**************************************************************************** + * Name: mrf24j40_norm_trigger + * + * Description: + * Trigger the normal TX FIFO + * + ****************************************************************************/ + +static inline void mrf24j40_norm_trigger(FAR struct mrf24j40_radio_s *dev) +{ + uint8_t reg; + + reg = mrf24j40_getreg(dev->spi, MRF24J40_TXNCON); + + reg |= MRF24J40_TXNCON_TXNTRIG; + + mrf24j40_setreg(dev->spi, MRF24J40_TXNCON, reg); +} + /**************************************************************************** * Name: mrf24j40_gts_setup * @@ -1382,35 +1574,87 @@ static int mrf24j40_setup_fifo(FAR struct mrf24j40_radio_s *dev, static void mrf24j40_irqwork_txnorm(FAR struct mrf24j40_radio_s *dev) { - uint8_t txstat; + uint8_t reg; + enum ieee802154_status_e status; + bool framepending; /* Disable tx int */ - txstat = mrf24j40_getreg(dev->spi, MRF24J40_INTCON); - txstat |= MRF24J40_INTCON_TXNIE; - mrf24j40_setreg(dev->spi, MRF24J40_INTCON, txstat); + reg = mrf24j40_getreg(dev->spi, MRF24J40_INTCON); + reg |= MRF24J40_INTCON_TXNIE; + mrf24j40_setreg(dev->spi, MRF24J40_INTCON, reg); /* Get the status from the device and copy the status into the tx desc. * The status for the normal FIFO is represented with bit TXNSTAT where * 0=success, 1= failure. */ - txstat = mrf24j40_getreg(dev->spi, MRF24J40_TXSTAT); - dev->csma_desc->conf->status = txstat & MRF24J40_TXSTAT_TXNSTAT; + reg = mrf24j40_getreg(dev->spi, MRF24J40_TXSTAT); - /* Inform the next layer of the transmission success/failure */ + /* TXNSTAT = 0: Transmission was successful + * TXNSTAT = 1: Transmission failed, retry count exceeded + */ - dev->radiocb->txdone(dev->radiocb, dev->csma_desc); + if (reg & MRF24J40_TXSTAT_TXNSTAT) + { + /* The number of retries of the most recent transmission is contained in the + * TXNRETRY (TXSTAT 0x24<7:6>) bits. The CCAFAIL (TXSTAT 0x24<5>) bit = 1 + * indicates if the failed transmission was due to the channel busy + * (CSMA-CA timed out). + */ - /* We are now done with the transaction */ + if (reg & MRF24J40_TXSTAT_CCAFAIL) + { + status = IEEE802154_STATUS_CHANNEL_ACCESS_FAILURE; + } + else + { + status = IEEE802154_STATUS_NO_ACK; + } + } + else + { + status = IEEE802154_STATUS_SUCCESS; + } - dev->csma_busy = 0; + framepending = (mrf24j40_getreg(dev->spi, MRF24J40_TXNCON) & + MRF24J40_TXNCON_FPSTAT); - /* Free the IOB */ + if (dev->txdelayed_busy) + { + /* Inform the next layer of the transmission success/failure */ - iob_free(dev->csma_frame); + dev->txdelayed_desc->conf->status = status; + dev->txdelayed_desc->framepending = framepending; + dev->radiocb->txdone(dev->radiocb, dev->txdelayed_desc); - mrf24j40_dopoll_csma(dev); + dev->txdelayed_busy = false; + + if (dev->reschedule_csma) + { + mrf24j40_norm_setup(dev, dev->csma_desc->frame, true); + mrf24j40_norm_trigger(dev); + dev->reschedule_csma = false; + } + } + else + { + /* Inform the next layer of the transmission success/failure */ + + dev->csma_desc->conf->status = status; + dev->csma_desc->framepending = framepending; + dev->radiocb->txdone(dev->radiocb, dev->csma_desc); + + /* We are now done with the transaction */ + + dev->csma_busy = 0; + + /* Must unlock the radio before calling poll */ + + sem_post(&dev->exclsem); + mrf24j40_dopoll_csma(dev); + while (sem_wait(&dev->exclsem) != 0) { } + } } /**************************************************************************** @@ -1456,10 +1700,6 @@ static void mrf24j40_irqwork_txgts(FAR struct mrf24j40_radio_s *dev, dev->gts_busy[gts]= 0; - /* Free the IOB */ - - iob_free(dev->gts_frame[gts]); - mrf24j40_dopoll_gts(dev); } @@ -1471,8 +1711,9 @@ static void mrf24j40_irqwork_txgts(FAR struct mrf24j40_radio_s *dev, * ****************************************************************************/ -static int mrf24j40_rxenable(FAR struct mrf24j40_radio_s *dev, bool enable) +static int mrf24j40_rxenable(FAR struct ieee802154_radio_s *radio, bool enable) { + FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)radio; uint8_t reg; if (enable) @@ -1510,6 +1751,8 @@ static void mrf24j40_irqwork_rx(FAR struct mrf24j40_radio_s *dev) uint32_t index; uint8_t reg; + wlinfo("RX interrupt\n"); + /* Disable rx int */ reg = mrf24j40_getreg(dev->spi, MRF24J40_INTCON); @@ -1525,7 +1768,7 @@ static void mrf24j40_irqwork_rx(FAR struct mrf24j40_radio_s *dev) ind = ieee802154_ind_allocate(); if (ind == NULL) { - wlerr("ERROR: Unable to allocate data_ind. Discarding frame"); + wlerr("ERROR: Unable to allocate data_ind. Discarding frame\n"); goto done; } @@ -1533,7 +1776,7 @@ static void mrf24j40_irqwork_rx(FAR struct mrf24j40_radio_s *dev) addr = MRF24J40_RXBUF_BASE; - ind->frame->io_len= mrf24j40_getreg(dev->spi, addr++); + ind->frame->io_len = mrf24j40_getreg(dev->spi, addr++); /* TODO: This needs to be changed. It is inefficient to do the SPI read byte * by byte */ @@ -1597,18 +1840,37 @@ done: static void mrf24j40_irqworker(FAR void *arg) { FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)arg; - uint8_t intstat; + uint8_t intstat, intcon; DEBUGASSERT(dev); DEBUGASSERT(dev->spi); + /* Get exclusive access to the driver */ + + while (sem_wait(&dev->exclsem) != 0) { } + /* Read and store INTSTAT - this clears the register. */ intstat = mrf24j40_getreg(dev->spi, MRF24J40_INTSTAT); - //wlinfo("INT%02X\n", intstat); + wlinfo("INT%02X\n", intstat); /* Do work according to the pending interrupts */ + if ((intstat & MRF24J40_INTSTAT_HSYMTMRIF)) + { + /* As of now the only use for the MAC timer is for delayed transactions. + * Therefore, all we do here is trigger the TX norm FIFO + */ + + mrf24j40_norm_trigger(dev); + + /* Timers are one-shot, so disable the interrupt */ + + intcon = mrf24j40_getreg(dev->spi, MRF24J40_INTCON); + intcon |= MRF24J40_INTCON_HSYMTMRIE; + mrf24j40_setreg(dev->spi, MRF24J40_INTCON, intcon); + } + if ((intstat & MRF24J40_INTSTAT_RXIF)) { /* A packet was received, retrieve it */ @@ -1637,6 +1899,10 @@ static void mrf24j40_irqworker(FAR void *arg) mrf24j40_irqwork_txgts(dev, 1); } + /* Unlock the radio device */ + + sem_post(&dev->exclsem); + /* Re-enable GPIO interrupts */ dev->lower->enable(dev->lower, true); @@ -1721,7 +1987,14 @@ FAR struct ieee802154_radio_s *mrf24j40_init(FAR struct spi_dev_s *spi, sem_init(&dev->exclsem, 0, 1); - dev->radio.ops = &mrf24j40_devops; + dev->radio.bind = mrf24j40_bind; + dev->radio.txnotify = mrf24j40_txnotify; + dev->radio.txdelayed = mrf24j40_txdelayed; + dev->radio.reset_attrs = mrf24j40_reset_attrs; + dev->radio.get_attr = mrf24j40_get_attr; + dev->radio.set_attr = mrf24j40_set_attr; + dev->radio.rxenable = mrf24j40_rxenable; + dev->radio.req_rxenable = mrf24j40_req_rxenable; dev->lower = lower; dev->spi = spi; @@ -1746,6 +2019,13 @@ FAR struct ieee802154_radio_s *mrf24j40_init(FAR struct spi_dev_s *spi, mrf24j40_pacontrol(dev, MRF24J40_PA_AUTO); + /* For now, we want to always just have the frame pending bit set when + * acknowledging a Data Request command. The standard says that the coordinator + * can do this if it needs time to figure out whether it has data or not + */ + + mrf24j40_setreg(dev->spi, MRF24J40_ACKTMOUT, 0x39 | MRF24J40_ACKTMOUT_DRPACK); + dev->lower->enable(dev->lower, true); return &dev->radio; } diff --git a/drivers/wireless/ieee802154/mrf24j40.h b/drivers/wireless/ieee802154/mrf24j40.h index f9a8a35a5d0..397b9f4e398 100644 --- a/drivers/wireless/ieee802154/mrf24j40.h +++ b/drivers/wireless/ieee802154/mrf24j40.h @@ -184,6 +184,11 @@ #define MRF24J40_TXMCR_BATLIFEXT 0x40 #define MRF24J40_TXMCR_NOCSMA 0x80 +/* ACKTMOUT bits */ + +#define MRF24J40_ACKTMOUT_MAWD 0xEF +#define MRF24J40_ACKTMOUT_DRPACK 0x80 + /* INTCON bits */ #define MRF24J40_INTCON_SLPIE 0x80 diff --git a/include/nuttx/wireless/ieee802154/ieee802154_mac.h b/include/nuttx/wireless/ieee802154/ieee802154_mac.h index 5f28cfa0c73..a07978a64ee 100644 --- a/include/nuttx/wireless/ieee802154/ieee802154_mac.h +++ b/include/nuttx/wireless/ieee802154/ieee802154_mac.h @@ -200,10 +200,25 @@ enum ieee802154_status_e { + /* This first section of enums is defined in the standard. [1] pg. 70 + * They must be in this order + */ + IEEE802154_STATUS_SUCCESS = 0, - IEEE802154_STATUS_BEACON_LOSS = 0xE0, - IEEE802154_STATUS_CHANNEL_ACCESS_FAILURE, + IEEE802154_STATUS_OUT_OF_CAPACITY, IEEE802154_STATUS_DENIED, + + /* As of now, all values below do not have a specific value defined in the + * standard + */ + + IEEE802154_STATUS_FAILURE, /* This value is not outlined in the standard. It + * is a catch-all for any failures that are not + * outlined in the standard + */ + + IEEE802154_STATUS_BEACON_LOSS, + IEEE802154_STATUS_CHANNEL_ACCESS_FAILURE, IEEE802154_STATUS_DISABLE_TRX_FAILURE, IEEE802154_STATUS_FAILED_SECURITY_CHECK, IEEE802154_STATUS_FRAME_TOO_LONG, @@ -214,7 +229,6 @@ enum ieee802154_status_e IEEE802154_STATUS_NO_BEACON, IEEE802154_STATUS_NO_DATA, IEEE802154_STATUS_NO_SHORT_ADDRESS, - IEEE802154_STATUS_OUT_OF_CAP, IEEE802154_STATUS_PAN_ID_CONFLICT, IEEE802154_STATUS_REALIGNMENT, IEEE802154_STATUS_TRANSACTION_EXPIRED, @@ -222,93 +236,119 @@ enum ieee802154_status_e IEEE802154_STATUS_TX_ACTIVE, IEEE802154_STATUS_UNAVAILABLE_KEY, IEEE802154_STATUS_UNSUPPORTED_ATTRIBUTE, - IEEE802154_STATUS_FAILED /* This value is not outlined in the standard. It is - * a catch-all for any failures that are not outlined - * in the standard */ +}; + +static const char *IEEE802154_STATUS_STRING[] = +{ + "Success", + "Failure", + "Beacon loss", + "Channel access failure", + "Denied", + "Disable TRX failure", + "Failed security check", + "Frame too long", + "Invalid GTS", + "Invalid handle", + "Invalid parameter", + "No ack", + "No beacon", + "No data", + "No short address", + "Out of cap", + "PAN ID conflict", + "Realignment", + "Transaction expired", + "Transaction overflow", + "Tx active", + "Unavailable key", + "Unsupported attribute", }; /* IEEE 802.15.4 PHY/MAC PIB attributes IDs */ -enum ieee802154_pib_attr_e +enum ieee802154_attr_e { /* PHY PIB Attributes */ - IEEE802154_PIB_PHY_CURRENT_CHANNEL = 0x00, - IEEE802154_PIB_PHY_CHANNELS_SUPPORTED, - IEEE802154_PIB_PHY_TX_POWER_TOLERANCE, - IEEE802154_PIB_PHY_TX_POWER, - IEEE802154_PIB_PHY_CCA_MODE, - IEEE802154_PIB_PHY_CURRENT_PAGE, - IEEE802154_PIB_PHY_MAX_FRAME_DURATION, - IEEE802154_PIB_PHY_SHR_DURATION, - IEEE802154_PIB_PHY_SYM_PER_OCTET, - IEEE802154_PIB_PHY_PREAMBLE_SYM_LEN, - IEEE802154_PIB_PHY_UWB_DATARATES_SUP, - IEEE802154_PIB_PHY_CSS_LOW_DATARATE_SUP, - IEEE802154_PIB_PHY_UWB_COU_PULSES_SUP, - IEEE802154_PIB_PHY_UWB_CS_PULSES_SUP, - IEEE802154_PIB_PHY_UWB_LCP_PULSES_SUP, - IEEE802154_PIB_PHY_UWB_CURR_PULSE_SHAPE, - IEEE802154_PIB_PHY_UWB_COU_PULSE, - IEEE802154_PIB_PHY_UWB_CS_PULSE, - IEEE802154_PIB_PHY_UWB_LCP_WEIGHT1, - IEEE802154_PIB_PHY_UWB_LCP_WEIGHT2, - IEEE802154_PIB_PHY_UWB_LCP_WEIGHT3, - IEEE802154_PIB_PHY_UWB_LCP_WEIGHT4, - IEEE802154_PIB_PHY_UWB_LCP_DELAY2, - IEEE802154_PIB_PHY_UWB_LCP_DELAY3, - IEEE802154_PIB_PHY_UWB_LCP_DELAY4, - IEEE802154_PIB_PHY_RANGING, - IEEE802154_PIB_PHY_RANGING_CRYSTAL_OFFSET, - IEEE802154_PIB_PHY_RANGING_DPS, - IEEE802154_PIB_PHY_CURRENT_CODE, - IEEE802154_PIB_PHY_NATIVE_PRF, - IEEE802154_PIB_PHY_UWB_SCAN_BINS_PER_CHAN, - IEEE802154_PIB_PHY_UWB_INS_PREAMBLE_INTERVAL, - IEEE802154_PIB_PHY_UWB_TX_RMARKER, - IEEE802154_PIB_PHY_UWB_RX_RMARKER, - IEEE802154_PIB_PHY_RFRAME_PROC_TIME, - IEEE802154_PIB_PHY_CCA_DURATION, + IEEE802154_ATTR_PHY_CURRENT_CHANNEL = 0x00, + IEEE802154_ATTR_PHY_CHANNELS_SUPPORTED, + IEEE802154_ATTR_PHY_TX_POWER_TOLERANCE, + IEEE802154_ATTR_PHY_TX_POWER, + IEEE802154_ATTR_PHY_CCA_MODE, + IEEE802154_ATTR_PHY_CURRENT_PAGE, + IEEE802154_ATTR_PHY_MAX_FRAME_DURATION, + IEEE802154_ATTR_PHY_SHR_DURATION, + IEEE802154_ATTR_PHY_SYM_PER_OCTET, + IEEE802154_ATTR_PHY_PREAMBLE_SYM_LEN, + IEEE802154_ATTR_PHY_UWB_DATARATES_SUP, + IEEE802154_ATTR_PHY_CSS_LOW_DATARATE_SUP, + IEEE802154_ATTR_PHY_UWB_COU_PULSES_SUP, + IEEE802154_ATTR_PHY_UWB_CS_PULSES_SUP, + IEEE802154_ATTR_PHY_UWB_LCP_PULSES_SUP, + IEEE802154_ATTR_PHY_UWB_CURR_PULSE_SHAPE, + IEEE802154_ATTR_PHY_UWB_COU_PULSE, + IEEE802154_ATTR_PHY_UWB_CS_PULSE, + IEEE802154_ATTR_PHY_UWB_LCP_WEIGHT1, + IEEE802154_ATTR_PHY_UWB_LCP_WEIGHT2, + IEEE802154_ATTR_PHY_UWB_LCP_WEIGHT3, + IEEE802154_ATTR_PHY_UWB_LCP_WEIGHT4, + IEEE802154_ATTR_PHY_UWB_LCP_DELAY2, + IEEE802154_ATTR_PHY_UWB_LCP_DELAY3, + IEEE802154_ATTR_PHY_UWB_LCP_DELAY4, + IEEE802154_ATTR_PHY_RANGING, + IEEE802154_ATTR_PHY_RANGING_CRYSTAL_OFFSET, + IEEE802154_ATTR_PHY_RANGING_DPS, + IEEE802154_ATTR_PHY_CURRENT_CODE, + IEEE802154_ATTR_PHY_NATIVE_PRF, + IEEE802154_ATTR_PHY_UWB_SCAN_BINS_PER_CHAN, + IEEE802154_ATTR_PHY_UWB_INS_PREAMBLE_INTERVAL, + IEEE802154_ATTR_PHY_UWB_TX_RMARKER, + IEEE802154_ATTR_PHY_UWB_RX_RMARKER, + IEEE802154_ATTR_PHY_RFRAME_PROC_TIME, + IEEE802154_ATTR_PHY_CCA_DURATION, + IEEE802154_ATTR_PHY_SYMBOL_DURATION, /* Non-standard attribute */ /* MAC PIB Attributes */ - IEEE802154_PIB_MAC_EXTENDED_ADDR = 0x40, - IEEE802154_PIB_MAC_ACK_WAIT_DUR, - IEEE802154_PIB_MAC_ASSOCIATED_PANCOORD, - IEEE802154_PIB_MAC_ASSOCIATION_PERMIT, - IEEE802154_PIB_MAC_AUTO_REQUEST, - IEEE802154_PIB_MAC_BATT_LIFE_EXT, - IEEE802154_PIB_MAC_BATT_LIFE_EXT_PERIODS, - IEEE802154_PIB_MAC_BEACON_PAYLOAD, - IEEE802154_PIB_MAC_BEACON_PAYLOAD_LEN, - IEEE802154_PIB_MAC_BEACON_ORDER, - IEEE802154_PIB_MAC_BEACON_TX_TIME, - IEEE802154_PIB_MAC_BSN, - IEEE802154_PIB_MAC_COORD_EXT_ADDR, - IEEE802154_PIB_MAC_COORD_SHORT_ADDR, - IEEE802154_PIB_MAC_DSN, - IEEE802154_PIB_MAC_GTS_PERMIT, - IEEE802154_PIB_MAC_MAX_BE, - IEEE802154_PIB_MAC_MAX_CSMA_BACKOFFS, - IEEE802154_PIB_MAC_FRAME_TOTAL_WAIT_TIME, - IEEE802154_PIB_MAC_MAX_FRAME_RETRIES, - IEEE802154_PIB_MAC_MIN_BE, - IEEE802154_PIB_MAC_LIFS_PERIOD, - IEEE802154_PIB_MAC_SIFS_PERIOD, - IEEE802154_PIB_MAC_PANID, - IEEE802154_PIB_MAC_PROMISCUOUS_MODE, - IEEE802154_PIB_MAC_RANGING_SUPPORT, - IEEE802154_PIB_MAC_RESPONSE_WAIT_TIME, - IEEE802154_PIB_MAC_RX_ON_WHEN_IDLE, - IEEE802154_PIB_MAC_SECURITY_ENABLED, - IEEE802154_PIB_MAC_SHORT_ADDRESS, - IEEE802154_PIB_MAC_SUPERFRAME_ORDER, - IEEE802154_PIB_MAC_SYNC_SYMBOL_OFFSET, + IEEE802154_ATTR_MAC_EXTENDED_ADDR = 0x40, + IEEE802154_ATTR_MAC_ACK_WAIT_DUR, + IEEE802154_ATTR_MAC_ASSOCIATED_PANCOORD, + IEEE802154_ATTR_MAC_ASSOCIATION_PERMIT, + IEEE802154_ATTR_MAC_AUTO_REQUEST, + IEEE802154_ATTR_MAC_BATT_LIFE_EXT, + IEEE802154_ATTR_MAC_BATT_LIFE_EXT_PERIODS, + IEEE802154_ATTR_MAC_BEACON_PAYLOAD, + IEEE802154_ATTR_MAC_BEACON_PAYLOAD_LEN, + IEEE802154_ATTR_MAC_BEACON_ORDER, + IEEE802154_ATTR_MAC_BEACON_TX_TIME, + IEEE802154_ATTR_MAC_BSN, + IEEE802154_ATTR_MAC_COORD_EXT_ADDR, + IEEE802154_ATTR_MAC_COORD_SHORT_ADDR, + IEEE802154_ATTR_MAC_DSN, + IEEE802154_ATTR_MAC_GTS_PERMIT, + IEEE802154_ATTR_MAC_MAX_BE, + IEEE802154_ATTR_MAC_MAX_CSMA_BACKOFFS, + IEEE802154_ATTR_MAC_MAX_FRAME_WAITTIME, + IEEE802154_ATTR_MAC_MAX_FRAME_RETRIES, + IEEE802154_ATTR_MAC_MIN_BE, + IEEE802154_ATTR_MAC_LIFS_PERIOD, + IEEE802154_ATTR_MAC_SIFS_PERIOD, + IEEE802154_ATTR_MAC_PANID, + IEEE802154_ATTR_MAC_PROMISCUOUS_MODE, + IEEE802154_ATTR_MAC_RANGING_SUPPORT, + IEEE802154_ATTR_MAC_RESPONSE_WAIT_TIME, + IEEE802154_ATTR_MAC_RX_ON_WHEN_IDLE, + IEEE802154_ATTR_MAC_SECURITY_ENABLED, + IEEE802154_ATTR_MAC_SHORT_ADDRESS, + IEEE802154_ATTR_MAC_SUPERFRAME_ORDER, + IEEE802154_ATTR_MAC_SYNC_SYMBOL_OFFSET, IEEE802154_PIB_MAC_TIMESTAMP_SUPPORT, IEEE802154_PIB_MAC_TRANSACTION_PERSIST_TIME, IEEE802154_PIB_MAC_TX_CTRL_ACTIVE_DUR, IEEE802154_PIB_MAC_TX_CTRL_PAUSE_DUR, IEEE802154_PIB_MAC_TX_TOTAL_DUR, + IEEE802154_ATTR_MAC_DEVMODE, /* Non-standard */ /* MAC Security Attributes */ @@ -336,6 +376,7 @@ enum ieee802154_frametype_e }; /* MAC command IDs */ +/* TODO: Change terminology to be "current primitive" */ enum ieee802154_cmdid_e { @@ -352,7 +393,7 @@ enum ieee802154_cmdid_e enum ieee802154_devmode_e { - IEEE802154_DEVMODE_ENDPOINT, + IEEE802154_DEVMODE_ENDPOINT = 0x00, IEEE802154_DEVMODE_COORD, IEEE802154_DEVMODE_PANCOORD }; @@ -371,6 +412,10 @@ enum ieee802154_addrmode_e IEEE802154_ADDRMODE_NONE = 0, IEEE802154_ADDRMODE_SHORT = 2, IEEE802154_ADDRMODE_EXTENDED + + /* TODO: Add a IEEE802154_ADDRMODE_ANY setting for structs where both the + * extended and short addresses are safe to use. + */ }; struct ieee802154_addr_s @@ -379,7 +424,7 @@ struct ieee802154_addr_s enum ieee802154_addrmode_e mode; - uint16_t panid; /* PAN identifier, can be + uint16_t panid; /* PAN identifier, can be * IEEE802154_PAN_UNSPEC */ uint16_t saddr; /* short address */ uint8_t eaddr[IEEE802154_EADDR_LEN]; /* extended address */ @@ -502,6 +547,8 @@ union ieee802154_macattr_u uint8_t coord_eaddr[IEEE802154_EADDR_LEN]; uint16_t coord_saddr; + enum ieee802154_devmode_e devmode; + bool is_assoc; bool assoc_permit; bool auto_req; @@ -509,7 +556,7 @@ union ieee802154_macattr_u bool gts_permit; bool promisc_mode; bool rng_support; - bool resp_wait_time; + bool resp_waittime; bool rxonidle; bool sec_enabled; bool timestamp_support; @@ -519,7 +566,7 @@ union ieee802154_macattr_u uint8_t max_csma_backoffs : 3; uint8_t max_be : 4; uint8_t min_be : 4; - uint32_t max_frame_wait_time; + uint32_t max_frame_waittime; uint8_t max_retries; uint8_t lifs_period; uint8_t sifs_period; @@ -529,7 +576,7 @@ union ieee802154_macattr_u uint32_t tx_ctrl_pause_dur; uint32_t tx_total_dur; - uint8_t beacon_payload[IEEE802154_PIB_MAC_BEACON_PAYLOAD_LEN]; + uint8_t beacon_payload[IEEE802154_ATTR_MAC_BEACON_PAYLOAD_LEN]; uint8_t beacon_payload_len; uint8_t beacon_order; uint32_t beacon_tx_time : 24; @@ -543,7 +590,8 @@ union ieee802154_macattr_u union ieee802154_phyattr_u { uint8_t channel; - int32_t txpwr + int32_t txpwr; + uint32_t symdur_picosec; /* TODO: Fill this out as we implement supported get/set commands */ }; @@ -577,8 +625,8 @@ enum ieee802154_scantype_e struct ieee802154_frame_meta_s { - enum ieee802154_addrmode_e src_addrmode; /* Source Address Mode */ - struct ieee802154_addr_s dest_addr; /* Destination Address */ + enum ieee802154_addrmode_e srcaddr_mode; /* Source Address Mode */ + struct ieee802154_addr_s destaddr; /* Destination Address */ uint8_t msdu_handle; /* Handle assoc. with MSDU */ @@ -641,13 +689,13 @@ struct ieee802154_data_conf_s * the beginning of the ranging exchange */ - uint32_t rng_counter_start; + uint32_t rng_counter_start; /* A count of the time units corresponding to an RMARKER at the antenna at * end of the ranging exchange */ - uint32_t rng_counter_stop; + uint32_t rng_counter_stop; /* A count of the time units in a message exchange over which the tracking * offset was measured @@ -660,10 +708,10 @@ struct ieee802154_data_conf_s */ uint32_t rng_offset; - - /* The Figure of Merit (FoM) characterizing the ranging measurement */ - uint8_t rng_fom; + /* The Figure of Merit (FoM) characterizing the ranging measurement */ + + uint8_t rng_fom; #endif }; @@ -797,7 +845,7 @@ struct ieee802154_assoc_ind_s { /* Address of device requesting association. Always in extended mode */ - struct ieee802154_addr_s dev_addr; + uint8_t devaddr[IEEE802154_EADDR_LEN]; /* Capabilities of associating device */ @@ -822,7 +870,11 @@ struct ieee802154_assoc_resp_s { /* Address of device requesting association. Always in extended mode */ - struct ieee802154_addr_s dev_addr; + uint8_t devaddr[8]; + + /* Address assigned to the device. 0xFFFF if failure */ + + uint16_t assocsaddr; /* Status of association attempt */ @@ -851,7 +903,7 @@ struct ieee802154_assoc_conf_s * unsuccessful. */ - struct ieee802154_addr_s dev_addr; + uint16_t saddr; /* Status of association attempt */ @@ -1185,7 +1237,7 @@ struct ieee802154_scan_conf_s uint8_t ch_page; uint8_t num_channels; -#warning Figure out how to handle missing primitive semantics. See standard. + /* TODO: Figure out how to handle missing primitive semantics. See standard. */ }; /***************************************************************************** @@ -1198,7 +1250,7 @@ struct ieee802154_scan_conf_s struct ieee802154_get_req_s { - enum ieee802154_pib_attr_e pib_attr; + enum ieee802154_attr_e attr; union ieee802154_attr_u attrval; }; @@ -1208,17 +1260,17 @@ struct ieee802154_get_req_s * Description: * Attempts to write the given value to the indicated PIB attribute. * - * NOTE: The standard specifies that confirmation should be indicated via + * NOTE: The standard specifies that confirmation should be indicated via * the asynchronous MLME-SET.confirm primitve. However, in our implementation * there is no reason not to synchronously return the status immediately. - * Therefore, we do merge the functionality of the MLME-SET.request and + * Therefore, we do merge the functionality of the MLME-SET.request and * MLME-SET.confirm primitives together. - * + * *****************************************************************************/ struct ieee802154_set_req_s { - enum ieee802154_pib_attr_e pib_attr; + enum ieee802154_attr_e attr; union ieee802154_attr_u attrval; }; @@ -1318,7 +1370,7 @@ struct ieee802154_syncloss_ind_s struct ieee802154_poll_req_s { - struct ieee802154_addr_s coord_addr; + struct ieee802154_addr_s coordaddr; #ifdef CONFIG_IEEE802154_SECURITY /* Security information if enabled */ @@ -1396,13 +1448,16 @@ union ieee802154_notif_u struct ieee802154_notif_s { /* Must be first member so that we can interchange between the actual - *notification and this extended struct. + * notification and this extended struct. */ union ieee802154_notif_u u; enum ieee802154_notify_e notiftype; - /* Support a singly linked list */ + /* Support a singly linked list. For use by receivers. The MAC has it's own + * extended struct type with another forward link that the MAC uses internally + * to handle allocation and freeing. + */ FAR struct ieee802154_notif_s *flink; }; diff --git a/include/nuttx/wireless/ieee802154/ieee802154_radio.h b/include/nuttx/wireless/ieee802154/ieee802154_radio.h index e0ff8b664fe..7e9cd146537 100644 --- a/include/nuttx/wireless/ieee802154/ieee802154_radio.h +++ b/include/nuttx/wireless/ieee802154/ieee802154_radio.h @@ -66,6 +66,14 @@ struct ieee802154_txdesc_s FAR struct ieee802154_txdesc_s *flink; + /* Destination Address */ + + struct ieee802154_addr_s destaddr; /* Only used for indirect transactions */ + + /* Pointer to the frame IOB */ + + FAR struct iob_s *frame; + /* Pointer to the data confirmation structure to be populated upon * success/failure of the transmission. */ @@ -74,6 +82,9 @@ struct ieee802154_txdesc_s enum ieee802154_frametype_e frametype; /* Frame type. Used by MAC layer to * control how tx done is handled */ + bool framepending; /* Did the ACK have the frame pending bit + * bit set */ + uint32_t purge_time; /* Time to purge transaction */ /* TODO: Add slotting information for GTS transactions */ }; @@ -82,37 +93,32 @@ struct ieee802154_txdesc_s struct ieee802154_radiocb_s { - 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 int (*poll) (FAR const struct ieee802154_radiocb_s *radiocb, + bool gts, FAR struct ieee802154_txdesc_s **tx_desc); CODE void (*txdone) (FAR const struct ieee802154_radiocb_s *radiocb, - FAR const struct ieee802154_txdesc_s *tx_desc); + FAR 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_radio_s; /* Forward reference */ - -struct ieee802154_radioops_s +struct ieee802154_radio_s { 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 (*txnotify)(FAR struct ieee802154_radio_s *radio, bool gts); + CODE int (*txdelayed)(FAR struct ieee802154_radio_s *radio, + FAR struct ieee802154_txdesc_s *txdesc, + uint32_t symboldelay); + CODE int (*reset_attrs) (FAR struct ieee802154_radio_s *radio); CODE int (*get_attr) (FAR struct ieee802154_radio_s *radio, - enum ieee802154_pib_attr_e pib_attr, + enum ieee802154_attr_e , FAR union ieee802154_attr_u *attrval); CODE int (*set_attr) (FAR struct ieee802154_radio_s *radio, - enum ieee802154_pib_attr_e pib_attr, + enum ieee802154_attr_e , FAR const union ieee802154_attr_u *attrval); -}; - -struct ieee802154_radio_s -{ - FAR const struct ieee802154_radioops_s *ops; + CODE int (*rxenable) (FAR struct ieee802154_radio_s *radio, bool enable); + CODE int (*req_rxenable)(FAR struct ieee802154_radio_s *radio, + FAR struct ieee802154_rxenable_req_s *req); }; #ifdef __cplusplus diff --git a/net/sixlowpan/sixlowpan_framer.c b/net/sixlowpan/sixlowpan_framer.c index 2d8d54480a8..c67ae2768bc 100644 --- a/net/sixlowpan/sixlowpan_framer.c +++ b/net/sixlowpan/sixlowpan_framer.c @@ -163,7 +163,7 @@ int sixlowpan_meta_data(FAR struct ieee802154_driver_s *ieee, /* Source address mode */ - meta->src_addrmode = pktmeta->sextended != 0? + meta->srcaddr_mode = pktmeta->sextended != 0? IEEE802154_ADDRMODE_EXTENDED : IEEE802154_ADDRMODE_SHORT; @@ -197,25 +197,25 @@ int sixlowpan_meta_data(FAR struct ieee802154_driver_s *ieee, { /* Broadcast requires short address mode. */ - meta->dest_addr.mode = IEEE802154_ADDRMODE_SHORT; - meta->dest_addr.saddr = 0; + meta->destaddr.mode = IEEE802154_ADDRMODE_SHORT; + meta->destaddr.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); + meta->destaddr.mode = IEEE802154_ADDRMODE_EXTENDED; + sixlowpan_eaddrcopy(&meta->destaddr.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->destaddr.mode = IEEE802154_ADDRMODE_SHORT; + sixlowpan_saddrcopy(&meta->destaddr.saddr, pktmeta->dest.saddr.u8); } - meta->dest_addr.panid = pktmeta->dpanid; + meta->destaddr.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 diff --git a/net/sixlowpan/sixlowpan_utils.c b/net/sixlowpan/sixlowpan_utils.c index 75da3ed5567..822127f7f7d 100644 --- a/net/sixlowpan/sixlowpan_utils.c +++ b/net/sixlowpan/sixlowpan_utils.c @@ -195,7 +195,7 @@ int sixlowpan_src_panid(FAR struct ieee802154_driver_s *ieee, int ret; memcpy(arg.ifr_name, ieee->i_dev.d_ifname, IFNAMSIZ); - arg.u.getreq.pib_attr = IEEE802154_PIB_MAC_PANID; + arg.u.getreq.attr = IEEE802154_ATTR_MAC_PANID; ret = dev->d_ioctl(dev, MAC802154IOC_MLME_GET_REQUEST, (unsigned long)((uintptr_t)&arg)); if (ret < 0) diff --git a/wireless/ieee802154/Kconfig b/wireless/ieee802154/Kconfig index 9e12f8b1bb5..7ffe2654f43 100644 --- a/wireless/ieee802154/Kconfig +++ b/wireless/ieee802154/Kconfig @@ -15,6 +15,12 @@ menuconfig WIRELESS_IEEE802154 if WIRELESS_IEEE802154 +config IEEE802154_DEFAULT_EADDR + hex "IEEE 802.15.4 Default Extended Address" + default 0x00fade00deadbeef + ---help--- + Set the default extended address to be used by MAC networks on init + config IEEE802154_MAC_DEV bool "Character driver for IEEE 802.15.4 MAC layer" default n diff --git a/wireless/ieee802154/Make.defs b/wireless/ieee802154/Make.defs index eedec934ebb..da1b1bc05e0 100644 --- a/wireless/ieee802154/Make.defs +++ b/wireless/ieee802154/Make.defs @@ -37,7 +37,12 @@ ifeq ($(CONFIG_WIRELESS_IEEE802154),y) # Include IEEE 802.15.4 support -CSRCS += mac802154.c mac802154_indalloc.c +CSRCS += mac802154.c mac802154_indalloc.c mac802154_assoc.c mac802154_disassoc.c +CSRCS += mac802154_bind.c mac802154_data.c mac802154_get_mhrlen.c +CSRCS += mac802154_getset.c mac802154_gts.c mac802154_ioctl.c +CSRCS += mac802154_notif.c mac802154_orphan.c mac802154_poll.c mac802154_purge.c +CSRCS += mac802154_reset.c mac802154_rxenable.c mac802154_scan.c mac802154_start.c +CSRCS += mac802154_sync.c # Include wireless devices build support diff --git a/wireless/ieee802154/mac802154.c b/wireless/ieee802154/mac802154.c index c57891f83c2..755cdc035e4 100644 --- a/wireless/ieee802154/mac802154.c +++ b/wireless/ieee802154/mac802154.c @@ -2,8 +2,11 @@ * wireless/ieee802154/mac802154.c * * Copyright (C) 2016 Sebastien Lorquet. All rights reserved. + * Copyright (C) 2017 Gregory Nutt. All rights reserved. * Copyright (C) 2017 Verge Inc. All rights reserved. + * * Author: Sebastien Lorquet + * Author: Gregory Nutt * Author: Anthony Merlino * * Redistribution and use in source and binary forms, with or without @@ -53,347 +56,54 @@ #include #include "mac802154.h" +#include "mac802154_notif.h" +#include "mac802154_internal.h" +#include "mac802154_assoc.h" +#include "mac802154_data.h" +#include "mac802154_poll.h" #include #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ -/* Configuration ************************************************************/ -/* If processing is not done at the interrupt level, then work queue support - * is required. - */ - -#if !defined(CONFIG_SCHED_WORKQUEUE) -# error Work queue support is required in this configuration (CONFIG_SCHED_WORKQUEUE) -#else - - /* Use the low priority work queue if possible */ - -# if defined(CONFIG_MAC802154_HPWORK) -# define MAC802154_WORK HPWORK -# elif defined(CONFIG_MAC802154_LPWORK) -# define MAC802154_WORK LPWORK -# else -# error Neither CONFIG_MAC802154_HPWORK nor CONFIG_MAC802154_LPWORK defined -# endif -#endif - -#if !defined(CONFIG_MAC802154_NNOTIF) || CONFIG_MAC802154_NNOTIF <= 0 -# undef CONFIG_MAC802154_NNOTIF -# define CONFIG_MAC802154_NNOTIF 6 -#endif - -#if !defined(CONFIG_MAC802154_NTXDESC) || CONFIG_MAC802154_NTXDESC <= 0 -# undef CONFIG_MAC802154_NTXDESC -# define CONFIG_MAC802154_NTXDESC 3 -#endif - -#if CONFIG_MAC802154_NTXDESC > CONFIG_MAC802154_NNOTIF -#error CONFIG_MAC802154_NNOTIF must be greater than CONFIG_MAC802154_NTXDESC -#endif - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -struct mac802154_txtrans_s -{ - /* Supports a singly linked list */ - - FAR struct mac802154_txtrans_s *flink; - FAR struct iob_s *frame; - uint8_t handle; - enum ieee802154_frametype_e frametype; - sem_t sem; -}; - -struct mac802154_unsec_mhr_s -{ - uint8_t length; - union - { - uint16_t frame_control; - uint8_t data[IEEE802154_MAX_UNSEC_MHR_OVERHEAD]; - } u; -}; - -struct mac802154_radiocb_s -{ - struct ieee802154_radiocb_s cb; - FAR struct ieee802154_privmac_s *priv; -}; - -/* The privmac structure holds the internal state of the MAC and is the - * underlying represention of the opaque MACHANDLE. It contains storage for - * the IEEE802.15.4 MIB attributes. - */ - -struct ieee802154_privmac_s -{ - FAR struct ieee802154_radio_s *radio; /* Contained IEEE802.15.4 radio dev */ - FAR const struct mac802154_maccb_s *cb; /* Contained MAC callbacks */ - FAR struct mac802154_radiocb_s radiocb; /* Interface to bind to radio */ - - sem_t exclsem; /* Support exclusive access */ - - /* Support a single transaction dedicated to commands. As of now I see no - * condition where you need to have more than one command frame simultaneously - */ - - struct - { - sem_t sem; /* Exclusive use of the cmdtrans */ - enum ieee802154_cmdid_e type; /* Type of cmd in the cmdtrans */ - struct mac802154_txtrans_s trans; /* Dedicated txframe for cmds */ - - /* Has the command been successfully sent. This is to help protect - * against an odd edge case that may or may not ever happen. The condition - * occurs when you receive a seemingly appropriate response to the command - * yet the command was never actually sent. - */ - - bool txdone; - } cmd; - - /* Pre-allocated notifications to be passed to the registered callback. These - * need to be freed by the application using mac802154_xxxxnotif_free when - * the callee layer is finished with it's use. - */ - - FAR struct ieee802154_notif_s *notif_free; - struct ieee802154_notif_s notif_alloc[CONFIG_MAC802154_NNOTIF]; - sq_queue_t notif_queue; - - FAR struct ieee802154_txdesc_s *txdesc_free; - struct ieee802154_txdesc_s txdesc_alloc[CONFIG_IEEE802154_NTXDESC]; - sq_queue_t txdesc_queue; - sq_queue_t txdone_queue; - - /* Work structures for offloading aynchronous work */ - - struct work_s tx_work; - struct work_s rx_work; - - /* Support a singly linked list of transactions that will be sent using the - * CSMA algorithm. On a non-beacon enabled PAN, these transactions will be - * sent whenever. On a beacon-enabled PAN, these transactions will be sent - * during the CAP of the Coordinator's superframe. - */ - - sq_queue_t csma_queue; - - /* Support a singly linked list of transactions that will be sent indirectly. - * This list should only be used by a MAC acting as a coordinator. These - * transactions will stay here until the data is extracted by the destination - * device sending a Data Request MAC command or if too much time passes. This - * list should also be used to populate the address list of the outgoing - * beacon frame. - */ - - sq_queue_t indirect_queue; - - /* Support a singly linked list of frames received */ - - sq_queue_t dataind_queue; - - /* MAC PIB attributes, grouped to save memory */ - - /* Holds all address information (Extended, Short, and PAN ID) for the MAC. */ - - struct ieee802154_addr_s addr; - - /* Holds all address information (Extended, Short) for Coordinator */ - - struct ieee802154_addr_s coordaddr; - - /* The maximum number of symbols to wait for an acknowledgement frame to - * arrive following a transmitted data frame. [1] pg. 126 - * - * NOTE: This may be able to be a 16-bit or even an 8-bit number. I wasn't - * sure at the time what the range of reasonable values was. - */ - - uint32_t ack_waitdur; - - /* The maximum time to wait either for a frame intended as a response to a - * data request frame or for a broadcast frame following a beacon with the - * Frame Pending field set to one. [1] pg. 127 - * - * NOTE: This may be able to be a 16-bit or even an 8-bit number. I wasn't - * sure at the time what the range of reasonable values was. - */ - - uint32_t max_frame_waittime; - - /* The maximum time (in unit periods) that a transaction is stored by a - * coordinator and indicated in its beacon. - */ - - uint16_t trans_persisttime; - - /* Contents of beacon payload */ - - uint8_t beacon_payload[IEEE802154_MAX_BEACON_PAYLOAD_LEN]; - uint8_t beacon_payload_len; /* Length of beacon payload */ - - uint8_t battlifeext_periods; /* # of backoff periods during which rx is - * enabled after the IFS following beacon */ - - uint8_t bsn; /* Seq. num added to tx beacon frame */ - uint8_t dsn; /* Seq. num added to tx data or MAC frame */ - uint8_t maxretries; /* Max # of retries alloed after tx failure */ - - /* The maximum time, in multiples of aBaseSuperframeDuration, a device shall - * wait for a response command frame to be available following a request - * command frame. [1] 128. - */ - - uint8_t resp_waittime; - - /* The total transmit duration (including PHY header and FCS) specified in - * symbols. [1] pg. 129. - */ - - uint32_t tx_totaldur; - - /* Start of 32-bit bitfield */ - - uint32_t isassoc : 1; /* Are we associated to the PAN */ - uint32_t assocpermit : 1; /* Are we allowing assoc. as a coord. */ - uint32_t autoreq : 1; /* Automatically send data req. if addr - * addr is in the beacon frame */ - - uint32_t battlifeext : 1; /* Is BLE enabled */ - uint32_t gtspermit : 1; /* Is PAN Coord. accepting GTS reqs. */ - uint32_t promisc : 1; /* Is promiscuous mode on? */ - uint32_t rngsupport : 1; /* Does MAC sublayer support ranging */ - uint32_t sec_enabled : 1; /* Does MAC sublayer have security en. */ - uint32_t timestamp_support : 1; /* Does MAC layer supports timestamping */ - - uint32_t max_csmabackoffs : 3; /* Max num backoffs for CSMA algorithm - * before declaring ch access failure */ - - uint32_t beaconorder : 4; /* Freq. that beacon is transmitted */ - - uint32_t superframeorder : 4; /* Length of active portion of outgoing - * superframe, including the beacon */ - - /* The offset, measured is symbols, between the symbol boundary at which the - * MLME captures the timestamp of each transmitted and received frame, and - * the onset of the first symbol past the SFD, namely the first symbol of - * the frames [1] pg. 129. - */ - - uint32_t sync_symboffset : 12; - - /* End of 32-bit bitfield */ - - /* Start of 32-bit bitfield */ - - uint32_t beacon_txtime : 24; /* Time of last beacon transmit */ - uint32_t minbe : 4; /* Min value of backoff exponent (BE) */ - uint32_t maxbe : 4; /* Max value of backoff exponent (BE) */ - - /* End of 32-bit bitfield */ - - /* Start of 32-bit bitfield */ - - uint32_t txctrl_activedur : 17; /* Duration for which tx is permitted to - * be active */ - uint32_t txctrl_pausedur : 1; /* Duration after tx before another tx is - * permitted. 0=2000, 1= 10000 */ - - /* What type of device is this node acting as */ - - enum ieee802154_devmode_e devmode : 2; - - bool csma_tryagain : 1; - bool gts_tryagain : 1; - - /* 10-bits remaining */ - - /* End of 32-bit bitfield. */ - - /* TODO: Add Security-related MAC PIB attributes */ -}; - /**************************************************************************** * Private Function Prototypes ****************************************************************************/ -/* Internal Functions */ - -static inline int mac802154_takesem(sem_t *sem); -#define mac802154_givesem(s) sem_post(s); +/* Data structure pools and allocation helpers */ static void mac802154_resetqueues(FAR struct ieee802154_privmac_s *priv); -static void mac802154_notifpool_init(FAR struct ieee802154_privmac_s *priv); -static FAR struct ieee802154_notif_s * - mac802154_notif_alloc(FAR struct ieee802154_privmac_s *priv); - -static int mac802154_defaultmib(FAR struct ieee802154_privmac_s *priv); -static int mac802154_applymib(FAR struct ieee802154_privmac_s *priv); - -static void mac802154_txdone_worker(FAR void *arg); -static void mac802154_rxframe_worker(FAR void *arg); - -static void mac802154_cmd_txdone(FAR struct ieee802154_privmac_s *priv, - FAR struct ieee802154_txdesc_s *txdesc); /* IEEE 802.15.4 PHY Interface OPs */ -static int mac802154_poll_csma(FAR const struct ieee802154_radiocb_s *radiocb, - FAR struct ieee802154_txdesc_s **tx_desc, - FAR struct iob_s **frame); - -static int mac802154_poll_gts(FAR const struct ieee802154_radiocb_s *radiocb, - FAR struct ieee802154_txdesc_s **tx_desc, - FAR struct iob_s **frame); +static int mac802154_poll(FAR const struct ieee802154_radiocb_s *radiocb, + bool gts, FAR struct ieee802154_txdesc_s **tx_desc); static void mac802154_txdone(FAR const struct ieee802154_radiocb_s *radiocb, - FAR const struct ieee802154_txdesc_s *tx_desc); + FAR struct ieee802154_txdesc_s *tx_desc); +static void mac802154_txdone_worker(FAR void *arg); static void mac802154_rxframe(FAR const struct ieee802154_radiocb_s *radiocb, FAR struct ieee802154_data_ind_s *ind); +static void mac802154_rxframe_worker(FAR void *arg); -/**************************************************************************** - * Private Data - ****************************************************************************/ +static void mac802154_rx_datareq(FAR struct ieee802154_privmac_s *priv, + FAR struct ieee802154_data_ind_s *ind); +static void mac802154_rx_dataframe(FAR struct ieee802154_privmac_s *priv, + FAR struct ieee802154_data_ind_s *ind); -/* Map between ieee802154_addrmode_e enum and actual address length */ +static void mac802154_purge_worker(FAR void *arg); -static const uint8_t mac802154_addr_length[4] = {0, 0, 2, 8}; +/* Watchdog Timeout Functions */ + +static void mac802154_timeout_expiry(int argc, uint32_t arg, ...); + +static uint32_t mac802154_symtoticks(FAR struct ieee802154_privmac_s *priv, + uint32_t symbols); /**************************************************************************** * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: mac802154_semtake - * - * Description: - * Acquire the semaphore used for access serialization. - * - ****************************************************************************/ - -static inline int mac802154_takesem(sem_t *sem) -{ - /* Take a count from the semaphore, possibly waiting */ - - if (sem_wait(sem) < 0) - { - /* EINTR is the only error that we expect */ - - int errcode = get_errno(); - DEBUGASSERT(errcode == EINTR); - return -errcode; - } - - return OK; -} - /**************************************************************************** * Name: mac802154_resetqueues * @@ -409,303 +119,294 @@ static void mac802154_resetqueues(FAR struct ieee802154_privmac_s *priv) sq_init(&priv->txdone_queue); sq_init(&priv->csma_queue); + sq_init(&priv->gts_queue); sq_init(&priv->indirect_queue); sq_init(&priv->dataind_queue); - sq_init(&priv->notif_queue); + /* Initialize the tx descriptor allocation pool */ + sq_init(&priv->txdesc_queue); - - for (i = 0; i < CONFIG_MAC802154_NNOTIF; i++) - { - sq_addlast((FAR sq_entry_t *)&priv->notif_alloc[i], &priv->notif_queue); - } - for (i = 0; i < CONFIG_MAC802154_NTXDESC; i++) { - sq_addlast((FAR sq_entry_t *)&priv->txdesc_alloc[i], &priv->txdesc_queue); + sq_addlast((FAR sq_entry_t *)&priv->txdesc_pool[i], &priv->txdesc_queue); } - + sem_init(&priv->txdesc_sem, 0, CONFIG_MAC802154_NTXDESC); + + /* Initialize the notifcation allocation pool */ + mac802154_notifpool_init(priv); } /**************************************************************************** - * Name: mac802154_notifpool_init + * Name: mac802154_txdesc_pool * * Description: - * This function initializes the notification structure pool. It allows the - * MAC to pass notifications and for the callee to free them when they are - * done using them, saving copying the data when passing. - * - ****************************************************************************/ - -static void mac802154_notifpool_init(FAR struct ieee802154_privmac_s *priv) -{ - FAR struct ieee802154_notif_s *pool = priv->notif_alloc; - int remaining = CONFIG_MAC802154_NNOTIF; - - priv->notif_free = NULL; - while (remaining > 0) - { - FAR struct ieee802154_notif_s *notif = pool; - - /* Add the next meta data structure from the pool to the list of - * general structures. - */ - - notif->flink = priv->notif_free; - priv->notif_free = notif; - - /* Set up for the next structure from the pool */ - - pool++; - remaining--; - } -} - -/**************************************************************************** - * Name: mac802154_notif_alloc - * - * Description: - * This function allocates a free notification structure from the free list - * to be used for passing to the registered notify callback. The callee software - * is responsible for freeing the notification structure after it is done using - * it via mac802154_notif_free. + * This function allocates a tx descriptor and the dependent notification (data + * confirmation) from the free list. The notification and tx descriptor will + * be freed seperately, both by the MAC layer either directly, or through + * mac802154_notif_free in the case of the notification. * * Assumptions: * priv MAC struct is locked when calling. * + * Notes: + * If any of the semaphore waits inside this function get interrupted, the + * function will release the MAC layer. If this function returns -EINTR, the + * calling code should NOT release the MAC semaphore. + * ****************************************************************************/ -static FAR struct ieee802154_notif_s * - mac802154_notif_alloc(FAR struct ieee802154_privmac_s *priv) + +int mac802154_txdesc_alloc(FAR struct ieee802154_privmac_s *priv, + FAR struct ieee802154_txdesc_s **txdesc, + bool allow_interrupt) { + int ret; FAR struct ieee802154_notif_s *notif; - if (priv->notif_free == NULL) + /* Try and take a count from the semaphore. If this succeeds, we have + * "reserved" the structure, but still need to unlink it from the free list. + * The MAC is already locked, so there shouldn't be any other conflicting calls + */ + + ret = sem_trywait(&priv->txdesc_sem); + + if (ret == OK) { - return NULL; + *txdesc = (FAR struct ieee802154_txdesc_s *)sq_remfirst(&priv->txdesc_queue); } - - notif = priv->notif_free; - priv->notif_free = notif->flink; - - return notif; -} - -/**************************************************************************** - * Name: mac802154_defaultmib - * - * Description: - * Set the MIB to its default values. - * - ****************************************************************************/ - -static int mac802154_defaultmib(FAR struct ieee802154_privmac_s *priv) -{ - priv->isassoc = false; /* Not associated with a PAN */ - priv->assocpermit = false; /* Device (if coord) not accepting association */ - priv->autoreq = true; /* Auto send data req if addr. in beacon */ - priv->battlifeext = false; /* BLE disabled */ - priv->beacon_payload_len = 0; /* Beacon payload NULL */ - priv->beaconorder = 15; /* Non-beacon enabled network */ - priv->superframeorder = 15; /* Length of active portion of outgoing SF */ - priv->beacon_txtime = 0; /* Device never sent a beacon */ -#warning Set BSN and DSN to random values! - priv->bsn = 0; - priv->dsn = 0; - priv->gtspermit = true; /* PAN Coord accepting GTS requests */ - priv->minbe = 3; /* Min value of backoff exponent (BE) */ - priv->maxbe = 5; /* Max value of backoff exponent (BE) */ - priv->max_csmabackoffs = 4; /* Max # of backoffs before failure */ - priv->maxretries = 3; /* Max # of retries allowed after failure */ - priv->promisc = false; /* Device not in promiscuous mode */ - priv->rngsupport = false; /* Ranging not yet supported */ - priv->resp_waittime = 32; /* 32 SF durations */ - priv->sec_enabled = false; /* Security disabled by default */ - priv->tx_totaldur = 0; /* 0 transmit duration */ - - priv->trans_persisttime = 0x01F4; - - /* Reset the Coordinator address */ - - priv->coordaddr.mode = IEEE802154_ADDRMODE_NONE; - priv->coordaddr.saddr = IEEE802154_SADDR_UNSPEC; - memcpy(&priv->coordaddr.eaddr[0], IEEE802154_EADDR_UNSPEC, - IEEE802154_EADDR_LEN); - - /* Reset the device's address */ - - priv->addr.mode = IEEE802154_ADDRMODE_NONE; - priv->addr.panid = IEEE802154_PAN_UNSPEC; - priv->addr.saddr = IEEE802154_SADDR_UNSPEC; - memcpy(&priv->addr.eaddr[0], IEEE802154_EADDR_UNSPEC, IEEE802154_EADDR_LEN); - - - /* These attributes are effected and determined based on the PHY. Need to - * figure out how to "share" attributes between the radio driver and this - * MAC layer - * - * macAckWaitDuration - * macBattLifeExtPeriods - * macMaxFrameTotalWaitTime - * macLIFSPeriod - * macSIFSPeriod - * macSyncSymbolOffset - * macTimestampSupported - * macTxControlActiveDuration - * macTxControlPauseDuration - * macRxOnWhenIdle - */ - - return OK; -} - -/**************************************************************************** - * Name: mac802154_applymib - * - * Description: - * Some parts of the MIB must be sent to the radio device. This routine - * calls the radio device routines to store the related parameters in the - * radio driver. It must be called each time a MIB parameter is changed. - * - ****************************************************************************/ - -static int mac802154_applymib(FAR struct ieee802154_privmac_s *priv) -{ - return OK; -} - -/**************************************************************************** - * Name: mac802154_poll_csma - * - * Description: - * Called from the radio driver through the callback struct. This function is - * called when the radio has room for another CSMA transaction. If the MAC - * layer has a CSMA transaction, it copies it into the supplied buffer and - * returns the length. A descriptor is also populated with the transaction. - * - ****************************************************************************/ - -static int mac802154_poll_csma(FAR const struct ieee802154_radiocb_s *radiocb, - FAR struct ieee802154_txdesc_s **txdesc, - FAR struct iob_s **frame) -{ - FAR struct mac802154_radiocb_s *cb = - (FAR struct mac802154_radiocb_s *)radiocb; - FAR struct ieee802154_privmac_s *priv; - FAR struct mac802154_txtrans_s *trans; - FAR struct ieee802154_txdesc_s *desc; - FAR struct ieee802154_notif_s *notif; - - DEBUGASSERT(cb != NULL && cb->priv != NULL); - priv = cb->priv; - - /* Get exclusive access to the driver structure. We don't care about any - * signals so if we see one, just go back to trying to get access again. - */ - - while (mac802154_takesem(&priv->exclsem) != 0); - - /* Check to see if there are any CSMA transactions waiting */ - - trans = (FAR struct mac802154_txtrans_s *)sq_remfirst(&priv->csma_queue); - mac802154_givesem(&priv->exclsem); - - if (trans != NULL) + else { - /* Allocate a Tx descriptor to pass */ + /* Unlock MAC so that other work can be done to free a notification */ - desc = (FAR struct ieee802154_txdesc_s *)sq_remfirst(&priv->txdesc_queue); - if (desc == NULL) + mac802154_givesem(&priv->exclsem); + + /* Take a count from the tx desc semaphore, waiting if necessary. We + * only return from here with an error if we are allowing interruptions + * and we received a signal */ + + ret = mac802154_takesem(&priv->txdesc_sem, allow_interrupt); + if (ret < 0) { - wlerr("ERROR: Failed to allocate ieee802154_txdesc_s"); - goto errout; + /* MAC is already released */ + + return -EINTR; } - /* Allocate a notif struct (ie data confirmation struct) to pass with - * the tx descriptor. + /* If we've taken a count from the semaphore, we have "reserved" the struct + * but now we need to pop it off of the free list. We need to re-lock the + * MAC in order to ensure this happens correctly. */ - - notif = mac802154_notif_alloc(priv); - if (notif == NULL) + + ret = mac802154_takesem(&priv->exclsem, allow_interrupt); + if (ret < 0) { - wlerr("ERROR: Failed to allocate ieee802154_notif_s"); - - /* Free the tx descriptor */ - - sq_addlast((FAR sq_entry_t *)desc, &priv->txdesc_queue); - goto errout; + mac802154_givesem(&priv->txdesc_sem); + return -EINTR; } - desc->conf = (FAR struct ieee802154_data_conf_s *)notif; - desc->conf->handle = trans->handle; - desc->frametype = trans->frametype; + /* We can now safely unlink the next free structure from the free list */ - *frame = trans->frame; - *txdesc = desc; - - /* Now that we've passed off the data, notify the waiting thread. - * NOTE: The transaction was allocated on the waiting thread's stack so - * it will be automatically deallocated when that thread awakens and - * returns. */ - - sem_post(&trans->sem); - return (trans->frame->io_len); + *txdesc = (FAR struct ieee802154_txdesc_s *)sq_remfirst(&priv->txdesc_queue); } -errout: - /* Need to set flag to tell MAC to retry notifying radio layer about transmit - * since we couldn't allocate the required data structures at this time. + /* We have now successfully allocated the tx descriptor. Now we need to allocate + * the notification for the data confirmation that gets passed along with the + * tx descriptor. These are allocated together, but not freed together. */ - priv->csma_tryagain = true; - mac802154_givesem(&priv->exclsem); - return 0; + ret = mac802154_notif_alloc(priv, ¬if, allow_interrupt); + if (ret < 0) + { + /* The mac802154_notif_alloc function follows the same rules as this + * function. If it returns -EINTR, the MAC layer is already released + */ + + /* We need to free the txdesc */ + + mac802154_txdesc_free(priv, *txdesc); + return -EINTR; + } + + (*txdesc)->conf = ¬if->u.dataconf; + + return OK; } /**************************************************************************** - * Name: mac802154_poll_gts + * Name: mac802154_setupindirect + * + * Description: + * Internal function used by various parts of the MAC layer. This function + * places the provided tx descriptor in the indirect list and manages the + * scheduling for purging the transaction if it does not get extracted in + * time. + * + * Assumptions: + * Called with the MAC locked + * + ****************************************************************************/ + +void mac802154_setupindirect(FAR struct ieee802154_privmac_s *priv, + FAR struct ieee802154_txdesc_s *txdesc) +{ + uint32_t ticks; + uint32_t symbols; + + /* Link the tx descriptor into the list */ + + sq_addlast((FAR sq_entry_t *)txdesc, &priv->indirect_queue); + + /* Update the timestamp for purging the transaction */ + + /* The maximum time (in unit periods) that a transaction is stored by a + * coordinator and indicated in its beacon. The unit period is governed by + * macBeaconOrder, BO, as follows: For 0 ≤ BO ≤ 14, the unit period will be + * aBaseSuperframeDuration × 2 BO . For BO = 15, the unit period will be + * aBaseSuperframeDuration. [1] pg. 129 + */ + + if (priv->beaconorder < 15) + { + symbols = priv->trans_persisttime * + (IEEE802154_BASE_SUPERFRAME_DURATION * (1 << priv->beaconorder)); + } + else + { + symbols = priv->trans_persisttime * IEEE802154_BASE_SUPERFRAME_DURATION; + } + + ticks = mac802154_symtoticks(priv, symbols); + + txdesc->purge_time = clock_systimer() + ticks; + + /* Check to see if the purge indirect timer is scheduled. If it is, when the + * timer fires, it will schedule the next purge timer event. Inherently, the + * queue will be in order of which transaction needs to be purged next. + * + * If the purge indirect timer has not been scheduled, schedule it for when + * this transaction should expire. + */ + + if (work_available(&priv->purge_work)) + { + //work_queue(MAC802154_WORK, &priv->purge_work, mac802154_purge_worker, + // (FAR void *)priv, ticks); + } +} + +/**************************************************************************** + * Name: mac802154_purge_worker + * + * Description: + * Worker function scheduled in order to purge expired indirect transactions. + * The first element in the list should always be removed. The list is searched + * and transactions are removed until a transaction has not yet expired. Then + * if there are any remaining transactions, the work function is rescheduled + * for the next expiring transaction. + * + ****************************************************************************/ + +static void mac802154_purge_worker(FAR void *arg) +{ + FAR struct ieee802154_privmac_s *priv = + (FAR struct ieee802154_privmac_s *)arg; + FAR struct ieee802154_txdesc_s *txdesc; + + /* Get exclusive access to the driver structure. We don't care about any + * signals so don't allow interruptions + */ + + mac802154_takesem(&priv->exclsem, false); + + while (1) + { + /* Pop transactions off indirect queue until the transaction timeout has not + * passed. + */ + + txdesc = (FAR struct ieee802154_txdesc_s *)sq_peek(&priv->indirect_queue); + + if (txdesc == NULL) + { + break; + } + + /* Should probably check a little ahead and remove the transaction if it is within + * a certain number of clock ticks away. There is no since in scheduling the + * timer to expire in only a few ticks. + */ + + if (clock_systimer() >= txdesc->purge_time) + { + /* Unlink the transaction */ + + sq_remfirst(&priv->indirect_queue); + + /* Free the IOB, the notification, and the tx descriptor */ + + iob_free(txdesc->frame); + ((FAR struct mac802154_notif_s *)txdesc->conf)->flink = priv->notif_free; + priv->notif_free = ((FAR struct mac802154_notif_s *)txdesc->conf); + mac802154_txdesc_free(priv, txdesc); + + wlinfo("Indirect TX purged"); + } + else + { + /* Reschedule the transaction for the next timeout */ + + work_queue(MAC802154_WORK, &priv->purge_work, mac802154_purge_worker, + (FAR void *)priv, txdesc->purge_time - clock_systimer()); + break; + } + } +} + +/**************************************************************************** + * Name: mac802154_poll * * Description: * Called from the radio driver through the callback struct. This function is - * called when the radio has room for another GTS transaction. If the MAC - * layer has a GTS transaction, it copies it into the supplied buffer and + * called when the radio has room for another transaction. If the MAC + * layer has a transaction, it copies it into the supplied buffer and * returns the length. A descriptor is also populated with the transaction. * ****************************************************************************/ -static int mac802154_poll_gts(FAR const struct ieee802154_radiocb_s *radiocb, - FAR struct ieee802154_txdesc_s **tx_desc, - FAR struct iob_s **frame) +static int mac802154_poll(FAR const struct ieee802154_radiocb_s *radiocb, + bool gts, FAR struct ieee802154_txdesc_s **txdesc) { FAR struct mac802154_radiocb_s *cb = (FAR struct mac802154_radiocb_s *)radiocb; FAR struct ieee802154_privmac_s *priv; - FAR struct mac802154_txtrans_s *trans; - FAR struct ieee802154_txdesc_s *desc; - int ret = 0; DEBUGASSERT(cb != NULL && cb->priv != NULL); priv = cb->priv; - /* Get exclusive access to the driver structure. We don't care about any - * signals so if we see one, just go back to trying to get access again. - */ + /* Get exclusive access to the driver structure. Ignore any EINTR signals */ - while (mac802154_takesem(&priv->exclsem) != 0); + mac802154_takesem(&priv->exclsem, false); -#warning Missing logic. + if (gts) + { + /* Check to see if there are any GTS transactions waiting */ + + *txdesc = (FAR struct ieee802154_txdesc_s *)sq_remfirst(&priv->gts_queue); + } + else + { + /* Check to see if there are any CSMA transactions waiting */ + + *txdesc = (FAR struct ieee802154_txdesc_s *)sq_remfirst(&priv->csma_queue); + } mac802154_givesem(&priv->exclsem); - return 0; + if (*txdesc != NULL) + { + return (*txdesc)->frame->io_len; + } -errout: - /* Need to set flag to tell MAC to retry notifying radio layer about transmit - * since we couldn't allocate the required data structures at this time. - */ - - priv->gts_tryagain = true; - mac802154_givesem(&priv->exclsem); return 0; } @@ -723,7 +424,7 @@ errout: ****************************************************************************/ static void mac802154_txdone(FAR const struct ieee802154_radiocb_s *radiocb, - FAR const struct ieee802154_txdesc_s *txdesc) + FAR struct ieee802154_txdesc_s *txdesc) { FAR struct mac802154_radiocb_s *cb = (FAR struct mac802154_radiocb_s *)radiocb; @@ -733,10 +434,10 @@ static void mac802154_txdone(FAR const struct ieee802154_radiocb_s *radiocb, priv = cb->priv; /* Get exclusive access to the driver structure. We don't care about any - * signals so if we see one, just go back to trying to get access again. + * signals so don't allow interruptions */ - while (mac802154_takesem(&priv->exclsem) != 0); + mac802154_takesem(&priv->exclsem, false); sq_addlast((FAR sq_entry_t *)txdesc, &priv->txdone_queue); @@ -766,16 +467,14 @@ static void mac802154_txdone_worker(FAR void *arg) FAR struct ieee802154_privmac_s *priv = (FAR struct ieee802154_privmac_s *)arg; FAR struct ieee802154_txdesc_s *txdesc; - FAR struct ieee802154_data_conf_s *conf; FAR struct ieee802154_notif_s *notif; - enum ieee802154_frametype_e frametype; - int count; + FAR struct mac802154_notif_s *privnotif; /* Get exclusive access to the driver structure. We don't care about any - * signals so if we see one, just go back to trying to get access again. + * signals so don't allow interruptions */ - while (mac802154_takesem(&priv->exclsem) != 0); + mac802154_takesem(&priv->exclsem, false); while (1) { @@ -786,112 +485,104 @@ static void mac802154_txdone_worker(FAR void *arg) break; } - count++; - - /* Once we get the frametype and data confirmation struct, we can free - * the tx descriptor. + /* Cast the data_conf to a notification. We get both the private and public + * notification structure to make it easier to use. */ - conf = txdesc->conf; - frametype = txdesc->frametype; - sq_addlast((FAR sq_entry_t *)txdesc, &priv->txdesc_queue); + privnotif = (FAR struct mac802154_notif_s *)txdesc->conf; + notif = &privnotif->pub; - /* Cast the data_conf to a notification */ - - notif = (FAR struct ieee802154_notif_s *)conf; - - switch(frametype) + switch(txdesc->frametype) { case IEEE802154_FRAME_DATA: { notif->notiftype = IEEE802154_NOTIFY_CONF_DATA; - /* Release the MAC then call the callback */ - + /* Release the MAC, call the callback, get exclusive access again */ mac802154_givesem(&priv->exclsem); priv->cb->notify(priv->cb, notif); + mac802154_takesem(&priv->exclsem, false); } break; - case IEEE802154_FRAME_COMMAND: { - mac802154_cmd_txdone(priv, txdesc); + switch (priv->curr_cmd) + { + case IEEE802154_CMD_ASSOC_REQ: + mac802154_txdone_assocreq(priv, txdesc); + break; + case IEEE802154_CMD_ASSOC_RESP: + break; + case IEEE802154_CMD_DISASSOC_NOT: + break; + case IEEE802154_CMD_DATA_REQ: + /* Data requests can be sent for 3 different reasons. + * + * 1. On a beacon-enabled PAN, this command shall be sent + * by a device when macAutoRequest is equal to TRUE and + * a beacon frame indicating that data are pending for + * that device is received from its coordinator. + * 2. when instructed to do so by the next higher layer on + * reception of the MLME-POLL.request primitive. + * 3. a device may send this command to the coordinator + * macResponseWaitTime after the acknowledgment to an + * association request command. + */ - /* We can deallocate the data conf notification as it is no longer - * needed. We don't use the public function here since we already - * have the MAC locked. Additionally, we are already handling the - * tx_tryagain here, so we wouldn't want to handle it twice. - */ + switch (priv->curr_op) + { + case MAC802154_OP_ASSOC: + mac802154_txdone_datareq_assoc(priv, txdesc); + break; + case MAC802154_OP_POLL: + mac802154_txdone_datareq_poll(priv, txdesc); + break; + default: + break; + } + break; + case IEEE802154_CMD_PANID_CONF_NOT: + break; + case IEEE802154_CMD_ORPHAN_NOT: + break; + case IEEE802154_CMD_BEACON_REQ: + break; + case IEEE802154_CMD_COORD_REALIGN: + break; + case IEEE802154_CMD_GTS_REQ: + break; + default: + /* We can deallocate the data conf notification as it is no + * longer needed. We can't use the public function here + * since we already have the MAC locked. + */ - notif->flink = priv->notif_free; - priv->notif_free = notif; - mac802154_givesem(&priv->exclsem); + privnotif->flink = priv->notif_free; + priv->notif_free = privnotif; + break; + } } break; - default: { - mac802154_givesem(&priv->exclsem); + /* We can deallocate the data conf notification as it is no longer + * needed. We can't use the public function here since we already + * have the MAC locked. + */ + + privnotif->flink = priv->notif_free; + priv->notif_free = privnotif; } break; - } + + /* Free the IOB and the tx descriptor */ + + iob_free(txdesc->frame); + mac802154_txdesc_free(priv, txdesc); } - /* If we've freed a tx descriptor or notification structure and a previous - * attempt at passing data to the radio layer failed due to insufficient - * available structures, try again now that we've freed some resources */ - - if (count > 0 && priv->csma_tryagain) - { - priv->csma_tryagain = false; - priv->radio->ops->txnotify_csma(priv->radio); - } - - if (count > 0 && priv->gts_tryagain) - { - priv->gts_tryagain = false; - priv->radio->ops->txnotify_gts(priv->radio); - } -} - -/**************************************************************************** - * Name: mac802154_cmd_txdone - * - * Description: - * Called from mac802154_txdone_worker, this is a helper function for - * handling command frames that have either successfully sent or failed. - * - ****************************************************************************/ - -static void mac802154_cmd_txdone(FAR struct ieee802154_privmac_s *priv, - FAR struct ieee802154_txdesc_s *txdesc) -{ - - /* Check to see what type of command it was. All information about the command - * will still be valid because it is protected by a semaphore. - */ - - switch (priv->cmd.type) - { - case IEEE802154_CMD_ASSOC_REQ: - if(txdesc->conf->status != IEEE802154_STATUS_SUCCESS) - { - /* if the association request command cannot be sent due to a - * channel access failure, the MAC sublayer shall notify the next - * higher layer. [1] pg. 33 - */ - - - } - else - { - priv->cmd.txdone = true; - } - break; - default: - break; - } + mac802154_givesem(&priv->exclsem); } /**************************************************************************** @@ -922,12 +613,14 @@ static void mac802154_rxframe(FAR const struct ieee802154_radiocb_s *radiocb, * signals so if we see one, just go back to trying to get access again. */ - while (mac802154_takesem(&priv->exclsem) != 0); + mac802154_takesem(&priv->exclsem, false); /* Push the iob onto the tail of the frame list for processing */ sq_addlast((FAR sq_entry_t *)ind, &priv->dataind_queue); + wlinfo("frame received\n"); + mac802154_givesem(&priv->exclsem); /* Schedule work with the work queue to process the completion further */ @@ -966,27 +659,26 @@ static void mac802154_rxframe_worker(FAR void *arg) * signals so if we see one, just go back to trying to get access again. */ - while (mac802154_takesem(&priv->exclsem) != 0); + mac802154_takesem(&priv->exclsem, false); - /* Push the iob onto the tail of the frame list for processing */ + /* Pop the iob from the head of the frame list for processing */ ind = (FAR struct ieee802154_data_ind_s *)sq_remfirst(&priv->dataind_queue); - if (ind == NULL) - { - mac802154_givesem(&priv->exclsem); - break; - } - /* Once we pop off the indication, we don't need to keep the mac locked */ mac802154_givesem(&priv->exclsem); + if (ind == NULL) + { + return; + } + /* Get a local copy of the frame to make it easier to access */ frame = ind->frame; - /* Set a local pointer to the frame control then move the offset past + /* Set a local pointer to the frame control then move the offset past * the frame control field */ @@ -1014,19 +706,19 @@ static void mac802154_rxframe_worker(FAR void *arg) { /* Get the destination PAN ID */ - ind->dest.panid = frame->io_data[frame->io_offset]; + memcpy(&ind->dest.panid, &frame->io_data[frame->io_offset], 2); frame->io_offset += 2; if (ind->dest.mode == IEEE802154_ADDRMODE_SHORT) { - ind->dest.saddr = frame->io_data[frame->io_offset]; + memcpy(&ind->dest.saddr, &frame->io_data[frame->io_offset], 2); frame->io_offset += 2; } else if (ind->dest.mode == IEEE802154_ADDRMODE_EXTENDED) { - memcpy(&ind->dest.eaddr[0], &frame->io_data[frame->io_offset], + memcpy(&ind->dest.eaddr[0], &frame->io_data[frame->io_offset], IEEE802154_EADDR_LEN); - frame->io_offset += 8; + frame->io_offset += IEEE802154_EADDR_LEN; } } @@ -1036,29 +728,26 @@ static void mac802154_rxframe_worker(FAR void *arg) * is set, get the PAN ID from the header. */ - if (!panid_comp) + if (panid_comp) { - ind->src.panid = frame->io_data[frame->io_offset]; - frame->io_offset += 2; - } - - /* If the source address is included, and the PAN ID compression field - * is set, the source PAN ID is the same as the destination PAN ID - */ + /* The source PAN ID is equal to the destination PAN ID */ + ind->src.panid = ind->dest.panid; + } else { - ind->src.panid = ind->dest.panid; + memcpy(&ind->src.panid, &frame->io_data[frame->io_offset], 2); + frame->io_offset += 2; } if (ind->src.mode == IEEE802154_ADDRMODE_SHORT) { - ind->src.saddr = frame->io_data[frame->io_offset]; + memcpy(&ind->src.saddr, &frame->io_data[frame->io_offset], 2); frame->io_offset += 2; } else if (ind->src.mode == IEEE802154_ADDRMODE_EXTENDED) { - memcpy(&ind->src.eaddr[0], &frame->io_data[frame->io_offset], + memcpy(&ind->src.eaddr[0], &frame->io_data[frame->io_offset], IEEE802154_EADDR_LEN); frame->io_offset += 8; } @@ -1066,46 +755,568 @@ static void mac802154_rxframe_worker(FAR void *arg) ftype = (*frame_ctrl & IEEE802154_FRAMECTRL_FTYPE) >> IEEE802154_FRAMECTRL_SHIFT_FTYPE; - - if (ftype == IEEE802154_FRAME_DATA) - { - /* If there is a registered MCPS callback receiver registered, send - * the frame, otherwise, throw it out. - */ - if (priv->cb->rxframe != NULL) + switch (ftype) + { + case IEEE802154_FRAME_DATA: { - priv->cb->rxframe(priv->cb, ind); + mac802154_rx_dataframe(priv, ind); } - else + break; + + case IEEE802154_FRAME_COMMAND: { + /* Get the command type. The command type is always the first + * field after the MHR. Consu;me the byte by increasing offset so that + * subsequent functions can start from the byte after the command ID. + */ + + uint8_t cmdtype = frame->io_data[frame->io_offset++]; + + switch (cmdtype) + { + case IEEE802154_CMD_ASSOC_REQ: + mac802154_rx_assocreq(priv, ind); + break; + case IEEE802154_CMD_ASSOC_RESP: + mac802154_rx_assocresp(priv, ind); + break; + case IEEE802154_CMD_DISASSOC_NOT: + break; + case IEEE802154_CMD_DATA_REQ: + mac802154_rx_datareq(priv, ind); + break; + case IEEE802154_CMD_PANID_CONF_NOT: + break; + case IEEE802154_CMD_ORPHAN_NOT: + break; + case IEEE802154_CMD_BEACON_REQ: + break; + case IEEE802154_CMD_COORD_REALIGN: + break; + case IEEE802154_CMD_GTS_REQ: + break; + } + /* Free the data indication struct from the pool */ ieee802154_ind_free(ind); } - } - else if (ftype == IEEE802154_FRAME_COMMAND) - { + break; - } - else if (ftype == IEEE802154_FRAME_BEACON) - { + case IEEE802154_FRAME_BEACON: + { + /* TODO: Add logic here to handle extracting association response from + * coordinator if beacon tracking was enabled during the Association + * operation. + * + * txdesc = mac802154_assoc_getresp(priv); + * sq_addlast((FAR sq_entry_t *)txdesc, &priv->csma_queue); + */ + } + break; + case IEEE802154_FRAME_ACK: + { + /* The radio layer is responsible for handling all ACKs and retries. + * If for some reason an ACK gets here, just throw it out. + */ + + wlinfo("ACK received\n"); + ieee802154_ind_free(ind); + } + break; + } + } +} + +/**************************************************************************** + * Name: mac802154_rx_dataframe + * + * Description: + * Function called from the generic RX Frame worker to parse and handle the + * reception of a data frame. + * + ****************************************************************************/ + +static void mac802154_rx_dataframe(FAR struct ieee802154_privmac_s *priv, + FAR struct ieee802154_data_ind_s *ind) +{ + FAR struct ieee802154_notif_s *notif; + + /* Get exclusive access to the MAC */ + + mac802154_takesem(&priv->exclsem, false); + + /* If we are currently performing a POLL operation and we've + * received a data response, use the addressing information + * to determine if it is extracted data. If the addressing info + * matches, notify the next highest layer using POLL.confirm + * primitive. If the addressing information does not match, + * handle the transaction like any other data transaction. + * + * Note: We can't receive frames without addressing information + * unless we are the PAN coordinator. And in that situation, we + * wouldn't be performing a POLL operation. Meaning: + * + * If the current operation is POLL, we aren't the PAN coordinator + * so the incoming frame CAN'T + * + * FIXME: Fix documentation + */ + + if (priv->curr_op == MAC802154_OP_POLL || priv->curr_op == MAC802154_OP_ASSOC) + { + /* If we are in promiscuous mode, we need to check if the + * frame is even for us first. If the address is not ours, + * then handle the frame like a normal transaction. + */ + + if (priv->promisc) + { + if (ind->dest.panid != priv->addr.panid) + { + goto notify_with_lock; + } + + if (ind->dest.mode == IEEE802154_ADDRMODE_SHORT && + ind->dest.saddr != priv->addr.saddr) + { + goto notify_with_lock; + } + else if (ind->dest.mode == IEEE802154_ADDRMODE_EXTENDED && + (memcmp(&ind->dest.eaddr[0], &priv->addr.eaddr[0], + IEEE802154_EADDR_LEN) != 0)) + { + goto notify_with_lock; + } + else + { + goto notify_with_lock; + } + } + + /* If this was our extracted data, the source addressing field can only + * be NONE if we are trying to extract data from the PAN coordinator. + * A PAN coordinator shouldn't be sending us a frame if it wasn't + * our extracted data. Therefore just assume if the address mode is set + * to NONE, we process it as our extracted frame + */ + + if (ind->src.mode != priv->cmd_desc->destaddr.mode) + { + goto notify_with_lock; + } + + if (ind->src.mode == IEEE802154_ADDRMODE_SHORT && + ind->src.saddr != priv->cmd_desc->destaddr.saddr) + { + goto notify_with_lock; + } + else if (ind->src.mode == IEEE802154_ADDRMODE_EXTENDED && + (memcmp(&ind->src.eaddr[0], &priv->cmd_desc->destaddr.eaddr[0], + IEEE802154_EADDR_LEN) != 0)) + { + goto notify_with_lock; + } + + /* If we've gotten this far, the frame is our extracted data. Cancel the + * timeout */ + + mac802154_timercancel(priv); + + /* If a frame is received from the coordinator with a zero length payload + * or if the frame is a MAC command frame, the MLME will issue the + * MLME-POLL.confirm primitive with a status of NO_DATA. [1] pg. 111 + */ + + mac802154_notif_alloc(priv, ¬if, false); + + if (priv->curr_op == MAC802154_OP_POLL) + { + notif->notiftype = IEEE802154_NOTIFY_CONF_POLL; + + if (ind->frame->io_offset == ind->frame->io_len) + { + ieee802154_ind_free(ind); + notif->u.pollconf.status = IEEE802154_STATUS_NO_DATA; + } + else + { + notif->u.pollconf.status = IEEE802154_STATUS_SUCCESS; + } + } + else if (priv->curr_op == MAC802154_OP_ASSOC) + { + /* If we ever receive a data frame back as a response to the + * association request, we assume it means there wasn't any data. + */ + + notif->notiftype = IEEE802154_NOTIFY_CONF_ASSOC; + notif->u.assocconf.status = IEEE802154_STATUS_NO_DATA; + } + + /* We are no longer performing the association operation */ + + priv->curr_op = MAC802154_OP_NONE; + priv->cmd_desc = NULL; + mac802154_givesem(&priv->op_sem); + + /* Release the MAC */ + + mac802154_givesem(&priv->exclsem); + + priv->cb->notify(priv->cb, notif); + + /* If there was data, pass it along */ + + if (ind->frame->io_len > ind->frame->io_offset) + { + goto notify_without_lock; + } + } + else + { +notify_with_lock: + + mac802154_givesem(&priv->exclsem); + +notify_without_lock: + + /* If there is a registered MCPS callback receiver registered, + * send the frame, otherwise, throw it out. + */ + + if (priv->cb->rxframe != NULL) + { + priv->cb->rxframe(priv->cb, ind); } else { - /* The radio layer is responsible for handling all ACKs and retries. If for - * some reason an ACK gets here, just throw it out. - */ + /* Free the data indication struct from the pool */ + + ieee802154_ind_free(ind); } } } +/**************************************************************************** + * Name: mac802154_rx_datareq + * + * Description: + * Function called from the generic RX Frame worker to parse and handle the + * reception of an Data Request MAC command frame. + * + ****************************************************************************/ + +static void mac802154_rx_datareq(FAR struct ieee802154_privmac_s *priv, + FAR struct ieee802154_data_ind_s *ind) +{ + FAR struct ieee802154_txdesc_s *txdesc; + FAR struct iob_s *iob; + uint16_t *frame_ctrl; + + /* Get exclusive access to the MAC */ + + mac802154_takesem(&priv->exclsem, false); + + /* Search the list of indirect transactions to see if there are any waiting + * for the requesting device. + */ + + /* TODO: I believe there is an issue here. If there is for some reason a + * outgoing data frame to a device who is currently requesting association, + * we will send the data frame as a response to an association request. We + * need to check for this condition. + */ + + txdesc = (FAR struct ieee802154_txdesc_s *)sq_peek(&priv->indirect_queue); + + if (txdesc == NULL) + { + goto no_data; + } + + do + { + if (txdesc->destaddr.mode == ind->src.mode) + { + if (txdesc->destaddr.mode == IEEE802154_ADDRMODE_SHORT) + { + if (txdesc->destaddr.saddr == ind->src.saddr) + { + /* Remove the transaction from the queue */ + + sq_rem((FAR sq_entry_t *)txdesc, &priv->indirect_queue); + + /* The addresses match, send the transaction immediately */ + + priv->radio->txdelayed(priv->radio, txdesc, 0); + break; + } + } + else if (txdesc->destaddr.mode == IEEE802154_ADDRMODE_EXTENDED) + { + if (memcmp(&txdesc->destaddr.eaddr[0], &ind->src.eaddr[0], + sizeof(IEEE802154_EADDR_LEN)) == 0) + { + /* Remove the transaction from the queue */ + + sq_rem((FAR sq_entry_t *)txdesc, &priv->indirect_queue); + + /* The addresses match, send the transaction immediately */ + + priv->radio->txdelayed(priv->radio, txdesc, 0); + break; + } + } + else + { + DEBUGASSERT(false); + } + } + + txdesc = (FAR struct ieee802154_txdesc_s *)sq_next((FAR sq_entry_t *)txdesc); + + if (txdesc == NULL) + { + goto no_data; + } + } + while (1); + + mac802154_givesem(&priv->exclsem); + return; + +no_data: + + /* If there is no data frame pending for the requesting device, the coordinator + * shall send a data frame without requesting acknowledgment to the device + * containing a zero length payload, indicating that no data are present, using + * one of the mechanisms described in this subclause. [1] pg. 43 + */ + + /* Allocate an IOB to put the frame in */ + + iob = iob_alloc(false); + DEBUGASSERT(iob != NULL); + + iob->io_flink = NULL; + iob->io_len = 0; + iob->io_offset = 0; + iob->io_pktlen = 0; + + iob->io_len += 2; + + /* Cast the first two bytes of the IOB to a uint16_t frame control field */ + + frame_ctrl = (FAR uint16_t *)&iob->io_data[0]; + + /* Ensure we start with a clear frame control field */ + + *frame_ctrl = 0; + + /* Set the frame type to Data */ + + *frame_ctrl |= IEEE802154_FRAME_DATA << IEEE802154_FRAMECTRL_SHIFT_FTYPE; + + /* Each time a data or a MAC command frame is generated, the MAC sublayer + * shall copy the value of macDSN into the Sequence Number field of the MHR + * of the outgoing frame and then increment it by one. [1] pg. 40. + */ + + iob->io_data[iob->io_len++] = priv->dsn++; + + /* Use the source address information from the received data request to + * respond. + */ + + *((uint16_t *)&iob->io_data[iob->io_len]) = ind->src.panid; + iob->io_len += 2; + + if (ind->src.mode == IEEE802154_ADDRMODE_SHORT) + { + memcpy(&iob->io_data[iob->io_len], &ind->src.saddr, 2); + iob->io_len += 2; + } + else if (ind->src.mode == IEEE802154_ADDRMODE_EXTENDED) + { + memcpy(&iob->io_data[iob->io_len], &ind->src.eaddr, IEEE802154_EADDR_LEN); + iob->io_len += IEEE802154_EADDR_LEN; + } + else + { + DEBUGASSERT(false); + } + + /* Set the destination addr mode inside the frame control field */ + + *frame_ctrl |= (ind->src.mode << IEEE802154_FRAMECTRL_SHIFT_DADDR); + + /* Check if the source PAN ID of the incoming request is the same as ours. */ + + if (ind->src.panid == priv->addr.panid) + { + *frame_ctrl |= IEEE802154_FRAMECTRL_PANIDCOMP; + } + else + { + /* Copy in our PAN ID */ + + memcpy(&iob->io_data[iob->io_len], &priv->addr.panid, 2); + iob->io_len += 2; + } + + /* Copy in our address using the mode that the device used to address us */ + + if (ind->dest.mode == IEEE802154_ADDRMODE_SHORT) + { + memcpy(&iob->io_data[iob->io_len], &priv->addr.saddr, 2); + iob->io_len += 2; + + *frame_ctrl |= (IEEE802154_ADDRMODE_SHORT << IEEE802154_FRAMECTRL_SHIFT_SADDR); + } + else + { + memcpy(&iob->io_data[iob->io_len], &ind->dest.eaddr, IEEE802154_EADDR_LEN); + iob->io_len += IEEE802154_EADDR_LEN; + *frame_ctrl |= (IEEE802154_ADDRMODE_EXTENDED << IEEE802154_FRAMECTRL_SHIFT_SADDR); + } + + /* Allocate the txdesc, waiting if necessary, allow interruptions */ + + mac802154_txdesc_alloc(priv, &txdesc, false); + + txdesc->frame = iob; + txdesc->frametype = IEEE802154_FRAME_DATA; + + mac802154_givesem(&priv->exclsem); + + priv->radio->txdelayed(priv->radio, txdesc, 0); +} + +/**************************************************************************** + * Name: mac802154_symtoticks + * + * Description: + * Helper function for converting symbols to system clock ticks + * + * Assumptions: + * priv MAC struct is locked when calling. + * + ****************************************************************************/ + +static uint32_t mac802154_symtoticks(FAR struct ieee802154_privmac_s *priv, + uint32_t symbols) +{ + union ieee802154_attr_u attrval; + uint32_t ret; + + /* First, get the symbol duration from the radio layer. Symbol duration is + * returned in picoseconds to ensure precision is kept when multiplying to + * get overall times. + */ + + priv->radio->get_attr(priv->radio, IEEE802154_ATTR_PHY_SYMBOL_DURATION, + &attrval); + + /* After this step, ret represents microseconds */ + + ret = ((uint64_t)attrval.phy.symdur_picosec * symbols) / (1000 * 1000); + + /* This method should only be used for things that can be late. For instance, + * it's always okay to wait a little longer before disabling your receiver. + * Therefore, we force the tick count to round up. + */ + + if (ret % USEC_PER_TICK == 0) + { + ret = ret/USEC_PER_TICK; + } + else + { + ret = ret/USEC_PER_TICK; + ret++; + } + + return ret; +} + +/**************************************************************************** + * Name: mac802154_timerstart + * + * Description: + * Helper function wrapping the watchdog timer interface. Helps isolate + * different operations from having to worry about work queues and watchdog + * timers. + * + * Assumptions: + * priv MAC struct is locked when calling. + * + ****************************************************************************/ + +int mac802154_timerstart(FAR struct ieee802154_privmac_s *priv, + uint32_t numsymbols, mac802154_worker_t worker) +{ + /* TODO: Add check to make sure timer is not already being used. I'd like to + * design this so that it absolutely never happens */ + + /* Convert the number of symbols to the number of CPU ticks */ + + uint32_t ticks = mac802154_symtoticks(priv, numsymbols); + + /* Save the function pointer to call if the timeout expires */ + + priv->timeout_worker = worker; + + /* Start the watchdog */ + + wd_start(priv->timeout, (int32_t)ticks, mac802154_timeout_expiry, 1, (uint32_t)priv); + + return OK; +} + +/**************************************************************************** + * Function: mac802154_timeout_expiry + * + * Description: + * The watchdog timed out. Called from the timer interrupt handler. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void mac802154_timeout_expiry(int argc, uint32_t arg, ...) +{ + FAR struct ieee802154_privmac_s *priv = (FAR struct ieee802154_privmac_s *)arg; + + /* There should never be a case where the timeout is used twice at the same + * time. */ + + DEBUGASSERT(work_available(&priv->timeout_work)); + + /* Check to make sure the function pointer is still valid */ + + DEBUGASSERT(priv->timeout_worker != NULL); + + work_queue(MAC802154_WORK, &priv->timeout_work, (worker_t)priv->timeout_worker, + priv, 0); +} + /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** + * Name: mac802154_create * * Description: @@ -1133,6 +1344,8 @@ MACHANDLE mac802154_create(FAR struct ieee802154_radio_s *radiodev) { FAR struct ieee802154_privmac_s *mac; FAR struct ieee802154_radiocb_s *radiocb; + uint8_t eaddr[IEEE802154_EADDR_LEN]; + int i; /* Allocate object */ @@ -1148,1147 +1361,48 @@ MACHANDLE mac802154_create(FAR struct ieee802154_radio_s *radiodev) sem_init(&mac->exclsem, 0, 1); - /* Allow exlusive access to the dedicated command transaction */ + /* Allow exclusive access to the dedicated command transaction */ - sem_init(&mac->cmd.sem, 0, 1); + sem_init(&mac->op_sem, 0, 1); - /* Setup the signaling semaphore for the dedicated command transaction */ + /* Setup watchdog for extraction timeout */ - sem_init(&mac->cmd.trans.sem, 0, 0); - sem_setprotocol(&mac->cmd.trans.sem, SEM_PRIO_NONE); + mac->timeout = wd_create(); /* Initialize fields */ mac->radio = radiodev; - mac802154_defaultmib(mac); - mac802154_applymib(mac); + mac802154_req_reset((MACHANDLE)mac, true); /* Initialize the Radio callbacks */ mac->radiocb.priv = mac; - radiocb = &mac->radiocb.cb; - radiocb->poll_csma = mac802154_poll_csma; - radiocb->poll_gts = mac802154_poll_gts; - radiocb->txdone = mac802154_txdone; - radiocb->rxframe = mac802154_rxframe; + radiocb = &mac->radiocb.cb; + radiocb->poll = mac802154_poll; + radiocb->txdone = mac802154_txdone; + radiocb->rxframe = mac802154_rxframe; /* Bind our callback structure */ - radiodev->ops->bind(radiodev, &mac->radiocb.cb); + radiodev->bind(radiodev, &mac->radiocb.cb); /* Initialize our various data pools */ ieee802154_indpool_initialize(); mac802154_resetqueues(mac); - + + /* Set the default extended address */ + + for (i = 0; i < IEEE802154_EADDR_LEN; i++) + { + eaddr[i] = (CONFIG_IEEE802154_DEFAULT_EADDR >> (8 * i)) & 0xFF; + } + + memcpy(&mac->addr.eaddr, &eaddr[0], IEEE802154_EADDR_LEN); + mac->radio->set_attr(mac->radio, IEEE802154_ATTR_MAC_EXTENDED_ADDR, + (union ieee802154_attr_u *)&eaddr[0]); + return (MACHANDLE)mac; } - -/**************************************************************************** - * 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 mac802154_maccb_s *cb) -{ - FAR struct ieee802154_privmac_s *priv = - (FAR struct ieee802154_privmac_s *)mac; - - priv->cb = cb; - return OK; -} - -/**************************************************************************** - * 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) -{ - FAR struct ieee802154_privmac_s *priv = - (FAR struct ieee802154_privmac_s *)mac; - int ret = -EINVAL; - - FAR union ieee802154_macarg_u *macarg = - (FAR union ieee802154_macarg_u *)((uintptr_t)arg); - - DEBUGASSERT(priv != NULL); - - /* Check for IOCTLs aimed at the IEEE802.15.4 MAC layer */ - - if (_MAC802154IOCVALID(cmd)) - { - /* Handle the MAC IOCTL command */ - - switch (cmd) - { - case MAC802154IOC_MLME_ASSOC_REQUEST: - { - ret = mac802154_req_associate(mac, &macarg->assocreq); - } - break; - case MAC802154IOC_MLME_ASSOC_RESPONSE: - { - ret = mac802154_resp_associate(mac, &macarg->assocresp); - } - break; - case MAC802154IOC_MLME_DISASSOC_REQUEST: - { - ret = mac802154_req_disassociate(mac, &macarg->disassocreq); - } - break; - case MAC802154IOC_MLME_GET_REQUEST: - { - ret = mac802154_req_get(mac, macarg->getreq.pib_attr, - &macarg->getreq.attrval); - } - break; - case MAC802154IOC_MLME_GTS_REQUEST: - { - ret = mac802154_req_gts(mac, &macarg->gtsreq); - } - break; - case MAC802154IOC_MLME_ORPHAN_RESPONSE: - { - ret = mac802154_resp_orphan(mac, &macarg->orphanresp); - } - break; - case MAC802154IOC_MLME_RESET_REQUEST: - { - ret = mac802154_req_reset(mac, macarg->resetreq.rst_pibattr); - } - break; - case MAC802154IOC_MLME_RXENABLE_REQUEST: - { - ret = mac802154_req_rxenable(mac, &macarg->rxenabreq); - } - break; - case MAC802154IOC_MLME_SCAN_REQUEST: - { - ret = mac802154_req_scan(mac, &macarg->scanreq); - } - break; - case MAC802154IOC_MLME_SET_REQUEST: - { - ret = mac802154_req_set(mac, macarg->setreq.pib_attr, - &macarg->setreq.attrval); - } - break; - case MAC802154IOC_MLME_START_REQUEST: - { - ret = mac802154_req_start(mac, &macarg->startreq); - } - break; - case MAC802154IOC_MLME_SYNC_REQUEST: - { - ret = mac802154_req_sync(mac, &macarg->syncreq); - } - break; - case MAC802154IOC_MLME_POLL_REQUEST: - { - ret = mac802154_req_poll(mac, &macarg->pollreq); - } - break; - default: - wlerr("ERROR: Unrecognized cmd: %d\n", cmd); - ret = -ENOTTY; - break; - } - } - return ret; -} - -/**************************************************************************** - * 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) -{ - FAR struct ieee802154_privmac_s *priv = - (FAR struct ieee802154_privmac_s *)mac; - int ret = 3; /* Always frame control (2 bytes) and seq. num (1 byte) */ - - /* Check to make sure both the dest address and the source address are not set - * to NONE */ - - if (meta->dest_addr.mode == IEEE802154_ADDRMODE_NONE && - meta->src_addrmode == IEEE802154_ADDRMODE_NONE) - { - return -EINVAL; - } - - /* The source address can only be set to NONE if the device is the PAN coord */ - - if (meta->src_addrmode == IEEE802154_ADDRMODE_NONE && - priv->devmode != IEEE802154_DEVMODE_PANCOORD) - { - return -EINVAL; - } - - /* Add the destination address length */ - - ret += mac802154_addr_length[meta->dest_addr.mode]; - - /* Add the source address length */ - - ret += mac802154_addr_length[ meta->src_addrmode]; - - /* If both destination and source addressing information is present, the MAC - * sublayer shall compare the destination and source PAN identifiers. - * [1] pg. 41. - */ - - if (meta->src_addrmode != IEEE802154_ADDRMODE_NONE && - meta->dest_addr.mode != IEEE802154_ADDRMODE_NONE) - { - /* If the PAN identifiers are identical, the PAN ID Compression field - * shall be set to one, and the source PAN identifier shall be omitted - * from the transmitted frame. [1] pg. 41. - */ - - if (meta->dest_addr.panid == priv->addr.panid) - { - ret += 2; /* 2 bytes for destination PAN ID */ - return ret; - } - } - - /* If we are here, PAN ID compression is off, so include the dest and source - * PAN ID if the respective address is included - */ - - if (meta->src_addrmode != IEEE802154_ADDRMODE_NONE) - { - ret += 2; /* 2 bytes for source PAN ID */ - } - - if (meta->dest_addr.mode != IEEE802154_ADDRMODE_NONE) - { - ret += 2; /* 2 bytes for destination PAN ID */ - } - - return ret; -} - -/**************************************************************************** - * 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 mac802154_maccb_s->conf_data callback. - * - ****************************************************************************/ - -int mac802154_req_data(MACHANDLE mac, - FAR const struct ieee802154_frame_meta_s *meta, - FAR struct iob_s *frame) -{ - FAR struct ieee802154_privmac_s *priv = - (FAR struct ieee802154_privmac_s *)mac; - FAR struct mac802154_txtrans_s trans; - uint16_t *frame_ctrl; - uint8_t mhr_len = 3; /* Start assuming frame control and seq. num */ - int ret; - - /* Check the required frame size */ - - if (frame->io_len > IEEE802154_MAX_PHY_PACKET_SIZE) - { - return -E2BIG; - } - - /* Cast the first two bytes of the IOB to a uint16_t frame control field */ - - frame_ctrl = (FAR uint16_t *)&frame->io_data[0]; - - /* Ensure we start with a clear frame control field */ - - *frame_ctrl = 0; - - /* Set the frame type to Data */ - - *frame_ctrl |= IEEE802154_FRAME_DATA << IEEE802154_FRAMECTRL_SHIFT_FTYPE; - - /* If the msduLength is greater than aMaxMACSafePayloadSize, the MAC - * sublayer will set the Frame Version to one. [1] pg. 118. - */ - - if ((frame->io_len - frame->io_offset) > IEEE802154_MAX_SAFE_MAC_PAYLOAD_SIZE) - { - *frame_ctrl |= IEEE802154_FRAMECTRL_VERSION; - } - - /* If the TXOptions parameter specifies that an acknowledged transmission - * is required, the AR field will be set appropriately, as described in - * 5.1.6.4 [1] pg. 118. - */ - - *frame_ctrl |= (meta->msdu_flags.ack_tx << IEEE802154_FRAMECTRL_SHIFT_ACKREQ); - - /* If the destination address is present, copy the PAN ID and one of the - * addresses, depending on mode, into the MHR. - */ - - if (meta->dest_addr.mode != IEEE802154_ADDRMODE_NONE) - { - memcpy(&frame->io_data[mhr_len], &meta->dest_addr.panid, 2); - mhr_len += 2; - - if (meta->dest_addr.mode == IEEE802154_ADDRMODE_SHORT) - { - memcpy(&frame->io_data[mhr_len], &meta->dest_addr.saddr, 2); - mhr_len += 2; - } - else if (meta->dest_addr.mode == IEEE802154_ADDRMODE_EXTENDED) - { - memcpy(&frame->io_data[mhr_len], &meta->dest_addr.eaddr, - IEEE802154_EADDR_LEN); - - mhr_len += IEEE802154_EADDR_LEN; - } - } - - /* Set the destination addr mode inside the frame control field */ - - *frame_ctrl |= (meta->dest_addr.mode << IEEE802154_FRAMECTRL_SHIFT_DADDR); - - /* From this point on, we need exclusive access to the privmac struct */ - - ret = mac802154_takesem(&priv->exclsem); - if (ret < 0) - { - wlerr("ERROR: mac802154_takesem failed: %d\n", ret); - return ret; - } - - /* If both destination and source addressing information is present, the MAC - * sublayer shall compare the destination and source PAN identifiers. - * [1] pg. 41. - */ - - if (meta->src_addrmode != IEEE802154_ADDRMODE_NONE && - meta->dest_addr.mode != IEEE802154_ADDRMODE_NONE) - { - /* If the PAN identifiers are identical, the PAN ID Compression field - * shall be set to one, and the source PAN identifier shall be omitted - * from the transmitted frame. [1] pg. 41. - */ - - if (meta->dest_addr.panid == priv->addr.panid) - { - *frame_ctrl |= IEEE802154_FRAMECTRL_PANIDCOMP; - } - } - - if (meta->src_addrmode != IEEE802154_ADDRMODE_NONE) - { - /* If the destination address is not included, or if PAN ID Compression - * is off, we need to include the Source PAN ID. - */ - - if ((meta->dest_addr.mode == IEEE802154_ADDRMODE_NONE) || - (!(*frame_ctrl & IEEE802154_FRAMECTRL_PANIDCOMP))) - { - memcpy(&frame->io_data[mhr_len], &priv->addr.panid, 2); - mhr_len += 2; - } - - if (meta->src_addrmode == IEEE802154_ADDRMODE_SHORT) - { - memcpy(&frame->io_data[mhr_len], &priv->addr.saddr, 2); - mhr_len += 2; - } - else if (meta->src_addrmode == IEEE802154_ADDRMODE_EXTENDED) - { - memcpy(&frame->io_data[mhr_len], &priv->addr.eaddr, - IEEE802154_EADDR_LEN); - - mhr_len += IEEE802154_EADDR_LEN; - } - } - - /* Set the source addr mode inside the frame control field */ - - *frame_ctrl |= (meta->src_addrmode << IEEE802154_FRAMECTRL_SHIFT_SADDR); - - /* Each time a data or a MAC command frame is generated, the MAC sublayer - * shall copy the value of macDSN into the Sequence Number field of the MHR - * of the outgoing frame and then increment it by one. [1] pg. 40. - */ - - frame->io_data[2] = priv->dsn++; - - /* The MAC header we just created must never have exceeded where the app - * data starts. This should never happen since the offset should have - * been set via the same logic to calculate the header length as the logic - * here that created the header - */ - - DEBUGASSERT(mhr_len == frame->io_offset); - - frame->io_offset = 0; /* Set the offset to 0 to include the header */ - - /* Setup our transaction */ - - trans.handle = meta->msdu_handle; - trans.frametype = IEEE802154_FRAME_DATA; - trans.frame = frame; - sem_init(&trans.sem, 0, 0); - sem_setprotocol(&trans.sem, SEM_PRIO_NONE); - - /* If the TxOptions parameter specifies that a GTS transmission is required, - * the MAC sublayer will determine whether it has a valid GTS as described - * 5.1.7.3. If a valid GTS could not be found, the MAC sublayer will discard - * the MSDU. If a valid GTS was found, the MAC sublayer will defer, if - * necessary, until the GTS. If the TxOptions parameter specifies that a GTS - * transmission is not required, the MAC sublayer will transmit the MSDU using - * either slotted CSMA-CA in the CAP for a beacon-enabled PAN or unslotted - * CSMA-CA for a nonbeacon-enabled PAN. Specifying a GTS transmission in the - * TxOptions parameter overrides an indirect transmission request. - * [1] pg. 118. - */ - - if (meta->msdu_flags.gts_tx) - { - /* TODO: Support GTS transmission. This should just change where we link - * the transaction. Instead of going in the CSMA transaction list, it - * should be linked to the GTS' transaction list. We'll need to check if - * the GTS is valid, and then find the GTS, before linking. Note, we also - * don't have to try and kick-off any transmission here. - */ - - return -ENOTSUP; - } - else - { - /* If the TxOptions parameter specifies that an indirect transmission is - * required and this primitive is received by the MAC sublayer of a - * coordinator, the data frame is sent using indirect transmission, as - * described in 5.1.5 and 5.1.6.3. [1] - */ - - if (meta->msdu_flags.indirect_tx) - { - /* If the TxOptions parameter specifies that an indirect transmission - * is required and if the device receiving this primitive is not a - * coordinator, the destination address is not present, or the - * TxOptions parameter also specifies a GTS transmission, the indirect - * transmission option will be ignored. [1] - * - * NOTE: We don't just ignore the parameter. Instead, we throw an - * error, since this really shouldn't be happening. - */ - - if (priv->devmode == IEEE802154_DEVMODE_PANCOORD && - meta->dest_addr.mode != IEEE802154_ADDRMODE_NONE) - { - /* Link the transaction into the indirect_trans list */ - - } - else - { - return -EINVAL; - } - } - else - { - /* Link the transaction into the CSMA transaction list */ - - sq_addlast((FAR sq_entry_t *)&trans, &priv->csma_queue); - - /* We no longer need to have the MAC layer locked. */ - - mac802154_givesem(&priv->exclsem); - - /* Notify the radio driver that there is data available */ - - priv->radio->ops->txnotify_csma(priv->radio); - - ret = sem_wait(&trans.sem); - if (ret < 0) - { - return -EINTR; - } - } - } - - sem_destroy(&trans.sem); - return OK; -} - -/**************************************************************************** - * 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 mac802154_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) -{ - FAR struct ieee802154_privmac_s *priv = - (FAR struct ieee802154_privmac_s *)mac; - return -ENOTTY; -} - -/**************************************************************************** - * 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 mac802154_maccb_s->conf_associate callback. - * - ****************************************************************************/ - -int mac802154_req_associate(MACHANDLE mac, - FAR struct ieee802154_assoc_req_s *req) -{ - FAR struct ieee802154_privmac_s *priv = - (FAR struct ieee802154_privmac_s *)mac; - FAR struct mac802154_txtrans_s trans; - FAR struct iob_s *iob; - FAR uint16_t *u16; - bool rxonidle; - int ret; - - /* On receipt of the MLME-ASSOCIATE.request primitive, the MLME of an - * unassociated device first updates the appropriate PHY and MAC PIB - * attributes, as described in 5.1.3.1, and then generates an association - * request command, as defined in 5.3.1 [1] pg.80 - */ - - /* Get exlusive access to the shared command transaction. This must happen - * before getting exclusive access to the MAC struct or else there could be - * a lockup condition. This would occur if another thread is using the cmdtrans - * but needs access to the MAC in order to unlock it. - */ - - if (sem_wait(&priv->cmd.sem) < 0) - { - /* EINTR is the only error that we expect */ - - int errcode = get_errno(); - DEBUGASSERT(errcode == EINTR); - return -errcode; - } - - /* Get exclusive access to the MAC */ - - ret = mac802154_takesem(&priv->exclsem); - if (ret < 0) - { - wlerr("ERROR: mac802154_takesem failed: %d\n", ret); - return ret; - } - - /* Set the channel and channel page of the PHY layer */ - - priv->radio->ops->set_attr(priv->radio, IEEE802154_PIB_PHY_CURRENT_CHANNEL, - (FAR const union ieee802154_attr_u *)&req->chnum); - - priv->radio->ops->set_attr(priv->radio, IEEE802154_PIB_PHY_CURRENT_PAGE, - (FAR const union ieee802154_attr_u *)&req->chpage); - - /* Set the PANID attribute */ - - priv->addr.panid = req->coordaddr.panid; - priv->coordaddr.panid = req->coordaddr.panid; - priv->radio->ops->set_attr(priv->radio, IEEE802154_PIB_MAC_PANID, - (FAR const union ieee802154_attr_u *)&req->coordaddr.panid); - - /* Set the coordinator address attributes */ - - priv->coordaddr.mode = req->coordaddr.mode; - - if (priv->coordaddr.mode == IEEE802154_ADDRMODE_SHORT) - { - priv->coordaddr.saddr = req->coordaddr.saddr; - memcpy(&priv->coordaddr.eaddr[0], IEEE802154_EADDR_UNSPEC, - IEEE802154_EADDR_LEN); - } - else if (priv->coordaddr.mode == IEEE802154_ADDRMODE_EXTENDED) - { - priv->coordaddr.saddr = IEEE802154_SADDR_UNSPEC; - memcpy(&priv->coordaddr.eaddr[0], &req->coordaddr.eaddr[0], - IEEE802154_EADDR_LEN); - } - else - { - ret = -EINVAL; - goto errout; - } - - /* Copy in the capabilities information bitfield */ - - priv->devmode = (req->capabilities.devtype) ? - IEEE802154_DEVMODE_COORD : IEEE802154_DEVMODE_ENDPOINT; - - /* Unlike other attributes, we can't simply cast this one since it is a bit - * in a bitfield. Casting it will give us unpredicatble results. Instead - * of creating a ieee802154_attr_u, we use a local bool. Allocating the - * ieee802154_attr_u value would take up more room on the stack since it is - * as large as the largest attribute type. - */ - - rxonidle = req->capabilities.rxonidle; - priv->radio->ops->set_attr(priv->radio, IEEE802154_PIB_MAC_RX_ON_WHEN_IDLE, - (FAR const union ieee802154_attr_u *)&rxonidle); - - /* Allocate an IOB to put the frame in */ - - iob = iob_alloc(false); - DEBUGASSERT(iob != NULL); - - iob->io_flink = NULL; - iob->io_len = 0; - iob->io_offset = 0; - iob->io_pktlen = 0; - - /* Get a uin16_t reference to the first two bytes. ie frame control field */ - - u16 = (FAR uint16_t *)&iob->io_data[0]; - - *u16 = (IEEE802154_FRAME_COMMAND << IEEE802154_FRAMECTRL_SHIFT_FTYPE); - *u16 |= IEEE802154_FRAMECTRL_ACKREQ; - *u16 |= (priv->coordaddr.mode << IEEE802154_FRAMECTRL_SHIFT_DADDR); - *u16 |= (IEEE802154_ADDRMODE_EXTENDED << IEEE802154_FRAMECTRL_SHIFT_SADDR); - - iob->io_len = 2; - - /* Each time a data or a MAC command frame is generated, the MAC sublayer - * shall copy the value of macDSN into the Sequence Number field of the MHR - * of the outgoing frame and then increment it by one. [1] pg. 40. - */ - - iob->io_data[iob->io_len++] = priv->dsn++; - - /* The Destination PAN Identifier field shall contain the identifier of the - * PAN to which to associate. [1] pg. 68 - */ - - memcpy(&iob->io_data[iob->io_len], &priv->coordaddr.panid, 2); - - /* The Destination Address field shall contain the address from the beacon - * frame that was transmitted by the coordinator to which the association - * request command is being sent. [1] pg. 68 - */ - - if (priv->coordaddr.mode == IEEE802154_ADDRMODE_SHORT) - { - memcpy(&iob->io_data[iob->io_len], &priv->coordaddr.saddr, 2); - iob->io_len += 2; - } - else if (priv->coordaddr.mode == IEEE802154_ADDRMODE_EXTENDED) - { - memcpy(&iob->io_data[iob->io_len], &priv->coordaddr.eaddr[0], - IEEE802154_EADDR_LEN); - iob->io_len += IEEE802154_EADDR_LEN; - } - - /* The Source PAN Identifier field shall contain the broadcast PAN identifier.*/ - - u16 = (uint16_t *)&iob->io_data[iob->io_len]; - *u16 = IEEE802154_SADDR_BCAST; - iob->io_len += 2; - - /* The Source Address field shall contain the value of macExtendedAddress. */ - - memcpy(&iob->io_data[iob->io_len], &priv->addr.eaddr[0], - IEEE802154_EADDR_LEN); - iob->io_len += IEEE802154_EADDR_LEN; - - /* Copy in the Command Frame Identifier */ - - iob->io_data[iob->io_len++] = IEEE802154_CMD_ASSOC_REQ; - - /* Copy in the capability information bits */ - - iob->io_data[iob->io_len] = 0; - iob->io_data[iob->io_len] |= (req->capabilities.devtype << - IEEE802154_CAPABILITY_SHIFT_DEVTYPE); - iob->io_data[iob->io_len] |= (req->capabilities.powersource << - IEEE802154_CAPABILITY_SHIFT_PWRSRC); - iob->io_data[iob->io_len] |= (req->capabilities.rxonidle << - IEEE802154_CAPABILITY_SHIFT_RXONIDLE); - iob->io_data[iob->io_len] |= (req->capabilities.security << - IEEE802154_CAPABILITY_SHIFT_SECURITY); - iob->io_data[iob->io_len] |= (req->capabilities.allocaddr << - IEEE802154_CAPABILITY_SHIFT_ALLOCADDR); - - iob->io_len++; - - /* Copy reference to the frame into the shared command transaction */ - - priv->cmd.trans.frame = iob; - priv->cmd.trans.frametype = IEEE802154_FRAME_COMMAND; - priv->cmd.type = IEEE802154_CMD_ASSOC_REQ; - - /* Link the transaction into the CSMA transaction list */ - - sq_addlast((FAR sq_entry_t *)&trans, &priv->csma_queue); - - /* We no longer need to have the MAC layer locked. */ - - mac802154_givesem(&priv->exclsem); - - /* TODO: Need to setup a timeout here so that we can return an error to the - * user if the device never receives a response. - */ - - /* Notify the radio driver that there is data available */ - - priv->radio->ops->txnotify_csma(priv->radio); - - /* Wait for the transaction to be passed to the radio layer */ - - ret = sem_wait(&priv->cmd.trans.sem); - if (ret < 0) - { - return -EINTR; - } - - return OK; - -errout: - mac802154_givesem(&priv->exclsem); - return ret; -} - -/**************************************************************************** - * 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 mac802154_maccb_s->conf_disassociate callback. - * - ****************************************************************************/ - -int mac802154_req_disassociate(MACHANDLE mac, - FAR struct ieee802154_disassoc_req_s *req) -{ - FAR struct ieee802154_privmac_s *priv = - (FAR struct ieee802154_privmac_s *)mac; - return -ENOTTY; -} - -/**************************************************************************** - * 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 mac802154_maccb_s->conf_gts callback. - * - ****************************************************************************/ - -int mac802154_req_gts(MACHANDLE mac, FAR struct ieee802154_gts_req_s *req) -{ - FAR struct ieee802154_privmac_s *priv = - (FAR struct ieee802154_privmac_s *)mac; - return -ENOTTY; -} - -/**************************************************************************** - * 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) -{ - FAR struct ieee802154_privmac_s * priv = - (FAR struct ieee802154_privmac_s *) mac; - return -ENOTTY; -} - -/**************************************************************************** - * 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 mac802154_maccb_s->conf_rxenable callback. - * - ****************************************************************************/ - -int mac802154_req_rxenable(MACHANDLE mac, - FAR struct ieee802154_rxenable_req_s *req) -{ - FAR struct ieee802154_privmac_s * priv = - (FAR struct ieee802154_privmac_s *)mac; - return -ENOTTY; -} - -/**************************************************************************** - * 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 mac802154_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) -{ - FAR struct ieee802154_privmac_s *priv = - (FAR struct ieee802154_privmac_s *)mac; - return -ENOTTY; -} - -/**************************************************************************** - * 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_u *attrval) -{ - FAR struct ieee802154_privmac_s *priv = - (FAR struct ieee802154_privmac_s *)mac; - return -ENOTTY; -} - -/**************************************************************************** - * 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_u *attrval) -{ - FAR struct ieee802154_privmac_s *priv = - (FAR struct ieee802154_privmac_s *)mac; - int ret; - - switch (pib_attr) - { - case IEEE802154_PIB_MAC_EXTENDED_ADDR: - { - /* Set the MAC copy of the address in the table */ - - memcpy(&priv->addr.eaddr[0], &attrval->mac.eaddr[0], - IEEE802154_EADDR_LEN); - - /* Tell the radio about the attribute */ - - priv->radio->ops->set_attr(priv->radio, pib_attr, attrval); - - ret = IEEE802154_STATUS_SUCCESS; - } - break; - default: - { - /* The attribute may be handled soley in the radio driver, so pass - * it along. - */ - - ret = priv->radio->ops->set_attr(priv->radio, pib_attr, attrval); - } - break; - } - return ret; -} - -/**************************************************************************** - * 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 mac802154_maccb_s->conf_start callback. - * - ****************************************************************************/ - -int mac802154_req_start(MACHANDLE mac, FAR struct ieee802154_start_req_s *req) -{ - FAR struct ieee802154_privmac_s *priv = - (FAR struct ieee802154_privmac_s *)mac; - int ret; - - /* Get exclusive access to the MAC */ - - ret = mac802154_takesem(&priv->exclsem); - if (ret < 0) - { - wlerr("ERROR: mac802154_takesem failed: %d\n", ret); - return ret; - } - - /* When the CoordRealignment parameter is set to TRUE, the coordinator - * attempts to transmit a coordinator realignment command frame as described - * in 5.1.2.3.2. If the transmission of the coordinator realignment command - * fails due to a channel access failure, the MLME will not make any changes - * to the superframe configuration. (i.e., no PIB attributes will be changed). - * If the coordinator realignment command is successfully transmitted, the - * MLME updates the PIB attributes BeaconOrder, SuperframeOrder, PANId, - * ChannelPage, and ChannelNumber parameters. [1] pg. 106 - */ - - if (req->coordrealign) - { - /* TODO: Finish the realignment functionality */ - - return -ENOTTY; - } - - /* Set the PANID attribute */ - - priv->addr.panid = req->panid; - priv->radio->ops->set_attr(priv->radio, IEEE802154_PIB_MAC_PANID, - (FAR const union ieee802154_attr_u *)&req->panid); - - /* Set the radio attributes */ - priv->radio->ops->set_attr(priv->radio, IEEE802154_PIB_PHY_CURRENT_CHANNEL, - (FAR const union ieee802154_attr_u *)&req->chnum); - - priv->radio->ops->set_attr(priv->radio, IEEE802154_PIB_PHY_CURRENT_PAGE, - (FAR const union ieee802154_attr_u *)&req->chpage); - - /* Set the superframe order */ - - if(req->superframeorder > 15) - { - ret = -EINVAL; - goto errout; - } - - priv->superframeorder = req->superframeorder; - - /* Set the beacon order */ - - if(req->beaconorder > 15) - { - ret = -EINVAL; - goto errout; - } - - priv->beaconorder = req->beaconorder; - - if (req->pancoord) - { - priv->devmode = IEEE802154_DEVMODE_PANCOORD; - } - else - { - priv->devmode = IEEE802154_DEVMODE_COORD; - } - - /* If the BeaconOrder parameter is less than 15, the MLME sets macBattLifeExt to - * the value of the BatteryLifeExtension parameter. If the BeaconOrder parameter - * equals 15, the value of the BatteryLifeExtension parameter is ignored. - * [1] pg. 106 - */ - - if (priv->beaconorder < 15) - { - priv->battlifeext = req->battlifeext; - - /* TODO: Finish starting beacon enabled network */ - return -ENOTTY; - } - - mac802154_givesem(&priv->exclsem); - - return OK; - -errout: - mac802154_givesem(&priv->exclsem); - return ret; -} - -/**************************************************************************** - * 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 mac802154_maccb_s->int_commstatus callback. TOCHECK. - * - ****************************************************************************/ - -int mac802154_req_sync(MACHANDLE mac, FAR struct ieee802154_sync_req_s *req) -{ - FAR struct ieee802154_privmac_s *priv = - (FAR struct ieee802154_privmac_s *)mac; - return -ENOTTY; -} - -/**************************************************************************** - * 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 mac802154_maccb_s->conf_poll callback, followed by a - * struct mac802154_maccb_s->ind_data callback. - * - ****************************************************************************/ - -int mac802154_req_poll(MACHANDLE mac, FAR struct ieee802154_poll_req_s *req) -{ - FAR struct ieee802154_privmac_s *priv = - (FAR struct ieee802154_privmac_s *)mac; - return -ENOTTY; -} - -/**************************************************************************** - * 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) -{ - FAR struct ieee802154_privmac_s *priv = - (FAR struct ieee802154_privmac_s *)mac; - return -ENOTTY; -} - -/**************************************************************************** - * 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) -{ - FAR struct ieee802154_privmac_s *priv = - (FAR struct ieee802154_privmac_s *)mac; - return -ENOTTY; -} - -/**************************************************************************** - * Name: mac802154_notif_free - * - * Description: - * When the MAC calls the registered callback, it passes a reference - * to a mac802154_notify_s structure. This structure needs to be freed - * after the callback handler is done using it. - * - ****************************************************************************/ - -int mac802154_notif_free(MACHANDLE mac, - FAR struct ieee802154_notif_s *notif) -{ - FAR struct ieee802154_privmac_s *priv = - (FAR struct ieee802154_privmac_s *)mac; - - /* Get exclusive access to the MAC */ - - while(mac802154_takesem(&priv->exclsem) < 0); - - notif->flink = priv->notif_free; - priv->notif_free = notif; - - mac802154_givesem(&priv->exclsem); - - if (priv->csma_tryagain) - { - priv->csma_tryagain = false; - priv->radio->ops->txnotify_csma(priv->radio); - } - - if (priv->gts_tryagain) - { - priv->gts_tryagain = false; - priv->radio->ops->txnotify_gts(priv->radio); - } - - return -ENOTTY; -} diff --git a/wireless/ieee802154/mac802154.h b/wireless/ieee802154/mac802154.h index 2e8110f755a..40d00c9d696 100644 --- a/wireless/ieee802154/mac802154.h +++ b/wireless/ieee802154/mac802154.h @@ -58,8 +58,6 @@ * Public Data Types ****************************************************************************/ - - /* Callback operations to notify the next highest layer of various asynchronous * events, usually triggered by some previous request or response invoked by the * upper layer. @@ -141,7 +139,7 @@ int mac802154_get_mhrlen(MACHANDLE mac, * ****************************************************************************/ -int mac802154_req_data(MACHANDLE mac, +int mac802154_req_data(MACHANDLE mac, FAR const struct ieee802154_frame_meta_s *meta, FAR struct iob_s *frame); @@ -153,10 +151,10 @@ int mac802154_req_data(MACHANDLE mac, * an MSDU from the transaction queue. Confirmation is returned via * the struct mac802154_maccb_s->conf_purge callback. * - * NOTE: The standard specifies that confirmation should be indicated via + * 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 + * Therefore, we merge the functionality of the MLME-PURGE.request and * MLME-PURGE.confirm primitives together. * ****************************************************************************/ @@ -273,7 +271,7 @@ int mac802154_req_scan(MACHANDLE mac, FAR struct ieee802154_scan_req_s *req); * ****************************************************************************/ -int mac802154_req_get(MACHANDLE mac, enum ieee802154_pib_attr_e pib_attr, +int mac802154_req_get(MACHANDLE mac, enum ieee802154_attr_e , FAR union ieee802154_attr_u *attrval); /**************************************************************************** @@ -281,9 +279,9 @@ int mac802154_req_get(MACHANDLE mac, enum ieee802154_pib_attr_e pib_attr, * * Description: * The MLME-SET.request primitive attempts to write the given value to the - * indicated MAC PIB attribute. + * indicated MAC PIB attribute. * - * NOTE: The standard specifies that confirmation should be indicated via + * 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 @@ -291,7 +289,7 @@ int mac802154_req_get(MACHANDLE mac, enum ieee802154_pib_attr_e pib_attr, * ****************************************************************************/ -int mac802154_req_set(MACHANDLE mac, enum ieee802154_pib_attr_e pib_attr, +int mac802154_req_set(MACHANDLE mac, enum ieee802154_attr_e , FAR const union ieee802154_attr_u *attrval); /**************************************************************************** diff --git a/wireless/ieee802154/mac802154_assoc.c b/wireless/ieee802154/mac802154_assoc.c new file mode 100644 index 00000000000..0de0ec1977e --- /dev/null +++ b/wireless/ieee802154/mac802154_assoc.c @@ -0,0 +1,957 @@ +/**************************************************************************** + * wireless/ieee802154/mac802154_assoc.c + * + * Copyright (C) 2017 Verge Inc. All rights reserved. + * Author: Anthony Merlino + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "mac802154.h" +#include "mac802154_internal.h" +#include "mac802154_assoc.h" + +#include + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static void mac802154_timeout_assoc(FAR struct ieee802154_privmac_s *priv); +static FAR struct ieee802154_txdesc_s * + mac802154_assoc_getresp(FAR struct ieee802154_privmac_s *priv); + +/**************************************************************************** + * Public MAC Functions + ****************************************************************************/ + +/**************************************************************************** + * 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 mac802154_maccb_s->conf_associate callback. + * + * On receipt of the MLME-ASSOCIATE.request primitive, the MLME of an + * unassociated device first updates the appropriate PHY and MAC PIB + * attributes, as described in 5.1.3.1, and then generates an association + * request command, as defined in 5.3.1 [1] pg.80 + * + ****************************************************************************/ + +int mac802154_req_associate(MACHANDLE mac, + FAR struct ieee802154_assoc_req_s *req) +{ + FAR struct ieee802154_privmac_s *priv = + (FAR struct ieee802154_privmac_s *)mac; + FAR struct ieee802154_txdesc_s *txdesc; + FAR struct iob_s *iob; + FAR uint16_t *u16; + bool rxonidle; + int ret; + + /* Get exlusive access to the operation sempaphore. This must happen before + * getting exclusive access to the MAC struct or else there could be a lockup + * condition. This would occur if another thread is using the cmdtrans but + * needs access to the MAC in order to unlock it. + */ + + ret = mac802154_takesem(&priv->op_sem, true); + if (ret < 0) + { + return ret; + } + + priv->curr_op = MAC802154_OP_ASSOC; + priv->curr_cmd = IEEE802154_CMD_ASSOC_REQ; + + /* Get exclusive access to the MAC */ + + ret = mac802154_takesem(&priv->exclsem, true); + if (ret < 0) + { + mac802154_givesem(&priv->op_sem); + return ret; + } + + /* Set the channel and channel page of the PHY layer */ + + priv->radio->set_attr(priv->radio, IEEE802154_ATTR_PHY_CURRENT_CHANNEL, + (FAR const union ieee802154_attr_u *)&req->chnum); + + priv->radio->set_attr(priv->radio, IEEE802154_ATTR_PHY_CURRENT_PAGE, + (FAR const union ieee802154_attr_u *)&req->chpage); + + /* Set the PANID attribute */ + + priv->addr.panid = req->coordaddr.panid; + priv->coordaddr.panid = req->coordaddr.panid; + priv->radio->set_attr(priv->radio, IEEE802154_ATTR_MAC_PANID, + (FAR const union ieee802154_attr_u *)&req->coordaddr.panid); + + /* Set the coordinator address attributes */ + + priv->coordaddr.mode = req->coordaddr.mode; + + if (priv->coordaddr.mode == IEEE802154_ADDRMODE_SHORT) + { + priv->coordaddr.saddr = req->coordaddr.saddr; + memcpy(&priv->coordaddr.eaddr[0], IEEE802154_EADDR_UNSPEC, + IEEE802154_EADDR_LEN); + } + else if (priv->coordaddr.mode == IEEE802154_ADDRMODE_EXTENDED) + { + priv->coordaddr.saddr = IEEE802154_SADDR_UNSPEC; + memcpy(&priv->coordaddr.eaddr[0], &req->coordaddr.eaddr[0], + IEEE802154_EADDR_LEN); + } + else + { + ret = -EINVAL; + goto errout; + } + + /* Copy in the capabilities information bitfield */ + + priv->devmode = (req->capabilities.devtype) ? + IEEE802154_DEVMODE_COORD : IEEE802154_DEVMODE_ENDPOINT; + + /* Unlike other attributes, we can't simply cast this one since it is a bit + * in a bitfield. Casting it will give us unpredicatble results. Instead + * of creating a ieee802154_attr_u, we use a local bool. Allocating the + * ieee802154_attr_u value would take up more room on the stack since it is + * as large as the largest attribute type. + */ + + rxonidle = req->capabilities.rxonidle; + priv->radio->set_attr(priv->radio, IEEE802154_ATTR_MAC_RX_ON_WHEN_IDLE, + (FAR const union ieee802154_attr_u *)&rxonidle); + + /* Allocate an IOB to put the frame in */ + + iob = iob_alloc(false); + DEBUGASSERT(iob != NULL); + + iob->io_flink = NULL; + iob->io_len = 0; + iob->io_offset = 0; + iob->io_pktlen = 0; + + /* Allocate the txdesc, waiting if necessary */ + + ret = mac802154_txdesc_alloc(priv, &txdesc, true); + if (ret < 0) + { + iob_free(iob); + mac802154_givesem(&priv->exclsem); + mac802154_givesem(&priv->op_sem); + return ret; + } + + /* Get a uin16_t reference to the first two bytes. ie frame control field */ + + u16 = (FAR uint16_t *)&iob->io_data[0]; + + *u16 = (IEEE802154_FRAME_COMMAND << IEEE802154_FRAMECTRL_SHIFT_FTYPE); + *u16 |= IEEE802154_FRAMECTRL_ACKREQ; + *u16 |= (priv->coordaddr.mode << IEEE802154_FRAMECTRL_SHIFT_DADDR); + *u16 |= (IEEE802154_ADDRMODE_EXTENDED << IEEE802154_FRAMECTRL_SHIFT_SADDR); + + iob->io_len = 2; + + /* Each time a data or a MAC command frame is generated, the MAC sublayer + * shall copy the value of macDSN into the Sequence Number field of the MHR + * of the outgoing frame and then increment it by one. [1] pg. 40. + */ + + iob->io_data[iob->io_len++] = priv->dsn++; + + /* The Destination PAN Identifier field shall contain the identifier of the + * PAN to which to associate. [1] pg. 68 + */ + + memcpy(&iob->io_data[iob->io_len], &priv->coordaddr.panid, 2); + iob->io_len += 2; + + /* The Destination Address field shall contain the address from the beacon + * frame that was transmitted by the coordinator to which the association + * request command is being sent. [1] pg. 68 + */ + + if (priv->coordaddr.mode == IEEE802154_ADDRMODE_SHORT) + { + memcpy(&iob->io_data[iob->io_len], &priv->coordaddr.saddr, 2); + iob->io_len += 2; + } + else if (priv->coordaddr.mode == IEEE802154_ADDRMODE_EXTENDED) + { + memcpy(&iob->io_data[iob->io_len], &priv->coordaddr.eaddr[0], + IEEE802154_EADDR_LEN); + iob->io_len += IEEE802154_EADDR_LEN; + } + + /* The Source PAN Identifier field shall contain the broadcast PAN identifier.*/ + + u16 = (uint16_t *)&iob->io_data[iob->io_len]; + *u16 = IEEE802154_SADDR_BCAST; + iob->io_len += 2; + + /* The Source Address field shall contain the value of macExtendedAddress. */ + + memcpy(&iob->io_data[iob->io_len], &priv->addr.eaddr[0], + IEEE802154_EADDR_LEN); + iob->io_len += IEEE802154_EADDR_LEN; + + /* Copy in the Command Frame Identifier */ + + iob->io_data[iob->io_len++] = IEEE802154_CMD_ASSOC_REQ; + + /* Copy in the capability information bits */ + + iob->io_data[iob->io_len] = 0; + iob->io_data[iob->io_len] |= (req->capabilities.devtype << + IEEE802154_CAPABILITY_SHIFT_DEVTYPE); + iob->io_data[iob->io_len] |= (req->capabilities.powersource << + IEEE802154_CAPABILITY_SHIFT_PWRSRC); + iob->io_data[iob->io_len] |= (req->capabilities.rxonidle << + IEEE802154_CAPABILITY_SHIFT_RXONIDLE); + iob->io_data[iob->io_len] |= (req->capabilities.security << + IEEE802154_CAPABILITY_SHIFT_SECURITY); + iob->io_data[iob->io_len] |= (req->capabilities.allocaddr << + IEEE802154_CAPABILITY_SHIFT_ALLOCADDR); + + iob->io_len++; + + txdesc->frame = iob; + txdesc->frametype = IEEE802154_FRAME_COMMAND; + + /* Save a copy of the destination addressing infromation into the tx descriptor. + * We only do this for commands to help with handling their progession. + */ + + memcpy(&txdesc->destaddr, &req->coordaddr, sizeof(struct ieee802154_addr_s)); + + /* Save a reference of the tx descriptor */ + + priv->cmd_desc = txdesc; + + /* We no longer need to have the MAC layer locked. */ + + mac802154_givesem(&priv->exclsem); + + /* Association Request commands get sent out immediately */ + + priv->radio->txdelayed(priv->radio, txdesc, 0); + + return OK; + +errout: + mac802154_givesem(&priv->exclsem); + return ret; +} + +/**************************************************************************** + * 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) +{ + FAR struct ieee802154_privmac_s *priv = + (FAR struct ieee802154_privmac_s *)mac; + FAR struct ieee802154_txdesc_s *txdesc; + FAR struct iob_s *iob; + FAR uint16_t *u16; + int ret; + + /* Allocate an IOB to put the frame in */ + + iob = iob_alloc(false); + DEBUGASSERT(iob != NULL); + + iob->io_flink = NULL; + iob->io_len = 0; + iob->io_offset = 0; + iob->io_pktlen = 0; + + /* Get a uin16_t reference to the first two bytes. ie frame control field */ + + u16 = (FAR uint16_t *)&iob->io_data[0]; + + /* The Destination Addressing Mode and Source Addressing Mode fields shall + * each be set to indicate extended addressing. + * + * The Frame Pending field shall be set to zero and ignored upon reception, + * and the AR field shall be set to one. + * + * The PAN ID Compression field shall be set to one. [1] pg. 69 + */ + + *u16 = (IEEE802154_FRAME_COMMAND << IEEE802154_FRAMECTRL_SHIFT_FTYPE); + *u16 |= IEEE802154_FRAMECTRL_ACKREQ; + *u16 |= IEEE802154_FRAMECTRL_PANIDCOMP; + *u16 |= (IEEE802154_ADDRMODE_EXTENDED << IEEE802154_FRAMECTRL_SHIFT_DADDR); + *u16 |= (IEEE802154_ADDRMODE_EXTENDED << IEEE802154_FRAMECTRL_SHIFT_SADDR); + + iob->io_len = 2; + + /* Each time a data or a MAC command frame is generated, the MAC sublayer + * shall copy the value of macDSN into the Sequence Number field of the MHR + * of the outgoing frame and then increment it by one. [1] pg. 40. + */ + + iob->io_data[iob->io_len++] = priv->dsn++; + + /* In accordance with this value of the PAN ID Compression field, the + * Destination PAN Identifier field shall contain the value of macPANId, while + * the Source PAN Identifier field shall be omitted. [1] pg. 69 + */ + + memcpy(&iob->io_data[iob->io_len], &priv->addr.panid, 2); + iob->io_len += 2; + + /* The Destination Address field shall contain the extended address of the + * device requesting association. [1] pg. 69 */ + + memcpy(&iob->io_data[iob->io_len], &resp->devaddr[0], IEEE802154_EADDR_LEN); + iob->io_len += IEEE802154_EADDR_LEN; + + /* The Source Address field shall contain the value of macExtendedAddress. */ + + memcpy(&iob->io_data[iob->io_len], &priv->addr.eaddr[0], IEEE802154_EADDR_LEN); + iob->io_len += IEEE802154_EADDR_LEN; + + /* Copy in the Command Frame Identifier */ + + iob->io_data[iob->io_len++] = IEEE802154_CMD_ASSOC_RESP; + + /* Copy in the assigned short address */ + + if (resp->status == IEEE802154_STATUS_SUCCESS) + { + memcpy(&iob->io_data[iob->io_len], &resp->assocsaddr, 2); + } + else + { + u16 = (FAR uint16_t *)&iob->io_data[iob->io_len]; + *u16 = IEEE802154_SADDR_UNSPEC; + } + iob->io_len += 2; + + /* Copy in the association status */ + + iob->io_data[iob->io_len++] = resp->status; + + /* Get exclusive access to the MAC */ + + ret = mac802154_takesem(&priv->exclsem, true); + if (ret < 0) + { + iob_free(iob); + return ret; + } + + /* Allocate the txdesc, waiting if necessary */ + + ret = mac802154_txdesc_alloc(priv, &txdesc, true); + if (ret < 0) + { + iob_free(iob); + mac802154_givesem(&priv->exclsem); + return ret; + } + + txdesc->frame = iob; + txdesc->frametype = IEEE802154_FRAME_COMMAND; + + txdesc->destaddr.panid = priv->addr.panid; + txdesc->destaddr.mode = IEEE802154_ADDRMODE_EXTENDED; + memcpy(&txdesc->destaddr.eaddr[0], &resp->devaddr[0], IEEE802154_EADDR_LEN); + + mac802154_setupindirect(priv, txdesc); + + mac802154_givesem(&priv->exclsem); + + return OK; +} + +/**************************************************************************** + * Internal MAC Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mac802154_txdone_assocreq + * + * Description: + * Handle the completion (success/failure) of transmitting an association + * request command. + * + * Assumptions: + * Called with the MAC locked. + * + ****************************************************************************/ + +void mac802154_txdone_assocreq(FAR struct ieee802154_privmac_s *priv, + FAR struct ieee802154_txdesc_s *txdesc) +{ + enum ieee802154_status_e status; + FAR struct mac802154_notif_s *privnotif = + (FAR struct mac802154_notif_s *)txdesc->conf; + FAR struct ieee802154_notif_s *notif = &privnotif->pub; + FAR struct ieee802154_txdesc_s *respdesc; + + if(txdesc->conf->status != IEEE802154_STATUS_SUCCESS) + { + /* if the association request command cannot be sent due to a + * channel access failure, the MAC sublayer shall notify the next + * higher layer. [1] pg. 33 + */ + + /* We can actually high-jack the data conf notification since it + * is allocated as an ieee80215_notif_s anyway. Before we overwrite + * any data though, we need to get the status from the data + * confirmation as that is the method we use to get the reason + * why the tx failed from the radio layer. + */ + + status = txdesc->conf->status; + notif->notiftype = IEEE802154_NOTIFY_CONF_ASSOC; + + notif->u.assocconf.status = status; + + /* The short device address allocated by the coordinator on + * successful association. This parameter will be equal to 0xffff + * if the association attempt was unsuccessful. [1] pg. 81 + */ + + notif->u.assocconf.saddr = IEEE802154_SADDR_UNSPEC; + + /* We are now done the operation, unlock the semaphore */ + + priv->curr_op = MAC802154_OP_NONE; + priv->cmd_desc = NULL; + mac802154_givesem(&priv->op_sem); + + /* Release the MAC, call the callback, get exclusive access again */ + + mac802154_givesem(&priv->exclsem); + priv->cb->notify(priv->cb, notif); + mac802154_takesem(&priv->exclsem, false); + } + else + { + /* On receipt of the acknowledgment to the association request + * command, the device shall wait for at most macResponseWaitTime + * for the coordinator to make its association decision; the PIB + * attribute macResponseWaitTime is a network-topology-dependent + * parameter and may be set to match the specific requirements of + * the network that a device is trying to join. If the device is + * tracking the beacon, it shall attempt to extract the association + * response command from the coordinator whenever it is indicated in + * the beacon frame. If the device is not tracking the beacon, it + * shall attempt to extract the association response command from + * the coordinator after macResponseWaitTime. [1] pg. 34 + */ + + if (priv->trackingbeacon) + { + /* We are tracking the beacon, so we should see our address in the + * beacon frame within macResponseWaitTime if the coordinator is going + * to respond. Setup a timeout for macResponseWaitTime so that we + * can inform the next highest layer if the association attempt fails + * due to NO_DATA. + */ + + mac802154_timerstart(priv, + priv->resp_waittime*IEEE802154_BASE_SUPERFRAME_DURATION, + mac802154_timeout_assoc); + } + else + { + /* Send the Data Request MAC command after macResponseWaitTime to + * extract the data from the coordinator. + */ + + respdesc = mac802154_assoc_getresp(priv); + priv->radio->txdelayed(priv->radio, respdesc, + (priv->resp_waittime*IEEE802154_BASE_SUPERFRAME_DURATION)); + } + + /* We can deallocate the data conf notification as it is no longer + * needed. We can't use the public function here since we already + * have the MAC locked. + */ + + privnotif->flink = priv->notif_free; + priv->notif_free = privnotif; + } +} + +/**************************************************************************** + * Name: mac802154_txdone_datareq_assoc + * + * Description: + * Handle the completion (success/failure) of transmitting a data request + * command in an effort to extract the association response from the + * coordinator. + * + * Assumptions: + * Called with the MAC locked. + * + ****************************************************************************/ + +void mac802154_txdone_datareq_assoc(FAR struct ieee802154_privmac_s *priv, + FAR struct ieee802154_txdesc_s *txdesc) +{ + enum ieee802154_status_e status; + FAR struct mac802154_notif_s *privnotif = + (FAR struct mac802154_notif_s *)txdesc->conf; + FAR struct ieee802154_notif_s *notif = &privnotif->pub; + + /* If the data request failed to be sent, notify the next layer + * that the association has failed. + * OR + * On receipt of the Ack frame with the Frame Pending field set + * to zero, the device shall conclude that there are no data + * pending at the coordinator. [1] pg. 43 + */ + + if (notif->u.dataconf.status != IEEE802154_STATUS_SUCCESS || + txdesc->framepending == 0) + { + if (notif->u.dataconf.status != IEEE802154_STATUS_SUCCESS) + { + status = notif->u.dataconf.status; + } + else + { + /* If the device does not extract an association response + * command frame from the coordinator within macResponseWaitTime, + * the MLME shall issue the MLME-ASSOCIATE.confirm primitive, + * as described in 6.2.2.4, with a status of NO_DATA, and the + * association attempt shall be deemed a failure. [1] pg. 34 + */ + + status = IEEE802154_STATUS_NO_DATA; + } + + notif->notiftype = IEEE802154_NOTIFY_CONF_ASSOC; + notif->u.assocconf.status = status; + + /* The short device address allocated by the coordinator on + * successful association. This parameter will be equal to 0xffff + * if the association attempt was unsuccessful. [1] pg. 81 + */ + + notif->u.assocconf.saddr = IEEE802154_SADDR_UNSPEC; + + /* We are now done the operation, and can release the command */ + + priv->curr_op = MAC802154_OP_NONE; + priv->cmd_desc = NULL; + mac802154_givesem(&priv->op_sem); + + /* Release the MAC, call the callback, get exclusive access again */ + + mac802154_givesem(&priv->exclsem); + priv->cb->notify(priv->cb, notif); + mac802154_takesem(&priv->exclsem, false); + } + else + { + /* On receipt of the acknowledgment frame with the Frame + * Pending field set to one, a device shall enable its + * receiver for at most macMaxFrameTotalWaitTime to receive + * the corresponding data frame from the coordinator. [1] pg.43 + */ + + priv->radio->rxenable(priv->radio, true); + + /* Start a timer, if we receive the data frame, we will cancel + * the timer, otherwise it will expire and we will notify the + * next highest layer of the failure. + */ + + mac802154_timerstart(priv, priv->max_frame_waittime, + mac802154_timeout_assoc); + + /* We can deallocate the data conf notification as it is no longer + * needed. We can't use the public function here since we already + * have the MAC locked. + */ + + privnotif->flink = priv->notif_free; + priv->notif_free = privnotif; + mac802154_givesem(&priv->notif_sem); + } +} + +/**************************************************************************** + * Name: mac802154_rx_assocreq + * + * Description: + * Function called from the generic RX Frame worker to parse and handle the + * reception of an Association Request MAC command frame. + * + ****************************************************************************/ + +void mac802154_rx_assocreq(FAR struct ieee802154_privmac_s *priv, + FAR struct ieee802154_data_ind_s *ind) +{ + FAR struct iob_s *frame = ind->frame; + FAR struct ieee802154_notif_s *notif; + uint8_t cap; + + /* Get exclusive access to the MAC */ + + mac802154_takesem(&priv->exclsem, false); + + /* Allocate a notification to pass to the next highest layer */ + + mac802154_notif_alloc(priv, ¬if, false); + notif->notiftype = IEEE802154_NOTIFY_IND_ASSOC; + + /* Association Requests should always be sent from a device with source + * addressing mode set to extended mode. Throw out any request received + * without addressing set to extended + */ + + if (ind->src.mode != IEEE802154_ADDRMODE_EXTENDED) + { + goto errout_with_sem; + } + + /* Copy the extended address of the requesting device */ + + memcpy(¬if->u.assocind.devaddr[0], &ind->src.eaddr[0], + sizeof(struct ieee802154_addr_s)); + + /* Copy in the capability information from the frame to the notification */ + + cap = frame->io_data[frame->io_offset++]; + notif->u.assocind.capabilities.devtype = + (cap >> IEEE802154_CAPABILITY_SHIFT_DEVTYPE) & 0x01; + notif->u.assocind.capabilities.powersource = + (cap >> IEEE802154_CAPABILITY_SHIFT_PWRSRC) & 0x01; + notif->u.assocind.capabilities.rxonidle = + (cap >> IEEE802154_CAPABILITY_SHIFT_RXONIDLE) & 0x01; + notif->u.assocind.capabilities.security = + (cap >> IEEE802154_CAPABILITY_SHIFT_SECURITY) & 0x01; + notif->u.assocind.capabilities.allocaddr = + (cap >> IEEE802154_CAPABILITY_SHIFT_ALLOCADDR) & 0x01; + +#ifdef CONFIG_IEEE802154_SECURITY +#error Missing security logic +#endif + + /* Unlock the MAC */ + + mac802154_givesem(&priv->exclsem); + + /* Notify the next highest layer of the association status */ + + priv->cb->notify(priv->cb, notif); + + return; + +errout_with_sem: + mac802154_givesem(&priv->exclsem); + return; +} + +/**************************************************************************** + * Name: mac802154_rx_assocresp + * + * Description: + * Function called from the generic RX Frame worker to parse and handle the + * reception of an Association Response MAC command frame. + * + ****************************************************************************/ + +void mac802154_rx_assocresp(FAR struct ieee802154_privmac_s *priv, + FAR struct ieee802154_data_ind_s *ind) +{ + FAR struct iob_s *frame = ind->frame; + FAR struct ieee802154_notif_s *notif; + + /* Check if we are performing an Association operation, if not, we will just + * ignore the frame. + */ + + if (priv->curr_op != MAC802154_OP_ASSOC) + { + return; + } + + /* Cancel the timeout used if we didn't get a response */ + + mac802154_timercancel(priv); + + /* Get exclusive access to the MAC */ + + mac802154_takesem(&priv->exclsem, false); + + /* Allocate a notification to pass to the next highest layer */ + + mac802154_notif_alloc(priv, ¬if, false); + notif->notiftype = IEEE802154_NOTIFY_CONF_ASSOC; + + /* Parse the short address from the response */ + + priv->addr.saddr = (uint16_t)(frame->io_data[frame->io_offset]); + frame->io_offset += 2; + + /* Inform the radio of the address change */ + + priv->radio->set_attr(priv->radio, IEEE802154_ATTR_MAC_SHORT_ADDRESS, + (FAR union ieee802154_attr_u *)&priv->addr.saddr); + + /* A Short Address field value equal to 0xfffe shall indicate that the device + * has been successfully associated with a PAN but has not been allocated a + * short address. In this case, the device shall communicate on the PAN using + * only its extended address. [1] pg. 70 + */ + + if (priv->addr.saddr == IEEE802154_SADDR_BCAST) + { + /* TODO: Figure out if this is sufficient */ + + priv->addr.mode = IEEE802154_ADDRMODE_SHORT; + } + + /* Parse the status from the response */ + + notif->u.assocconf.status = frame->io_data[frame->io_offset++]; + + if (notif->u.assocconf.status == IEEE802154_STATUS_SUCCESS) + { + priv->isassoc = true; + } + else + { + priv->isassoc = false; + } + + notif->u.assocconf.saddr = priv->addr.saddr; + + /* Unlock the MAC */ + + mac802154_givesem(&priv->exclsem); + + /* We are no longer performing the association operation */ + + priv->curr_op = MAC802154_OP_NONE; + priv->cmd_desc = NULL; + mac802154_givesem(&priv->op_sem); + + /* Notify the next highest layer of the association status */ + + priv->cb->notify(priv->cb, notif); +} + +/**************************************************************************** + * Private Function + ****************************************************************************/ + +/**************************************************************************** + * Name: mac802154_timeout_assoc + * + * Description: + * Function registered with MAC timer that gets called via the work queue to + * handle a timeout for extracting the Association Response from the Coordinator. + * + ****************************************************************************/ + +static void mac802154_timeout_assoc(FAR struct ieee802154_privmac_s *priv) +{ + FAR struct ieee802154_notif_s *notif; + + DEBUGASSERT(priv->curr_op == MAC802154_OP_ASSOC); + + /* If the device does not extract an association response command + * frame from the coordinator within macResponseWaitTime, the MLME + * shall issue the MLME-ASSOCIATE.confirm primitive, as described + * in 6.2.2.4, with a status of NO_DATA, and the association attempt + * shall be deemed a failure. [1] pg. 33 + */ + + /* Allocate a notification struct to pass to the next highest layer. + * Don't allow EINTR to interrupt. + */ + + mac802154_takesem(&priv->exclsem, false); + mac802154_notif_alloc(priv, ¬if, false); + + /* We are no longer performing the association operation */ + priv->curr_op = MAC802154_OP_NONE; + priv->cmd_desc = NULL; + mac802154_givesem(&priv->op_sem); + + /* Release the MAC */ + + mac802154_givesem(&priv->exclsem); + + notif->notiftype = IEEE802154_NOTIFY_CONF_ASSOC; + notif->u.assocconf.status = IEEE802154_STATUS_NO_DATA; + notif->u.assocconf.saddr = IEEE802154_SADDR_UNSPEC; + + priv->cb->notify(priv->cb, notif); +} + +/**************************************************************************** + * Name: mac802154_assoc_getresp + * + * Description: + * Send a data request to the coordinator to extract the association response. + * + * Assumptions: + * MAC is locked when called. + * + * TODO: Can this be used for general data extraction? + * + ****************************************************************************/ + +static FAR struct ieee802154_txdesc_s * + mac802154_assoc_getresp(FAR struct ieee802154_privmac_s *priv) +{ + FAR struct iob_s *iob; + FAR struct ieee802154_txdesc_s *txdesc; + FAR uint16_t *u16; + + /* Allocate an IOB to put the frame in */ + + iob = iob_alloc(false); + DEBUGASSERT(iob != NULL); + + iob->io_flink = NULL; + iob->io_len = 0; + iob->io_offset = 0; + iob->io_pktlen = 0; + + /* Allocate a tx descriptor */ + + mac802154_txdesc_alloc(priv, &txdesc, false); + + priv->curr_cmd = IEEE802154_CMD_DATA_REQ; + + /* Get a uin16_t reference to the first two bytes. ie frame control field */ + + u16 = (FAR uint16_t *)&iob->io_data[0]; + + *u16 = (IEEE802154_FRAME_COMMAND << IEEE802154_FRAMECTRL_SHIFT_FTYPE); + *u16 |= IEEE802154_FRAMECTRL_ACKREQ; + *u16 |= (priv->coordaddr.mode << IEEE802154_FRAMECTRL_SHIFT_DADDR); + *u16 |= (IEEE802154_ADDRMODE_EXTENDED << IEEE802154_FRAMECTRL_SHIFT_SADDR); + + /* If the Destination Addressing Mode field is set to indicate that + * destination addressing information is not present, the PAN ID Compression + * field shall be set to zero and the source PAN identifier shall contain the + * value of macPANId. Otherwise, the PAN ID Compression field shall be set to + * one. In this case and in accordance with the PAN ID Compression field, the + * Destination PAN Identifier field shall contain the value of macPANId, while + * the Source PAN Identifier field shall be omitted. [1] pg. 72 + * + * The destination address for a data request to extract an assoication request + * should never be set to none. So we always set the PAN ID compression field + */ + + DEBUGASSERT(priv->coordaddr.mode != IEEE802154_ADDRMODE_NONE); + + *u16 |= IEEE802154_FRAMECTRL_PANIDCOMP; + + iob->io_len = 2; + + /* Each time a data or a MAC command frame is generated, the MAC sublayer + * shall copy the value of macDSN into the Sequence Number field of the + * MHR of the outgoing frame and then increment it by one. [1] pg. 40. + */ + + iob->io_data[iob->io_len++] = priv->dsn++; + + /* The Destination PAN Identifier field shall contain the identifier of + * the PAN to which to associate. [1] pg. 68 + */ + + memcpy(&iob->io_data[iob->io_len], &priv->coordaddr.panid, 2); + iob->io_len += 2; + + /* The Destination Address field shall contain the address from the + * beacon frame that was transmitted by the coordinator to which the + * association request command is being sent. [1] pg. 68 + */ + + if (priv->coordaddr.mode == IEEE802154_ADDRMODE_SHORT) + { + memcpy(&iob->io_data[iob->io_len], &priv->coordaddr.saddr, 2); + iob->io_len += 2; + } + else if (priv->coordaddr.mode == IEEE802154_ADDRMODE_EXTENDED) + { + memcpy(&iob->io_data[iob->io_len], &priv->coordaddr.eaddr[0], + IEEE802154_EADDR_LEN); + iob->io_len += IEEE802154_EADDR_LEN; + } + + /* The Source Address field shall contain the value of macExtendedAddress. */ + + memcpy(&iob->io_data[iob->io_len], &priv->addr.eaddr[0], + IEEE802154_EADDR_LEN); + iob->io_len += IEEE802154_EADDR_LEN; + + /* Copy in the Command Frame Identifier */ + + iob->io_data[iob->io_len++] = IEEE802154_CMD_DATA_REQ; + + /* Copy the IOB reference to the descriptor */ + + txdesc->frame = iob; + + return txdesc; +} diff --git a/wireless/ieee802154/mac802154_assoc.h b/wireless/ieee802154/mac802154_assoc.h new file mode 100644 index 00000000000..e1e7d1d3528 --- /dev/null +++ b/wireless/ieee802154/mac802154_assoc.h @@ -0,0 +1,75 @@ +/**************************************************************************** + * wireless/ieee802154/mac802154_assoc.h + * + * Copyright (C) 2017 Verge Inc. All rights reserved. + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * + * Author: Anthony Merlino + * Author: Gregory Nutt + * + * The naming and comments for various fields are taken directly + * from the IEEE 802.15.4 2011 standard. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __WIRELESS_IEEE802154__MAC802154_ASSOC_H +#define __WIRELESS_IEEE802154__MAC802154_ASSOC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +/**************************************************************************** + * Function Prototypes + ****************************************************************************/ + +struct ieee802154_privmac_s; /* Forward Reference */ + +void mac802154_txdone_assocreq(FAR struct ieee802154_privmac_s *priv, + FAR struct ieee802154_txdesc_s *txdesc); + +void mac802154_txdone_datareq_assoc(FAR struct ieee802154_privmac_s *priv, + FAR struct ieee802154_txdesc_s *txdesc); + +void mac802154_rx_assocreq(FAR struct ieee802154_privmac_s *priv, + FAR struct ieee802154_data_ind_s *ind); + +void mac802154_rx_assocresp(FAR struct ieee802154_privmac_s *priv, + FAR struct ieee802154_data_ind_s *ind); + +#endif /* __WIRELESS_IEEE802154__MAC802154_ASSOC_H */ \ No newline at end of file diff --git a/wireless/ieee802154/mac802154_bind.c b/wireless/ieee802154/mac802154_bind.c new file mode 100644 index 00000000000..c173aef477b --- /dev/null +++ b/wireless/ieee802154/mac802154_bind.c @@ -0,0 +1,80 @@ +/**************************************************************************** + * wireless/ieee802154/mac802154_bind.c + * + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * Copyright (C) 2017 Verge Inc. All rights reserved. + * + * Author: Gregory Nutt + * Author: Anthony Merlino + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "mac802154.h" +#include "mac802154_internal.h" + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * 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 mac802154_maccb_s *cb) +{ + FAR struct ieee802154_privmac_s *priv = + (FAR struct ieee802154_privmac_s *)mac; + + priv->cb = cb; + return OK; +} + diff --git a/wireless/ieee802154/mac802154_data.c b/wireless/ieee802154/mac802154_data.c new file mode 100644 index 00000000000..34e3eabd506 --- /dev/null +++ b/wireless/ieee802154/mac802154_data.c @@ -0,0 +1,331 @@ +/**************************************************************************** + * wireless/ieee802154/mac802154_data.c + * + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * Copyright (C) 2017 Verge Inc. All rights reserved. + * + * Author: Gregory Nutt + * Author: Anthony Merlino + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include + +#include "mac802154.h" +#include "mac802154_internal.h" +#include "mac802154_data.h" + +#include + +/**************************************************************************** + * Public MAC Functions + ****************************************************************************/ + +/**************************************************************************** + * 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 mac802154_maccb_s->conf_data callback. + * + ****************************************************************************/ + +int mac802154_req_data(MACHANDLE mac, + FAR const struct ieee802154_frame_meta_s *meta, + FAR struct iob_s *frame) +{ + FAR struct ieee802154_privmac_s *priv = + (FAR struct ieee802154_privmac_s *)mac; + FAR struct ieee802154_txdesc_s *txdesc; + uint16_t *frame_ctrl; + uint8_t mhr_len = 3; /* Start assuming frame control and seq. num */ + int ret; + + /* Check the required frame size */ + + if (frame->io_len > IEEE802154_MAX_PHY_PACKET_SIZE) + { + return -E2BIG; + } + + /* Cast the first two bytes of the IOB to a uint16_t frame control field */ + + frame_ctrl = (FAR uint16_t *)&frame->io_data[0]; + + /* Ensure we start with a clear frame control field */ + + *frame_ctrl = 0; + + /* Set the frame type to Data */ + + *frame_ctrl |= IEEE802154_FRAME_DATA << IEEE802154_FRAMECTRL_SHIFT_FTYPE; + + /* If the msduLength is greater than aMaxMACSafePayloadSize, the MAC + * sublayer will set the Frame Version to one. [1] pg. 118. + */ + + if ((frame->io_len - frame->io_offset) > IEEE802154_MAX_SAFE_MAC_PAYLOAD_SIZE) + { + *frame_ctrl |= IEEE802154_FRAMECTRL_VERSION; + } + + /* If the TXOptions parameter specifies that an acknowledged transmission + * is required, the AR field will be set appropriately, as described in + * 5.1.6.4 [1] pg. 118. + */ + + *frame_ctrl |= (meta->msdu_flags.ack_tx << IEEE802154_FRAMECTRL_SHIFT_ACKREQ); + + /* If the destination address is present, copy the PAN ID and one of the + * addresses, depending on mode, into the MHR. + */ + + if (meta->destaddr.mode != IEEE802154_ADDRMODE_NONE) + { + memcpy(&frame->io_data[mhr_len], &meta->destaddr.panid, 2); + mhr_len += 2; + + if (meta->destaddr.mode == IEEE802154_ADDRMODE_SHORT) + { + memcpy(&frame->io_data[mhr_len], &meta->destaddr.saddr, 2); + mhr_len += 2; + } + else if (meta->destaddr.mode == IEEE802154_ADDRMODE_EXTENDED) + { + memcpy(&frame->io_data[mhr_len], &meta->destaddr.eaddr, + IEEE802154_EADDR_LEN); + + mhr_len += IEEE802154_EADDR_LEN; + } + } + + /* Set the destination addr mode inside the frame control field */ + + *frame_ctrl |= (meta->destaddr.mode << IEEE802154_FRAMECTRL_SHIFT_DADDR); + + /* From this point on, we need exclusive access to the privmac struct */ + + ret = mac802154_takesem(&priv->exclsem, true); + if (ret < 0) + { + return ret; + } + + /* If both destination and source addressing information is present, the MAC + * sublayer shall compare the destination and source PAN identifiers. + * [1] pg. 41. + */ + + if (meta->srcaddr_mode != IEEE802154_ADDRMODE_NONE && + meta->destaddr.mode != IEEE802154_ADDRMODE_NONE) + { + /* If the PAN identifiers are identical, the PAN ID Compression field + * shall be set to one, and the source PAN identifier shall be omitted + * from the transmitted frame. [1] pg. 41. + */ + + if (meta->destaddr.panid == priv->addr.panid) + { + *frame_ctrl |= IEEE802154_FRAMECTRL_PANIDCOMP; + } + } + + if (meta->srcaddr_mode != IEEE802154_ADDRMODE_NONE) + { + /* If the destination address is not included, or if PAN ID Compression + * is off, we need to include the Source PAN ID. + */ + + if ((meta->destaddr.mode == IEEE802154_ADDRMODE_NONE) || + (!(*frame_ctrl & IEEE802154_FRAMECTRL_PANIDCOMP))) + { + memcpy(&frame->io_data[mhr_len], &priv->addr.panid, 2); + mhr_len += 2; + } + + if (meta->srcaddr_mode == IEEE802154_ADDRMODE_SHORT) + { + memcpy(&frame->io_data[mhr_len], &priv->addr.saddr, 2); + mhr_len += 2; + } + else if (meta->srcaddr_mode == IEEE802154_ADDRMODE_EXTENDED) + { + memcpy(&frame->io_data[mhr_len], &priv->addr.eaddr, + IEEE802154_EADDR_LEN); + + mhr_len += IEEE802154_EADDR_LEN; + } + } + else + { + /* If this device is not the PAN coordinator, it shouldn't be sending + * frames with a source address mode of NONE + */ + + if (priv->devmode != IEEE802154_DEVMODE_PANCOORD) + { + return -EINVAL; + } + } + + /* Set the source addr mode inside the frame control field */ + + *frame_ctrl |= (meta->srcaddr_mode << IEEE802154_FRAMECTRL_SHIFT_SADDR); + + /* Each time a data or a MAC command frame is generated, the MAC sublayer + * shall copy the value of macDSN into the Sequence Number field of the MHR + * of the outgoing frame and then increment it by one. [1] pg. 40. + */ + + frame->io_data[2] = priv->dsn++; + + /* The MAC header we just created must never have exceeded where the app + * data starts. This should never happen since the offset should have + * been set via the same logic to calculate the header length as the logic + * here that created the header + */ + + DEBUGASSERT(mhr_len == frame->io_offset); + + frame->io_offset = 0; /* Set the offset to 0 to include the header */ + + /* Allocate the txdesc, waiting if necessary, allow interruptions */ + + ret = mac802154_txdesc_alloc(priv, &txdesc, true); + if (ret < 0) + { + return ret; + } + + txdesc->conf->handle = meta->msdu_handle; + txdesc->frame = frame; + txdesc->frametype = IEEE802154_FRAME_DATA; + + /* If the TxOptions parameter specifies that a GTS transmission is required, + * the MAC sublayer will determine whether it has a valid GTS as described + * 5.1.7.3. If a valid GTS could not be found, the MAC sublayer will discard + * the MSDU. If a valid GTS was found, the MAC sublayer will defer, if + * necessary, until the GTS. If the TxOptions parameter specifies that a GTS + * transmission is not required, the MAC sublayer will transmit the MSDU using + * either slotted CSMA-CA in the CAP for a beacon-enabled PAN or unslotted + * CSMA-CA for a nonbeacon-enabled PAN. Specifying a GTS transmission in the + * TxOptions parameter overrides an indirect transmission request. + * [1] pg. 118. + */ + + if (meta->msdu_flags.gts_tx) + { + /* TODO: Support GTS transmission. This should just change where we link + * the transaction. Instead of going in the CSMA transaction list, it + * should be linked to the GTS' transaction list. We'll need to check if + * the GTS is valid, and then find the GTS, before linking. Note, we also + * don't have to try and kick-off any transmission here. + */ + + /* We no longer need to have the MAC layer locked. */ + + mac802154_givesem(&priv->exclsem); + + return -ENOTSUP; + } + else + { + /* If the TxOptions parameter specifies that an indirect transmission is + * required and this primitive is received by the MAC sublayer of a + * coordinator, the data frame is sent using indirect transmission, as + * described in 5.1.5 and 5.1.6.3. [1] + */ + + if (meta->msdu_flags.indirect_tx) + { + /* If the TxOptions parameter specifies that an indirect transmission + * is required and if the device receiving this primitive is not a + * coordinator, the destination address is not present, or the + * TxOptions parameter also specifies a GTS transmission, the indirect + * transmission option will be ignored. [1] + * + * NOTE: We don't just ignore the parameter. Instead, we throw an + * error, since this really shouldn't be happening. + */ + + if (priv->devmode >= IEEE802154_DEVMODE_COORD && + meta->destaddr.mode != IEEE802154_ADDRMODE_NONE) + { + /* Copy in a reference to the destination address to assist in + * searching when data is requested. + */ + + memcpy(&txdesc->destaddr, &meta->destaddr, + sizeof(struct ieee802154_addr_s)); + mac802154_setupindirect(priv, txdesc); + mac802154_givesem(&priv->exclsem); + } + else + { + mac802154_givesem(&priv->exclsem); + return -EINVAL; + } + } + else + { + /* Link the transaction into the CSMA transaction list */ + + sq_addlast((FAR sq_entry_t *)txdesc, &priv->csma_queue); + + /* We no longer need to have the MAC layer locked. */ + + mac802154_givesem(&priv->exclsem); + + /* Notify the radio driver that there is data available */ + + priv->radio->txnotify(priv->radio, false); + } + } + + return OK; +} + +/**************************************************************************** + * Internal MAC Functions + ****************************************************************************/ diff --git a/wireless/ieee802154/mac802154_data.h b/wireless/ieee802154/mac802154_data.h new file mode 100644 index 00000000000..c1514a6e142 --- /dev/null +++ b/wireless/ieee802154/mac802154_data.h @@ -0,0 +1,64 @@ +/**************************************************************************** + * wireless/ieee802154/mac802154_data.h + * + * Copyright (C) 2017 Verge Inc. All rights reserved. + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * + * Author: Anthony Merlino + * Author: Gregory Nutt + * + * The naming and comments for various fields are taken directly + * from the IEEE 802.15.4 2011 standard. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __WIRELESS_IEEE802154__MAC802154_DATA_H +#define __WIRELESS_IEEE802154__MAC802154_DATA_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Function Prototypes + ****************************************************************************/ + +#endif /* __WIRELESS_IEEE802154__MAC802154_DATA_H */ \ No newline at end of file diff --git a/wireless/ieee802154/mac802154_device.c b/wireless/ieee802154/mac802154_device.c index a41ff240bf6..b03ce94ba85 100644 --- a/wireless/ieee802154/mac802154_device.c +++ b/wireless/ieee802154/mac802154_device.c @@ -115,7 +115,7 @@ struct mac802154_chardevice_s bool readpending; /* Is there a read using the semaphore? */ sem_t readsem; /* Signaling semaphore for waiting read */ - sq_queue_t dataind_queue; + sq_queue_t dataind_queue; #ifndef CONFIG_DISABLE_SIGNALS /* MAC Service notification information */ @@ -254,7 +254,7 @@ static inline FAR struct ieee802154_notif_s * { dev->event_head = NULL; } - + notif->flink = NULL; } @@ -406,7 +406,7 @@ static int mac802154dev_close(FAR struct file *filep) /* If there are now no open instances of the driver and a signal handler is * not registered, purge the list of events. */ - + if (dev->md_open) { FAR struct ieee802154_notif_s *notif; @@ -474,7 +474,7 @@ static ssize_t mac802154dev_read(FAR struct file *filep, FAR char *buffer, /* Try popping a data indication off the list */ ind = (FAR struct ieee802154_data_ind_s *)sq_remfirst(&dev->dataind_queue); - + /* If the indication is not null, we can exit the loop and copy the data */ if (ind != NULL) @@ -483,8 +483,8 @@ static ssize_t mac802154dev_read(FAR struct file *filep, FAR char *buffer, break; } - /* If this is a non-blocking call, or if there is another read operation - * already pending, don't block. This driver returns EAGAIN even when + /* If this is a non-blocking call, or if there is another read operation + * already pending, don't block. This driver returns EAGAIN even when * configured as non-blocking if another read operation is already pending * This situation should be rare. It will only occur when there are 2 calls * to read from separate threads and there was no data in the rx list. @@ -500,7 +500,7 @@ static ssize_t mac802154dev_read(FAR struct file *filep, FAR char *buffer, mac802154dev_givesem(&dev->md_exclsem); /* Wait to be signaled when a frame is added to the list */ - + if (sem_wait(&dev->readsem) < 0) { DEBUGASSERT(errno == EINTR); @@ -512,18 +512,18 @@ static ssize_t mac802154dev_read(FAR struct file *filep, FAR char *buffer, * time, it should have a data indication */ } - + rx->length = (ind->frame->io_len - ind->frame->io_offset); /* Copy the data from the IOB to the user supplied struct */ memcpy(&rx->payload[0], &ind->frame->io_data[ind->frame->io_offset], - rx->length); + rx->length); memcpy(&rx->meta, ind, sizeof(struct ieee802154_data_ind_s)); /* Zero out the forward link and IOB reference */ - + rx->meta.flink = NULL; rx->meta.frame = NULL; @@ -600,6 +600,7 @@ static ssize_t mac802154dev_write(FAR struct file *filep, ret = mac802154_req_data(dev->md_mac, &tx->meta, iob); if (ret < 0) { + iob_free(iob); wlerr("ERROR: req_data failed %d\n", ret); return ret; } @@ -616,7 +617,7 @@ static ssize_t mac802154dev_write(FAR struct file *filep, ****************************************************************************/ static int mac802154dev_ioctl(FAR struct file *filep, int cmd, - unsigned long arg) + unsigned long arg) { FAR struct inode *inode; FAR struct mac802154_chardevice_s *dev; @@ -697,11 +698,10 @@ static int mac802154dev_ioctl(FAR struct file *filep, int cmd, /* Free the notification */ mac802154_notif_free(dev->md_mac, notif); - ret = OK; break; } - + /* If this is a non-blocking call, or if there is another getevent * operation already pending, don't block. This driver returns * EAGAIN even when configured as non-blocking if another getevent @@ -741,7 +741,7 @@ static int mac802154dev_ioctl(FAR struct file *filep, int cmd, } } break; - + case MAC802154IOC_ENABLE_EVENTS: { dev->enableevents = (bool)arg; @@ -752,7 +752,7 @@ static int mac802154dev_ioctl(FAR struct file *filep, int cmd, default: { /* Forward any unrecognized commands to the MAC layer */ - + ret = mac802154_ioctl(dev->md_mac, cmd, arg); } break; @@ -783,7 +783,7 @@ static void mac802154dev_notify(FAR const struct mac802154_maccb_s *maccb, * notifications. */ - if (dev->enableevents && (dev->md_open != NULL || dev->notify_registered)) + if (dev->enableevents && (dev->md_open != NULL || dev->notify_registered)) { mac802154dev_pushevent(dev, notif); @@ -797,7 +797,7 @@ static void mac802154dev_notify(FAR const struct mac802154_maccb_s *maccb, sem_post(&dev->geteventsem); } -#ifndef CONFIG_DISABLE_SIGNALS +#ifndef CONFIG_DISABLE_SIGNALS if (dev->notify_registered) { @@ -810,7 +810,7 @@ static void mac802154dev_notify(FAR const struct mac802154_maccb_s *maccb, (FAR void *)notif->notiftype); #endif } -#endif +#endif } else { @@ -854,7 +854,7 @@ static void mac802154dev_rxframe(FAR const struct mac802154_maccb_s *maccb, dev->readpending = false; sem_post(&dev->readsem); } - + /* Release the driver */ mac802154dev_givesem(&dev->md_exclsem); @@ -901,7 +901,7 @@ int mac802154dev_register(MACHANDLE mac, int minor) dev->md_mac = mac; sem_init(&dev->md_exclsem, 0, 1); /* Allow the device to be opened once * before blocking */ - + sem_init(&dev->readsem, 0, 0); sem_setprotocol(&dev->readsem, SEM_PRIO_NONE); dev->readpending = false; diff --git a/wireless/ieee802154/mac802154_disassoc.c b/wireless/ieee802154/mac802154_disassoc.c new file mode 100644 index 00000000000..ab5a7450685 --- /dev/null +++ b/wireless/ieee802154/mac802154_disassoc.c @@ -0,0 +1,79 @@ +/**************************************************************************** + * wireless/ieee802154/mac802154_disassoc.c + * + * Copyright (C) 2016 Sebastien Lorquet. All rights reserved. + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * Copyright (C) 2017 Verge Inc. All rights reserved. + * + * Author: Sebastien Lorquet + * Author: Gregory Nutt + * Author: Anthony Merlino + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "mac802154.h" + +#include + +/**************************************************************************** + * Public MAC Functions + ****************************************************************************/ + +/**************************************************************************** + * 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 mac802154_maccb_s->conf_disassociate callback. + * + ****************************************************************************/ + +int mac802154_req_disassociate(MACHANDLE mac, + FAR struct ieee802154_disassoc_req_s *req) +{ + FAR struct ieee802154_privmac_s *priv = + (FAR struct ieee802154_privmac_s *)mac; + return -ENOTTY; +} \ No newline at end of file diff --git a/wireless/ieee802154/mac802154_get_mhrlen.c b/wireless/ieee802154/mac802154_get_mhrlen.c new file mode 100644 index 00000000000..63f6f49455d --- /dev/null +++ b/wireless/ieee802154/mac802154_get_mhrlen.c @@ -0,0 +1,135 @@ +/**************************************************************************** + * wireless/ieee802154/mac802154_get_mhrlen.c + * + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * Copyright (C) 2017 Verge Inc. All rights reserved. + * + * Author: Gregory Nutt + * Author: Anthony Merlino + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "mac802154.h" +#include "mac802154_internal.h" + +#include + +/**************************************************************************** + * Public MAC Functions + ****************************************************************************/ + +/**************************************************************************** + * 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) +{ + FAR struct ieee802154_privmac_s *priv = + (FAR struct ieee802154_privmac_s *)mac; + int ret = 3; /* Always frame control (2 bytes) and seq. num (1 byte) */ + + /* Check to make sure both the dest address and the source address are not set + * to NONE */ + + if (meta->destaddr.mode == IEEE802154_ADDRMODE_NONE && + meta->srcaddr_mode == IEEE802154_ADDRMODE_NONE) + { + return -EINVAL; + } + + /* The source address can only be set to NONE if the device is the PAN coord */ + + if (meta->srcaddr_mode == IEEE802154_ADDRMODE_NONE && + priv->devmode != IEEE802154_DEVMODE_PANCOORD) + { + return -EINVAL; + } + + /* Add the destination address length */ + + ret += mac802154_addr_length[meta->destaddr.mode]; + + /* Add the source address length */ + + ret += mac802154_addr_length[ meta->srcaddr_mode]; + + /* If both destination and source addressing information is present, the MAC + * sublayer shall compare the destination and source PAN identifiers. + * [1] pg. 41. + */ + + if (meta->srcaddr_mode != IEEE802154_ADDRMODE_NONE && + meta->destaddr.mode != IEEE802154_ADDRMODE_NONE) + { + /* If the PAN identifiers are identical, the PAN ID Compression field + * shall be set to one, and the source PAN identifier shall be omitted + * from the transmitted frame. [1] pg. 41. + */ + + if (meta->destaddr.panid == priv->addr.panid) + { + ret += 2; /* 2 bytes for destination PAN ID */ + return ret; + } + } + + /* If we are here, PAN ID compression is off, so include the dest and source + * PAN ID if the respective address is included + */ + + if (meta->srcaddr_mode != IEEE802154_ADDRMODE_NONE) + { + ret += 2; /* 2 bytes for source PAN ID */ + } + + if (meta->destaddr.mode != IEEE802154_ADDRMODE_NONE) + { + ret += 2; /* 2 bytes for destination PAN ID */ + } + + return ret; +} diff --git a/wireless/ieee802154/mac802154_getset.c b/wireless/ieee802154/mac802154_getset.c new file mode 100644 index 00000000000..0173d409116 --- /dev/null +++ b/wireless/ieee802154/mac802154_getset.c @@ -0,0 +1,181 @@ +/**************************************************************************** + * wireless/ieee802154/mac802154_getset.c + * + * Copyright (C) 2016 Sebastien Lorquet. All rights reserved. + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * Copyright (C) 2017 Verge Inc. All rights reserved. + * + * Author: Sebastien Lorquet + * Author: Gregory Nutt + * Author: Anthony Merlino + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "mac802154.h" +#include "mac802154_internal.h" + +#include + +/**************************************************************************** + * Public MAC Functions + ****************************************************************************/ + +/**************************************************************************** + * 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_attr_e attr, + FAR union ieee802154_attr_u *attrval) +{ + FAR struct ieee802154_privmac_s *priv = + (FAR struct ieee802154_privmac_s *)mac; + int ret = IEEE802154_STATUS_SUCCESS; + + switch (attr) + { + case IEEE802154_ATTR_MAC_PANID: + attrval->mac.panid = priv->addr.panid; + break; + case IEEE802154_ATTR_MAC_SHORT_ADDRESS: + attrval->mac.saddr = priv->addr.saddr; + break; + case IEEE802154_ATTR_MAC_EXTENDED_ADDR: + memcpy(&attrval->mac.eaddr[0], &priv->addr.eaddr[0], IEEE802154_EADDR_LEN); + break; + case IEEE802154_ATTR_MAC_DEVMODE: + attrval->mac.devmode = priv->devmode; + break; + default: + /* The attribute may be handled soley in the radio driver, so pass + * it along. + */ + + ret = priv->radio->set_attr(priv->radio, attr, attrval); + break; + } + + return ret; +} + +/**************************************************************************** + * 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_attr_e attr, + FAR const union ieee802154_attr_u *attrval) +{ + FAR struct ieee802154_privmac_s *priv = + (FAR struct ieee802154_privmac_s *)mac; + int ret; + + switch (attr) + { + case IEEE802154_ATTR_MAC_PANID: + { + priv->addr.panid = attrval->mac.panid; + + /* Tell the radio about the attribute */ + + priv->radio->set_attr(priv->radio, attr, attrval); + + ret = IEEE802154_STATUS_SUCCESS; + } + break; + case IEEE802154_ATTR_MAC_SHORT_ADDRESS: + { + priv->addr.saddr = attrval->mac.saddr; + + /* Tell the radio about the attribute */ + + priv->radio->set_attr(priv->radio, attr, attrval); + + ret = IEEE802154_STATUS_SUCCESS; + } + break; + case IEEE802154_ATTR_MAC_EXTENDED_ADDR: + { + /* Set the MAC copy of the address in the table */ + + memcpy(&priv->addr.eaddr[0], &attrval->mac.eaddr[0], + IEEE802154_EADDR_LEN); + + /* Tell the radio about the attribute */ + + priv->radio->set_attr(priv->radio, attr, attrval); + + ret = IEEE802154_STATUS_SUCCESS; + } + break; + default: + { + /* The attribute may be handled soley in the radio driver, so pass + * it along. + */ + + ret = priv->radio->set_attr(priv->radio, attr, attrval); + } + break; + } + return ret; +} \ No newline at end of file diff --git a/wireless/ieee802154/mac802154_gts.c b/wireless/ieee802154/mac802154_gts.c new file mode 100644 index 00000000000..e24e409f81c --- /dev/null +++ b/wireless/ieee802154/mac802154_gts.c @@ -0,0 +1,72 @@ +/**************************************************************************** + * wireless/ieee802154/mac802154_gts.c + * + * Copyright (C) 2017 Verge Inc. All rights reserved. + * Author: Anthony Merlino + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "mac802154.h" + +#include + +/**************************************************************************** + * Public MAC Functions + ****************************************************************************/ + +/**************************************************************************** + * 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 mac802154_maccb_s->conf_gts callback. + * + ****************************************************************************/ + +int mac802154_req_gts(MACHANDLE mac, FAR struct ieee802154_gts_req_s *req) +{ + FAR struct ieee802154_privmac_s *priv = + (FAR struct ieee802154_privmac_s *)mac; + return -ENOTTY; +} \ No newline at end of file diff --git a/wireless/ieee802154/mac802154_internal.h b/wireless/ieee802154/mac802154_internal.h new file mode 100644 index 00000000000..fc85d7a009a --- /dev/null +++ b/wireless/ieee802154/mac802154_internal.h @@ -0,0 +1,405 @@ +/**************************************************************************** + * wireless/ieee802154/mac802154_internal.h + * + * Copyright (C) 2016 Sebastien Lorquet. All rights reserved. + * Copyright (C) 2017 Verge Inc. All rights reserved. + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * + * Author: Sebastien Lorquet + * Author: Anthony Merlino + * + * The naming and comments for various fields are taken directly + * from the IEEE 802.15.4 2011 standard. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __WIRELESS_IEEE802154__MAC802154_INTERNAL_H +#define __WIRELESS_IEEE802154__MAC802154_INTERNAL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "mac802154_notif.h" + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* If processing is not done at the interrupt level, then work queue support + * is required. + */ + +#if !defined(CONFIG_SCHED_WORKQUEUE) +# error Work queue support is required in this configuration (CONFIG_SCHED_WORKQUEUE) +#else + + /* Use the low priority work queue if possible */ + +# if defined(CONFIG_MAC802154_HPWORK) +# define MAC802154_WORK HPWORK +# elif defined(CONFIG_MAC802154_LPWORK) +# define MAC802154_WORK LPWORK +# else +# error Neither CONFIG_MAC802154_HPWORK nor CONFIG_MAC802154_LPWORK defined +# endif +#endif + +#if !defined(CONFIG_MAC802154_NNOTIF) || CONFIG_MAC802154_NNOTIF <= 0 +# undef CONFIG_MAC802154_NNOTIF +# define CONFIG_MAC802154_NNOTIF 6 +#endif + +#if !defined(CONFIG_MAC802154_NTXDESC) || CONFIG_MAC802154_NTXDESC <= 0 +# undef CONFIG_MAC802154_NTXDESC +# define CONFIG_MAC802154_NTXDESC 3 +#endif + +#if CONFIG_MAC802154_NTXDESC > CONFIG_MAC802154_NNOTIF +#error CONFIG_MAC802154_NNOTIF must be greater than CONFIG_MAC802154_NTXDESC +#endif + +#if !defined(CONFIG_IEEE802154_DEFAULT_EADDR) +#define CONFIG_IEEE802154_DEFAULT_EADDR 0xFFFFFFFFFFFFFFFF +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Map between ieee802154_addrmode_e enum and actual address length */ + +static const uint8_t mac802154_addr_length[4] = {0, 0, 2, 8}; + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct mac802154_radiocb_s +{ + struct ieee802154_radiocb_s cb; + FAR struct ieee802154_privmac_s *priv; +}; + +/* Enumeration for representing what operation the MAC layer is currently doing. + * There can only be one command being handled at any given time, but certain + * operations such as association requires more than one command to be sent. + * Therefore, the need to track not only what command is currently active, but + * also, what overall operation the command is apart of is necessary. + */ + +enum mac802154_operation_e +{ + MAC802154_OP_NONE, + MAC802154_OP_ASSOC, + MAC802154_OP_POLL +}; + +struct ieee802154_privmac_s; /* Forward Reference */ +typedef void (*mac802154_worker_t)(FAR struct ieee802154_privmac_s *priv); + +/* The privmac structure holds the internal state of the MAC and is the + * underlying represention of the opaque MACHANDLE. It contains storage for + * the IEEE802.15.4 MIB attributes. + */ + +struct ieee802154_privmac_s +{ + FAR struct ieee802154_radio_s *radio; /* Contained IEEE802.15.4 radio dev */ + FAR const struct mac802154_maccb_s *cb; /* Contained MAC callbacks */ + FAR struct mac802154_radiocb_s radiocb; /* Interface to bind to radio */ + + sem_t exclsem; /* Support exclusive access */ + + /* Only support a single command at any given time. As of now I see no + * condition where you need to have more than one command frame simultaneously + */ + + sem_t op_sem; /* Exclusive operations */ + enum mac802154_operation_e curr_op; /* The current overall operation */ + enum ieee802154_cmdid_e curr_cmd; /* Type of the current cmd */ + FAR struct ieee802154_txdesc_s *cmd_desc; /* TX descriptor for current cmd */ + + /* Pre-allocated notifications to be passed to the registered callback. These + * need to be freed by the application using mac802154_xxxxnotif_free when + * the callee layer is finished with it's use. + */ + + FAR struct mac802154_notif_s *notif_free; + struct mac802154_notif_s notif_pool[CONFIG_MAC802154_NNOTIF]; + sem_t notif_sem; + + struct ieee802154_txdesc_s txdesc_pool[CONFIG_IEEE802154_NTXDESC]; + sem_t txdesc_sem; + sq_queue_t txdesc_queue; + sq_queue_t txdone_queue; + + + /* Support a singly linked list of transactions that will be sent using the + * CSMA algorithm. On a non-beacon enabled PAN, these transactions will be + * sent whenever. On a beacon-enabled PAN, these transactions will be sent + * during the CAP of the Coordinator's superframe. + */ + + sq_queue_t csma_queue; + sq_queue_t gts_queue; + + /* Support a singly linked list of transactions that will be sent indirectly. + * This list should only be used by a MAC acting as a coordinator. These + * transactions will stay here until the data is extracted by the destination + * device sending a Data Request MAC command or if too much time passes. This + * list should also be used to populate the address list of the outgoing + * beacon frame. + */ + + sq_queue_t indirect_queue; + + /* Support a singly linked list of frames received */ + + sq_queue_t dataind_queue; + + /* Work structures for offloading aynchronous work */ + + struct work_s tx_work; + struct work_s rx_work; + + struct work_s timeout_work; + WDOG_ID timeout; /* Timeout watchdog */ + mac802154_worker_t timeout_worker; + + struct work_s purge_work; + + /* MAC PIB attributes, grouped to save memory */ + + /* Holds all address information (Extended, Short, and PAN ID) for the MAC. */ + + struct ieee802154_addr_s addr; + + /* Holds all address information (Extended, Short) for Coordinator */ + + struct ieee802154_addr_s coordaddr; + + /* The maximum number of symbols to wait for an acknowledgement frame to + * arrive following a transmitted data frame. [1] pg. 126 + * + * NOTE: This may be able to be a 16-bit or even an 8-bit number. I wasn't + * sure at the time what the range of reasonable values was. + */ + + uint32_t ack_waitdur; + + /* The maximum time to wait either for a frame intended as a response to a + * data request frame or for a broadcast frame following a beacon with the + * Frame Pending field set to one. [1] pg. 127 + * + * NOTE: This may be able to be a 16-bit or even an 8-bit number. I wasn't + * sure at the time what the range of reasonable values was. + */ + + uint32_t max_frame_waittime; + + /* The maximum time (in unit periods) that a transaction is stored by a + * coordinator and indicated in its beacon. + */ + + uint16_t trans_persisttime; + + /* Contents of beacon payload */ + + uint8_t beacon_payload[IEEE802154_MAX_BEACON_PAYLOAD_LEN]; + uint8_t beacon_payload_len; /* Length of beacon payload */ + + uint8_t battlifeext_periods; /* # of backoff periods during which rx is + * enabled after the IFS following beacon */ + + uint8_t bsn; /* Seq. num added to tx beacon frame */ + uint8_t dsn; /* Seq. num added to tx data or MAC frame */ + uint8_t maxretries; /* Max # of retries alloed after tx failure */ + + /* The maximum time, in multiples of aBaseSuperframeDuration, a device shall + * wait for a response command frame to be available following a request + * command frame. [1] 128. + */ + + uint8_t resp_waittime; + + /* The total transmit duration (including PHY header and FCS) specified in + * symbols. [1] pg. 129. + */ + + uint32_t tx_totaldur; + + /* Start of 32-bit bitfield */ + + uint32_t trackingbeacon : 1; /* Are we tracking the beacon */ + uint32_t isassoc : 1; /* Are we associated to the PAN */ + uint32_t assocpermit : 1; /* Are we allowing assoc. as a coord. */ + uint32_t autoreq : 1; /* Automatically send data req. if addr + * addr is in the beacon frame */ + + uint32_t battlifeext : 1; /* Is BLE enabled */ + uint32_t gtspermit : 1; /* Is PAN Coord. accepting GTS reqs. */ + uint32_t promisc : 1; /* Is promiscuous mode on? */ + uint32_t rngsupport : 1; /* Does MAC sublayer support ranging */ + uint32_t sec_enabled : 1; /* Does MAC sublayer have security en. */ + uint32_t timestamp_support : 1; /* Does MAC layer supports timestamping */ + + /* 2 available bits */ + + uint32_t beaconorder : 4; /* Freq. that beacon is transmitted */ + + uint32_t superframeorder : 4; /* Length of active portion of outgoing + * superframe, including the beacon */ + + /* The offset, measured is symbols, between the symbol boundary at which the + * MLME captures the timestamp of each transmitted and received frame, and + * the onset of the first symbol past the SFD, namely the first symbol of + * the frames [1] pg. 129. + */ + + uint32_t sync_symboffset : 12; + + /* End of 32-bit bitfield */ + + /* Start of 32-bit bitfield */ + + uint32_t beacon_txtime : 24; /* Time of last beacon transmit */ + uint32_t minbe : 4; /* Min value of backoff exponent (BE) */ + uint32_t maxbe : 4; /* Max value of backoff exponent (BE) */ + + /* End of 32-bit bitfield */ + + /* Start of 32-bit bitfield */ + + uint32_t txctrl_activedur : 17; /* Duration for which tx is permitted to + * be active */ + uint32_t txctrl_pausedur : 1; /* Duration after tx before another tx is + * permitted. 0=2000, 1= 10000 */ + + /* What type of device is this node acting as */ + + enum ieee802154_devmode_e devmode : 2; + + uint32_t max_csmabackoffs : 3; /* Max num backoffs for CSMA algorithm + * before declaring ch access failure */ + + /* 9-bits remaining */ + + /* End of 32-bit bitfield. */ + + /* TODO: Add Security-related MAC PIB attributes */ +}; + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#define mac802154_givesem(s) sem_post(s); + +static inline int mac802154_takesem(sem_t *sem, bool allowinterrupt) +{ + int ret; + do + { + /* Take a count from the semaphore, possibly waiting */ + + ret = sem_wait(sem); + if (ret < 0) + { + /* EINTR is the only error that we expect */ + + DEBUGASSERT(get_errno() == EINTR); + + if (allowinterrupt) + { + return -EINTR; + } + } + } + while (ret != OK); + + return OK; +} + +static inline void mac802154_txdesc_free(FAR struct ieee802154_privmac_s *priv, + FAR struct ieee802154_txdesc_s *txdesc) +{ + sq_addlast((FAR sq_entry_t *)txdesc, &priv->txdesc_queue); + mac802154_givesem(&priv->txdesc_sem); +} + +/**************************************************************************** + * Name: mac802154_timercancel + * + * Description: + * Cancel timer and remove reference to callback function + * + * Assumptions: + * priv MAC struct is locked when calling. + * + ****************************************************************************/ + +static inline int mac802154_timercancel(FAR struct ieee802154_privmac_s *priv) +{ + wd_cancel(priv->timeout); + priv->timeout_worker = NULL; + return OK; +} + +/**************************************************************************** + * Function Prototypes + ****************************************************************************/ + + +int mac802154_txdesc_alloc(FAR struct ieee802154_privmac_s *priv, + FAR struct ieee802154_txdesc_s **txdesc, + bool allow_interrupt); + +int mac802154_timerstart(FAR struct ieee802154_privmac_s *priv, + uint32_t numsymbols, mac802154_worker_t); + +void mac802154_setupindirect(FAR struct ieee802154_privmac_s *priv, + FAR struct ieee802154_txdesc_s *txdesc); + +#endif /* __WIRELESS_IEEE802154__MAC802154_INTERNAL_H */ diff --git a/wireless/ieee802154/mac802154_ioctl.c b/wireless/ieee802154/mac802154_ioctl.c new file mode 100644 index 00000000000..35093f69361 --- /dev/null +++ b/wireless/ieee802154/mac802154_ioctl.c @@ -0,0 +1,169 @@ +/**************************************************************************** + * wireless/ieee802154/mac802154_ioctl.c + * + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * Copyright (C) 2017 Verge Inc. All rights reserved. + * + * Author: Gregory Nutt + * Author: Anthony Merlino + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "mac802154.h" + +#include + +/**************************************************************************** + * Public MAC Functions + ****************************************************************************/ + +/**************************************************************************** + * 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) +{ + FAR struct ieee802154_privmac_s *priv = + (FAR struct ieee802154_privmac_s *)mac; + int ret = -EINVAL; + + FAR union ieee802154_macarg_u *macarg = + (FAR union ieee802154_macarg_u *)((uintptr_t)arg); + + DEBUGASSERT(priv != NULL); + + /* Check for IOCTLs aimed at the IEEE802.15.4 MAC layer */ + + if (_MAC802154IOCVALID(cmd)) + { + /* Handle the MAC IOCTL command */ + + switch (cmd) + { + case MAC802154IOC_MLME_ASSOC_REQUEST: + { + ret = mac802154_req_associate(mac, &macarg->assocreq); + } + break; + case MAC802154IOC_MLME_ASSOC_RESPONSE: + { + ret = mac802154_resp_associate(mac, &macarg->assocresp); + } + break; + case MAC802154IOC_MLME_DISASSOC_REQUEST: + { + ret = mac802154_req_disassociate(mac, &macarg->disassocreq); + } + break; + case MAC802154IOC_MLME_GET_REQUEST: + { + ret = mac802154_req_get(mac, macarg->getreq.attr, + &macarg->getreq.attrval); + } + break; + case MAC802154IOC_MLME_GTS_REQUEST: + { + ret = mac802154_req_gts(mac, &macarg->gtsreq); + } + break; + case MAC802154IOC_MLME_ORPHAN_RESPONSE: + { + ret = mac802154_resp_orphan(mac, &macarg->orphanresp); + } + break; + case MAC802154IOC_MLME_RESET_REQUEST: + { + ret = mac802154_req_reset(mac, macarg->resetreq.rst_pibattr); + } + break; + case MAC802154IOC_MLME_RXENABLE_REQUEST: + { + ret = mac802154_req_rxenable(mac, &macarg->rxenabreq); + } + break; + case MAC802154IOC_MLME_SCAN_REQUEST: + { + ret = mac802154_req_scan(mac, &macarg->scanreq); + } + break; + case MAC802154IOC_MLME_SET_REQUEST: + { + ret = mac802154_req_set(mac, macarg->setreq.attr, + &macarg->setreq.attrval); + } + break; + case MAC802154IOC_MLME_START_REQUEST: + { + ret = mac802154_req_start(mac, &macarg->startreq); + } + break; + case MAC802154IOC_MLME_SYNC_REQUEST: + { + ret = mac802154_req_sync(mac, &macarg->syncreq); + } + break; + case MAC802154IOC_MLME_POLL_REQUEST: + { + ret = mac802154_req_poll(mac, &macarg->pollreq); + } + break; + default: + wlerr("ERROR: Unrecognized cmd: %d\n", cmd); + ret = -ENOTTY; + break; + } + } + return ret; +} + diff --git a/wireless/ieee802154/mac802154_notif.c b/wireless/ieee802154/mac802154_notif.c new file mode 100644 index 00000000000..15368a5483b --- /dev/null +++ b/wireless/ieee802154/mac802154_notif.c @@ -0,0 +1,208 @@ +/**************************************************************************** + * wireless/ieee802154/mac802154_notif.c + * + * Copyright (C) 2016 Sebastien Lorquet. All rights reserved. + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * Copyright (C) 2017 Verge Inc. All rights reserved. + * + * Author: Sebastien Lorquet + * Author: Gregory Nutt + * Author: Anthony Merlino + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "mac802154.h" +#include "mac802154_internal.h" + +#include + +/**************************************************************************** + * Public MAC Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mac802154_notif_free + * + * Description: + * When the MAC calls the registered callback, it passes a reference + * to a mac802154_notify_s structure. This structure needs to be freed + * after the callback handler is done using it. + * + ****************************************************************************/ + +int mac802154_notif_free(MACHANDLE mac, + FAR struct ieee802154_notif_s *notif) +{ + FAR struct ieee802154_privmac_s *priv = + (FAR struct ieee802154_privmac_s *)mac; + FAR struct mac802154_notif_s *privnotif = (FAR struct mac802154_notif_s *)notif; + + /* Get exclusive access to the MAC */ + + mac802154_takesem(&priv->exclsem, false); + + privnotif->flink = priv->notif_free; + priv->notif_free = privnotif; + mac802154_givesem(&priv->notif_sem); + + mac802154_givesem(&priv->exclsem); + + return -ENOTTY; +} + +/**************************************************************************** + * Internal MAC Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mac802154_notifpool_init + * + * Description: + * This function initializes the notification structure pool. It allows the + * MAC to pass notifications and for the callee to free them when they are + * done using them, saving copying the data when passing. + * + ****************************************************************************/ + +void mac802154_notifpool_init(FAR struct ieee802154_privmac_s *priv) +{ + FAR struct mac802154_notif_s *pool = priv->notif_pool; + int remaining = CONFIG_MAC802154_NNOTIF; + + priv->notif_free = NULL; + while (remaining > 0) + { + FAR struct mac802154_notif_s *notif = pool; + + /* Add the next meta data structure from the pool to the list of + * general structures. + */ + + notif->flink = priv->notif_free; + priv->notif_free = notif; + + /* Set up for the next structure from the pool */ + + pool++; + remaining--; + } + sem_init(&priv->notif_sem, 0, CONFIG_MAC802154_NNOTIF); +} + +/**************************************************************************** + * Name: mac802154_notif_alloc + * + * Description: + * This function allocates a free notification structure from the free list + * to be used for passing to the registered notify callback. The callee software + * is responsible for freeing the notification structure after it is done using + * it via mac802154_notif_free. + * + * Assumptions: + * priv MAC struct is locked when calling. + * + * Notes: + * If any of the semaphore waits inside this function get interrupted, the + * function will release the MAC layer. If this function returns -EINTR, the + * calling code should NOT release the MAC semaphore. + * + ****************************************************************************/ + +int mac802154_notif_alloc(FAR struct ieee802154_privmac_s *priv, + FAR struct ieee802154_notif_s **notif, + bool allow_interrupt) +{ + int ret; + FAR struct mac802154_notif_s *privnotif; + + /* Try and take a count from the semaphore. If this succeeds, we have + * "reserved" the structure, but still need to unlink it from the free list. + * The MAC is already locked, so there shouldn't be any other conflicting calls + */ + + ret = sem_trywait(&priv->notif_sem); + + if (ret == OK) + { + privnotif = priv->notif_free; + priv->notif_free = privnotif->flink; + } + else + { + /* Unlock MAC so that other work can be done to free a notification */ + + mac802154_givesem(&priv->exclsem); + + /* Take a count from the notification semaphore, waiting if necessary. We + * only return from here with an error if we are allowing interruptions + * and we received a signal */ + + ret = mac802154_takesem(&priv->notif_sem, allow_interrupt); + if (ret < 0) + { + /* MAC sem is already released */ + + return -EINTR; + } + + /* If we've taken a count from the semaphore, we have "reserved" the struct + * but now we need to pop it off of the free list. We need to re-lock the + * MAC in order to ensure this happens correctly. + */ + + ret = mac802154_takesem(&priv->exclsem, allow_interrupt); + if (ret < 0) + { + mac802154_givesem(&priv->notif_sem); + return -EINTR; + } + + /* We can now safely unlink the next free structure from the free list */ + + privnotif = priv->notif_free; + priv->notif_free = privnotif->flink; + } + + *notif = (FAR struct ieee802154_notif_s *)privnotif; + + return OK; +} \ No newline at end of file diff --git a/wireless/ieee802154/mac802154_notif.h b/wireless/ieee802154/mac802154_notif.h new file mode 100644 index 00000000000..3cf088163db --- /dev/null +++ b/wireless/ieee802154/mac802154_notif.h @@ -0,0 +1,82 @@ +/**************************************************************************** + * wireless/ieee802154/mac802154_notif.h + * + * Copyright (C) 2017 Verge Inc. All rights reserved. + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * + * Author: Anthony Merlino + * Author: Gregory Nutt + * + * The naming and comments for various fields are taken directly + * from the IEEE 802.15.4 2011 standard. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __WIRELESS_IEEE802154__MAC802154_NOTIF_H +#define __WIRELESS_IEEE802154__MAC802154_NOTIF_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* Extend the public ieee802154_notif_s to include a private forward link to + * support a list to handle allocation + */ + +struct mac802154_notif_s +{ + struct ieee802154_notif_s pub; + FAR struct mac802154_notif_s *flink; +}; + +/**************************************************************************** + * Function Prototypes + ****************************************************************************/ + +struct ieee802154_privmac_s; /* Forward Reference */ + +void mac802154_notifpool_init(FAR struct ieee802154_privmac_s *priv); + +int mac802154_notif_alloc(FAR struct ieee802154_privmac_s *priv, + FAR struct ieee802154_notif_s **notif, + bool allow_interrupt); + +#endif /* __WIRELESS_IEEE802154__MAC802154_NOTIF_H */ \ No newline at end of file diff --git a/wireless/ieee802154/mac802154_orphan.c b/wireless/ieee802154/mac802154_orphan.c new file mode 100644 index 00000000000..9e4a80d4f23 --- /dev/null +++ b/wireless/ieee802154/mac802154_orphan.c @@ -0,0 +1,71 @@ +/**************************************************************************** + * wireless/ieee802154/mac802154_orphan.c + * + * Copyright (C) 2017 Verge Inc. All rights reserved. + * Author: Anthony Merlino + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "mac802154.h" + +#include + +/**************************************************************************** + * Public MAC Functions + ****************************************************************************/ + +/**************************************************************************** + * 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) +{ + FAR struct ieee802154_privmac_s *priv = + (FAR struct ieee802154_privmac_s *)mac; + return -ENOTTY; +} diff --git a/wireless/ieee802154/mac802154_poll.c b/wireless/ieee802154/mac802154_poll.c new file mode 100644 index 00000000000..377dd104ab7 --- /dev/null +++ b/wireless/ieee802154/mac802154_poll.c @@ -0,0 +1,376 @@ +/**************************************************************************** + * wireless/ieee802154/mac802154_poll.c + * + * Copyright (C) 2016 Sebastien Lorquet. All rights reserved. + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * Copyright (C) 2017 Verge Inc. All rights reserved. + * + * Author: Sebastien Lorquet + * Author: Gregory Nutt + * Author: Anthony Merlino + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include + +#include "mac802154.h" +#include "mac802154_internal.h" + +#include +#include + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static void mac802154_timeout_poll(FAR struct ieee802154_privmac_s *priv); + +/**************************************************************************** + * Public MAC Functions + ****************************************************************************/ + +/**************************************************************************** + * 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 mac802154_maccb_s->conf_poll callback, followed by a + * struct mac802154_maccb_s->ind_data callback. + * + ****************************************************************************/ + +int mac802154_req_poll(MACHANDLE mac, FAR struct ieee802154_poll_req_s *req) +{ + FAR struct ieee802154_privmac_s *priv = + (FAR struct ieee802154_privmac_s *)mac; + FAR struct iob_s *iob; + FAR struct ieee802154_txdesc_s *txdesc; + FAR uint16_t *frame_ctrl; + int ret; + + /* On receipt of the MLME-POLL.request primitive, the MLME requests data from + * the coordinator, as described in 5.1.6.3. If the poll is directed to the + * PAN coordinator, the data request command may be generated without any + * destination address information present. Otherwise, the data request + * command is always generated with the destination address information in the + * CoordPANId and CoordAddress parameters. + */ + + /* Get exlusive access to the operation sempaphore. This must happen before + * getting exclusive access to the MAC struct or else there could be a lockup + * condition. This would occur if another thread is using the cmdtrans but + * needs access to the MAC in order to unlock it. + */ + + ret = mac802154_takesem(&priv->op_sem, true); + if (ret < 0) + { + return ret; + } + + priv->curr_op = MAC802154_OP_POLL; + priv->curr_cmd = IEEE802154_CMD_DATA_REQ; + + /* Get exclusive access to the MAC */ + + ret = mac802154_takesem(&priv->exclsem, true); + if (ret < 0) + { + mac802154_givesem(&priv->op_sem); + return ret; + } + + /* Allocate an IOB to put the frame in */ + + iob = iob_alloc(false); + DEBUGASSERT(iob != NULL); + + iob->io_flink = NULL; + iob->io_len = 0; + iob->io_offset = 0; + iob->io_pktlen = 0; + + /* Allocate the txdesc, waiting if necessary */ + + ret = mac802154_txdesc_alloc(priv, &txdesc, true); + if (ret < 0) + { + iob_free(iob); + mac802154_givesem(&priv->exclsem); + mac802154_givesem(&priv->op_sem); + return ret; + } + + /* Get a uin16_t reference to the first two bytes. ie frame control field */ + + frame_ctrl = (FAR uint16_t *)&iob->io_data[0]; + iob->io_len = 2; + + *frame_ctrl = (IEEE802154_FRAME_COMMAND << IEEE802154_FRAMECTRL_SHIFT_FTYPE); + *frame_ctrl |= IEEE802154_FRAMECTRL_ACKREQ; + + /* Each time a data or a MAC command frame is generated, the MAC sublayer + * shall copy the value of macDSN into the Sequence Number field of the + * MHR of the outgoing frame and then increment it by one. [1] pg. 40. + */ + + iob->io_data[iob->io_len++] = priv->dsn++; + + /* If the destination address is present, copy the PAN ID and one of the + * addresses, depending on mode, into the MHR. + */ + + if (req->coordaddr.mode != IEEE802154_ADDRMODE_NONE) + { + memcpy(&iob->io_data[iob->io_len], &req->coordaddr.panid, 2); + iob->io_len += 2; + + if (req->coordaddr.mode == IEEE802154_ADDRMODE_SHORT) + { + memcpy(&iob->io_data[iob->io_len], &req->coordaddr.saddr, 2); + iob->io_len += 2; + } + else if (req->coordaddr.mode == IEEE802154_ADDRMODE_EXTENDED) + { + memcpy(&iob->io_data[iob->io_len], &req->coordaddr.eaddr, + IEEE802154_EADDR_LEN); + iob->io_len += IEEE802154_EADDR_LEN; + } + } + + *frame_ctrl |= (req->coordaddr.mode << IEEE802154_FRAMECTRL_SHIFT_DADDR); + + + + /* If the PAN identifiers are identical, the PAN ID Compression field + * shall be set to one, and the source PAN identifier shall be omitted + * from the transmitted frame. [1] pg. 41. + */ + + if (req->coordaddr.mode != IEEE802154_ADDRMODE_NONE && + req->coordaddr.panid == priv->addr.panid) + { + *frame_ctrl |= IEEE802154_FRAMECTRL_PANIDCOMP; + } + else + { + memcpy(&iob->io_data[iob->io_len], &priv->addr.panid, 2); + iob->io_len += 2; + } + + /* The Source Addressing Mode field shall be set according to the value of + * macShortAddress. If macShortAddress is less than 0xfffe, short addressing + * shall be used. Extended addressing shall be used otherwise. + */ + + if (priv->addr.saddr == IEEE802154_SADDR_BCAST) + { + *frame_ctrl |= (IEEE802154_ADDRMODE_EXTENDED << IEEE802154_FRAMECTRL_SHIFT_SADDR); + memcpy(&iob->io_data[iob->io_len], &priv->addr.eaddr[0], IEEE802154_EADDR_LEN); + iob->io_len += IEEE802154_EADDR_LEN; + } + else + { + *frame_ctrl |= (IEEE802154_ADDRMODE_SHORT << IEEE802154_FRAMECTRL_SHIFT_SADDR); + memcpy(&iob->io_data[iob->io_len], &priv->addr.saddr, 2); + iob->io_len += 2; + } + + /* Copy in the Command Frame Identifier */ + + iob->io_data[iob->io_len++] = IEEE802154_CMD_DATA_REQ; + + /* Copy the IOB reference to the descriptor */ + + txdesc->frame = iob; + txdesc->frametype = IEEE802154_FRAME_COMMAND; + + /* Save a copy of the destination addressing infromation into the tx descriptor. + * We only do this for commands to help with handling their progession. + */ + + memcpy(&txdesc->destaddr, &req->coordaddr, sizeof(struct ieee802154_addr_s)); + + /* Save a reference of the tx descriptor */ + + priv->cmd_desc = txdesc; + + /* Link the transaction into the CSMA transaction list */ + + sq_addlast((FAR sq_entry_t *)txdesc, &priv->csma_queue); + + /* We no longer need to have the MAC layer locked. */ + + mac802154_givesem(&priv->exclsem); + + /* Notify the radio driver that there is data available */ + + priv->radio->txnotify(priv->radio, false); + + return OK; +} + +/**************************************************************************** + * Internal MAC Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: mac802154_txdone_datareq_poll + * + * Description: + * Handle the completion (success/failure) of transmitting a data request + * command in an effort to extract data from the coordinator triggered by + * a POLL.request from the next highest layer + * + * Assumptions: + * Called with the MAC locked. + * + ****************************************************************************/ + +void mac802154_txdone_datareq_poll(FAR struct ieee802154_privmac_s *priv, + FAR struct ieee802154_txdesc_s *txdesc) +{ + enum ieee802154_status_e status; + FAR struct mac802154_notif_s *privnotif = + (FAR struct mac802154_notif_s *)txdesc->conf; + FAR struct ieee802154_notif_s *notif = &privnotif->pub; + + /* If the data request failed to be sent, notify the next layer + * that the poll has failed. + * OR + * On receipt of the Ack frame with the Frame Pending field set + * to zero, the device shall conclude that there are no data + * pending at the coordinator. [1] pg. 43 + */ + + if (notif->u.dataconf.status != IEEE802154_STATUS_SUCCESS || + txdesc->framepending == 0) + { + if (notif->u.dataconf.status != IEEE802154_STATUS_SUCCESS) + { + status = notif->u.dataconf.status; + } + else + { + status = IEEE802154_STATUS_NO_DATA; + } + + notif->notiftype = IEEE802154_NOTIFY_CONF_POLL; + notif->u.pollconf.status = status; + + /* We are now done the operation, and can release the command */ + + priv->curr_op = MAC802154_OP_NONE; + priv->cmd_desc = NULL; + mac802154_givesem(&priv->op_sem); + + /* Release the MAC, call the callback, get exclusive access again */ + + mac802154_givesem(&priv->exclsem); + priv->cb->notify(priv->cb, notif); + mac802154_takesem(&priv->exclsem, false); + } + else + { + /* On receipt of the acknowledgment frame with the Frame + * Pending field set to one, a device shall enable its + * receiver for at most macMaxFrameTotalWaitTime to receive + * the corresponding data frame from the coordinator. [1] pg.43 + */ + + priv->radio->rxenable(priv->radio, true); + + /* Start a timer, if we receive the data frame, we will cancel + * the timer, otherwise it will expire and we will notify the + * next highest layer of the failure. + */ + + mac802154_timerstart(priv, priv->max_frame_waittime, + mac802154_timeout_poll); + + /* We can deallocate the data conf notification as it is no longer + * needed. We can't use the public function here since we already + * have the MAC locked. + */ + + privnotif->flink = priv->notif_free; + priv->notif_free = privnotif; + } +} + +/**************************************************************************** + * Name: mac802154_timeout_poll + * + * Description: + * Function registered with MAC timer that gets called via the work queue to + * handle a timeout for extracting a response from the Coordinator. + * + ****************************************************************************/ + +static void mac802154_timeout_poll(FAR struct ieee802154_privmac_s *priv) +{ + FAR struct ieee802154_notif_s *notif; + + DEBUGASSERT(priv->curr_op == MAC802154_OP_POLL); + + /* Allocate a notification struct to pass to the next highest layer. + * Don't allow EINTR to interrupt. + */ + + mac802154_takesem(&priv->exclsem, false); + mac802154_notif_alloc(priv, ¬if, false); + + /* We are no longer performing the association operation */ + priv->curr_op = MAC802154_OP_NONE; + priv->cmd_desc = NULL; + mac802154_givesem(&priv->op_sem); + + /* Release the MAC */ + + mac802154_givesem(&priv->exclsem); + + notif->notiftype = IEEE802154_NOTIFY_CONF_POLL; + notif->u.pollconf.status = IEEE802154_STATUS_NO_DATA; + + priv->cb->notify(priv->cb, notif); +} \ No newline at end of file diff --git a/wireless/ieee802154/mac802154_poll.h b/wireless/ieee802154/mac802154_poll.h new file mode 100644 index 00000000000..ceb393023cb --- /dev/null +++ b/wireless/ieee802154/mac802154_poll.h @@ -0,0 +1,66 @@ +/**************************************************************************** + * wireless/ieee802154/mac802154_poll.h + * + * Copyright (C) 2017 Verge Inc. All rights reserved. + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * + * Author: Anthony Merlino + * Author: Gregory Nutt + * + * The naming and comments for various fields are taken directly + * from the IEEE 802.15.4 2011 standard. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __WIRELESS_IEEE802154__MAC802154_POLL_H +#define __WIRELESS_IEEE802154__MAC802154_POLL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +/**************************************************************************** + * Function Prototypes + ****************************************************************************/ + +struct ieee802154_privmac_s; /* Forward Reference */ + +void mac802154_txdone_datareq_poll(FAR struct ieee802154_privmac_s *priv, + FAR struct ieee802154_txdesc_s *txdesc); + +#endif /* __WIRELESS_IEEE802154__MAC802154_POLL_H */ \ No newline at end of file diff --git a/wireless/ieee802154/mac802154_purge.c b/wireless/ieee802154/mac802154_purge.c new file mode 100644 index 00000000000..6073c61f8cc --- /dev/null +++ b/wireless/ieee802154/mac802154_purge.c @@ -0,0 +1,83 @@ +/**************************************************************************** + * wireless/ieee802154/mac802154_purge.c + * + * Copyright (C) 2016 Sebastien Lorquet. All rights reserved. + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * Copyright (C) 2017 Verge Inc. All rights reserved. + * + * Author: Sebastien Lorquet + * Author: Gregory Nutt + * Author: Anthony Merlino + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "mac802154.h" + +#include + +/**************************************************************************** + * Public MAC Functions + ****************************************************************************/ + +/**************************************************************************** + * 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 mac802154_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) +{ + FAR struct ieee802154_privmac_s *priv = + (FAR struct ieee802154_privmac_s *)mac; + return -ENOTTY; +} + diff --git a/wireless/ieee802154/mac802154_reset.c b/wireless/ieee802154/mac802154_reset.c new file mode 100644 index 00000000000..c1115d01db4 --- /dev/null +++ b/wireless/ieee802154/mac802154_reset.c @@ -0,0 +1,159 @@ +/**************************************************************************** + * wireless/ieee802154/mac802154_reset.c + * + * Copyright (C) 2016 Sebastien Lorquet. All rights reserved. + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * Copyright (C) 2017 Verge Inc. All rights reserved. + * + * Author: Sebastien Lorquet + * Author: Gregory Nutt + * Author: Anthony Merlino + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "mac802154.h" +#include "mac802154_internal.h" + +#include + +/**************************************************************************** + * Public MAC Functions + ****************************************************************************/ + +/**************************************************************************** + * 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) +{ + FAR struct ieee802154_privmac_s * priv = + (FAR struct ieee802154_privmac_s *) mac; + union ieee802154_attr_u attr; + + if (rst_pibattr) + { + priv->isassoc = false; /* Not associated with a PAN */ + priv->trackingbeacon = false; /* Not tracking beacon by default */ + priv->assocpermit = false; /* Device (if coord) not accepting ssociation */ + priv->autoreq = true; /* Auto send data req if addr. in beacon */ + priv->battlifeext = false; /* BLE disabled */ + priv->beacon_payload_len = 0; /* Beacon payload NULL */ + priv->beaconorder = 15; /* Non-beacon enabled network */ + priv->superframeorder = 15; /* Length of active portion of outgoing SF */ + priv->beacon_txtime = 0; /* Device never sent a beacon */ +#warning Set BSN and DSN to random values! + priv->bsn = 0; + priv->dsn = 0; + priv->gtspermit = true; /* PAN Coord accepting GTS requests */ + priv->minbe = 3; /* Min value of backoff exponent (BE) */ + priv->maxbe = 5; /* Max value of backoff exponent (BE) */ + priv->max_csmabackoffs = 4; /* Max # of backoffs before failure */ + priv->maxretries = 3; /* Max # of retries allowed after failure */ + priv->promisc = false; /* Device not in promiscuous mode */ + priv->rngsupport = false; /* Ranging not yet supported */ + priv->resp_waittime = 32; /* 32 SF durations */ + priv->sec_enabled = false; /* Security disabled by default */ + priv->tx_totaldur = 0; /* 0 transmit duration */ + + priv->trans_persisttime = 0x01F4; + + /* Reset the Coordinator address */ + + priv->coordaddr.mode = IEEE802154_ADDRMODE_NONE; + priv->coordaddr.saddr = IEEE802154_SADDR_UNSPEC; + memcpy(&priv->coordaddr.eaddr[0], IEEE802154_EADDR_UNSPEC, + IEEE802154_EADDR_LEN); + + /* Reset the device's address */ + + priv->addr.mode = IEEE802154_ADDRMODE_NONE; + priv->addr.panid = IEEE802154_PAN_UNSPEC; + priv->addr.saddr = IEEE802154_SADDR_UNSPEC; + memcpy(&priv->addr.eaddr[0], IEEE802154_EADDR_UNSPEC, IEEE802154_EADDR_LEN); + + priv->radio->reset_attrs(priv->radio); + + /* The radio is in control of certain attributes, but we keep a mirror + * for easy access. Copy in the radio's values now that they've been + * reset. + */ + + priv->radio->get_attr(priv->radio, IEEE802154_ATTR_MAC_MAX_FRAME_WAITTIME, + &attr); + priv->max_frame_waittime = attr.mac.max_frame_waittime; + + /* These attributes are effected and determined based on the PHY. Need to + * figure out how to "share" attributes between the radio driver and this + * MAC layer + * + * macAckWaitDuration + * macBattLifeExtPeriods + * macMaxFrameTotalWaitTime + * macLIFSPeriod + * macSIFSPeriod + * macSyncSymbolOffset + * macTimestampSupported + * macTxControlActiveDuration + * macTxControlPauseDuration + * macRxOnWhenIdle + */ + } + + return OK; +} + + diff --git a/wireless/ieee802154/mac802154_rxenable.c b/wireless/ieee802154/mac802154_rxenable.c new file mode 100644 index 00000000000..683d130e758 --- /dev/null +++ b/wireless/ieee802154/mac802154_rxenable.c @@ -0,0 +1,78 @@ +/**************************************************************************** + * wireless/ieee802154/mac802154_rxenable.c + * + * Copyright (C) 2016 Sebastien Lorquet. All rights reserved. + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * Copyright (C) 2017 Verge Inc. All rights reserved. + * + * Author: Sebastien Lorquet + * Author: Gregory Nutt + * Author: Anthony Merlino + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "mac802154.h" + +#include + +/**************************************************************************** + * Public MAC Functions + ****************************************************************************/ + +/**************************************************************************** + * 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 mac802154_maccb_s->conf_rxenable callback. + * + ****************************************************************************/ + +int mac802154_req_rxenable(MACHANDLE mac, + FAR struct ieee802154_rxenable_req_s *req) +{ + FAR struct ieee802154_privmac_s * priv = + (FAR struct ieee802154_privmac_s *)mac; + return -ENOTTY; +} \ No newline at end of file diff --git a/wireless/ieee802154/mac802154_scan.c b/wireless/ieee802154/mac802154_scan.c new file mode 100644 index 00000000000..1ba99322889 --- /dev/null +++ b/wireless/ieee802154/mac802154_scan.c @@ -0,0 +1,82 @@ +/**************************************************************************** + * wireless/ieee802154/mac80215_scan.c + * + * Copyright (C) 2016 Sebastien Lorquet. All rights reserved. + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * Copyright (C) 2017 Verge Inc. All rights reserved. + * + * Author: Sebastien Lorquet + * Author: Gregory Nutt + * Author: Anthony Merlino + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "mac802154.h" + +#include + +/**************************************************************************** + * Public MAC Functions + ****************************************************************************/ + +/**************************************************************************** + * 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 mac802154_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) +{ + FAR struct ieee802154_privmac_s *priv = + (FAR struct ieee802154_privmac_s *)mac; + return -ENOTTY; +} + diff --git a/wireless/ieee802154/mac802154_start.c b/wireless/ieee802154/mac802154_start.c new file mode 100644 index 00000000000..263703b9e81 --- /dev/null +++ b/wireless/ieee802154/mac802154_start.c @@ -0,0 +1,167 @@ +/**************************************************************************** + * wireless/ieee802154/mac802154_start.c + * + * Copyright (C) 2017 Verge Inc. All rights reserved. + * Author: Anthony Merlino + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "mac802154.h" +#include "mac802154_internal.h" + +#include + +/**************************************************************************** + * Public MAC Functions + ****************************************************************************/ + +/**************************************************************************** + * 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 mac802154_maccb_s->conf_start callback. + * + ****************************************************************************/ + +int mac802154_req_start(MACHANDLE mac, FAR struct ieee802154_start_req_s *req) +{ + FAR struct ieee802154_privmac_s *priv = + (FAR struct ieee802154_privmac_s *)mac; + int ret; + + /* Get exclusive access to the MAC */ + + ret = mac802154_takesem(&priv->exclsem, true); + if (ret < 0) + { + return ret; + } + + /* When the CoordRealignment parameter is set to TRUE, the coordinator + * attempts to transmit a coordinator realignment command frame as described + * in 5.1.2.3.2. If the transmission of the coordinator realignment command + * fails due to a channel access failure, the MLME will not make any changes + * to the superframe configuration. (i.e., no PIB attributes will be changed). + * If the coordinator realignment command is successfully transmitted, the + * MLME updates the PIB attributes BeaconOrder, SuperframeOrder, PANId, + * ChannelPage, and ChannelNumber parameters. [1] pg. 106 + */ + + if (req->coordrealign) + { + /* TODO: Finish the realignment functionality */ + + return -ENOTTY; + } + + /* Set the PANID attribute */ + + priv->addr.panid = req->panid; + priv->radio->set_attr(priv->radio, IEEE802154_ATTR_MAC_PANID, + (FAR const union ieee802154_attr_u *)&req->panid); + + /* Set the radio attributes */ + priv->radio->set_attr(priv->radio, IEEE802154_ATTR_PHY_CURRENT_CHANNEL, + (FAR const union ieee802154_attr_u *)&req->chnum); + + priv->radio->set_attr(priv->radio, IEEE802154_ATTR_PHY_CURRENT_PAGE, + (FAR const union ieee802154_attr_u *)&req->chpage); + + + /* Set the beacon order */ + + if(req->beaconorder > 15) + { + ret = -EINVAL; + goto errout; + } + + priv->beaconorder = req->beaconorder; + + /* The value of macSuperframeOrder shall be ignored if macBeaconOrder = 15. pg. 19 */ + + if (priv->beaconorder < 15) + { + /* Set the superframe order */ + + if(req->superframeorder > 15) + { + ret = -EINVAL; + goto errout; + } + + priv->superframeorder = req->superframeorder; + } + + if (req->pancoord) + { + priv->devmode = IEEE802154_DEVMODE_PANCOORD; + } + else + { + priv->devmode = IEEE802154_DEVMODE_COORD; + } + + /* If the BeaconOrder parameter is less than 15, the MLME sets macBattLifeExt to + * the value of the BatteryLifeExtension parameter. If the BeaconOrder parameter + * equals 15, the value of the BatteryLifeExtension parameter is ignored. + * [1] pg. 106 + */ + + if (priv->beaconorder < 15) + { + priv->battlifeext = req->battlifeext; + + /* TODO: Finish starting beacon enabled network */ + return -ENOTTY; + } + + mac802154_givesem(&priv->exclsem); + + return OK; + +errout: + mac802154_givesem(&priv->exclsem); + return ret; +} \ No newline at end of file diff --git a/wireless/ieee802154/mac802154_sync.c b/wireless/ieee802154/mac802154_sync.c new file mode 100644 index 00000000000..fed5e452de1 --- /dev/null +++ b/wireless/ieee802154/mac802154_sync.c @@ -0,0 +1,78 @@ +/**************************************************************************** + * wireless/ieee802154/mac802154_sync.c + * + * Copyright (C) 2016 Sebastien Lorquet. All rights reserved. + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * Copyright (C) 2017 Verge Inc. All rights reserved. + * + * Author: Sebastien Lorquet + * Author: Gregory Nutt + * Author: Anthony Merlino + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "mac802154.h" + +#include + +/**************************************************************************** + * Public MAC Functions + ****************************************************************************/ + +/**************************************************************************** + * 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 mac802154_maccb_s->int_commstatus callback. TOCHECK. + * + ****************************************************************************/ + +int mac802154_req_sync(MACHANDLE mac, FAR struct ieee802154_sync_req_s *req) +{ + FAR struct ieee802154_privmac_s *priv = + (FAR struct ieee802154_privmac_s *)mac; + return -ENOTTY; +} +