Skip to content

Commit 5d98839

Browse files
Kimmo VaisanenHasnain Virk
authored andcommitted
Improve error handling & robustness
This commit also introduces API change for disconnect(). disconnect() will now return LORAWAN_STATUS_DEVICE_OFF for successfull disconnect. * LoRaWANStack::handle_tx() can be called with NULL buffer when length is 0. This commit fixes the case where user has provided NULL buffer and length is > max_possible_size. handle_tx() now always returns LORAWAN_STATUS_PARAMETER_INVALID if given buffer is NULL pointer and length > 0. General error checking is added and some asserts are added for events.
1 parent 35045f1 commit 5d98839

13 files changed

+208
-146
lines changed

features/lorawan/LoRaWANInterface.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,7 @@ lorawan_status_t LoRaWANInterface::connect(const lorawan_connect_t &connect)
113113

114114
lorawan_status_t LoRaWANInterface::disconnect()
115115
{
116-
stk_obj().shutdown();
117-
return LORAWAN_STATUS_OK;
116+
return stk_obj().shutdown();
118117
}
119118

120119
lorawan_status_t LoRaWANInterface::add_link_check_request()

features/lorawan/LoRaWANInterface.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,7 @@ class LoRaWANInterface: public LoRaWANBase {
125125

126126
/** Disconnect the current session.
127127
*
128-
* @return LORAWAN_STATUS_OK on success, a negative error code on
129-
* failure.
128+
* @return LORAWAN_STATUS_DEVICE_OFF on successfully shutdown.
130129
*/
131130
virtual lorawan_status_t disconnect();
132131

features/lorawan/LoRaWANStack.cpp

Lines changed: 69 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,15 @@ LoRaWANStack::LoRaWANStack()
107107
memset(&_lw_session, 0, sizeof(_lw_session));
108108
memset(&_tx_msg, 0, sizeof(_tx_msg));
109109
memset(&_rx_msg, 0, sizeof(_rx_msg));
110+
111+
LoRaMacPrimitives.mcps_confirm = callback(this, &LoRaWANStack::mcps_confirm_handler);
112+
LoRaMacPrimitives.mcps_indication = callback(this, &LoRaWANStack::mcps_indication_handler);
113+
LoRaMacPrimitives.mlme_confirm = callback(this, &LoRaWANStack::mlme_confirm_handler);
114+
LoRaMacPrimitives.mlme_indication = callback(this, &LoRaWANStack::mlme_indication_handler);
110115
}
111116

112117
LoRaWANStack::~LoRaWANStack()
113118
{
114-
115119
}
116120

