mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-18 12:52:44 +01:00
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.
This commit is contained in:
parent
02151deae4
commit
df97f348e2
@ -24,6 +24,7 @@
|
||||
#define NET_GNRC_LORAWAN_H
|
||||
|
||||
#include "gnrc_lorawan_internal.h"
|
||||
#include "assert.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -320,6 +321,21 @@ void gnrc_lorawan_set_timer(gnrc_lorawan_t *mac, uint32_t us);
|
||||
*/
|
||||
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
|
||||
|
@ -58,6 +58,7 @@ static inline void gnrc_lorawan_mcps_reset(gnrc_lorawan_t *mac)
|
||||
mac->mcps.waiting_for_ack = false;
|
||||
mac->mcps.fcnt = 0;
|
||||
mac->mcps.fcnt_down = 0;
|
||||
gnrc_lorawan_set_uncnf_redundancy(mac, CONFIG_LORAMAC_DEFAULT_REDUNDANCY);
|
||||
}
|
||||
|
||||
void gnrc_lorawan_set_rx2_dr(gnrc_lorawan_t *mac, uint8_t rx2_dr)
|
||||
@ -164,8 +165,11 @@ void gnrc_lorawan_timeout_cb(gnrc_lorawan_t *mac)
|
||||
case LORAWAN_STATE_JOIN:
|
||||
gnrc_lorawan_trigger_join(mac);
|
||||
break;
|
||||
case LORAWAN_STATE_IDLE:
|
||||
gnrc_lorawan_event_retrans_timeout(mac);
|
||||
break;
|
||||
default:
|
||||
gnrc_lorawan_event_ack_timeout(mac);
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -331,16 +331,33 @@ static void _transmit_pkt(gnrc_lorawan_t *mac)
|
||||
last_snip->iol_next = NULL;
|
||||
}
|
||||
|
||||
void gnrc_lorawan_event_ack_timeout(gnrc_lorawan_t *mac)
|
||||
void gnrc_lorawan_event_retrans_timeout(gnrc_lorawan_t *mac)
|
||||
{
|
||||
_transmit_pkt(mac);
|
||||
}
|
||||
|
||||
static void _handle_retransmissions(gnrc_lorawan_t *mac)
|
||||
{
|
||||
/* Check if retransmission should be handled.
|
||||
*
|
||||
* If there was a confirmed uplink, follow the standard retransmission
|
||||
* procedure.
|
||||
* If it was an unconfirmed uplink, perform retransmissions only if
|
||||
* there's redundancy > 0 */
|
||||
if (mac->mcps.nb_trials-- == 0) {
|
||||
_end_of_tx(mac, MCPS_CONFIRMED, -ETIMEDOUT);
|
||||
} else {
|
||||
if (mac->mcps.waiting_for_ack) {
|
||||
/* If we are here, the node ran out of confirmed uplink retransmissions.
|
||||
* This means, the transmission was not successful. */
|
||||
_end_of_tx(mac, MCPS_CONFIRMED, -ETIMEDOUT);
|
||||
}
|
||||
else {
|
||||
/* In this case, we finished sending one or more unconfirmed
|
||||
* (depending on the redundancy) */
|
||||
_end_of_tx(mac, MCPS_UNCONFIRMED, GNRC_LORAWAN_REQ_STATUS_SUCCESS);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Schedule a retransmission */
|
||||
gnrc_lorawan_set_timer(mac, 1000000 + random_uint32_range(0, 2000000));
|
||||
}
|
||||
}
|
||||
@ -358,14 +375,7 @@ void gnrc_lorawan_event_no_rx(gnrc_lorawan_t *mac)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Otherwise check if retransmission should be handled */
|
||||
|
||||
if (mac->mcps.waiting_for_ack) {
|
||||
_handle_retransmissions(mac);
|
||||
}
|
||||
else {
|
||||
_end_of_tx(mac, MCPS_UNCONFIRMED, GNRC_LORAWAN_REQ_STATUS_SUCCESS);
|
||||
}
|
||||
_handle_retransmissions(mac);
|
||||
}
|
||||
|
||||
void gnrc_lorawan_mcps_request(gnrc_lorawan_t *mac,
|
||||
@ -416,7 +426,7 @@ void gnrc_lorawan_mcps_request(gnrc_lorawan_t *mac,
|
||||
mac->mcps.waiting_for_ack = waiting_for_ack;
|
||||
mac->mcps.ack_requested = false;
|
||||
|
||||
mac->mcps.nb_trials = CONFIG_LORAMAC_DEFAULT_RETX;
|
||||
mac->mcps.nb_trials = waiting_for_ack ? CONFIG_LORAMAC_DEFAULT_RETX : mac->mcps.redundancy;
|
||||
|
||||
mac->mcps.msdu = pkt;
|
||||
mac->last_dr = mcps_request->data.dr;
|
||||
|
@ -153,6 +153,7 @@ typedef struct {
|
||||
int nb_trials; /**< holds the remaining number of retransmissions */
|
||||
int ack_requested; /**< whether the network server requested an ACK */
|
||||
int waiting_for_ack; /**< true if the MAC layer is waiting for an ACK */
|
||||
uint8_t redundancy; /**< unconfirmed uplink redundancy */
|
||||
char mhdr_mic[MHDR_MIC_BUF_SIZE]; /**< internal retransmissions buffer */
|
||||
} gnrc_lorawan_mcps_t;
|
||||
|
||||
@ -393,11 +394,11 @@ void gnrc_lorawan_mlme_no_rx(gnrc_lorawan_t *mac);
|
||||
void gnrc_lorawan_event_no_rx(gnrc_lorawan_t *mac);
|
||||
|
||||
/**
|
||||
* @brief Mac callback for ACK timeout event
|
||||
* @brief Mac callback for retransmission timeout event
|
||||
*
|
||||
* @param[in] mac pointer to the MAC descriptor
|
||||
*/
|
||||
void gnrc_lorawan_event_ack_timeout(gnrc_lorawan_t *mac);
|
||||
void gnrc_lorawan_event_retrans_timeout(gnrc_lorawan_t *mac);
|
||||
|
||||
/**
|
||||
* @brief Get the maximum MAC payload (M value) for a given datarate.
|
||||
|
Loading…
Reference in New Issue
Block a user