diff --git a/features/lorawan/LoRaWANInterface.h b/features/lorawan/LoRaWANInterface.h index f8d35b425f..3a0712ed19 100644 --- a/features/lorawan/LoRaWANInterface.h +++ b/features/lorawan/LoRaWANInterface.h @@ -44,7 +44,7 @@ public: * * @return 0 on success, a negative error code on failure. */ - virtual lorawan_status_t initialize(events::EventQueue *ev_queue) ; + virtual lorawan_status_t initialize(events::EventQueue *ev_queue); /** Connect OTAA or ABP using Mbed-OS config system * diff --git a/features/lorawan/lorastack/mac/LoRaMac.cpp b/features/lorawan/lorastack/mac/LoRaMac.cpp index 8a4403e731..efad84ddcd 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.cpp +++ b/features/lorawan/lorastack/mac/LoRaMac.cpp @@ -1547,51 +1547,51 @@ lorawan_status_t LoRaMac::send_frame_on_channel(uint8_t channel) return LORAWAN_STATUS_OK; } -lorawan_status_t LoRaMac::set_tx_continuous_wave(uint16_t timeout) -{ - cw_mode_params_t continuous_wave; +//lorawan_status_t LoRaMac::set_tx_continuous_wave(uint16_t timeout) +//{ +// cw_mode_params_t continuous_wave; - continuous_wave.channel = _params.channel; - continuous_wave.datarate = _params.sys_params.channel_data_rate; - continuous_wave.tx_power = _params.sys_params.channel_tx_power; - continuous_wave.max_eirp = _params.sys_params.max_eirp; - continuous_wave.antenna_gain = _params.sys_params.antenna_gain; - continuous_wave.timeout = timeout; +// continuous_wave.channel = _params.channel; +// continuous_wave.datarate = _params.sys_params.channel_data_rate; +// continuous_wave.tx_power = _params.sys_params.channel_tx_power; +// continuous_wave.max_eirp = _params.sys_params.max_eirp; +// continuous_wave.antenna_gain = _params.sys_params.antenna_gain; +// continuous_wave.timeout = timeout; - lora_phy->set_tx_cont_mode(&continuous_wave); +// lora_phy->set_tx_cont_mode(&continuous_wave); - // Starts the MAC layer status check timer - _lora_time.start(_params.timers.mac_state_check_timer, - MAC_STATE_CHECK_TIMEOUT); +// // Starts the MAC layer status check timer +// _lora_time.start(_params.timers.mac_state_check_timer, +// MAC_STATE_CHECK_TIMEOUT); - _params.mac_state |= LORAMAC_TX_RUNNING; +// _params.mac_state |= LORAMAC_TX_RUNNING; - return LORAWAN_STATUS_OK; -} +// return LORAWAN_STATUS_OK; +//} -lorawan_status_t LoRaMac::set_tx_continuous_wave1(uint16_t timeout, - uint32_t frequency, - uint8_t power) -{ - cw_mode_params_t continuous_wave; +//lorawan_status_t LoRaMac::set_tx_continuous_wave1(uint16_t timeout, +// uint32_t frequency, +// uint8_t power) +//{ +// cw_mode_params_t continuous_wave; - continuous_wave.channel = 0; - continuous_wave.datarate = 0; - continuous_wave.tx_power = power; - continuous_wave.max_eirp = 0; - continuous_wave.antenna_gain = 0; - continuous_wave.timeout = timeout; +// continuous_wave.channel = 0; +// continuous_wave.datarate = 0; +// continuous_wave.tx_power = power; +// continuous_wave.max_eirp = 0; +// continuous_wave.antenna_gain = 0; +// continuous_wave.timeout = timeout; - lora_phy->set_tx_cont_mode(&continuous_wave); +// lora_phy->set_tx_cont_mode(&continuous_wave); - // Starts the MAC layer status check timer - _lora_time.start(_params.timers.mac_state_check_timer, - MAC_STATE_CHECK_TIMEOUT); +// // Starts the MAC layer status check timer +// _lora_time.start(_params.timers.mac_state_check_timer, +// MAC_STATE_CHECK_TIMEOUT); - _params.mac_state |= LORAMAC_TX_RUNNING; +// _params.mac_state |= LORAMAC_TX_RUNNING; - return LORAWAN_STATUS_OK; -} +// return LORAWAN_STATUS_OK; +//} lorawan_status_t LoRaMac::initialize(loramac_primitives_t *primitives, LoRaPHY *phy, EventQueue *queue) @@ -1606,13 +1606,13 @@ lorawan_status_t LoRaMac::initialize(loramac_primitives_t *primitives, lora_phy = phy; // Activate MLME subsystem - mlme.activate_mlme_subsystem(this, lora_phy); + mlme.activate_mlme_subsystem(lora_phy); // Activate MCPS subsystem mcps.activate_mcps_subsystem(this, lora_phy); // Activate MIB subsystem - mib.activate_mib_subsystem(this, lora_phy); + mib.activate_mib_subsystem(lora_phy); // Activate channel planning subsystem channel_plan.activate_channelplan_subsystem(lora_phy); @@ -1878,10 +1878,74 @@ lorawan_status_t LoRaMac::multicast_channel_unlink( lorawan_status_t LoRaMac::mlme_request( loramac_mlme_req_t *mlmeRequest ) { - lorawan_status_t status = mlme.set_request(mlmeRequest, &_params); + if (LORAMAC_IDLE != _params.mac_state) { + return LORAWAN_STATUS_BUSY; + } + if (MLME_JOIN == mlmeRequest->type) { + reset_mac_parameters(); + } + + mlme.reset_confirmation(); + + mlme.get_confirmation().req_type = mlmeRequest->type; + _params.flags.bits.mlme_req = 1; + + lorawan_status_t status = LORAWAN_STATUS_SERVICE_UNKNOWN; + if (MLME_LINK_CHECK == mlmeRequest->type) { status = mac_commands.add_mac_command(MOTE_MAC_LINK_CHECK_REQ, 0, 0); + } else if (MLME_JOIN == mlmeRequest->type) { + if ((_params.mac_state & LORAMAC_TX_DELAYED) == LORAMAC_TX_DELAYED) { + return LORAWAN_STATUS_BUSY; + } + + if ((mlmeRequest->req.join.dev_eui == NULL) + || (mlmeRequest->req.join.app_eui == NULL) + || (mlmeRequest->req.join.app_key == NULL) + || (mlmeRequest->req.join.nb_trials == 0)) { + return LORAWAN_STATUS_PARAMETER_INVALID; + } + _params.keys.dev_eui = mlmeRequest->req.join.dev_eui; + _params.keys.app_eui = mlmeRequest->req.join.app_eui; + _params.keys.app_key = mlmeRequest->req.join.app_key; + _params.max_join_request_trials = mlmeRequest->req.join.nb_trials; + + if (!lora_phy->verify_nb_join_trials(mlmeRequest->req.join.nb_trials)) { + // Value not supported, get default + _params.max_join_request_trials = lora_phy->get_nb_join_trials(true); + } + // Reset variable JoinRequestTrials + _params.join_request_trial_counter = 0; + _params.sys_params.channel_data_rate = + lora_phy->get_alternate_DR(_params.join_request_trial_counter + 1); + + loramac_mhdr_t machdr; + machdr.value = 0; + machdr.bits.mtype = FRAME_TYPE_JOIN_REQ; + status = send(&machdr, 0, NULL, 0); + } else if (MLME_TXCW == mlmeRequest->type) { + mlme.set_tx_continuous_wave(_params.channel, _params.sys_params.channel_data_rate, _params.sys_params.channel_tx_power, + _params.sys_params.max_eirp, _params.sys_params.antenna_gain, mlmeRequest->req.cw_tx_mode.timeout); + _lora_time.start(_params.timers.mac_state_check_timer, + MAC_STATE_CHECK_TIMEOUT); + + _params.mac_state |= LORAMAC_TX_RUNNING; + status = LORAWAN_STATUS_OK; + } else if (MLME_TXCW_1 == mlmeRequest->type) { + mlme.set_tx_continuous_wave(0, 0, mlmeRequest->req.cw_tx_mode.power, 0, 0, mlmeRequest->req.cw_tx_mode.timeout); + _lora_time.start(_params.timers.mac_state_check_timer, + MAC_STATE_CHECK_TIMEOUT); + + _params.mac_state |= LORAMAC_TX_RUNNING; + status = LORAWAN_STATUS_OK; } + + if (status != LORAWAN_STATUS_OK) { + _params.is_node_ack_requested = false; + _params.flags.bits.mlme_req = 0; + } + + return status; } @@ -1903,7 +1967,12 @@ lorawan_status_t LoRaMac::mib_get_request_confirm( loramac_mib_req_confirm_t *mi lorawan_status_t LoRaMac::mib_set_request_confirm( loramac_mib_req_confirm_t *mibSet ) { - return mib.set_request(mibSet, &_params); + lorawan_status_t status = mib.set_request(mibSet, &_params); + if (LORAWAN_STATUS_OK == status && CLASS_C == _params.dev_class && (MIB_DEVICE_CLASS == mibSet->type || + (MIB_RX2_CHANNEL == mibSet->type && _params.is_nwk_joined))) { + open_continuous_rx2_window(); + } + return status; } radio_events_t *LoRaMac::get_phy_event_handlers() diff --git a/features/lorawan/lorastack/mac/LoRaMacMib.cpp b/features/lorawan/lorastack/mac/LoRaMacMib.cpp index c32fac9a54..b80ddcf2d4 100644 --- a/features/lorawan/lorastack/mac/LoRaMacMib.cpp +++ b/features/lorawan/lorastack/mac/LoRaMacMib.cpp @@ -27,7 +27,7 @@ SPDX-License-Identifier: BSD-3-Clause #include "lorastack/mac/LoRaMacMib.h" LoRaMacMib::LoRaMacMib() -: _lora_mac(NULL), _lora_phy(NULL) +: _lora_phy(NULL) { } @@ -35,16 +35,15 @@ LoRaMacMib::~LoRaMacMib() { } -void LoRaMacMib::activate_mib_subsystem(LoRaMac *mac, LoRaPHY *phy) +void LoRaMacMib::activate_mib_subsystem(LoRaPHY *phy) { - _lora_mac = mac; _lora_phy = phy; } lorawan_status_t LoRaMacMib::set_request(loramac_mib_req_confirm_t *mibSet, loramac_protocol_params *params) { - if (mibSet == NULL || _lora_phy == NULL || _lora_mac == NULL) { + if (mibSet == NULL || _lora_phy == NULL) { return LORAWAN_STATUS_PARAMETER_INVALID; } @@ -73,7 +72,6 @@ lorawan_status_t LoRaMacMib::set_request(loramac_mib_req_confirm_t *mibSet, params->sys_params.min_rx_symb, params->sys_params.max_sys_rx_error, ¶ms->rx_window2_config); - _lora_mac->open_continuous_rx2_window(); break; } } @@ -139,8 +137,6 @@ lorawan_status_t LoRaMacMib::set_request(loramac_mib_req_confirm_t *mibSet, params->sys_params.min_rx_symb, params->sys_params.max_sys_rx_error, ¶ms->rx_window2_config); - - _lora_mac->open_continuous_rx2_window(); } } else { status = LORAWAN_STATUS_PARAMETER_INVALID; diff --git a/features/lorawan/lorastack/mac/LoRaMacMib.h b/features/lorawan/lorastack/mac/LoRaMacMib.h index 70cbaecfeb..5816bbfe3a 100644 --- a/features/lorawan/lorastack/mac/LoRaMacMib.h +++ b/features/lorawan/lorastack/mac/LoRaMacMib.h @@ -56,7 +56,7 @@ public: * @param mac pointer to MAC layer * @param phy pointer to PHY layer */ - void activate_mib_subsystem(LoRaMac *mac, LoRaPHY *phy); + void activate_mib_subsystem(LoRaPHY *phy); /** Sets up a MIB Request * @@ -90,9 +90,8 @@ public: private: /** - * Pointers to MAC and PHY handles + * Pointer PHY handle */ - LoRaMac *_lora_mac; LoRaPHY *_lora_phy; }; diff --git a/features/lorawan/lorastack/mac/LoRaMacMlme.cpp b/features/lorawan/lorastack/mac/LoRaMacMlme.cpp index 36ea4b23fa..9153fa0d54 100644 --- a/features/lorawan/lorastack/mac/LoRaMacMlme.cpp +++ b/features/lorawan/lorastack/mac/LoRaMacMlme.cpp @@ -27,7 +27,7 @@ SPDX-License-Identifier: BSD-3-Clause #include "lorastack/mac/LoRaMacMlme.h" LoRaMacMlme::LoRaMacMlme() -: _lora_mac(NULL), _lora_phy(NULL) +: _lora_phy(NULL) { } @@ -35,6 +35,13 @@ LoRaMacMlme::~LoRaMacMlme() { } +void LoRaMacMlme::reset_confirmation() +{ + memset((uint8_t*) &confirmation, 0, sizeof(confirmation)); + + confirmation.status = LORAMAC_EVENT_INFO_STATUS_ERROR; +} + loramac_mlme_confirm_t& LoRaMacMlme::get_confirmation() { return confirmation; @@ -45,105 +52,22 @@ loramac_mlme_indication_t& LoRaMacMlme::get_indication() return indication; } -void LoRaMacMlme::activate_mlme_subsystem(LoRaMac *mac, LoRaPHY *phy) +void LoRaMacMlme::activate_mlme_subsystem(LoRaPHY *phy) { - _lora_mac = mac; _lora_phy = phy; } -lorawan_status_t LoRaMacMlme::set_request(loramac_mlme_req_t *request, - loramac_protocol_params *params) +void LoRaMacMlme::set_tx_continuous_wave(uint8_t channel, int8_t datarate, int8_t tx_power, + float max_eirp, float antenna_gain, uint16_t timeout) { - if (request && params && _lora_mac && _lora_phy) { + cw_mode_params_t continuous_wave; - lorawan_status_t status = LORAWAN_STATUS_SERVICE_UNKNOWN; - loramac_mhdr_t machdr; + continuous_wave.channel = channel; + continuous_wave.datarate = datarate; + continuous_wave.tx_power = tx_power; + continuous_wave.max_eirp = max_eirp; + continuous_wave.antenna_gain = antenna_gain; + continuous_wave.timeout = timeout; - if (params->mac_state != LORAMAC_IDLE) { - return LORAWAN_STATUS_BUSY; - } - - // Before setting a new MLME request, clear the MLME confirmation - // structure - memset((uint8_t*) &confirmation, 0, sizeof(confirmation)); - - confirmation.status = LORAMAC_EVENT_INFO_STATUS_ERROR; - - switch (request->type) { - case MLME_JOIN: { - if ((params->mac_state & LORAMAC_TX_DELAYED) - == LORAMAC_TX_DELAYED) { - return LORAWAN_STATUS_BUSY; - } - - if ((request->req.join.dev_eui == NULL) - || (request->req.join.app_eui == NULL) - || (request->req.join.app_key == NULL) - || (request->req.join.nb_trials == 0)) { - return LORAWAN_STATUS_PARAMETER_INVALID; - } - - if (false == _lora_phy->verify_nb_join_trials(request->req.join.nb_trials)) { - // Value not supported, get default - request->req.join.nb_trials = _lora_phy->get_nb_join_trials(true); - } - - params->flags.bits.mlme_req = 1; - confirmation.req_type = request->type; - - params->keys.dev_eui = request->req.join.dev_eui; - params->keys.app_eui = request->req.join.app_eui; - params->keys.app_key = request->req.join.app_key; - params->max_join_request_trials = request->req.join.nb_trials; - - // Reset variable JoinRequestTrials - params->join_request_trial_counter = 0; - - // Setup header information - machdr.value = 0; - machdr.bits.mtype = FRAME_TYPE_JOIN_REQ; - - _lora_mac->reset_mac_parameters(); - - params->sys_params.channel_data_rate = - _lora_phy->get_alternate_DR(params->join_request_trial_counter + 1); - - status = _lora_mac->send(&machdr, 0, NULL, 0); - break; - } - case MLME_LINK_CHECK: { - params->flags.bits.mlme_req = 1; - // LoRaMac will send this command piggy-backed - confirmation.req_type = request->type; - - status = LORAWAN_STATUS_OK; - break; - } - case MLME_TXCW: { - confirmation.req_type = request->type; - params->flags.bits.mlme_req = 1; - status = _lora_mac->set_tx_continuous_wave(request->req.cw_tx_mode.timeout); - break; - } - case MLME_TXCW_1: { - confirmation.req_type = request->type; - params->flags.bits.mlme_req = 1; - status = _lora_mac->set_tx_continuous_wave1(request->req.cw_tx_mode.timeout, - request->req.cw_tx_mode.frequency, - request->req.cw_tx_mode.power); - break; - } - default: - break; - } - - if (status != LORAWAN_STATUS_OK) { - params->is_node_ack_requested = false; - params->flags.bits.mlme_req = 0; - } - - return status; - } - - return LORAWAN_STATUS_PARAMETER_INVALID; + _lora_phy->set_tx_cont_mode(&continuous_wave); } diff --git a/features/lorawan/lorastack/mac/LoRaMacMlme.h b/features/lorawan/lorastack/mac/LoRaMacMlme.h index 2b751058b1..06ea8a43fc 100644 --- a/features/lorawan/lorastack/mac/LoRaMacMlme.h +++ b/features/lorawan/lorastack/mac/LoRaMacMlme.h @@ -49,6 +49,8 @@ public: */ ~LoRaMacMlme(); + void reset_confirmation(); + /** Activating MLME subsystem * * Stores pointers to MAC and PHY layer handles @@ -56,21 +58,7 @@ public: * @param mac pointer to MAC layer * @param phy pointer to PHY layer */ - void activate_mlme_subsystem(LoRaMac *mac, LoRaPHY *phy); - - /** Sets up an MLME Request - * - * Sets up an MLME request, e.g., a Join Request and sends it through - * to the central MAC control. It also modifies or uses protocol information - * provided in the MAC protocol data structure. - * - * @param request pointer to MLME request structure - * @param params pointer to MAC protocol parameters - * - * @return LORAWAN_STATUS_OK if everything goes well otherwise - * a negative error code is returned. - */ - lorawan_status_t set_request(loramac_mlme_req_t *request, loramac_protocol_params *params); + void activate_mlme_subsystem(LoRaPHY *phy); /** Grants access to MLME confirmation data * @@ -84,12 +72,14 @@ public: */ loramac_mlme_indication_t& get_indication(); + void set_tx_continuous_wave(uint8_t channel, int8_t datarate, int8_t tx_power, + float max_eirp, float antenna_gain, uint16_t timeout); + private: /** - * Pointers to MAC and PHY handles + * Pointer to PHY handle */ - LoRaMac *_lora_mac; LoRaPHY *_lora_phy; /**