1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-12-25 06:23:53 +01:00

Merge pull request #21617 from Teufelchen1/deprecate/gnrc_mac

net/mac: Remove deprecated 802.15.4 MAC module
This commit is contained in:
crasbe 2025-07-21 20:45:24 +00:00 committed by GitHub
commit d271fc88a4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 0 additions and 1728 deletions

View File

@ -1,5 +1,4 @@
# Add deprecated modules here
# Keep this list ALPHABETICALLY SORTED!!!!111elven
DEPRECATED_MODULES += gnrc_mac
DEPRECATED_MODULES += gnrc_nettype_lorawan
DEPRECATED_MODULES += sema_deprecated

View File

@ -130,7 +130,6 @@ PSEUDOMODULES += gnrc_netif_bus
PSEUDOMODULES += gnrc_netif_timestamp
PSEUDOMODULES += gnrc_netif_6lo
PSEUDOMODULES += gnrc_netif_ipv6
PSEUDOMODULES += gnrc_netif_mac
PSEUDOMODULES += gnrc_netif_single
PSEUDOMODULES += gnrc_netif_dedup

View File

@ -1,143 +0,0 @@
/*
* Copyright (C) 2015 Daniel Krebs
* 2016 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.
*/
#pragma once
/**
* @ingroup net_gnrc_mac
* @{
*
* @file
* @brief Definitions of internal functions of GNRC_MAC module
* @internal
* @author Daniel Krebs <github@daniel-krebs.net>
* @author Shuguo Zhuo <shuguo.zhuo@inria.fr>
*/
#include <stdint.h>
#include "net/ieee802154.h"
#include "net/gnrc/netif.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief get the 'rx_started' state of the device
*
* This function checks whether the device has started receiving a packet.
*
* @param[in] netif the network interface
*
* @return the rx_started state
*/
static inline bool gnrc_netif_get_rx_started(gnrc_netif_t *netif)
{
return (netif->mac.mac_info & GNRC_NETIF_MAC_INFO_RX_STARTED);
}
/**
* @brief set the rx_started state of the device
*
* This function is intended to be called only in netdev_t::event_callback().
*
* @param[in] netif the network interface
* @param[in] rx_started the rx_started state
*/
static inline void gnrc_netif_set_rx_started(gnrc_netif_t *netif, bool rx_started)
{
if (rx_started) {
netif->mac.mac_info |= GNRC_NETIF_MAC_INFO_RX_STARTED;
}
else {
netif->mac.mac_info &= ~GNRC_NETIF_MAC_INFO_RX_STARTED;
}
}
/**
* @brief get the transmission feedback of the device
*
* @param[in] netif the network interface
*
* @return the transmission feedback
*/
static inline gnrc_mac_tx_feedback_t gnrc_netif_get_tx_feedback(gnrc_netif_t *netif)
{
return (gnrc_mac_tx_feedback_t)(netif->mac.mac_info &
GNRC_NETIF_MAC_INFO_TX_FEEDBACK_MASK);
}
/**
* @brief set the transmission feedback of the device
*
* This function is intended to be called only in netdev_t::event_callback().
*
* @param[in] netif the network interface
* @param[in] txf the transmission feedback
*/
static inline void gnrc_netif_set_tx_feedback(gnrc_netif_t *netif,
gnrc_mac_tx_feedback_t txf)
{
/* check if gnrc_mac_tx_feedback does not collide with
* GNRC_NETIF_MAC_INFO_RX_STARTED */
assert(!(txf & GNRC_NETIF_MAC_INFO_RX_STARTED));
/* unset previous value */
netif->mac.mac_info &= ~GNRC_NETIF_MAC_INFO_TX_FEEDBACK_MASK;
netif->mac.mac_info |= (uint16_t)(txf & GNRC_NETIF_MAC_INFO_TX_FEEDBACK_MASK);
}
#if (GNRC_MAC_TX_QUEUE_SIZE != 0) || defined(DOXYGEN)
/**
* @brief Queues the packet into the related transmission packet queue in netdev_t::tx.
* Note that, in case the `gnrc_mac_tx_neighbor_t` structure is in used (indicated
* by `CONFIG_GNRC_MAC_NEIGHBOR_COUNT != 0`), this function queues the packet to
* the queue associated to the pkt's destination neighbor, including a
* `broadcast-neighbor` (neighbor id is `0` in netdev_t::tx::neighbors) which
* specifically stores broadcasting packets.
* On the other hand, if `gnrc_mac_tx_neighbor_t` structure is not in used (indicated
* by `CONFIG_GNRC_MAC_NEIGHBOR_COUNT == 0`), this function queues the packet into the single
* priority TX queue defined in in netdev_t::tx.
*
* @param[in,out] tx gnrc_mac transmission management object
* @param[in] priority the priority of @p pkt
* @param[in] pkt gnrc packet that will be queued
*
* @return true if queued successfully, otherwise false.
*/
bool gnrc_mac_queue_tx_packet(gnrc_mac_tx_t *tx, uint32_t priority, gnrc_pktsnip_t *pkt);
#endif /* (GNRC_MAC_TX_QUEUE_SIZE != 0) || defined(DOXYGEN) */
#if (GNRC_MAC_RX_QUEUE_SIZE != 0) || defined(DOXYGEN)
/**
* @brief Queues the packet into the reception packet queue in netdev_t::rx.
*
* @param[in,out] rx gnrc_mac reception management object
* @param[in] priority the priority of @p pkt
* @param[in] pkt gnrc packet that will be queued
*
* @return true if queued successfully, otherwise false.
*/
bool gnrc_mac_queue_rx_packet(gnrc_mac_rx_t *rx, uint32_t priority, gnrc_pktsnip_t *pkt);
#endif /* (GNRC_MAC_RX_QUEUE_SIZE != 0) || defined(DOXYGEN) */
#if (GNRC_MAC_DISPATCH_BUFFER_SIZE != 0) || defined(DOXYGEN)
/**
* @brief Dispatch all the packets stored in netdev_t::rx:dispatch_buffer to upper layer.
*
* @param[in,out] rx gnrc_mac reception management object
*/
void gnrc_mac_dispatch(gnrc_mac_rx_t *rx);
#endif /* (GNRC_MAC_DISPATCH_BUFFER_SIZE != 0) || defined(DOXYGEN) */
#ifdef __cplusplus
}
#endif
/** @} */

View File

@ -1,128 +0,0 @@
/*
* Copyright (C) 2015 Daniel Krebs
* 2016 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.
*/
#pragma once
/**
* @defgroup net_gnrc_mac Common MAC module
* @ingroup net_gnrc
* @brief A MAC module for providing common MAC parameters and helper functions.
* @deprecated This module is deprecated and will be removed after the 2024.10 release.
* As an alternative, you can use @ref pkg_opendsme.
*
* @{
*
* @file
* @brief Definitions of GNRC_MAC
*
* @author Daniel Krebs <github@daniel-krebs.net>
* @author Shuguo Zhuo <shuguo.zhuo@inria.fr>
*/
#include "modules.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup net_gnrc_mac_conf GNRC MAC compile configurations
* @ingroup net_gnrc_conf
* @{
*/
/**
* @brief Default message queue size to use for the incoming packets (as
* exponent of 2^n).
*
* As the queue size ALWAYS needs to be power of two, this option represents the
* exponent of 2^n, which will be used as the size of the queue.
*/
#ifndef CONFIG_GNRC_MAC_RX_QUEUE_SIZE_EXP
#define CONFIG_GNRC_MAC_RX_QUEUE_SIZE_EXP (3U)
#endif
/**
* @brief Default buffer size to use for storing dispatching packets (as
* exponent of 2^n).
*
* As the buffer size ALWAYS needs to be power of two, this option represents
* the exponent of 2^n, which will be used as the size of the buffer.
*/
#ifndef CONFIG_GNRC_MAC_DISPATCH_BUFFER_SIZE_EXP
#define CONFIG_GNRC_MAC_DISPATCH_BUFFER_SIZE_EXP (3U)
#endif
/**
* @brief Count of neighbor nodes in one-hop distance.
*/
#ifndef CONFIG_GNRC_MAC_NEIGHBOR_COUNT
#define CONFIG_GNRC_MAC_NEIGHBOR_COUNT (8U)
#endif
/**
* @brief Default queue size for transmission packets coming from higher
* layers (as exponent of 2^n).
*
* As the queue size ALWAYS needs to be power of two, this option represents
* the exponent of 2^n, which will be used as the size of the buffer.
*/
#ifndef CONFIG_GNRC_MAC_TX_QUEUE_SIZE_EXP
#define CONFIG_GNRC_MAC_TX_QUEUE_SIZE_EXP (3U)
#endif
/**
* @brief Disable MAC radio duty-cycle recording and displaying.
*/
#ifdef DOXYGEN
#define CONFIG_GNRC_MAC_DISABLE_DUTYCYCLE_RECORD
#endif
/**
* @brief Enable/disable MAC radio duty-cycle recording and displaying.
*
* Set "1" to enable, set "0" to disable.
* @deprecated Use inverse @ref CONFIG_GNRC_MAC_DISABLE_DUTYCYCLE_RECORD
* instead. Will be removed after 2021.01 release.
*/
#ifndef GNRC_MAC_ENABLE_DUTYCYCLE_RECORD
#if IS_ACTIVE(CONFIG_GNRC_MAC_DISABLE_DUTYCYCLE_RECORD)
#define GNRC_MAC_ENABLE_DUTYCYCLE_RECORD (0)
#else
#define GNRC_MAC_ENABLE_DUTYCYCLE_RECORD (1U)
#endif
#endif
/** @} */
/**
* @brief The default rx queue size for incoming packets
*/
#ifndef GNRC_MAC_RX_QUEUE_SIZE
#define GNRC_MAC_RX_QUEUE_SIZE (1 << CONFIG_GNRC_MAC_RX_QUEUE_SIZE_EXP)
#endif
/**
* @brief The default buffer size for storing dispatching packets
*/
#ifndef GNRC_MAC_DISPATCH_BUFFER_SIZE
#define GNRC_MAC_DISPATCH_BUFFER_SIZE (1 << CONFIG_GNRC_MAC_DISPATCH_BUFFER_SIZE_EXP)
#endif
/**
* @brief The default queue size for transmission packets coming from higher
* layers
*/
#ifndef GNRC_MAC_TX_QUEUE_SIZE
#define GNRC_MAC_TX_QUEUE_SIZE (1 << CONFIG_GNRC_MAC_TX_QUEUE_SIZE_EXP)
#endif
#ifdef __cplusplus
}
#endif
/** @} */

