diff --git a/configs/clicker2-stm32/mrf24j40-mac/defconfig b/configs/clicker2-stm32/mrf24j40-mac/defconfig index 7ee79a1d4a..0feb83fa31 100644 --- a/configs/clicker2-stm32/mrf24j40-mac/defconfig +++ b/configs/clicker2-stm32/mrf24j40-mac/defconfig @@ -1168,10 +1168,10 @@ CONFIG_BUILTIN_PROXY_STACKSIZE=1024 CONFIG_EXAMPLES_NSH=y CONFIG_EXAMPLES_NSH_CXXINITIALIZE=y # CONFIG_EXAMPLES_NULL is not set +# CONFIG_EXAMPLES_NX is not set # CONFIG_EXAMPLES_NXFFS is not set # CONFIG_EXAMPLES_NXHELLO is not set # CONFIG_EXAMPLES_NXIMAGE is not set -# CONFIG_EXAMPLES_NX is not set # CONFIG_EXAMPLES_NXLINES is not set # CONFIG_EXAMPLES_NXTERM is not set # CONFIG_EXAMPLES_NXTEXT is not set @@ -1191,7 +1191,6 @@ CONFIG_EXAMPLES_NSH_CXXINITIALIZE=y # 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 @@ -1304,6 +1303,7 @@ CONFIG_NSH_DISABLE_PUT=y # CONFIG_NSH_DISABLE_SLEEP is not set # CONFIG_NSH_DISABLE_TIME is not set # CONFIG_NSH_DISABLE_TEST is not set +# CONFIG_NSH_DISABLE_TELNETD is not set # CONFIG_NSH_DISABLE_UMOUNT is not set # CONFIG_NSH_DISABLE_UNAME is not set # CONFIG_NSH_DISABLE_UNSET is not set diff --git a/configs/clicker2-stm32/mrf24j40-starhub/defconfig b/configs/clicker2-stm32/mrf24j40-starhub/defconfig index 45000c97af..b76ba0bfae 100644 --- a/configs/clicker2-stm32/mrf24j40-starhub/defconfig +++ b/configs/clicker2-stm32/mrf24j40-starhub/defconfig @@ -992,11 +992,7 @@ CONFIG_NET_6LOWPAN_MAXAGE=20 CONFIG_NET_6LOWPAN_MAX_MACTRANSMITS=4 CONFIG_NET_6LOWPAN_MTU=1294 CONFIG_NET_6LOWPAN_TCP_RECVWNDO=1220 -CONFIG_NET_HAVE_STAR=y CONFIG_NET_IPFORWARD=y -CONFIG_NET_STAR=y -# CONFIG_NET_STARPOINT is not set -CONFIG_NET_STARHUB=y # # Socket Support @@ -1062,6 +1058,14 @@ CONFIG_NET_UDP_READAHEAD=y # CONFIG_NET_ARCH_INCR32 is not set # CONFIG_NET_ARCH_CHKSUM is not set CONFIG_NET_STATISTICS=y +CONFIG_NET_HAVE_STAR=y + +# +# Network Topologies +# +CONFIG_NET_STAR=y +# CONFIG_NET_STARPOINT is not set +CONFIG_NET_STARHUB=y # # Routing Table Configuration @@ -1365,7 +1369,6 @@ CONFIG_EXAMPLES_NSH_CXXINITIALIZE=y # 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_UDP is not set diff --git a/configs/clicker2-stm32/mrf24j40-starpoint/defconfig b/configs/clicker2-stm32/mrf24j40-starpoint/defconfig index 99c76b0ead..9034a54f49 100644 --- a/configs/clicker2-stm32/mrf24j40-starpoint/defconfig +++ b/configs/clicker2-stm32/mrf24j40-starpoint/defconfig @@ -992,11 +992,7 @@ CONFIG_NET_6LOWPAN_MAXAGE=20 CONFIG_NET_6LOWPAN_MAX_MACTRANSMITS=4 CONFIG_NET_6LOWPAN_MTU=1294 CONFIG_NET_6LOWPAN_TCP_RECVWNDO=1220 -CONFIG_NET_HAVE_STAR=y # CONFIG_NET_IPFORWARD is not set -CONFIG_NET_STAR=y -CONFIG_NET_STARPOINT=y -# CONFIG_NET_STARHUB is not set # # Socket Support @@ -1062,6 +1058,14 @@ CONFIG_NET_UDP_READAHEAD=y # CONFIG_NET_ARCH_INCR32 is not set # CONFIG_NET_ARCH_CHKSUM is not set CONFIG_NET_STATISTICS=y +CONFIG_NET_HAVE_STAR=y + +# +# Network Topologies +# +CONFIG_NET_STAR=y +CONFIG_NET_STARPOINT=y +# CONFIG_NET_STARHUB is not set # # Routing Table Configuration diff --git a/drivers/wireless/ieee802154/Kconfig b/drivers/wireless/ieee802154/Kconfig index d0d8c550ec..4a799e4999 100644 --- a/drivers/wireless/ieee802154/Kconfig +++ b/drivers/wireless/ieee802154/Kconfig @@ -11,10 +11,14 @@ config IEEE802154_MRF24J40 ---help--- This selection enables support for the Microchip MRF24J40 device. +source drivers/wireless/ieee802154/mrf24j40/Kconfig + config IEEE802154_AT86RF233 bool "ATMEL RF233 IEEE 802.15.4 transceiver" default n ---help--- This selection enables support for the Atmel RF233 device. +source drivers/wireless/ieee802154/at86rf23x/Kconfig + endif # DRIVERS_IEEE802154 diff --git a/drivers/wireless/ieee802154/Make.defs b/drivers/wireless/ieee802154/Make.defs index 8e0924d67f..2aa926dbe0 100644 --- a/drivers/wireless/ieee802154/Make.defs +++ b/drivers/wireless/ieee802154/Make.defs @@ -1,7 +1,7 @@ ############################################################################ # drivers/ieee802154/Make.defs # -# Copyright (C) 2016 Gregory Nutt. All rights reserved. +# Copyright (C) 2016-2017 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -41,15 +41,10 @@ ifeq ($(CONFIG_DRIVERS_IEEE802154),y) # Include IEEE 802.15.4 drivers into the build -ifeq ($(CONFIG_IEEE802154_MRF24J40),y) - CSRCS += mrf24j40.c -endif +include wireless$(DELIM)ieee802154$(DELIM)mrf24j40$(DELIM)Make.defs +include wireless$(DELIM)ieee802154$(DELIM)at86rf23x$(DELIM)Make.defs -ifeq ($(CONFIG_IEEE802154_AT86RF233),y) - CSRCS += at86rf23x.c -endif - -# Include IEEE 802.15.4 build support +# Include common IEEE 802.15.4 build support DEPPATH += --dep-path wireless$(DELIM)ieee802154 VPATH += :wireless$(DELIM)ieee802154 diff --git a/drivers/wireless/ieee802154/at86rf23x/Kconfig b/drivers/wireless/ieee802154/at86rf23x/Kconfig new file mode 100644 index 0000000000..43ac4b882d --- /dev/null +++ b/drivers/wireless/ieee802154/at86rf23x/Kconfig @@ -0,0 +1,8 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if IEEE802154_AT86RF233 + +endif # IEEE802154_AT86RF233 diff --git a/drivers/wireless/ieee802154/at86rf23x/Make.defs b/drivers/wireless/ieee802154/at86rf23x/Make.defs new file mode 100644 index 0000000000..876032ddbc --- /dev/null +++ b/drivers/wireless/ieee802154/at86rf23x/Make.defs @@ -0,0 +1,48 @@ +############################################################################ +# drivers/ieee802154/at86rf23x/Make.defs +# +# Copyright (C) 2016-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 AT86RF23x drivers into the build + +ifeq ($(CONFIG_IEEE802154_AT86RF233),y) + +CSRCS += at86rf23x.c + +# Include AT86RF23x build support + +DEPPATH += --dep-path wireless$(DELIM)ieee802154$(DELIM)at86rf23x +VPATH += :wireless$(DELIM)ieee802154$(DELIM)at86rf23x +CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)drivers$(DELIM)wireless$(DELIM)ieee802154$(DELIM)at86rf23x} + +endif # CONFIG_IEEE802154_AT86RF233 \ No newline at end of file diff --git a/drivers/wireless/ieee802154/at86rf23x.c b/drivers/wireless/ieee802154/at86rf23x/at86rf23x.c similarity index 99% rename from drivers/wireless/ieee802154/at86rf23x.c rename to drivers/wireless/ieee802154/at86rf23x/at86rf23x.c index 3e4cd0ce11..1fe4250d3a 100644 --- a/drivers/wireless/ieee802154/at86rf23x.c +++ b/drivers/wireless/ieee802154/at86rf23x/at86rf23x.c @@ -1,5 +1,5 @@ /**************************************************************************** - * drivers/wireless/ieee802154/at86rf23x.c + * drivers/wireless/ieee802154/at86rf23x/at86rf23x.c * * Copyright (C) 2016 Matt Poppe. All rights reserved. * Author: Matt Poppe @@ -996,19 +996,20 @@ static int at86rf23x_gettxpower(FAR struct ieee802154_radio_s *ieee, reg = at86rf23x_getreg(dev->spi, RF23X_REG_TXPWR); switch (reg) { - case RF23X_TXPWR_POS_4: + case RF23X_TXPWR_POS_4: + *txpwr = 0; break; - case RF23X_TXPWR_POS_3_7: + case RF23X_TXPWR_POS_3_7: + *txpwr =0; + break; + + case RF23X_TXPWR_POS_3_4: *txpwr = 0; break; - case RF23X_TXPWR_POS_3_4: - *txpwr = 0; - break; - - case RF23X_TXPWR_POS_3: + case RF23X_TXPWR_POS_3: *txpwr = 0; break; @@ -1016,23 +1017,23 @@ static int at86rf23x_gettxpower(FAR struct ieee802154_radio_s *ieee, *txpwr = 0; break; - case RF23X_TXPWR_POS_2: + case RF23X_TXPWR_POS_2: *txpwr = 0; break; - case RF23X_TXPWR_POS_1: + case RF23X_TXPWR_POS_1: *txpwr = 0; break; - case RF23X_TXPWR_0: - *txpwr = 0; + case RF23X_TXPWR_0: + *txpwr =0; break; - case RF23X_TXPWR_NEG_1: + case RF23X_TXPWR_NEG_1: *txpwr = 1000; break; - case RF23X_TXPWR_NEG_2: + case RF23X_TXPWR_NEG_2: *txpwr = 2000; break; @@ -1071,11 +1072,11 @@ static int at86rf23x_gettxpower(FAR struct ieee802154_radio_s *ieee, * Configures if energy detection is used or carrier sense. The base * measurement is configured here as well * - * ****************************************************************************/ -static int at86rf23x_setcca(FAR struct ieee802154_radio_s *ieee, - FAR struct ieee802154_cca_s *cca) +static + int at86rf23x_setcca(FAR struct ieee802154_radio_s *ieee, + FAR struct ieee802154_cca_s *cca) { FAR struct at86rf23x_dev_s *dev = (struct at86rf23x_dev_s *)ieee; diff --git a/drivers/wireless/ieee802154/at86rf23x.h b/drivers/wireless/ieee802154/at86rf23x/at86rf23x.h similarity index 97% rename from drivers/wireless/ieee802154/at86rf23x.h rename to drivers/wireless/ieee802154/at86rf23x/at86rf23x.h index 4d64fed0c8..3d9700aec6 100644 --- a/drivers/wireless/ieee802154/at86rf23x.h +++ b/drivers/wireless/ieee802154/at86rf23x/at86rf23x.h @@ -1,5 +1,5 @@ /**************************************************************************** - * drivers/wireless/ieee802154/at86rf23x.c + * drivers/wireless/ieee802154/at86rf23x/at86rf23x.h * * Copyright (C) 2016 Matt Poppe. All rights reserved. * Author: Matt Poppe @@ -33,8 +33,8 @@ * ****************************************************************************/ -#ifndef __DRIVERS_WIRELESS_IEEE802154_AT86RF23X_H -#define __DRIVERS_WIRELESS_IEEE802154_AT86RF23X_H +#ifndef __DRIVERS_WIRELESS_IEEE802154_AT86RF23X_AT86RF23X_H +#define __DRIVERS_WIRELESS_IEEE802154_AT86RF23X_AT86RF23X_H /**************************************************************************** * Pre-processor Definitions @@ -218,4 +218,4 @@ #define RF23X_IRQ_MASK_DEFAULT (RF23X_IRQ_MASK_TRX_END) -#endif /* __DRIVERS_WIRELESS_IEEE802154_AT86RF23X_H */ +#endif /* __DRIVERS_WIRELESS_IEEE802154_AT86RF23X_AT86RF23X_H */ diff --git a/drivers/wireless/ieee802154/mrf24j40/Kconfig b/drivers/wireless/ieee802154/mrf24j40/Kconfig new file mode 100644 index 0000000000..851b804a14 --- /dev/null +++ b/drivers/wireless/ieee802154/mrf24j40/Kconfig @@ -0,0 +1,8 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if IEEE802154_MRF24J40 + +endif # IEEE802154_MRF24J40 diff --git a/drivers/wireless/ieee802154/mrf24j40/Make.defs b/drivers/wireless/ieee802154/mrf24j40/Make.defs new file mode 100644 index 0000000000..f6871f6ce5 --- /dev/null +++ b/drivers/wireless/ieee802154/mrf24j40/Make.defs @@ -0,0 +1,48 @@ +############################################################################ +# drivers/ieee802154/mrf24j40/Make.defs +# +# Copyright (C) 2016-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. +# +############################################################################ + +ifeq ($(CONFIG_IEEE802154_MRF24J40),y) + +# Include MRF24J40 files into the build + +CSRCS += mrf24j40.c + +# Include MRF24J40 build support + +DEPPATH += --dep-path wireless$(DELIM)ieee802154$(DELIM)mrf24j40 +VPATH += :wireless$(DELIM)ieee802154$(DELIM)mrf24j40 +CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)drivers$(DELIM)wireless$(DELIM)ieee802154$(DELIM)mrf24j40} + +endif # CONFIG_IEEE802154_MRF24J40 \ No newline at end of file diff --git a/drivers/wireless/ieee802154/mrf24j40.c b/drivers/wireless/ieee802154/mrf24j40/mrf24j40.c similarity index 90% rename from drivers/wireless/ieee802154/mrf24j40.c rename to drivers/wireless/ieee802154/mrf24j40/mrf24j40.c index b6259099c1..5098e96253 100644 --- a/drivers/wireless/ieee802154/mrf24j40.c +++ b/drivers/wireless/ieee802154/mrf24j40/mrf24j40.c @@ -1,5 +1,5 @@ /**************************************************************************** - * drivers/wireless/ieee802154/mrf24j40.c + * drivers/wireless/ieee802154/mrf24j40/mrf24j40.c * * Copyright (C) 2015-2016 Sebastien Lorquet. All rights reserved. * Copyright (C) 2017 Verge Inc. All rights reserved. @@ -147,10 +147,6 @@ struct mrf24j40_radio_s struct ieee802154_radio_s radio; /* The public device instance */ FAR struct ieee802154_radiocb_s *radiocb; /* Registered callbacks */ - /* MAC Attributes */ - - bool rxonidle : 1; - /* Low-level MCU-specific support */ FAR const struct mrf24j40_lower_s *lower; @@ -162,6 +158,8 @@ struct mrf24j40_radio_s sem_t exclsem; /* Exclusive access to this struct */ + /* MAC Attributes */ + struct ieee802154_addr_s addr; uint8_t chan; /* 11 to 26 for the 2.4 GHz band */ @@ -183,6 +181,8 @@ struct mrf24j40_radio_s bool rxenabled : 1; + uint8_t bsn; + struct ieee802154_txdesc_s *gts_desc[MRF24J40_GTS_SLOTS]; bool gts_busy[MRF24J40_GTS_SLOTS]; }; @@ -200,8 +200,9 @@ static void mrf24j40_setreg(FAR struct spi_dev_s *spi, uint32_t addr, static uint8_t mrf24j40_getreg(FAR struct spi_dev_s *spi, uint32_t addr); static int mrf24j40_resetrfsm(FAR struct mrf24j40_radio_s *dev); +static void mrf24j40_setorder(FAR struct mrf24j40_radio_s *dev, uint8_t bo, + uint8_t so); static int mrf24j40_pacontrol(FAR struct mrf24j40_radio_s *dev, int mode); -static int mrf24j40_initialize(FAR struct mrf24j40_radio_s *dev); static int mrf24j40_setrxmode(FAR struct mrf24j40_radio_s *dev, int mode); static int mrf24j40_regdump(FAR struct mrf24j40_radio_s *dev); @@ -225,6 +226,7 @@ static void mrf24j40_setup_fifo(FAR struct mrf24j40_radio_s *dev, FAR const uint8_t *buf, uint8_t length, uint32_t fifo_addr); static inline void mrf24j40_norm_trigger(FAR struct mrf24j40_radio_s *dev); +static inline void mrf24j40_beacon_trigger(FAR struct mrf24j40_radio_s *dev); static int mrf24j40_setchannel(FAR struct mrf24j40_radio_s *dev, uint8_t chan); @@ -252,20 +254,18 @@ static void mrf24j40_mactimer(FAR struct mrf24j40_radio_s *dev, int numsymbols); static int mrf24j40_bind(FAR struct ieee802154_radio_s *radio, FAR struct ieee802154_radiocb_s *radiocb); -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, +static int mrf24j40_reset(FAR struct ieee802154_radio_s *radio); +static int mrf24j40_getattr(FAR struct ieee802154_radio_s *radio, enum ieee802154_attr_e attr, FAR union ieee802154_attr_u *attrval); -static int mrf24j40_set_attr(FAR struct ieee802154_radio_s *radio, +static int mrf24j40_setattr(FAR struct ieee802154_radio_s *radio, enum ieee802154_attr_e attr, FAR const union ieee802154_attr_u *attrval); +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_rxenable(FAR struct ieee802154_radio_s *dev, bool enable); -static int mrf24j40_req_rxenable(FAR struct ieee802154_radio_s *radio, - FAR struct ieee802154_rxenable_req_s *req); static int mrf24j40_beaconstart(FAR struct ieee802154_radio_s *radio, FAR const struct ieee802154_superframespec_s *sfspec, FAR struct ieee802154_beaconframe_s *beacon); @@ -437,18 +437,83 @@ static int mrf24j40_txdelayed(FAR struct ieee802154_radio_s *radio, return OK; } -static int mrf24j40_reset_attrs(FAR struct ieee802154_radio_s *radio) +static int mrf24j40_reset(FAR struct ieee802154_radio_s *radio) { FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)radio; + struct ieee802154_cca_s cca; + int reg; + + /* Software reset */ + + mrf24j40_setreg(dev->spi, MRF24J40_SOFTRST , 0x07); /* 00000111 Reset */ + while(mrf24j40_getreg(dev->spi, MRF24J40_SOFTRST) & 0x07); + + /* Apply recommended settings */ + + mrf24j40_setreg(dev->spi, MRF24J40_PACON2 , 0x98); /* 10011000 Enable FIFO (default), TXONTS=6 (recommended), TXONT<8:7>=0 */ + mrf24j40_setreg(dev->spi, MRF24J40_TXSTBL , 0x95); /* 10010101 set the SIFS period. RFSTBL=9, MSIFS=5, aMinSIFSPeriod=14 (min 12) */ + mrf24j40_setreg(dev->spi, MRF24J40_TXPEND , 0x7C); /* 01111100 set the LIFS period, MLIFS=1Fh=31 aMinLIFSPeriod=40 (min 40) */ + mrf24j40_setreg(dev->spi, MRF24J40_TXTIME , 0x30); /* 00110000 set the turnaround time, TURNTIME=3 aTurnAroundTime=12 */ + mrf24j40_setreg(dev->spi, MRF24J40_RFCON1 , 0x02); /* 00000010 VCO optimization, recommended value */ + mrf24j40_setreg(dev->spi, MRF24J40_RFCON2 , 0x80); /* 10000000 Enable PLL */ + mrf24j40_setreg(dev->spi, MRF24J40_RFCON6 , 0x90); /* 10010000 TX filter enable, fast 20M recovery, No bat monitor*/ + mrf24j40_setreg(dev->spi, MRF24J40_RFCON7 , 0x80); /* 10000000 Sleep clock on internal 100 kHz */ + mrf24j40_setreg(dev->spi, MRF24J40_RFCON8 , 0x10); /* 00010000 VCO control bit, as recommended */ + mrf24j40_setreg(dev->spi, MRF24J40_SLPCON1, 0x01); /* 00000001 no CLKOUT, default divisor */ + mrf24j40_setreg(dev->spi, MRF24J40_BBREG6 , 0x40); /* 01000000 Append RSSI to rx packets */ + + /* Set this in reset since it can exist for all device modes. See pg 101 */ + + mrf24j40_setreg(dev->spi, MRF24J40_FRMOFFSET, 0x15); + + /* 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); + + /* Set WAKECNT (SLPACK 0x35<6:0>) value = 0x5F to set the main oscillator + * (20 MHz) start-up timer value. + */ + + mrf24j40_setreg(dev->spi, MRF24J40_SLPACK, 0x5F); + + /* Enable the SLPIF and WAKEIF flags */ + + reg = mrf24j40_getreg(dev->spi, MRF24J40_INTCON); + reg &= ~(MRF24J40_INTCON_SLPIE | MRF24J40_INTCON_WAKEIE); + mrf24j40_setreg(dev->spi, MRF24J40_INTCON, reg); + + dev->rxenabled = false; + + mrf24j40_setchannel(dev, 11); + mrf24j40_setpanid(dev, g_allones); + mrf24j40_setsaddr(dev, g_allones); + mrf24j40_seteaddr(dev, g_allones); dev->max_frame_waittime = MRF24J40_DEFAULT_MAX_FRAME_WAITTIME; + dev->bsn = 0; + + /* Default device params */ + + cca.use_ed = 1; + cca.use_cs = 0; + cca.edth = 0x60; /* CCA mode ED, no carrier sense, recommenced ED threshold -69 dBm */ + mrf24j40_setcca(dev, &cca); + + mrf24j40_setrxmode(dev, MRF24J40_RXMODE_NORMAL); + + mrf24j40_settxpower(dev, 0); /*16. Set transmitter power .*/ + + mrf24j40_pacontrol(dev, MRF24J40_PA_AUTO); return OK; } -static int mrf24j40_get_attr(FAR struct ieee802154_radio_s *radio, - enum ieee802154_attr_e attr, - FAR union ieee802154_attr_u *attrval) +static int mrf24j40_getattr(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; @@ -489,9 +554,9 @@ static int mrf24j40_get_attr(FAR struct ieee802154_radio_s *radio, return ret; } -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_setattr(FAR struct ieee802154_radio_s *radio, + 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; @@ -548,13 +613,6 @@ static int mrf24j40_set_attr(FAR struct ieee802154_radio_s *radio, } break; - case IEEE802154_ATTR_MAC_RX_ON_WHEN_IDLE: - { - dev->rxonidle = attrval->mac.rxonidle; - mrf24j40_rxenable(radio, dev->rxonidle); - ret = IEEE802154_STATUS_SUCCESS; - } - break; case IEEE802154_ATTR_PHY_CHAN: { @@ -567,23 +625,14 @@ static int mrf24j40_set_attr(FAR struct ieee802154_radio_s *radio, 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; -} - static int mrf24j40_beaconstart(FAR struct ieee802154_radio_s *radio, FAR const struct ieee802154_superframespec_s *sfspec, FAR struct ieee802154_beaconframe_s *beacon) { FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)radio; - uint32_t maincnt = 0; - uint32_t slpcal = 0; int reg; if (sfspec->pancoord) @@ -604,6 +653,11 @@ static int mrf24j40_beaconstart(FAR struct ieee802154_radio_s *radio, mrf24j40_setup_fifo(dev, beacon->bf_data, beacon->bf_len, MRF24J40_BEACON_FIFO); + /* The radio layer is responsible for setting the BSN. */ + + dev->bsn = 0; + mrf24j40_setreg(dev->spi, MRF24J40_BEACON_FIFO + 4, dev->bsn++); + /* Set the TXBMSK (TXBCON1 0x25<7>) bit = 1 to mask the beacon interrupt * mask */ @@ -628,75 +682,7 @@ static int mrf24j40_beaconstart(FAR struct ieee802154_radio_s *radio, /* TODO: Add GTS related code. See pg 100 of datasheet */ - /* Calibrate the Sleep Clock (SLPCLK) frequency. Refer to Section 3.15.1.2 - * “Sleep Clock Calibration”. - */ - - /* If the Sleep Clock Selection, SLPCLKSEL (0x207<7:6), is the internal - * oscillator (100 kHz), set SLPCLKDIV to a minimum value of 0x01. - */ - - mrf24j40_setreg(dev->spi, MRF24J40_SLPCON1, 0x01); - - /* Select the source of SLPCLK (internal 100kHz) */ - - mrf24j40_setreg(dev->spi, MRF24J40_RFCON7, MRF24J40_RFCON7_SEL_100KHZ); - - /* Begin calibration by setting the SLPCALEN bit (SLPCAL2 0x20B<4>) to - * ‘1’. Sixteen samples of the SLPCLK are counted and stored in the - * SLPCAL register. No need to mask, this is the only writable bit - */ - - mrf24j40_setreg(dev->spi, MRF24J40_SLPCAL2, MRF24J40_SLPCAL2_SLPCALEN); - - /* Calibration is complete when the SLPCALRDY bit (SLPCAL2 0x20B<7>) is - * set to ‘1’. - */ - - while (!(mrf24j40_getreg(dev->spi, MRF24J40_SLPCAL2) & - MRF24J40_SLPCAL2_SLPCALRDY)) - { - usleep(1); - } - - slpcal = mrf24j40_getreg(dev->spi, MRF24J40_SLPCAL0); - slpcal |= (mrf24j40_getreg(dev->spi, MRF24J40_SLPCAL1) << 8); - slpcal |= ((mrf24j40_getreg(dev->spi, MRF24J40_SLPCAL2) << 16) & 0x0F); - - /* Set WAKECNT (SLPACK 0x35<6:0>) value = 0x5F to set the main oscillator - * (20 MHz) start-up timer value. - */ - - mrf24j40_setreg(dev->spi, MRF24J40_SLPACK, 0x5F); - - /* Program the Beacon Interval into the Main Counter, MAINCNT (0x229<1:0>, - * 0x228, 0x227, 0x226), and Remain Counter, REMCNT (0x225, 0x224), - * according to BO and SO values. Refer to Section 3.15.1.3 “Sleep Mode - * Counters” - */ - - mrf24j40_setreg(dev->spi, MRF24J40_REMCNTL, (MRF24J40_REMCNT & 0xFF)); - mrf24j40_setreg(dev->spi, MRF24J40_REMCNTH, ((MRF24J40_REMCNT >> 8) & 0xFF)); - - maincnt = MRF24J40_MAINCNT(sfspec->beaconorder, (slpcal * 50 / 16)); - - mrf24j40_setreg(dev->spi, MRF24J40_MAINCNT0, (maincnt & 0xFF)); - mrf24j40_setreg(dev->spi, MRF24J40_MAINCNT1, ((maincnt >> 8) & 0xFF)); - mrf24j40_setreg(dev->spi, MRF24J40_MAINCNT2, ((maincnt >> 16) & 0xFF)); - mrf24j40_setreg(dev->spi, MRF24J40_MAINCNT3, ((maincnt >> 24) & 0x03)); - - /* Enable the SLPIF and WAKEIF flags */ - - reg = mrf24j40_getreg(dev->spi, MRF24J40_INTCON); - reg &= ~(MRF24J40_INTCON_SLPIE | MRF24J40_INTCON_WAKEIE); - mrf24j40_setreg(dev->spi, MRF24J40_INTCON, reg); - - /* Configure the BO (ORDER 0x10<7:4>) and SO (ORDER 0x10<3:0>) values. - * After configuring BO and SO, the beacon frame will be sent immediately. - */ - - mrf24j40_setreg(dev->spi, MRF24J40_ORDER, - ((sfspec->beaconorder << 4) & 0xF0) | (sfspec->sforder & 0x0F)); + mrf24j40_setorder(dev, sfspec->beaconorder, sfspec->sforder); } else { @@ -712,6 +698,7 @@ static int mrf24j40_beaconupdate(FAR struct ieee802154_radio_s *radio, FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)radio; mrf24j40_setup_fifo(dev, beacon->bf_data, beacon->bf_len, MRF24J40_BEACON_FIFO); + mrf24j40_beacon_trigger(dev); return OK; } @@ -727,17 +714,20 @@ static int mrf24j40_sfupdate(FAR struct ieee802154_radio_s *radio, FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)radio; int reg; - reg = mrf24j40_getreg(dev->spi, MRF24J40_RXMCR); + /* If we are operating on a beacon-enabled network, use slotted CSMA */ - if (sfspec->pancoord) + reg = mrf24j40_getreg(dev->spi, MRF24J40_TXMCR); + if (sfspec->beaconorder < 15) { - reg |= MRF24J40_RXMCR_PANCOORD; + reg |= MRF24J40_TXMCR_SLOTTED; } else { - reg &= ~MRF24J40_RXMCR_PANCOORD; + reg &= ~MRF24J40_TXMCR_SLOTTED; } - mrf24j40_setreg(dev->spi, MRF24J40_RXMCR, reg); + mrf24j40_setreg(dev->spi, MRF24J40_TXMCR, reg); + + mrf24j40_setorder(dev, sfspec->beaconorder, sfspec->sforder); /* Program the CAP end slot (ESLOTG1 0x13<3:0>) value. */ @@ -746,13 +736,6 @@ static int mrf24j40_sfupdate(FAR struct ieee802154_radio_s *radio, reg |= sfspec->final_capslot & MRF24J40_ESLOTG1_CAP; mrf24j40_setreg(dev->spi, MRF24J40_ESLOTG1, reg); - /* Configure the BO (ORDER 0x10<7:4>) and SO (ORDER 0x10<3:0>) values. - * After configuring BO and SO, the beacon frame will be sent immediately. - */ - - mrf24j40_setreg(dev->spi, MRF24J40_ORDER, - ((sfspec->beaconorder << 4) & 0xF0) | (sfspec->sforder & 0x0F)); - return OK; } @@ -823,10 +806,13 @@ static void mrf24j40_dopoll_csma(FAR void *arg) if (!dev->csma_busy) { + wlinfo("Polling for frame\n"); len = dev->radiocb->poll(dev->radiocb, false, &dev->csma_desc); if (len > 0) { + wlinfo("Frame received. Frame length: %d\n", len); + /* Now the txdesc is in use */ dev->csma_busy = 1; @@ -1036,6 +1022,78 @@ static int mrf24j40_resetrfsm(FAR struct mrf24j40_radio_s *dev) return OK; } +/**************************************************************************** + * Name: mrf24j40_setorder + * + * Description: + * Configures the timers and sets the ORDER register + ****************************************************************************/ + +static void mrf24j40_setorder(FAR struct mrf24j40_radio_s *dev, uint8_t bo, + uint8_t so) +{ + uint32_t maincnt = 0; + uint32_t slpcal = 0; + + /* Calibrate the Sleep Clock (SLPCLK) frequency. Refer to Section 3.15.1.2 + * “Sleep Clock Calibration”. + */ + + /* If the Sleep Clock Selection, SLPCLKSEL (0x207<7:6), is the internal + * oscillator (100 kHz), set SLPCLKDIV to a minimum value of 0x01. + */ + + mrf24j40_setreg(dev->spi, MRF24J40_SLPCON1, 0x01); + + /* Select the source of SLPCLK (internal 100kHz) */ + + mrf24j40_setreg(dev->spi, MRF24J40_RFCON7, MRF24J40_RFCON7_SEL_100KHZ); + + /* Begin calibration by setting the SLPCALEN bit (SLPCAL2 0x20B<4>) to + * ‘1’. Sixteen samples of the SLPCLK are counted and stored in the + * SLPCAL register. No need to mask, this is the only writable bit + */ + + mrf24j40_setreg(dev->spi, MRF24J40_SLPCAL2, MRF24J40_SLPCAL2_SLPCALEN); + + /* Calibration is complete when the SLPCALRDY bit (SLPCAL2 0x20B<7>) is + * set to ‘1’. + */ + + while (!(mrf24j40_getreg(dev->spi, MRF24J40_SLPCAL2) & + MRF24J40_SLPCAL2_SLPCALRDY)) + { + usleep(1); + } + + slpcal = mrf24j40_getreg(dev->spi, MRF24J40_SLPCAL0); + slpcal |= (mrf24j40_getreg(dev->spi, MRF24J40_SLPCAL1) << 8); + slpcal |= ((mrf24j40_getreg(dev->spi, MRF24J40_SLPCAL2) << 16) & 0x0F); + + /* Program the Beacon Interval into the Main Counter, MAINCNT (0x229<1:0>, + * 0x228, 0x227, 0x226), and Remain Counter, REMCNT (0x225, 0x224), + * according to BO and SO values. Refer to Section 3.15.1.3 “Sleep Mode + * Counters” + */ + + + mrf24j40_setreg(dev->spi, MRF24J40_REMCNTL, (MRF24J40_REMCNT & 0xFF)); + mrf24j40_setreg(dev->spi, MRF24J40_REMCNTH, ((MRF24J40_REMCNT >> 8) & 0xFF)); + + maincnt = MRF24J40_MAINCNT(bo, (slpcal * 50 / 16)); + + mrf24j40_setreg(dev->spi, MRF24J40_MAINCNT0, (maincnt & 0xFF)); + mrf24j40_setreg(dev->spi, MRF24J40_MAINCNT1, ((maincnt >> 8) & 0xFF)); + mrf24j40_setreg(dev->spi, MRF24J40_MAINCNT2, ((maincnt >> 16) & 0xFF)); + mrf24j40_setreg(dev->spi, MRF24J40_MAINCNT3, ((maincnt >> 24) & 0x03)); + + /* Configure the BO (ORDER 0x10<7:4>) and SO (ORDER 0x10<3:0>) values. + * After configuring BO and SO, the beacon frame will be sent immediately. + */ + + mrf24j40_setreg(dev->spi, MRF24J40_ORDER, ((bo << 4) & 0xF0) | (so & 0x0F)); +} + /**************************************************************************** * Name: mrf24j40_pacontrol * @@ -1080,38 +1138,6 @@ static int mrf24j40_pacontrol(FAR struct mrf24j40_radio_s *dev, int mode) return OK; } -/**************************************************************************** - * Name: mrf24j40_initialize - * - * Description: - * Reset the device and put in in order of operation - * - ****************************************************************************/ - -static int mrf24j40_initialize(FAR struct mrf24j40_radio_s *dev) -{ - /* Software reset */ - - mrf24j40_setreg(dev->spi, MRF24J40_SOFTRST , 0x07); /* 00000111 Reset */ - while(mrf24j40_getreg(dev->spi, MRF24J40_SOFTRST) & 0x07); - - /* Apply recommended settings */ - - mrf24j40_setreg(dev->spi, MRF24J40_PACON2 , 0x98); /* 10011000 Enable FIFO (default), TXONTS=6 (recommended), TXONT<8:7>=0 */ - mrf24j40_setreg(dev->spi, MRF24J40_TXSTBL , 0x95); /* 10010101 set the SIFS period. RFSTBL=9, MSIFS=5, aMinSIFSPeriod=14 (min 12) */ - mrf24j40_setreg(dev->spi, MRF24J40_TXPEND , 0x7C); /* 01111100 set the LIFS period, MLIFS=1Fh=31 aMinLIFSPeriod=40 (min 40) */ - mrf24j40_setreg(dev->spi, MRF24J40_TXTIME , 0x30); /* 00110000 set the turnaround time, TURNTIME=3 aTurnAroundTime=12 */ - mrf24j40_setreg(dev->spi, MRF24J40_RFCON1 , 0x02); /* 00000010 VCO optimization, recommended value */ - mrf24j40_setreg(dev->spi, MRF24J40_RFCON2 , 0x80); /* 10000000 Enable PLL */ - mrf24j40_setreg(dev->spi, MRF24J40_RFCON6 , 0x90); /* 10010000 TX filter enable, fast 20M recovery, No bat monitor*/ - mrf24j40_setreg(dev->spi, MRF24J40_RFCON7 , 0x80); /* 10000000 Sleep clock on internal 100 kHz */ - mrf24j40_setreg(dev->spi, MRF24J40_RFCON8 , 0x10); /* 00010000 VCO control bit, as recommended */ - mrf24j40_setreg(dev->spi, MRF24J40_SLPCON1, 0x01); /* 00000001 no CLKOUT, default divisor */ - mrf24j40_setreg(dev->spi, MRF24J40_BBREG6 , 0x40); /* 01000000 Append RSSI to rx packets */ - - return OK; -} - /**************************************************************************** * Name: mrf24j40_setrxmode * @@ -1208,7 +1234,7 @@ static int mrf24j40_setpanid(FAR struct mrf24j40_radio_s *dev, mrf24j40_setreg(dev->spi, MRF24J40_PANIDH, panid[1]); IEEE802154_PANIDCOPY(dev->addr.panid, panid); - wlinfo("%02X:%02X\n", panid[1], panid[0]); + wlinfo("%02X:%02X\n", panid[0], panid[1]); return OK; } @@ -1231,7 +1257,7 @@ static int mrf24j40_setsaddr(FAR struct mrf24j40_radio_s *dev, IEEE802154_SADDRCOPY(dev->addr.saddr, saddr); - wlinfo("%02X:%02X\n", saddr[1], saddr[0]); + wlinfo("%02X:%02X\n", saddr[0], saddr[1]); return OK; } @@ -1254,6 +1280,8 @@ static int mrf24j40_seteaddr(FAR struct mrf24j40_radio_s *dev, mrf24j40_setreg(dev->spi, MRF24J40_EADR0 + i, eaddr[i]); dev->addr.eaddr[i] = eaddr[i]; } + wlinfo("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n", eaddr[0], eaddr[1], + eaddr[2], eaddr[3], eaddr[4], eaddr[5], eaddr[6], eaddr[7]); return OK; } @@ -1276,7 +1304,7 @@ static int mrf24j40_setcoordsaddr(FAR struct mrf24j40_radio_s *dev, IEEE802154_SADDRCOPY(dev->addr.saddr, saddr); - wlinfo("%02X:%02X\n", saddr[1], saddr[0]); + wlinfo("%02X:%02X\n", saddr[0], saddr[1]); return OK; } @@ -1300,6 +1328,8 @@ static int mrf24j40_setcoordeaddr(FAR struct mrf24j40_radio_s *dev, dev->addr.eaddr[i] = eaddr[i]; } + wlinfo("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n", eaddr[0], eaddr[1], + eaddr[2], eaddr[3], eaddr[4], eaddr[5], eaddr[6], eaddr[7]); return OK; } @@ -1393,7 +1423,7 @@ static int mrf24j40_settxpower(FAR struct mrf24j40_radio_s *dev, return -EINVAL; } - wlinfo("remaining attenuation: %d mBm\n",txpwr); + wlinfo("Remaining attenuation: %d mBm\n",txpwr); switch(txpwr/100) { @@ -1422,235 +1452,494 @@ static int mrf24j40_settxpower(FAR struct mrf24j40_radio_s *dev, case -1: reg |= 0x02; + break; + + case 0: + reg |= 0x00; /* value 0x01 is 0.5 db, not used */ + break; + + default: + return -EINVAL; + } + + mrf24j40_setreg(dev->spi, MRF24J40_RFCON3, reg); + dev->txpower = save_txpwr; + return OK; + } + + /**************************************************************************** + * Name: mrf24j40_setcca + * + * Description: + * Define the Clear Channel Assessement method. + * + ****************************************************************************/ + + static int mrf24j40_setcca(FAR struct mrf24j40_radio_s *dev, + FAR struct ieee802154_cca_s *cca) + { + uint8_t mode; + + if (!cca->use_ed && !cca->use_cs) + { + return -EINVAL; + } + + if (cca->use_cs && cca->csth > 0x0f) + { + return -EINVAL; + } + + mode = mrf24j40_getreg(dev->spi, MRF24J40_BBREG2); + mode &= 0x03; + + if (cca->use_ed) + { + mode |= MRF24J40_BBREG2_CCAMODE_ED; + mrf24j40_setreg(dev->spi, MRF24J40_CCAEDTH, cca->edth); + } + + if (cca->use_cs) + { + mode |= MRF24J40_BBREG2_CCAMODE_CS; + mode |= cca->csth << 2; + } + + mrf24j40_setreg(dev->spi, MRF24J40_BBREG2, mode); + + memcpy(&dev->cca, cca, sizeof(struct ieee802154_cca_s)); + return OK; + } + + /**************************************************************************** + * Name: mrf24j40_regdump + * + * Description: + * Display the value of all registers. + * + ****************************************************************************/ + + static int mrf24j40_regdump(FAR struct mrf24j40_radio_s *dev) + { + uint32_t i; + char buf[4+16*3+2+1]; + int len = 0; + + wlinfo("Short regs:\n"); + + for (i = 0; i < 0x40; i++) + { + if ((i & 15) == 0) + { + len=sprintf(buf, "%02x: ",i&0xFF); + } + + len += sprintf(buf+len, "%02x ", mrf24j40_getreg(dev->spi, i)); + if ((i & 15) == 15) + { + sprintf(buf+len, "\n"); + wlinfo("%s", buf); + } + } + + wlinfo("Long regs:\n"); + for (i = 0x80000200; i < 0x80000250; i++) + { + if ((i & 15) == 0) + { + len=sprintf(buf, "%02x: ",i&0xFF); + } + + len += sprintf(buf+len, "%02x ", mrf24j40_getreg(dev->spi, i)); + if ((i & 15) == 15) + { + sprintf(buf+len, "\n"); + wlinfo("%s", buf); + } + } + + return 0; + } + + /**************************************************************************** + * Name: mrf24j40_energydetect + * + * Description: + * Measure the RSSI level for the current channel. + * + ****************************************************************************/ + + static int mrf24j40_energydetect(FAR struct mrf24j40_radio_s *dev, + FAR uint8_t *energy) + { + uint8_t reg; + + /* Manually enable the LNA*/ + + mrf24j40_pacontrol(dev, MRF24J40_PA_ED); + + /* Set RSSI average duration to 8 symbols */ + + reg = mrf24j40_getreg(dev->spi, MRF24J40_TXBCON1); + reg |= 0x30; + mrf24j40_setreg(dev->spi, MRF24J40_TXBCON1, reg); + + /* 1. Set RSSIMODE1 0x3E<7> – Initiate RSSI calculation. */ + + mrf24j40_setreg(dev->spi, MRF24J40_BBREG6, 0x80); + + /* 2. Wait until RSSIRDY 0x3E<0> is set to ‘1’ – RSSI calculation is + * complete. + */ + + while(!(mrf24j40_getreg(dev->spi, MRF24J40_BBREG6) & 0x01)); + + /* 3. Read RSSI 0x210<7:0> – The RSSI register contains the averaged RSSI + * received power level for 8 symbol periods. + */ + + *energy = mrf24j40_getreg(dev->spi, MRF24J40_RSSI); + + mrf24j40_setreg(dev->spi, MRF24J40_BBREG6, 0x40); + + /* Back to automatic control */ + + mrf24j40_pacontrol(dev, MRF24J40_PA_AUTO); + return OK; + } + + /**************************************************************************** + * Name: mrf24j40_norm_setup + * + * Description: + * Setup a transaction in the normal TX FIFO + * + ****************************************************************************/ + + static void mrf24j40_norm_setup(FAR struct mrf24j40_radio_s *dev, + FAR struct iob_s *frame, bool csma) + { + uint8_t reg; + + /* Enable tx int */ + + reg = mrf24j40_getreg(dev->spi, MRF24J40_INTCON); + 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 */ + + mrf24j40_setup_fifo(dev, frame->io_data, frame->io_len, MRF24J40_TXNORM_FIFO); + + /* If the frame control field contains an acknowledgment request, set the + * TXNACKREQ bit. See IEEE 802.15.4/2003 7.2.1.1 page 112 for info. + */ + + reg = mrf24j40_getreg(dev->spi, MRF24J40_TXNCON); + + if (frame->io_data[0] & IEEE802154_FRAMECTRL_ACKREQ) + { + reg |= MRF24J40_TXNCON_TXNACKREQ; + } + else + { + reg &= ~MRF24J40_TXNCON_TXNACKREQ; + } + + mrf24j40_setreg(dev->spi, MRF24J40_TXNCON, reg); + } + + /**************************************************************************** + * 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_beacon_trigger + + * + + * Description: + + * Trigger the beacon TX FIFO + + * + + ****************************************************************************/ + + + +static inline void mrf24j40_beacon_trigger(FAR struct mrf24j40_radio_s *dev) +{ + uint8_t reg; + + reg = mrf24j40_getreg(dev->spi, MRF24J40_TXBCON0); + + reg |= MRF24J40_TXBCON0_TXBTRIG; + + mrf24j40_setreg(dev->spi, MRF24J40_TXBCON0, reg); } /**************************************************************************** @@ -1678,6 +1967,7 @@ static void mrf24j40_setup_fifo(FAR struct mrf24j40_radio_s *dev, FAR const uint8_t *buf, uint8_t length, uint32_t fifo_addr) { + int hlen = 3; /* Include frame control and seq number */ int i; uint16_t frame_ctrl; @@ -1714,6 +2004,7 @@ static void mrf24j40_setup_fifo(FAR struct mrf24j40_radio_s *dev, mrf24j40_setreg(dev->spi, fifo_addr++, hlen); + /* Frame length */ mrf24j40_setreg(dev->spi, fifo_addr++, length); @@ -1783,6 +2074,7 @@ static void mrf24j40_irqwork_txnorm(FAR struct mrf24j40_radio_s *dev) MRF24J40_TXNCON_FPSTAT); if (dev->txdelayed_busy) + { /* Inform the next layer of the transmission success/failure */ @@ -1924,6 +2216,7 @@ static int mrf24j40_rxenable(FAR struct ieee802154_radio_s *radio, bool enable) ****************************************************************************/ static void mrf24j40_irqwork_rx(FAR struct mrf24j40_radio_s *dev) + { FAR struct ieee802154_data_ind_s *ind; uint32_t addr; @@ -1957,9 +2250,6 @@ static void mrf24j40_irqwork_rx(FAR struct mrf24j40_radio_s *dev) 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 */ - for (index = 0; index < ind->frame->io_len; index++) { ind->frame->io_data[index] = mrf24j40_getreg(dev->spi, addr++); @@ -2089,6 +2379,19 @@ static void mrf24j40_irqworker(FAR void *arg) mrf24j40_setreg(dev->spi, MRF24J40_SLPACK, reg); } + if ((intstat & MRF24J40_INTSTAT_WAKEIF)) + { + wlinfo("Wake Interrupt\n"); + /* This is right before the beacon, we set the bsn here, since the MAC + * uses the SLPIF (end of active portion of superframe). to make any + * changes to the beacon. This assumes that any changes to the beacon + * be in by the time that this interrupt fires. + */ + + mrf24j40_setreg(dev->spi, MRF24J40_BEACON_FIFO + 4, dev->bsn++); + mrf24j40_beacon_trigger(dev); + } + /* Unlock the radio device */ sem_post(&dev->exclsem); @@ -2155,7 +2458,6 @@ FAR struct ieee802154_radio_s *mrf24j40_init(FAR struct spi_dev_s *spi, FAR const struct mrf24j40_lower_s *lower) { FAR struct mrf24j40_radio_s *dev; - struct ieee802154_cca_s cca; dev = kmm_zalloc(sizeof(struct mrf24j40_radio_s)); if (dev == NULL) @@ -2178,13 +2480,12 @@ FAR struct ieee802154_radio_s *mrf24j40_init(FAR struct spi_dev_s *spi, sem_init(&dev->exclsem, 0, 1); dev->radio.bind = mrf24j40_bind; + dev->radio.reset = mrf24j40_reset; + dev->radio.getattr = mrf24j40_getattr; + dev->radio.setattr = mrf24j40_setattr; 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->radio.beaconstart = mrf24j40_beaconstart; dev->radio.beaconupdate = mrf24j40_beaconupdate; dev->radio.beaconstop = mrf24j40_beaconstop; @@ -2193,35 +2494,9 @@ FAR struct ieee802154_radio_s *mrf24j40_init(FAR struct spi_dev_s *spi, dev->lower = lower; dev->spi = spi; - - dev->rxenabled = false; - mrf24j40_initialize(dev); - - mrf24j40_setchannel(dev, 11); - mrf24j40_setpanid(dev, g_allones); - mrf24j40_setsaddr(dev, g_allones); - mrf24j40_seteaddr(dev, g_allones); - - /* Default device params */ - - cca.use_ed = 1; - cca.use_cs = 0; - cca.edth = 0x60; /* CCA mode ED, no carrier sense, recommenced ED threshold -69 dBm */ - mrf24j40_setcca(dev, &cca); - - mrf24j40_setrxmode(dev, MRF24J40_RXMODE_NORMAL); - - mrf24j40_settxpower(dev, 0); /*16. Set transmitter power .*/ - - 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); + mrf24j40_reset(&dev->radio); dev->lower->enable(dev->lower, true); return &dev->radio; } + diff --git a/drivers/wireless/ieee802154/mrf24j40.h b/drivers/wireless/ieee802154/mrf24j40/mrf24j40.h similarity index 97% rename from drivers/wireless/ieee802154/mrf24j40.h rename to drivers/wireless/ieee802154/mrf24j40/mrf24j40.h index e4e4e8ba5e..c21c2e9f38 100644 --- a/drivers/wireless/ieee802154/mrf24j40.h +++ b/drivers/wireless/ieee802154/mrf24j40/mrf24j40.h @@ -1,5 +1,5 @@ /**************************************************************************** - * drivers/wireless/ieee802154/mrf24j40.h + * drivers/wireless/ieee802154/mrf24j40/mrf24j40.h * * Copyright (C) 2015-2016 Sebastien Lorquet. All rights reserved. * Author: Sebastien Lorquet @@ -33,8 +33,8 @@ * ****************************************************************************/ -#ifndef __DRIVERS_WIRELESS_IEEE802154_MRF24J40_H -#define __DRIVERS_WIRELESS_IEEE802154_MRF24J40_H +#ifndef __DRIVERS_WIRELESS_IEEE802154_MRF24J40_MRF24J40_H +#define __DRIVERS_WIRELESS_IEEE802154_MRF24J40_MRF24J40_H /* MRF24J40 Registers *******************************************************/ @@ -226,6 +226,11 @@ #define MRF24J40_TXSTAT_X_SHIFT 6 #define MRF24J40_TXSTAT_X_MASK (3 << MRF24J40_TXSTAT_X_SHIFT) +/* TXBCON0 bits */ + +#define MRF24J40_TXBCON0_TXBTRIG 0x01 +#define MRF24J40_TXBCON0_TXBSECEN 0x02 + /* TXBCON1 bits */ #define MRF24J40_TXBCON1_RSSINUM 0x30 @@ -281,4 +286,5 @@ #define MRF24J40_RXFLUSH_SHIFT_WAKEPAD 5 #define MRF24J40_RXFLUSH_SHIFT_WAKEPOL 6 -#endif /* __DRIVERS_WIRELESS_IEEE802154_MRF24J40_H */ +#endif /* __DRIVERS_WIRELESS_IEEE802154_MRF24J40_MRF24J40_H */ + diff --git a/include/nuttx/wireless/ieee802154/ieee802154_mac.h b/include/nuttx/wireless/ieee802154/ieee802154_mac.h index b079a32902..1526ad3f0f 100644 --- a/include/nuttx/wireless/ieee802154/ieee802154_mac.h +++ b/include/nuttx/wireless/ieee802154/ieee802154_mac.h @@ -593,19 +593,10 @@ struct ieee802154_pandesc_s * in symbols */ }; -struct ieee802154_pend_addr_s +struct ieee802154_pendaddr_s { - union - { - uint8_t pa_spec; - struct - { - uint8_t num_short_addr : 3; /* Number of short addresses pending */ - uint8_t reserved_3 : 1; /* Reserved bit */ - uint8_t num_ext_addr : 3; /* Number of extended addresses pending */ - uint8_t reserved_7 : 1; /* Reserved bit */ - } pa_addr; - } u; + uint8_t nsaddr : 3; /* Number of short addresses pending */ + uint8_t neaddr : 3; /* Number of extended addresses pending */ struct ieee802154_addr_s addr[7]; /* Array of at most 7 addresses */ }; @@ -632,12 +623,11 @@ union ieee802154_macattr_u bool is_assoc; bool assocpermit; - bool auto_req; + bool autoreq; bool batt_life_ext; bool gts_permit; bool promisc_mode; bool rng_support; - bool resp_waittime; bool rxonidle; bool sec_enabled; bool timestamp_support; @@ -656,6 +646,7 @@ union ieee802154_macattr_u uint32_t tx_ctrl_active_dur; uint32_t tx_ctrl_pause_dur; uint32_t tx_total_dur; + uint8_t resp_waittime; uint8_t beacon_payload[IEEE802154_ATTR_MAC_BEACON_PAYLOAD_LEN]; uint8_t beacon_payload_len; @@ -1112,7 +1103,7 @@ struct ieee802154_disassoc_conf_s * *****************************************************************************/ -struct ieee802154_beaconnotify_ind_s +struct ieee802154_beacon_ind_s { uint8_t bsn; /* Beacon sequence number */ @@ -1122,20 +1113,11 @@ struct ieee802154_beaconnotify_ind_s /* Beacon pending addresses */ - struct ieee802154_pend_addr_s pend_addr; - - uint8_t sdu_length; /* Number of octets contained in the beacon - * payload of the received beacond frame */ - - /* Beacon payload */ - - uint8_t sdu[IEEE802154_MAX_BEACON_PAYLOAD_LEN]; + struct ieee802154_pendaddr_s pendaddr; + uint8_t payloadlength; /* # of octets contained in the beacon payload */ + uint8_t payload[IEEE802154_MAX_BEACON_PAYLOAD_LEN]; }; -#define SIZEOF_IEEE802154_BEACONNOTIFY_IND_S(n) \ - (sizeof(struct ieee802154_beaconnotify_ind_s) \ - - IEEE802154_MAX_BEACON_PAYLOAD_LEN + (n)) - /***************************************************************************** * Primitive: MLME-COMM-STATUS.indication * @@ -1265,7 +1247,7 @@ struct ieee802154_orphan_resp_s struct ieee802154_reset_req_s { - bool rst_pibattr; + bool resetattr; }; /***************************************************************************** @@ -1538,21 +1520,21 @@ union ieee802154_notif_u /* MLME Notifications */ - struct ieee802154_assoc_conf_s assocconf; - struct ieee802154_disassoc_conf_s disassocconf; - struct ieee802154_gts_conf_s gtsconf; - struct ieee802154_rxenable_conf_s rxenableconf; - struct ieee802154_scan_conf_s scanconf; - struct ieee802154_start_conf_s startconf; - struct ieee802154_poll_conf_s pollconf; + struct ieee802154_assoc_conf_s assocconf; + struct ieee802154_disassoc_conf_s disassocconf; + struct ieee802154_gts_conf_s gtsconf; + struct ieee802154_rxenable_conf_s rxenableconf; + struct ieee802154_scan_conf_s scanconf; + struct ieee802154_start_conf_s startconf; + struct ieee802154_poll_conf_s pollconf; - struct ieee802154_assoc_ind_s assocind; - struct ieee802154_disassoc_ind_s disassocind; - struct ieee802154_beaconnotify_ind_s beaconnotifyind; - struct ieee802154_gts_ind_s gtsind; - struct ieee802154_orphan_ind_s orphanind; - struct ieee802154_commstatus_ind_s commstatusind; - struct ieee802154_syncloss_ind_s synclossind; + struct ieee802154_assoc_ind_s assocind; + struct ieee802154_disassoc_ind_s disassocind; + struct ieee802154_beacon_ind_s beaconind; + struct ieee802154_gts_ind_s gtsind; + struct ieee802154_orphan_ind_s orphanind; + struct ieee802154_commstatus_ind_s commstatusind; + struct ieee802154_syncloss_ind_s synclossind; }; struct ieee802154_notif_s diff --git a/include/nuttx/wireless/ieee802154/ieee802154_radio.h b/include/nuttx/wireless/ieee802154/ieee802154_radio.h index 8f851ffe72..b6e802e0ea 100644 --- a/include/nuttx/wireless/ieee802154/ieee802154_radio.h +++ b/include/nuttx/wireless/ieee802154/ieee802154_radio.h @@ -119,20 +119,18 @@ struct ieee802154_radio_s { CODE int (*bind) (FAR struct ieee802154_radio_s *radio, FAR struct ieee802154_radiocb_s *radiocb); + CODE int (*reset) (FAR struct ieee802154_radio_s *radio); + CODE int (*getattr) (FAR struct ieee802154_radio_s *radio, + enum ieee802154_attr_e , + FAR union ieee802154_attr_u *attrval); + CODE int (*setattr) (FAR struct ieee802154_radio_s *radio, + enum ieee802154_attr_e , + FAR const union ieee802154_attr_u *attrval); 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_attr_e , - FAR union ieee802154_attr_u *attrval); - CODE int (*set_attr) (FAR struct ieee802154_radio_s *radio, - enum ieee802154_attr_e , - FAR const union ieee802154_attr_u *attrval); CODE int (*rxenable) (FAR struct ieee802154_radio_s *radio, bool enable); - CODE int (*req_rxenable)(FAR struct ieee802154_radio_s *radio, - FAR struct ieee802154_rxenable_req_s *req); CODE int (*beaconstart)(FAR struct ieee802154_radio_s *radio, FAR const struct ieee802154_superframespec_s *sfspec, FAR struct ieee802154_beaconframe_s *beacon); diff --git a/wireless/ieee802154/Make.defs b/wireless/ieee802154/Make.defs index 26705a51a7..18b52f2cf7 100644 --- a/wireless/ieee802154/Make.defs +++ b/wireless/ieee802154/Make.defs @@ -37,7 +37,7 @@ ifeq ($(CONFIG_WIRELESS_IEEE802154),y) # Include IEEE 802.15.4 support -CSRCS += mac802154.c mac802154_indalloc.c mac802154_assoc.c mac802154_disassoc.c +CSRCS += ieee802154_indalloc.c mac802154.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 diff --git a/wireless/ieee802154/mac802154_indalloc.c b/wireless/ieee802154/ieee802154_indalloc.c similarity index 100% rename from wireless/ieee802154/mac802154_indalloc.c rename to wireless/ieee802154/ieee802154_indalloc.c diff --git a/wireless/ieee802154/mac802154.c b/wireless/ieee802154/mac802154.c index af5e4523f7..09a3ab0274 100644 --- a/wireless/ieee802154/mac802154.c +++ b/wireless/ieee802154/mac802154.c @@ -354,9 +354,9 @@ void mac802154_createdatareq(FAR struct ieee802154_privmac_s *priv, memcpy(&txdesc->destaddr, &coordaddr, sizeof(struct ieee802154_addr_s)); - /* Copy the IOB reference to the descriptor */ + /* Save a reference of the tx descriptor */ - txdesc->frame = iob; + priv->cmd_desc = txdesc; } /**************************************************************************** @@ -417,9 +417,11 @@ void mac802154_updatebeacon(FAR struct ieee802154_privmac_s *priv) IEEE802154_SETSADDRMODE(beacon->bf_data, 0, priv->addr.mode); IEEE802154_SETVERSION(beacon->bf_data, 0, 1); - /* Copy in and increment the beacon sequence number */ + /* The beacon sequence number has to be taken care of by the radio layer, since + * we only want to update the whole frame when more changes than just the bsn. + */ - beacon->bf_data[beacon->bf_len++] = priv->bsn++; + beacon->bf_len++; IEEE802154_PANIDCOPY(&beacon->bf_data[beacon->bf_len], priv->addr.panid); beacon->bf_len += IEEE802154_PANIDSIZE; @@ -580,8 +582,8 @@ void mac802154_setupindirect(FAR struct ieee802154_privmac_s *priv, if (work_available(&priv->purge_work)) { - //work_queue(MAC802154_WORK, &priv->purge_work, mac802154_purge_worker, - // (FAR void *)priv, ticks); + work_queue(MAC802154_WORK, &priv->purge_work, mac802154_purge_worker, + (FAR void *)priv, ticks); } } @@ -636,8 +638,8 @@ static void mac802154_purge_worker(FAR void *arg) /* 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_notif_free_locked(priv, + (FAR struct ieee802154_notif_s *)txdesc->conf); mac802154_txdesc_free(priv, txdesc); priv->beaconupdate = true; @@ -760,7 +762,6 @@ static void mac802154_txdone_worker(FAR void *arg) (FAR struct ieee802154_privmac_s *)arg; FAR struct ieee802154_txdesc_s *txdesc; FAR struct ieee802154_notif_s *notif; - FAR struct mac802154_notif_s *privnotif; /* Get exclusive access to the driver structure. We don't care about any * signals so don't allow interruptions @@ -781,8 +782,9 @@ static void mac802154_txdone_worker(FAR void *arg) * notification structure to make it easier to use. */ - privnotif = (FAR struct mac802154_notif_s *)txdesc->conf; - notif = &privnotif->pub; + notif =(FAR struct ieee802154_notif_s *)txdesc->conf; + + wlinfo("Tx status: %s\n", IEEE802154_STATUS_STRING[txdesc->conf->status]); switch(txdesc->frametype) { @@ -857,14 +859,7 @@ static void mac802154_txdone_worker(FAR void *arg) 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. - */ - - privnotif->flink = priv->notif_free; - priv->notif_free = privnotif; - priv->nnotif = 0; + mac802154_notif_free_locked(priv, notif); break; } } @@ -872,13 +867,7 @@ static void mac802154_txdone_worker(FAR void *arg) 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. - */ - - privnotif->flink = priv->notif_free; - priv->notif_free = privnotif; + mac802154_notif_free_locked(priv, notif); } break; } @@ -926,7 +915,7 @@ static void mac802154_rxframe(FAR const struct ieee802154_radiocb_s *radiocb, sq_addlast((FAR sq_entry_t *)ind, &priv->dataind_queue); - wlinfo("frame received\n"); + wlinfo("Frame received\n"); mac802154_givesem(&priv->exclsem); @@ -1100,7 +1089,6 @@ static void mac802154_rxframe_worker(FAR void *arg) case IEEE802154_CMD_ORPHAN_NOT: wlinfo("Orphan notif received\n"); break; - break; case IEEE802154_CMD_BEACON_REQ: wlinfo("Beacon request received\n"); @@ -1178,7 +1166,9 @@ static void mac802154_rxdataframe(FAR struct ieee802154_privmac_s *priv, * FIXME: Fix documentation */ - if (priv->curr_op == MAC802154_OP_POLL || priv->curr_op == MAC802154_OP_ASSOC) + if (priv->curr_op == MAC802154_OP_POLL || + priv->curr_op == MAC802154_OP_ASSOC || + priv->curr_op == MAC802154_OP_AUTOEXTRACT) { /* If we are in promiscuous mode, we need to check if the * frame is even for us first. If the address is not ours, @@ -1232,7 +1222,8 @@ static void mac802154_rxdataframe(FAR struct ieee802154_privmac_s *priv, } /* If we've gotten this far, the frame is our extracted data. Cancel the - * timeout */ + * timeout + */ mac802154_timercancel(priv); @@ -1524,15 +1515,27 @@ static void mac802154_sfevent(FAR const struct ieee802154_radiocb_s *radiocb, mac802154_takesem(&priv->exclsem, false); - /* Check if there is any reason to update the beacon */ - - if (priv->beaconupdate) + switch (sfevent) { - mac802154_updatebeacon(priv); + case IEEE802154_SFEVENT_ENDOFACTIVE: + { + wlinfo("End of superframe\n"); - priv->radio->beaconupdate(priv->radio, &priv->beaconframe[priv->bf_ind]); + /* Check if there is any reason to update the beacon */ + + if (priv->beaconupdate) + { + mac802154_updatebeacon(priv); + + priv->radio->beaconupdate(priv->radio, &priv->beaconframe[priv->bf_ind]); + } + } + break; + default: + break; } + mac802154_givesem(&priv->exclsem); } @@ -1543,51 +1546,182 @@ static void mac802154_sfevent(FAR const struct ieee802154_radiocb_s *radiocb, * Function called from the generic RX Frame worker to parse and handle the * reception of a beacon frame. * + * Assumptions: MAC is locked + * ****************************************************************************/ static void mac802154_rxbeaconframe(FAR struct ieee802154_privmac_s *priv, FAR struct ieee802154_data_ind_s *ind) { - FAR struct iob_s *iob = ind->frame; - struct ieee802154_pandesc_s pandesc; FAR struct ieee802154_txdesc_s *respdesc; - uint8_t numgtsdesc; + FAR struct ieee802154_notif_s *notif; + FAR struct ieee802154_beacon_ind_s *beacon; + FAR struct iob_s *iob = ind->frame; + uint8_t ngtsdesc; uint8_t gtsdirmask; - uint8_t npendsaddr; - uint8_t npendeaddr; + bool pending_saddr = false; + bool pending_eaddr = false; int i; + /* Even though we may not use the notification, we use a notification to + * hold all the parsed beacon information. Freeing the notification is quick, + * so it's worth saving a copy (If you were to parse all the info in locally, + * you would have to copy the data over in the case that you actually need + * to notify the next highest layer) + */ + + mac802154_notif_alloc(priv, ¬if, false); + beacon = ¬if->u.beaconind; + + /* Make sure there is another 2 bytes to process */ + + if (iob->io_len < iob->io_offset + 2) + { + goto errout; + } + /* Copy the coordinator address and channel info into the pan descriptor */ - memcpy(&pandesc.coordaddr, &ind->src, sizeof(struct ieee802154_addr_s)); - pandesc.chan = priv->currscan.channels[priv->scanindex]; - pandesc.chpage = priv->currscan.chpage; - pandesc.lqi = ind->lqi; - pandesc.timestamp = ind->timestamp; + memcpy(&beacon->pandesc.coordaddr, &ind->src, sizeof(struct ieee802154_addr_s)); + beacon->pandesc.chan = priv->currscan.channels[priv->scanindex]; + beacon->pandesc.chpage = priv->currscan.chpage; + beacon->pandesc.lqi = ind->lqi; + beacon->pandesc.timestamp = ind->timestamp; /* Parse the superframe specification field */ - pandesc.sfspec.beaconorder = IEEE802154_GETBEACONORDER(iob->io_data, - iob->io_offset); + beacon->pandesc.sfspec.beaconorder = IEEE802154_GETBEACONORDER(iob->io_data, + iob->io_offset); + + beacon->pandesc.sfspec.sforder = + IEEE802154_GETSFORDER(iob->io_data, iob->io_offset); + + beacon->pandesc.sfspec.final_capslot = + IEEE802154_GETFINCAPSLOT(iob->io_data, iob->io_offset); + + beacon->pandesc.sfspec.ble = + IEEE802154_GETBLE(iob->io_data, iob->io_offset); + + beacon->pandesc.sfspec.pancoord = + IEEE802154_GETPANCOORD(iob->io_data, iob->io_offset); + + beacon->pandesc.sfspec.assocpermit = + IEEE802154_GETASSOCPERMIT(iob->io_data, iob->io_offset); - pandesc.sfspec.sforder = IEEE802154_GETSFORDER(iob->io_data, iob->io_offset); - pandesc.sfspec.final_capslot = IEEE802154_GETFINCAPSLOT(iob->io_data, - iob->io_offset); - pandesc.sfspec.ble = IEEE802154_GETBLE(iob->io_data, iob->io_offset); - pandesc.sfspec.pancoord = IEEE802154_GETPANCOORD(iob->io_data, iob->io_offset); - pandesc.sfspec.assocpermit = IEEE802154_GETASSOCPERMIT(iob->io_data, - iob->io_offset); iob->io_offset += 2; + /* Make sure there is another byte to process (GTS Spec) */ + + if (iob->io_len < iob->io_offset + 1) + { + goto errout; + } + /* Parse the GTS Specification field */ - numgtsdesc = IEEE802154_GETGTSDESCCOUNT(iob->io_data, iob->io_offset); - pandesc.gtspermit = IEEE802154_GETGTSPERMIT(iob->io_data, iob->io_offset); + ngtsdesc = IEEE802154_GETGTSDESCCOUNT(iob->io_data, iob->io_offset); + beacon->pandesc.gtspermit = IEEE802154_GETGTSPERMIT(iob->io_data, iob->io_offset); iob->io_offset++; - /* We only need to parse the rest of the frame if we are not performing a - * scan - */ + /* If there are any GTS descriptors, handle the GTS Dir and GTS List fields */ + + if (ngtsdesc > 0) + { + /* Make sure there is another bytes to process (GTS Direction) */ + + if (iob->io_len < iob->io_offset + 1) + { + goto errout; + } + + gtsdirmask = IEEE802154_GETGTSDIRMASK(iob->io_data, iob->io_offset); + UNUSED(gtsdirmask); + iob->io_offset++; + + /* Make sure there are enough bytes left to represent the GTS List */ + + if (iob->io_len < iob->io_offset + (3 * ngtsdesc)) + { + goto errout; + } + + for (i = 0; i < ngtsdesc; i++) + { + /* For now we just discard the data by skipping over it */ + + iob->io_offset += 3; + } + } + + /* Pending address fields. Min 1 byte, the Pending Address Specification */ + + if (iob->io_len < iob->io_offset + 1) + { + goto errout; + } + + beacon->pendaddr.nsaddr = IEEE802154_GETNPENDSADDR(iob->io_data, iob->io_offset); + beacon->pendaddr.neaddr = IEEE802154_GETNPENDEADDR(iob->io_data, iob->io_offset); + iob->io_offset++; + + /* Make sure there are enough bytes left to represent the address list */ + + if (iob->io_len < (iob->io_offset + + (IEEE802154_SADDRSIZE * beacon->pendaddr.nsaddr) + + (IEEE802154_EADDRSIZE * beacon->pendaddr.neaddr))) + { + goto errout; + } + + /* Copy in the pending addresses */ + + for (i = 0; i < beacon->pendaddr.nsaddr; i++) + { + beacon->pendaddr.addr[i].mode = IEEE802154_ADDRMODE_SHORT; + mac802154_takesaddr(iob, beacon->pendaddr.addr[i].saddr); + + /* Check if the short address matches our short address */ + + if (IEEE802154_SADDRCMP(beacon->pendaddr.addr[i].saddr, priv->addr.saddr)) + { + /* Wait to actually decide how to handle this until we parse + * the rest of the frame + */ + wlinfo("Data pending for us in coord\n"); + pending_saddr = true; + } + } + + for (i = beacon->pendaddr.nsaddr; + i < (beacon->pendaddr.nsaddr + beacon->pendaddr.neaddr); + i++) + { + beacon->pendaddr.addr[i].mode = IEEE802154_ADDRMODE_EXTENDED; + + mac802154_takeeaddr(iob, beacon->pendaddr.addr[i].eaddr); + + /* If the extended address matches our extended address */ + + if (IEEE802154_EADDRCMP(beacon->pendaddr.addr[i].eaddr, priv->addr.eaddr)) + { + /* Wait to actually decide how to handle this until we parse + * the rest of the frame + */ + wlinfo("Data pending for us in coord\n"); + pending_eaddr = true; + } + } + + /* If there is anything left in the frame, process it as the beacon payload */ + + beacon->payloadlength = iob->io_len - iob->io_offset; + + if (beacon->payloadlength > 0) + { + memcpy(beacon->payload, &iob->io_data[iob->io_offset], beacon->payloadlength); + } + + /* At this point, we have extracted all relevant info from the incoming frame */ if (priv->curr_op == MAC802154_OP_SCAN) { @@ -1601,19 +1735,31 @@ static void mac802154_rxbeaconframe(FAR struct ieee802154_privmac_s *priv, } if (memcmp(&ind->src, &priv->pandescs[i].coordaddr, - sizeof(struct ieee802154_addr_s))) + sizeof(struct ieee802154_addr_s)) != 0) { continue; } /* The beacon is the same as another, so discard it */ + mac802154_notif_free_locked(priv, notif); return; } + /* TODO: There is supposed to be different logic for the scanning procedure + * based on the macAutoRequest attribute. Currently, we perform scan + * operations as if macAutoRequest is set to TRUE, without actually checking + * the value. Basically, if macAutoRequest is TRUE, we are supposed to + * round up all of the pandesc results and pass them all up via the + * SCAN.confirm primitive. If macAutoRequest is FALSE, we are supposed + * to notify the next highest layer each time a unique beacon is received + * via the BEACON.notify primitive, and pass a NULLed out list of pandesc + * when SCAN.confirm is sent. + */ + /* Copy the pan desc to the list of pan desc */ - memcpy(&priv->pandescs[priv->npandesc], &pandesc, + memcpy(&priv->pandescs[priv->npandesc], &beacon->pandesc, sizeof(struct ieee802154_pandesc_s)); priv->npandesc++; @@ -1622,69 +1768,97 @@ static void mac802154_rxbeaconframe(FAR struct ieee802154_privmac_s *priv, mac802154_scanfinish(priv, IEEE802154_STATUS_LIMITREACHED); } } + + /* If we are not performing a SCAN operation */ + else { - /* If there are any GTS descriptors, handle the GTS Directions and - * GTS List fields - */ + /* Check the superframe structure and update the appropriate attributes. */ - if (numgtsdesc > 0) + if (memcmp(&priv->sfspec, &beacon->pandesc.sfspec, + sizeof(struct ieee802154_superframespec_s)) != 0) { - gtsdirmask = IEEE802154_GETGTSDIRMASK(iob->io_data, iob->io_offset); - iob->io_offset++; + /* Copy in the new superframe spec */ - for (i = 0; i < numgtsdesc; i++) - { - /* For now we just discard the data by skipping over it */ + memcpy(&priv->sfspec, &beacon->pandesc.sfspec, + sizeof(struct ieee802154_superframespec_s)); - iob->io_offset += 3; - } + /* Tell the radio layer about the superframe spec update */ + + priv->radio->sfupdate(priv->radio, &priv->sfspec); } - /* Pending address fields. Min 1 byte, the Pending Address Specification */ - - npendsaddr = IEEE802154_GETNPENDSADDR(iob->io_data, iob->io_offset); - npendeaddr = IEEE802154_GETNPENDEADDR(iob->io_data, iob->io_offset); - iob->io_offset++; - - /* The pending address field tells us whether or not there is any data - * pending for us. + /* If we are performing an association and there is data pending for us + * we ignore the autoRequest logic and just extract it. We also don't + * send a BEACON-NOTFIY.indication in this case, not sure if that + * is the right thing to do, can't find anything definitive in standard. */ - for (i = 0; i < npendsaddr; i++) + if (priv->curr_op == MAC802154_OP_ASSOC && pending_eaddr) { - /* If the short address matches our short address */ + priv->curr_cmd = IEEE802154_CMD_DATA_REQ; + mac802154_txdesc_alloc(priv, &respdesc, false); + mac802154_createdatareq(priv, &priv->pandesc.coordaddr, + IEEE802154_ADDRMODE_EXTENDED, respdesc); - if (IEEE802154_SADDRCMP(&iob->io_data[iob->io_offset], priv->addr.saddr)) - { - /* TODO: Handle data pending in coordinator for us */ - } - iob->io_offset += IEEE802154_SADDRSIZE; + /* Link the transaction into the CSMA transaction list */ + + sq_addlast((FAR sq_entry_t *)respdesc, &priv->csma_queue); + + /* Notify the radio driver that there is data available */ + + priv->radio->txnotify(priv->radio, false); } - - for (i = 0; i < npendeaddr; i++) + else { - /* If the extended address matches our extended address */ - - if (IEEE802154_EADDRCMP(&iob->io_data[iob->io_offset], priv->addr.eaddr)) + if (priv->autoreq || priv->curr_op == MAC802154_OP_POLL) { - /* If we are associating, polling, or if macAutoRequest is TRUE, - * extract the data. + /* If a beacon frame is received and macAutoRequest is set to + * TRUE, the MLME shall first issue the MLME- + * BEACON-NOTIFY.indication primitive if the beacon contains any + * payload. */ - if ((priv->autoreq) || (priv->curr_op == MAC802154_OP_ASSOC) || - (priv->curr_op == MAC802154_OP_POLL)) + if (beacon->payloadlength > 0) + { + /* Unlock the MAC, notify, then lock again */ + + mac802154_givesem(&priv->exclsem); + mac802154_notify(priv, notif); + mac802154_takesem(&priv->exclsem, false); + } + + /* If we have data pending for us, attempt to extract it. If for some + * reason we have data pending under our short address and our + * extended address, let the short address arbitrarily take precedence + */ + + if (pending_saddr | pending_eaddr) { mac802154_txdesc_alloc(priv, &respdesc, false); - mac802154_createdatareq(priv, &priv->pandesc.coordaddr, - IEEE802154_ADDRMODE_EXTENDED, respdesc); - - if (priv->curr_op == MAC802154_OP_ASSOC || - priv->curr_op == MAC802154_OP_POLL) + if (priv->curr_op == MAC802154_OP_POLL) { priv->curr_cmd = IEEE802154_CMD_DATA_REQ; } + else if (priv->curr_op == MAC802154_OP_NONE) + { + DEBUGASSERT(priv->opsem.semcount == 1); + mac802154_takesem(&priv->opsem, false); + priv->curr_op = MAC802154_OP_AUTOEXTRACT; + priv->curr_cmd = IEEE802154_CMD_DATA_REQ; + } + + if (pending_saddr) + { + mac802154_createdatareq(priv, &priv->pandesc.coordaddr, + IEEE802154_ADDRMODE_SHORT, respdesc); + } + else + { + mac802154_createdatareq(priv, &priv->pandesc.coordaddr, + IEEE802154_ADDRMODE_EXTENDED, respdesc); + } /* Link the transaction into the CSMA transaction list */ @@ -1694,29 +1868,39 @@ static void mac802154_rxbeaconframe(FAR struct ieee802154_privmac_s *priv, priv->radio->txnotify(priv->radio, false); } + + /* If there was a beacon payload, we used the notification, so + * return here to make sure we don't free the notification. + */ + + if (beacon->payloadlength > 0) + { + return; + } } - iob->io_offset += IEEE802154_EADDRSIZE; - } + else + { + /* If a valid beacon frame is received and macAutoRequest is set to FALSE, + * the MLME shall indicate the beacon parameters to the next higher layer + * by issuing the MLME-BEACON-NOTIFY.indication primitive. [1] pg. 38 + */ - /* TODO: Process incoming beacon payload - * If there is anything left in the frame, process it as the beacon payload - */ + /* Unlock the MAC, notify, then lock again */ - /* Check the superframe structure and update the appropriate attributes. */ - - if (memcmp(&priv->sfspec, &pandesc.sfspec, - sizeof(struct ieee802154_superframespec_s)) != 0) - { - /* Copy in the new superframe spec */ - - memcpy(&priv->sfspec, &pandesc.sfspec, - sizeof(struct ieee802154_superframespec_s)); - - /* Tell the radio layer about the superframe spec update */ - - priv->radio->sfupdate(priv->radio, &pandesc.sfspec); + mac802154_givesem(&priv->exclsem); + mac802154_notify(priv, notif); + mac802154_takesem(&priv->exclsem, false); + return; /* Return so that we don't free the notificaiton */ + } } } + + mac802154_notif_free_locked(priv, notif); + return; + +errout: + wlwarn("Received beacon with bad format\n"); + mac802154_notif_free_locked(priv, notif); } /**************************************************************************** @@ -1741,7 +1925,7 @@ static uint32_t mac802154_symtoticks(FAR struct ieee802154_privmac_s *priv, * get overall times. */ - priv->radio->get_attr(priv->radio, IEEE802154_ATTR_PHY_SYMBOL_DURATION, + priv->radio->getattr(priv->radio, IEEE802154_ATTR_PHY_SYMBOL_DURATION, &attrval); /* After this step, ret represents microseconds */ @@ -1832,6 +2016,8 @@ static void mac802154_timeout_expiry(int argc, wdparm_t arg, ...) DEBUGASSERT(priv->timeout_worker != NULL); + wlinfo("Timer expired\n"); + work_queue(MAC802154_WORK, &priv->timeout_work, (worker_t)priv->timeout_worker, priv, 0); } @@ -1879,6 +2065,7 @@ MACHANDLE mac802154_create(FAR struct ieee802154_radio_s *radiodev) if (mac == NULL) { + wlinfo("Failed allocation privmac structure\n"); return NULL; } @@ -1898,8 +2085,6 @@ MACHANDLE mac802154_create(FAR struct ieee802154_radio_s *radiodev) mac->radio = radiodev; - mac802154_req_reset((MACHANDLE)mac, true); - /* Initialize the Radio callbacks */ mac->radiocb.priv = mac; @@ -1919,6 +2104,8 @@ MACHANDLE mac802154_create(FAR struct ieee802154_radio_s *radiodev) ieee802154_indpool_initialize(); mac802154_resetqueues(mac); + mac802154_req_reset((MACHANDLE)mac, true); + /* Set the default extended address */ for (i = 0; i < IEEE802154_EADDRSIZE; i++) @@ -1926,9 +2113,7 @@ MACHANDLE mac802154_create(FAR struct ieee802154_radio_s *radiodev) eaddr[i] = (CONFIG_IEEE802154_DEFAULT_EADDR >> (8 * i)) & 0xFF; } - IEEE802154_EADDRCOPY(mac->addr.eaddr, eaddr); - mac->radio->set_attr(mac->radio, IEEE802154_ATTR_MAC_EADDR, - (union ieee802154_attr_u *)&eaddr[0]); + mac802154_seteaddr(mac, eaddr); return (MACHANDLE)mac; } diff --git a/wireless/ieee802154/mac802154.h b/wireless/ieee802154/mac802154.h index 90ff021952..d1f3a6b63f 100644 --- a/wireless/ieee802154/mac802154.h +++ b/wireless/ieee802154/mac802154.h @@ -223,11 +223,11 @@ int mac802154_req_gts(MACHANDLE mac, FAR struct ieee802154_gts_req_s *req); * * Input Parameters: * mac - Handle to the MAC layer instance - * rst_pibattr - Whether or not to reset the MAC PIB attributes to defaults + * reset_attr - Whether or not to reset the MAC PIB attributes to defaults * ****************************************************************************/ -int mac802154_req_reset(MACHANDLE mac, bool rst_pibattr); +int mac802154_req_reset(MACHANDLE mac, bool restattr); /**************************************************************************** * Name: mac802154_req_rxenable @@ -368,7 +368,7 @@ int mac802154_resp_orphan(MACHANDLE mac, * ****************************************************************************/ -int mac802154_notif_free(MACHANDLE mac, +void mac802154_notif_free(MACHANDLE mac, FAR struct ieee802154_notif_s *notif); #undef EXTERN diff --git a/wireless/ieee802154/mac802154_assoc.c b/wireless/ieee802154/mac802154_assoc.c index 2027013b7a..6f413eafe6 100644 --- a/wireless/ieee802154/mac802154_assoc.c +++ b/wireless/ieee802154/mac802154_assoc.c @@ -86,8 +86,8 @@ int mac802154_req_associate(MACHANDLE mac, (FAR struct ieee802154_privmac_s *)mac; FAR struct ieee802154_txdesc_s *txdesc; FAR struct iob_s *iob; - bool rxonidle; int ret; + int i; if (req->coordaddr.mode == IEEE802154_ADDRMODE_NONE) { @@ -127,8 +127,6 @@ int mac802154_req_associate(MACHANDLE mac, mac802154_setcoordaddr(priv, &req->coordaddr); - /* TODO: Need to send coordinator address to radio layer */ - /* Copy the coordinator PAN ID to our PAN ID */ mac802154_setpanid(priv, req->coordaddr.panid); @@ -138,16 +136,7 @@ int mac802154_req_associate(MACHANDLE mac, 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); + mac802154_setrxonidle(priv, req->capabilities.rxonidle); /* Allocate an IOB to put the frame in */ @@ -250,14 +239,68 @@ int mac802154_req_associate(MACHANDLE mac, priv->cmd_desc = txdesc; + /* Search the list of PAN descriptors, that would have been populated by the + * latest scan procedure. If we have seen a beacon from the coordinator that + * we are about to associate with, we can check the beacon order to determine + * whether we can send the command during the CAP. If we haven't received + * a beacon frame from the desired coordinator address, we have to just + * send the frame out immediately. + */ + + for (i = 0; i < priv->npandesc; i++) + { + /* Check to make sure the beacon is from the same channel as the request */ + + if (req->chan != priv->pandescs[i].chan) + { + continue; + } + + if (memcmp(&req->coordaddr, &priv->pandescs[i].coordaddr, + sizeof(struct ieee802154_addr_s)) == 0) + { + wlinfo("Found matching beacon to use for settings\n"); + + /* We have a beacon frame from this coordinator, we can set the + * sfspec and send accordingly. + */ + + /* Copy in the new superframe spec */ + + memcpy(&priv->sfspec, &priv->pandescs[i].sfspec, + sizeof(struct ieee802154_superframespec_s)); + + /* Tell the radio layer about the superframe spec update */ + + priv->radio->sfupdate(priv->radio, &priv->pandescs[i].sfspec); + } + } + + if (priv->sfspec.beaconorder == 15) + { + wlinfo("Transmitting assoc request\n"); + + /* Association Request command gets sent out immediately */ + + priv->radio->txdelayed(priv->radio, txdesc, 0); + } + else + { + wlinfo("Queuing assoc request for CAP\n"); + + /* Link the transaction into the CSMA transaction list */ + + sq_addlast((FAR sq_entry_t *)txdesc, &priv->csma_queue); + + /* Notify the radio driver that there is data available */ + + priv->radio->txnotify(priv->radio, false); + } + /* We no longer need to have the MAC layer locked. */ mac802154_givesem(&priv->exclsem); - /* Association Request command gets sent out immediately */ - - priv->radio->txdelayed(priv->radio, txdesc, 0); - return OK; } @@ -402,10 +445,9 @@ 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; + FAR struct ieee802154_notif_s *notif = + (FAR struct ieee802154_notif_s *)txdesc->conf; if(txdesc->conf->status != IEEE802154_STATUS_SUCCESS) { @@ -433,6 +475,7 @@ void mac802154_txdone_assocreq(FAR struct ieee802154_privmac_s *priv, IEEE802154_SADDRCOPY(notif->u.assocconf.saddr, &IEEE802154_SADDR_UNSPEC); + /* We are now done the operation, unlock the semaphore */ priv->curr_op = MAC802154_OP_NONE; @@ -467,17 +510,33 @@ void mac802154_txdone_assocreq(FAR struct ieee802154_privmac_s *priv, * 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. + * + * TODO: The standard defines macResponseWaitTime as: + * The maximum time, in multiples of aBaseSuperframeDuration, a device + * shall wait for a response command frame to be available following a + * request command frame. + * + * However, on beacon-enabled networks, it seems the maximum value + * isn't really that large of a value, AKA: assoc always fails from + * timeout even though everything is working as expected. The definition + * does say after we've sent a data request, which we, haven't sent + * yet, but we do need a timeout for association in general. Not sure + * what the correct answer is. For now, I am going to change the + * way macResponseWaitTime is used with beacon-enabled networks and + * make the timeout (BI * macResponseWaitTime) where BI is Beacon + * Interval = aBaseSuperframeDuration * 2^macBeaconOrder */ + wlinfo("Starting timeout timer\n"); mac802154_timerstart(priv, (priv->resp_waittime * - IEEE802154_BASE_SUPERFRAME_DURATION), - mac802154_assoctimeout); + (IEEE802154_BASE_SUPERFRAME_DURATION * (1 << priv->sfspec.beaconorder))), + mac802154_assoctimeout); } else { - /* Make sure the coordinator address mode is not set to none. This shouldn't - * happen since the association request should have set the mode to short or - * extended + /* Make sure the coordinator address mode is not set to none. This + * shouldn't happen since the association request should have set + * the mode to short or extended */ DEBUGASSERT(priv->pandesc.coordaddr.mode != IEEE802154_ADDRMODE_NONE); @@ -497,13 +556,9 @@ void mac802154_txdone_assocreq(FAR struct ieee802154_privmac_s *priv, (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. - */ + /* Deallocate the data conf notification as it is no longer needed. */ - privnotif->flink = priv->notif_free; - priv->notif_free = privnotif; + mac802154_notif_free_locked(priv, notif); } } @@ -524,9 +579,8 @@ 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; + FAR struct ieee802154_notif_s *notif = + (FAR struct ieee802154_notif_s *)txdesc->conf; /* If the data request failed to be sent, notify the next layer * that the association has failed. @@ -587,22 +641,33 @@ void mac802154_txdone_datareq_assoc(FAR struct ieee802154_privmac_s *priv, mac802154_rxenable(priv); - /* Start a timer, if we receive the data frame, we will cancel - * the timer, otherwise it will expire and we will notify the - * next highest layer of the failure. + /* If we are on a beacon-enabled network, we already have the association + * timeout timer scheduled. So we only need to start the timeout timer + * if we are operating on a non-beacon enabled network. + * + * NOTE: This may create a bad side-effect where the receiver is on + * for longer than it needs to be during association. Revisit if power + * is ever an issue. */ - mac802154_timerstart(priv, priv->max_frame_waittime, - mac802154_assoctimeout); + if (priv->sfspec.beaconorder == 15) + { - /* 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. - */ + /* 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. + */ + + wlinfo("Starting timeout timer\n"); + mac802154_timerstart(priv, priv->max_frame_waittime, + mac802154_assoctimeout); + + } + + /* Deallocate the data conf notification as it is no longer needed. */ + + mac802154_notif_free_locked(priv, notif); - privnotif->flink = priv->notif_free; - priv->notif_free = privnotif; - mac802154_givesem(&priv->notif_sem); } } @@ -698,6 +763,19 @@ void mac802154_rx_assocresp(FAR struct ieee802154_privmac_s *priv, if (priv->curr_op != MAC802154_OP_ASSOC) { + /* This situation can occur in a beacon-enabled network if the association + * request has timed out, but the Coordinator has already queued the + * response. Which means the beacon would contain our address, causing us + * to extract the response. + * + * TODO: What is supposed to happen in this situation. Are we supposed to + * accept the request? Are we supposed to Disassociate with the network + * as a convienience to the PAN Coordinator. So that it does not need + * to waste space holding our information? + */ + + wlinfo("Ignoring association response frame\n"); + return; } @@ -720,7 +798,7 @@ void mac802154_rx_assocresp(FAR struct ieee802154_privmac_s *priv, /* Inform the radio of the address change */ - priv->radio->set_attr(priv->radio, IEEE802154_ATTR_MAC_SADDR, + priv->radio->setattr(priv->radio, IEEE802154_ATTR_MAC_SADDR, (FAR union ieee802154_attr_u *)priv->addr.saddr); /* A Short Address field value equal to 0xfffe shall indicate that the device @@ -751,15 +829,16 @@ void mac802154_rx_assocresp(FAR struct ieee802154_privmac_s *priv, IEEE802154_SADDRCOPY(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->opsem); + mac802154_rxdisable(priv); + + /* Unlock the MAC */ + + mac802154_givesem(&priv->exclsem); /* Notify the next highest layer of the association status */ @@ -800,9 +879,11 @@ static void mac802154_assoctimeout(FAR struct ieee802154_privmac_s *priv) 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->opsem); + mac802154_rxdisable(priv); /* Release the MAC */ diff --git a/wireless/ieee802154/mac802154_disassoc.c b/wireless/ieee802154/mac802154_disassoc.c index ab5a745068..3051132e9d 100644 --- a/wireless/ieee802154/mac802154_disassoc.c +++ b/wireless/ieee802154/mac802154_disassoc.c @@ -73,7 +73,9 @@ int mac802154_req_disassociate(MACHANDLE mac, FAR struct ieee802154_disassoc_req_s *req) { +#if 0 FAR struct ieee802154_privmac_s *priv = (FAR struct ieee802154_privmac_s *)mac; +#endif return -ENOTTY; } \ No newline at end of file diff --git a/wireless/ieee802154/mac802154_getset.c b/wireless/ieee802154/mac802154_getset.c index b1c29f7191..d6a9ddf889 100644 --- a/wireless/ieee802154/mac802154_getset.c +++ b/wireless/ieee802154/mac802154_getset.c @@ -84,29 +84,55 @@ int mac802154_req_get(MACHANDLE mac, enum ieee802154_attr_e attr, switch (attr) { case IEEE802154_ATTR_MAC_PANID: - IEEE802154_PANIDCOPY(attrval->mac.panid, priv->addr.panid); + { + IEEE802154_PANIDCOPY(attrval->mac.panid, priv->addr.panid); + } break; - case IEEE802154_ATTR_MAC_SADDR: - IEEE802154_SADDRCOPY(attrval->mac.saddr, priv->addr.saddr); - break; - case IEEE802154_ATTR_MAC_EADDR: - IEEE802154_EADDRCOPY(attrval->mac.eaddr, priv->addr.eaddr); - break; - case IEEE802154_ATTR_MAC_COORD_SADDR: - IEEE802154_SADDRCOPY(attrval->mac.coordsaddr, priv->pandesc.coordaddr.saddr); - break; - case IEEE802154_ATTR_MAC_COORD_EADDR: - IEEE802154_EADDRCOPY(attrval->mac.coordeaddr, priv->pandesc.coordaddr.eaddr); - 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->get_attr(priv->radio, attr, attrval); + case IEEE802154_ATTR_MAC_SADDR: + { + IEEE802154_SADDRCOPY(attrval->mac.saddr, priv->addr.saddr); + } + break; + + case IEEE802154_ATTR_MAC_EADDR: + { + IEEE802154_EADDRCOPY(attrval->mac.eaddr, priv->addr.eaddr); + } + break; + + case IEEE802154_ATTR_MAC_COORD_SADDR: + { + IEEE802154_SADDRCOPY(attrval->mac.coordsaddr, priv->pandesc.coordaddr.saddr); + } + break; + + case IEEE802154_ATTR_MAC_COORD_EADDR: + { + IEEE802154_EADDRCOPY(attrval->mac.coordeaddr, priv->pandesc.coordaddr.eaddr); + } + break; + + case IEEE802154_ATTR_MAC_DEVMODE: + { + attrval->mac.devmode = priv->devmode; + } + break; + + case IEEE802154_ATTR_MAC_RESPONSE_WAIT_TIME: + { + attrval->mac.resp_waittime = priv->resp_waittime; + } + break;; + + default: + { + /* The attribute may be handled soley in the radio driver, so pass + * it along. + */ + + ret = priv->radio->getattr(priv->radio, attr, attrval); + } break; } @@ -133,54 +159,56 @@ int mac802154_req_set(MACHANDLE mac, enum ieee802154_attr_e attr, { FAR struct ieee802154_privmac_s *priv = (FAR struct ieee802154_privmac_s *)mac; - int ret; + int ret = IEEE802154_STATUS_SUCCESS; switch (attr) { case IEEE802154_ATTR_MAC_PANID: { mac802154_setpanid(priv, attrval->mac.panid); - ret = IEEE802154_STATUS_SUCCESS; } break; case IEEE802154_ATTR_MAC_SADDR: { mac802154_setsaddr(priv, attrval->mac.saddr); - ret = IEEE802154_STATUS_SUCCESS; } break; case IEEE802154_ATTR_MAC_EADDR: { mac802154_seteaddr(priv, attrval->mac.eaddr); - ret = IEEE802154_STATUS_SUCCESS; } break; case IEEE802154_ATTR_MAC_COORD_SADDR: { mac802154_setcoordsaddr(priv, attrval->mac.coordsaddr); - ret = IEEE802154_STATUS_SUCCESS; } break; case IEEE802154_ATTR_MAC_COORD_EADDR: { mac802154_setcoordeaddr(priv, attrval->mac.coordeaddr); - ret = IEEE802154_STATUS_SUCCESS; } break; case IEEE802154_ATTR_MAC_ASSOCIATION_PERMIT: { priv->sfspec.assocpermit = attrval->mac.assocpermit; priv->beaconupdate = true; - ret = IEEE802154_STATUS_SUCCESS; } break; + case IEEE802154_ATTR_MAC_RESPONSE_WAIT_TIME: + { + priv->resp_waittime = attrval->mac.resp_waittime; + } + case IEEE802154_ATTR_MAC_RX_ON_WHEN_IDLE: + { + mac802154_setrxonidle(priv, attrval->mac.rxonidle); + } default: { /* The attribute may be handled soley in the radio driver, so pass * it along. */ - ret = priv->radio->set_attr(priv->radio, attr, attrval); + ret = priv->radio->setattr(priv->radio, attr, attrval); } break; } diff --git a/wireless/ieee802154/mac802154_gts.c b/wireless/ieee802154/mac802154_gts.c index e24e409f81..97140d7403 100644 --- a/wireless/ieee802154/mac802154_gts.c +++ b/wireless/ieee802154/mac802154_gts.c @@ -66,7 +66,9 @@ int mac802154_req_gts(MACHANDLE mac, FAR struct ieee802154_gts_req_s *req) { +#if 0 FAR struct ieee802154_privmac_s *priv = (FAR struct ieee802154_privmac_s *)mac; +#endif return -ENOTTY; } \ No newline at end of file diff --git a/wireless/ieee802154/mac802154_internal.h b/wireless/ieee802154/mac802154_internal.h index aa19f79f60..d3f86be9dd 100644 --- a/wireless/ieee802154/mac802154_internal.h +++ b/wireless/ieee802154/mac802154_internal.h @@ -135,7 +135,8 @@ enum mac802154_operation_e MAC802154_OP_NONE, MAC802154_OP_ASSOC, MAC802154_OP_POLL, - MAC802154_OP_SCAN + MAC802154_OP_SCAN, + MAC802154_OP_AUTOEXTRACT, }; struct ieee802154_privmac_s; /* Forward Reference */ @@ -156,7 +157,6 @@ struct ieee802154_privmac_s sem_t exclsem; /* Support exclusive access */ uint8_t nclients; /* Number of notification clients */ - uint8_t nnotif; /* Number of remaining notifications */ /* Only support a single command at any given time. As of now I see no * condition where you need to have more than one command frame simultaneously @@ -233,8 +233,6 @@ struct ieee802154_privmac_s /*************** Fields related to beacon-enabled networks ******************/ - uint8_t bsn; /* Seq. num added to tx beacon frame */ - /* Holds attributes pertaining to the superframe specification */ struct ieee802154_superframespec_s sfspec; @@ -358,6 +356,14 @@ struct ieee802154_privmac_s uint8_t maxretries : 3; /* Max # of retries allowed after tx fail */ /* End of 8-bit bitfield. */ + /* Start of 8-bit bitfield */ + + uint8_t rxonidle : 1; /* Receiver on when idle? */ + + /* End of 8-bit bitfield. */ + + + /* TODO: Add Security-related MAC PIB attributes */ }; @@ -609,6 +615,7 @@ static inline int mac802154_timercancel(FAR struct ieee802154_privmac_s *priv) { wd_cancel(priv->timeout); priv->timeout_worker = NULL; + wlinfo("Timer cancelled\n"); return OK; } @@ -620,7 +627,7 @@ static inline void mac802154_rxenable(FAR struct ieee802154_privmac_s *priv) if (priv->nrxusers == 1) { - wlinfo("receiver enabled\n"); + wlinfo("Receiver enabled\n"); priv->radio->rxenable(priv->radio, true); } } @@ -633,7 +640,7 @@ static inline void mac802154_rxdisable(FAR struct ieee802154_privmac_s *priv) if (priv->nrxusers == 0) { - wlinfo("receiver disabled\n"); + wlinfo("Receiver disabled\n"); priv->radio->rxenable(priv->radio, true); priv->radio->rxenable(priv->radio, false); } @@ -642,14 +649,14 @@ static inline void mac802154_rxdisable(FAR struct ieee802154_privmac_s *priv) static inline void mac802154_setchannel(FAR struct ieee802154_privmac_s *priv, uint8_t channel) { - priv->radio->set_attr(priv->radio, IEEE802154_ATTR_PHY_CHAN, + priv->radio->setattr(priv->radio, IEEE802154_ATTR_PHY_CHAN, (FAR const union ieee802154_attr_u *)&channel); } static inline void mac802154_setchpage(FAR struct ieee802154_privmac_s *priv, uint8_t chpage) { - priv->radio->set_attr(priv->radio, IEEE802154_ATTR_PHY_CURRENT_PAGE, + priv->radio->setattr(priv->radio, IEEE802154_ATTR_PHY_CURRENT_PAGE, (FAR const union ieee802154_attr_u *)&chpage); } @@ -657,7 +664,7 @@ static inline void mac802154_setpanid(FAR struct ieee802154_privmac_s *priv, const uint8_t *panid) { IEEE802154_PANIDCOPY(priv->addr.panid, panid); - priv->radio->set_attr(priv->radio, IEEE802154_ATTR_MAC_PANID, + priv->radio->setattr(priv->radio, IEEE802154_ATTR_MAC_PANID, (FAR const union ieee802154_attr_u *)panid); } @@ -665,7 +672,7 @@ static inline void mac802154_setsaddr(FAR struct ieee802154_privmac_s *priv, const uint8_t *saddr) { IEEE802154_SADDRCOPY(priv->addr.saddr, saddr); - priv->radio->set_attr(priv->radio, IEEE802154_ATTR_MAC_SADDR, + priv->radio->setattr(priv->radio, IEEE802154_ATTR_MAC_SADDR, (FAR const union ieee802154_attr_u *)saddr); } @@ -673,7 +680,7 @@ static inline void mac802154_seteaddr(FAR struct ieee802154_privmac_s *priv, const uint8_t *eaddr) { IEEE802154_EADDRCOPY(priv->addr.eaddr, eaddr); - priv->radio->set_attr(priv->radio, IEEE802154_ATTR_MAC_EADDR, + priv->radio->setattr(priv->radio, IEEE802154_ATTR_MAC_EADDR, (FAR const union ieee802154_attr_u *)eaddr); } @@ -681,7 +688,7 @@ static inline void mac802154_setcoordsaddr(FAR struct ieee802154_privmac_s *priv const uint8_t *saddr) { IEEE802154_SADDRCOPY(priv->pandesc.coordaddr.saddr, saddr); - priv->radio->set_attr(priv->radio, IEEE802154_ATTR_MAC_COORD_SADDR, + priv->radio->setattr(priv->radio, IEEE802154_ATTR_MAC_COORD_SADDR, (FAR const union ieee802154_attr_u *)saddr); } @@ -689,7 +696,7 @@ static inline void mac802154_setcoordeaddr(FAR struct ieee802154_privmac_s *priv const uint8_t *eaddr) { IEEE802154_EADDRCOPY(priv->pandesc.coordaddr.eaddr, eaddr); - priv->radio->set_attr(priv->radio, IEEE802154_ATTR_MAC_COORD_EADDR, + priv->radio->setattr(priv->radio, IEEE802154_ATTR_MAC_COORD_EADDR, (FAR const union ieee802154_attr_u *)eaddr); } @@ -697,10 +704,34 @@ static inline void mac802154_setcoordaddr(FAR struct ieee802154_privmac_s *priv, FAR const struct ieee802154_addr_s *addr) { memcpy(&priv->pandesc.coordaddr, addr, sizeof(struct ieee802154_addr_s)); - priv->radio->set_attr(priv->radio, IEEE802154_ATTR_MAC_COORD_EADDR, + priv->radio->setattr(priv->radio, IEEE802154_ATTR_MAC_COORD_EADDR, (FAR const union ieee802154_attr_u *)addr->eaddr); - priv->radio->set_attr(priv->radio, IEEE802154_ATTR_MAC_COORD_SADDR, + priv->radio->setattr(priv->radio, IEEE802154_ATTR_MAC_COORD_SADDR, (FAR const union ieee802154_attr_u *)addr->saddr); } +static inline void mac802154_setrxonidle(FAR struct ieee802154_privmac_s *priv, + bool rxonidle) +{ + priv->rxonidle = true; + if (priv->rxonidle) + { + mac802154_rxenable(priv); + } + else + { + mac802154_rxdisable(priv); + } + + /* 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. + */ + + priv->radio->setattr(priv->radio, IEEE802154_ATTR_MAC_RX_ON_WHEN_IDLE, + (FAR const union ieee802154_attr_u *)&rxonidle); +} + #endif /* __WIRELESS_IEEE802154__MAC802154_INTERNAL_H */ diff --git a/wireless/ieee802154/mac802154_ioctl.c b/wireless/ieee802154/mac802154_ioctl.c index 35093f6936..20ab2557fd 100644 --- a/wireless/ieee802154/mac802154_ioctl.c +++ b/wireless/ieee802154/mac802154_ioctl.c @@ -124,7 +124,7 @@ int mac802154_ioctl(MACHANDLE mac, int cmd, unsigned long arg) break; case MAC802154IOC_MLME_RESET_REQUEST: { - ret = mac802154_req_reset(mac, macarg->resetreq.rst_pibattr); + ret = mac802154_req_reset(mac, macarg->resetreq.resetattr); } break; case MAC802154IOC_MLME_RXENABLE_REQUEST: diff --git a/wireless/ieee802154/mac802154_netdev.c b/wireless/ieee802154/mac802154_netdev.c index 0f49102c5e..bf0225db7b 100644 --- a/wireless/ieee802154/mac802154_netdev.c +++ b/wireless/ieee802154/mac802154_netdev.c @@ -173,8 +173,8 @@ static void macnet_ind_associate(FAR struct macnet_driver_s *priv, FAR struct ieee802154_assoc_ind_s *conf); static void macnet_ind_disassociate(FAR struct macnet_driver_s *priv, FAR struct ieee802154_disassoc_ind_s *conf); -static void macnet_ind_beaconnotify(FAR struct macnet_driver_s *priv, - FAR struct ieee802154_beaconnotify_ind_s *conf); +static void macnet_ind_beacon(FAR struct macnet_driver_s *priv, + FAR struct ieee802154_beacon_ind_s *conf); static void macnet_ind_gts(FAR struct macnet_driver_s *priv, FAR struct ieee802154_gts_ind_s *conf); static void macnet_ind_orphan(FAR struct macnet_driver_s *priv, @@ -589,15 +589,15 @@ static void macnet_ind_disassociate(FAR struct macnet_driver_s *priv, } /**************************************************************************** - * Name: macnet_ind_beaconnotify + * Name: macnet_ind_beacon * * Description: * Beacon notification * ****************************************************************************/ -static void macnet_ind_beaconnotify(FAR struct macnet_driver_s *priv, - FAR struct ieee802154_beaconnotify_ind_s *ind) +static void macnet_ind_beacon(FAR struct macnet_driver_s *priv, + FAR struct ieee802154_beacon_ind_s *ind) { } diff --git a/wireless/ieee802154/mac802154_notif.c b/wireless/ieee802154/mac802154_notif.c index bce299c139..059d95624c 100644 --- a/wireless/ieee802154/mac802154_notif.c +++ b/wireless/ieee802154/mac802154_notif.c @@ -69,44 +69,22 @@ * ****************************************************************************/ -int mac802154_notif_free(MACHANDLE mac, - FAR struct ieee802154_notif_s *notif) +void 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 */ + /* Lock the MAC */ mac802154_takesem(&priv->exclsem, false); - /* We know how many clients have registered for notifications. Each must - * call mac802154_notif_free() before we can release the notification - * resource. - */ + /* Call the internal helper function to free the notification */ - if (priv->nnotif < 2) - { - /* This is the free from the last notification */ + mac802154_notif_free_locked(priv, notif); - privnotif->flink = priv->notif_free; - priv->notif_free = privnotif; - priv->nnotif = 0; - - mac802154_givesem(&priv->notif_sem); - } - else - { - /* More calls are expected. Decrement the count of expected calls - * and preserve the notification resources. - */ - - priv->nnotif--; - } + /* Unlock the MAC */ mac802154_givesem(&priv->exclsem); - return -ENOTTY; } /**************************************************************************** @@ -184,9 +162,9 @@ int mac802154_notif_alloc(FAR struct ieee802154_privmac_s *priv, if (ret == OK) { - privnotif = priv->notif_free; - priv->notif_free = privnotif->flink; - priv->nnotif = 0; + privnotif = priv->notif_free; + priv->notif_free = privnotif->flink; + privnotif->nclients = 0; } else { @@ -220,9 +198,9 @@ int mac802154_notif_alloc(FAR struct ieee802154_privmac_s *priv, /* We can now safely unlink the next free structure from the free list */ - privnotif = priv->notif_free; - priv->notif_free = privnotif->flink; - priv->nnotif = 0; + privnotif = priv->notif_free; + priv->notif_free = privnotif->flink; + privnotif->nclients = 0; } *notif = (FAR struct ieee802154_notif_s *)privnotif; @@ -230,6 +208,49 @@ int mac802154_notif_alloc(FAR struct ieee802154_privmac_s *priv, return OK; } +/**************************************************************************** + * Name: mac802154_notif_free_locked + * + * 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. + * + * Internal version that already has MAC locked + * + ****************************************************************************/ + +void mac802154_notif_free_locked(FAR struct ieee802154_privmac_s * priv, + FAR struct ieee802154_notif_s *notif) +{ + FAR struct mac802154_notif_s *privnotif = + (FAR struct mac802154_notif_s *)notif; + + /* We know how many clients have registered for notifications. Each must + * call mac802154_notif_free() before we can release the notification + * resource. + */ + + if (privnotif->nclients < 2) + { + /* This is the free from the last notification */ + + privnotif->flink = priv->notif_free; + priv->notif_free = privnotif; + privnotif->nclients = 0; + + mac802154_givesem(&priv->notif_sem); + } + else + { + /* More calls are expected. Decrement the count of expected calls + * and preserve the notification resources. + */ + + privnotif->nclients--; + } +} + /**************************************************************************** * Name: mac802154_notify * @@ -242,12 +263,13 @@ void mac802154_notify(FAR struct ieee802154_privmac_s *priv, FAR struct ieee802154_notif_s *notif) { FAR struct mac802154_maccb_s *cb; + FAR struct mac802154_notif_s *privnotif = (FAR struct mac802154_notif_s *)notif; /* Set the notification count so that the notification resources will be * preserved until the final notification. */ - priv->nnotif = priv->nclients; + privnotif->nclients = priv->nclients; /* Try to notify every registered MAC client */ diff --git a/wireless/ieee802154/mac802154_notif.h b/wireless/ieee802154/mac802154_notif.h index 3c6bdd3523..886d786c6b 100644 --- a/wireless/ieee802154/mac802154_notif.h +++ b/wireless/ieee802154/mac802154_notif.h @@ -65,6 +65,7 @@ struct mac802154_notif_s { struct ieee802154_notif_s pub; /* Publically visible structure */ FAR struct mac802154_notif_s *flink; /* Supports a singly linked list */ + uint8_t nclients; }; /**************************************************************************** @@ -82,4 +83,7 @@ int mac802154_notif_alloc(FAR struct ieee802154_privmac_s *priv, void mac802154_notify(FAR struct ieee802154_privmac_s *priv, FAR struct ieee802154_notif_s *notif); +void mac802154_notif_free_locked(FAR struct ieee802154_privmac_s * priv, + FAR struct ieee802154_notif_s *notif); + #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 index 9e4a80d4f2..46a14e7e23 100644 --- a/wireless/ieee802154/mac802154_orphan.c +++ b/wireless/ieee802154/mac802154_orphan.c @@ -65,7 +65,9 @@ int mac802154_resp_orphan(MACHANDLE mac, FAR struct ieee802154_orphan_resp_s *resp) { +#if 0 FAR struct ieee802154_privmac_s *priv = (FAR struct ieee802154_privmac_s *)mac; +#endif return -ENOTTY; } diff --git a/wireless/ieee802154/mac802154_poll.c b/wireless/ieee802154/mac802154_poll.c index e2881a397a..368f8baac2 100644 --- a/wireless/ieee802154/mac802154_poll.c +++ b/wireless/ieee802154/mac802154_poll.c @@ -188,9 +188,8 @@ 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; + FAR struct ieee802154_notif_s *notif = + (FAR struct ieee802154_notif_s *)txdesc->conf; /* If the data request failed to be sent, notify the next layer * that the poll has failed. @@ -245,13 +244,9 @@ void mac802154_txdone_datareq_poll(FAR struct ieee802154_privmac_s *priv, mac802154_timerstart(priv, priv->max_frame_waittime, mac802154_polltimeout); - /* We can deallocate the data conf notification as it is no longer - * needed. We can't use the public function here since we already - * have the MAC locked. - */ + /* Deallocate the data conf notification as it is no longer needed. */ - privnotif->flink = priv->notif_free; - priv->notif_free = privnotif; + mac802154_notif_free_locked(priv, notif); } } diff --git a/wireless/ieee802154/mac802154_purge.c b/wireless/ieee802154/mac802154_purge.c index 6073c61f8c..d32843166d 100644 --- a/wireless/ieee802154/mac802154_purge.c +++ b/wireless/ieee802154/mac802154_purge.c @@ -76,8 +76,10 @@ int mac802154_req_purge(MACHANDLE mac, uint8_t msdu_handle) { +#if 0 FAR struct ieee802154_privmac_s *priv = (FAR struct ieee802154_privmac_s *)mac; +#endif return -ENOTTY; } diff --git a/wireless/ieee802154/mac802154_reset.c b/wireless/ieee802154/mac802154_reset.c index 759a44e31e..598275d9e0 100644 --- a/wireless/ieee802154/mac802154_reset.c +++ b/wireless/ieee802154/mac802154_reset.c @@ -74,17 +74,17 @@ * * Input Parameters: * mac - Handle to the MAC layer instance - * rst_pibattr - Whether or not to reset the MAC PIB attributes to defaults + * resetattr - Whether or not to reset the MAC PIB attributes to defaults * ****************************************************************************/ -int mac802154_req_reset(MACHANDLE mac, bool rst_pibattr) +int mac802154_req_reset(MACHANDLE mac, bool resetattr) { FAR struct ieee802154_privmac_s * priv = (FAR struct ieee802154_privmac_s *) mac; union ieee802154_attr_u attr; - if (rst_pibattr) + if (resetattr) { priv->isassoc = false; /* Not associated with a PAN */ priv->trackingbeacon = false; /* Not tracking beacon by default */ @@ -95,8 +95,6 @@ int mac802154_req_reset(MACHANDLE mac, bool rst_pibattr) priv->sfspec.beaconorder = 15; /* Non-beacon enabled network */ priv->sfspec.sforder = 15; /* Length of active portion of outgoing SF */ priv->beacon_txtime = 0; /* Device never sent a beacon */ -#warning Set BSN and DSN to random values! - priv->bsn = 0; priv->dsn = 0; priv->gtspermit = true; /* PAN Coord accepting GTS requests */ priv->minbe = 3; /* Min value of backoff exponent (BE) */ @@ -125,14 +123,14 @@ int mac802154_req_reset(MACHANDLE mac, bool rst_pibattr) IEEE802154_SADDRCOPY(priv->addr.saddr, &IEEE802154_SADDR_UNSPEC); IEEE802154_EADDRCOPY(priv->addr.eaddr, &IEEE802154_EADDR_UNSPEC); - priv->radio->reset_attrs(priv->radio); + priv->radio->reset(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, + priv->radio->getattr(priv->radio, IEEE802154_ATTR_MAC_MAX_FRAME_WAITTIME, &attr); priv->max_frame_waittime = attr.mac.max_frame_waittime; diff --git a/wireless/ieee802154/mac802154_rxenable.c b/wireless/ieee802154/mac802154_rxenable.c index 683d130e75..1f38689c30 100644 --- a/wireless/ieee802154/mac802154_rxenable.c +++ b/wireless/ieee802154/mac802154_rxenable.c @@ -72,7 +72,9 @@ int mac802154_req_rxenable(MACHANDLE mac, FAR struct ieee802154_rxenable_req_s *req) { +#if 0 FAR struct ieee802154_privmac_s * priv = (FAR struct ieee802154_privmac_s *)mac; +#endif return -ENOTTY; } \ No newline at end of file diff --git a/wireless/ieee802154/mac802154_scan.c b/wireless/ieee802154/mac802154_scan.c index d333d72d3c..819ac141f8 100644 --- a/wireless/ieee802154/mac802154_scan.c +++ b/wireless/ieee802154/mac802154_scan.c @@ -93,6 +93,8 @@ int mac802154_req_scan(MACHANDLE mac, FAR struct ieee802154_scan_req_s *req) goto errout; } + wlinfo("MLME: SCAN.request received\n"); + /* Need to get access to the ops semaphore since operations are serial. This * must be done before locking the MAC so that we don't hold the MAC */ @@ -126,6 +128,8 @@ int mac802154_req_scan(MACHANDLE mac, FAR struct ieee802154_scan_req_s *req) { case IEEE802154_SCANTYPE_PASSIVE: { + wlinfo("MLME: Starting Passive scan\n"); + /* Set the channel to the first channel in the list */ mac802154_setchannel(priv, req->channels[priv->scanindex]); diff --git a/wireless/ieee802154/mac802154_start.c b/wireless/ieee802154/mac802154_start.c index b3675393e2..5a9c4379ea 100644 --- a/wireless/ieee802154/mac802154_start.c +++ b/wireless/ieee802154/mac802154_start.c @@ -101,9 +101,9 @@ int mac802154_req_start(MACHANDLE mac, FAR struct ieee802154_start_req_s *req) /* Tell the radio layer to set the channel number and channel page */ - priv->radio->set_attr(priv->radio, IEEE802154_ATTR_PHY_CHAN, + priv->radio->setattr(priv->radio, IEEE802154_ATTR_PHY_CHAN, (FAR const union ieee802154_attr_u *)&req->chan); - priv->radio->set_attr(priv->radio, IEEE802154_ATTR_PHY_CURRENT_PAGE, + priv->radio->setattr(priv->radio, IEEE802154_ATTR_PHY_CURRENT_PAGE, (FAR const union ieee802154_attr_u *)&req->chpage); /* The address used in the Source Address field of the beacon frame shall diff --git a/wireless/ieee802154/mac802154_sync.c b/wireless/ieee802154/mac802154_sync.c index fed5e452de..2018a55dd3 100644 --- a/wireless/ieee802154/mac802154_sync.c +++ b/wireless/ieee802154/mac802154_sync.c @@ -71,8 +71,10 @@ int mac802154_req_sync(MACHANDLE mac, FAR struct ieee802154_sync_req_s *req) { +#if 0 FAR struct ieee802154_privmac_s *priv = (FAR struct ieee802154_privmac_s *)mac; +#endif return -ENOTTY; }