From 555d945a4286434ee30367ab68bec71fdbb2686f Mon Sep 17 00:00:00 2001 From: Hasnain Virk Date: Tue, 15 May 2018 14:59:55 +0300 Subject: [PATCH] Adding acquisition of TX Meta-data An API is added to fetch any meta-data available after a succesful transmission. The stack will make the meta data available after the TX interrupt is processed. User can get the tx meta data after receiving TX_DONE event. --- features/lorawan/LoRaWANBase.h | 16 ++++++++ features/lorawan/LoRaWANInterface.cpp | 6 +++ features/lorawan/LoRaWANInterface.h | 16 ++++++++ features/lorawan/LoRaWANStack.cpp | 26 +++++++++++++ features/lorawan/LoRaWANStack.h | 15 +++++++ features/lorawan/lorawan_types.h | 56 +++++++++++++++++++++++++++ 6 files changed, 135 insertions(+) diff --git a/features/lorawan/LoRaWANBase.h b/features/lorawan/LoRaWANBase.h index ce2f47ef09..729bc923cf 100644 --- a/features/lorawan/LoRaWANBase.h +++ b/features/lorawan/LoRaWANBase.h @@ -337,6 +337,22 @@ public: * or other negative error code if request failed. */ virtual lorawan_status_t set_device_class(device_class_t device_class) = 0; + + /** Get hold of TX meta-data + * + * Use this method to acquire any TX meta-data related to previous + * transmission. + * TX meta-data is only available right after the transmission is completed. + * In other words, you can check for TX meta-data right after receiving the + * TX_DONE event. + * + * @param metadata the inbound structure that will be filled if the meta-data + * is available. + * + * @return LORAWAN_STATUS_OK if the meta-data is available, otherwise + * LORAWAN_STATUS_METADATA_NOT_AVAILABLE is returned. + */ + virtual lorawan_status_t get_tx_metadata(lorawan_tx_metadata& metadata) = 0; }; #endif /* LORAWAN_BASE_H_ */ diff --git a/features/lorawan/LoRaWANInterface.cpp b/features/lorawan/LoRaWANInterface.cpp index 3ef705e0c8..b58be59e50 100644 --- a/features/lorawan/LoRaWANInterface.cpp +++ b/features/lorawan/LoRaWANInterface.cpp @@ -122,6 +122,12 @@ int16_t LoRaWANInterface::send(uint8_t port, const uint8_t* data, uint16_t lengt return _lw_stack.handle_tx(port, data, length, flags); } +lorawan_status_t LoRaWANInterface::get_tx_metadata(lorawan_tx_metadata& metadata) +{ + Lock lock(*this); + return _lw_stack.acquire_tx_metadata(metadata); +} + int16_t LoRaWANInterface::receive(uint8_t port, uint8_t* data, uint16_t length, int flags) { Lock lock(*this); diff --git a/features/lorawan/LoRaWANInterface.h b/features/lorawan/LoRaWANInterface.h index 1f5f20cdf5..874c7faa26 100644 --- a/features/lorawan/LoRaWANInterface.h +++ b/features/lorawan/LoRaWANInterface.h @@ -436,6 +436,22 @@ public: */ virtual lorawan_status_t set_device_class(const device_class_t device_class); + /** Get hold of TX meta-data + * + * Use this method to acquire any TX meta-data related to previous + * transmission. + * TX meta-data is only available right after the transmission is completed. + * In other words, you can check for TX meta-data right after receiving the + * TX_DONE event. + * + * @param metadata the inbound structure that will be filled if the meta-data + * is available. + * + * @return LORAWAN_STATUS_OK if the meta-data is available, otherwise + * LORAWAN_STATUS_METADATA_NOT_AVAILABLE is returned. + */ + virtual lorawan_status_t get_tx_metadata(lorawan_tx_metadata& metadata); + void lock(void) { _lw_stack.lock(); } void unlock(void) { _lw_stack.unlock(); } diff --git a/features/lorawan/LoRaWANStack.cpp b/features/lorawan/LoRaWANStack.cpp index 2ac948d522..db63d196da 100644 --- a/features/lorawan/LoRaWANStack.cpp +++ b/features/lorawan/LoRaWANStack.cpp @@ -73,6 +73,7 @@ LoRaWANStack::LoRaWANStack() _lw_session(), _tx_msg(), _rx_msg(), + _tx_metadata(), _num_retry(1), _ctrl_flags(IDLE_FLAG), _app_port(INVALID_PORT), @@ -81,6 +82,8 @@ LoRaWANStack::LoRaWANStack() _ready_for_rx(true), _queue(NULL) { + _tx_metadata.stale = true; + #ifdef MBED_CONF_LORA_APP_PORT if (is_port_valid(MBED_CONF_LORA_APP_PORT)) { _app_port = MBED_CONF_LORA_APP_PORT; @@ -419,6 +422,17 @@ lorawan_status_t LoRaWANStack::set_device_class(const device_class_t& device_cla return LORAWAN_STATUS_OK; } +lorawan_status_t LoRaWANStack::acquire_tx_metadata(lorawan_tx_metadata& tx_metadata) +{ + if (!_tx_metadata.stale) { + tx_metadata = _tx_metadata; + _tx_metadata.stale = true; + return LORAWAN_STATUS_OK; + } + + return LORAWAN_STATUS_METADATA_NOT_AVAILABLE; +} + /***************************************************************************** * Interrupt handlers * ****************************************************************************/ @@ -488,6 +502,8 @@ void LoRaWANStack::process_transmission(void) _loramac.on_radio_tx_done(); tr_debug("Transmission completed"); + make_tx_metadata_available(); + if (_device_current_state == DEVICE_STATE_JOINING) { _device_current_state = DEVICE_STATE_AWAITING_JOIN_ACCEPT; } @@ -609,6 +625,16 @@ void LoRaWANStack::process_reception_timeout(bool is_timeout) /***************************************************************************** * Private methods * ****************************************************************************/ +void LoRaWANStack::make_tx_metadata_available(void) +{ + _tx_metadata.stale = false; + _tx_metadata.channel = _loramac.get_mcps_confirmation()->channel; + _tx_metadata.data_rate = _loramac.get_mcps_confirmation()->data_rate; + _tx_metadata.tx_power = _loramac.get_mcps_confirmation()->tx_power; + _tx_metadata.tx_toa = _loramac.get_mcps_confirmation()->tx_toa; + _tx_metadata.nb_retries = _loramac.get_mcps_confirmation()->nb_retries; +} + bool LoRaWANStack::is_port_valid(const uint8_t port, bool allow_port_0) { //Application should not use reserved and illegal port numbers. diff --git a/features/lorawan/LoRaWANStack.h b/features/lorawan/LoRaWANStack.h index ee3cd934aa..3c0d2365cc 100644 --- a/features/lorawan/LoRaWANStack.h +++ b/features/lorawan/LoRaWANStack.h @@ -379,6 +379,18 @@ public: */ lorawan_status_t set_device_class(const device_class_t& device_class); + /** Acquire TX meta-data + * + * Upon successful transmission, TX meta-data will be made available + * + * @param metadata A reference to the inbound structure which will be + * filled with any TX meta-data if available. + * + * @return LORAWAN_STATUS_OK if successful, + * LORAWAN_STATUS_METADATA_NOT_AVAILABLE otherwise + */ + lorawan_status_t acquire_tx_metadata(lorawan_tx_metadata& metadata); + void lock(void) { _loramac.lock(); } void unlock(void) { _loramac.unlock(); } @@ -473,6 +485,8 @@ private: int convert_to_msg_flag(const mcps_type_t type); + void make_tx_metadata_available(void); + private: LoRaMac _loramac; radio_events_t radio_events; @@ -481,6 +495,7 @@ private: lorawan_session_t _lw_session; loramac_tx_message_t _tx_msg; loramac_rx_message_t _rx_msg; + lorawan_tx_metadata _tx_metadata; uint8_t _num_retry; uint32_t _ctrl_flags; uint8_t _app_port; diff --git a/features/lorawan/lorawan_types.h b/features/lorawan/lorawan_types.h index e3e174559b..e5ec38048b 100644 --- a/features/lorawan/lorawan_types.h +++ b/features/lorawan/lorawan_types.h @@ -101,6 +101,7 @@ typedef enum lorawan_status { LORAWAN_STATUS_DUTYCYCLE_RESTRICTED = -1020, LORAWAN_STATUS_NO_CHANNEL_FOUND = -1021, LORAWAN_STATUS_NO_FREE_CHANNEL_FOUND = -1022, + LORAWAN_STATUS_METADATA_NOT_AVAILABLE = -1023 } lorawan_status_t; /** The lorawan_connect_otaa structure. @@ -344,4 +345,59 @@ typedef struct lora_channelplan { loramac_channel_t *channels; } lorawan_channelplan_t; +/** + * Meta-data collection for a transmission + */ +typedef struct { + /** + * A boolean to mark if the meta data is stale + */ + bool stale; + /** + * The uplink channel used for transmission. + */ + uint32_t channel; + /** + * The uplink datarate. + */ + uint8_t data_rate; + /** + * The transmission power. + */ + int8_t tx_power; + /** + * Provides the number of retransmissions. + */ + uint8_t nb_retries; + /** + * The transmission time on air of the frame. + */ + uint32_t tx_toa; +} lorawan_tx_metadata; + + * Meta-data collection for the received packet + */ +typedef struct { + /** + * A boolean to mark if the meta data is stale + */ + bool stale; + /** + * Data rate of reception + */ + uint8_t rx_datarate; + /** + * Frame pending status. + */ + uint8_t fpending_status; + /** + * The RSSI for the received packet. + */ + int16_t rssi; + /** + * The SNR for the received packet. + */ + uint8_t snr; +} lorawan_rx_metadata; + #endif /* MBED_LORAWAN_TYPES_H_ */