View File

@ -1,147 +0,0 @@
/*
* Copyright (C) 2015 Daniel Krebs
* 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.
*/
#pragma once
/**
* @ingroup net_gnrc_mac
* @{
*
* @file
* @brief Timeout APIs used by GNRC_MAC
*
* @author Daniel Krebs <github@daniel-krebs.net>
* @author Shuguo Zhuo <shuguo.zhuo@inria.fr>
*/
#include <assert.h>
#include <stdint.h>
#include <stdbool.h>
#include "evtimer_msg.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief definition for GNRC_MAC timeout event type
*/
#define GNRC_MAC_EVENT_TIMEOUT_TYPE (0x4400)
/**
* @brief Definitions of GNRC_MAC timeout types.
*
* This structure can be extended to contain more needed
* timeout types of different MAC protocols. Please guard
* them by appropriate \#ifdef directives when applicable.
*/
typedef enum {
GNRC_MAC_TIMEOUT_DISABLED = 0, /**< Timeout is disabled, not in used. */
} gnrc_mac_timeout_type_t;
/**
* @brief Structure of the GNRC_MAC timeout event.
*/
typedef struct {
evtimer_msg_event_t msg_event; /**< The timeout message event. */
gnrc_mac_timeout_type_t type; /**< GNRC_MAC timeout type. */
} gnrc_mac_timeout_event_t;
/**
* @brief Structure holding the GNRC_MAC timeouts.
*/
typedef struct {
evtimer_t evtimer; /**< evtimer entity which
stores the timeout list. */
gnrc_mac_timeout_event_t *timeouts; /**< The gnrc_mac timeout
unites. */
uint8_t timeout_num; /**< Timeout number. */
} gnrc_mac_timeout_t;
/**
* @brief Initialize the MAC timeout module of gnrc_mac before using,
* it also sets the timeout callback function.
*
* @param[in,out] mac_timeout gnrc_mac timeout management unit
* @param[in] timeouts gnrc_mac timeouts
* @param[in] num timeout number
*/
void gnrc_mac_init_timeouts(gnrc_mac_timeout_t *mac_timeout,
gnrc_mac_timeout_event_t timeouts[],
uint8_t num);
/**
* @brief Set a MAC timeout of @p type.
*
* @param[in,out] mac_timeout gnrc_mac timeout management unit
* @param[in] type the MAC timeout type
* @param[in] offset the timeout offset
* @param[in] pid the targeted thread pid
*/
void gnrc_mac_set_timeout(gnrc_mac_timeout_t *mac_timeout, gnrc_mac_timeout_type_t type,
uint32_t offset, kernel_pid_t pid);
/**
* @brief Find a MAC timeout of @p type.
*
* @param[in] mac_timeout gnrc_mac timeout management unit
* @param[in] type the MAC timeout type
*
* @return Return index >= 0 if found timeout, -ENONENT if not found
*/
int gnrc_mac_find_timeout(gnrc_mac_timeout_t *mac_timeout, gnrc_mac_timeout_type_t type);
/**
* @brief Clear a MAC timeout of @p type.
*
* @param[in,out] mac_timeout gnrc_mac timeout management unit
* @param[in] type the MAC timeout type
*/
void gnrc_mac_clear_timeout(gnrc_mac_timeout_t *mac_timeout, gnrc_mac_timeout_type_t type);
/**
* @brief Check whether a MAC timeout of @p type is running or not.
*
* @param[in] mac_timeout gnrc_mac timeout management unit
* @param[in] type the MAC timeout type
*
* @return true, if the time of @p type is running
* @return false, if the time of @p type is not running, or not exist
*/
static inline bool gnrc_mac_timeout_is_running(gnrc_mac_timeout_t *mac_timeout,
gnrc_mac_timeout_type_t type)
{
assert(mac_timeout);
return (gnrc_mac_find_timeout(mac_timeout, type) >= 0);
}
/**
* @brief Check whether a MAC timeout of @p type has expired or not.
*
* @param[in,out] mac_timeout gnrc_mac timeout management unit
* @param[in] type the MAC timeout type
*
* @return true, if the MAC time of @p type is expired
* @return false, if the MAC time of @p type is not expired, or not exist
*/
bool gnrc_mac_timeout_is_expired(gnrc_mac_timeout_t *mac_timeout, gnrc_mac_timeout_type_t type);
/**
* @brief Reset all the MAC timeouts.
*
* @param[in,out] mac_timeout gnrc_mac timeout management unit
*/
void gnrc_mac_reset_timeouts(gnrc_mac_timeout_t *mac_timeout);
#ifdef __cplusplus
}
#endif
/** @} */

View File

