Frequent store and forward uplinks if offline
I'm implementing a tracking device which will be moved in and out of the range of a LoRaWAN gateway multiple times a day. I'm using the store and forward service to ensure that the locations are being forwarded at a later point in time if the device was out of range.
During a couple of tests I noticed that the service retransmitted the first unacked packet 40 to 50 times during the first hour of being offline. This is considered a lot, especially, since this happens multiple times a day for my use case. Furthermore, if the function smtc_modem_set_nb_trans is used to set nb_trans to 3 (as suggested here) each packet is repeated 3 times which results in 120 to 150 LoRaWAN uplinks being transmitted during the first hour of being offline.
I traced back the issue to the function store_and_forward_flash_compute_next_delay_s which is implemented here. Unfortunately, this function cannot be altered, except for STORE_AND_FORWARD_DELAY_MAX_S.
The current implementation of store_and_forward_flash_compute_next_delay_s is rather simple. A random number between 1 and 5 is multiplied with the number of unacked packets (sending_try_cpt) to get the delay in seconds. The random numbers are currently centered around 3. Allowing a user to set this center manually via a define would already help in my case. I would prefer the random numbers to be centered around 600 seconds (10 minutes) since in that case the delay increases much faster. Alternatively, you could adjust the implementation such that a user can provide a custom implementation of the store_and_forward_flash_compute_next_delay_s function.
Hi, We will improve this in the next release. Feel free to make a proposal. Many thanks,
Ok, thanks for the information.
I adjusted the store_and_forward_flash_compute_next_delay_s such that it uses an exponential backoff. This works fine for my application:
static uint32_t store_and_forward_flash_compute_next_delay_s( store_and_forward_flash_t* ctx )
{
if( ctx->sending_try_cpt == 0 )
{
return 0;
}
// Exponential backoff (2^sending_try_cpt * 60s)
uint32_t delay_s = (1 << ctx->sending_try_cpt) * 60;
if( delay_s > STORE_AND_FORWARD_DELAY_MAX_S )
{
delay_s = STORE_AND_FORWARD_DELAY_MAX_S;
}
return delay_s + smtc_modem_hal_get_random_nb_in_range( 0, 60 );
}