117121
/*****************************************************************************
@@ -131,6 +135,7 @@ radio_events_t *LoRaWANStack::bind_radio_driver(LoRaRadio& radio)
131135
_lora_phy.set_radio_instance(radio);
132136
return _mac_handlers;
133137
}
138+
134139
lorawan_status_t LoRaWANStack::initialize_mac_layer(EventQueue *queue)
135140
{
136141
if (DEVICE_STATE_NOT_INITIALIZED != _device_current_state)
@@ -139,31 +144,20 @@ lorawan_status_t LoRaWANStack::initialize_mac_layer(EventQueue *queue)
139144
return LORAWAN_STATUS_OK;
140145
}
141146

142-
static loramac_primitives_t LoRaMacPrimitives;
143-
static loramac_mib_req_confirm_t mib_req;
144-
145-
#if defined(LORAWAN_COMPLIANCE_TEST)
146-
static uint8_t compliance_test_buffer[MBED_CONF_LORA_TX_MAX_SIZE];
147-
#endif
148-
149147
tr_debug("Initializing MAC layer");
150148

151149
//store a pointer to Event Queue
152150
_queue = queue;
153151

154152
#if defined(LORAWAN_COMPLIANCE_TEST)
155-
// Allocate memory for compliance test
156153
_compliance_test.app_data_buffer = compliance_test_buffer;
157154
#endif
158155

159156
_lora_time.TimerTimeCounterInit(queue);
160-
161-
LoRaMacPrimitives.mcps_confirm = callback(this, &LoRaWANStack::mcps_confirm_handler);
162-
LoRaMacPrimitives.mcps_indication = callback(this, &LoRaWANStack::mcps_indication_handler);
163-
LoRaMacPrimitives.mlme_confirm = callback(this, &LoRaWANStack::mlme_confirm_handler);
164-
LoRaMacPrimitives.mlme_indication = callback(this, &LoRaWANStack::mlme_indication_handler);
165157
_loramac.LoRaMacInitialization(&LoRaMacPrimitives, &_lora_phy, queue);
166158

159+
loramac_mib_req_confirm_t mib_req;
160+
167161
mib_req.type = MIB_ADR;
168162
mib_req.param.is_adr_enable = MBED_CONF_LORA_ADR_ON;
169163
mib_set_request(&mib_req);
@@ -385,7 +379,6 @@ void LoRaWANStack::mlme_indication_handler(loramac_mlme_indication_t *mlmeIndica
385379
}
386380
}
387381

388-
389382
void LoRaWANStack::set_lora_callbacks(lorawan_app_callbacks_t *cbs)
390383
{
391384
if (cbs) {
@@ -597,6 +590,10 @@ int16_t LoRaWANStack::handle_tx(uint8_t port, const uint8_t* data,
597590
return LORAWAN_STATUS_WOULD_BLOCK;
598591
}
599592

593+
if (!data && length > 0) {
594+
return LORAWAN_STATUS_PARAMETER_INVALID;
595+
}
596+
600597
#if defined(LORAWAN_COMPLIANCE_TEST)
601598
if (_compliance_test.running) {
602599
return LORAWAN_STATUS_COMPLIANCE_TEST_ON;
@@ -653,7 +650,7 @@ int16_t LoRaWANStack::handle_tx(uint8_t port, const uint8_t* data,
653650
_tx_msg.f_buffer_size = length;
654651
_tx_msg.pending_size = 0;
655652
// copy user buffer upto the max_possible_size
656-
if (data && length > 0) {
653+
if (length > 0) {
657654
memcpy(_tx_msg.f_buffer, data, length);
658655
}
659656
}
@@ -679,11 +676,11 @@ int16_t LoRaWANStack::handle_tx(uint8_t port, const uint8_t* data,
679676

680677
tr_info("RTS = %u bytes, PEND = %u", _tx_msg.f_buffer_size, _tx_msg.pending_size);
681678
set_device_state(DEVICE_STATE_SEND);
682-
lora_state_machine();
679+
status = lora_state_machine();
683680

684681
// send user the length of data which is scheduled now.
685682
// user should take care of the pending data.
686-
return _tx_msg.f_buffer_size;
683+
return (status == LORAWAN_STATUS_OK) ? _tx_msg.f_buffer_size : status;
687684
}
688685

689686
int16_t LoRaWANStack::handle_rx(const uint8_t port, uint8_t* data,
@@ -785,6 +782,8 @@ lorawan_status_t LoRaWANStack::mlme_request_handler(loramac_mlme_req_t *mlme_req
785782
void LoRaWANStack::mlme_confirm_handler(loramac_mlme_confirm_t *mlme_confirm)
786783
{
787784
if (NULL == mlme_confirm) {
785+
tr_error("mlme_confirm: struct [in] is null!");
786+
MBED_ASSERT(0);
788787
return;
789788
}
790789

@@ -793,14 +792,20 @@ void LoRaWANStack::mlme_confirm_handler(loramac_mlme_confirm_t *mlme_confirm)
793792
if (mlme_confirm->status == LORAMAC_EVENT_INFO_STATUS_OK) {
794793
// Status is OK, node has joined the network
795794
set_device_state(DEVICE_STATE_JOINED);
796-
lora_state_machine();
795+
if (lora_state_machine() != LORAWAN_STATUS_OK) {
796+
tr_error("Lora state machine did not return LORAWAN_STATUS_OK");
797+
}
797798
} else {
798799
// Join attempt failed.
799800
set_device_state(DEVICE_STATE_IDLE);
800-
lora_state_machine();
801+
if (lora_state_machine() != LORAWAN_STATUS_IDLE) {
802+
tr_error("Lora state machine did not return DEVICE_STATE_IDLE !");
803+
}
801804

802805
if (_callbacks.events) {
803-
_queue->call(_callbacks.events, JOIN_FAILURE);
806+
const int ret = _queue->call(_callbacks.events, JOIN_FAILURE);
807+
MBED_ASSERT(ret != 0);
808+
(void)ret;
804809
}
805810
}
806811
break;
@@ -818,15 +823,16 @@ void LoRaWANStack::mlme_confirm_handler(loramac_mlme_confirm_t *mlme_confirm)
818823
{
819824
// normal operation as oppose to compliance testing
820825
if (_callbacks.link_check_resp) {
821-
_queue->call(_callbacks.link_check_resp,
822-
mlme_confirm->demod_margin,
823-
mlme_confirm->nb_gateways);
826+
const int ret = _queue->call(_callbacks.link_check_resp,
827+
mlme_confirm->demod_margin,
828+
mlme_confirm->nb_gateways);
829+
MBED_ASSERT(ret != 0);
830+
(void)ret;
824831
}
825832
}
826833
}
827834
break;
828835
default:
829-
return;
830836
break;
831837
}
832838
}
@@ -848,7 +854,8 @@ lorawan_status_t LoRaWANStack::mcps_request_handler(loramac_mcps_req_t *mcps_req
848854
void LoRaWANStack::mcps_confirm_handler(loramac_mcps_confirm_t *mcps_confirm)
849855
{
850856
if (mcps_confirm == NULL) {
851-
tr_error("mcps_confirm: struct [in] is null.");
857+
tr_error("mcps_confirm: struct [in] is null!");
858+
MBED_ASSERT(0);
852859
return;
853860
}
854861

@@ -865,7 +872,9 @@ void LoRaWANStack::mcps_confirm_handler(loramac_mcps_confirm_t *mcps_confirm)
865872
// If sending timed out, we have a special event for that
866873
if (mcps_confirm->status == LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT) {
867874
if (_callbacks.events) {
868-
_queue->call(_callbacks.events, TX_TIMEOUT);
875+
const int ret = _queue->call(_callbacks.events, TX_TIMEOUT);
876+
MBED_ASSERT(ret != 0);
877+
(void)ret;
869878
}
870879
return;
871880
} if (mcps_confirm->status == LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT) {
@@ -874,7 +883,9 @@ void LoRaWANStack::mcps_confirm_handler(loramac_mcps_confirm_t *mcps_confirm)
874883

875884
// Otherwise send a general TX_ERROR event
876885
if (_callbacks.events) {
877-
_queue->call(_callbacks.events, TX_ERROR);
886+
const int ret = _queue->call(_callbacks.events, TX_ERROR);
887+
MBED_ASSERT(ret != 0);
888+
(void)ret;
878889
}
879890
return;
880891
}
@@ -896,7 +907,9 @@ void LoRaWANStack::mcps_confirm_handler(loramac_mcps_confirm_t *mcps_confirm)
896907
_lw_session.uplink_counter = mcps_confirm->ul_frame_counter;
897908
_tx_msg.tx_ongoing = false;
898909
if (_callbacks.events) {
899-
_queue->call(_callbacks.events, TX_DONE);
910+
const int ret = _queue->call(_callbacks.events, TX_DONE);
911+
MBED_ASSERT(ret != 0);
912+
(void)ret;
900913
}
901914
}
902915

@@ -914,7 +927,9 @@ void LoRaWANStack::mcps_indication_handler(loramac_mcps_indication_t *mcps_indic
914927

915928
if (mcps_indication->status != LORAMAC_EVENT_INFO_STATUS_OK) {
916929
if (_callbacks.events) {
917-
_queue->call(_callbacks.events, RX_ERROR);
930+
const int ret = _queue->call(_callbacks.events, RX_ERROR);
931+
MBED_ASSERT(ret != 0);
932+
(void)ret;
918933
}
919934
return;
920935
}
@@ -971,7 +986,9 @@ void LoRaWANStack::mcps_indication_handler(loramac_mcps_indication_t *mcps_indic
971986
// to the size 255 bytes
972987
tr_debug("Cannot receive more than buffer capacity!");
973988
if (_callbacks.events) {
974-
_queue->call(_callbacks.events, RX_ERROR);
989+
const int ret = _queue->call(_callbacks.events, RX_ERROR);
990+
MBED_ASSERT(ret != 0);
991+
(void)ret;
975992
}
976993
return;
977994
} else {
@@ -987,7 +1004,9 @@ void LoRaWANStack::mcps_indication_handler(loramac_mcps_indication_t *mcps_indic
9871004
tr_debug("Received %d bytes", _rx_msg.msg.mcps_indication.buffer_size);
9881005
_rx_msg.receive_ready = true;
9891006
if (_callbacks.events) {
990-
_queue->call(_callbacks.events, RX_DONE);
1007+
const int ret = _queue->call(_callbacks.events, RX_DONE);
1008+
MBED_ASSERT(ret != 0);
1009+
(void)ret;
9911010
}
9921011

9931012
// If fPending bit is set we try to generate an empty packet
@@ -1146,7 +1165,6 @@ lorawan_status_t LoRaWANStack::mib_set_request(loramac_mib_req_confirm_t *mib_se
11461165
if (NULL == mib_set_params) {
11471166
return LORAWAN_STATUS_PARAMETER_INVALID;
11481167
}
1149-
11501168
return _loramac.LoRaMacMibSetRequestConfirm(mib_set_params);
11511169
}
11521170

@@ -1155,10 +1173,7 @@ lorawan_status_t LoRaWANStack::mib_get_request(loramac_mib_req_confirm_t *mib_ge
11551173
if(NULL == mib_get_params) {
11561174
return LORAWAN_STATUS_PARAMETER_INVALID;
11571175
}
1158-
11591176
return _loramac.LoRaMacMibGetRequestConfirm(mib_get_params);
1160-
1161-
11621177
}
11631178

11641179
lorawan_status_t LoRaWANStack::set_link_check_request()
@@ -1174,10 +1189,10 @@ lorawan_status_t LoRaWANStack::set_link_check_request()
11741189
return mlme_request_handler(&mlme_req);
11751190
}
11761191

1177-
void LoRaWANStack::shutdown()
1192+
lorawan_status_t LoRaWANStack::shutdown()
11781193
{
11791194
set_device_state(DEVICE_STATE_SHUTDOWN);
1180-
lora_state_machine();
1195+
return lora_state_machine();
11811196
}
11821197

11831198
lorawan_status_t LoRaWANStack::lora_state_machine()
@@ -1219,7 +1234,9 @@ lorawan_status_t LoRaWANStack::lora_state_machine()
12191234

12201235
tr_debug("LoRaWAN protocol has been shut down.");
12211236
if (_callbacks.events) {
1222-
_queue->call(_callbacks.events, DISCONNECTED);
1237+
const int ret = _queue->call(_callbacks.events, DISCONNECTED);
1238+
MBED_ASSERT(ret != 0);
1239+
(void)ret;
12231240
}
12241241
status = LORAWAN_STATUS_DEVICE_OFF;
12251242
break;
@@ -1254,7 +1271,6 @@ lorawan_status_t LoRaWANStack::lora_state_machine()
12541271
return LORAWAN_STATUS_CONNECT_IN_PROGRESS;
12551272
} else {
12561273
status = LORAWAN_STATUS_PARAMETER_INVALID;
1257-
break;
12581274
}
12591275
break;
12601276
case DEVICE_STATE_JOINED:
@@ -1263,8 +1279,11 @@ lorawan_status_t LoRaWANStack::lora_state_machine()
12631279
_lw_session.active = true;
12641280
// Tell the application that we are connected
12651281
if (_callbacks.events) {
1266-
_queue->call(_callbacks.events, CONNECTED);
1282+
const int ret = _queue->call(_callbacks.events, CONNECTED);
1283+
MBED_ASSERT(ret != 0);
1284+
(void)ret;
12671285
}
1286+
status = LORAWAN_STATUS_OK;
12681287
break;
12691288
case DEVICE_STATE_ABP_CONNECTING:
12701289
/*
@@ -1297,7 +1316,9 @@ lorawan_status_t LoRaWANStack::lora_state_machine()
12971316
// Session is now active
12981317
_lw_session.active = true;
12991318
if (_callbacks.events) {
1300-
_queue->call(_callbacks.events, CONNECTED);
1319+
const int ret = _queue->call(_callbacks.events, CONNECTED);
1320+
MBED_ASSERT(ret != 0);
1321+
(void)ret;
13011322
}
13021323
break;
13031324
case DEVICE_STATE_SEND:
@@ -1315,13 +1336,17 @@ lorawan_status_t LoRaWANStack::lora_state_machine()
13151336
case LORAWAN_STATUS_CRYPTO_FAIL:
13161337
tr_error("Crypto failed. Clearing TX buffers");
13171338
if (_callbacks.events) {
1318-
_queue->call(_callbacks.events, TX_CRYPTO_ERROR);
1339+
const int ret = _queue->call(_callbacks.events, TX_CRYPTO_ERROR);
1340+
MBED_ASSERT(ret != 0);
1341+
(void)ret;
13191342
}
13201343
break;
13211344
default:
13221345
tr_error("Failure to schedule TX!");
13231346
if (_callbacks.events) {
1324-
_queue->call(_callbacks.events, TX_SCHEDULING_ERROR);
1347+
const int ret = _queue->call(_callbacks.events, TX_SCHEDULING_ERROR);
1348+
MBED_ASSERT(ret != 0);
1349+
(void)ret;
13251350
}
13261351
break;
13271352
}

features/lorawan/LoRaWANStack.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,8 +322,10 @@ class LoRaWANStack: private mbed::NonCopyable<LoRaWANStack> {
322322
/** Shuts down the LoRaWAN protocol.
323323
*
324324
* In response to the user call for disconnection, the stack shuts down itself.
325+
*
326+
* @return LORAWAN_STATUS_DEVICE_OFF on successfully shutdown.
325327
*/
326-
void shutdown();
328+
lorawan_status_t shutdown();
327329

328330
private:
329331
LoRaWANStack();
@@ -442,8 +444,10 @@ class LoRaWANStack: private mbed::NonCopyable<LoRaWANStack> {
442444
LoRaWANTimeHandler _lora_time;
443445
LoRaMac _loramac;
444446
LoRaPHY_region _lora_phy;
447+
loramac_primitives_t LoRaMacPrimitives;
445448

446449
#if defined(LORAWAN_COMPLIANCE_TEST)
450+
uint8_t compliance_test_buffer[MBED_CONF_LORA_TX_MAX_SIZE];
447451
compliance_test_t _compliance_test;
448452
#endif
449453

0 commit comments

Comments
 (0)