Skip to content

Commit 50c39ce

Browse files
author
Hasnain Virk
committed
Adding thread safety
Making our LoRaWAN stack thread safe. If RTOS is not present, locks don't do anything. ScopedLock is used to automate the lock release on context expiry.
1 parent ff808cf commit 50c39ce

File tree

4 files changed

+53
-0
lines changed

4 files changed

+53
-0
lines changed

features/lorawan/LoRaWANInterface.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,95 +34,114 @@ LoRaWANInterface::~LoRaWANInterface()
3434

3535
lorawan_status_t LoRaWANInterface::initialize(EventQueue *queue)
3636
{
37+
Lock lock(*this);
3738
return _lw_stack.initialize_mac_layer(queue);
3839
}
3940

4041
lorawan_status_t LoRaWANInterface::connect()
4142
{
43+
Lock lock(*this);
4244
return _lw_stack.connect();
4345
}
4446

4547
lorawan_status_t LoRaWANInterface::connect(const lorawan_connect_t &connect)
4648
{
49+
Lock lock(*this);
4750
return _lw_stack.connect(connect);
4851
}
4952

5053
lorawan_status_t LoRaWANInterface::disconnect()
5154
{
55+
Lock lock(*this);
5256
return _lw_stack.shutdown();
5357
}
5458

5559
lorawan_status_t LoRaWANInterface::add_link_check_request()
5660
{
61+
Lock lock(*this);
5762
return _lw_stack.set_link_check_request();
5863
}
5964

6065
void LoRaWANInterface::remove_link_check_request()
6166
{
67+
Lock lock(*this);
6268
_lw_stack.remove_link_check_request();
6369
}
6470

6571
lorawan_status_t LoRaWANInterface::set_datarate(uint8_t data_rate)
6672
{
73+
Lock lock(*this);
6774
return _lw_stack.set_channel_data_rate(data_rate);
6875
}
6976

7077
lorawan_status_t LoRaWANInterface::set_confirmed_msg_retries(uint8_t count)
7178
{
79+
Lock lock(*this);
7280
return _lw_stack.set_confirmed_msg_retry(count);
7381
}
7482

7583
lorawan_status_t LoRaWANInterface::enable_adaptive_datarate()
7684
{
85+
Lock lock(*this);
7786
return _lw_stack.enable_adaptive_datarate(true);
7887
}
7988

8089
lorawan_status_t LoRaWANInterface::disable_adaptive_datarate()
8190
{
91+
Lock lock(*this);
8292
return _lw_stack.enable_adaptive_datarate(false);
8393
}
8494

8595
lorawan_status_t LoRaWANInterface::set_channel_plan(const lorawan_channelplan_t &channel_plan)
8696
{
97+
Lock lock(*this);
8798
return _lw_stack.add_channels(channel_plan);
8899
}
89100

90101
lorawan_status_t LoRaWANInterface::get_channel_plan(lorawan_channelplan_t &channel_plan)
91102
{
103+
Lock lock(*this);
92104
return _lw_stack.get_enabled_channels(channel_plan);
93105
}
94106

95107
lorawan_status_t LoRaWANInterface::remove_channel(uint8_t id)
96108
{
109+
Lock lock(*this);
97110
return _lw_stack.remove_a_channel(id);
98111
}
99112

100113
lorawan_status_t LoRaWANInterface::remove_channel_plan()
101114
{
115+
Lock lock(*this);
102116
return _lw_stack.drop_channel_list();
103117
}
104118

105119
int16_t LoRaWANInterface::send(uint8_t port, const uint8_t* data, uint16_t length, int flags)
106120
{
121+
Lock lock(*this);
107122
return _lw_stack.handle_tx(port, data, length, flags);
108123
}
109124

110125
int16_t LoRaWANInterface::receive(uint8_t port, uint8_t* data, uint16_t length, int flags)
111126
{
127+
Lock lock(*this);
112128
return _lw_stack.handle_rx(data, length, port, flags, true);
113129
}
114130

