Skip to content

Commit 5e62d17

Browse files
authored
Merge pull request #6566 from AnttiKauppila/stack_cleanup
LoRa: Stack cleanup
2 parents 8b2eb20 + 96610a6 commit 5e62d17

File tree

7 files changed

+293
-277
lines changed

7 files changed

+293
-277
lines changed

features/lorawan/LoRaWANStack.cpp

Lines changed: 111 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -122,56 +122,72 @@ void LoRaWANStack::bind_radio_driver(LoRaRadio& radio)
122122

123123
lorawan_status_t LoRaWANStack::connect()
124124
{
125-
// connection attempt without parameters.
126-
// System tries to look for configuration in mbed_lib.json that can be
127-
// overridden by mbed_app.json. However, if none of the json files are
128-
// available (highly unlikely), we still fallback to some default parameters.
129-
// Check lorawan_data_structure for fallback defaults.
130-
131-
lorawan_connect_t connection_params;
132-
133-
//TODO: LoRaWANStack don't need to know these values, move to LoRaMac (or below)
134-
#if MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION
135-
const static uint8_t dev_eui[] = MBED_CONF_LORA_DEVICE_EUI;
136-
const static uint8_t app_eui[] = MBED_CONF_LORA_APPLICATION_EUI;
137-
const static uint8_t app_key[] = MBED_CONF_LORA_APPLICATION_KEY;
138-
139-
connection_params.connect_type = LORAWAN_CONNECTION_OTAA;
140-
connection_params.connection_u.otaa.app_eui = const_cast<uint8_t *>(app_eui);
141-
connection_params.connection_u.otaa.dev_eui = const_cast<uint8_t *>(dev_eui);
142-
connection_params.connection_u.otaa.app_key = const_cast<uint8_t *>(app_key);
143-
connection_params.connection_u.otaa.nb_trials = MBED_CONF_LORA_NB_TRIALS;
144-
145-
return join_request_by_otaa(connection_params);
146-
#else
147-
const static uint8_t nwk_skey[] = MBED_CONF_LORA_NWKSKEY;
148-
const static uint8_t app_skey[] = MBED_CONF_LORA_APPSKEY;
149-
const static uint32_t dev_addr = MBED_CONF_LORA_DEVICE_ADDRESS;
150-
const static uint32_t nwk_id = (MBED_CONF_LORA_DEVICE_ADDRESS & LORAWAN_NETWORK_ID_MASK);
151-
152-
connection_params.connect_type = LORAWAN_CONNECTION_ABP;
153-
connection_params.connection_u.abp.nwk_id = const_cast<uint8_t *>(nwk_id);
154-
connection_params.connection_u.abp.dev_addr = const_cast<uint8_t *>(dev_addr);
155-
connection_params.connection_u.abp.nwk_skey = const_cast<uint8_t *>(nwk_skey);
156-
connection_params.connection_u.abp.app_skey = const_cast<uint8_t *>(app_skey);
157-
158-
return activation_by_personalization(connection_params);
159-
#endif
125+
if (DEVICE_STATE_NOT_INITIALIZED == _device_current_state) {
126+
tr_error("Stack not initialized!");
127+
return LORAWAN_STATUS_NOT_INITIALIZED;
128+
}
129+
130+
lorawan_status_t status = _loramac.prepare_join(NULL, MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION);
131+
132+
if (LORAWAN_STATUS_OK != status) {
133+
return status;
134+
}
135+
136+
return handle_connect(MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION);
160137
}
161138

