diff --git a/features/lorawan/LoRaWANStack.cpp b/features/lorawan/LoRaWANStack.cpp index c27b0df5b1..d60fa0b9d4 100644 --- a/features/lorawan/LoRaWANStack.cpp +++ b/features/lorawan/LoRaWANStack.cpp @@ -795,6 +795,8 @@ void LoRaWANStack::make_rx_metadata_available(void) _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; + _rx_metadata.channel = _loramac.get_mcps_indication()->channel; + _rx_metadata.rx_toa = _loramac.get_mcps_indication()->rx_toa; } bool LoRaWANStack::is_port_valid(const uint8_t port, bool allow_port_0) diff --git a/features/lorawan/lorastack/mac/LoRaMac.cpp b/features/lorawan/lorastack/mac/LoRaMac.cpp index 3c1e0f139c..b94ebe3596 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.cpp +++ b/features/lorawan/lorastack/mac/LoRaMac.cpp @@ -626,6 +626,17 @@ void LoRaMac::handle_data_frame(const uint8_t *const payload, if (_mcps_confirmation.ack_received) { _lora_time.stop(_params.timers.ack_timeout_timer); } + + channel_params_t *list = _lora_phy->get_phy_channels(); + _mcps_indication.channel = list[_params.channel].frequency; + + if (get_current_slot() == RX_SLOT_WIN_1) { + _mcps_indication.rx_toa = _lora_phy->get_rx_time_on_air(_params.rx_window1_config.modem_type, + _mcps_indication.buffer_size); + } else { + _mcps_indication.rx_toa = _lora_phy->get_rx_time_on_air(_params.rx_window2_config.modem_type, + _mcps_indication.buffer_size); + } } void LoRaMac::set_batterylevel_callback(mbed::Callback battery_level) @@ -889,7 +900,13 @@ void LoRaMac::open_rx1_window(void) _lora_time.stop(_params.timers.rx_window1_timer); _params.rx_slot = RX_SLOT_WIN_1; + channel_params_t *active_channel_list = _lora_phy->get_phy_channels(); _params.rx_window1_config.channel = _params.channel; + _params.rx_window1_config.frequency = active_channel_list[_params.channel].frequency; + // Apply the alternative RX 1 window frequency, if it is available + if (active_channel_list[_params.channel].rx1_frequency != 0) { + _params.rx_window1_config.frequency = active_channel_list[_params.channel].rx1_frequency; + } _params.rx_window1_config.dr_offset = _params.sys_params.rx1_dr_offset; _params.rx_window1_config.dl_dwell_time = _params.sys_params.downlink_dwell_time; _params.rx_window1_config.is_repeater_supported = _params.is_repeater_supported; diff --git a/features/lorawan/lorastack/phy/LoRaPHY.cpp b/features/lorawan/lorastack/phy/LoRaPHY.cpp index c13f07d18a..3161e6574a 100644 --- a/features/lorawan/lorastack/phy/LoRaPHY.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHY.cpp @@ -855,22 +855,22 @@ void LoRaPHY::compute_rx_win_params(int8_t datarate, uint8_t min_rx_symbols, rx_conf_params->datarate); } +uint32_t LoRaPHY::get_rx_time_on_air(uint8_t modem, uint16_t pkt_len) +{ + uint32_t toa = 0; + + _radio->lock(); + toa = _radio->time_on_air((radio_modems_t) modem, pkt_len); + _radio->unlock(); + + return toa; +} + bool LoRaPHY::rx_config(rx_config_params_t *rx_conf) { - radio_modems_t modem; uint8_t dr = rx_conf->datarate; uint8_t max_payload = 0; uint8_t phy_dr = 0; - uint32_t frequency = rx_conf->frequency; - - if (rx_conf->rx_slot == RX_SLOT_WIN_1) { - // Apply window 1 frequency - frequency = phy_params.channels.channel_list[rx_conf->channel].frequency; - // Apply the alternative RX 1 window frequency, if it is available - if (phy_params.channels.channel_list[rx_conf->channel].rx1_frequency != 0) { - frequency = phy_params.channels.channel_list[rx_conf->channel].rx1_frequency; - } - } // Read the physical datarate from the datarates table uint8_t *datarate_table = (uint8_t *) phy_params.datarates.table; @@ -881,17 +881,17 @@ bool LoRaPHY::rx_config(rx_config_params_t *rx_conf) _radio->lock(); - _radio->set_channel(frequency); + _radio->set_channel(rx_conf->frequency); // Radio configuration if (dr == DR_7 && phy_params.fsk_supported) { - modem = MODEM_FSK; - _radio->set_rx_config(modem, 50000, phy_dr * 1000, 0, 83333, MAX_PREAMBLE_LENGTH, + rx_conf->modem_type = MODEM_FSK; + _radio->set_rx_config((radio_modems_t) rx_conf->modem_type, 50000, phy_dr * 1000, 0, 83333, MAX_PREAMBLE_LENGTH, rx_conf->window_timeout, false, 0, true, 0, 0, false, rx_conf->is_rx_continuous); } else { - modem = MODEM_LORA; - _radio->set_rx_config(modem, rx_conf->bandwidth, phy_dr, 1, 0, + rx_conf->modem_type = MODEM_LORA; + _radio->set_rx_config((radio_modems_t) rx_conf->modem_type, rx_conf->bandwidth, phy_dr, 1, 0, MAX_PREAMBLE_LENGTH, rx_conf->window_timeout, false, 0, false, 0, 0, true, rx_conf->is_rx_continuous); @@ -903,7 +903,7 @@ bool LoRaPHY::rx_config(rx_config_params_t *rx_conf) max_payload = payload_table[dr]; } - _radio->set_max_payload_length(modem, max_payload + LORA_MAC_FRMPAYLOAD_OVERHEAD); + _radio->set_max_payload_length((radio_modems_t) rx_conf->modem_type, max_payload + LORA_MAC_FRMPAYLOAD_OVERHEAD); _radio->unlock(); diff --git a/features/lorawan/lorastack/phy/LoRaPHY.h b/features/lorawan/lorastack/phy/LoRaPHY.h index 71b8ba094c..786d0b698f 100644 --- a/features/lorawan/lorastack/phy/LoRaPHY.h +++ b/features/lorawan/lorastack/phy/LoRaPHY.h @@ -520,6 +520,12 @@ public: */ bool is_custom_channel_plan_supported(); + /** + * @brief get_rx_time_on_air(...) calculates the time the received spent on air + * @return time spent on air in milliseconds + */ + uint32_t get_rx_time_on_air(uint8_t modem, uint16_t pkt_len); + public: //Verifiers /** diff --git a/features/lorawan/lorawan_types.h b/features/lorawan/lorawan_types.h index fd0a6e791c..324a5bc428 100644 --- a/features/lorawan/lorawan_types.h +++ b/features/lorawan/lorawan_types.h @@ -666,6 +666,14 @@ typedef struct { * A boolean to mark if the meta data is stale */ bool stale; + /** + * Frequency for the downlink channel + */ + uint32_t channel; + /** + * Time spent on air by the RX frame + */ + uint32_t rx_toa; } lorawan_rx_metadata; #endif /* MBED_LORAWAN_TYPES_H_ */ diff --git a/features/lorawan/system/lorawan_data_structures.h b/features/lorawan/system/lorawan_data_structures.h index e0aeb14476..7ce8cb33cf 100644 --- a/features/lorawan/system/lorawan_data_structures.h +++ b/features/lorawan/system/lorawan_data_structures.h @@ -681,6 +681,14 @@ typedef struct { * The downlink counter value for the received frame. */ uint32_t dl_frame_counter; + /*! + * The downlink channel + */ + uint32_t channel; + /*! + * The time on air of the received frame. + */ + lorawan_time_t rx_toa; } loramac_mcps_indication_t; /*! @@ -986,6 +994,10 @@ typedef struct lorawan_session { * The parameter structure for the function for regional rx configuration. */ typedef struct { + /*! + * Type of modulation used (LoRa or FSK) + */ + uint8_t modem_type; /*! * The RX channel. */