mirror of https://github.com/ARMmbed/mbed-os.git
				
				
				
			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.pull/6808/head
							parent
							
								
									a331c4b59a
								
							
						
					
					
						commit
						a75af9799e
					
				| 
						 | 
					@ -34,95 +34,114 @@ LoRaWANInterface::~LoRaWANInterface()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lorawan_status_t LoRaWANInterface::initialize(EventQueue *queue)
 | 
					lorawan_status_t LoRaWANInterface::initialize(EventQueue *queue)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    Lock lock(*this);
 | 
				
			||||||
    return _lw_stack.initialize_mac_layer(queue);
 | 
					    return _lw_stack.initialize_mac_layer(queue);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lorawan_status_t LoRaWANInterface::connect()
 | 
					lorawan_status_t LoRaWANInterface::connect()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    Lock lock(*this);
 | 
				
			||||||
    return _lw_stack.connect();
 | 
					    return _lw_stack.connect();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lorawan_status_t LoRaWANInterface::connect(const lorawan_connect_t &connect)
 | 
					lorawan_status_t LoRaWANInterface::connect(const lorawan_connect_t &connect)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    Lock lock(*this);
 | 
				
			||||||
    return _lw_stack.connect(connect);
 | 
					    return _lw_stack.connect(connect);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lorawan_status_t LoRaWANInterface::disconnect()
 | 
					lorawan_status_t LoRaWANInterface::disconnect()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    Lock lock(*this);
 | 
				
			||||||
    return _lw_stack.shutdown();
 | 
					    return _lw_stack.shutdown();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lorawan_status_t LoRaWANInterface::add_link_check_request()
 | 
					lorawan_status_t LoRaWANInterface::add_link_check_request()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    Lock lock(*this);
 | 
				
			||||||
    return _lw_stack.set_link_check_request();
 | 
					    return _lw_stack.set_link_check_request();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void LoRaWANInterface::remove_link_check_request()
 | 
					void LoRaWANInterface::remove_link_check_request()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    Lock lock(*this);
 | 
				
			||||||
    _lw_stack.remove_link_check_request();
 | 
					    _lw_stack.remove_link_check_request();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lorawan_status_t LoRaWANInterface::set_datarate(uint8_t data_rate)
 | 
					lorawan_status_t LoRaWANInterface::set_datarate(uint8_t data_rate)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    Lock lock(*this);
 | 
				
			||||||
    return _lw_stack.set_channel_data_rate(data_rate);
 | 
					    return _lw_stack.set_channel_data_rate(data_rate);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lorawan_status_t LoRaWANInterface::set_confirmed_msg_retries(uint8_t count)
 | 
					lorawan_status_t LoRaWANInterface::set_confirmed_msg_retries(uint8_t count)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    Lock lock(*this);
 | 
				
			||||||
    return _lw_stack.set_confirmed_msg_retry(count);
 | 
					    return _lw_stack.set_confirmed_msg_retry(count);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lorawan_status_t LoRaWANInterface::enable_adaptive_datarate()
 | 
					lorawan_status_t LoRaWANInterface::enable_adaptive_datarate()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    Lock lock(*this);
 | 
				
			||||||
    return _lw_stack.enable_adaptive_datarate(true);
 | 
					    return _lw_stack.enable_adaptive_datarate(true);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lorawan_status_t LoRaWANInterface::disable_adaptive_datarate()
 | 
					lorawan_status_t LoRaWANInterface::disable_adaptive_datarate()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    Lock lock(*this);
 | 
				
			||||||
    return _lw_stack.enable_adaptive_datarate(false);
 | 
					    return _lw_stack.enable_adaptive_datarate(false);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lorawan_status_t LoRaWANInterface::set_channel_plan(const lorawan_channelplan_t &channel_plan)
 | 
					lorawan_status_t LoRaWANInterface::set_channel_plan(const lorawan_channelplan_t &channel_plan)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    Lock lock(*this);
 | 
				
			||||||
    return _lw_stack.add_channels(channel_plan);
 | 
					    return _lw_stack.add_channels(channel_plan);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lorawan_status_t LoRaWANInterface::get_channel_plan(lorawan_channelplan_t &channel_plan)
 | 
					lorawan_status_t LoRaWANInterface::get_channel_plan(lorawan_channelplan_t &channel_plan)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    Lock lock(*this);
 | 
				
			||||||
    return _lw_stack.get_enabled_channels(channel_plan);
 | 
					    return _lw_stack.get_enabled_channels(channel_plan);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lorawan_status_t LoRaWANInterface::remove_channel(uint8_t id)
 | 
					lorawan_status_t LoRaWANInterface::remove_channel(uint8_t id)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    Lock lock(*this);
 | 
				
			||||||
    return _lw_stack.remove_a_channel(id);
 | 
					    return _lw_stack.remove_a_channel(id);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lorawan_status_t LoRaWANInterface::remove_channel_plan()
 | 
					lorawan_status_t LoRaWANInterface::remove_channel_plan()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    Lock lock(*this);
 | 
				
			||||||
    return _lw_stack.drop_channel_list();
 | 
					    return _lw_stack.drop_channel_list();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int16_t LoRaWANInterface::send(uint8_t port, const uint8_t* data, uint16_t length, int flags)
 | 
					int16_t LoRaWANInterface::send(uint8_t port, const uint8_t* data, uint16_t length, int flags)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    Lock lock(*this);
 | 
				
			||||||
    return _lw_stack.handle_tx(port, data, length, flags);
 | 
					    return _lw_stack.handle_tx(port, data, length, flags);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int16_t LoRaWANInterface::receive(uint8_t port, uint8_t* data, uint16_t length, int flags)
 | 
					int16_t LoRaWANInterface::receive(uint8_t port, uint8_t* data, uint16_t length, int flags)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    Lock lock(*this);
 | 
				
			||||||
    return _lw_stack.handle_rx(data, length, port, flags, true);
 | 
					    return _lw_stack.handle_rx(data, length, port, flags, true);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int16_t LoRaWANInterface::receive(uint8_t* data, uint16_t length, uint8_t& port, int& flags)
 | 
					int16_t LoRaWANInterface::receive(uint8_t* data, uint16_t length, uint8_t& port, int& flags)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    Lock lock(*this);
 | 
				
			||||||
    return _lw_stack.handle_rx(data, length, port, flags, false);
 | 
					    return _lw_stack.handle_rx(data, length, port, flags, false);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lorawan_status_t LoRaWANInterface::add_app_callbacks(lorawan_app_callbacks_t *callbacks)
 | 
					lorawan_status_t LoRaWANInterface::add_app_callbacks(lorawan_app_callbacks_t *callbacks)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    Lock lock(*this);
 | 
				
			||||||
    return _lw_stack.set_lora_callbacks(callbacks);
 | 
					    return _lw_stack.set_lora_callbacks(callbacks);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lorawan_status_t LoRaWANInterface::set_device_class(const device_class_t device_class)
 | 
					lorawan_status_t LoRaWANInterface::set_device_class(const device_class_t device_class)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    Lock lock(*this);
 | 
				
			||||||
    return _lw_stack.set_device_class(device_class);
 | 
					    return _lw_stack.set_device_class(device_class);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,6 +19,7 @@
 | 
				
			||||||