115131
int16_t LoRaWANInterface::receive(uint8_t* data, uint16_t length, uint8_t& port, int& flags)
116132
{
133+
Lock lock(*this);
117134
return _lw_stack.handle_rx(data, length, port, flags, false);
118135
}
119136

120137
lorawan_status_t LoRaWANInterface::add_app_callbacks(lorawan_app_callbacks_t *callbacks)
121138
{
139+
Lock lock(*this);
122140
return _lw_stack.set_lora_callbacks(callbacks);
123141
}
124142

125143
lorawan_status_t LoRaWANInterface::set_device_class(const device_class_t device_class)
126144
{
145+
Lock lock(*this);
127146
return _lw_stack.set_device_class(device_class);
128147
}

features/lorawan/LoRaWANInterface.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#define LORAWANINTERFACE_H_
2020

2121
#include "platform/Callback.h"
22+
#include "platform/ScopedLock.h"
2223
#include "LoRaWANStack.h"
2324
#include "LoRaRadio.h"
2425
#include "LoRaWANBase.h"
@@ -435,7 +436,13 @@ class LoRaWANInterface: public LoRaWANBase {
435436
*/
436437
virtual lorawan_status_t set_device_class(const device_class_t device_class);
437438

439+
void lock(void) { _lw_stack.lock(); }
440+
void unlock(void) { _lw_stack.unlock(); }
441+
442+
438443
private:
444+
typedef mbed::ScopedLock<LoRaWANInterface> Lock;
445+
439446
LoRaWANStack _lw_stack;
440447
};
441448

features/lorawan/LoRaWANStack.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#include "events/EventQueue.h"
4545
#include "platform/Callback.h"
4646
#include "platform/NonCopyable.h"
47+
#include "platform/ScopedLock.h"
4748

4849
#include "lorastack/mac/LoRaMac.h"
4950
#include "system/LoRaWANTimer.h"
@@ -395,7 +396,11 @@ class LoRaWANStack: private mbed::NonCopyable<LoRaWANStack> {
395396
*/
396397
lorawan_status_t set_device_class(const device_class_t& device_class);
397398

399+
void lock(void) { _loramac.lock(); }
400+
void unlock(void) { _loramac.unlock(); }
401+
398402
private:
403+
typedef mbed::ScopedLock<LoRaWANStack> Lock;
399404
/**
400405
* Checks if the user provided port is valid or not
401406
*/

features/lorawan/lorastack/mac/LoRaMac.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,11 @@
5151
#include "LoRaMacChannelPlan.h"
5252
#include "LoRaMacCommand.h"
5353
#include "LoRaMacCrypto.h"
54+
#if MBED_CONF_RTOS_PRESENT
55+
#include "rtos/Mutex.h"
56+
#endif
5457

58+
#include "platform/ScopedLock.h"
5559

5660
class LoRaMac {
5761

@@ -422,6 +426,24 @@ class LoRaMac {
422426
*/
423427
void on_mac_state_check_timer_event(void);
424428

429+
/**
430+
* These locks trample through to the upper layers and make
431+
* the stack thread safe.
432+
*/
433+
#if MBED_CONF_RTOS_PRESENT
434+
void lock(void) { osStatus status = _mutex.lock(); MBED_ASSERT(status == osOK); }
435+
void unlock(void) { osStatus status = _mutex.unlock(); MBED_ASSERT(status == osOK); }
436+
#else
437+
void lock(void) { }
438+
void unlock(void) { }
439+
#endif
440+
441+
private:
442+
typedef mbed::ScopedLock<LoRaMac> Lock;
443+
#if MBED_CONF_RTOS_PRESENT
444+
rtos::Mutex _mutex;
445+
#endif
446+
425447
/**
426448
* Function executed on duty cycle delayed Tx timer event
427449
*/

0 commit comments

Comments
 (0)