162139
lorawan_status_t LoRaWANStack::connect(const lorawan_connect_t &connect)
163140
{
164-
lorawan_status_t mac_status;
141+
if (DEVICE_STATE_NOT_INITIALIZED == _device_current_state) {
142+
tr_error("Stack not initialized!");
143+
return LORAWAN_STATUS_NOT_INITIALIZED;
144+
}
165145

166-
if (connect.connect_type == LORAWAN_CONNECTION_OTAA) {
167-
mac_status = join_request_by_otaa(connect);
168-
} else if (connect.connect_type == LORAWAN_CONNECTION_ABP) {
169-
mac_status = activation_by_personalization(connect);
170-
} else {
146+
if (!(connect.connect_type == LORAWAN_CONNECTION_OTAA) &&
147+
!(connect.connect_type == LORAWAN_CONNECTION_ABP)) {
171148
return LORAWAN_STATUS_PARAMETER_INVALID;
172149
}
150+
bool is_otaa = (connect.connect_type == LORAWAN_CONNECTION_OTAA);
151+
152+
lorawan_status_t status = _loramac.prepare_join(&connect, is_otaa);
153+
154+
if (LORAWAN_STATUS_OK != status) {
155+
return status;
156+
}
173157

174-
return mac_status;
158+
return handle_connect(is_otaa);
159+
}
160+
161+
lorawan_status_t LoRaWANStack::handle_connect(bool is_otaa)
162+
{
163+
device_states_t new_state;
164+
165+
if (is_otaa) {
166+
tr_debug("Initiating OTAA");
167+
168+
// As mentioned in the comment above, in 1.0.2 spec, counters are always set
169+
// to zero for new connection. This section is common for both normal and
170+
// connection restore at this moment. Will change in future with 1.1 support.
171+
_lw_session.downlink_counter = 0;
172+
_lw_session.uplink_counter = 0;
173+
new_state = DEVICE_STATE_JOINING;
174+
} else {
175+
// If current state is SHUTDOWN, device may be trying to re-establish
176+
// communication. In case of ABP specification is meddled about frame counters.
177+
// It says to reset counters to zero but there is no mechanism to tell the
178+
// network server that the device was disconnected or restarted.
179+
// At the moment, this implementation does not support a non-volatile
180+
// memory storage.
181+
//_lw_session.downlink_counter; //Get from NVM
182+
//_lw_session.uplink_counter; //Get from NVM
183+
184+
tr_debug("Initiating ABP");
185+
tr_debug("Frame Counters. UpCnt=%lu, DownCnt=%lu",
186+
_lw_session.uplink_counter, _lw_session.downlink_counter);
187+
new_state = DEVICE_STATE_ABP_CONNECTING;
188+
}
189+
190+
return lora_state_machine(new_state);
175191
}
176192

177193
lorawan_status_t LoRaWANStack::initialize_mac_layer(EventQueue *queue)
@@ -315,61 +331,6 @@ lorawan_status_t LoRaWANStack::set_channel_data_rate(uint8_t data_rate)
315331
return _loramac.set_channel_data_rate(data_rate);
316332
}
317333