@ -1,193 +0,0 @@
/*
* Copyright (C) 2015 Daniel Krebs
* 2016 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.
*/
#pragma once
/**
* @ingroup net_gnrc_mac
* @{
*
* @file
* @brief Internal data types used by GNRC_MAC
*
* @author Daniel Krebs <github@daniel-krebs.net>
* @author Shuguo Zhuo <shuguo.zhuo@inria.fr>
*/
#include <stdint.h>
#include <stdbool.h>
#include "net/gnrc/pkt.h"
#include "net/gnrc/priority_pktqueue.h"
#include "net/ieee802154.h"
#include "net/gnrc/mac/mac.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief MAC message type for getting radio's duty-cycle.
*/
#define GNRC_MAC_TYPE_GET_DUTYCYCLE (0x4401)
/**
* @brief definition for device transmission feedback types
*/
typedef enum {
TX_FEEDBACK_UNDEF = 0, /**< Transmission just start, no Tx feedback yet */
TX_FEEDBACK_SUCCESS, /**< Transmission succeeded */
TX_FEEDBACK_NOACK, /**< No ACK for the transmitted packet */
TX_FEEDBACK_BUSY /**< found medium busy when doing transmission */
} gnrc_mac_tx_feedback_t;
/**
* @brief Static initializer for gnrc_mac_tx_feedback_t.
*/
#define GNRC_MAC_TX_FEEDBACK_INIT { TX_FEEDBACK_UNDEF }
#if ((GNRC_MAC_RX_QUEUE_SIZE != 0) || (GNRC_MAC_DISPATCH_BUFFER_SIZE != 0)) || defined(DOXYGEN)
/**
* @brief MAC internal type for storing reception state parameters and
* state machines.
* This structure can be extended to contain more needed
* states and parameters. Please guard them by appropriate
* \#ifdef directives when applicable.
*/
typedef struct {
#if (GNRC_MAC_RX_QUEUE_SIZE != 0) || defined(DOXYGEN)
gnrc_priority_pktqueue_t queue; /**< RX packet queue */
gnrc_priority_pktqueue_node_t _queue_nodes[GNRC_MAC_RX_QUEUE_SIZE]; /**< RX queue nodes */
#endif /* (GNRC_MAC_RX_QUEUE_SIZE != 0) || defined(DOXYGEN) */
#if (GNRC_MAC_DISPATCH_BUFFER_SIZE != 0) || defined(DOXYGEN)
gnrc_pktsnip_t *dispatch_buffer[GNRC_MAC_DISPATCH_BUFFER_SIZE]; /**< dispatch packet buffer */
#endif /* (GNRC_MAC_DISPATCH_BUFFER_SIZE != 0) || defined(DOXYGEN) */
} gnrc_mac_rx_t;
/**
* @brief Static initializer for gnrc_mac_rx_t.
*/
#if ((GNRC_MAC_RX_QUEUE_SIZE != 0) && (GNRC_MAC_DISPATCH_BUFFER_SIZE != 0)) || defined(DOXYGEN)
#define GNRC_MAC_RX_INIT { \
PRIORITY_PKTQUEUE_INIT, \
{ PRIORITY_PKTQUEUE_NODE_INIT(0, NULL) }, \
{ NULL }, \
}
#elif (GNRC_MAC_RX_QUEUE_SIZE != 0) && (GNRC_MAC_DISPATCH_BUFFER_SIZE == 0) || defined(DOXYGEN)
#define GNRC_MAC_RX_INIT { \
PRIORITY_PKTQUEUE_INIT, \
{ PRIORITY_PKTQUEUE_NODE_INIT(0, NULL) }, \
}
#elif (GNRC_MAC_RX_QUEUE_SIZE == 0) && (GNRC_MAC_DISPATCH_BUFFER_SIZE != 0) || defined(DOXYGEN)
#define GNRC_MAC_RX_INIT { \
{ NULL }, \
}
#endif /* ((GNRC_MAC_RX_QUEUE_SIZE != 0) && (GNRC_MAC_DISPATCH_BUFFER_SIZE != 0)) || defined(DOXYGEN) */
#endif /* ((GNRC_MAC_RX_QUEUE_SIZE != 0) || (GNRC_MAC_DISPATCH_BUFFER_SIZE != 0)) || defined(DOXYGEN) */
#if (CONFIG_GNRC_MAC_NEIGHBOR_COUNT != 0) || defined(DOXYGEN)
/**
* @brief type for storing states of TX neighbor node.
*/
typedef struct {
uint8_t l2_addr[IEEE802154_LONG_ADDRESS_LEN]; /**< Address of neighbor node */
uint8_t l2_addr_len; /**< Neighbor address length */
uint32_t phase; /**< Neighbor's wake-up Phase */
#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) */
} gnrc_mac_tx_neighbor_t;
/**
* @brief Uninitialized phase value.
*/
#define GNRC_MAC_PHASE_UNINITIALIZED (0)
/**
* @brief Maximum phase value.
*/
#define GNRC_MAC_PHASE_MAX (-1)
/**
* @brief Static initializer for gnrc_mac_tx_neighbor_t.
*/
#if (GNRC_MAC_TX_QUEUE_SIZE != 0) || defined(DOXYGEN)
#define GNRC_MAC_TX_NEIGHBOR_INIT { \
{ 0 }, \
0, \
GNRC_MAC_PHASE_UNINITIALIZED, \
PRIORITY_PKTQUEUE_INIT, \
}
#else
#define GNRC_MAC_TX_NEIGHBOR_INIT { \
{ 0 }, \
0, \
GNRC_MAC_PHASE_UNINITIALIZED, \
}
#endif /* (GNRC_MAC_TX_QUEUE_SIZE != 0) || defined(DOXYGEN) */
#endif /* (CONFIG_GNRC_MAC_NEIGHBOR_COUNT != 0) || defined(DOXYGEN) */
#if ((GNRC_MAC_TX_QUEUE_SIZE != 0) || (CONFIG_GNRC_MAC_NEIGHBOR_COUNT != 0)) || defined(DOXYGEN)
/**
* @brief MAC internal type for storing transmission state parameters and
* state machines.
* This structure can be extended to contain more needed
* states and parameters. Please guard them by appropriate
* \#ifdef directives when applicable.
*/
typedef struct {
#if (CONFIG_GNRC_MAC_NEIGHBOR_COUNT != 0) || defined(DOXYGEN)
gnrc_mac_tx_neighbor_t neighbors[CONFIG_GNRC_MAC_NEIGHBOR_COUNT + 1]; /**< Neighbor information units for one-hop neighbors.
First unit is for broadcast (+1) */
gnrc_mac_tx_neighbor_t *current_neighbor; /**< Neighbor information unit of destination node to which
the current packet will be sent */
#endif /* (CONFIG_GNRC_MAC_NEIGHBOR_COUNT != 0) || defined(DOXYGEN) */
#if (GNRC_MAC_TX_QUEUE_SIZE != 0) || defined(DOXYGEN)
#if (CONFIG_GNRC_MAC_NEIGHBOR_COUNT == 0) || defined(DOXYGEN)
gnrc_priority_pktqueue_t queue; /**< If neighbor queues is not used, define
a single queue for managing TX packets. */
#endif /* (CONFIG_GNRC_MAC_NEIGHBOR_COUNT == 0) || defined(DOXYGEN) */
gnrc_priority_pktqueue_node_t _queue_nodes[GNRC_MAC_TX_QUEUE_SIZE]; /**< Shared buffer for TX queue nodes */
gnrc_pktsnip_t *packet; /**< currently scheduled packet for sending */
#endif /* (GNRC_MAC_TX_QUEUE_SIZE != 0) || defined(DOXYGEN) */
} gnrc_mac_tx_t;
/**
* @brief Static initializer for gnrc_mac_tx_t.
*/
#if ((GNRC_MAC_TX_QUEUE_SIZE != 0) && (CONFIG_GNRC_MAC_NEIGHBOR_COUNT != 0)) || defined(DOXYGEN)
#define GNRC_MAC_TX_INIT { \
{ GNRC_MAC_TX_NEIGHBOR_INIT }, \
NULL, \
{ PRIORITY_PKTQUEUE_NODE_INIT(0, NULL) }, \
NULL, \
}
#elif ((GNRC_MAC_TX_QUEUE_SIZE != 0) && (CONFIG_GNRC_MAC_NEIGHBOR_COUNT == 0)) || defined(DOXYGEN)
#define GNRC_MAC_TX_INIT { \
PRIORITY_PKTQUEUE_INIT, \
{ PRIORITY_PKTQUEUE_NODE_INIT(0, NULL) }, \
NULL, \
}
#elif ((GNRC_MAC_TX_QUEUE_SIZE == 0) && (CONFIG_GNRC_MAC_NEIGHBOR_COUNT != 0)) || defined(DOXYGEN)
#define GNRC_MAC_TX_INIT { \
{ GNRC_MAC_TX_NEIGHBOR_INIT }, \
NULL, \
}
#endif /* ((GNRC_MAC_TX_QUEUE_SIZE != 0) && (CONFIG_GNRC_MAC_NEIGHBOR_COUNT != 0)) || defined(DOXYGEN) */
#endif /* ((GNRC_MAC_TX_QUEUE_SIZE != 0) || (CONFIG_GNRC_MAC_NEIGHBOR_COUNT != 0)) || defined(DOXYGEN) */
#ifdef __cplusplus
}
#endif
/** @} */

View File

@ -56,9 +56,6 @@
#if IS_USED(MODULE_GNRC_NETIF_IPV6)
#include "net/gnrc/netif/ipv6.h"
#endif
#if IS_USED(MODULE_GNRC_NETIF_MAC)
#include "net/gnrc/netif/mac.h"
#endif
#if IS_USED(MODULE_GNRC_NETIF_PKTQ)
#include "net/gnrc/netif/pktq/type.h"
#endif
@ -146,9 +143,6 @@ typedef struct {
#if IS_USED(MODULE_GNRC_NETIF_IPV6) || defined(DOXYGEN)
gnrc_netif_ipv6_t ipv6; /**< IPv6 component */
#endif
#if IS_USED(MODULE_GNRC_NETIF_MAC) || defined(DOXYGEN)
gnrc_netif_mac_t mac; /**< @ref net_gnrc_mac component */
#endif /* IS_USED(MODULE_GNRC_NETIF_MAC) || defined(DOXYGEN) */
#if IS_USED(MODULE_GNRC_NETIF_BUS) || DOXYGEN
msg_bus_t bus[GNRC_NETIF_BUS_NUMOF]; /**< Event Message Bus */
#endif

View File

@ -1,88 +0,0 @@
/*
* Copyright (C) 2017 Freie Universität Berlin
*
* 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.
*/
#pragma once
/**
* @ingroup net_gnrc_netif
* @{
*
* @file
* @brief @ref net_gnrc_mac definitions for @ref net_gnrc_netif
*
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
*/
#include "net/gnrc/mac/types.h"
#include "net/csma_sender.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Mask for @ref gnrc_mac_tx_feedback_t
*/
#define GNRC_NETIF_MAC_INFO_TX_FEEDBACK_MASK (0x0003U)
/**
* @brief Flag to track if a transmission might have corrupted a received
* packet
*/
#define GNRC_NETIF_MAC_INFO_RX_STARTED (0x0004U)
/**
* @brief Flag to track if a device has enabled CSMA for transmissions
*
* In case the device doesn't support on-chip CSMA and this flag is set for
* requiring CSMA transmission, then, the device will run software CSMA
* using `csma_sender` APIs.
*/
#define GNRC_NETIF_MAC_INFO_CSMA_ENABLED (0x0100U)
/**
* @brief @ref net_gnrc_mac component of @ref gnrc_netif_mac_t
*/
typedef struct {
/**
* @brief general information for the MAC protocol
*/
uint16_t mac_info;
/**
* @brief device's software CSMA configuration
*/
csma_sender_conf_t csma_conf;
#if ((GNRC_MAC_RX_QUEUE_SIZE != 0) || (GNRC_MAC_DISPATCH_BUFFER_SIZE != 0)) || DOXYGEN
/**
* @brief MAC internal object which stores reception parameters, queues, and
* state machines.
*
* @note Only available if @ref GNRC_MAC_RX_QUEUE_SIZE or
* @ref GNRC_MAC_DISPATCH_BUFFER_SIZE is greater than 0.
*/
gnrc_mac_rx_t rx;
#endif /* ((GNRC_MAC_RX_QUEUE_SIZE != 0) || (GNRC_MAC_DISPATCH_BUFFER_SIZE != 0)) || DOXYGEN */
#if ((GNRC_MAC_TX_QUEUE_SIZE != 0) || (CONFIG_GNRC_MAC_NEIGHBOR_COUNT != 0)) || DOXYGEN
/**
* @brief MAC internal object which stores transmission parameters, queues, and
* state machines.
*
* @note Only available if @ref GNRC_MAC_TX_QUEUE_SIZE or
* @ref CONFIG_GNRC_MAC_NEIGHBOR_COUNT is greater than 0.
*/
gnrc_mac_tx_t tx;
#endif /* ((GNRC_MAC_TX_QUEUE_SIZE != 0) || (CONFIG_GNRC_MAC_NEIGHBOR_COUNT == 0)) || DOXYGEN */
} gnrc_netif_mac_t;
#ifdef __cplusplus
}
#endif
/** @} */

