mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-15 01:23:49 +01:00
gomach: a robust traffic adaptive multichannel MAC for IoT.
This commit is contained in:
parent
0af6938906
commit
ea5aeeb10f
@ -24,6 +24,14 @@ ifneq (,$(filter gnrc_mac,$(USEMODULE)))
|
||||
USEMODULE += csma_sender
|
||||
endif
|
||||
|
||||
ifneq (,$(filter gnrc_gomach,$(USEMODULE)))
|
||||
USEMODULE += gnrc_netif
|
||||
USEMODULE += random
|
||||
USEMODULE += xtimer
|
||||
USEMODULE += gnrc_mac
|
||||
FEATURES_REQUIRED += periph_rtt
|
||||
endif
|
||||
|
||||
ifneq (,$(filter nhdp,$(USEMODULE)))
|
||||
USEMODULE += sock_udp
|
||||
USEMODULE += xtimer
|
||||
|
||||
@ -4,10 +4,12 @@ APPLICATION = gnrc_networking_mac
|
||||
# If no BOARD is found in the environment, use this default:
|
||||
BOARD ?= samr21-xpro
|
||||
|
||||
# Currently, LWMAC is only tested and evaluated through on samr21-xpro.
|
||||
# Once LWMAC has also been tested through on other boards, the whitelist should be
|
||||
# Currently, GoMacH has only been tested and evaluated through on samr21-xpro and iotlab-m3.
|
||||
# Once GoMacH has also been tested through on other boards, the whitelist should be
|
||||
# then accordingly extended.
|
||||
BOARD_WHITELIST := samr21-xpro
|
||||
# Notably, for LWMAC, we have only evaluated it on samr21-xpro nodes. To this end, if
|
||||
# you are going to include LWMAC for testing, you should only run the example on samr21-xpro.
|
||||
BOARD_WHITELIST := samr21-xpro iotlab-m3
|
||||
|
||||
# This has to be the absolute path to the RIOT base directory:
|
||||
RIOTBASE ?= $(CURDIR)/../..
|
||||
@ -33,8 +35,10 @@ USEMODULE += ps
|
||||
USEMODULE += netstats_l2
|
||||
USEMODULE += netstats_ipv6
|
||||
USEMODULE += netstats_rpl
|
||||
# Use LWMAC as the MAC layer protocol
|
||||
USEMODULE += gnrc_lwmac
|
||||
# Use GoMacH as the MAC layer protocol
|
||||
USEMODULE += gnrc_gomach
|
||||
# In case of using LWMAC MAC protocol instead of GoMacH, uncomment the following line and comment the above line
|
||||
# USEMODULE += gnrc_lwmac
|
||||
|
||||
# Comment this out to disable code in RIOT that does safety checking
|
||||
# which is not needed in a production environment but helps in the
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
# gnrc_networking_mac example
|
||||
|
||||
This example shows you how to try out communications between RIOT instances with LWMAC as the MAC layer ptotocol for IEEE 802.15.4 devices.
|
||||
This example is generally based on `gnrc_networking` but embeds LWMAC to support low duty-cycle operation to conserve power. Also, it intends to show that the duty-cycled LWMAC can support popular upper layer protocols like UDP and RPL.
|
||||
Currently, it seems that you can only use the samr21-xpro board to test this MAC, since some certain features of the protocol are only available on that platform. Also, the current implementation of LWMAC uses RTT as the underlying timer source. So, currently, LWMAC cannot run on nodes that don't have RTT. But, as a long-term plan, we will replace RTT by a general timer API as the underlying timer to make LWMAC available for more devices, when the related implementations are ready.
|
||||
This example shows you how to try out communications between RIOT instances with duty-cycled MAC layer protocols (GoMacH and LWMAC) for IEEE 802.15.4 devices.
|
||||
This example is generally based on `gnrc_networking` but embeds GoMacH (or LWMAC) to support low duty-cycle operation to conserve power. Also, it intends to show that the duty-cycled MAC protocol can support popular upper layer protocols like UDP and RPL.
|
||||
Currently, it seems that you can only use samr21-xpro and iotlab-m3 boards (in case of using LWMAC, then only samr21-xpro board) to test with this example, since some certain features of the MAC protocol are only available on that platform. Also, the current implementations of GoMacH and LWMAC use RTT as the underlying timer source. So, currently, GoMacH and LWMAC cannot run on nodes that don't have RTT. But, as a long-term plan, we will replace RTT by a general timer API as the underlying timer to make GoMacH and LWMAC available for more devices, when the related implementations are ready.
|
||||
|
||||
|
||||
## Usage
|
||||
@ -15,13 +15,16 @@ make flash
|
||||
make term
|
||||
```
|
||||
|
||||
## Print out the achieved duty-cyle of GoMacH
|
||||
|
||||
You can print out the radio duty-cyle (a roughly one) of GoMacH by setting the `GNRC_GOMACH_ENABLE_DUTYCYLE_RECORD` flag in `sys/include/net/gnrc/gomach/types.h` to "1". By doing so, each time when a device sends or receives a packet, it will print out its achieved radio duty-cycle value.
|
||||
|
||||
## Print out the achieved duty-cyle of LWMAC
|
||||
|
||||
You can print out the radio duty-cyle (a roughly one) of LWMAC by setting the `LWMAC_ENABLE_DUTYCYLE_RECORD` flag in `sys/include/net/gnrc/lwmac/types.h` to "1". By doing so, each time when a device sends or receives a packet, it will print out its radio duty-cycle value.
|
||||
You can print out the radio duty-cyle (a roughly one) of LWMAC by setting the `LWMAC_ENABLE_DUTYCYLE_RECORD` flag in `sys/include/net/gnrc/lwmac/types.h` to "1". By doing so, each time when a device sends or receives a packet, it will print out its achieved radio duty-cycle value.
|
||||
Also, by further enabling the debug flag in `sys/net/gnrc/link_layer/lwmac/tx_state_machine.c`, you will get the printout of how many preamble (WR) and time (sending delay) cost for sending this packet in the TX procedure of LWMAC.
|
||||
|
||||
|
||||
## Try UDP transmissions with LWMAC
|
||||
## Try UDP transmissions with LWMAC (or GoMacH)
|
||||
|
||||
In the RIOT shell, get to know the IP address of one node:
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Freie Universität Berlin
|
||||
* 2017 INRIA
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
@ -14,6 +15,7 @@
|
||||
* @brief Example application for demonstrating the RIOT network stack
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
* @author Shuguo Zhuo <shuguo.zhuo@inria.fr>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
@ -25,6 +25,9 @@
|
||||
#ifdef MODULE_GNRC_LWMAC
|
||||
#include "net/gnrc/lwmac/lwmac.h"
|
||||
#endif
|
||||
#ifdef MODULE_GNRC_GOMACH
|
||||
#include "net/gnrc/gomach/gomach.h"
|
||||
#endif
|
||||
#include "net/gnrc.h"
|
||||
|
||||
#include "at86rf2xx.h"
|
||||
@ -50,7 +53,12 @@ void auto_init_at86rf2xx(void)
|
||||
LOG_DEBUG("[auto_init_netif] initializing at86rf2xx #%u\n", i);
|
||||
|
||||
at86rf2xx_setup(&at86rf2xx_devs[i], &at86rf2xx_params[i]);
|
||||
#ifdef MODULE_GNRC_LWMAC
|
||||
#if defined(MODULE_GNRC_GOMACH)
|
||||
gnrc_netif_gomach_create(_at86rf2xx_stacks[i],
|
||||
AT86RF2XX_MAC_STACKSIZE,
|
||||
AT86RF2XX_MAC_PRIO, "at86rf2xx-gomach",
|
||||
(netdev_t *)&at86rf2xx_devs[i]);
|
||||
#elif defined(MODULE_GNRC_LWMAC)
|
||||
gnrc_netif_lwmac_create(_at86rf2xx_stacks[i],
|
||||
AT86RF2XX_MAC_STACKSIZE,
|
||||
AT86RF2XX_MAC_PRIO, "at86rf2xx-lwmac",
|
||||
|
||||
353
sys/include/net/gnrc/gomach/gomach.h
Normal file
353
sys/include/net/gnrc/gomach/gomach.h
Normal file
@ -0,0 +1,353 @@
|
||||
/*
|
||||
* Copyright (C) 2017 INRIA
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup net_gnrc_gomach A traffic-adaptive multi-channel MAC
|
||||
* @ingroup net_gnrc
|
||||
* @brief A traffic adaptive MAC protocol that provides high traffic
|
||||
* adaptability, high energy efficiency and high robustness.
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of GoMacH protocol
|
||||
*
|
||||
* @author Shuguo Zhuo <shuguo.zhuo@inria.fr>
|
||||
*/
|
||||
|
||||
#ifndef NET_GNRC_GOMACH_GOMACH_H
|
||||
#define NET_GNRC_GOMACH_GOMACH_H
|
||||
|
||||
#include "periph/rtt.h"
|
||||
#include "kernel_types.h"
|
||||
#include "net/gnrc/netif.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief The default duration of GoMacH's wake-up period (WP).
|
||||
*
|
||||
* GoMacH adopts the duty-cycle scheme that, by default, a node only wakes up
|
||||
* for a short period of @ref GNRC_GOMACH_CP_DURATION_US in each cycle. In the
|
||||
* rest of the cycle (except vTDMA), the node turns off the radio to conserve
|
||||
* power. @ref GNRC_GOMACH_CP_DURATION_US should be at least longer than
|
||||
* @ref GNRC_GOMACH_MAX_PREAM_INTERVAL_US, thus to guarantee that the receiver
|
||||
* will not miss the preamble packet.
|
||||
*/
|
||||
#ifndef GNRC_GOMACH_CP_DURATION_US
|
||||
#define GNRC_GOMACH_CP_DURATION_US (10U * US_PER_MS)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief GoMacH's superframe duration, i.e., time between two consecutive wake-ups.
|
||||
*
|
||||
* This macro governs power consumption and GoMacH's reactiveness to traffic loads.
|
||||
* In GoMacH, nodes adopt duty-cycle scheme to conserve power. That is,
|
||||
* time is divided into repeated cycles (superframes), and in each
|
||||
* cycle, a node only wakes up for a short period of time for receiving potential
|
||||
* incoming packets for itself. This macro defines the wake-up interval, or,
|
||||
* in other words, defines the cycle duration used in GoMacH. If the wake-up
|
||||
* interval is short, nodes will wake up more frequently, which leads to quicker
|
||||
* reactiveness of the MAC protocol for handling packet reception and transmission,
|
||||
* but also results in higher power consumption due to more idle listening.
|
||||
* In GoMacH, by default, we regard the wake-up period (WP) as the beginning of
|
||||
* a cycle.
|
||||
*
|
||||
* Note that, GoMacH's superframe duration @ref GNRC_GOMACH_SUPERFRAME_DURATION_US
|
||||
* should not be shorter than 10 times of @ref GNRC_GOMACH_CP_DURATION_US and not
|
||||
* shorter than the RTT tickle interval.
|
||||
*/
|
||||
#ifndef GNRC_GOMACH_SUPERFRAME_DURATION_US
|
||||
#define GNRC_GOMACH_SUPERFRAME_DURATION_US (300LU * US_PER_MS)
|
||||
#endif
|
||||
|
||||
#if ((GNRC_GOMACH_SUPERFRAME_DURATION_US < ((1000LU *US_PER_MS) / RTT_FREQUENCY)) || \
|
||||
(GNRC_GOMACH_SUPERFRAME_DURATION_US < (10 *GNRC_GOMACH_CP_DURATION_US)))
|
||||
#undef GNRC_GOMACH_SUPERFRAME_DURATION_US
|
||||
#if (((1000LU *US_PER_MS) / RTT_FREQUENCY) > (10 * GNRC_GOMACH_CP_DURATION_US))
|
||||
#define GNRC_GOMACH_SUPERFRAME_DURATION_US ((1000LU * US_PER_MS) / RTT_FREQUENCY)
|
||||
#else
|
||||
#define GNRC_GOMACH_SUPERFRAME_DURATION_US (10 * GNRC_GOMACH_CP_DURATION_US)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief The maximum duration of the random period at the end of GoMacH's
|
||||
* wake-up period (WP).
|
||||
*
|
||||
* Currently, GoMacH's WP is actually composed of @ref GNRC_GOMACH_CP_DURATION_US
|
||||
* and (+) @ref GNRC_GOMACH_CP_RANDOM_END_US. We currently introduced this random
|
||||
* period to avoid beacon collision among neighbor nodes. This macro may be removed
|
||||
* in the future.
|
||||
*/
|
||||
#ifndef GNRC_GOMACH_CP_RANDOM_END_US
|
||||
#define GNRC_GOMACH_CP_RANDOM_END_US (1U * US_PER_MS)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief The maximum duration of GoMacH's wake-up period (WP).
|
||||
*
|
||||
* @ref GNRC_GOMACH_CP_DURATION_MAX_US defines the allowed maximum duration
|
||||
* of GoMacH's WP period. A node will quit WP once it reaches this maximum
|
||||
* duration.
|
||||
* Note that, in GoMacH's WP, after each normal packet reception (except
|
||||
* broadcast packet), a receiver will automatically extends the WP period
|
||||
* (reset WP timeout), to receiver more potential incoming packets, before
|
||||
* WP reaches this @ref GNRC_GOMACH_CP_DURATION_MAX_US duration.
|
||||
*/
|
||||
#ifndef GNRC_GOMACH_CP_DURATION_MAX_US
|
||||
#define GNRC_GOMACH_CP_DURATION_MAX_US (5LU * GNRC_GOMACH_CP_DURATION_US)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief The maximum time for waiting the receiver's beacon in GoMacH.
|
||||
*
|
||||
* After transmissions in the WP, if the sender still has pending packets
|
||||
* for the receiver, it will wait for the receiver's incoming beacon that
|
||||
* allocates dynamic transmission slots to it. @ref GNRC_GOMACH_WAIT_BEACON_TIME_US
|
||||
* defines the maximum waiting time for the beacon. Once the beacon-waiting
|
||||
* timeout expires, the sender will quit the vTMDA (slotted transmission)
|
||||
* procedure, and restarts transmissions (started with normal CSMA attempts
|
||||
* in the receiver's WP) in the next cycle for sending the pending packets
|
||||
* to the same receiver.
|
||||
*/
|
||||
#ifndef GNRC_GOMACH_WAIT_BEACON_TIME_US
|
||||
#define GNRC_GOMACH_WAIT_BEACON_TIME_US (GNRC_GOMACH_CP_DURATION_MAX_US)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief The minimum gap between neighbor nodes' wake-up phases in GoMacH.
|
||||
*
|
||||
* To reduce beacon collisions and transmission collisions, GoMacH intends
|
||||
* to avoid neighbor nodes' phases being too close to each other. This macro
|
||||
* defines the minimum gap between two nodes's wake-up phases. If the sender
|
||||
* finds its wake-up phase too closed to its receiver's, it will randomly
|
||||
* select a new phase for itself.
|
||||
*/
|
||||
#ifndef GNRC_GOMACH_CP_MIN_GAP_US
|
||||
#define GNRC_GOMACH_CP_MIN_GAP_US (25U * US_PER_MS)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Timeout duration for waiting @ref NETDEV_EVENT_RX_COMPLETE in GoMacH.
|
||||
*
|
||||
* Sometimes in GoMacH, if a node finds RX ongoing when it is just about to
|
||||
* enter the next MAC state, it will set up a timeout for waiting this packet
|
||||
* reception complete with a timeout of this @ref GNRC_GOMACH_WAIT_RX_END_US
|
||||
* duration.
|
||||
*/
|
||||
#ifndef GNRC_GOMACH_WAIT_RX_END_US
|
||||
#define GNRC_GOMACH_WAIT_RX_END_US (6U * US_PER_MS)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Timeout duration for confirming TX-No-ISR event in GoMacH.
|
||||
*
|
||||
* This macro is used to confirm/catch a case that a transmission doesn't have its
|
||||
* @ref NETDEV_EVENT_TX_COMPLETE interrupt event, which is considered as a hardware
|
||||
* abnormal event. Upon this timeout expiration, GoMach will accordingly take
|
||||
* actions to maintain its state-machine.
|
||||
*/
|
||||
#ifndef GNRC_GOMACH_NO_TX_ISR_US
|
||||
#define GNRC_GOMACH_NO_TX_ISR_US (50U * US_PER_MS)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Maximum time interval between two consecutive preamble packets in GoMacH.
|
||||
*
|
||||
* In GoMacH, a sender first uses preamble stream to track the receiver's wake-up
|
||||
* phase (WP), if the receiver's WP is unknown. This macro defines the maximum
|
||||
* time interval between twoconsecutive preamble packets.
|
||||
*/
|
||||
#ifndef GNRC_GOMACH_MAX_PREAM_INTERVAL_US
|
||||
#define GNRC_GOMACH_MAX_PREAM_INTERVAL_US (6U * US_PER_MS)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Time interval between two consecutive preamble packets in GoMacH.
|
||||
*
|
||||
* In GoMacH, after a preamble is sent, the sender sets a timeout with
|
||||
* @ref GNRC_GOMACH_PREAMBLE_INTERVAL_US duration for waiting to send the next
|
||||
* preamble. Notably, this macro is with a very small value. In GoMacH, for
|
||||
* receiving the preamble-ACK packet, the sender doesn't wait for the whole
|
||||
* reception of the preamble-ACK. Instead, it only waits for the
|
||||
* @ref NETDEV_EVENT_RX_STARTED event which leads to shorter time interval
|
||||
* between two consecutive preamble transmissions.
|
||||
*/
|
||||
#ifndef GNRC_GOMACH_PREAMBLE_INTERVAL_US
|
||||
#define GNRC_GOMACH_PREAMBLE_INTERVAL_US (2U * US_PER_MS)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Time interval between two consecutive broadcast packets in GoMacH.
|
||||
*
|
||||
* In GoMacH, when sending a broadcast packet, the sender broadcasts the same
|
||||
* packet frame on its two public channels simultaneously, with a total duration
|
||||
* of @ref GNRC_GOMACH_SUPERFRAME_DURATION_US to guarantee that all neighbors
|
||||
* will get a copy. This macro defines the time interval between sending two
|
||||
* consecutive broadcast copies.
|
||||
*/
|
||||
#ifndef GNRC_GOMACH_BCAST_INTERVAL_US
|
||||
#define GNRC_GOMACH_BCAST_INTERVAL_US (1U * US_PER_MS)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief The Maximum preamble duration time of GoMacH.
|
||||
*
|
||||
* Since GoMacH adopts duty-cycle scheme, to probe receiver's wake-up period
|
||||
* a sender sends preamble streams to notice the receiver for communication.
|
||||
* To ensure that the receiver will catch at least one preamble packet
|
||||
* in a critical case that one public channel is jammed, the sender repeatedly
|
||||
* broadcasts a stream of preamble packets with the broadcast duration
|
||||
* (preamble duration) slightly longer than twice
|
||||
* of @ref GNRC_GOMACH_SUPERFRAME_DURATION_US.
|
||||
*/
|
||||
#ifndef GNRC_GOMACH_PREAMBLE_DURATION_US
|
||||
#define GNRC_GOMACH_PREAMBLE_DURATION_US (21LU * GNRC_GOMACH_SUPERFRAME_DURATION_US / 10)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief The transmission slot size in GoMacH.
|
||||
*
|
||||
* GoMacH adopts dynamic slots allocation scheme to allocate transmission
|
||||
* slots to senders that have pending packets. Each slot is for one data packet
|
||||
* with ACK transmission. @ref GNRC_GOMACH_VTDMA_SLOT_SIZE_US is right sufficient
|
||||
* for the transmission of the longest packet in IEEE 802.15.4 with ACK. Should
|
||||
* not be changed.
|
||||
*/
|
||||
#ifndef GNRC_GOMACH_VTDMA_SLOT_SIZE_US
|
||||
#define GNRC_GOMACH_VTDMA_SLOT_SIZE_US (5U * US_PER_MS)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Maximum times of CSMA TX attempts under busy-indication in the WP
|
||||
* period of the receiver.
|
||||
*
|
||||
* Senders in GoMacH adopt CSMA scheme to send data packets in the WP period of
|
||||
* the receiver. In case of having medium-busy feedback in WP and the TX failure
|
||||
* count (due to busy) is below @ref GNRC_GOMACH_TX_BUSY_THRESHOLD, the sender
|
||||
* continue to send the packet with CSMAin the receiver's WP, with the consideration
|
||||
* that there may be multi-senderssimultaneously competing in WP and the WP will
|
||||
* be continuously extended (thus the packet can be received).
|
||||
*/
|
||||
#ifndef GNRC_GOMACH_TX_BUSY_THRESHOLD
|
||||
#define GNRC_GOMACH_TX_BUSY_THRESHOLD (5U)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Maximum WP period extension number in GoMacH.
|
||||
*
|
||||
* In GoMacH, the WP period of a receiver will be extended upon each successful
|
||||
* packet reception (except receiving broadcast or preamble packet) to receive
|
||||
* more potentialincoming packets. This macro defines the maximum WP period
|
||||
* extension number allowed in GoMacH.
|
||||
*/
|
||||
#ifndef GNRC_GOMACH_CP_EXTEND_THRESHOLD
|
||||
#define GNRC_GOMACH_CP_EXTEND_THRESHOLD (5U)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief GoMacH's check-duplicate-packet unit life time in cycle count.
|
||||
*
|
||||
* In GoMacH, to avoid receiving duplicate-packet, we currently introduce a
|
||||
* data type of @ref gnrc_gomach_dupchk_unit_t to record the recent senders'
|
||||
* information (especially MAC TX sequence). This macro defines the
|
||||
* check-duplicate-packet data unit's life time in cycle count. Once expired,
|
||||
* the related data unit will be reset. This macro maybe removed in the future.
|
||||
*/
|
||||
#ifndef GNRC_GOMACH_RX_DUPCHK_UNIT_LIFE
|
||||
#define GNRC_GOMACH_RX_DUPCHK_UNIT_LIFE (30U)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Maximum number of slots allowed to be allocated in one cycle.
|
||||
*
|
||||
* GoMacH dynamically allocates transmission slots to senders that have
|
||||
* pending packets.This macro defines the maximum number of slots allowed
|
||||
* to be allocated in one cycle.
|
||||
*/
|
||||
#ifndef GNRC_GOMACH_MAX_ALLOC_SLOTS_NUM
|
||||
#define GNRC_GOMACH_MAX_ALLOC_SLOTS_NUM (25U)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Maximum t2k attempts before going to t2u in GoMacH.
|
||||
*
|
||||
* After phase-locked with the receiver, a sender runs a t2k (transmit-to-known)
|
||||
* procedure to transmit packet to the phase-known device. However, due to
|
||||
* factors like timer driftor busy-channel, a transmission attempt may fail
|
||||
* in t2k. If the t2k failure count has reached this
|
||||
* @ref GNRC_GOMACH_REPHASELOCK_THRESHOLD, the sender regards phase-locked failed
|
||||
* due to timer drift. In this case, it will adopt t2u (transmit-to-unknown)
|
||||
* procedure to get re-phase-locked with the receiver.
|
||||
*/
|
||||
#ifndef GNRC_GOMACH_REPHASELOCK_THRESHOLD
|
||||
#define GNRC_GOMACH_REPHASELOCK_THRESHOLD (4U)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Maximum t2u attempts before dropping data packet in GoMacH.
|
||||
*
|
||||
* In case the receiver's phase is unknown to the sender, the sender adopts
|
||||
* the t2u (transmit-to-unknown) procedure to get phase-locked with the
|
||||
* receiver. This macrodefines the maximum t2u attempts before dropping the
|
||||
* data packet in GoMacH.
|
||||
*/
|
||||
#ifndef GNRC_GOMACH_T2U_RETYR_THRESHOLD
|
||||
#define GNRC_GOMACH_T2U_RETYR_THRESHOLD (2U)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Maximum t2u attempts before re-initiate radio in GoMacH.
|
||||
*
|
||||
* After a long period of run time, a radio may be in wrong condition which
|
||||
* needs to be re-calibrated. This is indicated by having a series of
|
||||
* continuous t2u failures (no preambleACK) in GoMacH. In cast we have
|
||||
* @ref GNRC_GOMACH_MAX_T2U_RETYR_THRESHOLD number of t2u failures, then we
|
||||
* re-initiate the radio, trying to re-calibrate the radio for bringing it
|
||||
* back to normal condition.
|
||||
*/
|
||||
#ifndef GNRC_GOMACH_MAX_T2U_RETYR_THRESHOLD
|
||||
#define GNRC_GOMACH_MAX_T2U_RETYR_THRESHOLD (10U)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Default message queue size to use for the GoMacH thread.
|
||||
*
|
||||
* The value of this macro should be enough for supporting the manipulation of
|
||||
* GoMacH.
|
||||
*/
|
||||
#ifndef GNRC_GOMACH_IPC_MSG_QUEUE_SIZE
|
||||
#define GNRC_GOMACH_IPC_MSG_QUEUE_SIZE (8U)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Creates an IEEE 802.15.4 GoMacH network interface
|
||||
*
|
||||
* @param[in] stack The stack for the GoMacH network interface's thread.
|
||||
* @param[in] stacksize Size of @p stack.
|
||||
* @param[in] priority Priority for the GoMacH network interface's thread.
|
||||
* @param[in] name Name for the GoMacH network interface. May be NULL.
|
||||
* @param[in] dev Device for the interface
|
||||
*
|
||||
* @see @ref gnrc_netif_create()
|
||||
*
|
||||
* @return The network interface on success.
|
||||
* @return NULL, on error.
|
||||
*/
|
||||
gnrc_netif_t *gnrc_netif_gomach_create(char *stack, int stacksize,
|
||||
char priority, char *name,
|
||||
netdev_t *dev);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NET_GNRC_GOMACH_GOMACH_H */
|
||||
/** @} */
|
||||
143
sys/include/net/gnrc/gomach/hdr.h
Normal file
143
sys/include/net/gnrc/gomach/hdr.h
Normal file
@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright (C) 2017 INRIA
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup net_gnrc_gomach
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Header definition of GoMacH
|
||||
* @internal
|
||||
* @author Shuguo Zhuo <shuguo.zhuo@inria.fr>
|
||||
*/
|
||||
|
||||
#ifndef NET_GNRC_GOMACH_HDR_H
|
||||
#define NET_GNRC_GOMACH_HDR_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "net/ieee802154.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief GoMacH internal L2 address structure.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t addr[IEEE802154_LONG_ADDRESS_LEN]; /**< Address of node. */
|
||||
uint8_t len; /**< Address length. */
|
||||
} gnrc_gomach_l2_addr_t;
|
||||
|
||||
/**
|
||||
* @brief Static initializer for gnrc_gomach_l2_addr_t.
|
||||
*/
|
||||
#define GNRC_GOMACH_L2_ADDR_INIT { { 0 }, 0 }
|
||||
|
||||
/**
|
||||
* @brief GoMacH beacon frame type.
|
||||
*/
|
||||
#define GNRC_GOMACH_FRAME_BEACON (0x01U)
|
||||
|
||||
/**
|
||||
* @brief GoMacH data frame type.
|
||||
*/
|
||||
#define GNRC_GOMACH_FRAME_DATA (0x02U)
|
||||
|
||||
/**
|
||||
* @brief GoMacH preamble frame type.
|
||||
*/
|
||||
#define GNRC_GOMACH_FRAME_PREAMBLE (0x03U)
|
||||
|
||||
/**
|
||||
* @brief GoMacH preamble-ACK frame type.
|
||||
*/
|
||||
#define GNRC_GOMACH_FRAME_PREAMBLE_ACK (0x04U)
|
||||
|
||||
/**
|
||||
* @brief GoMacH broadcast frame type.
|
||||
*/
|
||||
#define GNRC_GOMACH_FRAME_BROADCAST (0x05U)
|
||||
|
||||
/**
|
||||
* @brief GoMacH announce frame type.
|
||||
*
|
||||
* This frame type is specifically used to announce the chosen sub-channel
|
||||
* sequence of the node to its one-hop neighbors.
|
||||
*/
|
||||
#define GNRC_GOMACH_FRAME_ANNOUNCE (0x06U)
|
||||
|
||||
/**
|
||||
* @brief GoMacH frame header.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t type; /**< Type of GoMacH frame. */
|
||||
} gnrc_gomach_hdr_t;
|
||||
|
||||
/**
|
||||
* @brief GoMacH Beacon frame
|
||||
*/
|
||||
typedef struct __attribute__((packed)) {
|
||||
gnrc_gomach_hdr_t header; /**< Beacon frame header type. */
|
||||
uint8_t sub_channel_seq; /**< Sub-channel sequence of this node. */
|
||||
uint8_t schedulelist_size; /**< vTDMA schedule list size. */
|
||||
} gnrc_gomach_frame_beacon_t;
|
||||
|
||||
/**
|
||||
* @brief GoMacH data frame
|
||||
*/
|
||||
typedef struct __attribute__((packed)) {
|
||||
gnrc_gomach_hdr_t header; /**< Data frame header type. */
|
||||
uint8_t queue_indicator; /**< Queue-length indicator of this node. */
|
||||
} gnrc_gomach_frame_data_t;
|
||||
|
||||
/**
|
||||
* @brief GoMacH sub-channel announce frame.
|
||||
*
|
||||
* This frame type is specifically used to announce the chosen sub-channel
|
||||
* sequence of the node to its one-hop neighbors.
|
||||
*/
|
||||
typedef struct __attribute__((packed)) {
|
||||
gnrc_gomach_hdr_t header; /**< Announce frame header type. */
|
||||
uint8_t subchannel_seq; /**< Sub-channel sequence of this node. */
|
||||
} gnrc_gomach_frame_announce_t;
|
||||
|
||||
/**
|
||||
* @brief GoMacH preamble frame.
|
||||
*/
|
||||
typedef struct __attribute__((packed)) {
|
||||
gnrc_gomach_hdr_t header; /**< Preamble frame header type. */
|
||||
gnrc_gomach_l2_addr_t dst_addr; /**< Address of this node. */
|
||||
} gnrc_gomach_frame_preamble_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief GoMacH preamble_ack frame.
|
||||
*/
|
||||
typedef struct __attribute__((packed)) {
|
||||
gnrc_gomach_hdr_t header; /**< Preamble-ACK frame header type. */
|
||||
gnrc_gomach_l2_addr_t dst_addr; /**< Address of this node. */
|
||||
uint32_t phase_in_us; /**< Current phase of this node. */
|
||||
} gnrc_gomach_frame_preamble_ack_t;
|
||||
|
||||
/**
|
||||
* @brief GoMacH broadcast frame.
|
||||
*/
|
||||
typedef struct __attribute__((packed)) {
|
||||
gnrc_gomach_hdr_t header; /**< Broadcast frame header type. */
|
||||
uint8_t seq_nr; /**< Broadcast sequence of this node. */
|
||||
} gnrc_gomach_frame_broadcast_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NET_GNRC_GOMACH_HDR_H */
|
||||
/** @} */
|
||||
100
sys/include/net/gnrc/gomach/timeout.h
Normal file
100
sys/include/net/gnrc/gomach/timeout.h
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (C) 2017 INRIA
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup net_gnrc_gomach
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Timeout handling of GoMacH.
|
||||
* @internal
|
||||
* @author Shuguo Zhuo <shuguo.zhuo@inria.fr>
|
||||
*/
|
||||
|
||||
#ifndef NET_GNRC_GOMACH_TIMEOUT_H
|
||||
#define NET_GNRC_GOMACH_TIMEOUT_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "msg.h"
|
||||
#include "xtimer.h"
|
||||
#include "net/gnrc/netif.h"
|
||||
#include "types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Set GoMacH timeout of type @p type of offset @p offset.
|
||||
*
|
||||
* @param[in,out] netif the network interface.
|
||||
* @param[in] type GoMacH timeout type.
|
||||
* @param[in] offset timeout offset.
|
||||
*/
|
||||
void gnrc_gomach_set_timeout(gnrc_netif_t *netif,
|
||||
gnrc_gomach_timeout_type_t type,
|
||||
uint32_t offset);
|
||||
|
||||
/**
|
||||
* @brief Clear GoMacH timeout of type @p type.
|
||||
*
|
||||
* @param[in,out] netif the network interface.
|
||||
* @param[in] type GoMacH timeout type.
|
||||
*/
|
||||
void gnrc_gomach_clear_timeout(gnrc_netif_t *netif, gnrc_gomach_timeout_type_t type);
|
||||
|
||||
/**
|
||||
* @brief Check whether GoMacH timeout of type @p type is running.
|
||||
*
|
||||
* @param[in] netif the network interface.
|
||||
* @param[in] type GoMacH timeout type.
|
||||
*
|
||||
* @return true, if timeout of type @p type is running.
|
||||
* @return false, if timeout of type @p type is not running.
|
||||
*/
|
||||
bool gnrc_gomach_timeout_is_running(gnrc_netif_t *netif, gnrc_gomach_timeout_type_t type);
|
||||
|
||||
/**
|
||||
* @brief Check whether GoMacH timeout of type @p type is expired. It will clear
|
||||
* the timeout once it is found expired.
|
||||
*
|
||||
* @param[in,out] netif the network interface.
|
||||
* @param[in] type GoMacH timeout type.
|
||||
*
|
||||
* @return true, if timeout of type @p type is expired.
|
||||
* @return false, if timeout of type @p type is not expired, or not exist.
|
||||
*/
|
||||
bool gnrc_gomach_timeout_is_expired(gnrc_netif_t *netif, gnrc_gomach_timeout_type_t type);
|
||||
|
||||
/**
|
||||
* @brief Reset all GoMacH timeouts.
|
||||
*
|
||||
* @param[in,out] netif the network interface.
|
||||
*/
|
||||
void gnrc_gomach_reset_timeouts(gnrc_netif_t *netif);
|
||||
|
||||
/**
|
||||
* @brief Make a specific GoMacH timeout expired.
|
||||
*
|
||||
* @param[in,out] timeout GoMacH timeout
|
||||
*/
|
||||
static inline void gnrc_gomach_timeout_make_expire(gnrc_gomach_timeout_t *timeout)
|
||||
{
|
||||
assert(timeout);
|
||||
|
||||
timeout->expired = true;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NET_GNRC_GOMACH_TIMEOUT_H */
|
||||
/** @} */
|
||||
326
sys/include/net/gnrc/gomach/types.h
Normal file
326
sys/include/net/gnrc/gomach/types.h
Normal file
@ -0,0 +1,326 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Shuguo Zhuo
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup net_gnrc_gomach
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Internal used types of GoMacH
|
||||
* @internal
|
||||
* @author Shuguo Zhuo <shuguo.zhuo@inria.fr>
|
||||
*/
|
||||
|
||||
#ifndef NET_GNRC_GOMACH_TYPES_H
|
||||
#define NET_GNRC_GOMACH_TYPES_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "kernel_types.h"
|
||||
#include "xtimer.h"
|
||||
#include "net/gnrc.h"
|
||||
#include "net/gnrc/gomach/hdr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief GoMacH RTT event type.
|
||||
*/
|
||||
#define GNRC_GOMACH_EVENT_RTT_TYPE (0x4300)
|
||||
|
||||
/**
|
||||
* @brief GoMacH RTT new cycle start event type.
|
||||
*/
|
||||
#define GNRC_GOMACH_EVENT_RTT_NEW_CYCLE (0x4301)
|
||||
|
||||
/**
|
||||
* @brief GoMacH timeout event type.
|
||||
*/
|
||||
#define GNRC_GOMACH_EVENT_TIMEOUT_TYPE (0x4400)
|
||||
|
||||
/**
|
||||
* @brief GoMacH uninitialized phase value.
|
||||
*/
|
||||
#define GNRC_GOMACH_PHASE_UNINITIALIZED (0)
|
||||
|
||||
/**
|
||||
* @brief GoMacH max phase value.
|
||||
*/
|
||||
#define GNRC_GOMACH_PHASE_MAX (-1)
|
||||
|
||||
/**
|
||||
* @brief GoMacH check duplicate packet buffer size.
|
||||
*/
|
||||
#define GNRC_GOMACH_DUPCHK_BUFFER_SIZE (8U)
|
||||
|
||||
/**
|
||||
* @brief The default largest number of parallel timeouts in GoMacH.
|
||||
*/
|
||||
#define GNRC_GOMACH_TIMEOUT_COUNT (6U)
|
||||
|
||||
/**
|
||||
* @brief The default number of slot-schedule-unit
|
||||
* @ref gnrc_gomach_slosch_unit_t in GoMacH.
|
||||
*/
|
||||
#define GNRC_GOMACH_SLOSCH_UNIT_COUNT (11U)
|
||||
|
||||
/**
|
||||
* @brief MAC type of unknown in GoMacH for indicating that
|
||||
* the node's phase is unknown.
|
||||
*/
|
||||
#define GNRC_GOMACH_TYPE_UNKNOWN (0U)
|
||||
|
||||
/**
|
||||
* @brief MAC type of known in GoMacH for indicating that the
|
||||
* node's phase is known.
|
||||
*/
|
||||
#define GNRC_GOMACH_TYPE_KNOWN (1U)
|
||||
|
||||
/**
|
||||
* @brief Enable/disable duty-cycle record and print out.
|
||||
*
|
||||
* Set "1" to enable, set "0" to disable.
|
||||
*/
|
||||
#ifndef GNRC_GOMACH_ENABLE_DUTYCYLE_RECORD
|
||||
#define GNRC_GOMACH_ENABLE_DUTYCYLE_RECORD (0U)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief State-machine states of Broadcast procedure of GoMacH.
|
||||
*/
|
||||
typedef enum {
|
||||
GNRC_GOMACH_BCAST_INIT, /**< Initiate broadcast. */
|
||||
GNRC_GOMACH_BCAST_SEND, /**< Send broadcast packet. */
|
||||
GNRC_GOMACH_BCAST_WAIT_TX_FINISH, /**< Wait for broadcast TX finish. */
|
||||
GNRC_GOMACH_BCAST_WAIT_NEXT_TX, /**< Wait for next broadcast TX timing. */
|
||||
GNRC_GOMACH_BCAST_END /**< End of broadcast procedure. */
|
||||
} gnrc_gomach_bcast_state_t;
|
||||
|
||||
/**
|
||||
* @brief State-machine states of Transmission-to-phase-known
|
||||
* (t2k) procedure of GoMacH.
|
||||
*/
|
||||
typedef enum {
|
||||
GNRC_GOMACH_T2K_INIT, /**< Initiate t2k procedure. */
|
||||
GNRC_GOMACH_T2K_WAIT_CP, /**< Wait for receiver's CP (wake-up) period. */
|
||||
GNRC_GOMACH_T2K_TRANS_IN_CP, /**< Transmit data in receiver's CP period. */
|
||||
GNRC_GOMACH_T2K_WAIT_CPTX_FEEDBACK, /**< Wait for CP transmission finish. */
|
||||
GNRC_GOMACH_T2K_WAIT_BEACON, /**< Wait receiver's beacon. */
|
||||
GNRC_GOMACH_T2K_WAIT_SLOTS, /**< Wait for the node's allocated slots period. */
|
||||
GNRC_GOMACH_T2K_VTDMA_TRANS, /**< Transmit data in allocate slots. */
|
||||
GNRC_GOMACH_T2K_WAIT_VTDMA_FEEDBACK, /**< Wait for TX finish in TX-slot. */
|
||||
GNRC_GOMACH_T2K_END /**< End of t2k procedure. */
|
||||
} gnrc_gomach_t2k_state_t;
|
||||
|
||||
/**
|
||||
* @brief State-machine states of Transmission-to-phase-unknown
|
||||
* (t2u) procedure of GoMacH.
|
||||
*/
|
||||
typedef enum {
|
||||
GNRC_GOMACH_T2U_INIT, /**< Initiate t2u procedure. */
|
||||
GNRC_GOMACH_T2U_PREAMBLE_PREPARE, /**< Prepare settings before sending preamble. */
|
||||
GNRC_GOMACH_T2U_SEND_PREAMBLE, /**< Send preamble in t2u. */
|
||||
GNRC_GOMACH_T2U_WAIT_PREAMBLE_TX, /**< Wait for Send preamble TX finish. */
|
||||
GNRC_GOMACH_T2U_WAIT_PREAMBLE_ACK, /**< Wait for preamble-ACK from receiver. */
|
||||
GNRC_GOMACH_T2U_SEND_DATA, /**< Send data packet to the receiver. */
|
||||
GNRC_GOMACH_T2U_WAIT_DATA_TX, /**< Wait for Send data TX finish. */
|
||||
GNRC_GOMACH_T2U_END /**< End of t2u procedure. */
|
||||
} gnrc_gomach_t2u_state_t;
|
||||
|
||||
/**
|
||||
* @brief State-machine states of basic management procedure of GoMacH.
|
||||
*/
|
||||
typedef enum {
|
||||
GNRC_GOMACH_INIT, /**< Initiate GoMacH. */
|
||||
GNRC_GOMACH_LISTEN, /**< GoMacH's duty-cycled listen procedure. */
|
||||
GNRC_GOMACH_TRANSMIT /**< GoMacH's transmission procedure. */
|
||||
} gnrc_gomach_basic_state_t;
|
||||
|
||||
/**
|
||||
* @brief State-machine states of initialization procedure of GoMacH.
|
||||
*/
|
||||
typedef enum {
|
||||
GNRC_GOMACH_INIT_PREPARE, /**< Prepare the initialization procedure of GoMacH. */
|
||||
GNRC_GOMACH_INIT_ANNC_SUBCHAN, /**< Announce the sub-channel sequence of the node. */
|
||||
GNRC_GOMACH_INIT_WAIT_FEEDBACK, /**< Wait for announce TX finish. */
|
||||
GNRC_GOMACH_INIT_END /**< End of the initialization procedure of GoMacH. */
|
||||
} gnrc_gomach_init_state_t;
|
||||
|
||||
/**
|
||||
* @brief State-machine states of duty-cycled listening procedure of GoMacH.
|
||||
*/
|
||||
typedef enum {
|
||||
GNRC_GOMACH_LISTEN_CP_INIT, /**< Initiate the listen period. */
|
||||
GNRC_GOMACH_LISTEN_CP_LISTEN, /**< Listen for incoming packets. */
|
||||
GNRC_GOMACH_LISTEN_CP_END, /**< End of packet listen period. */
|
||||
GNRC_GOMACH_LISTEN_SEND_BEACON, /**< Send beacon packet when needed. */
|
||||
GNRC_GOMACH_LISTEN_WAIT_BEACON_TX, /**< Wait for send beacon TX finish. */
|
||||
GNRC_GOMACH_LISTEN_VTDMA_INIT, /**< Initiate the vTDMA period. */
|
||||
GNRC_GOMACH_LISTEN_VTDMA, /**< Listen for incoming packets in vTDMA. */
|
||||
GNRC_GOMACH_LISTEN_VTDMA_END, /**< End of the vTDMA period. */
|
||||
GNRC_GOMACH_LISTEN_SLEEP_INIT, /**< Initiate the sleep period. */
|
||||
GNRC_GOMACH_LISTEN_SLEEP, /**< Turn radio off to sleep. */
|
||||
GNRC_GOMACH_LISTEN_SLEEP_END /**< End of the sleep period. */
|
||||
} gnrc_gomach_listen_state_t;
|
||||
|
||||
/**
|
||||
* @brief State-machine states of basic transmission management procedure of GoMacH.
|
||||
*/
|
||||
typedef enum {
|
||||
GNRC_GOMACH_TRANS_TO_UNKNOWN, /**< Transmit to phase-unknown node in GoMacH. */
|
||||
GNRC_GOMACH_TRANS_TO_KNOWN, /**< Transmit to phase-known node in GoMacH. */
|
||||
GNRC_GOMACH_BROADCAST /**< Broadcast packet in GoMacH. */
|
||||
} gnrc_gomach_transmit_state_t;
|
||||
|
||||
/**
|
||||
* @brief GoMacH timeout types.
|
||||
*/
|
||||
typedef enum {
|
||||
GNRC_GOMACH_TIMEOUT_DISABLED, /**< Timeout is disabled. */
|
||||
GNRC_GOMACH_TIMEOUT_BCAST_FINISH, /**< Timeout of broadcast procedure end. */
|
||||
GNRC_GOMACH_TIMEOUT_BCAST_INTERVAL, /**< Timeout of next broadcast transmission. */
|
||||
GNRC_GOMACH_TIMEOUT_PREAMBLE, /**< Timeout of next preamble transmission. */
|
||||
GNRC_GOMACH_TIMEOUT_MAX_PREAM_INTERVAL, /**< Timeout of maximum preamble interval. */
|
||||
GNRC_GOMACH_TIMEOUT_PREAM_DURATION, /**< Timeout of maximum preamble duration. */
|
||||
GNRC_GOMACH_TIMEOUT_WAIT_CP, /**< Timeout of waiting receiver's CP period. */
|
||||
GNRC_GOMACH_TIMEOUT_WAIT_BEACON, /**< Timeout of waiting beacon. */
|
||||
GNRC_GOMACH_TIMEOUT_WAIT_SLOTS, /**< Timeout of waiting own slots. */
|
||||
GNRC_GOMACH_TIMEOUT_CP_END, /**< Timeout of CP (wake-up) period ending. */
|
||||
GNRC_GOMACH_TIMEOUT_CP_MAX, /**< Timeout of maximum CP duration. */
|
||||
GNRC_GOMACH_TIMEOUT_WAIT_RX_END, /**< Timeout of waiting reception complete. */
|
||||
GNRC_GOMACH_TIMEOUT_VTDMA, /**< Timeout of vTDMA period end. */
|
||||
GNRC_GOMACH_TIMEOUT_NO_TX_ISR, /**< Timeout of maximum transmission duration. */
|
||||
} gnrc_gomach_timeout_type_t;
|
||||
|
||||
/**
|
||||
* @brief GoMacH internal L2 address structure
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t addr[IEEE802154_LONG_ADDRESS_LEN]; /**< Node's address. */
|
||||
} gnrc_gomach_l2_id_t;
|
||||
|
||||
/**
|
||||
* @brief GoMacH's slot-schedule-unit.
|
||||
*
|
||||
* This slot-schedule-unit is used to record related information of a node for
|
||||
* running the dynamic slots allocation scheme in GoMacH.
|
||||
*/
|
||||
typedef struct {
|
||||
gnrc_gomach_l2_addr_t node_addr; /**< Node's address. */
|
||||
uint8_t queue_indicator; /**< Node's queue-length indicator. */
|
||||
} gnrc_gomach_slosch_unit_t;
|
||||
|
||||
/**
|
||||
* @brief GoMacH's vTDMA (dynamic slots allocation) management unit.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t total_slots_num; /**< Number of total allocated transmission slots. */
|
||||
uint8_t sub_channel_seq; /**< Receiver's sub-channel sequence. */
|
||||
} gnrc_gomach_vtdma_manag_t;
|
||||
|
||||
/**
|
||||
* @brief GoMacH's data structure for recording sender's past TX information.
|
||||
*/
|
||||
typedef struct {
|
||||
gnrc_gomach_l2_addr_t node_addr; /**< Node's address. */
|
||||
uint8_t seq; /**< Node's MAC packet sequence. */
|
||||
uint8_t life_cycle; /**< Lifetime of this record unit. */
|
||||
} gnrc_gomach_dupchk_unit_t;
|
||||
|
||||
/**
|
||||
* @brief GoMacH's data structure for recording TX information for avoiding receiving
|
||||
* duplicate packets.
|
||||
*/
|
||||
typedef struct {
|
||||
gnrc_gomach_dupchk_unit_t last_nodes[GNRC_GOMACH_DUPCHK_BUFFER_SIZE]; /**< Duplicate
|
||||
check unit. */
|
||||
uint8_t queue_head; /**< Check queue's
|
||||
head. */
|
||||
} gnrc_gomach_dupchk_t;
|
||||
|
||||
/**
|
||||
* @brief Type to pass information about packet parsing.
|
||||
*/
|
||||
typedef struct {
|
||||
gnrc_gomach_hdr_t *header; /**< GoMacH header of packet. */
|
||||
gnrc_gomach_l2_addr_t src_addr; /**< Copied source address of packet. */
|
||||
gnrc_gomach_l2_addr_t dst_addr; /**< Copied destination address of packet. */
|
||||
uint8_t seq; /**< MAC sequence of the received packet. */
|
||||
} gnrc_gomach_packet_info_t;
|
||||
|
||||
/**
|
||||
* @brief Sender's vTDMA (dynamic slots allocation) management unit.
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t sub_channel_seq; /**< Receiver's sub-channel sequence. */
|
||||
uint8_t slots_position; /**< Node's own slots position. */
|
||||
uint8_t slots_num; /**< Node's allocated slots number. */
|
||||
} gnrc_gomach_vtdma_t;
|
||||
|
||||
/**
|
||||
* @brief GoMacH's timeout structure
|
||||
*/
|
||||
typedef struct {
|
||||
xtimer_t timer; /**< xtimer entity. */
|
||||
msg_t msg; /**< msg entity. */
|
||||
bool expired; /**< Timeout expiration indicator. */
|
||||
gnrc_gomach_timeout_type_t type; /**< GoMacH timeout type. */
|
||||
} gnrc_gomach_timeout_t;
|
||||
|
||||
/**
|
||||
* @brief Static initializer for @ref gnrc_gomach_timeout_t.
|
||||
*/
|
||||
#define GNRC_GOMACH_TIMEOUT_INIT { {}, {}, false, GNRC_GOMACH_TIMEOUT_DISABLED }
|
||||
|
||||
/**
|
||||
* @brief GoMacH's specific structure for storing internal states.
|
||||
*/
|
||||
typedef struct gomach {
|
||||
gnrc_gomach_basic_state_t basic_state; /**< Basic state. */
|
||||
gnrc_gomach_init_state_t init_state; /**< Initialization state. */
|
||||
gnrc_gomach_timeout_t timeouts[GNRC_GOMACH_TIMEOUT_COUNT]; /**< GoMacH's timeouts. */
|
||||
uint16_t subchannel_occu_flags; /**< Sub-channel
|
||||
usage indicator. */
|
||||
uint16_t sub_channel_seq; /**< Sub-channel sequence. */
|
||||
uint16_t pub_channel_1; /**< Public channel 1. */
|
||||
uint16_t pub_channel_2; /**< Public channel 2. */
|
||||
uint16_t cur_pub_channel; /**< Current public channel. */
|
||||
uint8_t cp_extend_count; /**< CP extend count. */
|
||||
uint32_t last_wakeup; /**< Last wake-up timing. */
|
||||
uint32_t backoff_phase_us; /**< Phase backoff time. */
|
||||
uint16_t gomach_info; /**< GoMacH's internal
|
||||
information. */
|
||||
uint64_t last_wakeup_phase_us; /**< Last cycle wakeup phase. */
|
||||
int16_t rx_pkt_rssi; /**< RSSI of latest received
|
||||
packet in dBm */
|
||||
uint8_t rx_pkt_lqi; /**< LQI of latest received
|
||||
packet */
|
||||
|
||||
|
||||
#if (GNRC_GOMACH_ENABLE_DUTYCYLE_RECORD == 1)
|
||||
/* Parameters for recording duty-cycle */
|
||||
uint64_t last_radio_on_time_ticks; /**< The last time in ticks
|
||||
when radio is on */
|
||||
uint64_t radio_off_time_ticks; /**< The time in ticks when
|
||||
radio is off */
|
||||
uint64_t system_start_time_ticks; /**< The time in ticks when
|
||||
chip is started */
|
||||
uint64_t awake_duration_sum_ticks; /**< The sum of time in ticks
|
||||
when radio is on */
|
||||
#endif
|
||||
} gnrc_gomach_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NET_GNRC_GOMACH_TYPES_H */
|
||||
/** @} */
|
||||
@ -32,6 +32,9 @@
|
||||
#ifdef MODULE_GNRC_LWMAC
|
||||
#include "net/gnrc/lwmac/types.h"
|
||||
#endif
|
||||
#ifdef MODULE_GNRC_GOMACH
|
||||
#include "net/gnrc/gomach/types.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -75,6 +78,13 @@ typedef struct {
|
||||
gnrc_lwmac_rx_state_t state; /**< LWMAC specific internal reception state */
|
||||
uint8_t rx_bad_exten_count; /**< Count how many unnecessary RX extensions have been executed */
|
||||
#endif
|
||||
|
||||
#ifdef MODULE_GNRC_GOMACH
|
||||
gnrc_gomach_listen_state_t listen_state; /**< Listen state. */
|
||||
gnrc_gomach_slosch_unit_t slosch_list[GNRC_GOMACH_SLOSCH_UNIT_COUNT]; /**< Queue-indicator record units. */
|
||||
gnrc_gomach_vtdma_manag_t vtdma_manag; /**< vTDMA management unit. */
|
||||
gnrc_gomach_dupchk_t check_dup_pkt; /**< Check duplicate packet unit. */
|
||||
#endif
|
||||
} gnrc_mac_rx_t;
|
||||
|
||||
/**
|
||||
@ -110,6 +120,12 @@ typedef struct {
|
||||
#if (GNRC_MAC_TX_QUEUE_SIZE != 0) || defined(DOXYGEN)
|
||||
gnrc_priority_pktqueue_t queue; /**< TX queue for this particular Neighbor */
|
||||
#endif /* (GNRC_MAC_TX_QUEUE_SIZE != 0) || defined(DOXYGEN) */
|
||||
|
||||
#ifdef MODULE_GNRC_GOMACH
|
||||
uint16_t pub_chanseq; /**< Neighbor's current public channel sequence. */
|
||||
uint32_t cp_phase; /**< Neighbor's wake-up phase. */
|
||||
uint8_t mac_type; /**< Neighbor's phase-track indicator. */
|
||||
#endif
|
||||
} gnrc_mac_tx_neighbor_t;
|
||||
|
||||
/**
|
||||
@ -175,6 +191,22 @@ typedef struct {
|
||||
uint8_t tx_burst_count; /**< Count how many consecutive packets have been transmitted */
|
||||
uint8_t tx_retry_count; /**< Count how many Tx-retrials have been executed before packet drop */
|
||||
#endif
|
||||
|
||||
#ifdef MODULE_GNRC_GOMACH
|
||||
gnrc_gomach_transmit_state_t transmit_state; /**< Basic transmission state. */
|
||||
gnrc_gomach_bcast_state_t bcast_state; /**< Broadcast state. */
|
||||
gnrc_gomach_t2k_state_t t2k_state; /**< t2k (transmit-to-known) state. */
|
||||
gnrc_gomach_t2u_state_t t2u_state; /**< t2u (transmit-to-unknown) state. */
|
||||
uint8_t preamble_sent; /**< Preamble sent count. */
|
||||
uint8_t broadcast_seq; /**< Node's broadcast sequence. */
|
||||
uint8_t tx_seq; /**< Node's MAC transmission (TX) sequence. */
|
||||
gnrc_gomach_vtdma_t vtdma_para; /**< Node's vTMDA slots allocation management unit. */
|
||||
uint8_t no_ack_counter; /**< Counter for recording no-ACK times for data transmission. */
|
||||
uint8_t t2u_retry_counter; /**< Counter for recording t2u attempt failures. */
|
||||
uint8_t last_tx_neighbor_id; /**< Record last TX neighbor's sequence in the neighbor list. */
|
||||
uint8_t tx_busy_count; /**< Counter recording csma busy feedback times. */
|
||||
uint8_t t2u_fail_count; /**< Preamble trial failure count. */
|
||||
#endif
|
||||
} gnrc_mac_tx_t;
|
||||
|
||||
/**
|
||||
|
||||
@ -45,6 +45,27 @@ extern "C" {
|
||||
*/
|
||||
#define GNRC_NETIF_MAC_INFO_CSMA_ENABLED (0x0100U)
|
||||
|
||||
#if defined(MODULE_GNRC_LWMAC) || defined(MODULE_GNRC_GOMACH)
|
||||
/**
|
||||
* @brief Data type to hold MAC protocols
|
||||
*/
|
||||
typedef union {
|
||||
#ifdef MODULE_GNRC_LWMAC
|
||||
/**
|
||||
* @brief LWMAC specific structure object for storing LWMAC internal states.
|
||||
*/
|
||||
gnrc_lwmac_t lwmac;
|
||||
#endif
|
||||
|
||||
#ifdef MODULE_GNRC_GOMACH
|
||||
/**
|
||||
* @brief GoMacH specific structure object for storing GoMacH internal states.
|
||||
*/
|
||||
gnrc_gomach_t gomach;
|
||||
#endif
|
||||
} gnrc_mac_prot_t;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief @ref net_gnrc_mac component of @ref gnrc_netif_mac_t
|
||||
*/
|
||||
@ -80,11 +101,8 @@ typedef struct {
|
||||
gnrc_mac_tx_t tx;
|
||||
#endif /* ((GNRC_MAC_TX_QUEUE_SIZE != 0) || (GNRC_MAC_NEIGHBOR_COUNT == 0)) || DOXYGEN */
|
||||
|
||||
#ifdef MODULE_GNRC_LWMAC
|
||||
/**
|
||||
* @brief LWMAC specific structure object for storing LWMAC internal states.
|
||||
*/
|
||||
gnrc_lwmac_t lwmac;
|
||||
#if defined(MODULE_GNRC_LWMAC) || defined(MODULE_GNRC_GOMACH)
|
||||
gnrc_mac_prot_t prot;
|
||||
#endif
|
||||
} gnrc_netif_mac_t;
|
||||
|
||||
|
||||
@ -56,6 +56,17 @@ typedef enum {
|
||||
GNRC_NETTYPE_SIXLOWPAN, /**< Protocol is 6LoWPAN */
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @{
|
||||
* @name Link layer
|
||||
*/
|
||||
#ifdef MODULE_GNRC_GOMACH
|
||||
GNRC_NETTYPE_GOMACH, /**< Protocol is GoMacH */
|
||||
#endif
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @{
|
||||
* @name Link layer
|
||||
|
||||
@ -55,6 +55,9 @@ endif
|
||||
ifneq (,$(filter gnrc_pktbuf_malloc,$(USEMODULE)))
|
||||
DIRS += pktbuf_malloc
|
||||
endif
|
||||
ifneq (,$(filter gnrc_gomach,$(USEMODULE)))
|
||||
DIRS += link_layer/gomach
|
||||
endif
|
||||
ifneq (,$(filter gnrc_pktbuf_static,$(USEMODULE)))
|
||||
DIRS += pktbuf_static
|
||||
endif
|
||||
|
||||
@ -252,6 +252,19 @@ void gnrc_mac_dispatch(gnrc_mac_rx_t *rx)
|
||||
/* make append netif header after payload again */
|
||||
rx->dispatch_buffer[i]->next = netif;
|
||||
#endif
|
||||
|
||||
#ifdef MODULE_GNRC_GOMACH
|
||||
/* save pointer to netif header */
|
||||
gnrc_pktsnip_t *netif = rx->dispatch_buffer[i]->next->next;
|
||||
|
||||
/* remove GoMacH header */
|
||||
rx->dispatch_buffer[i]->next->next = NULL;
|
||||
gnrc_pktbuf_release(rx->dispatch_buffer[i]->next);
|
||||
|
||||
/* make append netif header after payload again */
|
||||
rx->dispatch_buffer[i]->next = netif;
|
||||
#endif
|
||||
|
||||
if (!gnrc_netapi_dispatch_receive(rx->dispatch_buffer[i]->type,
|
||||
GNRC_NETREG_DEMUX_CTX_ALL,
|
||||
rx->dispatch_buffer[i])) {
|
||||
|
||||
3
sys/net/gnrc/link_layer/gomach/Makefile
Normal file
3
sys/net/gnrc/link_layer/gomach/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
MODULE = gnrc_gomach
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
2211
sys/net/gnrc/link_layer/gomach/gomach.c
Normal file
2211
sys/net/gnrc/link_layer/gomach/gomach.c
Normal file
File diff suppressed because it is too large
Load Diff
1430
sys/net/gnrc/link_layer/gomach/gomach_internal.c
Normal file
1430
sys/net/gnrc/link_layer/gomach/gomach_internal.c
Normal file
File diff suppressed because it is too large
Load Diff
917
sys/net/gnrc/link_layer/gomach/include/gomach_internal.h
Normal file
917
sys/net/gnrc/link_layer/gomach/include/gomach_internal.h
Normal file
@ -0,0 +1,917 @@
|
||||
/*
|
||||
* Copyright (C) 2017 INRIA
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup net_gnrc_gomach
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief GoMacH's internal functions.
|
||||
* @internal
|
||||
* @author Shuguo Zhuo <shuguo.zhuo@inria.fr>
|
||||
*/
|
||||
|
||||
#ifndef GOMACH_INTERNAL_H
|
||||
#define GOMACH_INTERNAL_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "periph/rtt.h"
|
||||
#include "net/gnrc/netif.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Flag to track if the transmission has finished.
|
||||
*/
|
||||
#define GNRC_GOMACH_INFO_TX_FINISHED (0x0008U)
|
||||
|
||||
/**
|
||||
* @brief Flag to track if a packet has been successfully received.
|
||||
*/
|
||||
#define GNRC_GOMACH_INFO_PKT_RECEIVED (0x0010U)
|
||||
|
||||
/**
|
||||
* @brief Flag to track if need to update GoMacH.
|
||||
*/
|
||||
#define GNRC_GOMACH_INTERNAL_INFO_ND_UPDATE (0x0001U)
|
||||
|
||||
/**
|
||||
* @brief Flag to track if need to quit the current cycle in GoMacH.
|
||||
*/
|
||||
#define GNRC_GOMACH_INTERNAL_INFO_QUIT_CYCLE (0x0002U)
|
||||
|
||||
/**
|
||||
* @brief Flag to track if CP period has ended in GoMacH.
|
||||
*/
|
||||
#define GNRC_GOMACH_INTERNAL_INFO_CP_END (0x0004U)
|
||||
|
||||
/**
|
||||
* @brief Flag to track if vTDMA has ended in GoMacH.
|
||||
*/
|
||||
#define GNRC_GOMACH_INTERNAL_INFO_VTDMA_END (0x0008U)
|
||||
|
||||
/**
|
||||
* @brief Flag to track if the node has received unintended preamble.
|
||||
*/
|
||||
#define GNRC_GOMACH_INTERNAL_INFO_UNINTD_PREAMBLE (0x0010U)
|
||||
|
||||
/**
|
||||
* @brief Flag to track if need to quit the current cycle in GoMacH.
|
||||
*/
|
||||
#define GNRC_GOMACH_INTERNAL_INFO_GOT_PREAMBLE (0x0020U)
|
||||
|
||||
/**
|
||||
* @brief Flag to track if node's duty-cycle has started in GoMacH.
|
||||
*/
|
||||
#define GNRC_GOMACH_INTERNAL_INFO_DUTY_CYCLE_START (0x0040U)
|
||||
|
||||
/**
|
||||
* @brief Flag to track if node need to backoff its phase in GoMacH.
|
||||
*/
|
||||
#define GNRC_GOMACH_INTERNAL_INFO_PHASE_BACKOFF (0x0080U)
|
||||
|
||||
/**
|
||||
* @brief Flag to track if beacon transmission fail in GoMacH.
|
||||
*/
|
||||
#define GNRC_GOMACH_INTERNAL_INFO_BEACON_FAIL (0x0200U)
|
||||
|
||||
/**
|
||||
* @brief Flag to track if node's packet buffer is full in GoMacH.
|
||||
*/
|
||||
#define GNRC_GOMACH_INTERNAL_INFO_BUFFER_FULL (0x0400U)
|
||||
|
||||
/**
|
||||
* @brief Flag to track if node has entered a new cycle in GoMacH.
|
||||
*/
|
||||
#define GNRC_GOMACH_INTERNAL_INFO_ENTER_NEW_CYCLE (0x0800U)
|
||||
|
||||
/**
|
||||
* @brief Flag to track if node has got preamble-ACK in GoMacH.
|
||||
*/
|
||||
#define GNRC_GOMACH_INTERNAL_INFO_GOT_PREAMBLEACK (0x1000U)
|
||||
|
||||
/**
|
||||
* @brief Flag to track if node's radio is on public-channel-1.
|
||||
*/
|
||||
#define GNRC_GOMACH_INTERNAL_INFO_ON_PUBCHAN_1 (0x2000U)
|
||||
|
||||
/**
|
||||
* @brief Flag to track if node has reached maximum preamble interval.
|
||||
*/
|
||||
#define GNRC_GOMACH_INTERNAL_INFO_MAX_PREAM_INTERV (0x4000U)
|
||||
|
||||
/**
|
||||
* @brief Flag to track if node has turned on its radio.
|
||||
*/
|
||||
#define GNRC_GOMACH_INTERNAL_INFO_RADIO_IS_ON (0x8000U)
|
||||
|
||||
/**
|
||||
* @brief Set the @ref GNRC_GOMACH_INFO_TX_FINISHED flag of the device.
|
||||
*
|
||||
* @param[in,out] netif the network interface.
|
||||
* @param[in] tx_finish value for GoMacH's
|
||||
* @ref GNRC_GOMACH_INFO_TX_FINISHED flag.
|
||||
*
|
||||
*/
|
||||
static inline void gnrc_gomach_set_tx_finish(gnrc_netif_t *netif, bool tx_finish)
|
||||
{
|
||||
if (tx_finish) {
|
||||
netif->mac.mac_info |= GNRC_GOMACH_INFO_TX_FINISHED;
|
||||
}
|
||||
else {
|
||||
netif->mac.mac_info &= ~GNRC_GOMACH_INFO_TX_FINISHED;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the @ref GNRC_GOMACH_INFO_TX_FINISHED flag of the device.
|
||||
*
|
||||
* @param[in] netif the network interface.
|
||||
*
|
||||
* @return true if TX has finished.
|
||||
* @return false if TX hasn't finished yet.
|
||||
*/
|
||||
static inline bool gnrc_gomach_get_tx_finish(gnrc_netif_t *netif)
|
||||
{
|
||||
return (netif->mac.mac_info & GNRC_GOMACH_INFO_TX_FINISHED);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the @ref GNRC_GOMACH_INFO_PKT_RECEIVED flag of the device.
|
||||
*
|
||||
* @param[in,out] netif the network interface.
|
||||
* @param[in] received value for GoMacH's
|
||||
* @ref GNRC_GOMACH_INFO_PKT_RECEIVED flag.
|
||||
*
|
||||
*/
|
||||
static inline void gnrc_gomach_set_pkt_received(gnrc_netif_t *netif, bool received)
|
||||
{
|
||||
if (received) {
|
||||
netif->mac.mac_info |= GNRC_GOMACH_INFO_PKT_RECEIVED;
|
||||
}
|
||||
else {
|
||||
netif->mac.mac_info &= ~GNRC_GOMACH_INFO_PKT_RECEIVED;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the @ref GNRC_GOMACH_INFO_PKT_RECEIVED flag of the device.
|
||||
*
|
||||
* @param[in] netif the network interface.
|
||||
*
|
||||
* @return true if radio has successfully received a packet.
|
||||
* @return false if radio hasn't received a packet yet.
|
||||
*/
|
||||
static inline bool gnrc_gomach_get_pkt_received(gnrc_netif_t *netif)
|
||||
{
|
||||
return (netif->mac.mac_info & GNRC_GOMACH_INFO_PKT_RECEIVED);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the @ref GNRC_GOMACH_INTERNAL_INFO_QUIT_CYCLE flag of the device.
|
||||
*
|
||||
* @param[in,out] netif the network interface.
|
||||
* @param[in] quit value for GoMacH's
|
||||
* @ref GNRC_GOMACH_INTERNAL_INFO_QUIT_CYCLE flag.
|
||||
*
|
||||
*/
|
||||
static inline void gnrc_gomach_set_quit_cycle(gnrc_netif_t *netif, bool quit)
|
||||
{
|
||||
if (quit) {
|
||||
netif->mac.prot.gomach.gomach_info |= GNRC_GOMACH_INTERNAL_INFO_QUIT_CYCLE;
|
||||
}
|
||||
else {
|
||||
netif->mac.prot.gomach.gomach_info &= ~GNRC_GOMACH_INTERNAL_INFO_QUIT_CYCLE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the @ref GNRC_GOMACH_INTERNAL_INFO_QUIT_CYCLE flag of the device.
|
||||
*
|
||||
* @param[in] netif the network interface.
|
||||
*
|
||||
* @return true if need to quit cycle.
|
||||
* @return false if no need to quit cycle.
|
||||
*/
|
||||
static inline bool gnrc_gomach_get_quit_cycle(gnrc_netif_t *netif)
|
||||
{
|
||||
return (netif->mac.prot.gomach.gomach_info & GNRC_GOMACH_INTERNAL_INFO_QUIT_CYCLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the @ref GNRC_GOMACH_INTERNAL_INFO_GOT_PREAMBLE flag of the device.
|
||||
*
|
||||
* @param[in,out] netif the network interface.
|
||||
* @param[in] got_preamble value for GoMacH's
|
||||
* @ref GNRC_GOMACH_INTERNAL_INFO_GOT_PREAMBLE flag.
|
||||
*
|
||||
*/
|
||||
static inline void gnrc_gomach_set_got_preamble(gnrc_netif_t *netif, bool got_preamble)
|
||||
{
|
||||
if (got_preamble) {
|
||||
netif->mac.prot.gomach.gomach_info |= GNRC_GOMACH_INTERNAL_INFO_GOT_PREAMBLE;
|
||||
}
|
||||
else {
|
||||
netif->mac.prot.gomach.gomach_info &= ~GNRC_GOMACH_INTERNAL_INFO_GOT_PREAMBLE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the @ref GNRC_GOMACH_INTERNAL_INFO_GOT_PREAMBLE flag of the device.
|
||||
*
|
||||
* @param[in] netif the network interface.
|
||||
*
|
||||
* @return true if get preamble packet.
|
||||
* @return false if not get preamble packet yet.
|
||||
*/
|
||||
static inline bool gnrc_gomach_get_got_preamble(gnrc_netif_t *netif)
|
||||
{
|
||||
return (netif->mac.prot.gomach.gomach_info & GNRC_GOMACH_INTERNAL_INFO_GOT_PREAMBLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the @ref GNRC_GOMACH_INTERNAL_INFO_CP_END flag of the device.
|
||||
*
|
||||
* @param[in,out] netif the network interface.
|
||||
* @param[in] cp_end value for GoMacH's
|
||||
* @ref GNRC_GOMACH_INTERNAL_INFO_CP_END flag.
|
||||
*
|
||||
*/
|
||||
static inline void gnrc_gomach_set_cp_end(gnrc_netif_t *netif, bool cp_end)
|
||||
{
|
||||
if (cp_end) {
|
||||
netif->mac.prot.gomach.gomach_info |= GNRC_GOMACH_INTERNAL_INFO_CP_END;
|
||||
}
|
||||
else {
|
||||
netif->mac.prot.gomach.gomach_info &= ~GNRC_GOMACH_INTERNAL_INFO_CP_END;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the @ref GNRC_GOMACH_INTERNAL_INFO_CP_END flag of the device.
|
||||
*
|
||||
* @param[in] netif the network interface.
|
||||
*
|
||||
* @return true if cp has ended.
|
||||
* @return false if cp hasn't ended yet.
|
||||
*/
|
||||
static inline bool gnrc_gomach_get_cp_end(gnrc_netif_t *netif)
|
||||
{
|
||||
return (netif->mac.prot.gomach.gomach_info & GNRC_GOMACH_INTERNAL_INFO_CP_END);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the @ref GNRC_GOMACH_INTERNAL_INFO_VTDMA_END flag of the device.
|
||||
*
|
||||
* @param[in,out] netif the network interface.
|
||||
* @param[in] vtdma_end value for GoMacH's
|
||||
* @ref GNRC_GOMACH_INTERNAL_INFO_VTDMA_END flag.
|
||||
*
|
||||
*/
|
||||
static inline void gnrc_gomach_set_vTDMA_end(gnrc_netif_t *netif, bool vtdma_end)
|
||||
{
|
||||
if (vtdma_end) {
|
||||
netif->mac.prot.gomach.gomach_info |= GNRC_GOMACH_INTERNAL_INFO_VTDMA_END;
|
||||
}
|
||||
else {
|
||||
netif->mac.prot.gomach.gomach_info &= ~GNRC_GOMACH_INTERNAL_INFO_VTDMA_END;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the @ref GNRC_GOMACH_INTERNAL_INFO_VTDMA_END flag of the device.
|
||||
*
|
||||
* @param[in] netif the network interface.
|
||||
*
|
||||
* @return true if vTDMA has ended.
|
||||
* @return false if vTDMA hasn't ended yet.
|
||||
*/
|
||||
static inline bool gnrc_gomach_get_vTDMA_end(gnrc_netif_t *netif)
|
||||
{
|
||||
return (netif->mac.prot.gomach.gomach_info & GNRC_GOMACH_INTERNAL_INFO_VTDMA_END);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the @ref GNRC_GOMACH_INTERNAL_INFO_UNINTD_PREAMBLE flag of the device.
|
||||
*
|
||||
* @param[in,out] netif the network interface.
|
||||
* @param[in] uintd_preamble value for GoMacH's
|
||||
* @ref GNRC_GOMACH_INTERNAL_INFO_UNINTD_PREAMBLE flag.
|
||||
*
|
||||
*/
|
||||
static inline void gnrc_gomach_set_unintd_preamble(gnrc_netif_t *netif, bool uintd_preamble)
|
||||
{
|
||||
if (uintd_preamble) {
|
||||
netif->mac.prot.gomach.gomach_info |= GNRC_GOMACH_INTERNAL_INFO_UNINTD_PREAMBLE;
|
||||
}
|
||||
else {
|
||||
netif->mac.prot.gomach.gomach_info &= ~GNRC_GOMACH_INTERNAL_INFO_UNINTD_PREAMBLE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the @ref GNRC_GOMACH_INTERNAL_INFO_UNINTD_PREAMBLE flag of the device.
|
||||
*
|
||||
* @param[in] netif the network interface.
|
||||
*
|
||||
* @return true if has received unintended-preamble.
|
||||
* @return false if hasn't received unintended-preamble yet.
|
||||
*/
|
||||
static inline bool gnrc_gomach_get_unintd_preamble(gnrc_netif_t *netif)
|
||||
{
|
||||
return (netif->mac.prot.gomach.gomach_info & GNRC_GOMACH_INTERNAL_INFO_UNINTD_PREAMBLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the @ref GNRC_GOMACH_INTERNAL_INFO_ND_UPDATE flag of the device.
|
||||
*
|
||||
* @param[in,out] netif the network interface.
|
||||
* @param[in] update value for GoMacH's
|
||||
* @ref GNRC_GOMACH_INTERNAL_INFO_ND_UPDATE flag.
|
||||
*
|
||||
*/
|
||||
static inline void gnrc_gomach_set_update(gnrc_netif_t *netif, bool update)
|
||||
{
|
||||
if (update) {
|
||||
netif->mac.prot.gomach.gomach_info |= GNRC_GOMACH_INTERNAL_INFO_ND_UPDATE;
|
||||
}
|
||||
else {
|
||||
netif->mac.prot.gomach.gomach_info &= ~GNRC_GOMACH_INTERNAL_INFO_ND_UPDATE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the @ref GNRC_GOMACH_INTERNAL_INFO_ND_UPDATE flag of the device.
|
||||
*
|
||||
* @param[in] netif the network interface.
|
||||
*
|
||||
* @return true if need update GoMacH.
|
||||
* @return false if no need to update GoMacH.
|
||||
*/
|
||||
static inline bool gnrc_gomach_get_update(gnrc_netif_t *netif)
|
||||
{
|
||||
return (netif->mac.prot.gomach.gomach_info & GNRC_GOMACH_INTERNAL_INFO_ND_UPDATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the @ref GNRC_GOMACH_INTERNAL_INFO_DUTY_CYCLE_START flag of the device.
|
||||
*
|
||||
* @param[in,out] netif the network interface.
|
||||
* @param[in] start value for GoMacH's
|
||||
* @ref GNRC_GOMACH_INTERNAL_INFO_DUTY_CYCLE_START flag.
|
||||
*
|
||||
*/
|
||||
static inline void gnrc_gomach_set_duty_cycle_start(gnrc_netif_t *netif, bool start)
|
||||
{
|
||||
if (start) {
|
||||
netif->mac.prot.gomach.gomach_info |= GNRC_GOMACH_INTERNAL_INFO_DUTY_CYCLE_START;
|
||||
}
|
||||
else {
|
||||
netif->mac.prot.gomach.gomach_info &= ~GNRC_GOMACH_INTERNAL_INFO_DUTY_CYCLE_START;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the @ref GNRC_GOMACH_INTERNAL_INFO_DUTY_CYCLE_START flag of the device.
|
||||
*
|
||||
* @param[in] netif the network interface.
|
||||
*
|
||||
* @return true if duty-cycle has started.
|
||||
* @return false if duty-cycle hasn't started yet.
|
||||
*/
|
||||
static inline bool gnrc_gomach_get_duty_cycle_start(gnrc_netif_t *netif)
|
||||
{
|
||||
return (netif->mac.prot.gomach.gomach_info & GNRC_GOMACH_INTERNAL_INFO_DUTY_CYCLE_START);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the @ref GNRC_GOMACH_INTERNAL_INFO_PHASE_BACKOFF flag of the device.
|
||||
*
|
||||
* @param[in,out] netif the network interface.
|
||||
* @param[in] backoff value for GoMacH's
|
||||
* @ref GNRC_GOMACH_INTERNAL_INFO_PHASE_BACKOFF flag.
|
||||
*
|
||||
*/
|
||||
static inline void gnrc_gomach_set_phase_backoff(gnrc_netif_t *netif, bool backoff)
|
||||
{
|
||||
if (backoff) {
|
||||
netif->mac.prot.gomach.gomach_info |= GNRC_GOMACH_INTERNAL_INFO_PHASE_BACKOFF;
|
||||
}
|
||||
else {
|
||||
netif->mac.prot.gomach.gomach_info &= ~GNRC_GOMACH_INTERNAL_INFO_PHASE_BACKOFF;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the @ref GNRC_GOMACH_INTERNAL_INFO_PHASE_BACKOFF flag of the device.
|
||||
*
|
||||
* @param[in] netif the network interface.
|
||||
*
|
||||
* @return true if need to run phase backoff.
|
||||
* @return false if no need to run phase backoff.
|
||||
*/
|
||||
static inline bool gnrc_gomach_get_phase_backoff(gnrc_netif_t *netif)
|
||||
{
|
||||
return (netif->mac.prot.gomach.gomach_info & GNRC_GOMACH_INTERNAL_INFO_PHASE_BACKOFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the @ref GNRC_GOMACH_INTERNAL_INFO_BEACON_FAIL flag of the device.
|
||||
*
|
||||
* @param[in,out] netif the network interface.
|
||||
* @param[in] fail value for GoMacH's
|
||||
* @ref GNRC_GOMACH_INTERNAL_INFO_BEACON_FAIL flag.
|
||||
*
|
||||
*/
|
||||
static inline void gnrc_gomach_set_beacon_fail(gnrc_netif_t *netif, bool fail)
|
||||
{
|
||||
if (fail) {
|
||||
netif->mac.prot.gomach.gomach_info |= GNRC_GOMACH_INTERNAL_INFO_BEACON_FAIL;
|
||||
}
|
||||
else {
|
||||
netif->mac.prot.gomach.gomach_info &= ~GNRC_GOMACH_INTERNAL_INFO_BEACON_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the @ref GNRC_GOMACH_INTERNAL_INFO_BEACON_FAIL flag of the device.
|
||||
*
|
||||
* @param[in] netif the network interface.
|
||||
*
|
||||
* @return true if send beacon fail.
|
||||
* @return false upon beacon transmission success.
|
||||
*/
|
||||
static inline bool gnrc_gomach_get_beacon_fail(gnrc_netif_t *netif)
|
||||
{
|
||||
return (netif->mac.prot.gomach.gomach_info & GNRC_GOMACH_INTERNAL_INFO_BEACON_FAIL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the @ref GNRC_GOMACH_INTERNAL_INFO_BUFFER_FULL flag of the device.
|
||||
*
|
||||
* @param[in,out] netif the network interface.
|
||||
* @param[in] full value for GoMacH's
|
||||
* @ref GNRC_GOMACH_INTERNAL_INFO_BUFFER_FULL flag.
|
||||
*
|
||||
*/
|
||||
static inline void gnrc_gomach_set_buffer_full(gnrc_netif_t *netif, bool full)
|
||||
{
|
||||
if (full) {
|
||||
netif->mac.prot.gomach.gomach_info |= GNRC_GOMACH_INTERNAL_INFO_BUFFER_FULL;
|
||||
}
|
||||
else {
|
||||
netif->mac.prot.gomach.gomach_info &= ~GNRC_GOMACH_INTERNAL_INFO_BUFFER_FULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the @ref GNRC_GOMACH_INTERNAL_INFO_BUFFER_FULL flag of the device.
|
||||
*
|
||||
* @param[in] netif the network interface.
|
||||
*
|
||||
* @return true if node's packet buffer is full.
|
||||
* @return false if node's packet buffer is not full.
|
||||
*/
|
||||
static inline bool gnrc_gomach_get_buffer_full(gnrc_netif_t *netif)
|
||||
{
|
||||
return (netif->mac.prot.gomach.gomach_info & GNRC_GOMACH_INTERNAL_INFO_BUFFER_FULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the @ref GNRC_GOMACH_INTERNAL_INFO_ENTER_NEW_CYCLE flag of the device.
|
||||
*
|
||||
* @param[in,out] netif the network interface.
|
||||
* @param[in] enter value for GoMacH's
|
||||
* @ref GNRC_GOMACH_INTERNAL_INFO_ENTER_NEW_CYCLE flag.
|
||||
*
|
||||
*/
|
||||
static inline void gnrc_gomach_set_enter_new_cycle(gnrc_netif_t *netif, bool enter)
|
||||
{
|
||||
if (enter) {
|
||||
netif->mac.prot.gomach.gomach_info |= GNRC_GOMACH_INTERNAL_INFO_ENTER_NEW_CYCLE;
|
||||
}
|
||||
else {
|
||||
netif->mac.prot.gomach.gomach_info &= ~GNRC_GOMACH_INTERNAL_INFO_ENTER_NEW_CYCLE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the @ref GNRC_GOMACH_INTERNAL_INFO_ENTER_NEW_CYCLE flag of the device.
|
||||
*
|
||||
* @param[in] netif the network interface.
|
||||
*
|
||||
* @return true if node has entered a new cycle.
|
||||
* @return false if node hasn't entered a new cycle yet.
|
||||
*/
|
||||
static inline bool gnrc_gomach_get_enter_new_cycle(gnrc_netif_t *netif)
|
||||
{
|
||||
return (netif->mac.prot.gomach.gomach_info & GNRC_GOMACH_INTERNAL_INFO_ENTER_NEW_CYCLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the @ref GNRC_GOMACH_INTERNAL_INFO_GOT_PREAMBLEACK flag of the device.
|
||||
*
|
||||
* @param[in,out] netif the network interface.
|
||||
* @param[in] got value for GoMacH's
|
||||
* @ref GNRC_GOMACH_INTERNAL_INFO_GOT_PREAMBLEACK flag.
|
||||
*
|
||||
*/
|
||||
static inline void gnrc_gomach_set_got_preamble_ack(gnrc_netif_t *netif, bool got)
|
||||
{
|
||||
if (got) {
|
||||
netif->mac.prot.gomach.gomach_info |= GNRC_GOMACH_INTERNAL_INFO_GOT_PREAMBLEACK;
|
||||
}
|
||||
else {
|
||||
netif->mac.prot.gomach.gomach_info &= ~GNRC_GOMACH_INTERNAL_INFO_GOT_PREAMBLEACK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the @ref GNRC_GOMACH_INTERNAL_INFO_GOT_PREAMBLEACK flag of the device.
|
||||
*
|
||||
* @param[in] netif the network interface.
|
||||
*
|
||||
* @return true if node has got preamble-ACK.
|
||||
* @return false if node hasn't got preamble-ACK yet.
|
||||
*/
|
||||
static inline bool gnrc_gomach_get_got_preamble_ack(gnrc_netif_t *netif)
|
||||
{
|
||||
return (netif->mac.prot.gomach.gomach_info & GNRC_GOMACH_INTERNAL_INFO_GOT_PREAMBLEACK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the @ref GNRC_GOMACH_INTERNAL_INFO_ON_PUBCHAN_1 flag of the device.
|
||||
*
|
||||
* @param[in,out] netif the network interface.
|
||||
* @param[in] on_pubchan_1 value for GoMacH's
|
||||
* @ref GNRC_GOMACH_INTERNAL_INFO_ON_PUBCHAN_1 flag.
|
||||
*
|
||||
*/
|
||||
static inline void gnrc_gomach_set_on_pubchan_1(gnrc_netif_t *netif, bool on_pubchan_1)
|
||||
{
|
||||
if (on_pubchan_1) {
|
||||
netif->mac.prot.gomach.gomach_info |= GNRC_GOMACH_INTERNAL_INFO_ON_PUBCHAN_1;
|
||||
}
|
||||
else {
|
||||
netif->mac.prot.gomach.gomach_info &= ~GNRC_GOMACH_INTERNAL_INFO_ON_PUBCHAN_1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the @ref GNRC_GOMACH_INTERNAL_INFO_ON_PUBCHAN_1 flag of the device.
|
||||
*
|
||||
* @param[in] netif the network interface.
|
||||
*
|
||||
* @return true if node is on public channel 1.
|
||||
* @return false if node is not on public channel 1.
|
||||
*/
|
||||
static inline bool gnrc_gomach_get_on_pubchan_1(gnrc_netif_t *netif)
|
||||
{
|
||||
return (netif->mac.prot.gomach.gomach_info & GNRC_GOMACH_INTERNAL_INFO_ON_PUBCHAN_1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the @ref GNRC_GOMACH_INTERNAL_INFO_MAX_PREAM_INTERV flag of the device.
|
||||
*
|
||||
* @param[in,out] netif the network interface.
|
||||
* @param[in] max value for GoMacH's @ref
|
||||
* GNRC_GOMACH_INTERNAL_INFO_MAX_PREAM_INTERV flag.
|
||||
*
|
||||
*/
|
||||
static inline void gnrc_gomach_set_max_pream_interv(gnrc_netif_t *netif, bool max)
|
||||
{
|
||||
if (max) {
|
||||
netif->mac.prot.gomach.gomach_info |= GNRC_GOMACH_INTERNAL_INFO_MAX_PREAM_INTERV;
|
||||
}
|
||||
else {
|
||||
netif->mac.prot.gomach.gomach_info &= ~GNRC_GOMACH_INTERNAL_INFO_MAX_PREAM_INTERV;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the @ref GNRC_GOMACH_INTERNAL_INFO_MAX_PREAM_INTERV flag of the device.
|
||||
*
|
||||
* @param[in] netif the network interface.
|
||||
*
|
||||
* @return true if node has reached maximum preamble interval.
|
||||
* @return false if node hasn't reached maximum preamble interval yet.
|
||||
*/
|
||||
static inline bool gnrc_gomach_get_max_pream_interv(gnrc_netif_t *netif)
|
||||
{
|
||||
return (netif->mac.prot.gomach.gomach_info & GNRC_GOMACH_INTERNAL_INFO_MAX_PREAM_INTERV);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get device's current phase.
|
||||
*
|
||||
* @param[in] netif the network interface.
|
||||
*
|
||||
* @return device's current phase.
|
||||
*/
|
||||
uint64_t gnrc_gomach_phase_now(gnrc_netif_t *netif);
|
||||
|
||||
/**
|
||||
* @brief Shortcut to set the state of netdev
|
||||
*
|
||||
* @param[in] netif ptr to the network interface
|
||||
* @param[in] devstate new state for netdev
|
||||
*/
|
||||
void gnrc_gomach_set_netdev_state(gnrc_netif_t *netif, netopt_state_t devstate);
|
||||
|
||||
/**
|
||||
* @brief Set the auto-ACK parameter of the device.
|
||||
*
|
||||
* @param[in,out] netif the network interface.
|
||||
* @param[in] autoack value for the auto-ACK parameter.
|
||||
*
|
||||
*/
|
||||
static inline void gnrc_gomach_set_autoack(gnrc_netif_t *netif, netopt_enable_t autoack)
|
||||
{
|
||||
assert(netif != NULL);
|
||||
|
||||
netif->dev->driver->set(netif->dev,
|
||||
NETOPT_AUTOACK,
|
||||
&autoack,
|
||||
sizeof(autoack));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the ACK-require parameter of the device.
|
||||
*
|
||||
* @param[in,out] netif the network interface.
|
||||
* @param[in] ack_req value for the ACK-require parameter.
|
||||
*
|
||||
*/
|
||||
static inline void gnrc_gomach_set_ack_req(gnrc_netif_t *netif, netopt_enable_t ack_req)
|
||||
{
|
||||
assert(netif != NULL);
|
||||
|
||||
netif->dev->driver->set(netif->dev,
|
||||
NETOPT_ACK_REQ,
|
||||
&ack_req,
|
||||
sizeof(ack_req));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Shortcut to get the state of netdev.
|
||||
*
|
||||
* @param[in] netif the network interface.
|
||||
*
|
||||
* @return state of netdev upon success.
|
||||
* @return -ENOSYS, upon failure.
|
||||
*/
|
||||
static inline netopt_state_t gnrc_gomach_get_netdev_state(gnrc_netif_t *netif)
|
||||
{
|
||||
assert(netif != NULL);
|
||||
|
||||
netopt_state_t state;
|
||||
|
||||
if (0 < netif->dev->driver->get(netif->dev,
|
||||
NETOPT_STATE,
|
||||
&state,
|
||||
sizeof(state))) {
|
||||
return state;
|
||||
}
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Turn the radio to a specific channel.
|
||||
*
|
||||
* @param[in,out] netif the network interface.
|
||||
* @param[in] channel_num targeted channel number to turn to.
|
||||
*
|
||||
*/
|
||||
static inline void gnrc_gomach_turn_channel(gnrc_netif_t *netif, uint16_t channel_num)
|
||||
{
|
||||
assert(netif != NULL);
|
||||
|
||||
netif->dev->driver->set(netif->dev,
|
||||
NETOPT_CHANNEL,
|
||||
&channel_num,
|
||||
sizeof(channel_num));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief send a @ref net_gnrc_pkt "packet" over the network interface in GoMacH
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @pre `netif != NULL && pkt != NULL`
|
||||
*
|
||||
* @note The function re-formats the content of @p pkt to a format expected
|
||||
* by the netdev_driver_t::send() method of gnrc_netif_t::dev and
|
||||
* releases the packet before returning (so no additional release
|
||||
* should be required after calling this method).
|
||||
*
|
||||
* @param[in] netif The network interface.
|
||||
* @param[in] pkt A packet to send.
|
||||
*
|
||||
* @return The number of bytes actually sent on success
|
||||
* @return -EBADMSG, if the @ref net_gnrc_netif_hdr in @p pkt is missing
|
||||
* or is in an unexpected format.
|
||||
* @return -ENOTSUP, if sending @p pkt in the given format isn't supported
|
||||
* (e.g. empty payload with Ethernet).
|
||||
* @return Any negative error code reported by gnrc_netif_t::dev.
|
||||
*/
|
||||
int _gnrc_gomach_transmit(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt);
|
||||
|
||||
/**
|
||||
* @brief Check if the received packet is a duplicate packet.
|
||||
*
|
||||
* @param[in] netif the network interface.
|
||||
* @param[in] pa_info ptr to received packet's parsed information.
|
||||
*
|
||||
* @return true if the received packet is a duplicate packet.
|
||||
* @return false if the received packet is not a duplicate packet.
|
||||
*/
|
||||
bool gnrc_gomach_check_duplicate(gnrc_netif_t *netif, gnrc_gomach_packet_info_t *pa_info);
|
||||
|
||||
/**
|
||||
* @brief Send a pktsnip in GoMacH.
|
||||
*
|
||||
* @param[in] netif the network interface.
|
||||
* @param[in] pkt ptr to the packet for sending.
|
||||
* @param[in] csma_enable value of csma-enable parameter.
|
||||
*
|
||||
* @return >0 upon sending success.
|
||||
* @return 0< upon sending failure.
|
||||
*/
|
||||
int gnrc_gomach_send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt, netopt_enable_t csma_enable);
|
||||
|
||||
/**
|
||||
* @brief Reply a preamble-ACK packet in GoMacH.
|
||||
*
|
||||
* @param[in] netif the network interface.
|
||||
* @param[in] info ptr to the info of the preamble packet.
|
||||
*
|
||||
* @return >0 upon sending success.
|
||||
* @return 0< upon sending failure.
|
||||
*/
|
||||
int gnrc_gomach_send_preamble_ack(gnrc_netif_t *netif, gnrc_gomach_packet_info_t *info);
|
||||
|
||||
/**
|
||||
* @brief Broadcast a beacon packet in GoMacH.
|
||||
*
|
||||
* @param[in] netif the network interface.
|
||||
*
|
||||
* @return >0 upon sending success.
|
||||
* @return 0< upon sending failure.
|
||||
*/
|
||||
int gnrc_gomach_send_beacon(gnrc_netif_t *netif);
|
||||
|
||||
/**
|
||||
* @brief Store the received packet to the dispatch buffer.
|
||||
*
|
||||
* @param[in,out] buffer RX dispatch packet buffer
|
||||
* @param[in] pkt received packet
|
||||
*
|
||||
* @return 0 if correctly stored
|
||||
* @return <0 on error
|
||||
*/
|
||||
int gnrc_gomach_dispatch_defer(gnrc_pktsnip_t * buffer[], gnrc_pktsnip_t * pkt);
|
||||
|
||||
/**
|
||||
* @brief Update the queue-length indicator of the packet sender.
|
||||
*
|
||||
* @param[in,out] netif the network interface.
|
||||
* @param[in] pkt received packet
|
||||
* @param[in] pa_info ptr to the info of the received packet.
|
||||
*
|
||||
*/
|
||||
void gnrc_gomach_indicator_update(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt,
|
||||
gnrc_gomach_packet_info_t *pa_info);
|
||||
|
||||
/**
|
||||
* @brief Process packets received during the CP (wake-up) period of GoMacH.
|
||||
*
|
||||
* @param[in,out] netif the network interface.
|
||||
*
|
||||
*/
|
||||
void gnrc_gomach_cp_packet_process(gnrc_netif_t *netif);
|
||||
|
||||
/**
|
||||
* @brief Choose a sub-channel for a device running GoMacH.
|
||||
*
|
||||
* @param[in,out] netif the network interface.
|
||||
*
|
||||
*/
|
||||
void gnrc_gomach_init_choose_subchannel(gnrc_netif_t *netif);
|
||||
|
||||
/**
|
||||
* @brief Broadcast the chosen sub-channel sequence to the device's neighbors.
|
||||
*
|
||||
* @param[in] netif the network interface.
|
||||
* @param[in] use_csma value of csma-enable parameter.
|
||||
*
|
||||
* @return >0 upon sending success.
|
||||
* @return 0< upon sending failure.
|
||||
*/
|
||||
int gnrc_gomach_bcast_subchann_seq(gnrc_netif_t *netif, netopt_enable_t use_csma);
|
||||
|
||||
/**
|
||||
* @brief Send a preamble packet to the targeted neighbor.
|
||||
*
|
||||
* @param[in] netif the network interface.
|
||||
* @param[in] csma_enable value of csma-enable parameter.
|
||||
*
|
||||
* @return >0 upon sending success.
|
||||
* @return 0< upon sending failure.
|
||||
*/
|
||||
int gnrc_gomach_send_preamble(gnrc_netif_t *netif, netopt_enable_t csma_enable);
|
||||
|
||||
/**
|
||||
* @brief Process the received preamble-ACK packet to get phase-locked with the sender.
|
||||
*
|
||||
* @param[in,out] netif the network interface.
|
||||
* @param[in] pkt ptr to the received preamble-ACK.
|
||||
*
|
||||
*/
|
||||
void gnrc_gomach_process_preamble_ack(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt);
|
||||
|
||||
/**
|
||||
* @brief Process the received packets to when waiting for the preamble-ACK packet.
|
||||
*
|
||||
* @param[in,out] netif the network interface.
|
||||
*
|
||||
*/
|
||||
void gnrc_gomach_process_pkt_in_wait_preamble_ack(gnrc_netif_t *netif);
|
||||
|
||||
/**
|
||||
* @brief Send a data packet to the targeted neighbor.
|
||||
*
|
||||
* @param[in,out] netif the network interface.
|
||||
* @param[in] csma_enable value of csma-enable parameter.
|
||||
*
|
||||
* @return >0 upon sending success.
|
||||
* @return 0< upon sending failure.
|
||||
*/
|
||||
int gnrc_gomach_send_data(gnrc_netif_t *netif, netopt_enable_t csma_enable);
|
||||
|
||||
/**
|
||||
* @brief Find a neighbor that is next to send packet to.
|
||||
*
|
||||
* @param[in,out] netif the network interface.
|
||||
*
|
||||
* @return true, if found next TX neighbor.
|
||||
* @return false, if not found next TX neighbor.
|
||||
*
|
||||
*/
|
||||
bool gnrc_gomach_find_next_tx_neighbor(gnrc_netif_t *netif);
|
||||
|
||||
/**
|
||||
* @brief Process the received beacon packet.
|
||||
*
|
||||
* @param[in,out] netif the network interface.
|
||||
* @param[in] pkt ptr to the received beacon.
|
||||
*
|
||||
*/
|
||||
void gnrc_gomach_beacon_process(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt);
|
||||
|
||||
/**
|
||||
* @brief Process the received packets when waiting for the beacon during
|
||||
* t2k procedure in GoMacH.
|
||||
*
|
||||
* @param[in,out] netif the network interface.
|
||||
*
|
||||
*/
|
||||
void gnrc_gomach_packet_process_in_wait_beacon(gnrc_netif_t *netif);
|
||||
|
||||
/**
|
||||
* @brief Process the received packets in the vTDMA period in GoMacH.
|
||||
*
|
||||
* @param[in,out] netif the network interface.
|
||||
*
|
||||
*/
|
||||
void gnrc_gomach_packet_process_in_vtdma(gnrc_netif_t *netif);
|
||||
|
||||
/**
|
||||
* @brief Update the TX neighbors' phases in GoMacH.
|
||||
*
|
||||
* @param[in,out] netif the network interface.
|
||||
*
|
||||
*/
|
||||
void gnrc_gomach_update_neighbor_phase(gnrc_netif_t *netif);
|
||||
|
||||
/**
|
||||
* @brief Update the TX neighbors' public channel phase in GoMacH.
|
||||
*
|
||||
* @param[in,out] netif the network interface.
|
||||
*
|
||||
*/
|
||||
void gnrc_gomach_update_neighbor_pubchan(gnrc_netif_t *netif);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GOMACH_INTERNAL_H */
|
||||
/** @} */
|
||||
122
sys/net/gnrc/link_layer/gomach/timeout.c
Normal file
122
sys/net/gnrc/link_layer/gomach/timeout.c
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (C) 2017 INRIA
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup net_gnrc_gomach
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of GoMacH's timeout module.
|
||||
*
|
||||
* @author Shuguo Zhuo <shuguo.zhuo@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "xtimer.h"
|
||||
#include "net/gnrc/gomach/gomach.h"
|
||||
#include "net/gnrc/gomach/timeout.h"
|
||||
#include "net/gnrc/gomach/types.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
/* Return index >= 0 if found, -ENONENT if not found. */
|
||||
static int _gomach_find_timeout(gnrc_gomach_t *gomach, gnrc_gomach_timeout_type_t type)
|
||||
{
|
||||
assert(gomach);
|
||||
|
||||
for (unsigned i = 0; i < GNRC_GOMACH_TIMEOUT_COUNT; i++) {
|
||||
if (gomach->timeouts[i].type == type) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
inline bool gnrc_gomach_timeout_is_running(gnrc_netif_t *netif,
|
||||
gnrc_gomach_timeout_type_t type)
|
||||
{
|
||||
assert(netif);
|
||||
return (_gomach_find_timeout(&netif->mac.prot.gomach, type) >= 0);
|
||||
}
|
||||
|
||||
bool gnrc_gomach_timeout_is_expired(gnrc_netif_t *netif, gnrc_gomach_timeout_type_t type)
|
||||
{
|
||||
assert(netif);
|
||||
|
||||
int index = _gomach_find_timeout(&netif->mac.prot.gomach, type);
|
||||
if (index >= 0) {
|
||||
if (netif->mac.prot.gomach.timeouts[index].expired) {
|
||||
xtimer_remove(&(netif->mac.prot.gomach.timeouts[index].timer));
|
||||
netif->mac.prot.gomach.timeouts[index].type = GNRC_GOMACH_TIMEOUT_DISABLED;
|
||||
}
|
||||
return netif->mac.prot.gomach.timeouts[index].expired;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
gnrc_gomach_timeout_t *_gomach_acquire_timeout(gnrc_netif_t *netif,
|
||||
gnrc_gomach_timeout_type_t type)
|
||||
{
|
||||
assert(netif);
|
||||
|
||||
if (gnrc_gomach_timeout_is_running(netif, type)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < GNRC_GOMACH_TIMEOUT_COUNT; i++) {
|
||||
if (netif->mac.prot.gomach.timeouts[i].type == GNRC_GOMACH_TIMEOUT_DISABLED) {
|
||||
netif->mac.prot.gomach.timeouts[i].type = type;
|
||||
return &netif->mac.prot.gomach.timeouts[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void gnrc_gomach_clear_timeout(gnrc_netif_t *netif, gnrc_gomach_timeout_type_t type)
|
||||
{
|
||||
assert(netif);
|
||||
|
||||
int index = _gomach_find_timeout(&netif->mac.prot.gomach, type);
|
||||
if (index >= 0) {
|
||||
xtimer_remove(&(netif->mac.prot.gomach.timeouts[index].timer));
|
||||
netif->mac.prot.gomach.timeouts[index].type = GNRC_GOMACH_TIMEOUT_DISABLED;
|
||||
netif->mac.prot.gomach.timeouts[index].expired = false;
|
||||
}
|
||||
}
|
||||
|
||||
void gnrc_gomach_set_timeout(gnrc_netif_t *netif,
|
||||
gnrc_gomach_timeout_type_t type,
|
||||
uint32_t offset)
|
||||
{
|
||||
assert(netif);
|
||||
|
||||
gnrc_gomach_timeout_t *timeout;
|
||||
if ((timeout = _gomach_acquire_timeout(netif, type))) {
|
||||
timeout->expired = false;
|
||||
timeout->msg.type = GNRC_GOMACH_EVENT_TIMEOUT_TYPE;
|
||||
timeout->msg.content.ptr = (void *) timeout;
|
||||
xtimer_set_msg(&(timeout->timer), offset,
|
||||
&(timeout->msg), netif->pid);
|
||||
}
|
||||
else {
|
||||
DEBUG("[GoMacH]: Cannot set timeout, too many concurrent timeouts\n");
|
||||
}
|
||||
}
|
||||
|
||||
void gnrc_gomach_reset_timeouts(gnrc_netif_t *netif)
|
||||
{
|
||||
assert(netif);
|
||||
|
||||
for (unsigned i = 0; i < GNRC_GOMACH_TIMEOUT_COUNT; i++) {
|
||||
if (netif->mac.prot.gomach.timeouts[i].type != GNRC_GOMACH_TIMEOUT_DISABLED) {
|
||||
xtimer_remove(&(netif->mac.prot.gomach.timeouts[i].timer));
|
||||
netif->mac.prot.gomach.timeouts[i].type = GNRC_GOMACH_TIMEOUT_DISABLED;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -227,10 +227,10 @@ static inline bool gnrc_lwmac_get_quit_rx(gnrc_netif_t *netif)
|
||||
static inline void gnrc_lwmac_set_dutycycle_active(gnrc_netif_t *netif, bool active)
|
||||
{
|
||||
if (active) {
|
||||
netif->mac.lwmac.lwmac_info |= GNRC_LWMAC_DUTYCYCLE_ACTIVE;
|
||||
netif->mac.prot.lwmac.lwmac_info |= GNRC_LWMAC_DUTYCYCLE_ACTIVE;
|
||||
}
|
||||
else {
|
||||
netif->mac.lwmac.lwmac_info &= ~GNRC_LWMAC_DUTYCYCLE_ACTIVE;
|
||||
netif->mac.prot.lwmac.lwmac_info &= ~GNRC_LWMAC_DUTYCYCLE_ACTIVE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -244,7 +244,7 @@ static inline void gnrc_lwmac_set_dutycycle_active(gnrc_netif_t *netif, bool act
|
||||
*/
|
||||
static inline bool gnrc_lwmac_get_dutycycle_active(gnrc_netif_t *netif)
|
||||
{
|
||||
return (netif->mac.lwmac.lwmac_info & GNRC_LWMAC_DUTYCYCLE_ACTIVE);
|
||||
return (netif->mac.prot.lwmac.lwmac_info & GNRC_LWMAC_DUTYCYCLE_ACTIVE);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -257,10 +257,10 @@ static inline bool gnrc_lwmac_get_dutycycle_active(gnrc_netif_t *netif)
|
||||
static inline void gnrc_lwmac_set_reschedule(gnrc_netif_t *netif, bool reschedule)
|
||||
{
|
||||
if (reschedule) {
|
||||
netif->mac.lwmac.lwmac_info |= GNRC_LWMAC_NEEDS_RESCHEDULE;
|
||||
netif->mac.prot.lwmac.lwmac_info |= GNRC_LWMAC_NEEDS_RESCHEDULE;
|
||||
}
|
||||
else {
|
||||
netif->mac.lwmac.lwmac_info &= ~GNRC_LWMAC_NEEDS_RESCHEDULE;
|
||||
netif->mac.prot.lwmac.lwmac_info &= ~GNRC_LWMAC_NEEDS_RESCHEDULE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -274,7 +274,7 @@ static inline void gnrc_lwmac_set_reschedule(gnrc_netif_t *netif, bool reschedul
|
||||
*/
|
||||
static inline bool gnrc_lwmac_get_reschedule(gnrc_netif_t *netif)
|
||||
{
|
||||
return (netif->mac.lwmac.lwmac_info & GNRC_LWMAC_NEEDS_RESCHEDULE);
|
||||
return (netif->mac.prot.lwmac.lwmac_info & GNRC_LWMAC_NEEDS_RESCHEDULE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -245,7 +245,7 @@ inline void lwmac_schedule_update(gnrc_netif_t *netif)
|
||||
|
||||
void lwmac_set_state(gnrc_netif_t *netif, gnrc_lwmac_state_t newstate)
|
||||
{
|
||||
gnrc_lwmac_state_t oldstate = netif->mac.lwmac.state;
|
||||
gnrc_lwmac_state_t oldstate = netif->mac.prot.lwmac.state;
|
||||
|
||||
if (newstate == oldstate) {
|
||||
return;
|
||||
@ -257,7 +257,7 @@ void lwmac_set_state(gnrc_netif_t *netif, gnrc_lwmac_state_t newstate)
|
||||
}
|
||||
|
||||
/* Already change state, but might be reverted to oldstate when needed */
|
||||
netif->mac.lwmac.state = newstate;
|
||||
netif->mac.prot.lwmac.state = newstate;
|
||||
|
||||
/* Actions when leaving old state */
|
||||
switch (oldstate) {
|
||||
@ -269,8 +269,8 @@ void lwmac_set_state(gnrc_netif_t *netif, gnrc_lwmac_state_t newstate)
|
||||
/* Output duty-cycle ratio */
|
||||
uint64_t duty;
|
||||
duty = (uint64_t) rtt_get_counter();
|
||||
duty = ((uint64_t) netif->mac.lwmac.awake_duration_sum_ticks) * 100 /
|
||||
(duty - (uint64_t)netif->mac.lwmac.system_start_time_ticks);
|
||||
duty = ((uint64_t) netif->mac.prot.lwmac.awake_duration_sum_ticks) * 100 /
|
||||
(duty - (uint64_t)netif->mac.prot.lwmac.system_start_time_ticks);
|
||||
printf("[LWMAC]: achieved duty-cycle: %lu %% \n", (uint32_t)duty);
|
||||
#endif
|
||||
break;
|
||||
@ -305,8 +305,8 @@ void lwmac_set_state(gnrc_netif_t *netif, gnrc_lwmac_state_t newstate)
|
||||
RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US -
|
||||
(3 * GNRC_LWMAC_WAKEUP_DURATION_US / 2)));
|
||||
LOG_WARNING("WARNING: [LWMAC] phase backoffed: %lu us\n", RTT_TICKS_TO_US(alarm));
|
||||
netif->mac.lwmac.last_wakeup = netif->mac.lwmac.last_wakeup + alarm;
|
||||
alarm = _next_inphase_event(netif->mac.lwmac.last_wakeup,
|
||||
netif->mac.prot.lwmac.last_wakeup = netif->mac.prot.lwmac.last_wakeup + alarm;
|
||||
alarm = _next_inphase_event(netif->mac.prot.lwmac.last_wakeup,
|
||||
RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US));
|
||||
rtt_set_alarm(alarm, rtt_cb, (void *) GNRC_LWMAC_EVENT_RTT_WAKEUP_PENDING);
|
||||
}
|
||||
@ -441,12 +441,12 @@ static void _rx_management_failed(gnrc_netif_t *netif)
|
||||
/* Here we check if we are close to the end of the cycle. If yes,
|
||||
* go to sleep. Firstly, get the relative phase. */
|
||||
uint32_t phase = rtt_get_counter();
|
||||
if (phase < netif->mac.lwmac.last_wakeup) {
|
||||
phase = (RTT_US_TO_TICKS(GNRC_LWMAC_PHASE_MAX) - netif->mac.lwmac.last_wakeup) +
|
||||
if (phase < netif->mac.prot.lwmac.last_wakeup) {
|
||||
phase = (RTT_US_TO_TICKS(GNRC_LWMAC_PHASE_MAX) - netif->mac.prot.lwmac.last_wakeup) +
|
||||
phase;
|
||||
}
|
||||
else {
|
||||
phase = phase - netif->mac.lwmac.last_wakeup;
|
||||
phase = phase - netif->mac.prot.lwmac.last_wakeup;
|
||||
}
|
||||
/* If the relative phase is beyond 4/5 cycle time, go to sleep. */
|
||||
if (phase > (4 * RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US) / 5)) {
|
||||
@ -472,12 +472,12 @@ static void _rx_management_success(gnrc_netif_t *netif)
|
||||
/* Here we check if we are close to the end of the cycle. If yes,
|
||||
* go to sleep. Firstly, get the relative phase. */
|
||||
uint32_t phase = rtt_get_counter();
|
||||
if (phase < netif->mac.lwmac.last_wakeup) {
|
||||
phase = (RTT_US_TO_TICKS(GNRC_LWMAC_PHASE_MAX) - netif->mac.lwmac.last_wakeup) +
|
||||
if (phase < netif->mac.prot.lwmac.last_wakeup) {
|
||||
phase = (RTT_US_TO_TICKS(GNRC_LWMAC_PHASE_MAX) - netif->mac.prot.lwmac.last_wakeup) +
|
||||
phase;
|
||||
}
|
||||
else {
|
||||
phase = phase - netif->mac.lwmac.last_wakeup;
|
||||
phase = phase - netif->mac.prot.lwmac.last_wakeup;
|
||||
}
|
||||
/* If the relative phase is beyond 4/5 cycle time, go to sleep. */
|
||||
if (phase > (4 * RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US) / 5)) {
|
||||
@ -619,7 +619,7 @@ static void _lwmac_update_listening(gnrc_netif_t *netif)
|
||||
/* Dispatch first as there still may be broadcast packets. */
|
||||
gnrc_mac_dispatch(&netif->mac.rx);
|
||||
|
||||
netif->mac.lwmac.state = GNRC_LWMAC_SLEEPING;
|
||||
netif->mac.prot.lwmac.state = GNRC_LWMAC_SLEEPING;
|
||||
/* Enable duty cycling again */
|
||||
rtt_handler(GNRC_LWMAC_EVENT_RTT_RESUME, netif);
|
||||
|
||||
@ -648,7 +648,7 @@ static bool lwmac_update(gnrc_netif_t *netif)
|
||||
{
|
||||
gnrc_lwmac_set_reschedule(netif, false);
|
||||
|
||||
switch (netif->mac.lwmac.state) {
|
||||
switch (netif->mac.prot.lwmac.state) {
|
||||
case GNRC_LWMAC_SLEEPING: {
|
||||
/* Quit scheduling transmission if 'quit-tx' flag is found set, thus
|
||||
* to avoid potential collisions with ongoing transmissions of other
|
||||
@ -673,7 +673,7 @@ static bool lwmac_update(gnrc_netif_t *netif)
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LOG_DEBUG("[LWMAC] No actions in state %u\n", netif->mac.lwmac.state);
|
||||
LOG_DEBUG("[LWMAC] No actions in state %u\n", netif->mac.prot.lwmac.state);
|
||||
}
|
||||
|
||||
return gnrc_lwmac_get_reschedule(netif);
|
||||
@ -699,8 +699,8 @@ void rtt_handler(uint32_t event, gnrc_netif_t *netif)
|
||||
switch (event & 0xffff) {
|
||||
case GNRC_LWMAC_EVENT_RTT_WAKEUP_PENDING: {
|
||||
/* A new cycle starts, set sleep timing and initialize related MAC-info flags. */
|
||||
netif->mac.lwmac.last_wakeup = rtt_get_alarm();
|
||||
alarm = _next_inphase_event(netif->mac.lwmac.last_wakeup,
|
||||
netif->mac.prot.lwmac.last_wakeup = rtt_get_alarm();
|
||||
alarm = _next_inphase_event(netif->mac.prot.lwmac.last_wakeup,
|
||||
RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_DURATION_US));
|
||||
rtt_set_alarm(alarm, rtt_cb, (void *) GNRC_LWMAC_EVENT_RTT_SLEEP_PENDING);
|
||||
gnrc_lwmac_set_quit_tx(netif, false);
|
||||
@ -712,7 +712,7 @@ void rtt_handler(uint32_t event, gnrc_netif_t *netif)
|
||||
}
|
||||
case GNRC_LWMAC_EVENT_RTT_SLEEP_PENDING: {
|
||||
/* Set next wake-up timing. */
|
||||
alarm = _next_inphase_event(netif->mac.lwmac.last_wakeup,
|
||||
alarm = _next_inphase_event(netif->mac.prot.lwmac.last_wakeup,
|
||||
RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US));
|
||||
rtt_set_alarm(alarm, rtt_cb, (void *) GNRC_LWMAC_EVENT_RTT_WAKEUP_PENDING);
|
||||
lwmac_set_state(netif, GNRC_LWMAC_SLEEPING);
|
||||
@ -730,14 +730,14 @@ void rtt_handler(uint32_t event, gnrc_netif_t *netif)
|
||||
case GNRC_LWMAC_EVENT_RTT_PAUSE: {
|
||||
rtt_clear_alarm();
|
||||
LOG_DEBUG("[LWMAC] RTT: Stop duty cycling, now in state %u\n",
|
||||
netif->mac.lwmac.state);
|
||||
netif->mac.prot.lwmac.state);
|
||||
gnrc_lwmac_set_dutycycle_active(netif, false);
|
||||
break;
|
||||
}
|
||||
case GNRC_LWMAC_EVENT_RTT_RESUME: {
|
||||
LOG_DEBUG("[LWMAC] RTT: Resume duty cycling\n");
|
||||
rtt_clear_alarm();
|
||||
alarm = _next_inphase_event(netif->mac.lwmac.last_wakeup,
|
||||
alarm = _next_inphase_event(netif->mac.prot.lwmac.last_wakeup,
|
||||
RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US));
|
||||
rtt_set_alarm(alarm, rtt_cb, (void *) GNRC_LWMAC_EVENT_RTT_WAKEUP_PENDING);
|
||||
gnrc_lwmac_set_dutycycle_active(netif, true);
|
||||
@ -934,9 +934,9 @@ static void _lwmac_init(gnrc_netif_t *netif)
|
||||
|
||||
#if (GNRC_LWMAC_ENABLE_DUTYCYLE_RECORD == 1)
|
||||
/* Start duty cycle recording */
|
||||
netif->mac.lwmac.system_start_time_ticks = rtt_get_counter();
|
||||
netif->mac.lwmac.last_radio_on_time_ticks = netif->mac.lwmac.system_start_time_ticks;
|
||||
netif->mac.lwmac.awake_duration_sum_ticks = 0;
|
||||
netif->mac.lwmac.lwmac_info |= GNRC_LWMAC_RADIO_IS_ON;
|
||||
netif->mac.prot.lwmac.system_start_time_ticks = rtt_get_counter();
|
||||
netif->mac.prot.lwmac.last_radio_on_time_ticks = netif->mac.prot.lwmac.system_start_time_ticks;
|
||||
netif->mac.prot.lwmac.awake_duration_sum_ticks = 0;
|
||||
netif->mac.prot.lwmac.lwmac_info |= GNRC_LWMAC_RADIO_IS_ON;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -198,21 +198,21 @@ void _gnrc_lwmac_set_netdev_state(gnrc_netif_t *netif, netopt_state_t devstate)
|
||||
|
||||
#if (GNRC_LWMAC_ENABLE_DUTYCYLE_RECORD == 1)
|
||||
if (devstate == NETOPT_STATE_IDLE) {
|
||||
if (!(netif->mac.lwmac.lwmac_info & GNRC_LWMAC_RADIO_IS_ON)) {
|
||||
netif->mac.lwmac.last_radio_on_time_ticks = rtt_get_counter();
|
||||
netif->mac.lwmac.lwmac_info |= GNRC_LWMAC_RADIO_IS_ON;
|
||||
if (!(netif->mac.prot.lwmac.lwmac_info & GNRC_LWMAC_RADIO_IS_ON)) {
|
||||
netif->mac.prot.lwmac.last_radio_on_time_ticks = rtt_get_counter();
|
||||
netif->mac.prot.lwmac.lwmac_info |= GNRC_LWMAC_RADIO_IS_ON;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if ((devstate == NETOPT_STATE_SLEEP) &&
|
||||
(netif->mac.lwmac.lwmac_info & GNRC_LWMAC_RADIO_IS_ON)) {
|
||||
netif->mac.lwmac.radio_off_time_ticks = rtt_get_counter();
|
||||
(netif->mac.prot.lwmac.lwmac_info & GNRC_LWMAC_RADIO_IS_ON)) {
|
||||
netif->mac.prot.lwmac.radio_off_time_ticks = rtt_get_counter();
|
||||
|
||||
netif->mac.lwmac.awake_duration_sum_ticks +=
|
||||
(netif->mac.lwmac.radio_off_time_ticks -
|
||||
netif->mac.lwmac.last_radio_on_time_ticks);
|
||||
netif->mac.prot.lwmac.awake_duration_sum_ticks +=
|
||||
(netif->mac.prot.lwmac.radio_off_time_ticks -
|
||||
netif->mac.prot.lwmac.last_radio_on_time_ticks);
|
||||
|
||||
netif->mac.lwmac.lwmac_info &= ~GNRC_LWMAC_RADIO_IS_ON;
|
||||
netif->mac.prot.lwmac.lwmac_info &= ~GNRC_LWMAC_RADIO_IS_ON;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -138,13 +138,13 @@ static bool _send_wa(gnrc_netif_t *netif)
|
||||
/* Embed the current 'relative phase timing' (counted from the start of this cycle)
|
||||
* of the receiver into its WA packet, thus to allow the sender to infer the
|
||||
* receiver's exact wake-up timing */
|
||||
if (phase_now > _gnrc_lwmac_ticks_to_phase(netif->mac.lwmac.last_wakeup)) {
|
||||
if (phase_now > _gnrc_lwmac_ticks_to_phase(netif->mac.prot.lwmac.last_wakeup)) {
|
||||
lwmac_hdr.current_phase = (phase_now -
|
||||
_gnrc_lwmac_ticks_to_phase(netif->mac.lwmac.last_wakeup));
|
||||
_gnrc_lwmac_ticks_to_phase(netif->mac.prot.lwmac.last_wakeup));
|
||||
}
|
||||
else {
|
||||
lwmac_hdr.current_phase = (phase_now + RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US)) -
|
||||
_gnrc_lwmac_ticks_to_phase(netif->mac.lwmac.last_wakeup);
|
||||
_gnrc_lwmac_ticks_to_phase(netif->mac.prot.lwmac.last_wakeup);
|
||||
}
|
||||
|
||||
pkt = gnrc_pktbuf_add(NULL, &lwmac_hdr, sizeof(lwmac_hdr), GNRC_NETTYPE_LWMAC);
|
||||
|
||||
@ -62,19 +62,19 @@ inline bool gnrc_lwmac_timeout_is_running(gnrc_netif_t *netif,
|
||||
gnrc_lwmac_timeout_type_t type)
|
||||
{
|
||||
assert(netif);
|
||||
return (_lwmac_find_timeout(&netif->mac.lwmac, type) >= 0);
|
||||
return (_lwmac_find_timeout(&netif->mac.prot.lwmac, type) >= 0);
|
||||
}
|
||||
|
||||
bool gnrc_lwmac_timeout_is_expired(gnrc_netif_t *netif, gnrc_lwmac_timeout_type_t type)
|
||||
{
|
||||
assert(netif);
|
||||
|
||||
int index = _lwmac_find_timeout(&netif->mac.lwmac, type);
|
||||
int index = _lwmac_find_timeout(&netif->mac.prot.lwmac, type);
|
||||
if (index >= 0) {
|
||||
if (netif->mac.lwmac.timeouts[index].expired) {
|
||||
_lwmac_clear_timeout(&netif->mac.lwmac.timeouts[index]);
|
||||
if (netif->mac.prot.lwmac.timeouts[index].expired) {
|
||||
_lwmac_clear_timeout(&netif->mac.prot.lwmac.timeouts[index]);
|
||||
}
|
||||
return netif->mac.lwmac.timeouts[index].expired;
|
||||
return netif->mac.prot.lwmac.timeouts[index].expired;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -89,9 +89,9 @@ gnrc_lwmac_timeout_t *_lwmac_acquire_timeout(gnrc_netif_t *netif,
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < GNRC_LWMAC_TIMEOUT_COUNT; i++) {
|
||||
if (netif->mac.lwmac.timeouts[i].type == GNRC_LWMAC_TIMEOUT_DISABLED) {
|
||||
netif->mac.lwmac.timeouts[i].type = type;
|
||||
return &netif->mac.lwmac.timeouts[i];
|
||||
if (netif->mac.prot.lwmac.timeouts[i].type == GNRC_LWMAC_TIMEOUT_DISABLED) {
|
||||
netif->mac.prot.lwmac.timeouts[i].type = type;
|
||||
return &netif->mac.prot.lwmac.timeouts[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
@ -108,9 +108,9 @@ void gnrc_lwmac_clear_timeout(gnrc_netif_t *netif, gnrc_lwmac_timeout_type_t typ
|
||||
{
|
||||
assert(netif);
|
||||
|
||||
int index = _lwmac_find_timeout(&netif->mac.lwmac, type);
|
||||
int index = _lwmac_find_timeout(&netif->mac.prot.lwmac, type);
|
||||
if (index >= 0) {
|
||||
_lwmac_clear_timeout(&netif->mac.lwmac.timeouts[index]);
|
||||
_lwmac_clear_timeout(&netif->mac.prot.lwmac.timeouts[index]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -141,8 +141,8 @@ void gnrc_lwmac_reset_timeouts(gnrc_netif_t *netif)
|
||||
assert(netif);
|
||||
|
||||
for (unsigned i = 0; i < GNRC_LWMAC_TIMEOUT_COUNT; i++) {
|
||||
if (netif->mac.lwmac.timeouts[i].type != GNRC_LWMAC_TIMEOUT_DISABLED) {
|
||||
_lwmac_clear_timeout(&netif->mac.lwmac.timeouts[i]);
|
||||
if (netif->mac.prot.lwmac.timeouts[i].type != GNRC_LWMAC_TIMEOUT_DISABLED) {
|
||||
_lwmac_clear_timeout(&netif->mac.prot.lwmac.timeouts[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -316,7 +316,7 @@ static uint8_t _packet_process_in_wait_for_wa(gnrc_netif_t *netif)
|
||||
}
|
||||
|
||||
uint32_t own_phase;
|
||||
own_phase = _gnrc_lwmac_ticks_to_phase(netif->mac.lwmac.last_wakeup);
|
||||
own_phase = _gnrc_lwmac_ticks_to_phase(netif->mac.prot.lwmac.last_wakeup);
|
||||
|
||||
if (own_phase >= netif->mac.tx.timestamp) {
|
||||
own_phase = own_phase - netif->mac.tx.timestamp;
|
||||
@ -464,10 +464,10 @@ static bool _send_data(gnrc_netif_t *netif)
|
||||
DEBUG("[LWMAC-tx]: spent %lu WR in TX\n", netif->mac.tx.wr_sent);
|
||||
|
||||
#if (LWMAC_ENABLE_DUTYCYLE_RECORD == 1)
|
||||
netif->mac.lwmac.pkt_start_sending_time_ticks =
|
||||
rtt_get_counter() - netif->mac.lwmac.pkt_start_sending_time_ticks;
|
||||
netif->mac.prot.lwmac.pkt_start_sending_time_ticks =
|
||||
rtt_get_counter() - netif->mac.prot.lwmac.pkt_start_sending_time_ticks;
|
||||
DEBUG("[LWMAC-tx]: pkt sending delay in TX: %lu us\n",
|
||||
RTT_TICKS_TO_US(netif->mac.lwmac.pkt_start_sending_time_ticks));
|
||||
RTT_TICKS_TO_US(netif->mac.prot.lwmac.pkt_start_sending_time_ticks));
|
||||
#endif
|
||||
|
||||
return true;
|
||||
@ -492,7 +492,7 @@ void gnrc_lwmac_tx_start(gnrc_netif_t *netif,
|
||||
netif->mac.tx.wr_sent = 0;
|
||||
|
||||
#if (LWMAC_ENABLE_DUTYCYLE_RECORD == 1)
|
||||
netif->mac.lwmac.pkt_start_sending_time_ticks = rtt_get_counter();
|
||||
netif->mac.prot.lwmac.pkt_start_sending_time_ticks = rtt_get_counter();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
49
tests/gomach/Makefile
Normal file
49
tests/gomach/Makefile
Normal file
@ -0,0 +1,49 @@
|
||||
# name of your application
|
||||
APPLICATION = gomach
|
||||
|
||||
# This has to be the absolute path to the RIOT base directory:
|
||||
RIOTBASE ?= $(CURDIR)/../..
|
||||
|
||||
# If no BOARD is found in the environment, use this default:
|
||||
BOARD ?= samr21-xpro
|
||||
|
||||
# Currently, GoMacH has only been tested and evaluated through on samr21-xpro and iotlab-m3
|
||||
# nodes. Once GoMacH has also been tested through on other devices, the whitelist should
|
||||
# be then accordingly extended.
|
||||
BOARD_WHITELIST := samr21-xpro iotlab-m3
|
||||
|
||||
# Comment this out to disable code in RIOT that does safety checking
|
||||
# which is not needed in a production environment but helps in the
|
||||
# development process:
|
||||
CFLAGS += -DDEVELHELP
|
||||
|
||||
# Modules to include:
|
||||
USEMODULE += shell
|
||||
USEMODULE += shell_commands
|
||||
USEMODULE += ps
|
||||
# include and auto-initialize all available sensors
|
||||
USEMODULE += saul_default
|
||||
|
||||
# Use modules for networking
|
||||
# gnrc is a meta module including all required, basic gnrc networking modules
|
||||
USEMODULE += gnrc
|
||||
# use the default network interface for the board
|
||||
USEMODULE += gnrc_netdev_default
|
||||
# automatically initialize the network interface
|
||||
USEMODULE += auto_init_gnrc_netif
|
||||
# shell command to send L2 packets with a simple string
|
||||
USEMODULE += gnrc_txtsnd
|
||||
# the application dumps received packets to stdout
|
||||
USEMODULE += gnrc_pktdump
|
||||
# Use GoMacH as the MAC protocol
|
||||
USEMODULE += gnrc_gomach
|
||||
|
||||
# We use only the lower layers of the GNRC network stack, hence, we can
|
||||
# reduce the size of the packet buffer a bit
|
||||
CFLAGS += -DGNRC_PKTBUF_SIZE=1024
|
||||
|
||||
# Set a custom channel if needed
|
||||
DEFAULT_CHANNEL ?= 26
|
||||
CFLAGS += -DIEEE802154_DEFAULT_CHANNEL=$(DEFAULT_CHANNEL)
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
||||
53
tests/gomach/README.md
Normal file
53
tests/gomach/README.md
Normal file
@ -0,0 +1,53 @@
|
||||
GoMacH test application
|
||||
=======================
|
||||
This application is a showcase for testing GoMacH communications. Using it
|
||||
for your board, you should be able to interactively use any hardware
|
||||
that is supported for communications among devices based on GoMacH.
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
Build, flash and start the application:
|
||||
```
|
||||
export BOARD=your_board
|
||||
make
|
||||
make flash
|
||||
make term
|
||||
```
|
||||
|
||||
The `term` make target starts a terminal emulator for your board. It
|
||||
connects to a default port so you can interact with the shell, usually
|
||||
that is `/dev/ttyUSB0`. If your port is named differently, the
|
||||
`PORT=/dev/yourport` variable can be used to override this.
|
||||
|
||||
|
||||
Example output
|
||||
==============
|
||||
|
||||
The `ifconfig` command will help you to configure all available network
|
||||
interfaces. On an samr21 board it will print something like:
|
||||
```
|
||||
2015-09-16 16:58:37,762 - INFO # ifconfig
|
||||
2015-09-16 16:58:37,766 - INFO # Iface 4 HWaddr: 9e:72 Channel: 26 NID: 0x23 TX-Power: 0dBm State: IDLE CSMA Retries: 4
|
||||
2015-09-16 16:58:37,768 - INFO # Long HWaddr: 36:32:48:33:46:da:9e:72
|
||||
2015-09-16 16:58:37,769 - INFO # AUTOACK CSMA
|
||||
2015-09-16 16:58:37,770 - INFO # Source address length: 2
|
||||
```
|
||||
|
||||
The `txtsnd` command allows you to send a simple string directly over the link
|
||||
layer (here, it is GoMacH) using unicast or broadcast. The application will also automatically print
|
||||
information about any received packet over the serial. This will look like:
|
||||
```
|
||||
2015-09-16 16:59:29,187 - INFO # PKTDUMP: data received:
|
||||
2015-09-16 16:59:29,189 - INFO # ~~ SNIP 0 - size: 28 byte, type:
|
||||
NETTYPE_UNDEF (0)
|
||||
2015-09-16 16:59:29,190 - INFO # 000000 7b 3b 3a 02 85 00 e7 fb 00 00 00 00 01
|
||||
02 5a 55
|
||||
2015-09-16 16:59:29,192 - INFO # 000010 40 42 3e 62 f2 1a 00 00 00 00 00 00
|
||||
2015-09-16 16:59:29,194 - INFO # ~~ SNIP 1 - size: 18 byte, type:
|
||||
NETTYPE_NETIF (-1)
|
||||
2015-09-16 16:59:29,195 - INFO # if_pid: 4 rssi: 49 lqi: 78
|
||||
2015-09-16 16:59:29,196 - INFO # src_l2addr: 5a:55:40:42:3e:62:f2:1a
|
||||
2015-09-16 16:59:29,197 - INFO # dst_l2addr: ff:ff
|
||||
2015-09-16 16:59:29,198 - INFO # ~~ PKT - 2 snips, total size: 46 byte
|
||||
```
|
||||
40
tests/gomach/main.c
Normal file
40
tests/gomach/main.c
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2017 INRIA
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup tests
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Test application for testing the GoMacH implementation
|
||||
*
|
||||
* @author Shuguo Zhuo <shuguo.zhuo@inria.fr>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "thread.h"
|
||||
#include "shell.h"
|
||||
#include "shell_commands.h"
|
||||
#include "net/gnrc/pktdump.h"
|
||||
#include "net/gnrc.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
gnrc_netreg_entry_t dump = GNRC_NETREG_ENTRY_INIT_PID(GNRC_NETREG_DEMUX_CTX_ALL,
|
||||
gnrc_pktdump_pid);
|
||||
gnrc_netreg_register(GNRC_NETTYPE_UNDEF, &dump);
|
||||
|
||||
char line_buf[SHELL_DEFAULT_BUFSIZE];
|
||||
shell_run(NULL, line_buf, SHELL_DEFAULT_BUFSIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user