diff --git a/features/lorawan/LoRaWANBase.h b/features/lorawan/LoRaWANBase.h index 729bc923cf..d4a085c075 100644 --- a/features/lorawan/LoRaWANBase.h +++ b/features/lorawan/LoRaWANBase.h @@ -353,6 +353,22 @@ public: * LORAWAN_STATUS_METADATA_NOT_AVAILABLE is returned. */ virtual lorawan_status_t get_tx_metadata(lorawan_tx_metadata& metadata) = 0; + + /** Get hold of RX meta-data + * + * Use this method to acquire any RX meta-data related to current + * reception. + * RX meta-data is only available right after the reception is completed. + * In other words, you can check for RX meta-data right after receiving the + * RX_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_rx_metadata(lorawan_rx_metadata& metadata) = 0; }; #endif /* LORAWAN_BASE_H_ */ diff --git a/features/lorawan/LoRaWANInterface.cpp b/features/lorawan/LoRaWANInterface.cpp index b58be59e50..1beb6139ab 100644 --- a/features/lorawan/LoRaWANInterface.cpp +++ b/features/lorawan/LoRaWANInterface.cpp @@ -128,6 +128,12 @@ lorawan_status_t LoRaWANInterface::get_tx_metadata(lorawan_tx_metadata& metadata return _lw_stack.acquire_tx_metadata(metadata); } +lorawan_status_t LoRaWANInterface::get_rx_metadata(lorawan_rx_metadata& metadata) +{ + Lock lock(*this); + return _lw_stack.acquire_rx_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 874c7faa26..8d5a46d8e1 100644 --- a/features/lorawan/LoRaWANInterface.h +++ b/features/lorawan/LoRaWANInterface.h @@ -452,6 +452,22 @@ public: */ virtual lorawan_status_t get_tx_metadata(lorawan_tx_metadata& metadata); + /** Get hold of RX meta-data + * + * Use this method to acquire any RX meta-data related to current + * reception. + * RX meta-data is only available right after the reception is completed. + * In other words, you can check for RX meta-data right after receiving the + * RX_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_rx_metadata(lorawan_rx_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 db63d196da..777d1e7289 100644 --- a/features/lorawan/LoRaWANStack.cpp +++ b/features/lorawan/LoRaWANStack.cpp @@ -74,6 +74,7 @@ LoRaWANStack::LoRaWANStack() _tx_msg(), _rx_msg(), _tx_metadata(), + _rx_metadata(), _num_retry(1), _ctrl_flags(IDLE_FLAG), _app_port(INVALID_PORT), @@ -83,6 +84,7 @@ LoRaWANStack::LoRaWANStack() _queue(NULL) { _tx_metadata.stale = true; + _rx_metadata.stale = true; #ifdef MBED_CONF_LORA_APP_PORT if (is_port_valid(MBED_CONF_LORA_APP_PORT)) { @@ -433,6 +435,17 @@ lorawan_status_t LoRaWANStack::acquire_tx_metadata(lorawan_tx_metadata& tx_meta return LORAWAN_STATUS_METADATA_NOT_AVAILABLE; } +lorawan_status_t LoRaWANStack::acquire_rx_metadata(lorawan_rx_metadata& metadata) +{ + if (!_rx_metadata.stale) { + metadata = _rx_metadata; + _rx_metadata.stale = true; + return LORAWAN_STATUS_OK; + } + + return LORAWAN_STATUS_METADATA_NOT_AVAILABLE; +} + /***************************************************************************** * Interrupt handlers * ****************************************************************************/ @@ -539,6 +552,8 @@ void LoRaWANStack::process_reception(const uint8_t* const payload, uint16_t size _loramac.on_radio_rx_done(payload, size, rssi, snr); + make_rx_metadata_available(); + if (_loramac.get_mlme_confirmation()->pending) { _loramac.post_process_mlme_request(); mlme_confirm_handler(); @@ -635,6 +650,15 @@ void LoRaWANStack::make_tx_metadata_available(void) _tx_metadata.nb_retries = _loramac.get_mcps_confirmation()->nb_retries; } +void LoRaWANStack::make_rx_metadata_available(void) +{ + _rx_metadata.stale = false; + _rx_metadata.fpending_status = _loramac.get_mcps_indication()->fpending_status; + _rx_metadata.rx_datarate = _loramac.get_mcps_indication()->rx_datarate; + _rx_metadata.rssi = _loramac.get_mcps_indication()->rssi; + _rx_metadata.snr = _loramac.get_mcps_indication()->snr; +} + 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 3c0d2365cc..a87e75d7dd 100644 --- a/features/lorawan/LoRaWANStack.h +++ b/features/lorawan/LoRaWANStack.h @@ -391,6 +391,18 @@ public: */ lorawan_status_t acquire_tx_metadata(lorawan_tx_metadata& metadata); + /** Acquire RX meta-data + * + * Upon successful reception, RX meta-data will be made available + * + * @param metadata A reference to the inbound structure which will be + * filled with any RX meta-data if available. + * + * @return LORAWAN_STATUS_OK if successful, + * LORAWAN_STATUS_METADATA_NOT_AVAILABLE otherwise + */ + lorawan_status_t acquire_rx_metadata(lorawan_rx_metadata& metadata); + void lock(void) { _loramac.lock(); } void unlock(void) { _loramac.unlock(); } @@ -486,6 +498,7 @@ private: int convert_to_msg_flag(const mcps_type_t type); void make_tx_metadata_available(void); + void make_rx_metadata_available(void); private: LoRaMac _loramac; @@ -496,6 +509,7 @@ private: loramac_tx_message_t _tx_msg; loramac_rx_message_t _rx_msg; lorawan_tx_metadata _tx_metadata; + lorawan_rx_metadata _rx_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 e5ec38048b..d9b3c3a567 100644 --- a/features/lorawan/lorawan_types.h +++ b/features/lorawan/lorawan_types.h @@ -375,6 +375,7 @@ typedef struct { uint32_t tx_toa; } lorawan_tx_metadata; +/** * Meta-data collection for the received packet */ typedef struct {