1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
RIOT/sys/include/net/gnrc/lorawan.h
Jose Alamos df97f348e2
net/gnrc_lorawan: implement uplink redundancy
This commit implements uplink redundancy in GNRC LoRaWAN. Uplink
redundancy is used to retransmit unconfirmed uplink frames. The
retransmission stops when either a downlink message is received or the
number of uplink retransmissions is reached.

This functionality doesn't affect confirmed uplinks.
2021-07-21 03:51:47 +02:00

345 lines
10 KiB
C

/*
* Copyright (C) 2017 Fundación Inria Chile
* Copyright (C) 2019 HAW Hamburg
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @defgroup net_gnrc_lorawan GNRC LoRaWAN
* @ingroup net_gnrc
* @brief GNRC LoRaWAN stack implementation
*
* @{
*
* @file
* @brief GNRC LoRaWAN API definition
*
* @author José Ignacio Alamos <jose.alamos@haw-hamburg.de>
* @author Francisco Molina <femolina@uc.cl>
*/
#ifndef NET_GNRC_LORAWAN_H
#define NET_GNRC_LORAWAN_H
#include "gnrc_lorawan_internal.h"
#include "assert.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup net_gnrc_lorawan_conf GNRC LoRaWAN compile configurations
* @ingroup net_gnrc_conf
* @{
*/
/**
* @brief the minimum symbols to detect a LoRa preamble
*/
#ifndef CONFIG_GNRC_LORAWAN_MIN_SYMBOLS_TIMEOUT
#define CONFIG_GNRC_LORAWAN_MIN_SYMBOLS_TIMEOUT 30
#endif
/** @} */
#define GNRC_LORAWAN_REQ_STATUS_SUCCESS (0) /**< MLME or MCPS request successful status */
#define GNRC_LORAWAN_REQ_STATUS_DEFERRED (1) /**< the MLME or MCPS confirm message is asynchronous */
/**
* @brief MCPS events
*/
typedef enum {
MCPS_EVENT_RX, /**< MCPS RX event */
MCPS_EVENT_NO_RX, /**< MCPS no RX event */
} mcps_event_t;
/**
* @brief LoRaWAN activation mechanism
*/
typedef enum {
MLME_ACTIVATION_NONE, /**< MAC layer is not activated */
MLME_ACTIVATION_ABP, /**< MAC layer activated by ABP */
MLME_ACTIVATION_OTAA /**< MAC layer activated by OTAA */
} mlme_activation_t;
/**
* @brief MAC Information Base attributes
*/
typedef enum {
MIB_ACTIVATION_METHOD, /**< type is activation method */
MIB_DEV_ADDR, /**< type is dev addr */
MIB_RX2_DR, /**< type is rx2 DR */
} mlme_mib_type_t;
/**
* @brief MLME primitive types
*/
typedef enum {
MLME_JOIN, /**< join a LoRaWAN network */
MLME_LINK_CHECK, /**< perform a Link Check */
MLME_RESET, /**< reset the MAC layer */
MLME_SET, /**< set the MIB */
MLME_GET, /**< get the MIB */
MLME_SCHEDULE_UPLINK /**< schedule uplink indication */
} mlme_type_t;
/**
* @brief MCPS primitive types
*/
typedef enum {
MCPS_CONFIRMED, /**< confirmed data */
MCPS_UNCONFIRMED /**< unconfirmed data */
} mcps_type_t;
/**
* @brief MAC Information Base descriptor for MLME Request-Confirm
*/
typedef struct {
mlme_mib_type_t type; /**< MIB attribute identifier */
union {
mlme_activation_t activation; /**< holds activation mechanism */
void *dev_addr; /**< pointer to the dev_addr */
uint8_t rx2_dr; /** datarate of second rx window */
};
} mlme_mib_t;
/**
* @brief MAC (sub) Layer Management Entity (MLME) request representation
*/
typedef struct {
union {
mlme_lorawan_join_t join; /**< Join Data holder */
mlme_mib_t mib; /**< MIB holder */
};
mlme_type_t type; /**< type of the MLME request */
} mlme_request_t;
/**
* @brief Mac Common Part Sublayer (MCPS) request representation
*/
typedef struct {
union {
mcps_data_t data; /**< MCPS data holder */
};
mcps_type_t type; /**< type of the MCPS request */
} mcps_request_t;
/**
* @brief MAC (sub) Layer Management Entity (MLME) confirm representation
*/
typedef struct {
int16_t status; /**< status of the MLME confirm */
mlme_type_t type; /**< type of the MLME confirm */
union {
mlme_link_req_confirm_t link_req; /**< Link Check confirmation data */
mlme_mib_t mib; /**< MIB confirmation data */
};
} mlme_confirm_t;
/**
* @brief Mac Common Part Sublayer (MCPS) confirm representation
*/
typedef struct {
int16_t status; /**< status of the MCPS confirm */
mcps_type_t type; /**< type of the MCPS confirm */
iolist_t *msdu; /**< pointer to the msdu */
} mcps_confirm_t;
/**
* @brief Mac Common Part Sublayer (MCPS) indication representation
*/
typedef struct {
mcps_type_t type; /**< type of the MCPS indication */
union {
mcps_data_t data; /**< MCPS Data holder */
};
} mcps_indication_t;
/**
* @brief MAC (sub) Layer Management Entity (MLME) indication representation
*/
typedef struct {
mlme_type_t type; /**< type of the MLME indication */
} mlme_indication_t;
/**
* @brief Indicate the MAC layer there was a timeout event
*
* @param[in] mac pointer to the MAC descriptor
*/
void gnrc_lorawan_radio_rx_timeout_cb(gnrc_lorawan_t *mac);
/**
* @brief Indicate the MAC layer when the transmission finished
*
* @param[in] mac pointer to the MAC descriptor
*/
void gnrc_lorawan_radio_tx_done_cb(gnrc_lorawan_t *mac);
/**
* @brief Indicate the MAC layer reception of a frame went wrong.
*
* @param[in] mac pointer to the MAC descriptor
*/
static inline void gnrc_lorawan_radio_rx_error_cb(gnrc_lorawan_t *mac)
{
/* The failed reception is seen by the MAC layer as an RX timeout */
gnrc_lorawan_radio_rx_timeout_cb(mac);
}
/**
* @brief Indicate the MAC layer that the timer was fired
*
* @param[in] mac pointer to the MAC descriptor
*/
void gnrc_lorawan_timeout_cb(gnrc_lorawan_t *mac);
/**
* @brief Init GNRC LoRaWAN
*
* @param[in] mac pointer to the MAC descriptor
* @param[in] nwkskey buffer to store the NwkSKey. Should be at least 16 bytes long
* @param[in] appskey buffer to store the AppsKey. Should be at least 16 bytes long
*/
void gnrc_lorawan_init(gnrc_lorawan_t *mac, uint8_t *nwkskey, uint8_t *appskey);
/**
* @brief Perform a MLME request
*
* @param[in] mac pointer to the MAC descriptor
* @param[in] mlme_request the MLME request
* @param[out] mlme_confirm the MLME confirm. `mlme_confirm->status` could either
* be GNRC_LORAWAN_REQ_STATUS_SUCCESS if the request was OK,
* GNRC_LORAWAN_REQ_STATUS_DEFERRED if the confirmation is deferred
* or an standard error number
*/
void gnrc_lorawan_mlme_request(gnrc_lorawan_t *mac,
const mlme_request_t *mlme_request,
mlme_confirm_t *mlme_confirm);
/**
* @brief Perform a MCPS request
*
* @param[in] mac pointer to the MAC descriptor
* @param[in] mcps_request the MCPS request
* @param[out] mcps_confirm the MCPS confirm. `mlme_confirm->status` could either
* be GNRC_LORAWAN_REQ_STATUS_SUCCESS if the request was OK,
* GNRC_LORAWAN_REQ_STATUS_DEFERRED if the confirmation is deferred
* or an standard error number
*/
void gnrc_lorawan_mcps_request(gnrc_lorawan_t *mac,
const mcps_request_t *mcps_request,
mcps_confirm_t *mcps_confirm);
/**
* @brief Fetch a LoRaWAN packet from the radio.
*
* To be called on radio RX done event.
*
* @param[in] mac pointer to the MAC descriptor
* @param[in] data pointer to the psdu. Must not be NULL. Use
* @ref gnrc_lorawan_radio_rx_error_cb instead if the reception was
* not successful.
* @param[in] size size of the PSDU
*/
void gnrc_lorawan_radio_rx_done_cb(gnrc_lorawan_t *mac, uint8_t *data,
size_t size);
/**
* @brief MCPS indication callback
* @note Supposed to be implemented by the user of GNRC LoRaWAN
*
* @param[in] mac pointer to the MAC descriptor
* @param[in] ind pointer of the indication (see @ref mcps_indication_t)
*/
void gnrc_lorawan_mcps_indication(gnrc_lorawan_t *mac, mcps_indication_t *ind);
/**
* @brief MLME indication callback
* @note Supposed to be implemented by the user of GNRC LoRaWAN
*
* @param[in] mac pointer to the MAC descriptor
* @param[in] ind pointer of the indication (see @ref mlme_indication_t)
*/
void gnrc_lorawan_mlme_indication(gnrc_lorawan_t *mac, mlme_indication_t *ind);
/**
* @brief MCPS Confirm callback
* @note Supposed to be implemented by the user of GNRC LoRaWAN
*
* @param[in] mac pointer to the MAC descriptor
* @param[in] confirm pointer to the confirm (see @ref mcps_confirm_t)
*/
void gnrc_lorawan_mcps_confirm(gnrc_lorawan_t *mac, mcps_confirm_t *confirm);
/**
* @brief MLME confirm callback
* @note Supposed to be implemented by the user of GNRC LoRaWAN
*
* @param[in] mac pointer to the MAC descriptor
* @param[in] confirm pointer to the confirm (see @ref mlme_confirm_t)
*/
void gnrc_lorawan_mlme_confirm(gnrc_lorawan_t *mac, mlme_confirm_t *confirm);
/**
* @brief Get netdev pointer from mac descriptor
* @note Supposed to be implemented by the user of GNRC LoRaWAN
*
* @param[in] mac pointer to the MAC descriptor
*
* @return pointer to the @ref netdev_t structure
*/
netdev_t *gnrc_lorawan_get_netdev(gnrc_lorawan_t *mac);
/**
* @brief Set the channel mask in order to enable or disable LoRaWAN channels
*
* @param[in] mac pointer to the MAC descriptor
* @param[in] channel_mask the channel mask. LSB maps to channel 0
*
* @return 0 on success
* @return -EINVAL if @p channel_mask is zero or if the channel mask tries to
* enable an undefined channel
*/
int gnrc_lorawan_phy_set_channel_mask(gnrc_lorawan_t *mac, uint16_t channel_mask);
/**
* @brief Set a timer with the given time
* @note Supposed to be implemented by the user of GNRC LoRaWAN
*
* @param[in] mac pointer to the MAC descriptor
* @param us timeout microseconds
*/
void gnrc_lorawan_set_timer(gnrc_lorawan_t *mac, uint32_t us);
/**
* @brief Remove the current timer
* @note Supposed to be implemented by the user of GNRC LoRaWAN
*
* @param[in] mac pointer to the MAC descriptor
*/
void gnrc_lorawan_remove_timer(gnrc_lorawan_t *mac);
/**
* @brief Set unconfirmed uplink redundancy
*
* @pre @p redundancy <= 14
*
* @param[in] mac pointer to the MAC descriptor
* @param[in] redundancy number of unconfirmed uplink retransmissions
*/
static inline void gnrc_lorawan_set_uncnf_redundancy(gnrc_lorawan_t *mac,
uint8_t redundancy)
{
assert(redundancy <= (0xF - 1));
mac->mcps.redundancy = redundancy;
}
#ifdef __cplusplus
}
#endif
#endif /* NET_GNRC_LORAWAN_H */
/** @} */