diff --git a/features/lorawan/LoRaWANInterface.cpp b/features/lorawan/LoRaWANInterface.cpp index e78ec41b60..92022a9c1d 100644 --- a/features/lorawan/LoRaWANInterface.cpp +++ b/features/lorawan/LoRaWANInterface.cpp @@ -21,6 +21,8 @@ #include "lorawan/LoRaWANInterface.h" +using namespace events; + inline LoRaWANStack& stk_obj() { return LoRaWANStack::get_lorawan_stack(); @@ -40,9 +42,13 @@ LoRaWANInterface::~LoRaWANInterface() { } -lora_mac_status_t LoRaWANInterface::initialize() +lora_mac_status_t LoRaWANInterface::initialize(EventQueue *queue) { - return stk_obj().initialize_mac_layer(); + if(!queue) { + return LORA_MAC_STATUS_PARAMETER_INVALID; + } + + return stk_obj().initialize_mac_layer(queue); } lora_mac_status_t LoRaWANInterface::connect() diff --git a/features/lorawan/LoRaWANInterface.h b/features/lorawan/LoRaWANInterface.h index 3f39f193c7..87d533da72 100644 --- a/features/lorawan/LoRaWANInterface.h +++ b/features/lorawan/LoRaWANInterface.h @@ -40,9 +40,11 @@ public: * * You must call this first to be able to use the LoRa stack. * - * \return 0 on success, a negative error code on failure. + * @param ev_queue A pointer to EventQueue provided by the application. + * + * @return 0 on success, a negative error code on failure. */ - virtual lora_mac_status_t initialize(); + virtual lora_mac_status_t initialize(events::EventQueue *ev_queue) ; /** Connect OTAA or ABP using Mbed-OS config system * diff --git a/features/lorawan/LoRaWANStack.cpp b/features/lorawan/LoRaWANStack.cpp index e9182491f0..c017eba21f 100644 --- a/features/lorawan/LoRaWANStack.cpp +++ b/features/lorawan/LoRaWANStack.cpp @@ -26,6 +26,7 @@ SPDX-License-Identifier: BSD-3-Clause #include #include #include "platform/Callback.h" +#include "events/EventQueue.h" #include "lorawan/LoRaWANStack.h" #if defined(FEATURE_COMMON_PAL) #include "mbed_trace.h" @@ -77,6 +78,7 @@ SPDX-License-Identifier: BSD-3-Clause #endif //MBED_CONF_LORA_PHY using namespace mbed; +using namespace events; /** * Helper function prototypes @@ -129,7 +131,7 @@ lora_mac_status_t LoRaWANStack::set_application_port(uint8_t port) ****************************************************************************/ LoRaWANStack::LoRaWANStack() : _device_current_state(DEVICE_STATE_NOT_INITIALIZED), _mac_handlers(NULL), - _num_retry(1), _duty_cycle_on(LORAWAN_DUTYCYCLE_ON) + _num_retry(1), _queue(NULL), _duty_cycle_on(LORAWAN_DUTYCYCLE_ON) { #ifdef MBED_CONF_LORA_APP_PORT // is_port_valid() is not virtual, so we can call it in constructor @@ -173,7 +175,7 @@ radio_events_t *LoRaWANStack::bind_radio_driver(LoRaRadio& radio) lora_phy.set_radio_instance(radio); return _mac_handlers; } -lora_mac_status_t LoRaWANStack::initialize_mac_layer() +lora_mac_status_t LoRaWANStack::initialize_mac_layer(EventQueue *queue) { if (DEVICE_STATE_NOT_INITIALIZED != _device_current_state) { @@ -188,6 +190,9 @@ lora_mac_status_t LoRaWANStack::initialize_mac_layer() tr_debug("Initializing MAC layer"); + //store a pointer to Event Queue + _queue = queue; + // Allocate memory for compliance test _compliance_test.app_data_buffer = compliance_test_buffer; @@ -196,7 +201,7 @@ lora_mac_status_t LoRaWANStack::initialize_mac_layer() LoRaMacPrimitives.MacMcpsIndication = callback(this, &LoRaWANStack::mcps_indication); LoRaMacPrimitives.MacMlmeConfirm = callback(this, &LoRaWANStack::mlme_confirm); LoRaMacCallbacks.TxNextPacketTimerEvent = callback(this, &LoRaWANStack::on_tx_next_packet_timer_event); - LoRaMacInitialization(&LoRaMacPrimitives, &LoRaMacCallbacks, lora_phy); + LoRaMacInitialization(&LoRaMacPrimitives, &LoRaMacCallbacks, &lora_phy, queue); mib_req.type = LORA_MIB_ADR; mib_req.param.adr_enable = LORAWAN_ADR_ON; @@ -394,7 +399,7 @@ void LoRaWANStack::on_tx_next_packet_timer_event(void) lora_mac_status_t LoRaWANStack::set_confirmed_msg_retry(uint8_t count) { - if (count > MAX_CONFIRMED_MSG_RETRIES) { + if (count >= MAX_CONFIRMED_MSG_RETRIES) { return LORA_MAC_STATUS_PARAMETER_INVALID; } @@ -1046,7 +1051,7 @@ void LoRaWANStack::mlme_confirm_handler(lora_mac_mlme_confirm_t *mlme_confirm) // Join attempt failed. set_device_state(DEVICE_STATE_IDLE); lora_state_machine(); - _events(JOIN_FAILURE); + _queue->call(_events, JOIN_FAILURE); } break; case LORA_MLME_LINK_CHECK: @@ -1127,14 +1132,14 @@ void LoRaWANStack::mcps_confirm_handler(lora_mac_mcps_confirm_t *mcps_confirm) // If sending timed out, we have a special event for that if (mcps_confirm->status == LORA_EVENT_INFO_STATUS_TX_TIMEOUT) { - _events(TX_TIMEOUT); + _queue->call(_events, TX_TIMEOUT); return; } if (mcps_confirm->status == LORA_EVENT_INFO_STATUS_RX2_TIMEOUT) { tr_debug("Did not receive Ack"); } // Otherwise send a general TX_ERROR event - _events(TX_ERROR); + _queue->call(_events, TX_ERROR); return; } @@ -1154,7 +1159,7 @@ void LoRaWANStack::mcps_confirm_handler(lora_mac_mcps_confirm_t *mcps_confirm) // data rate plus frame counter. _lw_session.uplink_counter = mcps_confirm->uplink_counter; _tx_msg.tx_ongoing = false; - _events(TX_DONE); + _queue->call(_events, TX_DONE); } /** MCPS-Indication event function @@ -1170,7 +1175,7 @@ void LoRaWANStack::mcps_indication_handler(lora_mac_mcps_indication_t *mcps_indi } if (mcps_indication->status != LORA_EVENT_INFO_STATUS_OK) { - _events(RX_ERROR); + _queue->call(_events, RX_ERROR); return; } @@ -1219,7 +1224,7 @@ void LoRaWANStack::mcps_indication_handler(lora_mac_mcps_indication_t *mcps_indi // This may never happen as both radio and MAC are limited // to the size 255 bytes tr_debug("Cannot receive more than buffer capacity!"); - _events(RX_ERROR); + _queue->call(_events, RX_ERROR); return; } else { _rx_msg.type = LORAMAC_RX_MCPS_INDICATION; @@ -1233,7 +1238,7 @@ void LoRaWANStack::mcps_indication_handler(lora_mac_mcps_indication_t *mcps_indi // Notify application about received frame.. tr_debug("Received %d bytes", _rx_msg.rx_message.mcps_indication.buffer_size); _rx_msg.receive_ready = true; - _events(RX_DONE); + _queue->call(_events, RX_DONE); } else { // Invalid port, ports 0, 224 and 225-255 are reserved. } @@ -1800,7 +1805,7 @@ lora_mac_status_t LoRaWANStack::lora_state_machine() _lw_session.active = false; tr_debug("LoRaWAN protocol has been shut down."); - _events(DISCONNECTED); + _queue->call(_events, DISCONNECTED); status = LORA_MAC_STATUS_DEVICE_OFF; break; case DEVICE_STATE_NOT_INITIALIZED: @@ -1842,7 +1847,7 @@ lora_mac_status_t LoRaWANStack::lora_state_machine() // Session is now active _lw_session.active = true; // Tell the application that we are connected - _events(CONNECTED); + _queue->call(_events, CONNECTED); break; case DEVICE_STATE_ABP_CONNECTING: /* @@ -1874,7 +1879,7 @@ lora_mac_status_t LoRaWANStack::lora_state_machine() status = LORA_MAC_STATUS_OK; // Session is now active _lw_session.active = true; - _events(CONNECTED); + _queue->call(_events, CONNECTED); break; case DEVICE_STATE_SEND: // If a transmission is ongoing, don't interrupt @@ -1890,11 +1895,11 @@ lora_mac_status_t LoRaWANStack::lora_state_machine() break; case LORA_MAC_STATUS_CRYPTO_FAIL: tr_error("Crypto failed. Clearing TX buffers"); - _events(TX_CRYPTO_ERROR); + _queue->call(_events, TX_CRYPTO_ERROR); break; default: tr_error("Failure to schedule TX!"); - _events(TX_SCHEDULING_ERROR); + _queue->call(_events, TX_SCHEDULING_ERROR); break; } } diff --git a/features/lorawan/LoRaWANStack.h b/features/lorawan/LoRaWANStack.h index a4a5b62135..0e1aa7f675 100644 --- a/features/lorawan/LoRaWANStack.h +++ b/features/lorawan/LoRaWANStack.h @@ -27,6 +27,7 @@ SPDX-License-Identifier: BSD-3-Clause #define LORAWANSTACK_H_ #include +#include "events/EventQueue.h" #include "platform/Callback.h" #include "platform/NonCopyable.h" #include "lorawan/system/LoRaWANTimer.h" @@ -59,14 +60,14 @@ public: radio_events_t *bind_radio_driver(LoRaRadio& radio); /** End device initialization. - * - * \return 0 on success, a negative error code on failure. + * @param queue A pointer to an EventQueue passed from the application. + * @return LORA_MAC_STATUS_OK on success, a negative error code on failure. */ - lora_mac_status_t initialize_mac_layer(); + lora_mac_status_t initialize_mac_layer(events::EventQueue *queue); /** Sets all callbacks of the LoRaWAN interface. * - * \param *event_cb An event structure representing all possible callbacks. + * @param *event_cb An event structure representing all possible callbacks. */ void set_lora_event_cb(mbed::Callback event_cb); @@ -418,6 +419,7 @@ private: lora_mac_rx_message_t _rx_msg; uint8_t _app_port; uint8_t _num_retry; + events::EventQueue *_queue; bool _duty_cycle_on; }; diff --git a/features/lorawan/lorastack/mac/LoRaMac.cpp b/features/lorawan/lorastack/mac/LoRaMac.cpp index 4d7418e24c..994945976d 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.cpp +++ b/features/lorawan/lorastack/mac/LoRaMac.cpp @@ -38,12 +38,18 @@ SPDX-License-Identifier: BSD-3-Clause #define tr_error(...) (void(0)) //dummies if feature common pal is not added #endif //defined(FEATURE_COMMON_PAL) +using namespace events; /** * LoRa PHY layer object storage */ static LoRaPHY *lora_phy; +/** + * EventQueue object storage + */ +static EventQueue *ev_queue; + /** * Radio event callback handlers for MAC */ @@ -643,115 +649,49 @@ static void handle_delayed_tx_timer_event(void); static void handle_mac_state_check_timer_event(void); static void handle_next_tx_timer_event(void); -/*************************************************************************** - * LoRaMACTask class - Handles deferred callbacks * - * and timers from Interrupt context * - **************************************************************************/ -/** - * An internal class to facilitate MAC related tasks. - * Idea is to mould Semtech code as less as possible so - * as to make future integration smoother. - * - * This class is present only if RTOS is being used. - */ -#ifdef MBED_CONF_RTOS_PRESENT - -class LoRaMACTask { - -public: - LoRaMACTask(); - events::EventQueue queue; - -private: - rtos::Thread t; -}; - -LoRaMACTask::LoRaMACTask() - : queue(16 * EVENTS_EVENT_SIZE), - t(osPriorityNormal, 2048) -{ - t.start(callback(&queue, &events::EventQueue::dispatch_forever)); -} - -static LoRaMACTask mac_task; - -#endif //MBED_CONF_RTOS_PRESENT - /*************************************************************************** * ISRs - Handlers * **************************************************************************/ static void handle_tx_done(void) { -#ifdef MBED_CONF_RTOS_PRESENT - mac_task.queue.call(OnRadioTxDone); -#else - OnRadioTxDone(); -#endif + ev_queue->call(OnRadioTxDone); } static void handle_rx_done(uint8_t *payload, uint16_t size, int16_t rssi, - int8_t snr) + int8_t snr) { -#ifdef MBED_CONF_RTOS_PRESENT - mac_task.queue.call(OnRadioRxDone, payload, size, rssi, snr); -#else - OnRadioRxDone(payload, size, rssi, snr); -#endif + ev_queue->call(OnRadioRxDone, payload, size, rssi, snr); } static void handle_rx_error(void) { -#ifdef MBED_CONF_RTOS_PRESENT - mac_task.queue.call(OnRadioRxError); -#else - OnRadioRxError(); -#endif + ev_queue->call(OnRadioRxError); } static void handle_rx_timeout(void) { -#ifdef MBED_CONF_RTOS_PRESENT - mac_task.queue.call(OnRadioRxTimeout); -#else - OnRadioRxTimeout(); -#endif + ev_queue->call(OnRadioRxTimeout); } static void handle_tx_timeout(void) { -#ifdef MBED_CONF_RTOS_PRESENT - mac_task.queue.call(OnRadioTxTimeout); -#else - OnRadioTxTimeout(); -#endif + ev_queue->call(OnRadioTxTimeout); } static void handle_cad_done(bool cad) { -#ifdef MBED_CONF_RTOS_PRESENT - //mac_task.queue.call(OnRadioCadDone, cad); -#else - //TODO Doesn't exist yet - //OnRadioCadDOne(cad); -#endif + //TODO Not implemented yet + //ev_queue->call(OnRadioCadDone, cad); } static void handle_fhss_change_channel(uint8_t cur_channel) { -#ifdef MBED_CONF_RTOS_PRESENT - //mac_task.queue.call(OnRadioFHSSChangeChannel, cur_channel); -#else // TODO Not implemented yet - //OnRadioFHSSChangeChannel(cur_channel); -#endif + //ev_queue->call(OnRadioFHSSChangeChannel, cur_channel); } static void handle_mac_state_check_timer_event(void) { -#ifdef MBED_CONF_RTOS_PRESENT - mac_task.queue.call(OnMacStateCheckTimerEvent); -#else - OnMacStateCheckTimerEvent(); -#endif + ev_queue->call(OnMacStateCheckTimerEvent); } static void handle_next_tx_timer_event(void) @@ -760,47 +700,28 @@ static void handle_next_tx_timer_event(void) if ((LoRaMacState & LORAMAC_TX_RUNNING) == LORAMAC_TX_RUNNING) { return; } -#ifdef MBED_CONF_RTOS_PRESENT - mac_task.queue.call(OnNextTx); -#else - OnNextTx(); -#endif + + ev_queue->call(OnNextTx); } static void handle_delayed_tx_timer_event(void) { -#ifdef MBED_CONF_RTOS_PRESENT - mac_task.queue.call(OnTxDelayedTimerEvent); -#else - OnTxDelayedTimerEvent(); -#endif + ev_queue->call(OnTxDelayedTimerEvent); } static void handle_ack_timeout() { -#ifdef MBED_CONF_RTOS_PRESENT - mac_task.queue.call(OnAckTimeoutTimerEvent); -#else - OnAckTimeoutTimerEvent(); -#endif + ev_queue->call(OnAckTimeoutTimerEvent); } static void handle_rx1_timer_event(void) { -#ifdef MBED_CONF_RTOS_PRESENT - mac_task.queue.call(OnRxWindow1TimerEvent); -#else - OnRxWindow1TimerEvent(); -#endif + ev_queue->call(OnRxWindow1TimerEvent); } static void handle_rx2_timer_event(void) { -#ifdef MBED_CONF_RTOS_PRESENT - mac_task.queue.call(OnRxWindow2TimerEvent); -#else - OnRxWindow2TimerEvent(); -#endif + ev_queue->call(OnRxWindow2TimerEvent); } /*************************************************************************** @@ -2552,17 +2473,23 @@ LoRaMacStatus_t SetTxContinuousWave1( uint16_t timeout, uint32_t frequency, uint return LORAMAC_STATUS_OK; } -LoRaMacStatus_t LoRaMacInitialization( LoRaMacPrimitives_t *primitives, LoRaMacCallback_t *callbacks, LoRaPHY& phy) +LoRaMacStatus_t LoRaMacInitialization(LoRaMacPrimitives_t *primitives, + LoRaMacCallback_t *callbacks, + LoRaPHY *phy, + EventQueue *queue) { GetPhyParams_t getPhy; PhyParam_t phyParam; + //store event queue pointer + ev_queue = queue; + if(!primitives || !callbacks) { return LORAMAC_STATUS_PARAMETER_INVALID; } - lora_phy = &phy; + lora_phy = phy; LoRaMacPrimitives = primitives; LoRaMacCallbacks = callbacks; diff --git a/features/lorawan/lorastack/mac/LoRaMac.h b/features/lorawan/lorastack/mac/LoRaMac.h index 6981b68ae8..bb90661bc7 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.h +++ b/features/lorawan/lorastack/mac/LoRaMac.h @@ -86,14 +86,19 @@ static const uint8_t LoRaMacMaxEirpTable[] = { 8, 10, 12, 13, 14, 16, 18, 20, 21 * \param callbacks [in] - A pointer to the structure defining the LoRaMAC * callback functions. Refer to \ref LoRaMacCallback_t. * - * \param phy [in]- A reference to the selected PHY layer. + * \param phy [in]- A pointer to the selected PHY layer. + * + * \param queue [in]- A pointer to the application provided EventQueue. * * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: * \ref LORAMAC_STATUS_OK * \ref LORAMAC_STATUS_PARAMETER_INVALID * \ref LORAMAC_STATUS_REGION_NOT_SUPPORTED. */ -LoRaMacStatus_t LoRaMacInitialization( LoRaMacPrimitives_t *primitives, LoRaMacCallback_t *callbacks, LoRaPHY& phy); +LoRaMacStatus_t LoRaMacInitialization(LoRaMacPrimitives_t *primitives, + LoRaMacCallback_t *callbacks, + LoRaPHY *phy, + events::EventQueue *queue); /*! * \brief Queries the LoRaMAC whether it is possible to send the next frame with diff --git a/features/lorawan/mbed_lib.json b/features/lorawan/mbed_lib.json index 63143cf56b..e4ddf214fa 100644 --- a/features/lorawan/mbed_lib.json +++ b/features/lorawan/mbed_lib.json @@ -71,8 +71,8 @@ "value": true }, "lbt-on": { - "help": "Enables/disables LBT. NOTE: Disable only for testing. Mandatory in many regions/sub-bands.", - "value": true + "help": "Enables/disables LBT. NOTE: [This feature is not yet integrated].", + "value": false } } } diff --git a/features/lorawan/system/lorawan_data_structures.h b/features/lorawan/system/lorawan_data_structures.h index 437db4006b..a7ac9a8742 100644 --- a/features/lorawan/system/lorawan_data_structures.h +++ b/features/lorawan/system/lorawan_data_structures.h @@ -1638,24 +1638,6 @@ typedef struct sLoRaMacCallback mbed::Callback TxNextPacketTimerEvent; }LoRaMacCallback_t; -/** - * The maximum size of receiver buffer. - */ -#ifdef MBED_CONF_LORA_RX_MESSAGE_BUFFER_MAX_SIZE -#define LORAWAN_RX_MESSAGE_BUFFER_MAX_SIZE MBED_CONF_LORA_RX_MESSAGE_BUFFER_MAX_SIZE -#else -#define LORAWAN_RX_MESSAGE_BUFFER_MAX_SIZE 5 -#endif - -/** - * The maximum size of transmission buffer. - */ -#ifdef MBED_CONF_LORA_TX_MESSAGE_BUFFER_MAX_SIZE -#define LORAWAN_TX_MESSAGE_BUFFER_MAX_SIZE MBED_CONF_LORA_TX_MESSAGE_BUFFER_MAX_SIZE -#else -#define LORAWAN_TX_MESSAGE_BUFFER_MAX_SIZE 5 -#endif - /** * The AES encryption/decryption cipher application session key. */ diff --git a/features/netsocket/LoRaWANBase.h b/features/netsocket/LoRaWANBase.h index b84c301215..f8826e09a2 100644 --- a/features/netsocket/LoRaWANBase.h +++ b/features/netsocket/LoRaWANBase.h @@ -20,6 +20,7 @@ #define LORAWAN_BASE_H_ #include "lorawan/system/lorawan_data_structures.h" +#include "events/EventQueue.h" class LoRaWANBase { @@ -28,10 +29,12 @@ public: * * You must call this before using the LoRa stack. * + * @param queue A pointer to EventQueue provided by the application. + * * @return LORA_MAC_STATUS_OK on success, a negative error code on * failure. */ - virtual lora_mac_status_t initialize() = 0; + virtual lora_mac_status_t initialize(events::EventQueue *queue) = 0; /** Connect OTAA or ABP by setup. *