View File

@ -9,7 +9,6 @@ menu "GNRC Network stack"
rsource "application_layer/dhcpv6/Kconfig"
rsource "link_layer/lorawan/Kconfig"
rsource "link_layer/mac/Kconfig"
rsource "netif/Kconfig"
rsource "network_layer/ipv6/Kconfig"
rsource "network_layer/sixlowpan/Kconfig"

View File

@ -49,9 +49,6 @@ endif
ifneq (,$(filter gnrc_netreg,$(USEMODULE)))
DIRS += netreg
endif
ifneq (,$(filter gnrc_mac,$(USEMODULE)))
DIRS += link_layer/mac
endif
ifneq (,$(filter gnrc_pkt,$(USEMODULE)))
DIRS += pkt
endif

View File

@ -10,15 +10,6 @@ ifneq (,$(filter sock_async,$(USEMODULE)))
USEMODULE += gnrc_sock_async
endif
ifneq (,$(filter gnrc_mac,$(USEMODULE)))
USEMODULE += gnrc_priority_pktqueue
USEMODULE += csma_sender
USEMODULE += evtimer
ifneq (,$(filter gnrc_netif,$(USEMODULE)))
USEMODULE += gnrc_netif_mac
endif
endif
ifneq (,$(filter gnrc_lorawan,$(USEMODULE)))
USEMODULE += ztimer_msec
USEMODULE += random

View File

@ -1,42 +0,0 @@
# Copyright (c) 2020 Freie Universitaet Berlin
#
# 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.
#
menu "GNRC MAC"
depends on USEMODULE_GNRC_MAC
config GNRC_MAC_RX_QUEUE_SIZE_EXP
int "Exponent for the RX queue size (resulting in the queue size 2^n)"
default 3
help
As the queue size ALWAYS needs to be power of two, this option
represents the exponent of 2^n, which will be used as the size of the RX
queue for incoming packets.
config GNRC_MAC_DISPATCH_BUFFER_SIZE_EXP
int "Exponent for the dispatch buffer size (resulting in the buffer size 2^n)"
default 3
help
As the buffer size ALWAYS needs to be power of two, this option
represents the exponent of 2^n, which will be used as the size of the
dispatch buffer for storing dispatching packets.
config GNRC_MAC_NEIGHBOR_COUNT
int "Count of neighbor nodes in one-hop distance"
default 8
config GNRC_MAC_TX_QUEUE_SIZE_EXP
int "Exponent for the TX queue size (resulting in the queue size 2^n)"
default 3
help
As the queue size ALWAYS needs to be power of two, this option
represents the exponent of 2^n, which will be used as the size of the TX
queue for transmission packets coming from higher layers.
config GNRC_MAC_DISABLE_DUTYCYCLE_RECORD
bool "Disable MAC radio duty-cycle recording and displaying"
endmenu # GNRC MAC

View File

@ -1,3 +0,0 @@
MODULE = gnrc_mac
include $(RIOTBASE)/Makefile.base

View File