318-
lorawan_status_t LoRaWANStack::join_request_by_otaa(const lorawan_connect_t &params)
319-
{
320-
if (DEVICE_STATE_NOT_INITIALIZED == _device_current_state)
321-
{
322-
tr_error("Stack not initialized!");
323-
return LORAWAN_STATUS_NOT_INITIALIZED;
324-
}
325-
326-
tr_debug("Initiating OTAA");
327-
328-
// As mentioned in the comment above, in 1.0.2 spec, counters are always set
329-
// to zero for new connection. This section is common for both normal and
330-
// connection restore at this moment. Will change in future with 1.1 support.
331-
_lw_session.downlink_counter = 0;
332-
_lw_session.uplink_counter = 0;
333-
_lw_session.connection.connect_type = LORAWAN_CONNECTION_OTAA;
334-
335-
_lw_session.connection.connection_u.otaa.dev_eui = params.connection_u.otaa.dev_eui;
336-
_lw_session.connection.connection_u.otaa.app_eui = params.connection_u.otaa.app_eui;
337-
_lw_session.connection.connection_u.otaa.app_key = params.connection_u.otaa.app_key;
338-
_lw_session.connection.connection_u.otaa.nb_trials = params.connection_u.otaa.nb_trials;
339-
340-
return lora_state_machine(DEVICE_STATE_JOINING);
341-
}
342-
343-
lorawan_status_t LoRaWANStack::activation_by_personalization(const lorawan_connect_t &params)
344-
{
345-
if (DEVICE_STATE_NOT_INITIALIZED == _device_current_state) {
346-
tr_error("Stack not initialized!");
347-
return LORAWAN_STATUS_NOT_INITIALIZED;
348-
}
349-
350-
tr_debug("Initiating ABP");
351-
352-
_lw_session.connection.connect_type = LORAWAN_CONNECTION_ABP;
353-
354-
_lw_session.connection.connection_u.abp.dev_addr = params.connection_u.abp.dev_addr;
355-
_lw_session.connection.connection_u.abp.nwk_skey = params.connection_u.abp.nwk_skey;
356-
_lw_session.connection.connection_u.abp.app_skey = params.connection_u.abp.app_skey;
357-
358-
// If current state is SHUTDOWN, device may be trying to re-establish
359-
// communication. In case of ABP specification is meddled about frame counters.
360-
// It says to reset counters to zero but there is no mechanism to tell the
361-
// network server that the device was disconnected or restarted.
362-
// At the moment, this implementation does not support a non-volatile
363-
// memory storage.
364-
//_lw_session.downlink_counter; //Get from NVM
365-
//_lw_session.uplink_counter; //Get from NVM
366-
367-
tr_debug("Frame Counters. UpCnt=%lu, DownCnt=%lu",
368-
_lw_session.uplink_counter, _lw_session.downlink_counter);
369-
370-
return lora_state_machine(DEVICE_STATE_ABP_CONNECTING);
371-
}
372-
373334
int16_t LoRaWANStack::handle_tx(uint8_t port, const uint8_t* data,
374335
uint16_t length, uint8_t flags, bool null_allowed)
375336
{
@@ -512,12 +473,10 @@ void LoRaWANStack::mlme_confirm_handler(loramac_mlme_confirm_t *mlme_confirm)
512473
switch (mlme_confirm->req_type) {
513474
case MLME_JOIN:
514475
if (mlme_confirm->status == LORAMAC_EVENT_INFO_STATUS_OK) {
515-
// Status is OK, node has joined the network
516476
if (lora_state_machine(DEVICE_STATE_JOINED) != LORAWAN_STATUS_OK) {
517477
tr_error("Lora state machine did not return LORAWAN_STATUS_OK");
518478
}
519479
} else {
520-
// Join attempt failed.
521480
if (lora_state_machine(DEVICE_STATE_IDLE) != LORAWAN_STATUS_IDLE) {
522481
tr_error("Lora state machine did not return DEVICE_STATE_IDLE !");
523482
}
@@ -531,8 +490,6 @@ void LoRaWANStack::mlme_confirm_handler(loramac_mlme_confirm_t *mlme_confirm)
531490
break;
532491
case MLME_LINK_CHECK:
533492
if (mlme_confirm->status == LORAMAC_EVENT_INFO_STATUS_OK) {
534-
// Check DemodMargin
535-
// Check NbGateways
536493
#if defined(LORAWAN_COMPLIANCE_TEST)
537494
if (_compliance_test.running == true) {
538495
_compliance_test.link_check = true;
@@ -541,7 +498,6 @@ void LoRaWANStack::mlme_confirm_handler(loramac_mlme_confirm_t *mlme_confirm)
541498
} else
542499
#endif
543500
{
544-
// normal operation as oppose to compliance testing
545501
if (_callbacks.link_check_resp) {
546502
const int ret = _queue->call(_callbacks.link_check_resp,
547503
mlme_confirm->demod_margin,
@@ -640,61 +596,63 @@ void LoRaWANStack::mcps_indication_handler(loramac_mcps_indication_t *mcps_indic
640596
}
641597
#endif
642598

643-
if (mcps_indication->is_data_recvd == true) {
644-
switch (mcps_indication->port) {
645-
case 224: {
599+
if (!mcps_indication->is_data_recvd) {
600+
return;
601+
}
602+
603+
switch (mcps_indication->port) {
604+
case 224: {
646605
#if defined(LORAWAN_COMPLIANCE_TEST)
647-
tr_debug("Compliance test command received.");
648-
compliance_test_handler(mcps_indication);
606+
tr_debug("Compliance test command received.");
607+
compliance_test_handler(mcps_indication);
649608
#else
650-
tr_info("Compliance test disabled.");
609+
tr_info("Compliance test disabled.");
651610
#endif
652-
break;
653-
}
654-
default: {
655-
if (is_port_valid(mcps_indication->port) == true ||
656-
mcps_indication->type == MCPS_PROPRIETARY) {
657-
658-
// Valid message arrived.
659-
_rx_msg.type = LORAMAC_RX_MCPS_INDICATION;
660-
_rx_msg.msg.mcps_indication.buffer_size = mcps_indication->buffer_size;
661-
_rx_msg.msg.mcps_indication.port = mcps_indication->port;
662-
_rx_msg.msg.mcps_indication.buffer = mcps_indication->buffer;
663-
664-
// Notify application about received frame..
665-
tr_debug("Received %d bytes", _rx_msg.msg.mcps_indication.buffer_size);
666-
_rx_msg.receive_ready = true;
667-
668-
if (_callbacks.events) {
669-
const int ret = _queue->call(_callbacks.events, RX_DONE);
670-
MBED_ASSERT(ret != 0);
671-
(void)ret;
672-
}
611+
break;
612+
}
613+
default: {
614+
if (is_port_valid(mcps_indication->port) == true ||
615+
mcps_indication->type == MCPS_PROPRIETARY) {
673616

674-
//TODO: below if clauses can be combined,
675-
// because those are calling same function with same parameters
617+
// Valid message arrived.
618+
_rx_msg.type = LORAMAC_RX_MCPS_INDICATION;
619+
_rx_msg.msg.mcps_indication.buffer_size = mcps_indication->buffer_size;
620+
_rx_msg.msg.mcps_indication.port = mcps_indication->port;
621+
_rx_msg.msg.mcps_indication.buffer = mcps_indication->buffer;
676622

677-
// If fPending bit is set we try to generate an empty packet
678-
// with CONFIRMED flag set. We always set a CONFIRMED flag so
679-
// that we could retry a certain number of times if the uplink
680-
// failed for some reason
681-
if (_loramac.get_device_class() != CLASS_C && mcps_indication->fpending_status) {
682-
handle_tx(mcps_indication->port, NULL, 0, MSG_CONFIRMED_FLAG, true);
683-
}
623+
// Notify application about received frame..
624+
tr_debug("Received %d bytes", _rx_msg.msg.mcps_indication.buffer_size);
625+
_rx_msg.receive_ready = true;
684626

685-
// Class C and node received a confirmed message so we need to
686-
// send an empty packet to acknowledge the message.
687-
// This scenario is unspecified by LoRaWAN 1.0.2 specification,
688-
// but version 1.1.0 says that network SHALL not send any new
689-
// confirmed messages until ack has been sent
690-
if (_loramac.get_device_class() == CLASS_C && mcps_indication->type == MCPS_CONFIRMED) {
691-
handle_tx(mcps_indication->port, NULL, 0, MSG_CONFIRMED_FLAG, true);
692-
}
693-
} else {
694-
// Invalid port, ports 0, 224 and 225-255 are reserved.
627+
if (_callbacks.events) {
628+
const int ret = _queue->call(_callbacks.events, RX_DONE);
629+
MBED_ASSERT(ret != 0);
630+
(void)ret;
695631
}
696-
break;
632+
633+
//TODO: below if clauses can be combined,
634+
// because those are calling same function with same parameters
635+
636+
// If fPending bit is set we try to generate an empty packet
637+
// with CONFIRMED flag set. We always set a CONFIRMED flag so
638+
// that we could retry a certain number of times if the uplink
639+
// failed for some reason
640+
if (_loramac.get_device_class() != CLASS_C && mcps_indication->fpending_status) {
641+
handle_tx(mcps_indication->port, NULL, 0, MSG_CONFIRMED_FLAG, true);
642+
}
643+
644+
// Class C and node received a confirmed message so we need to
645+
// send an empty packet to acknowledge the message.
646+
// This scenario is unspecified by LoRaWAN 1.0.2 specification,
647+
// but version 1.1.0 says that network SHALL not send any new
648+
// confirmed messages until ack has been sent
649+
if (_loramac.get_device_class() == CLASS_C && mcps_indication->type == MCPS_CONFIRMED) {
650+
handle_tx(mcps_indication->port, NULL, 0, MSG_CONFIRMED_FLAG, true);
651+
}
652+
} else {
653+
// Invalid port, ports 0, 224 and 225-255 are reserved.
697654
}
655+
break;
698656
}
699657
}
700658
}
@@ -774,10 +732,10 @@ lorawan_status_t LoRaWANStack::lora_state_machine(device_states_t new_state)
774732
status = LORAWAN_STATUS_OK;
775733
break;
776734
case DEVICE_STATE_JOINING:
777-
if (_lw_session.connection.connect_type == LORAWAN_CONNECTION_OTAA) {
735+
if (_lw_session.connect_type == LORAWAN_CONNECTION_OTAA) {
778736
tr_debug("Send Join-request..");
779737

780-
status = _loramac.join_by_otaa(_lw_session.connection.connection_u.otaa);
738+
status = _loramac.join(true);
781739
if (status != LORAWAN_STATUS_OK) {
782740
return status;
783741
}
@@ -801,7 +759,7 @@ lorawan_status_t LoRaWANStack::lora_state_machine(device_states_t new_state)
801759
break;
802760
case DEVICE_STATE_ABP_CONNECTING:
803761

804-
_loramac.join_by_abp(_lw_session.connection.connection_u.abp);
762+
_loramac.join(false);
805763

806764
tr_debug("ABP Connection OK!");
807765

@@ -1028,7 +986,7 @@ void LoRaWANStack::compliance_test_handler(loramac_mcps_indication_t *mcps_indic
1028986
#if MBED_CONF_LORA_PHY == 0
1029987
_loramac.LoRaMacTestSetDutyCycleOn(MBED_CONF_LORA_DUTY_CYCLE_ON);
1030988
#endif
1031-
_loramac.join_by_otaa(_lw_session.connection.connection_u.otaa);
989+
_loramac.join(true);
1032990
break;
1033991
case 7: // (x)
1034992
if (mcps_indication->buffer_size == 3) {

0 commit comments

Comments
 (0)