mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #7895 from zhuoshuguo/lwmac_port_to_netif2
gnrc_lwmac: port to gnrc_netif2
This commit is contained in:
commit
ea27fe34d1
@ -559,8 +559,8 @@ ifneq (,$(filter netstats_%, $(USEMODULE)))
|
||||
endif
|
||||
|
||||
ifneq (,$(filter gnrc_lwmac,$(USEMODULE)))
|
||||
USEMODULE += gnrc_netif2
|
||||
USEMODULE += gnrc_mac
|
||||
USEMODULE += gnrc_netdev
|
||||
FEATURES_REQUIRED += periph_rtt
|
||||
endif
|
||||
|
||||
|
@ -61,10 +61,17 @@ void auto_init_at86rf2xx(void)
|
||||
|
||||
at86rf2xx_setup(&at86rf2xx_devs[i], &at86rf2xx_params[i]);
|
||||
#ifdef MODULE_GNRC_NETIF2
|
||||
#ifdef MODULE_GNRC_LWMAC
|
||||
gnrc_netif2_lwmac_create(_at86rf2xx_stacks[i],
|
||||
AT86RF2XX_MAC_STACKSIZE,
|
||||
AT86RF2XX_MAC_PRIO, "at86rf2xx-lwmac",
|
||||
(netdev_t *)&at86rf2xx_devs[i]);
|
||||
#else
|
||||
gnrc_netif2_ieee802154_create(_at86rf2xx_stacks[i],
|
||||
AT86RF2XX_MAC_STACKSIZE,
|
||||
AT86RF2XX_MAC_PRIO, "at86rf2xx",
|
||||
(netdev_t *)&at86rf2xx_devs[i]);
|
||||
#endif
|
||||
#else
|
||||
int res = gnrc_netdev_ieee802154_init(&gnrc_adpt[i],
|
||||
(netdev_ieee802154_t *)&at86rf2xx_devs[i]);
|
||||
@ -73,19 +80,11 @@ void auto_init_at86rf2xx(void)
|
||||
LOG_ERROR("[auto_init_netif] error initializing at86rf2xx radio #%u\n", i);
|
||||
}
|
||||
else {
|
||||
#ifdef MODULE_GNRC_LWMAC
|
||||
gnrc_lwmac_init(_at86rf2xx_stacks[i],
|
||||
AT86RF2XX_MAC_STACKSIZE,
|
||||
AT86RF2XX_MAC_PRIO,
|
||||
"at86rf2xx-lwmac",
|
||||
&gnrc_adpt[i]);
|
||||
#else
|
||||
gnrc_netdev_init(_at86rf2xx_stacks[i],
|
||||
AT86RF2XX_MAC_STACKSIZE,
|
||||
AT86RF2XX_MAC_PRIO,
|
||||
"at86rf2xx",
|
||||
&gnrc_adpt[i]);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -59,8 +59,8 @@ extern "C" {
|
||||
* @brief LWMAC internal L2 address structure
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t addr[IEEE802154_LONG_ADDRESS_LEN]; /**< address of node */
|
||||
uint8_t len; /**< address */
|
||||
uint8_t addr[IEEE802154_LONG_ADDRESS_LEN]; /**< address of node */
|
||||
uint8_t len; /**< address */
|
||||
} gnrc_lwmac_l2_addr_t;
|
||||
|
||||
/**
|
||||
@ -79,25 +79,25 @@ typedef struct {
|
||||
* @brief LWMAC WR (wake-up request packet, i.e., preamble packet) frame
|
||||
*/
|
||||
typedef struct __attribute__((packed)) {
|
||||
gnrc_lwmac_hdr_t header; /**< WR packet header type */
|
||||
gnrc_lwmac_l2_addr_t dst_addr; /**< WR is broadcast, so destination address needed */
|
||||
gnrc_lwmac_hdr_t header; /**< WR packet header type */
|
||||
gnrc_lwmac_l2_addr_t dst_addr; /**< WR is broadcast, so destination address needed */
|
||||
} gnrc_lwmac_frame_wr_t;
|
||||
|
||||
/**
|
||||
* @brief LWMAC WA (wake-up answer packet, i.e., preamble-ACK packet) frame
|
||||
*/
|
||||
typedef struct __attribute__((packed)) {
|
||||
gnrc_lwmac_hdr_t header; /**< WA packet header type */
|
||||
gnrc_lwmac_l2_addr_t dst_addr; /**< WA is broadcast, so destination address needed */
|
||||
uint32_t current_phase; /**< Node's current phase value */
|
||||
gnrc_lwmac_hdr_t header; /**< WA packet header type */
|
||||
gnrc_lwmac_l2_addr_t dst_addr; /**< WA is broadcast, so destination address needed */
|
||||
uint32_t current_phase; /**< Node's current phase value */
|
||||
} gnrc_lwmac_frame_wa_t;
|
||||
|
||||
/**
|
||||
* @brief LWMAC broadcast data frame
|
||||
*/
|
||||
typedef struct __attribute__((packed)) {
|
||||
gnrc_lwmac_hdr_t header; /**< Broadcast packet header type */
|
||||
uint8_t seq_nr; /**< Broadcast sequence */
|
||||
gnrc_lwmac_hdr_t header; /**< Broadcast packet header type */
|
||||
uint8_t seq_nr; /**< Broadcast sequence */
|
||||
} gnrc_lwmac_frame_broadcast_t;
|
||||
|
||||
/**
|
||||
|
@ -74,7 +74,7 @@
|
||||
#define NET_GNRC_LWMAC_LWMAC_H
|
||||
|
||||
#include "kernel_types.h"
|
||||
#include "net/gnrc/netdev.h"
|
||||
#include "net/gnrc/netif2.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -95,7 +95,7 @@ extern "C" {
|
||||
* In LWMAC, by default, we regard the wake-up period as the beginning of a cycle.
|
||||
*/
|
||||
#ifndef GNRC_LWMAC_WAKEUP_INTERVAL_US
|
||||
#define GNRC_LWMAC_WAKEUP_INTERVAL_US (100LU * US_PER_MS)
|
||||
#define GNRC_LWMAC_WAKEUP_INTERVAL_US (200LU *US_PER_MS)
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -110,7 +110,7 @@ extern "C" {
|
||||
* @ref GNRC_LWMAC_WAKEUP_INTERVAL_US.
|
||||
*/
|
||||
#ifndef GNRC_LWMAC_PREAMBLE_DURATION_US
|
||||
#define GNRC_LWMAC_PREAMBLE_DURATION_US ((13LU * GNRC_LWMAC_WAKEUP_INTERVAL_US) / 10)
|
||||
#define GNRC_LWMAC_PREAMBLE_DURATION_US ((13LU *GNRC_LWMAC_WAKEUP_INTERVAL_US) / 10)
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -129,7 +129,7 @@ extern "C" {
|
||||
* send a WR with the given hardware (including processor) and data rate.
|
||||
*/
|
||||
#ifndef GNRC_LWMAC_TIME_BETWEEN_WR_US
|
||||
#define GNRC_LWMAC_TIME_BETWEEN_WR_US (5U * US_PER_MS)
|
||||
#define GNRC_LWMAC_TIME_BETWEEN_WR_US (5U *US_PER_MS)
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -187,7 +187,7 @@ extern "C" {
|
||||
* period of the receiver, otherwise will lead to a long WR procedure.
|
||||
*/
|
||||
#ifndef GNRC_LWMAC_WR_PREPARATION_US
|
||||
#define GNRC_LWMAC_WR_PREPARATION_US ((3U * US_PER_MS))
|
||||
#define GNRC_LWMAC_WR_PREPARATION_US ((3U *US_PER_MS))
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -207,7 +207,7 @@ extern "C" {
|
||||
* supports @ref NETDEV_EVENT_RX_STARTED event (this can be important for big packets).
|
||||
*/
|
||||
#ifndef GNRC_LWMAC_DATA_DELAY_US
|
||||
#define GNRC_LWMAC_DATA_DELAY_US (10U * US_PER_MS)
|
||||
#define GNRC_LWMAC_DATA_DELAY_US (10U *US_PER_MS)
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -298,24 +298,22 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Initialize an instance of the LWMAC layer
|
||||
* @brief Creates an IEEE 802.15.4 LWMAC network interface
|
||||
*
|
||||
* The initialization starts a new thread that connects to the given netdev
|
||||
* device and starts a link layer event loop.
|
||||
* @param[in] stack The stack for the LWMAC network interface's thread.
|
||||
* @param[in] stacksize Size of @p stack.
|
||||
* @param[in] priority Priority for the LWMAC network interface's thread.
|
||||
* @param[in] name Name for the LWMAC network interface. May be NULL.
|
||||
* @param[in] dev Device for the interface
|
||||
*
|
||||
* @param[in] stack stack for the control thread
|
||||
* @param[in] stacksize size of *stack*
|
||||
* @param[in] priority priority for the thread housing the LWMAC instance
|
||||
* @param[in] name name of the thread housing the LWMAC instance
|
||||
* @param[in] dev netdev device, needs to be already initialized
|
||||
* @see @ref gnrc_netif2_create()
|
||||
*
|
||||
* @return PID of LWMAC thread on success
|
||||
* @return -EINVAL if creation of thread fails
|
||||
* @return -ENODEV if *dev* is invalid
|
||||
* @return The network interface on success.
|
||||
* @return NULL, on error.
|
||||
*/
|
||||
kernel_pid_t gnrc_lwmac_init(char *stack, int stacksize, char priority,
|
||||
const char *name, gnrc_netdev_t *dev);
|
||||
|
||||
gnrc_netif2_t *gnrc_netif2_lwmac_create(char *stack, int stacksize,
|
||||
char priority, char *name,
|
||||
netdev_t *dev);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "net/gnrc/netdev.h"
|
||||
#include "net/gnrc/netif2.h"
|
||||
#include "net/gnrc/lwmac/types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -40,52 +40,52 @@ extern "C" {
|
||||
/**
|
||||
* @brief Set LWMAC timeout of type @p type of offset @p offset.
|
||||
*
|
||||
* @param[in,out] gnrc_netdev gnrc_netdev structure
|
||||
* @param[in,out] netif the network interface
|
||||
* @param[in] type LWMAC timeout type
|
||||
* @param[in] offset timeout offset
|
||||
*/
|
||||
void gnrc_lwmac_set_timeout(gnrc_netdev_t *gnrc_netdev,
|
||||
void gnrc_lwmac_set_timeout(gnrc_netif2_t *netif,
|
||||
gnrc_lwmac_timeout_type_t type,
|
||||
uint32_t offset);
|
||||
|
||||
/**
|
||||
* @brief Clear LWMAC timeout of type @p type.
|
||||
*
|
||||
* @param[in,out] gnrc_netdev gnrc_netdev structure
|
||||
* @param[in,out] netif the network interface
|
||||
* @param[in] type LWMAC timeout type
|
||||
*/
|
||||
void gnrc_lwmac_clear_timeout(gnrc_netdev_t *gnrc_netdev, gnrc_lwmac_timeout_type_t type);
|
||||
void gnrc_lwmac_clear_timeout(gnrc_netif2_t *netif, gnrc_lwmac_timeout_type_t type);
|
||||
|
||||
/**
|
||||
* @brief Check whether LWMAC timeout of type @p type is running.
|
||||
*
|
||||
* @param[in] gnrc_netdev gnrc_netdev structure
|
||||
* @param[in] netif the network interface
|
||||
* @param[in] type LWMAC 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_lwmac_timeout_is_running(gnrc_netdev_t *gnrc_netdev,
|
||||
bool gnrc_lwmac_timeout_is_running(gnrc_netif2_t *netif,
|
||||
gnrc_lwmac_timeout_type_t type);
|
||||
|
||||
/**
|
||||
* @brief Check whether LWMAC timeout of type @p type is expired. It will clear
|
||||
* the timeout once it is found expired.
|
||||
*
|
||||
* @param[in,out] gnrc_netdev gnrc_netdev structure
|
||||
* @param[in,out] netif the network interface
|
||||
* @param[in] type LWMAC 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_lwmac_timeout_is_expired(gnrc_netdev_t *gnrc_netdev, gnrc_lwmac_timeout_type_t type);
|
||||
bool gnrc_lwmac_timeout_is_expired(gnrc_netif2_t *netif, gnrc_lwmac_timeout_type_t type);
|
||||
|
||||
/**
|
||||
* @brief Reset all LWMAC timeouts.
|
||||
*
|
||||
* @param[in,out] gnrc_netdev gnrc_netdev structure
|
||||
* @param[in,out] netif the network interface
|
||||
*/
|
||||
void gnrc_lwmac_reset_timeouts(gnrc_netdev_t *gnrc_netdev);
|
||||
void gnrc_lwmac_reset_timeouts(gnrc_netif2_t *netif);
|
||||
|
||||
/**
|
||||
* @brief Make a specific LWMAC timeout expired.
|
||||
|
@ -109,32 +109,32 @@ extern "C" {
|
||||
* @brief Internal states of LWMAC
|
||||
*/
|
||||
typedef enum {
|
||||
GNRC_LWMAC_UNDEF = -1, /**< Undefined state of LWMAC */
|
||||
GNRC_LWMAC_STOPPED, /**< LWMAC's main state machine has been stopped */
|
||||
GNRC_LWMAC_START, /**< Start LWMAC's main state machine */
|
||||
GNRC_LWMAC_STOP, /**< Stop LWMAC's main state machine */
|
||||
GNRC_LWMAC_RESET, /**< Reset LWMAC's main state machine */
|
||||
GNRC_LWMAC_LISTENING, /**< Listen the channel for receiving packets */
|
||||
GNRC_LWMAC_RECEIVING, /**< RX is handled in own state machine */
|
||||
GNRC_LWMAC_TRANSMITTING, /**< TX is handled in own state machine */
|
||||
GNRC_LWMAC_SLEEPING, /**< Turn off radio to conserve power */
|
||||
GNRC_LWMAC_STATE_COUNT /**< Count of LWMAC's states */
|
||||
GNRC_LWMAC_UNDEF = -1, /**< Undefined state of LWMAC */
|
||||
GNRC_LWMAC_STOPPED, /**< LWMAC's main state machine has been stopped */
|
||||
GNRC_LWMAC_START, /**< Start LWMAC's main state machine */
|
||||
GNRC_LWMAC_STOP, /**< Stop LWMAC's main state machine */
|
||||
GNRC_LWMAC_RESET, /**< Reset LWMAC's main state machine */
|
||||
GNRC_LWMAC_LISTENING, /**< Listen the channel for receiving packets */
|
||||
GNRC_LWMAC_RECEIVING, /**< RX is handled in own state machine */
|
||||
GNRC_LWMAC_TRANSMITTING, /**< TX is handled in own state machine */
|
||||
GNRC_LWMAC_SLEEPING, /**< Turn off radio to conserve power */
|
||||
GNRC_LWMAC_STATE_COUNT /**< Count of LWMAC's states */
|
||||
} gnrc_lwmac_state_t;
|
||||
|
||||
/**
|
||||
* @brief TX states of LWMAC
|
||||
*/
|
||||
typedef enum {
|
||||
GNRC_LWMAC_TX_STATE_STOPPED, /**< Tx schedule stopped, stop sending packet */
|
||||
GNRC_LWMAC_TX_STATE_INIT, /**< Initiate transmission */
|
||||
GNRC_LWMAC_TX_STATE_SEND_BROADCAST, /**< directly goes to SUCCESSFUL or FAILED when finished */
|
||||
GNRC_LWMAC_TX_STATE_SEND_WR, /**< Send a wakeup request */
|
||||
GNRC_LWMAC_TX_STATE_WAIT_WR_SENT, /**< Wait until WR sent to set timeout */
|
||||
GNRC_LWMAC_TX_STATE_WAIT_FOR_WA, /**< Wait for dest node's wakeup ackknowledge */
|
||||
GNRC_LWMAC_TX_STATE_SEND_DATA, /**< Send the actual payload data */
|
||||
GNRC_LWMAC_TX_STATE_WAIT_FEEDBACK, /**< Wait if packet was ACKed */
|
||||
GNRC_LWMAC_TX_STATE_SUCCESSFUL, /**< Transmission has finished successfully */
|
||||
GNRC_LWMAC_TX_STATE_FAILED /**< Payload data couldn't be delivered to dest */
|
||||
GNRC_LWMAC_TX_STATE_STOPPED, /**< Tx schedule stopped, stop sending packet */
|
||||
GNRC_LWMAC_TX_STATE_INIT, /**< Initiate transmission */
|
||||
GNRC_LWMAC_TX_STATE_SEND_BROADCAST, /**< directly goes to SUCCESSFUL or FAILED when finished */
|
||||
GNRC_LWMAC_TX_STATE_SEND_WR, /**< Send a wakeup request */
|
||||
GNRC_LWMAC_TX_STATE_WAIT_WR_SENT, /**< Wait until WR sent to set timeout */
|
||||
GNRC_LWMAC_TX_STATE_WAIT_FOR_WA, /**< Wait for dest node's wakeup ackknowledge */
|
||||
GNRC_LWMAC_TX_STATE_SEND_DATA, /**< Send the actual payload data */
|
||||
GNRC_LWMAC_TX_STATE_WAIT_FEEDBACK, /**< Wait if packet was ACKed */
|
||||
GNRC_LWMAC_TX_STATE_SUCCESSFUL, /**< Transmission has finished successfully */
|
||||
GNRC_LWMAC_TX_STATE_FAILED /**< Payload data couldn't be delivered to dest */
|
||||
} gnrc_lwmac_tx_state_t;
|
||||
|
||||
/**
|
||||
@ -146,14 +146,14 @@ typedef enum {
|
||||
* @brief RX states of LWMAC
|
||||
*/
|
||||
typedef enum {
|
||||
GNRC_LWMAC_RX_STATE_STOPPED, /**< Rx schedule stopped */
|
||||
GNRC_LWMAC_RX_STATE_INIT, /**< Initiate reception */
|
||||
GNRC_LWMAC_RX_STATE_WAIT_FOR_WR, /**< Wait for a wakeup request */
|
||||
GNRC_LWMAC_RX_STATE_SEND_WA, /**< Send wakeup ackknowledge to requesting node */
|
||||
GNRC_LWMAC_RX_STATE_WAIT_WA_SENT, /**< Wait until WA sent to set timeout */
|
||||
GNRC_LWMAC_RX_STATE_WAIT_FOR_DATA, /**< Wait for actual payload data */
|
||||
GNRC_LWMAC_RX_STATE_SUCCESSFUL, /**< Recption has finished successfully */
|
||||
GNRC_LWMAC_RX_STATE_FAILED /**< Reception over, but nothing received */
|
||||
GNRC_LWMAC_RX_STATE_STOPPED, /**< Rx schedule stopped */
|
||||
GNRC_LWMAC_RX_STATE_INIT, /**< Initiate reception */
|
||||
GNRC_LWMAC_RX_STATE_WAIT_FOR_WR, /**< Wait for a wakeup request */
|
||||
GNRC_LWMAC_RX_STATE_SEND_WA, /**< Send wakeup ackknowledge to requesting node */
|
||||
GNRC_LWMAC_RX_STATE_WAIT_WA_SENT, /**< Wait until WA sent to set timeout */
|
||||
GNRC_LWMAC_RX_STATE_WAIT_FOR_DATA, /**< Wait for actual payload data */
|
||||
GNRC_LWMAC_RX_STATE_SUCCESSFUL, /**< Recption has finished successfully */
|
||||
GNRC_LWMAC_RX_STATE_FAILED /**< Reception over, but nothing received */
|
||||
} gnrc_lwmac_rx_state_t;
|
||||
|
||||
/**
|
||||
@ -175,14 +175,14 @@ typedef enum {
|
||||
* @brief LWMAC timeout types
|
||||
*/
|
||||
typedef enum {
|
||||
GNRC_LWMAC_TIMEOUT_DISABLED, /**< Timeout is diabled */
|
||||
GNRC_LWMAC_TIMEOUT_WR, /**< WR timeout, waiting WA */
|
||||
GNRC_LWMAC_TIMEOUT_NO_RESPONSE, /**< Maximum WR duration timeout awaiting WA */
|
||||
GNRC_LWMAC_TIMEOUT_DATA, /**< Timeout awaiting data packet from receiver */
|
||||
GNRC_LWMAC_TIMEOUT_WAIT_DEST_WAKEUP, /**< Timeout for waiting receiver's wake-up phase */
|
||||
GNRC_LWMAC_TIMEOUT_WAKEUP_PERIOD, /**< Wake up period timeout for going to sleep */
|
||||
GNRC_LWMAC_TIMEOUT_NEXT_BROADCAST, /**< Timeout for waiting to send the next broadcast packet */
|
||||
GNRC_LWMAC_TIMEOUT_BROADCAST_END, /**< Timeout awaiting the end of the whole broadcast period */
|
||||
GNRC_LWMAC_TIMEOUT_DISABLED, /**< Timeout is diabled */
|
||||
GNRC_LWMAC_TIMEOUT_WR, /**< WR timeout, waiting WA */
|
||||
GNRC_LWMAC_TIMEOUT_NO_RESPONSE, /**< Maximum WR duration timeout awaiting WA */
|
||||
GNRC_LWMAC_TIMEOUT_DATA, /**< Timeout awaiting data packet from receiver */
|
||||
GNRC_LWMAC_TIMEOUT_WAIT_DEST_WAKEUP, /**< Timeout for waiting receiver's wake-up phase */
|
||||
GNRC_LWMAC_TIMEOUT_WAKEUP_PERIOD, /**< Wake up period timeout for going to sleep */
|
||||
GNRC_LWMAC_TIMEOUT_NEXT_BROADCAST, /**< Timeout for waiting to send the next broadcast packet */
|
||||
GNRC_LWMAC_TIMEOUT_BROADCAST_END, /**< Timeout awaiting the end of the whole broadcast period */
|
||||
} gnrc_lwmac_timeout_type_t;
|
||||
|
||||
/**
|
||||
@ -199,19 +199,19 @@ typedef struct {
|
||||
* @brief LWMAC specific structure for storing internal states.
|
||||
*/
|
||||
typedef struct lwmac {
|
||||
gnrc_lwmac_state_t state; /**< Internal state of MAC layer */
|
||||
uint32_t last_wakeup; /**< Used to calculate wakeup times */
|
||||
uint8_t lwmac_info; /**< LWMAC's internal informations (flags) */
|
||||
gnrc_lwmac_timeout_t timeouts[GNRC_LWMAC_TIMEOUT_COUNT]; /**< Store timeouts used for protocol */
|
||||
gnrc_lwmac_state_t state; /**< Internal state of MAC layer */
|
||||
uint32_t last_wakeup; /**< Used to calculate wakeup times */
|
||||
uint8_t lwmac_info; /**< LWMAC's internal informations (flags) */
|
||||
gnrc_lwmac_timeout_t timeouts[GNRC_LWMAC_TIMEOUT_COUNT]; /**< Store timeouts used for protocol */
|
||||
|
||||
#if (GNRC_LWMAC_ENABLE_DUTYCYLE_RECORD == 1)
|
||||
/* Parameters for recording duty-cycle */
|
||||
uint32_t last_radio_on_time_ticks; /**< The last time in ticks when radio is on */
|
||||
uint32_t radio_off_time_ticks; /**< The time in ticks when radio is off */
|
||||
uint32_t system_start_time_ticks; /**< The time in ticks when chip is started */
|
||||
uint32_t awake_duration_sum_ticks; /**< The sum of time in ticks when radio is on */
|
||||
uint32_t pkt_start_sending_time_ticks; /**< The time in ticks when the packet is started
|
||||
to be sent */
|
||||
uint32_t last_radio_on_time_ticks; /**< The last time in ticks when radio is on */
|
||||
uint32_t radio_off_time_ticks; /**< The time in ticks when radio is off */
|
||||
uint32_t system_start_time_ticks; /**< The time in ticks when chip is started */
|
||||
uint32_t awake_duration_sum_ticks; /**< The sum of time in ticks when radio is on */
|
||||
uint32_t pkt_start_sending_time_ticks; /**< The time in ticks when the packet is started
|
||||
to be sent */
|
||||
#endif
|
||||
} gnrc_lwmac_t;
|
||||
|
||||
|
@ -25,11 +25,76 @@
|
||||
|
||||
#include "net/ieee802154.h"
|
||||
#include "net/gnrc/mac/types.h"
|
||||
#include "net/gnrc/netif2.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_netif2_get_rx_started(gnrc_netif2_t *netif)
|
||||
{
|
||||
return (netif->mac.mac_info & GNRC_NETIF2_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_netif2_set_rx_started(gnrc_netif2_t *netif, bool rx_started)
|
||||
{
|
||||
if (rx_started) {
|
||||
netif->mac.mac_info |= GNRC_NETIF2_MAC_INFO_RX_STARTED;
|
||||
}
|
||||
else {
|
||||
netif->mac.mac_info &= ~GNRC_NETIF2_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_netif2_get_tx_feedback(gnrc_netif2_t *netif)
|
||||
{
|
||||
return (gnrc_mac_tx_feedback_t)(netif->mac.mac_info &
|
||||
GNRC_NETIF2_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_netif2_set_tx_feedback(gnrc_netif2_t *netif,
|
||||
gnrc_mac_tx_feedback_t txf)
|
||||
{
|
||||
/* check if gnrc_mac_tx_feedback does not collide with
|
||||
* GNRC_NETIF2_MAC_INFO_RX_STARTED */
|
||||
assert(!(txf & GNRC_NETIF2_MAC_INFO_RX_STARTED));
|
||||
/* unset previous value */
|
||||
netif->mac.mac_info &= ~GNRC_NETIF2_MAC_INFO_TX_FEEDBACK_MASK;
|
||||
netif->mac.mac_info |= (uint16_t)(txf & GNRC_NETIF2_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.
|
||||
|
@ -19,15 +19,46 @@
|
||||
#define NET_GNRC_NETIF2_MAC_H
|
||||
|
||||
#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_NETIF2_MAC_INFO_TX_FEEDBACK_MASK (0x0003U)
|
||||
|
||||
/**
|
||||
* @brief Flag to track if a transmission might have corrupted a received
|
||||
* packet
|
||||
*/
|
||||
#define GNRC_NETIF2_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_NETIF2_MAC_INFO_CSMA_ENABLED (0x0100U)
|
||||
|
||||
/**
|
||||
* @brief @ref net_gnrc_mac component of @ref gnrc_netif2_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
|
||||
@ -48,6 +79,13 @@ 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;
|
||||
#endif
|
||||
} gnrc_netif2_mac_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "periph/rtt.h"
|
||||
#include "net/gnrc/netdev.h"
|
||||
#include "net/gnrc/netif2.h"
|
||||
#include "net/gnrc/mac/types.h"
|
||||
#include "net/gnrc/lwmac/types.h"
|
||||
|
||||
@ -41,7 +41,7 @@ extern "C" {
|
||||
* successively transmit its packets back to back with this flag set up,
|
||||
* with the awareness that the receiver will also keep awake for receptions.
|
||||
*/
|
||||
#define GNRC_NETDEV_LWMAC_TX_CONTINUE (0x0008U)
|
||||
#define GNRC_LWMAC_TX_CONTINUE (0x0008U)
|
||||
|
||||
/**
|
||||
* @brief Flag to track if the sender should quit Tx in current cycle.
|
||||
@ -53,7 +53,7 @@ extern "C" {
|
||||
* cycle (started by the wake-up period), thus not to collide with other
|
||||
* (neighbor) nodes' transmissions.
|
||||
*/
|
||||
#define GNRC_NETDEV_LWMAC_QUIT_TX (0x0010U)
|
||||
#define GNRC_LWMAC_QUIT_TX (0x0010U)
|
||||
|
||||
/**
|
||||
* @brief Flag to track if the device need to reselect a new wake-up phase.
|
||||
@ -65,7 +65,7 @@ extern "C" {
|
||||
* sender finds its phase close to its receiver's, it sets up this flag and then
|
||||
* randomly reselects a new wake-up phase.
|
||||
*/
|
||||
#define GNRC_NETDEV_LWMAC_PHASE_BACKOFF (0x0020U)
|
||||
#define GNRC_LWMAC_PHASE_BACKOFF (0x0020U)
|
||||
|
||||
/**
|
||||
* @brief Flag to track if the device needs to quit the wake-up (listening) procedure.
|
||||
@ -78,15 +78,15 @@ extern "C" {
|
||||
* should immediately goto sleep (by setting up this flag) after one reception, thus not
|
||||
* to receive duplicate broadcast packets.
|
||||
*/
|
||||
#define GNRC_NETDEV_LWMAC_QUIT_RX (0x0040U)
|
||||
#define GNRC_LWMAC_QUIT_RX (0x0040U)
|
||||
|
||||
/**
|
||||
* @brief Type to pass information about parsing.
|
||||
*/
|
||||
typedef struct {
|
||||
gnrc_lwmac_hdr_t *header; /**< LWMAC header of packet */
|
||||
gnrc_lwmac_l2_addr_t src_addr; /**< copied source address of packet */
|
||||
gnrc_lwmac_l2_addr_t dst_addr; /**< copied destination address of packet */
|
||||
gnrc_lwmac_hdr_t *header; /**< LWMAC header of packet */
|
||||
gnrc_lwmac_l2_addr_t src_addr; /**< copied source address of packet */
|
||||
gnrc_lwmac_l2_addr_t dst_addr; /**< copied destination address of packet */
|
||||
} gnrc_lwmac_packet_info_t;
|
||||
|
||||
/**
|
||||
@ -98,185 +98,209 @@ typedef struct {
|
||||
#define GNRC_LWMAC_RTT_EVENT_MARGIN_TICKS (RTT_MS_TO_TICKS(2))
|
||||
|
||||
/**
|
||||
* @brief set the TX-continue flag of the device
|
||||
* @brief set the @ref GNRC_LWMAC_TX_CONTINUE flag of the device
|
||||
*
|
||||
* @param[in] dev ptr to netdev device
|
||||
* @param[in] netif ptr to the network interface
|
||||
* @param[in] tx_continue value for LWMAC tx-continue flag
|
||||
*
|
||||
*/
|
||||
static inline void gnrc_netdev_lwmac_set_tx_continue(gnrc_netdev_t *dev, bool tx_continue)
|
||||
static inline void gnrc_lwmac_set_tx_continue(gnrc_netif2_t *netif, bool tx_continue)
|
||||
{
|
||||
if (tx_continue) {
|
||||
dev->mac_info |= GNRC_NETDEV_LWMAC_TX_CONTINUE;
|
||||
netif->mac.mac_info |= GNRC_LWMAC_TX_CONTINUE;
|
||||
}
|
||||
else {
|
||||
dev->mac_info &= ~GNRC_NETDEV_LWMAC_TX_CONTINUE;
|
||||
netif->mac.mac_info &= ~GNRC_LWMAC_TX_CONTINUE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get the TX-continue flag of the device
|
||||
* @brief get the @ref GNRC_LWMAC_TX_CONTINUE flag of the device
|
||||
*
|
||||
* @param[in] dev ptr to netdev device
|
||||
* @param[in] netif ptr to the network interface
|
||||
*
|
||||
* @return true if tx continue
|
||||
* @return false if tx will continue
|
||||
* @return false if tx will not continue
|
||||
*/
|
||||
static inline bool gnrc_netdev_lwmac_get_tx_continue(gnrc_netdev_t *dev)
|
||||
static inline bool gnrc_lwmac_get_tx_continue(gnrc_netif2_t *netif)
|
||||
{
|
||||
return (dev->mac_info & GNRC_NETDEV_LWMAC_TX_CONTINUE);
|
||||
return (netif->mac.mac_info & GNRC_LWMAC_TX_CONTINUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set the quit-TX flag of the device
|
||||
* @brief set the @ref GNRC_LWMAC_QUIT_TX flag of the device
|
||||
*
|
||||
* @param[in] dev ptr to netdev device
|
||||
* @param[in] quit_tx value for LWMAC quit-TX flag
|
||||
* @param[in] netif ptr to the network interface
|
||||
* @param[in] quit_tx value for @ref GNRC_LWMAC_QUIT_TX flag
|
||||
*
|
||||
*/
|
||||
static inline void gnrc_netdev_lwmac_set_quit_tx(gnrc_netdev_t *dev, bool quit_tx)
|
||||
static inline void gnrc_lwmac_set_quit_tx(gnrc_netif2_t *netif, bool quit_tx)
|
||||
{
|
||||
if (quit_tx) {
|
||||
dev->mac_info |= GNRC_NETDEV_LWMAC_QUIT_TX;
|
||||
netif->mac.mac_info |= GNRC_LWMAC_QUIT_TX;
|
||||
}
|
||||
else {
|
||||
dev->mac_info &= ~GNRC_NETDEV_LWMAC_QUIT_TX;
|
||||
netif->mac.mac_info &= ~GNRC_LWMAC_QUIT_TX;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get the quit-TX flag of the device
|
||||
* @brief get the @ref GNRC_LWMAC_QUIT_TX flag of the device
|
||||
*
|
||||
* @param[in] dev ptr to netdev device
|
||||
* @param[in] netif ptr to the network interface
|
||||
*
|
||||
* @return true if quit tx
|
||||
* @return false if will not quit tx
|
||||
*/
|
||||
static inline bool gnrc_netdev_lwmac_get_quit_tx(gnrc_netdev_t *dev)
|
||||
static inline bool gnrc_lwmac_get_quit_tx(gnrc_netif2_t *netif)
|
||||
{
|
||||
return (dev->mac_info & GNRC_NETDEV_LWMAC_QUIT_TX);
|
||||
return (netif->mac.mac_info & GNRC_LWMAC_QUIT_TX);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set the phase-backoff flag of the device
|
||||
* @brief set the @ref GNRC_LWMAC_PHASE_BACKOFF flag of the device
|
||||
*
|
||||
* @param[in] dev ptr to netdev device
|
||||
* @param[in] backoff value for LWMAC phase-backoff flag
|
||||
* @param[in] netif ptr to the network interface
|
||||
* @param[in] backoff value for LWMAC @ref GNRC_LWMAC_PHASE_BACKOFF flag
|
||||
*
|
||||
*/
|
||||
static inline void gnrc_netdev_lwmac_set_phase_backoff(gnrc_netdev_t *dev, bool backoff)
|
||||
static inline void gnrc_lwmac_set_phase_backoff(gnrc_netif2_t *netif, bool backoff)
|
||||
{
|
||||
if (backoff) {
|
||||
dev->mac_info |= GNRC_NETDEV_LWMAC_PHASE_BACKOFF;
|
||||
netif->mac.mac_info |= GNRC_LWMAC_PHASE_BACKOFF;
|
||||
}
|
||||
else {
|
||||
dev->mac_info &= ~GNRC_NETDEV_LWMAC_PHASE_BACKOFF;
|
||||
netif->mac.mac_info &= ~GNRC_LWMAC_PHASE_BACKOFF;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get the phase-backoff of the device
|
||||
* @brief get the @ref GNRC_LWMAC_PHASE_BACKOFF flag of the device
|
||||
*
|
||||
* @param[in] dev ptr to netdev device
|
||||
* @param[in] netif ptr to the network interface
|
||||
*
|
||||
* @return true if will run phase-backoff
|
||||
* @return false if will not run phase-backoff
|
||||
*/
|
||||
static inline bool gnrc_netdev_lwmac_get_phase_backoff(gnrc_netdev_t *dev)
|
||||
static inline bool gnrc_lwmac_get_phase_backoff(gnrc_netif2_t *netif)
|
||||
{
|
||||
return (dev->mac_info & GNRC_NETDEV_LWMAC_PHASE_BACKOFF);
|
||||
return (netif->mac.mac_info & GNRC_LWMAC_PHASE_BACKOFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set the quit-RX flag of the device
|
||||
* @brief set the @ref GNRC_LWMAC_QUIT_RX flag of the device
|
||||
*
|
||||
* @param[in] dev ptr to netdev device
|
||||
* @param[in] quit_rx value for LWMAC quit-Rx flag
|
||||
* @param[in] netif ptr to the network interface
|
||||
* @param[in] quit_rx value for LWMAC @ref GNRC_LWMAC_QUIT_RX flag
|
||||
*
|
||||
*/
|
||||
static inline void gnrc_netdev_lwmac_set_quit_rx(gnrc_netdev_t *dev, bool quit_rx)
|
||||
static inline void gnrc_lwmac_set_quit_rx(gnrc_netif2_t *netif, bool quit_rx)
|
||||
{
|
||||
if (quit_rx) {
|
||||
dev->mac_info |= GNRC_NETDEV_LWMAC_QUIT_RX;
|
||||
netif->mac.mac_info |= GNRC_LWMAC_QUIT_RX;
|
||||
}
|
||||
else {
|
||||
dev->mac_info &= ~GNRC_NETDEV_LWMAC_QUIT_RX;
|
||||
netif->mac.mac_info &= ~GNRC_LWMAC_QUIT_RX;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get the quit-RX flag of the device
|
||||
* @brief get the @ref GNRC_LWMAC_QUIT_RX flag of the device
|
||||
*
|
||||
* @param[in] dev ptr to netdev device
|
||||
* @param[in] netif ptr to the network interface
|
||||
*
|
||||
* @return true if will quit rx
|
||||
* @return false if will not quit rx
|
||||
*/
|
||||
static inline bool gnrc_netdev_lwmac_get_quit_rx(gnrc_netdev_t *dev)
|
||||
static inline bool gnrc_lwmac_get_quit_rx(gnrc_netif2_t *netif)
|
||||
{
|
||||
return (dev->mac_info & GNRC_NETDEV_LWMAC_QUIT_RX);
|
||||
return (netif->mac.mac_info & GNRC_LWMAC_QUIT_RX);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set the duty-cycle-active flag of LWMAC
|
||||
* @brief set the @ref GNRC_LWMAC_DUTYCYCLE_ACTIVE flag of LWMAC
|
||||
*
|
||||
* @param[in] dev ptr to netdev device
|
||||
* @param[in] active value for LWMAC duty-cycle-active flag
|
||||
* @param[in] netif ptr to the network interface
|
||||
* @param[in] active value for LWMAC @ref GNRC_LWMAC_DUTYCYCLE_ACTIVE flag
|
||||
*
|
||||
*/
|
||||
static inline void gnrc_netdev_lwmac_set_dutycycle_active(gnrc_netdev_t *dev, bool active)
|
||||
static inline void gnrc_lwmac_set_dutycycle_active(gnrc_netif2_t *netif, bool active)
|
||||
{
|
||||
if (active) {
|
||||
dev->lwmac.lwmac_info |= GNRC_LWMAC_DUTYCYCLE_ACTIVE;
|
||||
netif->mac.lwmac.lwmac_info |= GNRC_LWMAC_DUTYCYCLE_ACTIVE;
|
||||
}
|
||||
else {
|
||||
dev->lwmac.lwmac_info &= ~GNRC_LWMAC_DUTYCYCLE_ACTIVE;
|
||||
netif->mac.lwmac.lwmac_info &= ~GNRC_LWMAC_DUTYCYCLE_ACTIVE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get the duty-cycle-active flag of LWMAC
|
||||
* @brief get the @ref GNRC_LWMAC_DUTYCYCLE_ACTIVE flag of LWMAC
|
||||
*
|
||||
* @param[in] dev ptr to netdev device
|
||||
* @param[in] netif ptr to the network interface
|
||||
*
|
||||
* @return true if active
|
||||
* @return false if not active
|
||||
*/
|
||||
static inline bool gnrc_netdev_lwmac_get_dutycycle_active(gnrc_netdev_t *dev)
|
||||
static inline bool gnrc_lwmac_get_dutycycle_active(gnrc_netif2_t *netif)
|
||||
{
|
||||
return (dev->lwmac.lwmac_info & GNRC_LWMAC_DUTYCYCLE_ACTIVE);
|
||||
return (netif->mac.lwmac.lwmac_info & GNRC_LWMAC_DUTYCYCLE_ACTIVE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set the needs-rescheduling flag of LWMAC
|
||||
* @brief set the @ref GNRC_LWMAC_NEEDS_RESCHEDULE flag of LWMAC
|
||||
*
|
||||
* @param[in] dev ptr to netdev device
|
||||
* @param[in] reschedule value for LWMAC needs-rescheduling flag
|
||||
* @param[in] netif ptr to the network interface
|
||||
* @param[in] reschedule value for @ref GNRC_LWMAC_NEEDS_RESCHEDULE flag
|
||||
*
|
||||
*/
|
||||
static inline void gnrc_netdev_lwmac_set_reschedule(gnrc_netdev_t *dev, bool reschedule)
|
||||
static inline void gnrc_lwmac_set_reschedule(gnrc_netif2_t *netif, bool reschedule)
|
||||
{
|
||||
if (reschedule) {
|
||||
dev->lwmac.lwmac_info |= GNRC_LWMAC_NEEDS_RESCHEDULE;
|
||||
netif->mac.lwmac.lwmac_info |= GNRC_LWMAC_NEEDS_RESCHEDULE;
|
||||
}
|
||||
else {
|
||||
dev->lwmac.lwmac_info &= ~GNRC_LWMAC_NEEDS_RESCHEDULE;
|
||||
netif->mac.lwmac.lwmac_info &= ~GNRC_LWMAC_NEEDS_RESCHEDULE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get the needs-rescheduling flag of LWMAC
|
||||
* @brief get the @ref GNRC_LWMAC_NEEDS_RESCHEDULE flag of LWMAC
|
||||
*
|
||||
* @param[in] dev ptr to netdev device
|
||||
* @param[in] netif ptr to the network interface
|
||||
*
|
||||
* @return true if needs rescheduling
|
||||
* @return false if no need for rescheduling
|
||||
*/
|
||||
static inline bool gnrc_netdev_lwmac_get_reschedule(gnrc_netdev_t *dev)
|
||||
static inline bool gnrc_lwmac_get_reschedule(gnrc_netif2_t *netif)
|
||||
{
|
||||
return (dev->lwmac.lwmac_info & GNRC_LWMAC_NEEDS_RESCHEDULE);
|
||||
return (netif->mac.lwmac.lwmac_info & GNRC_LWMAC_NEEDS_RESCHEDULE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief send a @ref net_gnrc_pkt "packet" over the network interface in LWMAC
|
||||
*
|
||||
* @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_netif2_t::dev.
|
||||
*/
|
||||
int _gnrc_lwmac_transmit(gnrc_netif2_t *netif, gnrc_pktsnip_t *pkt);
|
||||
|
||||
/**
|
||||
* @brief Parse an incoming packet and extract important information.
|
||||
*
|
||||
@ -293,19 +317,19 @@ int _gnrc_lwmac_parse_packet(gnrc_pktsnip_t *pkt, gnrc_lwmac_packet_info_t *info
|
||||
/**
|
||||
* @brief Shortcut to get the state of netdev.
|
||||
*
|
||||
* @param[in] gnrc_netdev gnrc_netdev structure
|
||||
* @param[in] netif ptr to the network interface
|
||||
*
|
||||
* @return state of netdev
|
||||
* @return state of netdev
|
||||
*/
|
||||
netopt_state_t _gnrc_lwmac_get_netdev_state(gnrc_netdev_t *gnrc_netdev);
|
||||
netopt_state_t _gnrc_lwmac_get_netdev_state(gnrc_netif2_t *netif);
|
||||
|
||||
/**
|
||||
* @brief Shortcut to set the state of netdev
|
||||
*
|
||||
* @param[in] gnrc_netdev gnrc_netdev structure
|
||||
* @param[in] devstate new state for netdev
|
||||
* @param[in] netif ptr to the network interface
|
||||
* @param[in] devstate new state for netdev
|
||||
*/
|
||||
void _gnrc_lwmac_set_netdev_state(gnrc_netdev_t *gnrc_netdev, netopt_state_t devstate);
|
||||
void _gnrc_lwmac_set_netdev_state(gnrc_netif2_t *netif, netopt_state_t devstate);
|
||||
|
||||
/**
|
||||
* @brief Convert RTT ticks to device phase
|
||||
|
@ -23,7 +23,7 @@
|
||||
#define RX_STATE_MACHINE_H
|
||||
|
||||
#include "net/gnrc/pkt.h"
|
||||
#include "net/gnrc/netdev.h"
|
||||
#include "net/gnrc/netif2.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -32,26 +32,26 @@ extern "C" {
|
||||
/**
|
||||
* @brief Start LWMAC RX procedure to receive packet
|
||||
*
|
||||
* @param[in,out] gnrc_netdev gnrc_netdev structure
|
||||
* @param[in,out] netif ptr to the network interface
|
||||
*
|
||||
*/
|
||||
void gnrc_lwmac_rx_start(gnrc_netdev_t *gnrc_netdev);
|
||||
void gnrc_lwmac_rx_start(gnrc_netif2_t *netif);
|
||||
|
||||
/**
|
||||
* @brief Stop LWMAC RX procedure
|
||||
*
|
||||
* @param[in,out] gnrc_netdev gnrc_netdev structure
|
||||
* @param[in,out] netif ptr to the network interface
|
||||
*
|
||||
*/
|
||||
void gnrc_lwmac_rx_stop(gnrc_netdev_t *gnrc_netdev);
|
||||
void gnrc_lwmac_rx_stop(gnrc_netif2_t *netif);
|
||||
|
||||
/**
|
||||
* @brief Update LWMAC RX procedure for packet reception
|
||||
*
|
||||
* @param[in,out] gnrc_netdev gnrc_netdev structure
|
||||
* @param[in,out] netif ptr to the network interface
|
||||
*
|
||||
*/
|
||||
void gnrc_lwmac_rx_update(gnrc_netdev_t *gnrc_netdev);
|
||||
void gnrc_lwmac_rx_update(gnrc_netif2_t *netif);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
#define TX_STATE_MACHINE_H
|
||||
|
||||
#include "net/gnrc/pkt.h"
|
||||
#include "net/gnrc/netdev.h"
|
||||
#include "net/gnrc/netif2.h"
|
||||
#include "net/gnrc/mac/types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -33,30 +33,30 @@ extern "C" {
|
||||
/**
|
||||
* @brief Start LWMAC TX procedure to transmit packet @p pkt to @p neighbor
|
||||
*
|
||||
* @param[in,out] gnrc_netdev gnrc_netdev structure
|
||||
* @param[in,out] netif ptr to the network interface
|
||||
* @param[in] pkt packet to transmit
|
||||
* @param[in] neighbor Tx neighbor
|
||||
*
|
||||
*/
|
||||
void gnrc_lwmac_tx_start(gnrc_netdev_t *gnrc_netdev,
|
||||
void gnrc_lwmac_tx_start(gnrc_netif2_t *netif,
|
||||
gnrc_pktsnip_t *pkt,
|
||||
gnrc_mac_tx_neighbor_t *neighbor);
|
||||
|
||||
/**
|
||||
* @brief Stop LWMAC TX procedure
|
||||
*
|
||||
* @param[in,out] gnrc_netdev gnrc_netdev structure
|
||||
* @param[in,out] netif ptr to the network interface
|
||||
*
|
||||
*/
|
||||
void gnrc_lwmac_tx_stop(gnrc_netdev_t *gnrc_netdev);
|
||||
void gnrc_lwmac_tx_stop(gnrc_netif2_t *netif);
|
||||
|
||||
/**
|
||||
* @brief Update LWMAC TX procedure for transmission
|
||||
*
|
||||
* @param[in,out] gnrc_netdev gnrc_netdev structure
|
||||
* @param[in,out] netif ptr to the network interface
|
||||
*
|
||||
*/
|
||||
void gnrc_lwmac_tx_update(gnrc_netdev_t *gnrc_netdev);
|
||||
void gnrc_lwmac_tx_update(gnrc_netif2_t *netif);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -27,10 +27,97 @@
|
||||
#include "net/gnrc/netdev.h"
|
||||
#include "net/gnrc/lwmac/lwmac.h"
|
||||
#include "include/lwmac_internal.h"
|
||||
#include "net/gnrc/netif2/ieee802154.h"
|
||||
#include "net/netdev/ieee802154.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
int _gnrc_lwmac_transmit(gnrc_netif2_t *netif, gnrc_pktsnip_t *pkt)
|
||||
{
|
||||
netdev_t *dev = netif->dev;
|
||||
netdev_ieee802154_t *state = (netdev_ieee802154_t *)netif->dev;
|
||||
gnrc_netif_hdr_t *netif_hdr;
|
||||
gnrc_pktsnip_t *vec_snip;
|
||||
const uint8_t *src, *dst = NULL;
|
||||
int res = 0;
|
||||
size_t n, src_len, dst_len;
|
||||
uint8_t mhr[IEEE802154_MAX_HDR_LEN];
|
||||
uint8_t flags = (uint8_t)(state->flags & NETDEV_IEEE802154_SEND_MASK);
|
||||
le_uint16_t dev_pan = byteorder_btols(byteorder_htons(state->pan));
|
||||
|
||||
flags |= IEEE802154_FCF_TYPE_DATA;
|
||||
if (pkt == NULL) {
|
||||
DEBUG("_send_ieee802154: pkt was NULL\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (pkt->type != GNRC_NETTYPE_NETIF) {
|
||||
DEBUG("_send_ieee802154: first header is not generic netif header\n");
|
||||
return -EBADMSG;
|
||||
}
|
||||
netif_hdr = pkt->data;
|
||||
/* prepare destination address */
|
||||
if (netif_hdr->flags & /* If any of these flags is set assume broadcast */
|
||||
(GNRC_NETIF_HDR_FLAGS_BROADCAST | GNRC_NETIF_HDR_FLAGS_MULTICAST)) {
|
||||
dst = ieee802154_addr_bcast;
|
||||
dst_len = IEEE802154_ADDR_BCAST_LEN;
|
||||
}
|
||||
else {
|
||||
dst = gnrc_netif_hdr_get_dst_addr(netif_hdr);
|
||||
dst_len = netif_hdr->dst_l2addr_len;
|
||||
}
|
||||
src_len = netif_hdr->src_l2addr_len;
|
||||
if (src_len > 0) {
|
||||
src = gnrc_netif_hdr_get_src_addr(netif_hdr);
|
||||
}
|
||||
else {
|
||||
src_len = netif->l2addr_len;
|
||||
src = netif->l2addr;
|
||||
}
|
||||
/* fill MAC header, seq should be set by device */
|
||||
if ((res = ieee802154_set_frame_hdr(mhr, src, src_len,
|
||||
dst, dst_len, dev_pan,
|
||||
dev_pan, flags, state->seq++)) == 0) {
|
||||
DEBUG("_send_ieee802154: Error preperaring frame\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
/* prepare packet for sending */
|
||||
vec_snip = gnrc_pktbuf_get_iovec(pkt, &n);
|
||||
if (vec_snip != NULL) {
|
||||
struct iovec *vector;
|
||||
|
||||
pkt = vec_snip; /* reassign for later release; vec_snip is prepended to pkt */
|
||||
vector = (struct iovec *)pkt->data;
|
||||
vector[0].iov_base = mhr;
|
||||
vector[0].iov_len = (size_t)res;
|
||||
#ifdef MODULE_NETSTATS_L2
|
||||
if (netif_hdr->flags &
|
||||
(GNRC_NETIF_HDR_FLAGS_BROADCAST | GNRC_NETIF_HDR_FLAGS_MULTICAST)) {
|
||||
netif->dev->stats.tx_mcast_count++;
|
||||
}
|
||||
else {
|
||||
netif->dev->stats.tx_unicast_count++;
|
||||
}
|
||||
#endif
|
||||
#ifdef MODULE_GNRC_MAC
|
||||
if (netif->mac.mac_info & GNRC_NETDEV_MAC_INFO_CSMA_ENABLED) {
|
||||
res = csma_sender_csma_ca_send(dev, vector, n, &netif->mac.csma_conf);
|
||||
}
|
||||
else {
|
||||
res = dev->driver->send(dev, vector, n);
|
||||
}
|
||||
#else
|
||||
res = dev->driver->send(dev, vector, n);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
return -ENOBUFS;
|
||||
}
|
||||
/* release old data */
|
||||
gnrc_pktbuf_release(pkt);
|
||||
return res;
|
||||
}
|
||||
|
||||
int _gnrc_lwmac_parse_packet(gnrc_pktsnip_t *pkt, gnrc_lwmac_packet_info_t *info)
|
||||
{
|
||||
gnrc_netif_hdr_t *netif_hdr;
|
||||
@ -103,42 +190,42 @@ int _gnrc_lwmac_parse_packet(gnrc_pktsnip_t *pkt, gnrc_lwmac_packet_info_t *info
|
||||
return 0;
|
||||
}
|
||||
|
||||
void _gnrc_lwmac_set_netdev_state(gnrc_netdev_t *gnrc_netdev, netopt_state_t devstate)
|
||||
void _gnrc_lwmac_set_netdev_state(gnrc_netif2_t *netif, netopt_state_t devstate)
|
||||
{
|
||||
gnrc_netdev->dev->driver->set(gnrc_netdev->dev,
|
||||
NETOPT_STATE,
|
||||
&devstate,
|
||||
sizeof(devstate));
|
||||
netif->dev->driver->set(netif->dev,
|
||||
NETOPT_STATE,
|
||||
&devstate,
|
||||
sizeof(devstate));
|
||||
|
||||
#if (GNRC_LWMAC_ENABLE_DUTYCYLE_RECORD == 1)
|
||||
if (devstate == NETOPT_STATE_IDLE) {
|
||||
if (!(gnrc_netdev->lwmac.lwmac_info & GNRC_LWMAC_RADIO_IS_ON)) {
|
||||
gnrc_netdev->lwmac.last_radio_on_time_ticks = rtt_get_counter();
|
||||
gnrc_netdev->lwmac.lwmac_info |= GNRC_LWMAC_RADIO_IS_ON;
|
||||
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;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if ((devstate == NETOPT_STATE_SLEEP) &&
|
||||
(gnrc_netdev->lwmac.lwmac_info & GNRC_LWMAC_RADIO_IS_ON)) {
|
||||
gnrc_netdev->lwmac.radio_off_time_ticks = rtt_get_counter();
|
||||
(netif->mac.lwmac.lwmac_info & GNRC_LWMAC_RADIO_IS_ON)) {
|
||||
netif->mac.lwmac.radio_off_time_ticks = rtt_get_counter();
|
||||
|
||||
gnrc_netdev->lwmac.awake_duration_sum_ticks +=
|
||||
(gnrc_netdev->lwmac.radio_off_time_ticks -
|
||||
gnrc_netdev->lwmac.last_radio_on_time_ticks);
|
||||
netif->mac.lwmac.awake_duration_sum_ticks +=
|
||||
(netif->mac.lwmac.radio_off_time_ticks -
|
||||
netif->mac.lwmac.last_radio_on_time_ticks);
|
||||
|
||||
gnrc_netdev->lwmac.lwmac_info &= ~GNRC_LWMAC_RADIO_IS_ON;
|
||||
netif->mac.lwmac.lwmac_info &= ~GNRC_LWMAC_RADIO_IS_ON;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
netopt_state_t _gnrc_lwmac_get_netdev_state(gnrc_netdev_t *gnrc_netdev)
|
||||
netopt_state_t _gnrc_lwmac_get_netdev_state(gnrc_netif2_t *netif)
|
||||
{
|
||||
netopt_state_t state;
|
||||
|
||||
if (0 < gnrc_netdev->dev->driver->get(gnrc_netdev->dev,
|
||||
NETOPT_STATE,
|
||||
&state,
|
||||
sizeof(state))) {
|
||||
if (0 < netif->dev->driver->get(netif->dev,
|
||||
NETOPT_STATE,
|
||||
&state,
|
||||
sizeof(state))) {
|
||||
return state;
|
||||
}
|
||||
return -1;
|
||||
@ -165,23 +252,23 @@ int _gnrc_lwmac_dispatch_defer(gnrc_pktsnip_t *buffer[], gnrc_pktsnip_t *pkt)
|
||||
return 0;
|
||||
}
|
||||
else if (bcast &&
|
||||
(((gnrc_lwmac_hdr_t *)buffer[i]->next->data)->type == GNRC_LWMAC_FRAMETYPE_BROADCAST) &&
|
||||
(bcast->seq_nr == ((gnrc_lwmac_frame_broadcast_t *)buffer[i]->next->data)->seq_nr)) {
|
||||
/* Filter same broadcasts, compare sequence number */
|
||||
gnrc_netif_hdr_t *hdr_queued, *hdr_new;
|
||||
hdr_new = pkt->next->next->data;
|
||||
hdr_queued = buffer[i]->next->next->data;
|
||||
(((gnrc_lwmac_hdr_t *)buffer[i]->next->data)->type == GNRC_LWMAC_FRAMETYPE_BROADCAST) &&
|
||||
(bcast->seq_nr == ((gnrc_lwmac_frame_broadcast_t *)buffer[i]->next->data)->seq_nr)) {
|
||||
/* Filter same broadcasts, compare sequence number */
|
||||
gnrc_netif_hdr_t *hdr_queued, *hdr_new;
|
||||
hdr_new = pkt->next->next->data;
|
||||
hdr_queued = buffer[i]->next->next->data;
|
||||
|
||||
/* Sequence numbers match, compare source addresses */
|
||||
if ((hdr_new->src_l2addr_len == hdr_queued->src_l2addr_len) &&
|
||||
(memcmp(gnrc_netif_hdr_get_src_addr(hdr_new),
|
||||
gnrc_netif_hdr_get_src_addr(hdr_queued),
|
||||
hdr_new->src_l2addr_len) == 0)) {
|
||||
/* Source addresses match, same packet */
|
||||
DEBUG("[LWMAC] Found duplicate broadcast packet, dropping\n");
|
||||
gnrc_pktbuf_release(pkt);
|
||||
return -2;
|
||||
}
|
||||
/* Sequence numbers match, compare source addresses */
|
||||
if ((hdr_new->src_l2addr_len == hdr_queued->src_l2addr_len) &&
|
||||
(memcmp(gnrc_netif_hdr_get_src_addr(hdr_new),
|
||||
gnrc_netif_hdr_get_src_addr(hdr_queued),
|
||||
hdr_new->src_l2addr_len) == 0)) {
|
||||
/* Source addresses match, same packet */
|
||||
DEBUG("[LWMAC] Found duplicate broadcast packet, dropping\n");
|
||||
gnrc_pktbuf_release(pkt);
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,14 +52,14 @@
|
||||
*/
|
||||
#define GNRC_LWMAC_RX_FOUND_DATA (0x04U)
|
||||
|
||||
static uint8_t _packet_process_in_wait_for_wr(gnrc_netdev_t *gnrc_netdev)
|
||||
static uint8_t _packet_process_in_wait_for_wr(gnrc_netif2_t *netif)
|
||||
{
|
||||
uint8_t rx_info = 0;
|
||||
gnrc_pktsnip_t *pkt;
|
||||
|
||||
assert(gnrc_netdev != NULL);
|
||||
assert(netif != NULL);
|
||||
|
||||
while ((pkt = gnrc_priority_pktqueue_pop(&gnrc_netdev->rx.queue)) != NULL) {
|
||||
while ((pkt = gnrc_priority_pktqueue_pop(&netif->mac.rx.queue)) != NULL) {
|
||||
LOG_DEBUG("[LWMAC-rx] Inspecting pkt @ %p\n", pkt);
|
||||
|
||||
/* Parse packet */
|
||||
@ -72,13 +72,13 @@ static uint8_t _packet_process_in_wait_for_wr(gnrc_netdev_t *gnrc_netdev)
|
||||
}
|
||||
|
||||
if (info.header->type == GNRC_LWMAC_FRAMETYPE_BROADCAST) {
|
||||
_gnrc_lwmac_dispatch_defer(gnrc_netdev->rx.dispatch_buffer, pkt);
|
||||
gnrc_mac_dispatch(&gnrc_netdev->rx);
|
||||
_gnrc_lwmac_dispatch_defer(netif->mac.rx.dispatch_buffer, pkt);
|
||||
gnrc_mac_dispatch(&netif->mac.rx);
|
||||
rx_info |= GNRC_LWMAC_RX_FOUND_BROADCAST;
|
||||
/* quit listening period to avoid receiving duplicate broadcast packets */
|
||||
gnrc_netdev_lwmac_set_quit_rx(gnrc_netdev, true);
|
||||
gnrc_lwmac_set_quit_rx(netif, true);
|
||||
/* quit TX in this cycle to avoid collisions with broadcast packets */
|
||||
gnrc_netdev_lwmac_set_quit_tx(gnrc_netdev, true);
|
||||
gnrc_lwmac_set_quit_tx(netif, true);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -91,18 +91,18 @@ static uint8_t _packet_process_in_wait_for_wr(gnrc_netdev_t *gnrc_netdev)
|
||||
/* No need to keep pkt anymore */
|
||||
gnrc_pktbuf_release(pkt);
|
||||
|
||||
if (!(memcmp(&info.dst_addr.addr, &gnrc_netdev->l2_addr,
|
||||
gnrc_netdev->l2_addr_len) == 0)) {
|
||||
if (!(memcmp(&info.dst_addr.addr, &netif->l2addr,
|
||||
netif->l2addr_len) == 0)) {
|
||||
LOG_DEBUG("[LWMAC-rx] Packet is WR but not for us\n");
|
||||
/* quit TX in this cycle to avoid collisions with other senders, since
|
||||
* found ongoing WR (preamble) stream */
|
||||
gnrc_netdev_lwmac_set_quit_tx(gnrc_netdev, true);
|
||||
gnrc_lwmac_set_quit_tx(netif, true);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If reach here, the node gets a WR for itself. */
|
||||
/* Save source address for later addressing */
|
||||
gnrc_netdev->rx.l2_addr = info.src_addr;
|
||||
netif->mac.rx.l2_addr = info.src_addr;
|
||||
|
||||
rx_info |= GNRC_LWMAC_RX_FOUND_WR;
|
||||
break;
|
||||
@ -112,56 +112,56 @@ static uint8_t _packet_process_in_wait_for_wr(gnrc_netdev_t *gnrc_netdev)
|
||||
}
|
||||
|
||||
/* return false if send wa failed, otherwise return true */
|
||||
static bool _send_wa(gnrc_netdev_t *gnrc_netdev)
|
||||
static bool _send_wa(gnrc_netif2_t *netif)
|
||||
{
|
||||
gnrc_pktsnip_t *pkt;
|
||||
gnrc_pktsnip_t *pkt_lwmac;
|
||||
gnrc_netif_hdr_t *nethdr_wa;
|
||||
|
||||
assert(gnrc_netdev != NULL);
|
||||
assert(gnrc_netdev->rx.l2_addr.len != 0);
|
||||
assert(netif != NULL);
|
||||
assert(netif->mac.rx.l2_addr.len != 0);
|
||||
|
||||
/* if found ongoing transmission,
|
||||
* quit sending WA for collision avoidance. */
|
||||
if (_gnrc_lwmac_get_netdev_state(gnrc_netdev) == NETOPT_STATE_RX) {
|
||||
gnrc_netdev->rx.rx_bad_exten_count++;
|
||||
if (_gnrc_lwmac_get_netdev_state(netif) == NETOPT_STATE_RX) {
|
||||
netif->mac.rx.rx_bad_exten_count++;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Assemble WA packet */
|
||||
gnrc_lwmac_frame_wa_t lwmac_hdr;
|
||||
lwmac_hdr.header.type = GNRC_LWMAC_FRAMETYPE_WA;
|
||||
lwmac_hdr.dst_addr = gnrc_netdev->rx.l2_addr;
|
||||
lwmac_hdr.dst_addr = netif->mac.rx.l2_addr;
|
||||
|
||||
uint32_t phase_now = _gnrc_lwmac_phase_now();
|
||||
|
||||
/* 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(gnrc_netdev->lwmac.last_wakeup)) {
|
||||
if (phase_now > _gnrc_lwmac_ticks_to_phase(netif->mac.lwmac.last_wakeup)) {
|
||||
lwmac_hdr.current_phase = (phase_now -
|
||||
_gnrc_lwmac_ticks_to_phase(gnrc_netdev->lwmac.last_wakeup));
|
||||
_gnrc_lwmac_ticks_to_phase(netif->mac.lwmac.last_wakeup));
|
||||
}
|
||||
else {
|
||||
lwmac_hdr.current_phase = (phase_now + RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US)) -
|
||||
_gnrc_lwmac_ticks_to_phase(gnrc_netdev->lwmac.last_wakeup);
|
||||
_gnrc_lwmac_ticks_to_phase(netif->mac.lwmac.last_wakeup);
|
||||
}
|
||||
|
||||
pkt = gnrc_pktbuf_add(NULL, &lwmac_hdr, sizeof(lwmac_hdr), GNRC_NETTYPE_LWMAC);
|
||||
if (pkt == NULL) {
|
||||
LOG_ERROR("ERROR: [LWMAC-rx] Cannot allocate pktbuf of type GNRC_NETTYPE_LWMAC\n");
|
||||
gnrc_netdev_lwmac_set_quit_rx(gnrc_netdev, true);
|
||||
gnrc_lwmac_set_quit_rx(netif, true);
|
||||
return false;
|
||||
}
|
||||
pkt_lwmac = pkt;
|
||||
|
||||
pkt = gnrc_pktbuf_add(pkt, NULL,
|
||||
sizeof(gnrc_netif_hdr_t) + gnrc_netdev->rx.l2_addr.len,
|
||||
sizeof(gnrc_netif_hdr_t) + netif->mac.rx.l2_addr.len,
|
||||
GNRC_NETTYPE_NETIF);
|
||||
if (pkt == NULL) {
|
||||
LOG_ERROR("ERROR: [LWMAC-rx] Cannot allocate pktbuf of type GNRC_NETTYPE_NETIF\n");
|
||||
gnrc_pktbuf_release(pkt_lwmac);
|
||||
gnrc_netdev_lwmac_set_quit_rx(gnrc_netdev, true);
|
||||
gnrc_lwmac_set_quit_rx(netif, true);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -170,44 +170,44 @@ static bool _send_wa(gnrc_netdev_t *gnrc_netdev)
|
||||
nethdr_wa = (gnrc_netif_hdr_t *)(gnrc_pktsnip_search_type(pkt,
|
||||
GNRC_NETTYPE_NETIF)->data);
|
||||
/* Construct NETIF header and insert address for WA packet */
|
||||
gnrc_netif_hdr_init(nethdr_wa, 0, gnrc_netdev->rx.l2_addr.len);
|
||||
gnrc_netif_hdr_init(nethdr_wa, 0, netif->mac.rx.l2_addr.len);
|
||||
|
||||
/* Send WA as broadcast*/
|
||||
nethdr_wa->flags |= GNRC_NETIF_HDR_FLAGS_BROADCAST;
|
||||
|
||||
/* Disable Auto ACK */
|
||||
netopt_enable_t autoack = NETOPT_DISABLE;
|
||||
gnrc_netdev->dev->driver->set(gnrc_netdev->dev, NETOPT_AUTOACK, &autoack,
|
||||
sizeof(autoack));
|
||||
netif->dev->driver->set(netif->dev, NETOPT_AUTOACK, &autoack,
|
||||
sizeof(autoack));
|
||||
|
||||
/* Send WA */
|
||||
if (gnrc_netdev->send(gnrc_netdev, pkt) < 0) {
|
||||
if (_gnrc_lwmac_transmit(netif, pkt) < 0) {
|
||||
LOG_ERROR("ERROR: [LWMAC-rx] Send WA failed.");
|
||||
if (pkt != NULL) {
|
||||
gnrc_pktbuf_release(pkt);
|
||||
}
|
||||
gnrc_netdev_lwmac_set_quit_rx(gnrc_netdev, true);
|
||||
gnrc_lwmac_set_quit_rx(netif, true);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Enable Auto ACK again for data reception */
|
||||
autoack = NETOPT_ENABLE;
|
||||
gnrc_netdev->dev->driver->set(gnrc_netdev->dev, NETOPT_AUTOACK, &autoack,
|
||||
sizeof(autoack));
|
||||
netif->dev->driver->set(netif->dev, NETOPT_AUTOACK, &autoack,
|
||||
sizeof(autoack));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint8_t _packet_process_in_wait_for_data(gnrc_netdev_t *gnrc_netdev)
|
||||
static uint8_t _packet_process_in_wait_for_data(gnrc_netif2_t *netif)
|
||||
{
|
||||
uint8_t rx_info = 0;
|
||||
gnrc_pktsnip_t *pkt;
|
||||
|
||||
assert(gnrc_netdev != NULL);
|
||||
assert(netif != NULL);
|
||||
|
||||
pkt = NULL;
|
||||
|
||||
while ((pkt = gnrc_priority_pktqueue_pop(&gnrc_netdev->rx.queue)) != NULL) {
|
||||
while ((pkt = gnrc_priority_pktqueue_pop(&netif->mac.rx.queue)) != NULL) {
|
||||
LOG_DEBUG("[LWMAC-rx] Inspecting pkt @ %p\n", pkt);
|
||||
|
||||
/* Parse packet */
|
||||
@ -220,40 +220,40 @@ static uint8_t _packet_process_in_wait_for_data(gnrc_netdev_t *gnrc_netdev)
|
||||
}
|
||||
|
||||
if (info.header->type == GNRC_LWMAC_FRAMETYPE_BROADCAST) {
|
||||
_gnrc_lwmac_dispatch_defer(gnrc_netdev->rx.dispatch_buffer, pkt);
|
||||
gnrc_mac_dispatch(&gnrc_netdev->rx);
|
||||
_gnrc_lwmac_dispatch_defer(netif->mac.rx.dispatch_buffer, pkt);
|
||||
gnrc_mac_dispatch(&netif->mac.rx);
|
||||
/* quit listening period to avoid receiving duplicate broadcast packets */
|
||||
gnrc_netdev_lwmac_set_quit_rx(gnrc_netdev, true);
|
||||
gnrc_lwmac_set_quit_rx(netif, true);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(memcmp(&info.src_addr.addr, &gnrc_netdev->rx.l2_addr.addr,
|
||||
gnrc_netdev->rx.l2_addr.len) == 0)) {
|
||||
if (!(memcmp(&info.src_addr.addr, &netif->mac.rx.l2_addr.addr,
|
||||
netif->mac.rx.l2_addr.len) == 0)) {
|
||||
LOG_DEBUG("[LWMAC-rx] Packet is not from destination\n");
|
||||
gnrc_pktbuf_release(pkt);
|
||||
/* Reset timeout to wait for the data packet */
|
||||
gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_DATA);
|
||||
gnrc_lwmac_set_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_DATA, GNRC_LWMAC_DATA_DELAY_US);
|
||||
gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA);
|
||||
gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA, GNRC_LWMAC_DATA_DELAY_US);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(memcmp(&info.dst_addr.addr, &gnrc_netdev->l2_addr,
|
||||
gnrc_netdev->l2_addr_len) == 0)) {
|
||||
if (!(memcmp(&info.dst_addr.addr, &netif->l2addr,
|
||||
netif->l2addr_len) == 0)) {
|
||||
LOG_DEBUG("[LWMAC-rx] Packet is not for us\n");
|
||||
gnrc_pktbuf_release(pkt);
|
||||
/* Reset timeout to wait for the data packet */
|
||||
gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_DATA);
|
||||
gnrc_lwmac_set_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_DATA, GNRC_LWMAC_DATA_DELAY_US);
|
||||
gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA);
|
||||
gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA, GNRC_LWMAC_DATA_DELAY_US);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Sender maybe didn't get the WA */
|
||||
if (info.header->type == GNRC_LWMAC_FRAMETYPE_WR) {
|
||||
LOG_DEBUG("[LWMAC-rx] Found a WR while waiting for DATA\n");
|
||||
gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_DATA);
|
||||
gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA);
|
||||
rx_info |= GNRC_LWMAC_RX_FOUND_WR;
|
||||
/* Push WR back to rx queue */
|
||||
gnrc_mac_queue_rx_packet(&gnrc_netdev->rx, 0, pkt);
|
||||
gnrc_mac_queue_rx_packet(&netif->mac.rx, 0, pkt);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -261,10 +261,10 @@ static uint8_t _packet_process_in_wait_for_data(gnrc_netdev_t *gnrc_netdev)
|
||||
case GNRC_LWMAC_FRAMETYPE_DATA:
|
||||
case GNRC_LWMAC_FRAMETYPE_DATA_PENDING: {
|
||||
/* Receiver gets the data packet */
|
||||
_gnrc_lwmac_dispatch_defer(gnrc_netdev->rx.dispatch_buffer, pkt);
|
||||
gnrc_mac_dispatch(&gnrc_netdev->rx);
|
||||
_gnrc_lwmac_dispatch_defer(netif->mac.rx.dispatch_buffer, pkt);
|
||||
gnrc_mac_dispatch(&netif->mac.rx);
|
||||
LOG_DEBUG("[LWMAC-rx] Found DATA!\n");
|
||||
gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_DATA);
|
||||
gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA);
|
||||
rx_info |= GNRC_LWMAC_RX_FOUND_DATA;
|
||||
return rx_info;
|
||||
}
|
||||
@ -277,117 +277,117 @@ static uint8_t _packet_process_in_wait_for_data(gnrc_netdev_t *gnrc_netdev)
|
||||
return rx_info;
|
||||
}
|
||||
|
||||
void gnrc_lwmac_rx_start(gnrc_netdev_t *gnrc_netdev)
|
||||
void gnrc_lwmac_rx_start(gnrc_netif2_t *netif)
|
||||
{
|
||||
if (gnrc_netdev == NULL) {
|
||||
if (netif == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* RX address should have been reset, probably not stopped then */
|
||||
assert(gnrc_netdev->rx.l2_addr.len == 0);
|
||||
assert(netif->mac.rx.l2_addr.len == 0);
|
||||
|
||||
/* Don't attempt to send a WA if channel is busy to get timings right */
|
||||
gnrc_netdev->mac_info &= ~GNRC_NETDEV_MAC_INFO_CSMA_ENABLED;
|
||||
netif->mac.mac_info &= ~GNRC_NETIF2_MAC_INFO_CSMA_ENABLED;
|
||||
netopt_enable_t csma_disable = NETOPT_DISABLE;
|
||||
gnrc_netdev->dev->driver->set(gnrc_netdev->dev, NETOPT_CSMA, &csma_disable,
|
||||
sizeof(csma_disable));
|
||||
netif->dev->driver->set(netif->dev, NETOPT_CSMA, &csma_disable,
|
||||
sizeof(csma_disable));
|
||||
|
||||
gnrc_netdev->rx.state = GNRC_LWMAC_RX_STATE_INIT;
|
||||
netif->mac.rx.state = GNRC_LWMAC_RX_STATE_INIT;
|
||||
}
|
||||
|
||||
void gnrc_lwmac_rx_stop(gnrc_netdev_t *gnrc_netdev)
|
||||
void gnrc_lwmac_rx_stop(gnrc_netif2_t *netif)
|
||||
{
|
||||
if (!gnrc_netdev) {
|
||||
if (!netif) {
|
||||
return;
|
||||
}
|
||||
|
||||
gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_DATA);
|
||||
gnrc_netdev->rx.state = GNRC_LWMAC_RX_STATE_STOPPED;
|
||||
gnrc_netdev->rx.l2_addr.len = 0;
|
||||
gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA);
|
||||
netif->mac.rx.state = GNRC_LWMAC_RX_STATE_STOPPED;
|
||||
netif->mac.rx.l2_addr.len = 0;
|
||||
}
|
||||
|
||||
/* Returns whether rescheduling is needed or not */
|
||||
static bool _lwmac_rx_update(gnrc_netdev_t *gnrc_netdev)
|
||||
static bool _lwmac_rx_update(gnrc_netif2_t *netif)
|
||||
{
|
||||
bool reschedule = false;
|
||||
|
||||
if (!gnrc_netdev) {
|
||||
if (!netif) {
|
||||
return reschedule;
|
||||
}
|
||||
|
||||
switch (gnrc_netdev->rx.state) {
|
||||
switch (netif->mac.rx.state) {
|
||||
case GNRC_LWMAC_RX_STATE_INIT: {
|
||||
gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_DATA);
|
||||
gnrc_netdev->rx.state = GNRC_LWMAC_RX_STATE_WAIT_FOR_WR;
|
||||
gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA);
|
||||
netif->mac.rx.state = GNRC_LWMAC_RX_STATE_WAIT_FOR_WR;
|
||||
reschedule = true;
|
||||
break;
|
||||
}
|
||||
case GNRC_LWMAC_RX_STATE_WAIT_FOR_WR: {
|
||||
LOG_DEBUG("[LWMAC-rx] GNRC_LWMAC_RX_STATE_WAIT_FOR_WR\n");
|
||||
|
||||
uint8_t rx_info = _packet_process_in_wait_for_wr(gnrc_netdev);
|
||||
uint8_t rx_info = _packet_process_in_wait_for_wr(netif);
|
||||
|
||||
/* if found broadcast packet, goto rx successful */
|
||||
if (rx_info & GNRC_LWMAC_RX_FOUND_BROADCAST) {
|
||||
gnrc_netdev->rx.state = GNRC_LWMAC_RX_STATE_SUCCESSFUL;
|
||||
netif->mac.rx.state = GNRC_LWMAC_RX_STATE_SUCCESSFUL;
|
||||
reschedule = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(rx_info & GNRC_LWMAC_RX_FOUND_WR)) {
|
||||
LOG_DEBUG("[LWMAC-rx] No WR found, stop RX\n");
|
||||
gnrc_netdev->rx.rx_bad_exten_count++;
|
||||
gnrc_netdev->rx.state = GNRC_LWMAC_RX_STATE_FAILED;
|
||||
netif->mac.rx.rx_bad_exten_count++;
|
||||
netif->mac.rx.state = GNRC_LWMAC_RX_STATE_FAILED;
|
||||
reschedule = true;
|
||||
break;
|
||||
}
|
||||
|
||||
gnrc_priority_pktqueue_flush(&gnrc_netdev->rx.queue);
|
||||
gnrc_priority_pktqueue_flush(&netif->mac.rx.queue);
|
||||
/* Found WR packet (preamble), goto next state to send WA (preamble-ACK) */
|
||||
gnrc_netdev->rx.state = GNRC_LWMAC_RX_STATE_SEND_WA;
|
||||
netif->mac.rx.state = GNRC_LWMAC_RX_STATE_SEND_WA;
|
||||
reschedule = true;
|
||||
break;
|
||||
}
|
||||
case GNRC_LWMAC_RX_STATE_SEND_WA: {
|
||||
LOG_DEBUG("[LWMAC-rx] GNRC_LWMAC_RX_STATE_SEND_WA\n");
|
||||
|
||||
if (!_send_wa(gnrc_netdev)) {
|
||||
gnrc_netdev->rx.state = GNRC_LWMAC_RX_STATE_FAILED;
|
||||
if (!_send_wa(netif)) {
|
||||
netif->mac.rx.state = GNRC_LWMAC_RX_STATE_FAILED;
|
||||
reschedule = true;
|
||||
break;
|
||||
}
|
||||
|
||||
gnrc_netdev->rx.state = GNRC_LWMAC_RX_STATE_WAIT_WA_SENT;
|
||||
netif->mac.rx.state = GNRC_LWMAC_RX_STATE_WAIT_WA_SENT;
|
||||
reschedule = false;
|
||||
break;
|
||||
}
|
||||
case GNRC_LWMAC_RX_STATE_WAIT_WA_SENT: {
|
||||
LOG_DEBUG("[LWMAC-rx] GNRC_LWMAC_RX_STATE_WAIT_WA_SENT\n");
|
||||
|
||||
if (gnrc_netdev_get_tx_feedback(gnrc_netdev) == TX_FEEDBACK_UNDEF) {
|
||||
if (gnrc_netif2_get_tx_feedback(netif) == TX_FEEDBACK_UNDEF) {
|
||||
LOG_DEBUG("[LWMAC-rx] WA not yet completely sent\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/* When reach here, WA has been sent, set timeout for expected data arrival */
|
||||
gnrc_lwmac_set_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_DATA, GNRC_LWMAC_DATA_DELAY_US);
|
||||
gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA, GNRC_LWMAC_DATA_DELAY_US);
|
||||
|
||||
_gnrc_lwmac_set_netdev_state(gnrc_netdev, NETOPT_STATE_IDLE);
|
||||
gnrc_netdev->rx.state = GNRC_LWMAC_RX_STATE_WAIT_FOR_DATA;
|
||||
_gnrc_lwmac_set_netdev_state(netif, NETOPT_STATE_IDLE);
|
||||
netif->mac.rx.state = GNRC_LWMAC_RX_STATE_WAIT_FOR_DATA;
|
||||
reschedule = false;
|
||||
break;
|
||||
}
|
||||
case GNRC_LWMAC_RX_STATE_WAIT_FOR_DATA: {
|
||||
LOG_DEBUG("[LWMAC-rx] GNRC_LWMAC_RX_STATE_WAIT_FOR_DATA\n");
|
||||
|
||||
uint8_t rx_info = _packet_process_in_wait_for_data(gnrc_netdev);
|
||||
uint8_t rx_info = _packet_process_in_wait_for_data(netif);
|
||||
|
||||
/* If WA got lost we wait for data but we will be hammered with WR
|
||||
* packets. So a WR indicates a lost WA => reset RX state machine. */
|
||||
if (rx_info & GNRC_LWMAC_RX_FOUND_WR) {
|
||||
LOG_INFO("[LWMAC-rx] WA probably got lost, reset RX state machine\n");
|
||||
/* Start over again */
|
||||
gnrc_netdev->rx.state = GNRC_LWMAC_RX_STATE_INIT;
|
||||
netif->mac.rx.state = GNRC_LWMAC_RX_STATE_INIT;
|
||||
reschedule = true;
|
||||
break;
|
||||
}
|
||||
@ -396,16 +396,16 @@ static bool _lwmac_rx_update(gnrc_netdev_t *gnrc_netdev)
|
||||
* received. This won't be blocked by WRs as they restart the state
|
||||
* machine (see above).
|
||||
*/
|
||||
if (gnrc_lwmac_timeout_is_expired(gnrc_netdev, GNRC_LWMAC_TIMEOUT_DATA)) {
|
||||
if (!gnrc_netdev_get_rx_started(gnrc_netdev)) {
|
||||
if (gnrc_lwmac_timeout_is_expired(netif, GNRC_LWMAC_TIMEOUT_DATA)) {
|
||||
if (!gnrc_netif2_get_rx_started(netif)) {
|
||||
LOG_INFO("[LWMAC-rx] DATA timed out\n");
|
||||
gnrc_netdev->rx.rx_bad_exten_count++;
|
||||
gnrc_netdev->rx.state = GNRC_LWMAC_RX_STATE_FAILED;
|
||||
netif->mac.rx.rx_bad_exten_count++;
|
||||
netif->mac.rx.state = GNRC_LWMAC_RX_STATE_FAILED;
|
||||
reschedule = true;
|
||||
}
|
||||
else {
|
||||
/* If radio is receiving packet, reset wait data timeout */
|
||||
gnrc_lwmac_set_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_DATA, GNRC_LWMAC_DATA_DELAY_US);
|
||||
gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_DATA, GNRC_LWMAC_DATA_DELAY_US);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -415,7 +415,7 @@ static bool _lwmac_rx_update(gnrc_netdev_t *gnrc_netdev)
|
||||
break;
|
||||
}
|
||||
|
||||
gnrc_netdev->rx.state = GNRC_LWMAC_RX_STATE_SUCCESSFUL;
|
||||
netif->mac.rx.state = GNRC_LWMAC_RX_STATE_SUCCESSFUL;
|
||||
reschedule = true;
|
||||
break;
|
||||
}
|
||||
@ -430,8 +430,8 @@ static bool _lwmac_rx_update(gnrc_netdev_t *gnrc_netdev)
|
||||
return reschedule;
|
||||
}
|
||||
|
||||
void gnrc_lwmac_rx_update(gnrc_netdev_t *gnrc_netdev)
|
||||
void gnrc_lwmac_rx_update(gnrc_netif2_t *netif)
|
||||
{
|
||||
/* Update until no rescheduling needed */
|
||||
while (_lwmac_rx_update(gnrc_netdev)) {}
|
||||
while (_lwmac_rx_update(netif)) {}
|
||||
}
|
||||
|
@ -58,40 +58,40 @@ static int _lwmac_find_timeout(gnrc_lwmac_t *lwmac, gnrc_lwmac_timeout_type_t ty
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
inline bool gnrc_lwmac_timeout_is_running(gnrc_netdev_t *gnrc_netdev,
|
||||
inline bool gnrc_lwmac_timeout_is_running(gnrc_netif2_t *netif,
|
||||
gnrc_lwmac_timeout_type_t type)
|
||||
{
|
||||
assert(gnrc_netdev);
|
||||
return (_lwmac_find_timeout(&gnrc_netdev->lwmac, type) >= 0);
|
||||
assert(netif);
|
||||
return (_lwmac_find_timeout(&netif->mac.lwmac, type) >= 0);
|
||||
}
|
||||
|
||||
bool gnrc_lwmac_timeout_is_expired(gnrc_netdev_t *gnrc_netdev, gnrc_lwmac_timeout_type_t type)
|
||||
bool gnrc_lwmac_timeout_is_expired(gnrc_netif2_t *netif, gnrc_lwmac_timeout_type_t type)
|
||||
{
|
||||
assert(gnrc_netdev);
|
||||
assert(netif);
|
||||
|
||||
int index = _lwmac_find_timeout(&gnrc_netdev->lwmac, type);
|
||||
int index = _lwmac_find_timeout(&netif->mac.lwmac, type);
|
||||
if (index >= 0) {
|
||||
if (gnrc_netdev->lwmac.timeouts[index].expired) {
|
||||
_lwmac_clear_timeout(&gnrc_netdev->lwmac.timeouts[index]);
|
||||
if (netif->mac.lwmac.timeouts[index].expired) {
|
||||
_lwmac_clear_timeout(&netif->mac.lwmac.timeouts[index]);
|
||||
}
|
||||
return gnrc_netdev->lwmac.timeouts[index].expired;
|
||||
return netif->mac.lwmac.timeouts[index].expired;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
gnrc_lwmac_timeout_t *_lwmac_acquire_timeout(gnrc_netdev_t *gnrc_netdev,
|
||||
gnrc_lwmac_timeout_t *_lwmac_acquire_timeout(gnrc_netif2_t *netif,
|
||||
gnrc_lwmac_timeout_type_t type)
|
||||
{
|
||||
assert(gnrc_netdev);
|
||||
assert(netif);
|
||||
|
||||
if (gnrc_lwmac_timeout_is_running(gnrc_netdev, type)) {
|
||||
if (gnrc_lwmac_timeout_is_running(netif, type)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < GNRC_LWMAC_TIMEOUT_COUNT; i++) {
|
||||
if (gnrc_netdev->lwmac.timeouts[i].type == GNRC_LWMAC_TIMEOUT_DISABLED) {
|
||||
gnrc_netdev->lwmac.timeouts[i].type = type;
|
||||
return &gnrc_netdev->lwmac.timeouts[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];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
@ -104,31 +104,31 @@ void gnrc_lwmac_timeout_make_expire(gnrc_lwmac_timeout_t *timeout)
|
||||
timeout->expired = true;
|
||||
}
|
||||
|
||||
void gnrc_lwmac_clear_timeout(gnrc_netdev_t *gnrc_netdev, gnrc_lwmac_timeout_type_t type)
|
||||
void gnrc_lwmac_clear_timeout(gnrc_netif2_t *netif, gnrc_lwmac_timeout_type_t type)
|
||||
{
|
||||
assert(gnrc_netdev);
|
||||
assert(netif);
|
||||
|
||||
int index = _lwmac_find_timeout(&gnrc_netdev->lwmac, type);
|
||||
int index = _lwmac_find_timeout(&netif->mac.lwmac, type);
|
||||
if (index >= 0) {
|
||||
_lwmac_clear_timeout(&gnrc_netdev->lwmac.timeouts[index]);
|
||||
_lwmac_clear_timeout(&netif->mac.lwmac.timeouts[index]);
|
||||
}
|
||||
}
|
||||
|
||||
void gnrc_lwmac_set_timeout(gnrc_netdev_t *gnrc_netdev,
|
||||
void gnrc_lwmac_set_timeout(gnrc_netif2_t *netif,
|
||||
gnrc_lwmac_timeout_type_t type,
|
||||
uint32_t offset)
|
||||
{
|
||||
assert(gnrc_netdev);
|
||||
assert(netif);
|
||||
|
||||
gnrc_lwmac_timeout_t *timeout;
|
||||
if ((timeout = _lwmac_acquire_timeout(gnrc_netdev, type))) {
|
||||
if ((timeout = _lwmac_acquire_timeout(netif, type))) {
|
||||
DEBUG("[LWMAC] Set timeout %s in %" PRIu32 " us\n",
|
||||
lwmac_timeout_names[type], offset);
|
||||
timeout->expired = false;
|
||||
timeout->msg.type = GNRC_LWMAC_EVENT_TIMEOUT_TYPE;
|
||||
timeout->msg.content.ptr = (void *) timeout;
|
||||
xtimer_set_msg(&(timeout->timer), offset,
|
||||
&(timeout->msg), gnrc_netdev->pid);
|
||||
&(timeout->msg), netif->pid);
|
||||
}
|
||||
else {
|
||||
DEBUG("[LWMAC] Cannot set timeout %s, too many concurrent timeouts\n",
|
||||
@ -136,13 +136,13 @@ void gnrc_lwmac_set_timeout(gnrc_netdev_t *gnrc_netdev,
|
||||
}
|
||||
}
|
||||
|
||||
void gnrc_lwmac_reset_timeouts(gnrc_netdev_t *gnrc_netdev)
|
||||
void gnrc_lwmac_reset_timeouts(gnrc_netif2_t *netif)
|
||||
{
|
||||
assert(gnrc_netdev);
|
||||
assert(netif);
|
||||
|
||||
for (unsigned i = 0; i < GNRC_LWMAC_TIMEOUT_COUNT; i++) {
|
||||
if (gnrc_netdev->lwmac.timeouts[i].type != GNRC_LWMAC_TIMEOUT_DISABLED) {
|
||||
_lwmac_clear_timeout(&gnrc_netdev->lwmac.timeouts[i]);
|
||||
if (netif->mac.lwmac.timeouts[i].type != GNRC_LWMAC_TIMEOUT_DISABLED) {
|
||||
_lwmac_clear_timeout(&netif->mac.lwmac.timeouts[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,77 +49,77 @@
|
||||
*/
|
||||
#define GNRC_LWMAC_TX_FAIL (0x02U)
|
||||
|
||||
static uint8_t _send_bcast(gnrc_netdev_t *gnrc_netdev)
|
||||
static uint8_t _send_bcast(gnrc_netif2_t *netif)
|
||||
{
|
||||
assert(gnrc_netdev != NULL);
|
||||
assert(netif != NULL);
|
||||
|
||||
uint8_t tx_info = 0;
|
||||
gnrc_pktsnip_t *pkt = gnrc_netdev->tx.packet;
|
||||
gnrc_pktsnip_t *pkt = netif->mac.tx.packet;
|
||||
bool first = false;
|
||||
|
||||
if (gnrc_lwmac_timeout_is_running(gnrc_netdev, GNRC_LWMAC_TIMEOUT_BROADCAST_END)) {
|
||||
if (gnrc_lwmac_timeout_is_expired(gnrc_netdev, GNRC_LWMAC_TIMEOUT_BROADCAST_END)) {
|
||||
gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_NEXT_BROADCAST);
|
||||
if (gnrc_lwmac_timeout_is_running(netif, GNRC_LWMAC_TIMEOUT_BROADCAST_END)) {
|
||||
if (gnrc_lwmac_timeout_is_expired(netif, GNRC_LWMAC_TIMEOUT_BROADCAST_END)) {
|
||||
gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_NEXT_BROADCAST);
|
||||
gnrc_pktbuf_release(pkt);
|
||||
gnrc_netdev->tx.packet = NULL;
|
||||
netif->mac.tx.packet = NULL;
|
||||
tx_info |= GNRC_LWMAC_TX_SUCCESS;
|
||||
return tx_info;
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG_INFO("[LWMAC-tx] Initialize broadcasting\n");
|
||||
gnrc_lwmac_set_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_BROADCAST_END,
|
||||
GNRC_LWMAC_BROADCAST_DURATION_US);
|
||||
gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_BROADCAST_END,
|
||||
GNRC_LWMAC_BROADCAST_DURATION_US);
|
||||
|
||||
gnrc_pktsnip_t *pkt_payload;
|
||||
|
||||
/* Prepare packet with LWMAC header*/
|
||||
gnrc_lwmac_frame_broadcast_t hdr = {};
|
||||
hdr.header.type = GNRC_LWMAC_FRAMETYPE_BROADCAST;
|
||||
hdr.seq_nr = gnrc_netdev->tx.bcast_seqnr++;
|
||||
hdr.seq_nr = netif->mac.tx.bcast_seqnr++;
|
||||
|
||||
pkt_payload = pkt->next;
|
||||
pkt->next = gnrc_pktbuf_add(pkt->next, &hdr, sizeof(hdr), GNRC_NETTYPE_LWMAC);
|
||||
if (pkt->next == NULL) {
|
||||
LOG_ERROR("ERROR: [LWMAC-tx] Cannot allocate pktbuf of type FRAMETYPE_BROADCAST\n");
|
||||
gnrc_netdev->tx.packet->next = pkt_payload;
|
||||
netif->mac.tx.packet->next = pkt_payload;
|
||||
/* Drop the broadcast packet */
|
||||
LOG_ERROR("ERROR: [LWMAC-tx] Memory maybe full, drop the broadcast packet\n");
|
||||
gnrc_pktbuf_release(gnrc_netdev->tx.packet);
|
||||
gnrc_pktbuf_release(netif->mac.tx.packet);
|
||||
/* clear packet point to avoid TX retry */
|
||||
gnrc_netdev->tx.packet = NULL;
|
||||
netif->mac.tx.packet = NULL;
|
||||
tx_info |= GNRC_LWMAC_TX_FAIL;
|
||||
return tx_info;
|
||||
}
|
||||
|
||||
/* No Auto-ACK for broadcast packets */
|
||||
netopt_enable_t autoack = NETOPT_DISABLE;
|
||||
gnrc_netdev->dev->driver->set(gnrc_netdev->dev, NETOPT_AUTOACK, &autoack,
|
||||
sizeof(autoack));
|
||||
netif->dev->driver->set(netif->dev, NETOPT_AUTOACK, &autoack,
|
||||
sizeof(autoack));
|
||||
first = true;
|
||||
}
|
||||
|
||||
if (gnrc_lwmac_timeout_is_expired(gnrc_netdev, GNRC_LWMAC_TIMEOUT_NEXT_BROADCAST) ||
|
||||
if (gnrc_lwmac_timeout_is_expired(netif, GNRC_LWMAC_TIMEOUT_NEXT_BROADCAST) ||
|
||||
first) {
|
||||
/* if found ongoing transmission, quit this cycle for collision avoidance.
|
||||
* Broadcast packet will be re-queued and try to send in the next cycle. */
|
||||
if (_gnrc_lwmac_get_netdev_state(gnrc_netdev) == NETOPT_STATE_RX) {
|
||||
* Broadcast packet will be re-queued and try to send in the next cycle. */
|
||||
if (_gnrc_lwmac_get_netdev_state(netif) == NETOPT_STATE_RX) {
|
||||
/* save pointer to netif header */
|
||||
gnrc_pktsnip_t *netif = pkt->next->next;
|
||||
gnrc_pktsnip_t *netif_snip = pkt->next->next;
|
||||
|
||||
/* remove LWMAC header */
|
||||
pkt->next->next = NULL;
|
||||
gnrc_pktbuf_release(pkt->next);
|
||||
|
||||
/* make append netif header after payload again */
|
||||
pkt->next = netif;
|
||||
pkt->next = netif_snip;
|
||||
|
||||
if (!gnrc_mac_queue_tx_packet(&gnrc_netdev->tx, 0, gnrc_netdev->tx.packet)) {
|
||||
gnrc_pktbuf_release(gnrc_netdev->tx.packet);
|
||||
if (!gnrc_mac_queue_tx_packet(&netif->mac.tx, 0, netif->mac.tx.packet)) {
|
||||
gnrc_pktbuf_release(netif->mac.tx.packet);
|
||||
LOG_WARNING("WARNING: [LWMAC-tx] TX queue full, drop packet\n");
|
||||
}
|
||||
/* drop pointer so it wont be free'd */
|
||||
gnrc_netdev->tx.packet = NULL;
|
||||
netif->mac.tx.packet = NULL;
|
||||
tx_info |= GNRC_LWMAC_TX_FAIL;
|
||||
return tx_info;
|
||||
}
|
||||
@ -127,24 +127,24 @@ static uint8_t _send_bcast(gnrc_netdev_t *gnrc_netdev)
|
||||
/* Don't let the packet be released yet, we want to send it again */
|
||||
gnrc_pktbuf_hold(pkt, 1);
|
||||
|
||||
int res = gnrc_netdev->send(gnrc_netdev, pkt);
|
||||
int res = _gnrc_lwmac_transmit(netif, pkt);
|
||||
if (res < 0) {
|
||||
LOG_ERROR("ERROR: [LWMAC-tx] Send broadcast pkt failed.");
|
||||
tx_info |= GNRC_LWMAC_TX_FAIL;
|
||||
return tx_info;
|
||||
}
|
||||
|
||||
gnrc_lwmac_set_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_NEXT_BROADCAST,
|
||||
GNRC_LWMAC_TIME_BETWEEN_BROADCAST_US);
|
||||
gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_NEXT_BROADCAST,
|
||||
GNRC_LWMAC_TIME_BETWEEN_BROADCAST_US);
|
||||
LOG_INFO("[LWMAC-tx] Broadcast sent\n");
|
||||
}
|
||||
|
||||
return tx_info;
|
||||
}
|
||||
|
||||
static uint8_t _send_wr(gnrc_netdev_t *gnrc_netdev)
|
||||
static uint8_t _send_wr(gnrc_netif2_t *netif)
|
||||
{
|
||||
assert(gnrc_netdev != NULL);
|
||||
assert(netif != NULL);
|
||||
|
||||
uint8_t tx_info = 0;
|
||||
gnrc_pktsnip_t *pkt;
|
||||
@ -153,13 +153,13 @@ static uint8_t _send_wr(gnrc_netdev_t *gnrc_netdev)
|
||||
|
||||
/* if found ongoing transmission, quit this cycle for collision avoidance.
|
||||
* Data packet will be re-queued and try to send in the next cycle. */
|
||||
if (_gnrc_lwmac_get_netdev_state(gnrc_netdev) == NETOPT_STATE_RX) {
|
||||
if (!gnrc_mac_queue_tx_packet(&gnrc_netdev->tx, 0, gnrc_netdev->tx.packet)) {
|
||||
gnrc_pktbuf_release(gnrc_netdev->tx.packet);
|
||||
if (_gnrc_lwmac_get_netdev_state(netif) == NETOPT_STATE_RX) {
|
||||
if (!gnrc_mac_queue_tx_packet(&netif->mac.tx, 0, netif->mac.tx.packet)) {
|
||||
gnrc_pktbuf_release(netif->mac.tx.packet);
|
||||
LOG_WARNING("WARNING: [LWMAC-tx] TX queue full, drop packet\n");
|
||||
}
|
||||
/* drop pointer so it wont be free'd */
|
||||
gnrc_netdev->tx.packet = NULL;
|
||||
netif->mac.tx.packet = NULL;
|
||||
tx_info |= GNRC_LWMAC_TX_FAIL;
|
||||
return tx_info;
|
||||
}
|
||||
@ -167,17 +167,17 @@ static uint8_t _send_wr(gnrc_netdev_t *gnrc_netdev)
|
||||
/* Assemble WR */
|
||||
gnrc_lwmac_frame_wr_t wr_hdr = {};
|
||||
wr_hdr.header.type = GNRC_LWMAC_FRAMETYPE_WR;
|
||||
memcpy(&(wr_hdr.dst_addr.addr), gnrc_netdev->tx.current_neighbor->l2_addr,
|
||||
gnrc_netdev->tx.current_neighbor->l2_addr_len);
|
||||
wr_hdr.dst_addr.len = gnrc_netdev->tx.current_neighbor->l2_addr_len;
|
||||
memcpy(&(wr_hdr.dst_addr.addr), netif->mac.tx.current_neighbor->l2_addr,
|
||||
netif->mac.tx.current_neighbor->l2_addr_len);
|
||||
wr_hdr.dst_addr.len = netif->mac.tx.current_neighbor->l2_addr_len;
|
||||
|
||||
pkt = gnrc_pktbuf_add(NULL, &wr_hdr, sizeof(wr_hdr), GNRC_NETTYPE_LWMAC);
|
||||
if (pkt == NULL) {
|
||||
LOG_ERROR("ERROR: [LWMAC-tx] Cannot allocate pktbuf of type GNRC_NETTYPE_LWMAC\n");
|
||||
gnrc_pktbuf_release(gnrc_netdev->tx.packet);
|
||||
gnrc_pktbuf_release(netif->mac.tx.packet);
|
||||
LOG_ERROR("ERROR: [LWMAC-tx] Memory maybe full, drop the data packet\n");
|
||||
/* clear packet point to avoid TX retry */
|
||||
gnrc_netdev->tx.packet = NULL;
|
||||
netif->mac.tx.packet = NULL;
|
||||
tx_info |= GNRC_LWMAC_TX_FAIL;
|
||||
return tx_info;
|
||||
}
|
||||
@ -190,9 +190,9 @@ static uint8_t _send_wr(gnrc_netdev_t *gnrc_netdev)
|
||||
LOG_ERROR("ERROR: [LWMAC-tx] Cannot allocate pktbuf of type GNRC_NETTYPE_NETIF\n");
|
||||
gnrc_pktbuf_release(pkt_lwmac);
|
||||
LOG_ERROR("ERROR: [LWMAC-tx] Memory maybe full, drop the data packet\n");
|
||||
gnrc_pktbuf_release(gnrc_netdev->tx.packet);
|
||||
gnrc_pktbuf_release(netif->mac.tx.packet);
|
||||
/* clear packet point to avoid TX retry */
|
||||
gnrc_netdev->tx.packet = NULL;
|
||||
netif->mac.tx.packet = NULL;
|
||||
tx_info |= GNRC_LWMAC_TX_FAIL;
|
||||
return tx_info;
|
||||
}
|
||||
@ -209,12 +209,12 @@ static uint8_t _send_wr(gnrc_netdev_t *gnrc_netdev)
|
||||
|
||||
/* Disable Auto ACK */
|
||||
netopt_enable_t autoack = NETOPT_DISABLE;
|
||||
gnrc_netdev->dev->driver->set(gnrc_netdev->dev, NETOPT_AUTOACK, &autoack,
|
||||
sizeof(autoack));
|
||||
netif->dev->driver->set(netif->dev, NETOPT_AUTOACK, &autoack,
|
||||
sizeof(autoack));
|
||||
|
||||
/* Prepare WR, this will discard any frame in the transceiver that has
|
||||
* possibly arrived in the meantime but we don't care at this point. */
|
||||
int res = gnrc_netdev->send(gnrc_netdev, pkt);
|
||||
* possibly arrived in the meantime but we don't care at this point. */
|
||||
int res = _gnrc_lwmac_transmit(netif, pkt);
|
||||
if (res < 0) {
|
||||
LOG_ERROR("ERROR: [LWMAC-tx] Send WR failed.");
|
||||
if (pkt != NULL) {
|
||||
@ -224,13 +224,13 @@ static uint8_t _send_wr(gnrc_netdev_t *gnrc_netdev)
|
||||
return tx_info;
|
||||
}
|
||||
|
||||
gnrc_priority_pktqueue_flush(&gnrc_netdev->rx.queue);
|
||||
gnrc_priority_pktqueue_flush(&netif->mac.rx.queue);
|
||||
return tx_info;
|
||||
}
|
||||
|
||||
static uint8_t _packet_process_in_wait_for_wa(gnrc_netdev_t *gnrc_netdev)
|
||||
static uint8_t _packet_process_in_wait_for_wa(gnrc_netif2_t *netif)
|
||||
{
|
||||
assert(gnrc_netdev != NULL);
|
||||
assert(netif != NULL);
|
||||
|
||||
uint8_t tx_info = 0;
|
||||
gnrc_pktsnip_t *pkt;
|
||||
@ -238,7 +238,7 @@ static uint8_t _packet_process_in_wait_for_wa(gnrc_netdev_t *gnrc_netdev)
|
||||
bool postponed = false;
|
||||
bool from_expected_destination = false;
|
||||
|
||||
while ((pkt = gnrc_priority_pktqueue_pop(&gnrc_netdev->rx.queue)) != NULL) {
|
||||
while ((pkt = gnrc_priority_pktqueue_pop(&netif->mac.rx.queue)) != NULL) {
|
||||
LOG_DEBUG("[LWMAC-tx] Inspecting pkt @ %p\n", pkt);
|
||||
|
||||
/* Parse packet */
|
||||
@ -251,14 +251,14 @@ static uint8_t _packet_process_in_wait_for_wa(gnrc_netdev_t *gnrc_netdev)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (memcmp(&info.src_addr.addr, &gnrc_netdev->tx.current_neighbor->l2_addr,
|
||||
gnrc_netdev->tx.current_neighbor->l2_addr_len) == 0) {
|
||||
if (memcmp(&info.src_addr.addr, &netif->mac.tx.current_neighbor->l2_addr,
|
||||
netif->mac.tx.current_neighbor->l2_addr_len) == 0) {
|
||||
from_expected_destination = true;
|
||||
}
|
||||
|
||||
if (info.header->type == GNRC_LWMAC_FRAMETYPE_BROADCAST) {
|
||||
_gnrc_lwmac_dispatch_defer(gnrc_netdev->rx.dispatch_buffer, pkt);
|
||||
gnrc_mac_dispatch(&gnrc_netdev->rx);
|
||||
_gnrc_lwmac_dispatch_defer(netif->mac.rx.dispatch_buffer, pkt);
|
||||
gnrc_mac_dispatch(&netif->mac.rx);
|
||||
/* Drop pointer to it can't get released */
|
||||
pkt = NULL;
|
||||
continue;
|
||||
@ -267,14 +267,14 @@ static uint8_t _packet_process_in_wait_for_wa(gnrc_netdev_t *gnrc_netdev)
|
||||
/* Check if destination is talking to another node. It will sleep
|
||||
* after a finished transaction so there's no point in trying any
|
||||
* further now. */
|
||||
if (!(memcmp(&info.dst_addr.addr, &gnrc_netdev->l2_addr,
|
||||
gnrc_netdev->l2_addr_len) == 0) && from_expected_destination) {
|
||||
if (!gnrc_mac_queue_tx_packet(&gnrc_netdev->tx, 0, gnrc_netdev->tx.packet)) {
|
||||
gnrc_pktbuf_release(gnrc_netdev->tx.packet);
|
||||
if (!(memcmp(&info.dst_addr.addr, &netif->l2addr,
|
||||
netif->l2addr_len) == 0) && from_expected_destination) {
|
||||
if (!gnrc_mac_queue_tx_packet(&netif->mac.tx, 0, netif->mac.tx.packet)) {
|
||||
gnrc_pktbuf_release(netif->mac.tx.packet);
|
||||
LOG_WARNING("WARNING: [LWMAC-tx] TX queue full, drop packet\n");
|
||||
}
|
||||
/* drop pointer so it wont be free'd */
|
||||
gnrc_netdev->tx.packet = NULL;
|
||||
netif->mac.tx.packet = NULL;
|
||||
postponed = true;
|
||||
gnrc_pktbuf_release(pkt);
|
||||
break;
|
||||
@ -283,12 +283,12 @@ static uint8_t _packet_process_in_wait_for_wa(gnrc_netdev_t *gnrc_netdev)
|
||||
/* if found anther node is also trying to send data,
|
||||
* quit this cycle for collision avoidance. */
|
||||
if (info.header->type == GNRC_LWMAC_FRAMETYPE_WR) {
|
||||
if (!gnrc_mac_queue_tx_packet(&gnrc_netdev->tx, 0, gnrc_netdev->tx.packet)) {
|
||||
gnrc_pktbuf_release(gnrc_netdev->tx.packet);
|
||||
if (!gnrc_mac_queue_tx_packet(&netif->mac.tx, 0, netif->mac.tx.packet)) {
|
||||
gnrc_pktbuf_release(netif->mac.tx.packet);
|
||||
LOG_WARNING("WARNING: [LWMAC-tx] TX queue full, drop packet\n");
|
||||
}
|
||||
/* drop pointer so it wont be free'd */
|
||||
gnrc_netdev->tx.packet = NULL;
|
||||
netif->mac.tx.packet = NULL;
|
||||
postponed = true;
|
||||
gnrc_pktbuf_release(pkt);
|
||||
break;
|
||||
@ -302,33 +302,33 @@ static uint8_t _packet_process_in_wait_for_wa(gnrc_netdev_t *gnrc_netdev)
|
||||
|
||||
if (from_expected_destination) {
|
||||
/* calculate the phase of the receiver based on WA */
|
||||
gnrc_netdev->tx.timestamp = _gnrc_lwmac_phase_now();
|
||||
netif->mac.tx.timestamp = _gnrc_lwmac_phase_now();
|
||||
gnrc_lwmac_frame_wa_t *wa_hdr;
|
||||
wa_hdr = (gnrc_pktsnip_search_type(pkt, GNRC_NETTYPE_LWMAC))->data;
|
||||
|
||||
if (gnrc_netdev->tx.timestamp >= wa_hdr->current_phase) {
|
||||
gnrc_netdev->tx.timestamp = gnrc_netdev->tx.timestamp -
|
||||
wa_hdr->current_phase;
|
||||
if (netif->mac.tx.timestamp >= wa_hdr->current_phase) {
|
||||
netif->mac.tx.timestamp = netif->mac.tx.timestamp -
|
||||
wa_hdr->current_phase;
|
||||
}
|
||||
else {
|
||||
gnrc_netdev->tx.timestamp += RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US);
|
||||
gnrc_netdev->tx.timestamp -= wa_hdr->current_phase;
|
||||
netif->mac.tx.timestamp += RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US);
|
||||
netif->mac.tx.timestamp -= wa_hdr->current_phase;
|
||||
}
|
||||
|
||||
uint32_t own_phase;
|
||||
own_phase = _gnrc_lwmac_ticks_to_phase(gnrc_netdev->lwmac.last_wakeup);
|
||||
own_phase = _gnrc_lwmac_ticks_to_phase(netif->mac.lwmac.last_wakeup);
|
||||
|
||||
if (own_phase >= gnrc_netdev->tx.timestamp) {
|
||||
own_phase = own_phase - gnrc_netdev->tx.timestamp;
|
||||
if (own_phase >= netif->mac.tx.timestamp) {
|
||||
own_phase = own_phase - netif->mac.tx.timestamp;
|
||||
}
|
||||
else {
|
||||
own_phase = gnrc_netdev->tx.timestamp - own_phase;
|
||||
own_phase = netif->mac.tx.timestamp - own_phase;
|
||||
}
|
||||
|
||||
if ((own_phase < RTT_US_TO_TICKS((3 * GNRC_LWMAC_WAKEUP_DURATION_US / 2))) ||
|
||||
(own_phase > RTT_US_TO_TICKS(GNRC_LWMAC_WAKEUP_INTERVAL_US -
|
||||
(3 * GNRC_LWMAC_WAKEUP_DURATION_US / 2)))) {
|
||||
gnrc_netdev_lwmac_set_phase_backoff(gnrc_netdev, true);
|
||||
gnrc_lwmac_set_phase_backoff(netif, true);
|
||||
LOG_WARNING("WARNING: [LWMAC-tx] phase close\n");
|
||||
}
|
||||
}
|
||||
@ -342,7 +342,7 @@ static uint8_t _packet_process_in_wait_for_wa(gnrc_netdev_t *gnrc_netdev)
|
||||
}
|
||||
|
||||
/* All checks passed so this must be a valid WA */
|
||||
gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_WR);
|
||||
gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_WR);
|
||||
|
||||
found_wa = true;
|
||||
break;
|
||||
@ -360,39 +360,39 @@ static uint8_t _packet_process_in_wait_for_wa(gnrc_netdev_t *gnrc_netdev)
|
||||
}
|
||||
|
||||
/* Save newly calculated phase for destination */
|
||||
gnrc_netdev->tx.current_neighbor->phase = gnrc_netdev->tx.timestamp;
|
||||
LOG_INFO("[LWMAC-tx] New phase: %" PRIu32 "\n", gnrc_netdev->tx.timestamp);
|
||||
netif->mac.tx.current_neighbor->phase = netif->mac.tx.timestamp;
|
||||
LOG_INFO("[LWMAC-tx] New phase: %" PRIu32 "\n", netif->mac.tx.timestamp);
|
||||
|
||||
/* We've got our WA, so discard the rest, TODO: no flushing */
|
||||
gnrc_priority_pktqueue_flush(&gnrc_netdev->rx.queue);
|
||||
gnrc_priority_pktqueue_flush(&netif->mac.rx.queue);
|
||||
|
||||
tx_info |= GNRC_LWMAC_TX_SUCCESS;
|
||||
return tx_info;
|
||||
}
|
||||
|
||||
/* return false if send data failed, otherwise return true */
|
||||
static bool _send_data(gnrc_netdev_t *gnrc_netdev)
|
||||
static bool _send_data(gnrc_netif2_t *netif)
|
||||
{
|
||||
assert(gnrc_netdev != NULL);
|
||||
assert(netif != NULL);
|
||||
|
||||
gnrc_pktsnip_t *pkt = gnrc_netdev->tx.packet;
|
||||
gnrc_pktsnip_t *pkt = netif->mac.tx.packet;
|
||||
gnrc_pktsnip_t *pkt_payload;
|
||||
|
||||
/* Enable Auto ACK again */
|
||||
netopt_enable_t autoack = NETOPT_ENABLE;
|
||||
gnrc_netdev->dev->driver->set(gnrc_netdev->dev, NETOPT_AUTOACK,
|
||||
&autoack, sizeof(autoack));
|
||||
netif->dev->driver->set(netif->dev, NETOPT_AUTOACK,
|
||||
&autoack, sizeof(autoack));
|
||||
|
||||
/* It's okay to retry sending DATA. Timing doesn't matter anymore and
|
||||
* destination is waiting for a certain amount of time. */
|
||||
uint8_t csma_retries = GNRC_LWMAC_DATA_CSMA_RETRIES;
|
||||
gnrc_netdev->dev->driver->set(gnrc_netdev->dev, NETOPT_CSMA_RETRIES,
|
||||
&csma_retries, sizeof(csma_retries));
|
||||
netif->dev->driver->set(netif->dev, NETOPT_CSMA_RETRIES,
|
||||
&csma_retries, sizeof(csma_retries));
|
||||
|
||||
gnrc_netdev->mac_info |= GNRC_NETDEV_MAC_INFO_CSMA_ENABLED;
|
||||
netif->mac.mac_info |= GNRC_NETIF2_MAC_INFO_CSMA_ENABLED;
|
||||
netopt_enable_t csma_enable = NETOPT_ENABLE;
|
||||
gnrc_netdev->dev->driver->set(gnrc_netdev->dev, NETOPT_CSMA,
|
||||
&csma_enable, sizeof(csma_enable));
|
||||
netif->dev->driver->set(netif->dev, NETOPT_CSMA,
|
||||
&csma_enable, sizeof(csma_enable));
|
||||
|
||||
pkt_payload = pkt->next;
|
||||
|
||||
@ -403,198 +403,198 @@ static bool _send_data(gnrc_netdev_t *gnrc_netdev)
|
||||
* In case the sender has no more packet for the receiver, it simply sets the
|
||||
* data type to FRAMETYPE_DATA. */
|
||||
gnrc_lwmac_hdr_t hdr;
|
||||
if ((gnrc_priority_pktqueue_length(&gnrc_netdev->tx.current_neighbor->queue) > 0) &&
|
||||
(gnrc_netdev->tx.tx_burst_count < GNRC_LWMAC_MAX_TX_BURST_PKT_NUM)) {
|
||||
if ((gnrc_priority_pktqueue_length(&netif->mac.tx.current_neighbor->queue) > 0) &&
|
||||
(netif->mac.tx.tx_burst_count < GNRC_LWMAC_MAX_TX_BURST_PKT_NUM)) {
|
||||
hdr.type = GNRC_LWMAC_FRAMETYPE_DATA_PENDING;
|
||||
gnrc_netdev_lwmac_set_tx_continue(gnrc_netdev, true);
|
||||
gnrc_netdev->tx.tx_burst_count++;
|
||||
gnrc_lwmac_set_tx_continue(netif, true);
|
||||
netif->mac.tx.tx_burst_count++;
|
||||
}
|
||||
else {
|
||||
hdr.type = GNRC_LWMAC_FRAMETYPE_DATA;
|
||||
gnrc_netdev_lwmac_set_tx_continue(gnrc_netdev, false);
|
||||
gnrc_lwmac_set_tx_continue(netif, false);
|
||||
}
|
||||
|
||||
pkt->next = gnrc_pktbuf_add(pkt->next, &hdr, sizeof(hdr), GNRC_NETTYPE_LWMAC);
|
||||
if (pkt->next == NULL) {
|
||||
LOG_ERROR("ERROR: [LWMAC-tx] Cannot allocate pktbuf of type GNRC_NETTYPE_LWMAC\n");
|
||||
LOG_ERROR("ERROR: [LWMAC-tx] Memory maybe full, drop the data packet\n");
|
||||
gnrc_netdev->tx.packet->next = pkt_payload;
|
||||
gnrc_pktbuf_release(gnrc_netdev->tx.packet);
|
||||
netif->mac.tx.packet->next = pkt_payload;
|
||||
gnrc_pktbuf_release(netif->mac.tx.packet);
|
||||
/* clear packet point to avoid TX retry */
|
||||
gnrc_netdev->tx.packet = NULL;
|
||||
netif->mac.tx.packet = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* if found ongoing transmission, quit this cycle for collision avoidance.
|
||||
* Data packet will be re-queued and try to send in the next cycle. */
|
||||
if (_gnrc_lwmac_get_netdev_state(gnrc_netdev) == NETOPT_STATE_RX) {
|
||||
if (_gnrc_lwmac_get_netdev_state(netif) == NETOPT_STATE_RX) {
|
||||
/* save pointer to netif header */
|
||||
gnrc_pktsnip_t *netif = pkt->next->next;
|
||||
gnrc_pktsnip_t *netif_snip = pkt->next->next;
|
||||
|
||||
/* remove LWMAC header */
|
||||
pkt->next->next = NULL;
|
||||
gnrc_pktbuf_release(pkt->next);
|
||||
|
||||
/* make append netif header after payload again */
|
||||
pkt->next = netif;
|
||||
pkt->next = netif_snip;
|
||||
|
||||
if (!gnrc_mac_queue_tx_packet(&gnrc_netdev->tx, 0, gnrc_netdev->tx.packet)) {
|
||||
gnrc_pktbuf_release(gnrc_netdev->tx.packet);
|
||||
if (!gnrc_mac_queue_tx_packet(&netif->mac.tx, 0, netif->mac.tx.packet)) {
|
||||
gnrc_pktbuf_release(netif->mac.tx.packet);
|
||||
LOG_WARNING("WARNING: [LWMAC-tx] TX queue full, drop packet\n");
|
||||
}
|
||||
/* drop pointer so it wont be free'd */
|
||||
gnrc_netdev->tx.packet = NULL;
|
||||
netif->mac.tx.packet = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Send data */
|
||||
int res = gnrc_netdev->send(gnrc_netdev, pkt);
|
||||
int res = _gnrc_lwmac_transmit(netif, pkt);
|
||||
if (res < 0) {
|
||||
LOG_ERROR("ERROR: [LWMAC-tx] Send data failed.");
|
||||
if (pkt != NULL) {
|
||||
gnrc_pktbuf_release(pkt);
|
||||
}
|
||||
/* clear packet point to avoid TX retry */
|
||||
gnrc_netdev->tx.packet = NULL;
|
||||
netif->mac.tx.packet = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Packet has been released by netdev, so drop pointer */
|
||||
gnrc_netdev->tx.packet = NULL;
|
||||
netif->mac.tx.packet = NULL;
|
||||
|
||||
DEBUG("[LWMAC-tx]: spent %lu WR in TX\n", gnrc_netdev->tx.wr_sent);
|
||||
DEBUG("[LWMAC-tx]: spent %lu WR in TX\n", netif->mac.tx.wr_sent);
|
||||
|
||||
#if (LWMAC_ENABLE_DUTYCYLE_RECORD == 1)
|
||||
gnrc_netdev->lwmac.pkt_start_sending_time_ticks =
|
||||
rtt_get_counter() - gnrc_netdev->lwmac.pkt_start_sending_time_ticks;
|
||||
netif->mac.lwmac.pkt_start_sending_time_ticks =
|
||||
rtt_get_counter() - netif->mac.lwmac.pkt_start_sending_time_ticks;
|
||||
DEBUG("[LWMAC-tx]: pkt sending delay in TX: %lu us\n",
|
||||
RTT_TICKS_TO_US(gnrc_netdev->lwmac.pkt_start_sending_time_ticks));
|
||||
RTT_TICKS_TO_US(netif->mac.lwmac.pkt_start_sending_time_ticks));
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void gnrc_lwmac_tx_start(gnrc_netdev_t *gnrc_netdev,
|
||||
void gnrc_lwmac_tx_start(gnrc_netif2_t *netif,
|
||||
gnrc_pktsnip_t *pkt,
|
||||
gnrc_mac_tx_neighbor_t *neighbor)
|
||||
{
|
||||
assert(gnrc_netdev != NULL);
|
||||
assert(netif != NULL);
|
||||
assert(pkt != NULL);
|
||||
assert(neighbor != NULL);
|
||||
|
||||
if (gnrc_netdev->tx.packet) {
|
||||
if (netif->mac.tx.packet) {
|
||||
LOG_WARNING("WARNING: [LWMAC-tx] Starting but tx.packet is still set\n");
|
||||
gnrc_pktbuf_release(gnrc_netdev->tx.packet);
|
||||
gnrc_pktbuf_release(netif->mac.tx.packet);
|
||||
}
|
||||
|
||||
gnrc_netdev->tx.packet = pkt;
|
||||
gnrc_netdev->tx.current_neighbor = neighbor;
|
||||
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_INIT;
|
||||
gnrc_netdev->tx.wr_sent = 0;
|
||||
netif->mac.tx.packet = pkt;
|
||||
netif->mac.tx.current_neighbor = neighbor;
|
||||
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_INIT;
|
||||
netif->mac.tx.wr_sent = 0;
|
||||
|
||||
#if (LWMAC_ENABLE_DUTYCYLE_RECORD == 1)
|
||||
gnrc_netdev->lwmac.pkt_start_sending_time_ticks = rtt_get_counter();
|
||||
netif->mac.lwmac.pkt_start_sending_time_ticks = rtt_get_counter();
|
||||
#endif
|
||||
}
|
||||
|
||||
void gnrc_lwmac_tx_stop(gnrc_netdev_t *gnrc_netdev)
|
||||
void gnrc_lwmac_tx_stop(gnrc_netif2_t *netif)
|
||||
{
|
||||
assert(gnrc_netdev != NULL);
|
||||
assert(netif != NULL);
|
||||
|
||||
gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_WR);
|
||||
gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_NO_RESPONSE);
|
||||
gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_NEXT_BROADCAST);
|
||||
gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_BROADCAST_END);
|
||||
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_STOPPED;
|
||||
gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_WR);
|
||||
gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_NO_RESPONSE);
|
||||
gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_NEXT_BROADCAST);
|
||||
gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_BROADCAST_END);
|
||||
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_STOPPED;
|
||||
|
||||
/* Release packet in case of failure */
|
||||
if (gnrc_netdev->tx.packet) {
|
||||
if (gnrc_netdev->tx.tx_retry_count >= GNRC_LWMAC_MAX_DATA_TX_RETRIES) {
|
||||
gnrc_netdev->tx.tx_retry_count = 0;
|
||||
gnrc_pktbuf_release(gnrc_netdev->tx.packet);
|
||||
gnrc_netdev->tx.packet = NULL;
|
||||
if (netif->mac.tx.packet) {
|
||||
if (netif->mac.tx.tx_retry_count >= GNRC_LWMAC_MAX_DATA_TX_RETRIES) {
|
||||
netif->mac.tx.tx_retry_count = 0;
|
||||
gnrc_pktbuf_release(netif->mac.tx.packet);
|
||||
netif->mac.tx.packet = NULL;
|
||||
LOG_WARNING("WARNING: [LWMAC-tx] Drop TX packet\n");
|
||||
}
|
||||
else {
|
||||
gnrc_netdev->tx.tx_retry_count++;
|
||||
netif->mac.tx.tx_retry_count++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!gnrc_netdev_lwmac_get_tx_continue(gnrc_netdev)) {
|
||||
gnrc_netdev->tx.current_neighbor = NULL;
|
||||
if (!gnrc_lwmac_get_tx_continue(netif)) {
|
||||
netif->mac.tx.current_neighbor = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns whether rescheduling is needed or not */
|
||||
static bool _lwmac_tx_update(gnrc_netdev_t *gnrc_netdev)
|
||||
static bool _lwmac_tx_update(gnrc_netif2_t *netif)
|
||||
{
|
||||
assert(gnrc_netdev != NULL);
|
||||
assert(netif != NULL);
|
||||
|
||||
bool reschedule = false;
|
||||
|
||||
switch (gnrc_netdev->tx.state) {
|
||||
switch (netif->mac.tx.state) {
|
||||
case GNRC_LWMAC_TX_STATE_INIT: {
|
||||
gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_WR);
|
||||
gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_NO_RESPONSE);
|
||||
gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_NEXT_BROADCAST);
|
||||
gnrc_lwmac_clear_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_BROADCAST_END);
|
||||
gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_WR);
|
||||
gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_NO_RESPONSE);
|
||||
gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_NEXT_BROADCAST);
|
||||
gnrc_lwmac_clear_timeout(netif, GNRC_LWMAC_TIMEOUT_BROADCAST_END);
|
||||
|
||||
/* if found ongoing transmission,
|
||||
* quit this cycle for collision avoidance. */
|
||||
if (_gnrc_lwmac_get_netdev_state(gnrc_netdev) == NETOPT_STATE_RX) {
|
||||
if (!gnrc_mac_queue_tx_packet(&gnrc_netdev->tx, 0, gnrc_netdev->tx.packet)) {
|
||||
gnrc_pktbuf_release(gnrc_netdev->tx.packet);
|
||||
if (_gnrc_lwmac_get_netdev_state(netif) == NETOPT_STATE_RX) {
|
||||
if (!gnrc_mac_queue_tx_packet(&netif->mac.tx, 0, netif->mac.tx.packet)) {
|
||||
gnrc_pktbuf_release(netif->mac.tx.packet);
|
||||
LOG_WARNING("WARNING: [LWMAC-tx] TX queue full, drop packet\n");
|
||||
}
|
||||
/* drop pointer so it wont be free'd */
|
||||
gnrc_netdev->tx.packet = NULL;
|
||||
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
|
||||
netif->mac.tx.packet = NULL;
|
||||
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
|
||||
reschedule = true;
|
||||
break;
|
||||
}
|
||||
|
||||
/* check if the packet is for broadcast */
|
||||
if (gnrc_netif_hdr_get_flag(gnrc_netdev->tx.packet) &
|
||||
if (gnrc_netif_hdr_get_flag(netif->mac.tx.packet) &
|
||||
(GNRC_NETIF_HDR_FLAGS_BROADCAST | GNRC_NETIF_HDR_FLAGS_MULTICAST)) {
|
||||
/* Set CSMA retries as configured and enable */
|
||||
uint8_t csma_retries = GNRC_LWMAC_BROADCAST_CSMA_RETRIES;
|
||||
gnrc_netdev->dev->driver->set(gnrc_netdev->dev, NETOPT_CSMA_RETRIES,
|
||||
&csma_retries, sizeof(csma_retries));
|
||||
gnrc_netdev->mac_info |= GNRC_NETDEV_MAC_INFO_CSMA_ENABLED;
|
||||
netif->dev->driver->set(netif->dev, NETOPT_CSMA_RETRIES,
|
||||
&csma_retries, sizeof(csma_retries));
|
||||
netif->mac.mac_info |= GNRC_NETIF2_MAC_INFO_CSMA_ENABLED;
|
||||
netopt_enable_t csma_enable = NETOPT_ENABLE;
|
||||
gnrc_netdev->dev->driver->set(gnrc_netdev->dev, NETOPT_CSMA,
|
||||
&csma_enable, sizeof(csma_enable));
|
||||
netif->dev->driver->set(netif->dev, NETOPT_CSMA,
|
||||
&csma_enable, sizeof(csma_enable));
|
||||
|
||||
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_SEND_BROADCAST;
|
||||
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_SEND_BROADCAST;
|
||||
reschedule = true;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
/* Use CSMA for the first WR */
|
||||
gnrc_netdev->mac_info |= GNRC_NETDEV_MAC_INFO_CSMA_ENABLED;
|
||||
netif->mac.mac_info |= GNRC_NETIF2_MAC_INFO_CSMA_ENABLED;
|
||||
netopt_enable_t csma_disable = NETOPT_ENABLE;
|
||||
gnrc_netdev->dev->driver->set(gnrc_netdev->dev, NETOPT_CSMA,
|
||||
&csma_disable, sizeof(csma_disable));
|
||||
netif->dev->driver->set(netif->dev, NETOPT_CSMA,
|
||||
&csma_disable, sizeof(csma_disable));
|
||||
/* Set a timeout for the maximum transmission procedure */
|
||||
gnrc_lwmac_set_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_NO_RESPONSE, GNRC_LWMAC_PREAMBLE_DURATION_US);
|
||||
gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_NO_RESPONSE, GNRC_LWMAC_PREAMBLE_DURATION_US);
|
||||
|
||||
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_SEND_WR;
|
||||
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_SEND_WR;
|
||||
reschedule = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
case GNRC_LWMAC_TX_STATE_SEND_BROADCAST: {
|
||||
uint8_t tx_info = _send_bcast(gnrc_netdev);
|
||||
uint8_t tx_info = _send_bcast(netif);
|
||||
|
||||
if (tx_info & GNRC_LWMAC_TX_SUCCESS) {
|
||||
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_SUCCESSFUL;
|
||||
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_SUCCESSFUL;
|
||||
reschedule = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (tx_info & GNRC_LWMAC_TX_FAIL) {
|
||||
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
|
||||
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
|
||||
reschedule = true;
|
||||
break;
|
||||
}
|
||||
@ -603,23 +603,23 @@ static bool _lwmac_tx_update(gnrc_netdev_t *gnrc_netdev)
|
||||
}
|
||||
case GNRC_LWMAC_TX_STATE_SEND_WR: {
|
||||
/* In case of no Tx-isr error (e.g., no Tx-isr), goto TX failure. */
|
||||
if (gnrc_lwmac_timeout_is_expired(gnrc_netdev, GNRC_LWMAC_TIMEOUT_NO_RESPONSE)) {
|
||||
if (gnrc_lwmac_timeout_is_expired(netif, GNRC_LWMAC_TIMEOUT_NO_RESPONSE)) {
|
||||
LOG_WARNING("WARNING: [LWMAC-tx] No response from destination, "
|
||||
"probably no TX-ISR\n");
|
||||
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
|
||||
"probably no TX-ISR\n");
|
||||
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
|
||||
reschedule = true;
|
||||
break;
|
||||
}
|
||||
LOG_DEBUG("[LWMAC-tx] GNRC_LWMAC_TX_STATE_SEND_WR\n");
|
||||
uint8_t tx_info = _send_wr(gnrc_netdev);
|
||||
uint8_t tx_info = _send_wr(netif);
|
||||
|
||||
if (tx_info & GNRC_LWMAC_TX_FAIL) {
|
||||
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
|
||||
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
|
||||
reschedule = true;
|
||||
break;
|
||||
}
|
||||
|
||||
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_WAIT_WR_SENT;
|
||||
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_WAIT_WR_SENT;
|
||||
reschedule = false;
|
||||
break;
|
||||
}
|
||||
@ -627,84 +627,84 @@ static bool _lwmac_tx_update(gnrc_netdev_t *gnrc_netdev)
|
||||
LOG_DEBUG("[LWMAC-tx] GNRC_LWMAC_TX_STATE_WAIT_WR_SENT\n");
|
||||
|
||||
/* In case of no Tx-isr error (e.g., no Tx-isr), goto TX failure. */
|
||||
if (gnrc_lwmac_timeout_is_expired(gnrc_netdev, GNRC_LWMAC_TIMEOUT_NO_RESPONSE)) {
|
||||
if (gnrc_lwmac_timeout_is_expired(netif, GNRC_LWMAC_TIMEOUT_NO_RESPONSE)) {
|
||||
LOG_WARNING("WARNING: [LWMAC-tx] No response from destination\n");
|
||||
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
|
||||
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
|
||||
reschedule = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (gnrc_netdev_get_tx_feedback(gnrc_netdev) == TX_FEEDBACK_UNDEF) {
|
||||
if (gnrc_netif2_get_tx_feedback(netif) == TX_FEEDBACK_UNDEF) {
|
||||
LOG_DEBUG("[LWMAC-tx] WR not yet completely sent\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/* If found ongoing transmission, goto TX failure, i.e., postpone transmission to
|
||||
* next cycle. This is mainly for collision avoidance. */
|
||||
if (gnrc_netdev_get_tx_feedback(gnrc_netdev) == TX_FEEDBACK_BUSY) {
|
||||
if (!gnrc_mac_queue_tx_packet(&gnrc_netdev->tx, 0, gnrc_netdev->tx.packet)) {
|
||||
gnrc_pktbuf_release(gnrc_netdev->tx.packet);
|
||||
if (gnrc_netif2_get_tx_feedback(netif) == TX_FEEDBACK_BUSY) {
|
||||
if (!gnrc_mac_queue_tx_packet(&netif->mac.tx, 0, netif->mac.tx.packet)) {
|
||||
gnrc_pktbuf_release(netif->mac.tx.packet);
|
||||
LOG_WARNING("WARNING: [LWMAC-tx] TX queue full, drop packet\n");
|
||||
}
|
||||
/* clear packet point to avoid TX retry */
|
||||
gnrc_netdev->tx.packet = NULL;
|
||||
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
|
||||
netif->mac.tx.packet = NULL;
|
||||
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
|
||||
reschedule = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (gnrc_netdev->tx.wr_sent == 0) {
|
||||
if (netif->mac.tx.wr_sent == 0) {
|
||||
/* Only the first WR use CSMA */
|
||||
gnrc_netdev->mac_info &= ~GNRC_NETDEV_MAC_INFO_CSMA_ENABLED;
|
||||
netif->mac.mac_info &= ~GNRC_NETIF2_MAC_INFO_CSMA_ENABLED;
|
||||
netopt_enable_t csma_disable = NETOPT_DISABLE;
|
||||
gnrc_netdev->dev->driver->set(gnrc_netdev->dev, NETOPT_CSMA,
|
||||
&csma_disable, sizeof(csma_disable));
|
||||
netif->dev->driver->set(netif->dev, NETOPT_CSMA,
|
||||
&csma_disable, sizeof(csma_disable));
|
||||
}
|
||||
|
||||
gnrc_netdev->tx.wr_sent++;
|
||||
netif->mac.tx.wr_sent++;
|
||||
|
||||
/* Set timeout for next WR in case no WA will be received */
|
||||
gnrc_lwmac_set_timeout(gnrc_netdev, GNRC_LWMAC_TIMEOUT_WR, GNRC_LWMAC_TIME_BETWEEN_WR_US);
|
||||
gnrc_lwmac_set_timeout(netif, GNRC_LWMAC_TIMEOUT_WR, GNRC_LWMAC_TIME_BETWEEN_WR_US);
|
||||
|
||||
/* Debug WR timing */
|
||||
LOG_DEBUG("[LWMAC-tx] Destination phase was: %" PRIu32 "\n",
|
||||
gnrc_netdev->tx.current_neighbor->phase);
|
||||
netif->mac.tx.current_neighbor->phase);
|
||||
LOG_DEBUG("[LWMAC-tx] Phase when sent was: %" PRIu32 "\n",
|
||||
_gnrc_lwmac_ticks_to_phase(gnrc_netdev->tx.timestamp));
|
||||
_gnrc_lwmac_ticks_to_phase(netif->mac.tx.timestamp));
|
||||
LOG_DEBUG("[LWMAC-tx] Ticks when sent was: %" PRIu32 "\n",
|
||||
gnrc_netdev->tx.timestamp);
|
||||
_gnrc_lwmac_set_netdev_state(gnrc_netdev, NETOPT_STATE_IDLE);
|
||||
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_WAIT_FOR_WA;
|
||||
netif->mac.tx.timestamp);
|
||||
_gnrc_lwmac_set_netdev_state(netif, NETOPT_STATE_IDLE);
|
||||
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_WAIT_FOR_WA;
|
||||
reschedule = false;
|
||||
break;
|
||||
}
|
||||
case GNRC_LWMAC_TX_STATE_WAIT_FOR_WA: {
|
||||
LOG_DEBUG("[LWMAC-tx] GNRC_LWMAC_TX_STATE_WAIT_FOR_WA\n");
|
||||
|
||||
if (gnrc_lwmac_timeout_is_expired(gnrc_netdev, GNRC_LWMAC_TIMEOUT_NO_RESPONSE)) {
|
||||
if (gnrc_lwmac_timeout_is_expired(netif, GNRC_LWMAC_TIMEOUT_NO_RESPONSE)) {
|
||||
LOG_WARNING("WARNING: [LWMAC-tx] No response from destination\n");
|
||||
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
|
||||
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
|
||||
reschedule = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (gnrc_lwmac_timeout_is_expired(gnrc_netdev, GNRC_LWMAC_TIMEOUT_WR)) {
|
||||
if (gnrc_lwmac_timeout_is_expired(netif, GNRC_LWMAC_TIMEOUT_WR)) {
|
||||
/* In case the sender is in consecutive (burst) transmission to the receiver,
|
||||
* meaning that the sender has already successfully sent at least one data to
|
||||
* the receiver, then the sender will only spend one WR for triggering the next
|
||||
* transmission procedure. And, if this WR doesn't work (no WA replied), the
|
||||
* sender regards consecutive transmission failed.
|
||||
*/
|
||||
if (gnrc_netdev_lwmac_get_tx_continue(gnrc_netdev)) {
|
||||
if (gnrc_lwmac_get_tx_continue(netif)) {
|
||||
LOG_DEBUG("[LWMAC-tx] Tx burst fail\n");
|
||||
if (!gnrc_mac_queue_tx_packet(&gnrc_netdev->tx, 0, gnrc_netdev->tx.packet)) {
|
||||
gnrc_pktbuf_release(gnrc_netdev->tx.packet);
|
||||
if (!gnrc_mac_queue_tx_packet(&netif->mac.tx, 0, netif->mac.tx.packet)) {
|
||||
gnrc_pktbuf_release(netif->mac.tx.packet);
|
||||
LOG_WARNING("WARNING: [LWMAC-tx] TX queue full, drop packet\n");
|
||||
}
|
||||
/* drop pointer so it wont be free'd */
|
||||
gnrc_netdev->tx.packet = NULL;
|
||||
netif->mac.tx.packet = NULL;
|
||||
|
||||
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
|
||||
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
|
||||
reschedule = true;
|
||||
break;
|
||||
}
|
||||
@ -713,27 +713,27 @@ static bool _lwmac_tx_update(gnrc_netdev_t *gnrc_netdev)
|
||||
* latter's wake-up period, the sender just keep sending WRs until it
|
||||
* finds the WA.
|
||||
*/
|
||||
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_SEND_WR;
|
||||
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_SEND_WR;
|
||||
reschedule = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_gnrc_lwmac_get_netdev_state(gnrc_netdev) == NETOPT_STATE_RX) {
|
||||
if (_gnrc_lwmac_get_netdev_state(netif) == NETOPT_STATE_RX) {
|
||||
/* Wait for completion of frame reception */
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t tx_info = _packet_process_in_wait_for_wa(gnrc_netdev);
|
||||
uint8_t tx_info = _packet_process_in_wait_for_wa(netif);
|
||||
|
||||
if (tx_info & GNRC_LWMAC_TX_FAIL) {
|
||||
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
|
||||
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
|
||||
reschedule = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (tx_info & GNRC_LWMAC_TX_SUCCESS) {
|
||||
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_SEND_DATA;
|
||||
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_SEND_DATA;
|
||||
reschedule = true;
|
||||
break;
|
||||
}
|
||||
@ -745,49 +745,49 @@ static bool _lwmac_tx_update(gnrc_netdev_t *gnrc_netdev)
|
||||
case GNRC_LWMAC_TX_STATE_SEND_DATA: {
|
||||
LOG_DEBUG("[LWMAC-tx] GNRC_LWMAC_TX_STATE_SEND_DATA\n");
|
||||
|
||||
if (!_send_data(gnrc_netdev)) {
|
||||
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
|
||||
if (!_send_data(netif)) {
|
||||
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
|
||||
reschedule = true;
|
||||
break;
|
||||
}
|
||||
|
||||
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_WAIT_FEEDBACK;
|
||||
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_WAIT_FEEDBACK;
|
||||
reschedule = false;
|
||||
break;
|
||||
}
|
||||
case GNRC_LWMAC_TX_STATE_WAIT_FEEDBACK: {
|
||||
/* In case of no Tx-isr error, goto TX failure. */
|
||||
if (gnrc_lwmac_timeout_is_expired(gnrc_netdev, GNRC_LWMAC_TIMEOUT_NO_RESPONSE)) {
|
||||
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
|
||||
if (gnrc_lwmac_timeout_is_expired(netif, GNRC_LWMAC_TIMEOUT_NO_RESPONSE)) {
|
||||
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
|
||||
reschedule = true;
|
||||
break;
|
||||
}
|
||||
|
||||
LOG_DEBUG("[LWMAC-tx] GNRC_LWMAC_TX_STATE_WAIT_FEEDBACK\n");
|
||||
if (gnrc_netdev_get_tx_feedback(gnrc_netdev) == TX_FEEDBACK_UNDEF) {
|
||||
if (gnrc_netif2_get_tx_feedback(netif) == TX_FEEDBACK_UNDEF) {
|
||||
break;
|
||||
}
|
||||
else if (gnrc_netdev_get_tx_feedback(gnrc_netdev) == TX_FEEDBACK_SUCCESS) {
|
||||
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_SUCCESSFUL;
|
||||
else if (gnrc_netif2_get_tx_feedback(netif) == TX_FEEDBACK_SUCCESS) {
|
||||
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_SUCCESSFUL;
|
||||
reschedule = true;
|
||||
break;
|
||||
}
|
||||
else if (gnrc_netdev_get_tx_feedback(gnrc_netdev) == TX_FEEDBACK_NOACK) {
|
||||
else if (gnrc_netif2_get_tx_feedback(netif) == TX_FEEDBACK_NOACK) {
|
||||
LOG_ERROR("ERROR: [LWMAC-tx] Not ACKED\n");
|
||||
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
|
||||
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
|
||||
reschedule = true;
|
||||
break;
|
||||
}
|
||||
else if (gnrc_netdev_get_tx_feedback(gnrc_netdev) == TX_FEEDBACK_BUSY) {
|
||||
else if (gnrc_netif2_get_tx_feedback(netif) == TX_FEEDBACK_BUSY) {
|
||||
LOG_ERROR("ERROR: [LWMAC-tx] Channel busy \n");
|
||||
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
|
||||
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
|
||||
reschedule = true;
|
||||
break;
|
||||
}
|
||||
|
||||
LOG_ERROR("ERROR: [LWMAC-tx] Tx feedback unhandled: %i\n",
|
||||
gnrc_netdev_get_tx_feedback(gnrc_netdev));
|
||||
gnrc_netdev->tx.state = GNRC_LWMAC_TX_STATE_FAILED;
|
||||
gnrc_netif2_get_tx_feedback(netif));
|
||||
netif->mac.tx.state = GNRC_LWMAC_TX_STATE_FAILED;
|
||||
reschedule = true;
|
||||
break;
|
||||
}
|
||||
@ -803,8 +803,8 @@ static bool _lwmac_tx_update(gnrc_netdev_t *gnrc_netdev)
|
||||
return reschedule;
|
||||
}
|
||||
|
||||
void gnrc_lwmac_tx_update(gnrc_netdev_t *gnrc_netdev)
|
||||
void gnrc_lwmac_tx_update(gnrc_netif2_t *netif)
|
||||
{
|
||||
/* Update until no rescheduling needed */
|
||||
while (_lwmac_tx_update(gnrc_netdev)) {}
|
||||
while (_lwmac_tx_update(netif)) {}
|
||||
}
|
||||
|
@ -223,8 +223,8 @@ static int _send(gnrc_netif2_t *netif, gnrc_pktsnip_t *pkt)
|
||||
}
|
||||
#endif
|
||||
#ifdef MODULE_GNRC_MAC
|
||||
if (netif->mac_info & GNRC_NETDEV_MAC_INFO_CSMA_ENABLED) {
|
||||
res = csma_sender_csma_ca_send(dev, vector, n, &netif->csma_conf);
|
||||
if (netif->mac.mac_info & GNRC_NETIF2_MAC_INFO_CSMA_ENABLED) {
|
||||
res = csma_sender_csma_ca_send(dev, vector, n, &netif->mac.csma_conf);
|
||||
}
|
||||
else {
|
||||
res = dev->driver->send(dev, vector, n);
|
||||
|
Loading…
Reference in New Issue
Block a user