#define LORAWANINTERFACE_H_
 | 
					#define LORAWANINTERFACE_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "platform/Callback.h"
 | 
					#include "platform/Callback.h"
 | 
				
			||||||
 | 
					#include "platform/ScopedLock.h"
 | 
				
			||||||
#include "LoRaWANStack.h"
 | 
					#include "LoRaWANStack.h"
 | 
				
			||||||
#include "LoRaRadio.h"
 | 
					#include "LoRaRadio.h"
 | 
				
			||||||
#include "LoRaWANBase.h"
 | 
					#include "LoRaWANBase.h"
 | 
				
			||||||
| 
						 | 
					@ -435,7 +436,13 @@ public:
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    virtual lorawan_status_t set_device_class(const device_class_t device_class);
 | 
					    virtual lorawan_status_t set_device_class(const device_class_t device_class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void lock(void) { _lw_stack.lock(); }
 | 
				
			||||||
 | 
					    void unlock(void) { _lw_stack.unlock(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
 | 
					    typedef mbed::ScopedLock<LoRaWANInterface> Lock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    LoRaWANStack _lw_stack;
 | 
					    LoRaWANStack _lw_stack;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,6 +44,7 @@
 | 
				
			||||||
#include "events/EventQueue.h"
 | 
					#include "events/EventQueue.h"
 | 
				
			||||||
#include "platform/Callback.h"
 | 
					#include "platform/Callback.h"
 | 
				
			||||||
#include "platform/NonCopyable.h"
 | 
					#include "platform/NonCopyable.h"
 | 
				
			||||||
 | 
					#include "platform/ScopedLock.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "lorastack/mac/LoRaMac.h"
 | 
					#include "lorastack/mac/LoRaMac.h"
 | 
				
			||||||
#include "system/LoRaWANTimer.h"
 | 
					#include "system/LoRaWANTimer.h"
 | 
				
			||||||
| 
						 | 
					@ -395,7 +396,11 @@ public:
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    lorawan_status_t set_device_class(const device_class_t& device_class);
 | 
					    lorawan_status_t set_device_class(const device_class_t& device_class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void lock(void) { _loramac.lock(); }
 | 
				
			||||||
 | 
					    void unlock(void) { _loramac.unlock(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
 | 
					    typedef mbed::ScopedLock<LoRaWANStack> Lock;
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Checks if the user provided port is valid or not
 | 
					     * Checks if the user provided port is valid or not
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,7 +51,11 @@
 | 
				
			||||||
#include "LoRaMacChannelPlan.h"
 | 
					#include "LoRaMacChannelPlan.h"
 | 
				
			||||||
#include "LoRaMacCommand.h"
 | 
					#include "LoRaMacCommand.h"
 | 
				
			||||||
#include "LoRaMacCrypto.h"
 | 
					#include "LoRaMacCrypto.h"
 | 
				
			||||||
 | 
					#if MBED_CONF_RTOS_PRESENT
 | 
				
			||||||
 | 
					#include "rtos/Mutex.h"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "platform/ScopedLock.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class LoRaMac {
 | 
					class LoRaMac {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -422,6 +426,24 @@ private:
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    void on_mac_state_check_timer_event(void);
 | 
					    void on_mac_state_check_timer_event(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * These locks trample through to the upper layers and make
 | 
				
			||||||
 | 
					     * the stack thread safe.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					#if MBED_CONF_RTOS_PRESENT
 | 
				
			||||||
 | 
					    void lock(void) { osStatus status = _mutex.lock(); MBED_ASSERT(status == osOK); }
 | 
				
			||||||
 | 
					    void unlock(void) { osStatus status = _mutex.unlock(); MBED_ASSERT(status == osOK); }
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    void lock(void) { }
 | 
				
			||||||
 | 
					    void unlock(void) { }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    typedef mbed::ScopedLock<LoRaMac> Lock;
 | 
				
			||||||
 | 
					#if MBED_CONF_RTOS_PRESENT
 | 
				
			||||||
 | 
					    rtos::Mutex _mutex;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Function executed on duty cycle delayed Tx  timer event
 | 
					     * Function executed on duty cycle delayed Tx  timer event
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue