Merge pull request #15946 from jia200x/pr/gnrc_lorawan_redundancy

net/gnrc_lorawan: implement unconfirmed uplink redundancy
This commit is contained in:
Martine Lenders 2021-09-17 13:38:10 +02:00 committed by GitHub
commit 75c9aaceb4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 74 additions and 16 deletions

View File

@ -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

View File

@ -284,6 +284,21 @@ extern "C" {
#define CONFIG_LORAMAC_DEFAULT_TX_MODE (LORAMAC_TX_CNF)
#endif
/**
* @brief Default redundancy for unconfirmed uplink
*
* This corresponds to the number of unconfirmed uplink retransmissions when
* using ADR. This configuration does not affect confirmed uplinks. By
* default, uplinks are sent without retransmissions (this means, the device
* sends only one uplink packet)
*
* @note This value MUST NOT be greater than 14, since the LinkADRCommand it's
* already limited by a 4 bit value (therefore, 15 uplink transmissions)
*/
#ifndef CONFIG_LORAMAC_DEFAULT_REDUNDANCY
#define CONFIG_LORAMAC_DEFAULT_REDUNDANCY (0U)
#endif
/**
* @brief Enable/disable adaptive datarate state
*
@ -535,7 +550,7 @@ extern "C" {
#define LORAMAC_PORT_MIN (1U)
/**
* @brief Maximmu port value
* @brief Maximum port value
*/
#define LORAMAC_PORT_MAX (223U)

View File

@ -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;
}
}

View File

@ -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) {
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 {
}
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);
}
}
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;

View File

@ -152,6 +152,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;
@ -392,11 +393,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.

View File

@ -524,4 +524,16 @@ config LORAMAC_DEFAULT_MIN_RX_SYMBOLS
system timer. Refer SX1276_settings_for_LoRaWAN_v2p2.pdf
(AN1200.24) from Semtech for more information.
config LORAMAC_DEFAULT_REDUNDANCY
int "Default redundancy for unconfirmed uplinks"
depends on USEMODULE_GNRC_LORAWAN
default 0
range 0 14
help
This corresponds to the number of unconfirmed
uplink retransmissions when using ADR. This
configuration does not affect confirmed uplinks.
By default, uplinks are sent without retransmissions
(this means, the device sends only one uplink packet)
endif # KCONFIG_USEMODULE_LORAWAN