@ -1,255 +0,0 @@
/*
* Copyright (C) 2015 Daniel Krebs
* 2016 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_mac
* @{
*
* @file
* @brief Implementation of internal functions of GNRC_MAC
*
* @author Daniel Krebs <github@daniel-krebs.net>
* @author Shuguo Zhuo <shuguo.zhuo@inria.fr>
* @}
*/
#include <assert.h>
#include <stdbool.h>
#include "net/gnrc.h"
#include "net/gnrc/mac/internal.h"
#define ENABLE_DEBUG 0
#include "debug.h"
#if ((GNRC_MAC_TX_QUEUE_SIZE != 0) || (GNRC_MAC_RX_QUEUE_SIZE != 0))
gnrc_priority_pktqueue_node_t *_alloc_pktqueue_node(gnrc_priority_pktqueue_node_t *nodes,
uint32_t size)
{
assert(nodes != NULL);
assert(size > 0);
/* search for free packet_queue_node */
for (size_t i = 0; i < size; i++) {
if ((nodes[i].pkt == NULL) &&
(nodes[i].next == NULL)) {
return &nodes[i];
}
}
return NULL;
}
#endif /* ((GNRC_MAC_TX_QUEUE_SIZE != 0) || (GNRC_MAC_RX_QUEUE_SIZE != 0)) */
#if GNRC_MAC_TX_QUEUE_SIZE != 0
#if CONFIG_GNRC_MAC_NEIGHBOR_COUNT != 0
/* Find the neighbor's id based on the given address */
int _gnrc_mac_find_neighbor(gnrc_mac_tx_t *tx, const uint8_t *dst_addr, int addr_len)
{
assert(tx != NULL);
assert(dst_addr != NULL);
assert(addr_len > 0);
gnrc_mac_tx_neighbor_t *neighbors;
neighbors = tx->neighbors;
/* Don't attempt to find broadcast neighbor, so start at index 1 */
for (int i = 1; i <= (signed)CONFIG_GNRC_MAC_NEIGHBOR_COUNT; i++) {
if (neighbors[i].l2_addr_len == addr_len) {
if (memcmp(&(neighbors[i].l2_addr), dst_addr, addr_len) == 0) {
return i;
}
}
}
return -ENOENT;
}
/* Free first empty queue (neighbor) that is not active */
int _gnrc_mac_free_neighbor(gnrc_mac_tx_t *tx)
{
assert(tx != NULL);
gnrc_mac_tx_neighbor_t *neighbors;
neighbors = tx->neighbors;
/* Don't attempt to free broadcast neighbor, so start at index 1 */
for (int i = 1; i <= (signed)CONFIG_GNRC_MAC_NEIGHBOR_COUNT; i++) {
if ((gnrc_priority_pktqueue_length(&(neighbors[i].queue)) == 0) &&
(&neighbors[i] != tx->current_neighbor)) {
/* Mark as free */
neighbors[i].l2_addr_len = 0;
return i;
}
}
return -ENOSPC;
}
/* Allocate first unused queue (neighbor) */
int _gnrc_mac_alloc_neighbor(gnrc_mac_tx_t *tx)
{
assert(tx != NULL);
gnrc_mac_tx_neighbor_t *neighbors;
neighbors = tx->neighbors;
/* Don't attempt to allocate broadcast neighbor, so start at index 1 */
for (int i = 1; i <= (signed)CONFIG_GNRC_MAC_NEIGHBOR_COUNT; i++) {
if (neighbors[i].l2_addr_len == 0) {
gnrc_priority_pktqueue_init(&(neighbors[i].queue));
return i;
}
}
return -ENOSPC;
}
/* Initialize the neighbor */
void _gnrc_mac_init_neighbor(gnrc_mac_tx_neighbor_t *neighbor, const uint8_t *addr, int len)
{
assert(neighbor != NULL);
assert(addr != NULL);
assert(len > 0);
neighbor->l2_addr_len = len;
neighbor->phase = GNRC_MAC_PHASE_MAX;
memcpy(&(neighbor->l2_addr), addr, len);
}
#endif /* CONFIG_GNRC_MAC_NEIGHBOR_COUNT != 0 */
bool gnrc_mac_queue_tx_packet(gnrc_mac_tx_t *tx, uint32_t priority, gnrc_pktsnip_t *pkt)
{
assert(tx != NULL);
assert(pkt != NULL);
#if CONFIG_GNRC_MAC_NEIGHBOR_COUNT == 0
gnrc_priority_pktqueue_node_t *node;
node = _alloc_pktqueue_node(tx->_queue_nodes, GNRC_MAC_TX_QUEUE_SIZE);
if (node) {
gnrc_priority_pktqueue_node_init(node, priority, pkt);
gnrc_priority_pktqueue_push(&tx->queue, node);
return true;
}
DEBUG("[gnrc_mac-int] Can't push to TX queue, no entries left\n");
return false;
#else
gnrc_mac_tx_neighbor_t *neighbor;
int neighbor_id;
/* Check whether the packet it for broadcast or multicast */
if (gnrc_netif_hdr_get_flag(pkt) &
(GNRC_NETIF_HDR_FLAGS_MULTICAST | GNRC_NETIF_HDR_FLAGS_BROADCAST)) {
/* Broadcast/multicast queue is neighbor 0 by definition */
neighbor_id = 0;
neighbor = &tx->neighbors[neighbor_id];
}
else {
uint8_t *addr;
int addr_len;
bool neighbor_known = true;
/* Get destination address of packet */
addr_len = gnrc_netif_hdr_get_dstaddr(pkt, &addr);
if (addr_len <= 0) {
DEBUG("[gnrc_mac-int] Packet has no destination address\n");
return false;
}
/* Search for existing queue for destination */
neighbor_id = _gnrc_mac_find_neighbor(tx, addr, addr_len);
/* neighbor node doesn't have a queue yet */
if (neighbor_id < 0) {
neighbor_known = false;
/* Try to allocate neighbor entry */
neighbor_id = _gnrc_mac_alloc_neighbor(tx);
/* No neighbor entries left */
if (neighbor_id < 0) {
DEBUG("[gnrc_mac-int] No neighbor entries left, maybe increase "
"CONFIG_GNRC_MAC_NEIGHBOR_COUNT for better performance\n");
/* Try to free an unused queue */
neighbor_id = _gnrc_mac_free_neighbor(tx);
/* All queues are in use, so reject */
if (neighbor_id < 0) {
DEBUG("[gnrc_mac-int] Couldn't allocate tx queue for packet\n");
return false;
}
}
}
neighbor = &tx->neighbors[neighbor_id];
if (!neighbor_known) {
_gnrc_mac_init_neighbor(neighbor, addr, addr_len);
}
}
gnrc_priority_pktqueue_node_t *node;
node = _alloc_pktqueue_node(tx->_queue_nodes, GNRC_MAC_TX_QUEUE_SIZE);
if (node) {
gnrc_priority_pktqueue_node_init(node, priority, pkt);
gnrc_priority_pktqueue_push(&neighbor->queue, node);
DEBUG("[gnrc_mac-int] Queuing pkt to neighbor #%d\n", neighbor_id);
return true;
}
DEBUG("[gnrc_mac-int] Can't push to neighbor #%d's queue, no entries left\n",
neighbor_id);
return false;
#endif /* CONFIG_GNRC_MAC_NEIGHBOR_COUNT == 0 */
}
#endif /* GNRC_MAC_TX_QUEUE_SIZE != 0 */
#if GNRC_MAC_RX_QUEUE_SIZE != 0
bool gnrc_mac_queue_rx_packet(gnrc_mac_rx_t *rx, uint32_t priority, gnrc_pktsnip_t *pkt)
{
assert(rx != NULL);
assert(pkt != NULL);
gnrc_priority_pktqueue_node_t *node;
node = _alloc_pktqueue_node(rx->_queue_nodes, GNRC_MAC_RX_QUEUE_SIZE);
if (node) {
gnrc_priority_pktqueue_node_init(node, priority, pkt);
gnrc_priority_pktqueue_push(&rx->queue, node);
return true;
}
DEBUG("[gnrc_mac] Can't push RX packet @ %p, no entries left\n", (void*)pkt);
return false;
}
#endif /* GNRC_MAC_RX_QUEUE_SIZE != 0 */
#if GNRC_MAC_DISPATCH_BUFFER_SIZE != 0
void gnrc_mac_dispatch(gnrc_mac_rx_t *rx)
{
assert(rx != NULL);
for (unsigned i = 0; i < GNRC_MAC_DISPATCH_BUFFER_SIZE; i++) {
if (rx->dispatch_buffer[i]) {
if (!gnrc_netapi_dispatch_receive(rx->dispatch_buffer[i]->type,
GNRC_NETREG_DEMUX_CTX_ALL,
rx->dispatch_buffer[i])) {
DEBUG("Unable to forward packet of type %i\n", rx->dispatch_buffer[i]->type);
gnrc_pktbuf_release(rx->dispatch_buffer[i]);
}
rx->dispatch_buffer[i] = NULL;
}
}
}
#endif /* GNRC_MAC_DISPATCH_BUFFER_SIZE != 0 */

View File

@ -1,148 +0,0 @@
/*
* Copyright (C) 2015 Daniel Krebs
* 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_mac
* @{
*
* @file
* @brief Implementation of timeout module of GNRC_MAC
*
* @author Daniel Krebs <github@daniel-krebs.net>
* @author Shuguo Zhuo <shuguo.zhuo@inria.fr>
* @}
*/
#include <assert.h>
#include "net/gnrc.h"
#include "net/gnrc/mac/timeout.h"
#define ENABLE_DEBUG 0
#include "debug.h"
void gnrc_mac_init_timeouts(gnrc_mac_timeout_t *mac_timeout,
gnrc_mac_timeout_event_t timeouts[],
uint8_t num)
{
assert(mac_timeout);
assert(timeouts);
assert(num);
mac_timeout->timeouts = timeouts;
mac_timeout->timeout_num = num;
for (int i = 0; i < mac_timeout->timeout_num; i++) {
mac_timeout->timeouts[i].msg_event.event.next = NULL;
mac_timeout->timeouts[i].type = GNRC_MAC_TIMEOUT_DISABLED;
}
evtimer_init_msg(&mac_timeout->evtimer);
}
int gnrc_mac_find_timeout(gnrc_mac_timeout_t *mac_timeout, gnrc_mac_timeout_type_t type)
{
assert(mac_timeout);
assert(mac_timeout->timeout_num);
for (unsigned i = 0; i < mac_timeout->timeout_num; i++) {
if (mac_timeout->timeouts[i].type == type) {
return i;
}
}
return -ENOENT;
}
gnrc_mac_timeout_event_t *_gnrc_mac_acquire_timeout(gnrc_mac_timeout_t *mac_timeout,
gnrc_mac_timeout_type_t type)
{
assert(mac_timeout);
assert(mac_timeout->timeout_num);
if (gnrc_mac_timeout_is_running(mac_timeout, type)) {
return NULL;
}
for (unsigned i = 0; i < mac_timeout->timeout_num; i++) {
if (mac_timeout->timeouts[i].type == GNRC_MAC_TIMEOUT_DISABLED) {
mac_timeout->timeouts[i].type = type;
return &mac_timeout->timeouts[i];
}
}
return NULL;
}
void gnrc_mac_set_timeout(gnrc_mac_timeout_t *mac_timeout, gnrc_mac_timeout_type_t type,
uint32_t offset, kernel_pid_t pid)
{
assert(mac_timeout);
gnrc_mac_timeout_event_t *timeout_event;
if ((timeout_event = _gnrc_mac_acquire_timeout(mac_timeout, type))) {
DEBUG("[gnrc_mac] Set timeout type-%d in %" PRIu32 " us\n",
type, offset);
timeout_event->msg_event.event.offset = offset;
timeout_event->msg_event.msg.type = GNRC_MAC_EVENT_TIMEOUT_TYPE;
timeout_event->msg_event.msg.content.ptr = (void *) timeout_event;
timeout_event->msg_event.msg.sender_pid = pid;
evtimer_add(&mac_timeout->evtimer, &timeout_event->msg_event.event);
}
else {
DEBUG("[gnrc_mac] Cannot set timeout type-%d, too many concurrent timeouts\n",
type);
}
}
void gnrc_mac_clear_timeout(gnrc_mac_timeout_t *mac_timeout, gnrc_mac_timeout_type_t type)
{
assert(mac_timeout);
int index = gnrc_mac_find_timeout(mac_timeout, type);
if (index >= 0) {
mac_timeout->timeouts[index].type = GNRC_MAC_TIMEOUT_DISABLED;
evtimer_del(&mac_timeout->evtimer,
&mac_timeout->timeouts[index].msg_event.event);
}
}
bool gnrc_mac_timeout_is_expired(gnrc_mac_timeout_t *mac_timeout, gnrc_mac_timeout_type_t type)
{
assert(mac_timeout);
int index = gnrc_mac_find_timeout(mac_timeout, type);
if (index >= 0) {
evtimer_event_t *list;
list = (evtimer_event_t *)&mac_timeout->evtimer.events;
while (list->next) {
if (list->next == &mac_timeout->timeouts[index].msg_event.event) {
return false;
}
list = list->next;
}
/* if we reach here, timeout is expired */
mac_timeout->timeouts[index].type = GNRC_MAC_TIMEOUT_DISABLED;
return true;
}
return false;
}
void gnrc_mac_reset_timeouts(gnrc_mac_timeout_t *mac_timeout)
{
assert(mac_timeout);
assert(mac_timeout->timeout_num);
for (unsigned i = 0; i < mac_timeout->timeout_num; i++) {
if (mac_timeout->timeouts[i].type != GNRC_MAC_TIMEOUT_DISABLED) {
mac_timeout->timeouts[i].type = GNRC_MAC_TIMEOUT_DISABLED;
evtimer_del(&mac_timeout->evtimer,
&mac_timeout->timeouts[i].msg_event.event);
}
}
}

