Skip to content

Commit bdf13bc

Browse files
Jordan Yatesnashif
authored andcommitted
lorawan: store current datarate for ADR
Keep track of the current network datarate when ADR is enabled. The datarate can change in two circumstances. Firstly, the datarate may change as a result of a command from the LoRaWAN server as the link budget varies. Secondly, the datarate may be changed due to not receiving an expected ADRACKReq response. This necessitates querying the datarate on both packet reception and transmission to provide timely notifications to the application. Due to querying the default region datarate at startup and validating manual datarate parameters, when ADR is not enabled the datarate will never be different from the value provided to `lorawan_set_datarate`. Signed-off-by: Jordan Yates <[email protected]>
1 parent 8c1a45b commit bdf13bc

File tree

1 file changed

+38
-7
lines changed

1 file changed

+38
-7
lines changed

subsys/lorawan/lorawan.c

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,12 @@ K_SEM_DEFINE(mcps_confirm_sem, 0, 1);
5353
K_MUTEX_DEFINE(lorawan_join_mutex);
5454
K_MUTEX_DEFINE(lorawan_send_mutex);
5555

56-
static enum lorawan_datarate lorawan_datarate;
56+
/* We store both the default datarate requested through lorawan_set_datarate
57+
* and the current datarate so that we can use the default datarate for all
58+
* join requests, even as the current datarate changes due to ADR.
59+
*/
60+
static enum lorawan_datarate default_datarate;
61+
static enum lorawan_datarate current_datarate;
5762
static uint8_t lorawan_conf_msg_tries = 1;
5863
static bool lorawan_adr_enable;
5964

@@ -83,6 +88,20 @@ static void OnMacProcessNotify(void)
8388
LoRaMacProcess();
8489
}
8590

91+
static void datarate_observe(bool force_notification)
92+
{
93+
MibRequestConfirm_t mibGet;
94+
95+
mibGet.Type = MIB_CHANNELS_DATARATE;
96+
LoRaMacMibGetRequestConfirm(&mibGet);
97+
98+
if ((mibGet.Param.ChannelsDatarate != current_datarate) ||
99+
(force_notification)) {
100+
current_datarate = mibGet.Param.ChannelsDatarate;
101+
LOG_INF("Datarate changed: DR_%d", current_datarate);
102+
}
103+
}
104+
86105
static void McpsConfirm(McpsConfirm_t *mcpsConfirm)
87106
{
88107
LOG_DBG("Received McpsConfirm (for McpsRequest %d)",
@@ -95,6 +114,11 @@ static void McpsConfirm(McpsConfirm_t *mcpsConfirm)
95114
LOG_DBG("McpsRequest success!");
96115
}
97116

117+
/* Datarate may have changed due to a missed ADRACK */
118+
if (lorawan_adr_enable) {
119+
datarate_observe(false);
120+
}
121+
98122
last_mcps_confirm_status = mcpsConfirm->Status;
99123
/* mcps_confirm_sem is only blocked on in the MCPS_CONFIRMED case */
100124
if (mcpsConfirm->McpsRequest == MCPS_CONFIRMED) {
@@ -112,6 +136,11 @@ static void McpsIndication(McpsIndication_t *mcpsIndication)
112136
return;
113137
}
114138

139+
/* Datarate can change as result of ADR command from server */
140+
if (lorawan_adr_enable) {
141+
datarate_observe(false);
142+
}
143+
115144
/* TODO: Check MCPS Indication type */
116145
if (mcpsIndication->RxData == true) {
117146
if (mcpsIndication->BufferSize != 0) {
@@ -170,7 +199,7 @@ static LoRaMacStatus_t lorawan_join_otaa(
170199
MibRequestConfirm_t mib_req;
171200

172201
mlme_req.Type = MLME_JOIN;
173-
mlme_req.Req.Join.Datarate = lorawan_datarate;
202+
mlme_req.Req.Join.Datarate = default_datarate;
174203

175204
mib_req.Type = MIB_DEV_EUI;
176205
mib_req.Param.DevEui = join_cfg->dev_eui;
@@ -290,7 +319,7 @@ int lorawan_join(const struct lorawan_join_config *join_cfg)
290319
MibRequestConfirm_t mib_req;
291320

292321
mib_req.Type = MIB_CHANNELS_DATARATE;
293-
mib_req.Param.ChannelsDatarate = lorawan_datarate;
322+
mib_req.Param.ChannelsDatarate = default_datarate;
294323
LoRaMacMibSetRequestConfirm(&mib_req);
295324
}
296325

@@ -344,7 +373,8 @@ int lorawan_set_datarate(enum lorawan_datarate dr)
344373
return -EINVAL;
345374
}
346375

347-
lorawan_datarate = dr;
376+
default_datarate = dr;
377+
current_datarate = dr;
348378

349379
return 0;
350380
}
@@ -429,14 +459,14 @@ int lorawan_send(uint8_t port, uint8_t *data, uint8_t len, uint8_t flags)
429459
mcpsReq.Req.Confirmed.fBuffer = data;
430460
mcpsReq.Req.Confirmed.fBufferSize = len;
431461
mcpsReq.Req.Confirmed.NbTrials = lorawan_conf_msg_tries;
432-
mcpsReq.Req.Confirmed.Datarate = lorawan_datarate;
462+
mcpsReq.Req.Confirmed.Datarate = current_datarate;
433463
} else {
434464
/* default message type */
435465
mcpsReq.Type = MCPS_UNCONFIRMED;
436466
mcpsReq.Req.Unconfirmed.fPort = port;
437467
mcpsReq.Req.Unconfirmed.fBuffer = data;
438468
mcpsReq.Req.Unconfirmed.fBufferSize = len;
439-
mcpsReq.Req.Unconfirmed.Datarate = lorawan_datarate;
469+
mcpsReq.Req.Unconfirmed.Datarate = current_datarate;
440470
}
441471
}
442472

@@ -503,7 +533,8 @@ int lorawan_start(void)
503533
/* Retrieve the default TX datarate for selected region */
504534
phy_params.Attribute = PHY_DEF_TX_DR;
505535
phy_param = RegionGetPhyParam(LORAWAN_REGION, &phy_params);
506-
lorawan_datarate = phy_param.Value;
536+
default_datarate = phy_param.Value;
537+
current_datarate = default_datarate;
507538

508539
/* TODO: Move these to a proper location */
509540
mib_req.Type = MIB_SYSTEM_MAX_RX_ERROR;

0 commit comments

Comments
 (0)