View File

@ -387,16 +387,7 @@ static int _send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt)
netif->stats.tx_unicast_count++;
}
#endif
#ifdef MODULE_GNRC_MAC
if (netif->mac.mac_info & GNRC_NETIF_MAC_INFO_CSMA_ENABLED) {
res = csma_sender_csma_ca_send(dev, &iolist_header, &netif->mac.csma_conf);
}
else {
res = dev->driver->send(dev, &iolist_header);
}
#else
res = dev->driver->send(dev, &iolist_header);
#endif
if (gnrc_netif_netdev_legacy_api(netif)) {
/* only for legacy drivers we need to release pkt here */

View File

@ -1,6 +0,0 @@
include ../Makefile.net_common
USEMODULE += ztimer_msec
USEMODULE += gnrc_mac
include $(RIOTBASE)/Makefile.include

View File

@ -1,26 +0,0 @@
BOARD_INSUFFICIENT_MEMORY := \
arduino-duemilanove \
arduino-leonardo \
arduino-mega2560 \
arduino-nano \
arduino-uno \
atmega328p \
atmega328p-xplained-mini \
atmega8 \
bluepill-stm32f030c8 \
i-nucleo-lrwan1 \
nucleo-f030r8 \
nucleo-f031k6 \
nucleo-f042k6 \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
samd10-xmini \
slstk3400a \
stk3200 \
stm32f030f4-demo \
stm32f0discovery \
stm32g0316-disco \
stm32l0538-disco \
weact-g030f6 \
#

View File

@ -1,14 +0,0 @@
Expected result
===============
This is a test application for using the timeout module of gnrc_mac for setting timeouts.
When everything works as expected, you should see timeouts expired at the time they are set
to be expired. Also, you should see the status of timeouts are corresponding to their real
status, i.e., the system should state that a timeout is "running" when it is set and
awaiting to be expired, and state "not running" when a timeout has expired and not set
again.
Background
==========
Test for verifying the functionalities of the timeout module of gnrc_mac.

View File

@ -1,117 +0,0 @@
/*
* 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 gnrc_mac timeout test application
*
* @author Shuguo Zhuo <shuguo.zhuo@inria.fr>
*
* @}
*/
#include <stdio.h>
#include "net/gnrc/mac/timeout.h"
#include "thread.h"
#include "msg.h"
#include "ztimer.h"
#define TIMEOUT_COUNT 3
#define TIMEOUT_1_DURATION 1000
#define TIMEOUT_2_DURATION 2538
#define TIMEOUT_3_DURATION 3471
static gnrc_mac_timeout_t mac_timeout;
static gnrc_mac_timeout_event_t test_timeouts[TIMEOUT_COUNT];
static gnrc_mac_timeout_type_t timeout_1;
static gnrc_mac_timeout_type_t timeout_2;
static gnrc_mac_timeout_type_t timeout_3;
static ztimer_now_t start_time;
static char worker_stack[THREAD_STACKSIZE_MAIN];
/* This thread will print the drift to stdout once per second */
void *worker_thread(void *arg)
{
int count = 1;
(void) arg;
while (1) {
msg_t m;
ztimer_now_t now;
msg_receive(&m);
now = ztimer_now(ZTIMER_MSEC);
if (gnrc_mac_timeout_is_expired(&mac_timeout, timeout_1)) {
printf("At %6" PRIu32 " ms received msg %i: timeout_1 (set at %" PRIu32 " ms) expired, "
"supposed to be %" PRIu32 " ms!\n", now, count++, start_time, (TIMEOUT_1_DURATION + start_time));
}
if (gnrc_mac_timeout_is_expired(&mac_timeout, timeout_2)) {
printf("At %6" PRIu32 " ms received msg %i: timeout_2 (set at %" PRIu32 " ms) expired, "
"supposed to be %" PRIu32 " ms!\n", now, count++, start_time, (TIMEOUT_2_DURATION + start_time));
}
if (gnrc_mac_timeout_is_expired(&mac_timeout, timeout_3)) {
printf("At %6" PRIu32 " ms received msg %i: timeout_3 (set at %" PRIu32 " ms) expired, "
"supposed to be %" PRIu32 " ms!\n", now, count++, start_time, (TIMEOUT_3_DURATION + start_time));
}
if (gnrc_mac_timeout_is_running(&mac_timeout, timeout_1)) {
printf("At %6" PRIu32 " ms: timeout_1 is running.\n", now);
}
else {
printf("At %6" PRIu32 " ms: timeout_1 is not running.\n", now);
}
if (gnrc_mac_timeout_is_running(&mac_timeout, timeout_2)) {
printf("At %6" PRIu32 " ms: timeout_2 is running.\n", now);
}
else {
printf("At %6" PRIu32 " ms: timeout_2 is not running.\n", now);
}
if (gnrc_mac_timeout_is_running(&mac_timeout, timeout_3)) {
printf("At %6" PRIu32 " ms: timeout_3 is running.\n", now);
}
else {
printf("At %6" PRIu32 " ms: timeout_3 is not running.\n", now);
}
}
}
int main(void)
{
/* create worker thread */
kernel_pid_t pid = thread_create(worker_stack, sizeof(worker_stack),
THREAD_PRIORITY_MAIN - 1,
0,
worker_thread, NULL, "worker");
timeout_1 = -1;
timeout_2 = -2;
timeout_3 = -3;
start_time = ztimer_now(ZTIMER_MSEC);
gnrc_mac_init_timeouts(&mac_timeout, test_timeouts, TIMEOUT_COUNT);
gnrc_mac_set_timeout(&mac_timeout, timeout_1, TIMEOUT_1_DURATION, pid);
gnrc_mac_set_timeout(&mac_timeout, timeout_2, TIMEOUT_2_DURATION, pid);
gnrc_mac_set_timeout(&mac_timeout, timeout_3, TIMEOUT_3_DURATION, pid);
printf("Testing gnrc_mac timeout module (start time = %" PRIu32 " ms)\n", start_time);
printf("Set timeout_1, should be expired at %" PRIu32 " ms)\n", TIMEOUT_1_DURATION + start_time);
printf("Set timeout_2, should be expired at %" PRIu32 " ms)\n", TIMEOUT_2_DURATION + start_time);
printf("Set timeout_3, should be expired at %" PRIu32 " ms)\n", TIMEOUT_3_DURATION + start_time);
puts("Are the reception times of all 3 msgs close to the supposed values?\n");
puts("If yes, the tests were successful");
}

View File

@ -1,61 +0,0 @@
#!/usr/bin/env python3
# Copyright (C) 2023 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.
import sys
from testrunner import run
ERROR_MS = 50 # This is large enough to pass the test on IoT-LAB nrf52dk
def testfunc(child):
child.expect(r"Testing gnrc_mac timeout module \(start time = (\d+) ms\)")
start = int(child.match.group(1))
child.expect(r"Set timeout_1, should be expired at (\d+) ms\)")
timeout_1 = int(child.match.group(1))
child.expect(r"Set timeout_2, should be expired at (\d+) ms\)")
timeout_2 = int(child.match.group(1))
child.expect(r"Set timeout_3, should be expired at (\d+) ms\)")
timeout_3 = int(child.match.group(1))
child.expect_exact("Are the reception times of all 3 msgs close to the supposed values?")
child.expect_exact("If yes, the tests were successful")
child.expect(
r"At (\d+) ms received msg 1: "
r"timeout_1 \(set at {start} ms\) expired, supposed to be {timeout_1} ms\!"
.format(start=start, timeout_1=timeout_1)
)
timeout_1_measured = int(child.match.group(1))
assert timeout_1_measured - timeout_1 < ERROR_MS
child.expect_exact(f"At {timeout_1_measured} ms: timeout_1 is not running.")
child.expect_exact(f"At {timeout_1_measured} ms: timeout_2 is running.")
child.expect_exact(f"At {timeout_1_measured} ms: timeout_3 is running.")
child.expect(
r"At (\d+) ms received msg 2: "
r"timeout_2 \(set at {start} ms\) expired, supposed to be {timeout_2} ms\!"
.format(start=start, timeout_2=timeout_2)
)
timeout_2_measured = int(child.match.group(1))
assert timeout_2_measured - timeout_2 < ERROR_MS
child.expect_exact(f"At {timeout_2_measured} ms: timeout_1 is not running.")
child.expect_exact(f"At {timeout_2_measured} ms: timeout_2 is not running.")
child.expect_exact(f"At {timeout_2_measured} ms: timeout_3 is running.")
child.expect(
r"At (\d+) ms received msg 3: "
r"timeout_3 \(set at {start} ms\) expired, supposed to be {timeout_3} ms\!"
.format(start=start, timeout_3=timeout_3)
)
timeout_3_measured = int(child.match.group(1))
assert timeout_3_measured - timeout_3 < ERROR_MS
child.expect_exact(f"At {timeout_3_measured} ms: timeout_1 is not running.")
child.expect_exact(f"At {timeout_3_measured} ms: timeout_2 is not running.")
child.expect_exact(f"At {timeout_3_measured} ms: timeout_3 is not running.")
if __name__ == "__main__":
sys.exit(run(testfunc))

View File

@ -1 +0,0 @@
include $(RIOTBASE)/Makefile.base

View File

@ -1,5 +0,0 @@
USEMODULE += gnrc_priority_pktqueue
USEMODULE += gnrc_mac
# Set CFLAGS if not being set via Kconfig
CFLAGS += $(if $(CONFIG_KCONFIG_MODULE_GNRC_MAC),,-DGNRC_MAC_TX_QUEUE_SIZE=4 -DCONFIG_GNRC_MAC_NEIGHBOR_COUNT=4)

View File

@ -1,284 +0,0 @@
/*
* Copyright (C) 2016, 2016 Shuguo Zhuo <shuguo.zhuo@inria.fr>
*
* 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.
*/
/**
* @{
*
* @file
*/
#include <string.h>
#include "embUnit.h"
#include "net/gnrc/pktbuf.h"
#include "net/gnrc/netif/hdr.h"
#include "net/gnrc/mac/internal.h"
#include "unittests-constants.h"
#include "tests-gnrc_mac_internal.h"
static void set_up(void)
{
gnrc_pktbuf_init();
}
#if GNRC_MAC_TX_QUEUE_SIZE != 0
/**
* @brief This function test the `gnrc_mac_queue_tx_packet()`, to see whether it can
* correctly queue the packet to the corresponded priority packet queue.
*
* In case when the `gnrc_mac_tx_neighbor_t` structure is in used (indicated by
* by `CONFIG_GNRC_MAC_NEIGHBOR_COUNT != 0`), `test_gnrc_mac_queue_tx_packet()` successively
* queues 4 packets, which are pkt1, pkt2, pkt3 and pkt_bcast, into a defined `tx`
* (type of `gnrc_mac_tx_t`). Pkt1, pkt2 have the same destination address of "0x76b6",
* , pkt3 is heading for "0x447e", while pkt_bcast is for broadcasting.
* Expected results: pkt1 and pkt2 should be queued to `tx::neighbors[1]::queue`,
* pkt3 should be queued to `tx::neighbors[2]::queue`, while pkt_bcast should be
* queued to `tx::neighbors[0]::queue`.
*
* In case when the `gnrc_mac_tx_neighbor_t` structure is not in used (indicated by
* by `CONFIG_GNRC_MAC_NEIGHBOR_COUNT == 0`), `test_gnrc_mac_queue_tx_packet()` successively
* queues 4 packets, which are pkt1, pkt2, pkt3 and pkt_bcast, into a defined `tx`
* (type of `gnrc_mac_tx_t`). Pkt1, pkt2 have the same destination address of "0x76b6",
* , pkt3 is heading for "0x447e", while pkt_bcast is for broadcasting.
* Expected results: all packets should be queued to `tx::queue`, and ranking in
* `tx::queue` according to their priorities.
*
*/
static void test_gnrc_mac_queue_tx_packet(void)
{
gnrc_mac_tx_t tx = GNRC_MAC_TX_INIT;
gnrc_pktsnip_t *hdr;
gnrc_netif_hdr_t* netif_hdr;
uint8_t dst_addr[2];
dst_addr[0] = 0x76;
dst_addr[1] = 0xb6;
hdr = gnrc_netif_hdr_build(NULL, 0, NULL, 0);
gnrc_pktsnip_t *pkt_bcast = gnrc_pktbuf_add(NULL, TEST_STRING12, sizeof(TEST_STRING12),
GNRC_NETTYPE_UNDEF);
hdr = gnrc_pkt_append(hdr, pkt_bcast);
pkt_bcast = hdr;
netif_hdr = hdr->data;
netif_hdr->flags |= GNRC_NETIF_HDR_FLAGS_BROADCAST;
hdr = gnrc_netif_hdr_build(NULL, 0, dst_addr, 2);
gnrc_pktsnip_t *pkt1 = gnrc_pktbuf_add(NULL, TEST_STRING4, sizeof(TEST_STRING4),
GNRC_NETTYPE_UNDEF);
hdr = gnrc_pkt_append(hdr, pkt1);
pkt1 = hdr;
hdr = gnrc_netif_hdr_build(NULL, 0, dst_addr, 2);
gnrc_pktsnip_t *pkt2 = gnrc_pktbuf_add(NULL, TEST_STRING8, sizeof(TEST_STRING8),
GNRC_NETTYPE_UNDEF);
hdr = gnrc_pkt_append(hdr, pkt2);
pkt2 = hdr;
dst_addr[0] = 0x44;
dst_addr[1] = 0x7e;
hdr = gnrc_netif_hdr_build(NULL, 0, dst_addr, 2);
gnrc_pktsnip_t *pkt3 = gnrc_pktbuf_add(NULL, TEST_STRING16, sizeof(TEST_STRING16),
GNRC_NETTYPE_UNDEF);
hdr = gnrc_pkt_append(hdr, pkt3);
pkt3 = hdr;
#if CONFIG_GNRC_MAC_NEIGHBOR_COUNT != 0
gnrc_pktsnip_t *pkt_head;
TEST_ASSERT(gnrc_mac_queue_tx_packet(&tx, 1, pkt1));
pkt_head = gnrc_priority_pktqueue_head(&tx.neighbors[1].queue);
TEST_ASSERT(pkt_head == pkt1);
TEST_ASSERT(1 == gnrc_priority_pktqueue_length(&tx.neighbors[1].queue));
TEST_ASSERT_EQUAL_STRING(TEST_STRING4, pkt_head->next->data);
TEST_ASSERT(gnrc_mac_queue_tx_packet(&tx, 0, pkt2));
pkt_head = gnrc_priority_pktqueue_head(&tx.neighbors[1].queue);
TEST_ASSERT(pkt_head == pkt2);
TEST_ASSERT(2 == gnrc_priority_pktqueue_length(&tx.neighbors[1].queue));
TEST_ASSERT_EQUAL_STRING(TEST_STRING8, pkt_head->next->data);
pkt_head = gnrc_priority_pktqueue_pop(&tx.neighbors[1].queue);
TEST_ASSERT(pkt_head == pkt2);
TEST_ASSERT(1 == gnrc_priority_pktqueue_length(&tx.neighbors[1].queue));
TEST_ASSERT_EQUAL_STRING(TEST_STRING8, pkt_head->next->data);
pkt_head = gnrc_priority_pktqueue_head(&tx.neighbors[1].queue);
TEST_ASSERT(pkt_head == pkt1);
TEST_ASSERT_EQUAL_STRING(TEST_STRING4, pkt_head->next->data);
TEST_ASSERT(gnrc_mac_queue_tx_packet(&tx, 0, pkt3));
pkt_head = gnrc_priority_pktqueue_head(&tx.neighbors[2].queue);
TEST_ASSERT(pkt_head == pkt3);
TEST_ASSERT(1 == gnrc_priority_pktqueue_length(&tx.neighbors[2].queue));
TEST_ASSERT_EQUAL_STRING(TEST_STRING16, pkt_head->next->data);
TEST_ASSERT(gnrc_mac_queue_tx_packet(&tx, 0, pkt_bcast));
pkt_head = gnrc_priority_pktqueue_head(&tx.neighbors[0].queue);
TEST_ASSERT(pkt_head == pkt_bcast);
TEST_ASSERT(1 == gnrc_priority_pktqueue_length(&tx.neighbors[0].queue));
TEST_ASSERT_EQUAL_STRING(TEST_STRING12, pkt_head->next->data);
#else
TEST_ASSERT(gnrc_mac_queue_tx_packet(&tx, 1, pkt1));
TEST_ASSERT(1 == gnrc_priority_pktqueue_length(&tx.queue));
gnrc_pktsnip_t *pkt_head;
pkt_head = gnrc_priority_pktqueue_head(&tx.queue);
TEST_ASSERT(pkt_head == pkt1);
TEST_ASSERT_EQUAL_STRING(TEST_STRING4, pkt_head->next->data);
TEST_ASSERT(gnrc_mac_queue_tx_packet(&tx, 1, pkt2));
TEST_ASSERT(2 == gnrc_priority_pktqueue_length(&tx.queue));
pkt_head = gnrc_priority_pktqueue_head(&tx.queue);
TEST_ASSERT(pkt_head == pkt1);
TEST_ASSERT_EQUAL_STRING(TEST_STRING4, pkt_head->next->data);
TEST_ASSERT(gnrc_mac_queue_tx_packet(&tx, 0, pkt3));
TEST_ASSERT(3 == gnrc_priority_pktqueue_length(&tx.queue));
pkt_head = gnrc_priority_pktqueue_head(&tx.queue);
TEST_ASSERT(pkt_head == pkt3);
TEST_ASSERT_EQUAL_STRING(TEST_STRING16, pkt_head->next->data);
TEST_ASSERT(gnrc_mac_queue_tx_packet(&tx, 0, pkt_bcast));
TEST_ASSERT(4 == gnrc_priority_pktqueue_length(&tx.queue));
pkt_head = gnrc_priority_pktqueue_head(&tx.queue);
TEST_ASSERT(pkt_head == pkt3);
pkt_head = gnrc_priority_pktqueue_pop(&tx.queue);
TEST_ASSERT(pkt_head == pkt3);
TEST_ASSERT(3 == gnrc_priority_pktqueue_length(&tx.queue));
TEST_ASSERT_EQUAL_STRING(TEST_STRING16, pkt_head->next->data);
pkt_head = gnrc_priority_pktqueue_pop(&tx.queue);
TEST_ASSERT(pkt_head == pkt_bcast);
TEST_ASSERT(2 == gnrc_priority_pktqueue_length(&tx.queue));
TEST_ASSERT_EQUAL_STRING(TEST_STRING12, pkt_head->next->data);
pkt_head = gnrc_priority_pktqueue_pop(&tx.queue);
TEST_ASSERT(pkt_head == pkt1);
TEST_ASSERT(1 == gnrc_priority_pktqueue_length(&tx.queue));
TEST_ASSERT_EQUAL_STRING(TEST_STRING4, pkt_head->next->data);
pkt_head = gnrc_priority_pktqueue_pop(&tx.queue);
TEST_ASSERT(pkt_head == pkt2);
TEST_ASSERT(0 == gnrc_priority_pktqueue_length(&tx.queue));
TEST_ASSERT_EQUAL_STRING(TEST_STRING8, pkt_head->next->data);
#endif /* CONFIG_GNRC_MAC_NEIGHBOR_COUNT != 0 */
}
#endif /* GNRC_MAC_TX_QUEUE_SIZE != 0 */
#if GNRC_MAC_RX_QUEUE_SIZE != 0
/**
* @brief This function test the `gnrc_mac_queue_rx_packet()`, to see whether it can
* correctly queue the packets to `rx::queue` according to their priorities.
*
* `test_gnrc_mac_queue_tx_packet()` successively queues 3 packets, which are
* pkt1, pkt2, pkt3, into a defined `rx` (type of `gnrc_mac_rx_t`).
* Pkt1, pkt2 have the same priority of "1", while pkt3 has the priority of "0".
* Expected results: after all the packets are queued, in `rx::queue`, them should
* be ranked as (from high priority to low): pkt3, pkt1 and pkt2.
*
*/
static void test_gnrc_mac_queue_rx_packet(void)
{
gnrc_mac_rx_t rx = GNRC_MAC_RX_INIT;
gnrc_pktsnip_t *pkt1 = gnrc_pktbuf_add(NULL, TEST_STRING4, sizeof(TEST_STRING4),
GNRC_NETTYPE_UNDEF);
gnrc_pktsnip_t *pkt2 = gnrc_pktbuf_add(NULL, TEST_STRING8, sizeof(TEST_STRING8),
GNRC_NETTYPE_UNDEF);
gnrc_pktsnip_t *pkt3 = gnrc_pktbuf_add(NULL, TEST_STRING16, sizeof(TEST_STRING16),
GNRC_NETTYPE_UNDEF);
TEST_ASSERT(gnrc_mac_queue_rx_packet(&rx, 1, pkt1));
TEST_ASSERT(1 == gnrc_priority_pktqueue_length(&rx.queue));
gnrc_pktsnip_t *pkt_head;
pkt_head = gnrc_priority_pktqueue_head(&rx.queue);
TEST_ASSERT(pkt_head == pkt1);
TEST_ASSERT_EQUAL_STRING(TEST_STRING4, pkt_head->data);
TEST_ASSERT(gnrc_mac_queue_rx_packet(&rx, 1, pkt2));
TEST_ASSERT(2 == gnrc_priority_pktqueue_length(&rx.queue));
pkt_head = gnrc_priority_pktqueue_head(&rx.queue);
TEST_ASSERT(pkt_head == pkt1);
TEST_ASSERT_EQUAL_STRING(TEST_STRING4, pkt_head->data);
TEST_ASSERT(gnrc_mac_queue_rx_packet(&rx, 0, pkt3));
TEST_ASSERT(3 == gnrc_priority_pktqueue_length(&rx.queue));
pkt_head = gnrc_priority_pktqueue_head(&rx.queue);
TEST_ASSERT(pkt_head == pkt3);
TEST_ASSERT_EQUAL_STRING(TEST_STRING16, pkt_head->data);
pkt_head = gnrc_priority_pktqueue_pop(&rx.queue);
TEST_ASSERT(pkt_head == pkt3);
TEST_ASSERT(2 == gnrc_priority_pktqueue_length(&rx.queue));
TEST_ASSERT_EQUAL_STRING(TEST_STRING16, pkt_head->data);
pkt_head = gnrc_priority_pktqueue_pop(&rx.queue);
TEST_ASSERT(pkt_head == pkt1);
TEST_ASSERT(1 == gnrc_priority_pktqueue_length(&rx.queue));
TEST_ASSERT_EQUAL_STRING(TEST_STRING4, pkt_head->data);
pkt_head = gnrc_priority_pktqueue_pop(&rx.queue);
TEST_ASSERT(pkt_head == pkt2);
TEST_ASSERT(0 == gnrc_priority_pktqueue_length(&rx.queue));
TEST_ASSERT_EQUAL_STRING(TEST_STRING8, pkt_head->data);
}
#endif /* GNRC_MAC_RX_QUEUE_SIZE != 0 */
#if GNRC_MAC_DISPATCH_BUFFER_SIZE != 0
static void test_gnrc_mac_dispatch(void)
{
gnrc_mac_rx_t rx = GNRC_MAC_RX_INIT;
for (size_t i = 0; i < GNRC_MAC_DISPATCH_BUFFER_SIZE; i++) {
rx.dispatch_buffer[i] = gnrc_pktbuf_add(NULL, TEST_STRING4, sizeof(TEST_STRING4),
GNRC_NETTYPE_UNDEF);
}
gnrc_mac_dispatch(&rx);
for (size_t i = 0; i < GNRC_MAC_DISPATCH_BUFFER_SIZE; i++) {
TEST_ASSERT_NULL(rx.dispatch_buffer[i]);
}
}
#endif /* GNRC_MAC_DISPATCH_BUFFER_SIZE != 0 */
Test *tests_gnrc_mac_internal_tests(void)
{
EMB_UNIT_TESTFIXTURES(fixtures) {
#if GNRC_MAC_TX_QUEUE_SIZE != 0
new_TestFixture(test_gnrc_mac_queue_tx_packet),
#endif /* GNRC_MAC_TX_QUEUE_SIZE != 0 */
#if GNRC_MAC_RX_QUEUE_SIZE != 0
new_TestFixture(test_gnrc_mac_queue_rx_packet),
#endif /* GNRC_MAC_RX_QUEUE_SIZE != 0 */
#if GNRC_MAC_DISPATCH_BUFFER_SIZE != 0
new_TestFixture(test_gnrc_mac_dispatch),
#endif /* GNRC_MAC_DISPATCH_BUFFER_SIZE != 0 */
};
EMB_UNIT_TESTCALLER(gnrc_mac_internal_tests, set_up, NULL, fixtures);
return (Test *)&gnrc_mac_internal_tests;
}
void tests_gnrc_mac_internal(void)
{
TESTS_RUN(tests_gnrc_mac_internal_tests());
}
/** @} */

View File

@ -1,37 +0,0 @@
/*
* Copyright (C) 2016 Shuguo Zhuo <shuguo.zhuo@inria.fr>
*
* 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.
*/
/**
* @addtogroup unittests
* @{
*
* @file
* @brief Unittests for the ``gnrc_mac`` module
*
* @author Shuguo Zhuo <shuguo.zhuo@inria.fr>
*/
#ifndef TESTS_GNRC_MAC_INTERNAL_H
#define TESTS_GNRC_MAC_INTERNAL_H
#include "embUnit.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief The entry point of this test suite.
*/
void tests_gnrc_mac_internal(void);
#ifdef __cplusplus
}
#endif
#endif /* TESTS_GNRC_MAC_INTERNAL_H */
/** @} */