From 1eedadd52d563069856e81316af429d234955740 Mon Sep 17 00:00:00 2001 From: Kimmo Vaisanen Date: Tue, 6 Feb 2018 08:41:24 +0200 Subject: [PATCH 01/23] Change region configuration help format New mbed os configuration parser no longer seems to allow multiline help description. --- features/lorawan/mbed_lib.json | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/features/lorawan/mbed_lib.json b/features/lorawan/mbed_lib.json index e4ddf214fa..df3e3ee9af 100644 --- a/features/lorawan/mbed_lib.json +++ b/features/lorawan/mbed_lib.json @@ -2,16 +2,7 @@ "name": "lora", "config": { "phy": { - "help": ["Select LoRa PHY layer. See README.md for more information. Default: 0 = LORA_PHY_EU868", - " 1 = LORA_PHY_AS923", - " 2 = LORA_PHY_AU915", - " 3 = LORA_PHY_CN470", - " 4 = LORA_PHY_CN779", - " 5 = LORA_PHY_EU433", - " 6 = LORA_PHY_IN865", - " 7 = LORA_PHY_KR920", - " 8 = LORA_PHY_US915", - " 9 = LORA_PHY_US915_HYBRID"], + "help": "LoRa PHY region. 0 = EU868 (default), 1 = AS923, 2 = AU915, 3 = CN470, 4 = CN779, 5 = EU433, 6 = IN865, 7 = KR920, 8 = US915, 9 = US915_HYBRID", "value": "0" }, "over-the-air-activation": { From b634ca49dd415be4fe2b68c96ad76e95b944f5fa Mon Sep 17 00:00:00 2001 From: Hasnain Virk Date: Fri, 15 Dec 2017 12:30:40 +0200 Subject: [PATCH 02/23] Architecture rework, bug fixing & missing features MAC layer is now a class rather than being a blob. In addition to that Mac commands are now being handled in a seperate subsystem (a class of its own). In future we will do the same with othe sublayers of MAC like MLME, MCPS etc. The drive behind this exercise is to make MAC and supporting layers into an object oriented system. Major bug fixes include: - last join time inclusion in band parameters - disabling rx2 window if we missed the slot already - MLME uplink schdule hook - nbRep according to spec - maintaining datarate after successful joining - suppressing MLME requests if MAC is in TX_DELAYED state - Uplink dwell time verification Some missing features are implemented. Details are as follows. Support for LinkCheckRequet: An application API is added, add_link_check_request() to delegate a request for Link Check Request MAC command. * Application provides a callback function that needs to be called on reception of link check response. * Mac command is piggybacked with data frames. This API makes the sticky MAC command stick with the application payloads until/unless the application un-sticks the said mac command using remove_link_check_request() API. Handling fPending bit: If in the Downlink, we get the fPending bit set in fctrl octet, we attempt to send an empty message back to Network Server to open additional Receive windows. This operation is independent of the application. An RX_DONE event is queued bedore generating the said empty message. Specification does not mention what can be the type of that empty message. We have decided it to be of CONFIRMED type as it gives us an added benefit of retries if the corresponding RX slots are missed. Radio event callbacks as Mbed callbacks: radio_events_t structure has been carrying C-style callbacks which was inherited from the legacy code. These callbacks has now been changed to Mbed Callbacks that makes sure that we can be object oriented from now on. --- features/lorawan/LoRaWANInterface.cpp | 19 +- features/lorawan/LoRaWANInterface.h | 43 +- features/lorawan/LoRaWANStack.cpp | 92 +- features/lorawan/LoRaWANStack.h | 39 +- features/lorawan/lorastack/mac/LoRaMac.cpp | 1334 ++++------------- features/lorawan/lorastack/mac/LoRaMac.h | 1144 ++++++++++---- .../lorawan/lorastack/mac/LoRaMacCommand.cpp | 444 ++++++ .../lorawan/lorastack/mac/LoRaMacCommand.h | 175 +++ features/lorawan/lorastack/mac/LoRaMacTest.h | 68 - features/lorawan/lorastack/phy/LoRaPHY.cpp | 4 +- .../lorawan/lorastack/phy/LoRaPHYAS923.cpp | 6 +- .../lorawan/lorastack/phy/LoRaPHYAU915.cpp | 6 +- .../lorawan/lorastack/phy/LoRaPHYCN470.cpp | 6 +- .../lorawan/lorastack/phy/LoRaPHYCN779.cpp | 6 +- .../lorawan/lorastack/phy/LoRaPHYEU433.cpp | 6 +- .../lorawan/lorastack/phy/LoRaPHYEU868.cpp | 26 +- .../lorawan/lorastack/phy/LoRaPHYIN865.cpp | 6 +- .../lorawan/lorastack/phy/LoRaPHYKR920.cpp | 6 +- .../lorawan/lorastack/phy/LoRaPHYUS915.cpp | 6 +- .../lorastack/phy/LoRaPHYUS915Hybrid.cpp | 6 +- features/lorawan/lorastack/phy/lora_phy_ds.h | 4 +- features/lorawan/system/LoRaWANTimer.h | 8 - .../lorawan/system/lorawan_data_structures.h | 79 +- features/netsocket/LoRaRadio.h | 47 +- features/netsocket/LoRaWANBase.h | 33 + 25 files changed, 2101 insertions(+), 1512 deletions(-) create mode 100644 features/lorawan/lorastack/mac/LoRaMacCommand.cpp create mode 100644 features/lorawan/lorastack/mac/LoRaMacCommand.h delete mode 100644 features/lorawan/lorastack/mac/LoRaMacTest.h diff --git a/features/lorawan/LoRaWANInterface.cpp b/features/lorawan/LoRaWANInterface.cpp index df9529d993..0e1268a876 100644 --- a/features/lorawan/LoRaWANInterface.cpp +++ b/features/lorawan/LoRaWANInterface.cpp @@ -28,7 +28,7 @@ inline LoRaWANStack& stk_obj() return LoRaWANStack::get_lorawan_stack(); } -LoRaWANInterface::LoRaWANInterface(LoRaRadio& radio) +LoRaWANInterface::LoRaWANInterface(LoRaRadio& radio) : _link_check_requested(false) { // Pass mac_handlers to radio to the radio driver after // binding radio driver to PHY layer @@ -117,6 +117,17 @@ lora_mac_status_t LoRaWANInterface::disconnect() return LORA_MAC_STATUS_OK; } +lora_mac_status_t LoRaWANInterface::add_link_check_request() +{ + _link_check_requested = true; + return stk_obj().set_link_check_request(); +} + +void LoRaWANInterface::remove_link_check_request() +{ + _link_check_requested = false; +} + lora_mac_status_t LoRaWANInterface::set_datarate(uint8_t data_rate) { return stk_obj().set_channel_data_rate(data_rate); @@ -160,6 +171,12 @@ lora_mac_status_t LoRaWANInterface::remove_channel_plan() int16_t LoRaWANInterface::send(uint8_t port, const uint8_t* data, uint16_t length, int flags) { + if (_link_check_requested) { + // add a link check request with normal data, until the application + // explicitly removes it. + add_link_check_request(); + } + if (data) { return stk_obj().handle_tx(port, data, length, flags); } else { diff --git a/features/lorawan/LoRaWANInterface.h b/features/lorawan/LoRaWANInterface.h index 5ea9916554..49c36678eb 100644 --- a/features/lorawan/LoRaWANInterface.h +++ b/features/lorawan/LoRaWANInterface.h @@ -130,6 +130,44 @@ public: */ virtual lora_mac_status_t disconnect(); + /** Validate the connectivity with the network. + * + * Application may use this API to submit a request to the stack for + * validation of its connectivity to a Network Server. Under the hood, this + * API schedules a Link Check Request command (LinkCheckReq) for the network + * server and once the response, i.e., LinkCheckAns MAC command is received + * from the Network Server, user provided method is called. + * + * One way to use this API may be the validation of connectivity after a long + * deep sleep. Mbed LoRaWANStack piggy-backs the MAC commands with data + * frame payload so the application needs to try sending something and the Network + * Server may respond during the RX slots. + * + * This API is usable only when the 'link_check_resp' callback is set by + * the application. See add_lora_app_callbacks API. If the above mentioned + * callback is not set, a LORA_MAC_STATUS_PARAMETER_INVALID error is thrown. + * + * First parameter to callback function is the demodulation margin and + * the second parameter is the number of gateways that successfully received + * the last request. + * + * A 'Link Check Request' MAC command remains set for every subsequent + * transmission, until/unless application explicitly turns it off using + * remove_link_check_request() API. + * + * @return LORA_MAC_STATUS_OK on successfully queuing a request, or + * a negative error code on failure. + * + */ + virtual lora_mac_status_t add_link_check_request(); + + /** Removes link check request sticky MAC command. + * + * Any already queued request may still get entertained. However, no new + * requests will be made. + */ + virtual void remove_link_check_request(); + /** Sets up a particular data rate * * `set_datarate()` first verifies whether the data rate given is valid or not. @@ -361,7 +399,7 @@ public: * int main() * { * lorawan.initialize(&queue); - * cbs.lorawan_events = mbed::callback(my_event_handler); + * cbs.events = mbed::callback(my_event_handler); * lorawan.add_app_callbacks(&cbs); * lorawan.connect(); * } @@ -387,6 +425,9 @@ public: * callbacks. */ virtual lora_mac_status_t add_app_callbacks(lorawan_app_callbacks_t *callbacks); + +private: + bool _link_check_requested; }; #endif /* LORAWANINTERFACE_H_ */ diff --git a/features/lorawan/LoRaWANStack.cpp b/features/lorawan/LoRaWANStack.cpp index ec0ef75b1e..261e20add5 100644 --- a/features/lorawan/LoRaWANStack.cpp +++ b/features/lorawan/LoRaWANStack.cpp @@ -129,7 +129,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), _queue(NULL), _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 @@ -168,7 +168,7 @@ LoRaWANStack& LoRaWANStack::get_lorawan_stack() radio_events_t *LoRaWANStack::bind_radio_driver(LoRaRadio& radio) { // Store pointer to callback routines inside MAC layer (non-IRQ safe) - _mac_handlers = GetPhyEventHandlers(); + _mac_handlers = _loramac.GetPhyEventHandlers(); // passes the reference to radio driver down to PHY layer lora_phy.get()->set_radio_instance(radio); return _mac_handlers; @@ -204,7 +204,8 @@ lora_mac_status_t LoRaWANStack::initialize_mac_layer(EventQueue *queue) LoRaMacPrimitives.MacMcpsConfirm = callback(this, &LoRaWANStack::mcps_confirm); LoRaMacPrimitives.MacMcpsIndication = callback(this, &LoRaWANStack::mcps_indication); LoRaMacPrimitives.MacMlmeConfirm = callback(this, &LoRaWANStack::mlme_confirm); - LoRaMacInitialization(&LoRaMacPrimitives, &LoRaMacCallbacks, lora_phy.get(), queue); + LoRaMacPrimitives.MacMlmeIndication = callback(this, &LoRaWANStack::mlme_indication); + _loramac.LoRaMacInitialization(&LoRaMacPrimitives, &LoRaMacCallbacks, lora_phy.get(), queue); mib_req.type = LORA_MIB_ADR; mib_req.param.adr_enable = LORAWAN_ADR_ON; @@ -315,7 +316,7 @@ lora_mac_status_t LoRaWANStack::send_compliance_test_frame_to_mac() uint16_t LoRaWANStack::check_possible_tx_size(uint16_t size) { LoRaMacTxInfo_t txInfo; - if (LoRaMacQueryTxPossible(size, &txInfo) == LORAMAC_STATUS_LENGTH_ERROR) { + if (_loramac.LoRaMacQueryTxPossible(size, &txInfo) == LORAMAC_STATUS_LENGTH_ERROR) { // Cannot transmit this much. Return how much data can be sent // at the moment return txInfo.MaxPossiblePayload; @@ -461,9 +462,30 @@ void LoRaWANStack::mlme_confirm(MlmeConfirm_t *mlme_confirm) mlme_confirm_handler(&lora_mlme_confirm); } +/*! + * \brief MLME-Indication event function + * + * \param [IN] mlmeIndication - Pointer to the indication structure. + */ +void LoRaWANStack::mlme_indication( MlmeIndication_t *mlmeIndication ) +{ + switch( mlmeIndication->MlmeIndication ) + { + case MLME_SCHEDULE_UPLINK: + {// The MAC signals that we shall provide an uplink as soon as possible + // TODO: Sending implementation missing and will be implemented using + // another task. + //OnTxNextPacketTimerEvent( ); + break; + } + default: + break; + } +} + + void LoRaWANStack::set_lora_callbacks(lorawan_app_callbacks_t *cbs) { - if (cbs) { if (cbs->events) { _callbacks.events = cbs->events; @@ -508,7 +530,7 @@ lora_mac_status_t LoRaWANStack::add_channels(const lora_channelplan_t &channel_p mac_layer_ch_params.Frequency = channel_plan.channels[i].ch_param.frequency; mac_layer_ch_params.Rx1Frequency =channel_plan.channels[i].ch_param.rx1_frequency; - status = LoRaMacChannelAdd(channel_plan.channels[i].id, mac_layer_ch_params); + status = _loramac.LoRaMacChannelAdd(channel_plan.channels[i].id, mac_layer_ch_params); if (status != LORAMAC_STATUS_OK) { return error_type_converter(status); @@ -560,7 +582,7 @@ lora_mac_status_t LoRaWANStack::drop_channel_list() continue; } - status = error_type_converter(LoRaMacChannelRemove(i)); + status = error_type_converter(_loramac.LoRaMacChannelRemove(i)); if (status != LORA_MAC_STATUS_OK) { return status; @@ -609,7 +631,7 @@ lora_mac_status_t LoRaWANStack::remove_a_channel(uint8_t channel_id) return LORA_MAC_STATUS_PARAMETER_INVALID; } - return error_type_converter(LoRaMacChannelRemove(channel_id)); + return error_type_converter(_loramac.LoRaMacChannelRemove(channel_id)); } lora_mac_status_t LoRaWANStack::get_enabled_channels(lora_channelplan_t& channel_plan) @@ -872,7 +894,9 @@ int16_t LoRaWANStack::handle_tx(uint8_t port, const uint8_t* data, _tx_msg.f_buffer_size = length; _tx_msg.pending_size = 0; // copy user buffer upto the max_possible_size - memcpy(_tx_msg.f_buffer, data, length); + if (data && length > 0) { + memcpy(_tx_msg.f_buffer, data, length); + } } // Handles all unconfirmed messages, including proprietary and multicast @@ -1018,7 +1042,7 @@ lora_mac_status_t LoRaWANStack::mlme_request_handler(lora_mac_mlme_req_t *mlme_r break; } - return error_type_converter(LoRaMacMlmeRequest(&request)); + return error_type_converter(_loramac.LoRaMacMlmeRequest(&request)); } /** MLME-Confirm event function @@ -1057,8 +1081,15 @@ void LoRaWANStack::mlme_confirm_handler(lora_mac_mlme_confirm_t *mlme_confirm) _compliance_test.link_check = true; _compliance_test.demod_margin = mlme_confirm->demod_margin; _compliance_test.nb_gateways = mlme_confirm->nb_gateways; - } + } else #endif + { + // normal operation as oppose to compliance testing + if (_callbacks.link_check_resp) { + _queue->call(_callbacks.link_check_resp, mlme_confirm->demod_margin, + mlme_confirm->nb_gateways); + } + } } break; default: @@ -1101,7 +1132,7 @@ lora_mac_status_t LoRaWANStack::mcps_request_handler(lora_mac_mcps_req_t *mcps_r break; } - return error_type_converter(LoRaMacMcpsRequest(&request)); + return error_type_converter(_loramac.LoRaMacMcpsRequest(&request)); } /** MCPS-Confirm event function @@ -1253,6 +1284,14 @@ void LoRaWANStack::mcps_indication_handler(lora_mac_mcps_indication_t *mcps_indi if (_callbacks.events) { _queue->call(_callbacks.events, RX_DONE); } + + // If fPending bit is set we try to generate an empty packet + // with CONFIRMED flag set. We always set a CONFIRMED flag so + // that we could retry a certain number of times if the uplink + // failed for some reason + if (mcps_indication->frame_pending) { + handle_tx(mcps_indication->port, NULL, 0, MSG_CONFIRMED_FLAG); + } } else { // Invalid port, ports 0, 224 and 225-255 are reserved. } @@ -1292,10 +1331,10 @@ void LoRaWANStack::compliance_test_handler(lora_mac_mcps_indication_t *mcps_indi mib_set_request(&mib_req); #if MBED_CONF_LORA_PHY == 0 - LoRaMacTestSetDutyCycleOn(false); + _loramac.LoRaMacTestSetDutyCycleOn(false); #endif //5000ms - LoRaMacSetTxTimer(5000); + _loramac.LoRaMacSetTxTimer(5000); set_device_state(DEVICE_STATE_COMPLIANCE_TEST); tr_debug("Compliance test activated."); } @@ -1314,11 +1353,11 @@ void LoRaWANStack::compliance_test_handler(lora_mac_mcps_indication_t *mcps_indi mib_req.param.adr_enable = LORAWAN_ADR_ON; mib_set_request(&mib_req); #if MBED_CONF_LORA_PHY == 0 - LoRaMacTestSetDutyCycleOn(LORAWAN_DUTYCYCLE_ON); + _loramac.LoRaMacTestSetDutyCycleOn(LORAWAN_DUTYCYCLE_ON); #endif // Go to idle state after compliance test mode. tr_debug("Compliance test disabled."); - LoRaMacStopTxTimer(); + _loramac.LoRaMacStopTxTimer(); // Clear any compliance test message stuff before going back to normal operation. memset(&_tx_msg, 0, sizeof(_tx_msg)); @@ -1366,7 +1405,7 @@ void LoRaWANStack::compliance_test_handler(lora_mac_mcps_indication_t *mcps_indi mib_request.param.adr_enable = LORAWAN_ADR_ON; mib_set_request(&mib_request); #if MBED_CONF_LORA_PHY == 0 - LoRaMacTestSetDutyCycleOn(LORAWAN_DUTYCYCLE_ON); + _loramac.LoRaMacTestSetDutyCycleOn(LORAWAN_DUTYCYCLE_ON); #endif mlme_request.type = LORA_MLME_JOIN; mlme_request.req.join.dev_eui = _lw_session.connection.connection_u.otaa.dev_eui; @@ -1569,7 +1608,7 @@ lora_mac_status_t LoRaWANStack::mib_set_request(lora_mac_mib_request_confirm_t * /* * Set MIB data to LoRa stack */ - status = error_type_converter(LoRaMacMibSetRequestConfirm(&stack_mib_set)); + status = error_type_converter(_loramac.LoRaMacMibSetRequestConfirm(&stack_mib_set)); /* * Release memory if reserved by multicast list */ @@ -1598,7 +1637,7 @@ lora_mac_status_t LoRaWANStack::mib_get_request(lora_mac_mib_request_confirm_t * // Interprets from lora_mac_mib_t to Mib_t stack_mib_get.Type = interpret_mib_req_confirm_type(mib_get_params->type); - mac_status = error_type_converter(LoRaMacMibGetRequestConfirm(&stack_mib_get)); + mac_status = error_type_converter(_loramac.LoRaMacMibGetRequestConfirm(&stack_mib_get)); if (LORA_MAC_STATUS_OK != mac_status) { return LORA_MAC_STATUS_SERVICE_UNKNOWN; @@ -1782,6 +1821,19 @@ lora_mac_status_t LoRaWANStack::error_type_converter(LoRaMacStatus_t type) } } +lora_mac_status_t LoRaWANStack::set_link_check_request() +{ + if (!_callbacks.link_check_resp) { + tr_error("Must assign a callback function for link check request. "); + return LORA_MAC_STATUS_PARAMETER_INVALID; + } + + lora_mac_mlme_req_t mlme_req; + + mlme_req.type = LORA_MLME_LINK_CHECK; + return mlme_request_handler(&mlme_req); +} + void LoRaWANStack::shutdown() { set_device_state(DEVICE_STATE_SHUTDOWN); @@ -1944,7 +1996,7 @@ lora_mac_status_t LoRaWANStack::lora_state_machine() tr_debug("Device is in compliance test mode."); //5000ms - LoRaMacSetTxTimer(5000); + _loramac.LoRaMacSetTxTimer(5000); if (_compliance_test.running == true) { send_compliance_test_frame_to_mac(); } diff --git a/features/lorawan/LoRaWANStack.h b/features/lorawan/LoRaWANStack.h index edad86ee9d..4dbfe7f313 100644 --- a/features/lorawan/LoRaWANStack.h +++ b/features/lorawan/LoRaWANStack.h @@ -67,7 +67,7 @@ public: /** Sets all callbacks for the application. * - * \param callbacks A pointer to the structure carrying callbacks. + * @param callbacks A pointer to the structure carrying callbacks. */ void set_lora_callbacks(lorawan_app_callbacks_t *callbacks); @@ -267,6 +267,22 @@ public: int16_t handle_rx(const uint8_t port, uint8_t* data, uint16_t length, uint8_t flags); + /** Send Link Check Request MAC command. + * + * + * This API schedules a Link Check Request command (LinkCheckReq) for the network + * server and once the response, i.e., LinkCheckAns MAC command is received + * from the Network Server, an event is generated. + * + * A callback function for the link check response must be set prior to using + * this API, otherwise a LORA_MAC_STATUS_PARAMETER_INVALID error is thrown. + * + * @return LORA_MAC_STATUS_OK on successfully queuing a request, or + * a negative error code on failure. + * + */ + lora_mac_status_t set_link_check_request(); + /** Shuts down the LoRaWAN protocol. * * In response to the user call for disconnection, the stack shuts down itself. @@ -296,11 +312,6 @@ private: */ void set_device_state(device_states_t new_state); - /** - * This function is used only for compliance testing - */ - void prepare_special_tx_frame(uint8_t port); - /** * Hands over the packet to Mac layer by posting an MCPS request. */ @@ -327,6 +338,13 @@ private: */ void mlme_confirm(MlmeConfirm_t *mlme_confirm); + /** + * Callback function for MLME indication. Mac layer calls this function once + * an MLME indication is received. This method translates Mac layer data + * structure into stack layer data structure. + */ + void mlme_indication( MlmeIndication_t *mlmeIndication ); + /** * Handles an MLME request coming from the upper layers and delegates * it to the Mac layer, for example, a Join request goes as an MLME request @@ -389,6 +407,12 @@ private: */ uint16_t check_possible_tx_size(uint16_t size); +#if defined(LORAWAN_COMPLIANCE_TEST) + /** + * This function is used only for compliance testing + */ + void prepare_special_tx_frame(uint8_t port); + /** * Used only for compliance testing */ @@ -398,12 +422,15 @@ private: * Used only for compliance testing */ lora_mac_status_t send_compliance_test_frame_to_mac(); +#endif /** * converts error codes from Mac layer to controller layer */ lora_mac_status_t error_type_converter(LoRaMacStatus_t type); + LoRaMac _loramac; + #if defined(LORAWAN_COMPLIANCE_TEST) compliance_test_t _compliance_test; #endif diff --git a/features/lorawan/lorastack/mac/LoRaMac.cpp b/features/lorawan/lorastack/mac/LoRaMac.cpp index f50d68cdf6..81d4b6e046 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.cpp +++ b/features/lorawan/lorastack/mac/LoRaMac.cpp @@ -22,12 +22,9 @@ Copyright (c) 2017, Arm Limited and affiliates. SPDX-License-Identifier: BSD-3-Clause */ #include -#include "events/EventQueue.h" #include "LoRaMac.h" #include "LoRaMacCrypto.h" -#include "LoRaMacTest.h" -#include "netsocket/LoRaRadio.h" -#include "lorastack/phy/LoRaPHY.h" + #if defined(FEATURE_COMMON_PAL) #include "mbed_trace.h" #define TRACE_GROUP "LMAC" @@ -39,30 +36,17 @@ SPDX-License-Identifier: BSD-3-Clause 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 - */ -radio_events_t RadioEvents; - /*! - * Maximum PHY layer payload size + * TODO: We should get rid of this + * + * Static handle to LoRaMac object. This is needed for static callback methods. */ -#define LORAMAC_PHY_MAXPAYLOAD 255 - -/*! - * Maximum MAC commands buffer size - */ -#define LORA_MAC_COMMAND_MAX_LENGTH 128 +static LoRaMac* isrHandler = NULL; /*! * Maximum length of the fOpts field @@ -85,627 +69,172 @@ radio_events_t RadioEvents; #define BACKOFF_DC_24_HOURS 10000 /*! - * Device IEEE EUI + * Check the MAC layer state every MAC_STATE_CHECK_TIMEOUT in ms. */ -static uint8_t *LoRaMacDevEui; +#define MAC_STATE_CHECK_TIMEOUT 1000 /*! - * Application IEEE EUI + * The maximum number of times the MAC layer tries to get an acknowledge. */ -static uint8_t *LoRaMacAppEui; +#define MAX_ACK_RETRIES 8 /*! - * AES encryption/decryption cipher application key + * The frame direction definition for uplink communications. */ -static uint8_t *LoRaMacAppKey; +#define UP_LINK 0 /*! - * AES encryption/decryption cipher network session key + * The frame direction definition for downlink communications. */ -static uint8_t LoRaMacNwkSKey[] = +#define DOWN_LINK 1 + + +LoRaMac::LoRaMac() + : mac_commands(*this) { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; + isrHandler = this; -/*! - * AES encryption/decryption cipher application session key - */ -static uint8_t LoRaMacAppSKey[] = + lora_phy = NULL; + //radio_events_t RadioEvents; + LoRaMacDevEui = NULL; + LoRaMacAppEui = NULL; + LoRaMacAppKey = NULL; + + memset(LoRaMacNwkSKey, 0, sizeof(LoRaMacNwkSKey)); + memset(LoRaMacAppSKey, 0, sizeof(LoRaMacAppSKey)); + + LoRaMacDevNonce = 0; + LoRaMacNetID = 0; + LoRaMacDevAddr = 0; + MulticastChannels = NULL; + //DeviceClass_t LoRaMacDeviceClass; + //bool PublicNetwork; + //bool RepeaterSupport; + //uint8_t LoRaMacBuffer[LORAMAC_PHY_MAXPAYLOAD]; + LoRaMacBufferPktLen = 0; + LoRaMacTxPayloadLen = 0; + //uint8_t LoRaMacRxPayload[LORAMAC_PHY_MAXPAYLOAD]; + UpLinkCounter = 0; + DownLinkCounter = 0; + IsUpLinkCounterFixed = false; + IsRxWindowsEnabled = true; + IsLoRaMacNetworkJoined = false; + LoRaMacParams.AdrCtrlOn = false; + AdrAckCounter = 0; + NodeAckRequested = false; + SrvAckRequested = false; + //LoRaMacParams_t LoRaMacParams; + //LoRaMacParams_t LoRaMacParamsDefaults; + ChannelsNbRepCounter = 0; + LoRaMacParams.MaxDCycle = 0; + //uint16_t AggregatedDCycle; + //TimerTime_t AggregatedLastTxDoneTime; + //TimerTime_t AggregatedTimeOff; + //bool DutyCycleOn; + //uint8_t Channel; + //uint8_t LastTxChannel; + //bool LastTxIsJoinRequest; + LoRaMacInitializationTime = 0; + LoRaMacState = LORAMAC_IDLE; + //TimerEvent_t MacStateCheckTimer; + //TimerEvent_t TxNextPacketTimer; + //LoRaMacPrimitives_t *LoRaMacPrimitives; + //LoRaMacCallback_t *LoRaMacCallbacks; + //TimerEvent_t TxDelayedTimer; + //TimerEvent_t RxWindowTimer1; + //TimerEvent_t RxWindowTimer2; + //uint32_t RxWindow1Delay; + //uint32_t RxWindow2Delay; + //RxConfigParams_t RxWindow1Config; + //RxConfigParams_t RxWindow2Config; + //TimerEvent_t AckTimeoutTimer; + AckTimeoutRetries = 1; + AckTimeoutRetriesCounter = 1; + AckTimeoutRetry = false; + TxTimeOnAir = 0; + //uint8_t JoinRequestTrials; + //uint8_t MaxJoinRequestTrials; + //McpsIndication_t McpsIndication; + //McpsConfirm_t McpsConfirm; + //MlmeConfirm_t MlmeConfirm; + //LoRaMacRxSlot_t RxSlot; + //LoRaMacFlags_t LoRaMacFlags; +} + +LoRaMac::~LoRaMac() { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; +} -/*! - * Device nonce is a random value extracted by issuing a sequence of RSSI - * measurements - */ -static uint16_t LoRaMacDevNonce; - -/*! - * Network ID ( 3 bytes ) - */ -static uint32_t LoRaMacNetID; - -/*! - * Mote Address - */ -static uint32_t LoRaMacDevAddr; - -/*! - * Multicast channels linked list - */ -static MulticastParams_t *MulticastChannels = NULL; - -/*! - * Actual device class - */ -static DeviceClass_t LoRaMacDeviceClass; - -/*! - * Indicates if the node is connected to a private or public network - */ -static bool PublicNetwork; - -/*! - * Indicates if the node supports repeaters - */ -static bool RepeaterSupport; - -/*! - * Buffer containing the data to be sent or received. - */ -static uint8_t LoRaMacBuffer[LORAMAC_PHY_MAXPAYLOAD]; - -/*! - * Length of packet in LoRaMacBuffer - */ -static uint16_t LoRaMacBufferPktLen = 0; - -/*! - * Length of the payload in LoRaMacBuffer - */ -static uint8_t LoRaMacTxPayloadLen = 0; - -/*! - * Buffer containing the upper layer data. - */ -static uint8_t LoRaMacRxPayload[LORAMAC_PHY_MAXPAYLOAD]; - -/*! - * LoRaMAC frame counter. Each time a packet is sent the counter is incremented. - * Only the 16 LSB bits are sent - */ -static uint32_t UpLinkCounter = 0; - -/*! - * LoRaMAC frame counter. Each time a packet is received the counter is incremented. - * Only the 16 LSB bits are received - */ -static uint32_t DownLinkCounter = 0; - -/*! - * IsPacketCounterFixed enables the MIC field tests by fixing the - * UpLinkCounter value - */ -static bool IsUpLinkCounterFixed = false; - -/*! - * Used for test purposes. Disables the opening of the reception windows. - */ -static bool IsRxWindowsEnabled = true; - -/*! - * Indicates if the MAC layer has already joined a network. - */ -static bool IsLoRaMacNetworkJoined = false; - -/*! - * LoRaMac ADR control status - */ -static bool AdrCtrlOn = false; - -/*! - * Counts the number of missed ADR acknowledgements - */ -static uint32_t AdrAckCounter = 0; - -/*! - * If the node has sent a FRAME_TYPE_DATA_CONFIRMED_UP this variable indicates - * if the nodes needs to manage the server acknowledgement. - */ -static bool NodeAckRequested = false; - -/*! - * If the server has sent a FRAME_TYPE_DATA_CONFIRMED_DOWN this variable indicates - * if the ACK bit must be set for the next transmission - */ -static bool SrvAckRequested = false; - -/*! - * Indicates if the MAC layer wants to send MAC commands - */ -static bool MacCommandsInNextTx = false; - -/*! - * Contains the current MacCommandsBuffer index - */ -static uint8_t MacCommandsBufferIndex = 0; - -/*! - * Contains the current MacCommandsBuffer index for MAC commands to repeat - */ -static uint8_t MacCommandsBufferToRepeatIndex = 0; - -/*! - * Buffer containing the MAC layer commands - */ -static uint8_t MacCommandsBuffer[LORA_MAC_COMMAND_MAX_LENGTH]; - -/*! - * Buffer containing the MAC layer commands which must be repeated - */ -static uint8_t MacCommandsBufferToRepeat[LORA_MAC_COMMAND_MAX_LENGTH]; - -/*! - * LoRaMac parameters - */ -LoRaMacParams_t LoRaMacParams; - -/*! - * LoRaMac default parameters - */ -LoRaMacParams_t LoRaMacParamsDefaults; - -/*! - * Uplink messages repetitions counter - */ -static uint8_t ChannelsNbRepCounter = 0; - -/*! - * Maximum duty cycle - * \remark Possibility to shutdown the device. - */ -static uint8_t MaxDCycle = 0; - -/*! - * Aggregated duty cycle management - */ -static uint16_t AggregatedDCycle; -static TimerTime_t AggregatedLastTxDoneTime; -static TimerTime_t AggregatedTimeOff; - -/*! - * Enables/Disables duty cycle management (Test only) - */ -static bool DutyCycleOn; - -/*! - * Current channel index - */ -static uint8_t Channel; - -/*! - * Current channel index - */ -static uint8_t LastTxChannel; - -/*! - * Set to true, if the last uplink was a join request - */ -static bool LastTxIsJoinRequest; - -/*! - * Stores the time at LoRaMac initialization. - * - * \remark Used for the BACKOFF_DC computation. - */ -static TimerTime_t LoRaMacInitializationTime = 0; - -/*! - * LoRaMac internal states - */ -enum eLoRaMacState -{ - LORAMAC_IDLE = 0x00000000, - LORAMAC_TX_RUNNING = 0x00000001, - LORAMAC_RX = 0x00000002, - LORAMAC_ACK_REQ = 0x00000004, - LORAMAC_ACK_RETRY = 0x00000008, - LORAMAC_TX_DELAYED = 0x00000010, - LORAMAC_TX_CONFIG = 0x00000020, - LORAMAC_RX_ABORT = 0x00000040, -}; - -/*! - * LoRaMac internal state - */ -uint32_t LoRaMacState = LORAMAC_IDLE; - -/*! - * LoRaMac timer used to check the LoRaMacState (runs every second) - */ -static TimerEvent_t MacStateCheckTimer; - -/*! - * LoRaMac upper layer event functions - */ -static LoRaMacPrimitives_t *LoRaMacPrimitives; - -/*! - * LoRaMac upper layer callback functions - */ -static LoRaMacCallback_t *LoRaMacCallbacks; - -/*! - * LoRaMac duty cycle delayed Tx timer - */ -static TimerEvent_t TxDelayedTimer; - -/*! - * LoRaMac reception windows timers - */ -static TimerEvent_t RxWindowTimer1; -static TimerEvent_t RxWindowTimer2; - -/*! - * LoRaMac reception windows delay - * \remark normal frame: RxWindowXDelay = ReceiveDelayX - RADIO_WAKEUP_TIME - * join frame : RxWindowXDelay = JoinAcceptDelayX - RADIO_WAKEUP_TIME - */ -static uint32_t RxWindow1Delay; -static uint32_t RxWindow2Delay; - -/*! - * LoRaMac Rx windows configuration - */ -static RxConfigParams_t RxWindow1Config; -static RxConfigParams_t RxWindow2Config; - -/*! - * Acknowledge timeout timer. Used for packet retransmissions. - */ -static TimerEvent_t AckTimeoutTimer; - -/*! - * Number of trials to get a frame acknowledged - */ -static uint8_t AckTimeoutRetries = 1; - -/*! - * Number of trials to get a frame acknowledged - */ -static uint8_t AckTimeoutRetriesCounter = 1; - -/*! - * Indicates if the AckTimeout timer has expired or not - */ -static bool AckTimeoutRetry = false; - -/*! - * Last transmission time on air - */ -TimerTime_t TxTimeOnAir = 0; - -/*! - * Number of trials for the Join Request - */ -static uint8_t JoinRequestTrials; - -/*! - * Maximum number of trials for the Join Request - */ -static uint8_t MaxJoinRequestTrials; - -/*! - * Structure to hold an MCPS indication data. - */ -static McpsIndication_t McpsIndication; - -/*! - * Structure to hold MCPS confirm data. - */ -static McpsConfirm_t McpsConfirm; - -/*! - * Structure to hold MLME confirm data. - */ -static MlmeConfirm_t MlmeConfirm; - -/*! - * Holds the current rx window slot - */ -static uint8_t RxSlot = 0; - -/*! - * LoRaMac tx/rx operation state - */ -LoRaMacFlags_t LoRaMacFlags; - -/*! - * \brief Function to be executed on Radio Tx Done event - */ -static void OnRadioTxDone( void ); - -/*! - * \brief This function prepares the MAC to abort the execution of function - * OnRadioRxDone in case of a reception error. - */ -static void PrepareRxDoneAbort( void ); - -/*! - * \brief Function to be executed on Radio Rx Done event - */ -static void OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ); - -/*! - * \brief Function executed on Radio Tx Timeout event - */ -static void OnRadioTxTimeout( void ); - -/*! - * \brief Function executed on Radio Rx error event - */ -static void OnRadioRxError( void ); - -/*! - * \brief Function executed on Radio Rx Timeout event - */ -static void OnRadioRxTimeout( void ); - -/*! - * \brief Function executed on Resend Frame timer event. - */ -static void OnMacStateCheckTimerEvent( void ); - -/*! - * \brief Function executed on duty cycle delayed Tx timer event - */ -static void OnTxDelayedTimerEvent( void ); - -/*! - * \brief Function executed on first Rx window timer event - */ -static void OnRxWindow1TimerEvent( void ); - -/*! - * \brief Function executed on second Rx window timer event - */ -static void OnRxWindow2TimerEvent( void ); - -/*! - * \brief Function executed on AckTimeout timer event - */ -static void OnAckTimeoutTimerEvent( void ); - -/*! - * \brief Initializes and opens the reception window - * - * \param [IN] rxContinuous Set to true, if the RX is in continuous mode - * \param [IN] maxRxWindow Maximum RX window timeout - */ -static void RxWindowSetup( bool rxContinuous, uint32_t maxRxWindow ); - -/*! - * \brief Adds a new MAC command to be sent. - * - * \Remark MAC layer internal function - * - * \param [in] cmd MAC command to be added - * [MOTE_MAC_LINK_CHECK_REQ, - * MOTE_MAC_LINK_ADR_ANS, - * MOTE_MAC_DUTY_CYCLE_ANS, - * MOTE_MAC_RX2_PARAM_SET_ANS, - * MOTE_MAC_DEV_STATUS_ANS - * MOTE_MAC_NEW_CHANNEL_ANS] - * \param [in] p1 1st parameter ( optional depends on the command ) - * \param [in] p2 2nd parameter ( optional depends on the command ) - * - * \retval status Function status [0: OK, 1: Unknown command, 2: Buffer full] - */ -static LoRaMacStatus_t AddMacCommand( uint8_t cmd, uint8_t p1, uint8_t p2 ); - -/*! - * \brief Parses the MAC commands which must be repeated. - * - * \Remark MAC layer internal function - * - * \param [IN] cmdBufIn Buffer which stores the MAC commands to send - * \param [IN] length Length of the input buffer to parse - * \param [OUT] cmdBufOut Buffer which stores the MAC commands which must be - * repeated. - * - * \retval Size of the MAC commands to repeat. - */ -static uint8_t ParseMacCommandsToRepeat( uint8_t* cmdBufIn, uint8_t length, uint8_t* cmdBufOut ); - -/*! - * \brief Validates if the payload fits into the frame, taking the datarate - * into account. - * - * \details Refer to chapter 4.3.2 of the LoRaWAN specification, v1.0 - * - * \param lenN Length of the application payload. The length depends on the - * datarate and is region specific - * - * \param datarate Current datarate - * - * \param fOptsLen Length of the fOpts field - * - * \retval [false: payload does not fit into the frame, true: payload fits into - * the frame] - */ -static bool ValidatePayloadLength( uint8_t lenN, int8_t datarate, uint8_t fOptsLen ); - -/*! - * \brief Decodes MAC commands in the fOpts field and in the payload - */ -static void ProcessMacCommands( uint8_t *payload, uint8_t macIndex, uint8_t commandsSize, uint8_t snr ); - -/*! - * \brief LoRaMAC layer generic send frame - * - * \param [IN] macHdr MAC header field - * \param [IN] fPort MAC payload port - * \param [IN] fBuffer MAC data buffer to be sent - * \param [IN] fBufferSize MAC data buffer size - * \retval status Status of the operation. - */ -LoRaMacStatus_t Send( LoRaMacHeader_t *macHdr, uint8_t fPort, void *fBuffer, uint16_t fBufferSize ); - -/*! - * \brief LoRaMAC layer frame buffer initialization - * - * \param [IN] macHdr MAC header field - * \param [IN] fCtrl MAC frame control field - * \param [IN] fOpts MAC commands buffer - * \param [IN] fPort MAC payload port - * \param [IN] fBuffer MAC data buffer to be sent - * \param [IN] fBufferSize MAC data buffer size - * \retval status Status of the operation. - */ -LoRaMacStatus_t PrepareFrame( LoRaMacHeader_t *macHdr, LoRaMacFrameCtrl_t *fCtrl, uint8_t fPort, void *fBuffer, uint16_t fBufferSize ); - -/* - * \brief Schedules the frame according to the duty cycle - * - * \retval Status of the operation - */ -static LoRaMacStatus_t ScheduleTx( void ); - -/* - * \brief Calculates the back-off time for the band of a channel. - * - * \param [IN] channel The last Tx channel index - */ -static void CalculateBackOff( uint8_t channel ); - -/*! - * \brief LoRaMAC layer prepared frame buffer transmission with channel specification - * - * \remark PrepareFrame must be called at least once before calling this - * function. - * - * \param [IN] channel Channel to transmit on - * \retval status Status of the operation. - */ -LoRaMacStatus_t SendFrameOnChannel( uint8_t channel ); - -/*! - * \brief Sets the radio in continuous transmission mode - * - * \remark Uses the radio parameters set on the previous transmission. - * - * \param [IN] timeout Time in seconds while the radio is kept in continuous wave mode - * \retval status Status of the operation. - */ -LoRaMacStatus_t SetTxContinuousWave( uint16_t timeout ); - -/*! - * \brief Sets the radio in continuous transmission mode - * - * \remark Uses the radio parameters set on the previous transmission. - * - * \param [IN] timeout Time in seconds while the radio is kept in continuous wave mode - * \param [IN] frequency RF frequency to be set. - * \param [IN] power RF output power to be set. - * \retval status Status of the operation. - */ -LoRaMacStatus_t SetTxContinuousWave1( uint16_t timeout, uint32_t frequency, uint8_t power ); - -/*! - * \brief Resets MAC specific parameters to default - */ -static void ResetMacParameters( void ); - - -/** - * Prototypes for ISR handlers - */ -static void handle_cad_done(bool cad); -static void handle_tx_done(void); -static void handle_rx_done(uint8_t *payload, uint16_t size, int16_t rssi, - int8_t snr); -static void handle_rx_error(void); -static void handle_rx_timeout(void); -static void handle_tx_timeout(void); -static void handle_fhss_change_channel(uint8_t cur_channel); -static void handle_rx1_timer_event(void); -static void handle_rx2_timer_event(void); -static void handle_ack_timeout(void); -static void handle_delayed_tx_timer_event(void); -static void handle_mac_state_check_timer_event(void); /*************************************************************************** * ISRs - Handlers * **************************************************************************/ -static void handle_tx_done(void) +void LoRaMac::handle_tx_done(void) { - ev_queue->call(OnRadioTxDone); + ev_queue->call(isrHandler, &LoRaMac::OnRadioTxDone); } -static void handle_rx_done(uint8_t *payload, uint16_t size, int16_t rssi, - int8_t snr) +void LoRaMac::handle_rx_done(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr) { - ev_queue->call(OnRadioRxDone, payload, size, rssi, snr); + ev_queue->call(isrHandler, &LoRaMac::OnRadioRxDone, payload, size, rssi, snr); } -static void handle_rx_error(void) +void LoRaMac::handle_rx_error(void) { - ev_queue->call(OnRadioRxError); + ev_queue->call(isrHandler, &LoRaMac::OnRadioRxError); } -static void handle_rx_timeout(void) +void LoRaMac::handle_rx_timeout(void) { - ev_queue->call(OnRadioRxTimeout); + ev_queue->call(isrHandler, &LoRaMac::OnRadioRxTimeout); } -static void handle_tx_timeout(void) +void LoRaMac::handle_tx_timeout(void) { - ev_queue->call(OnRadioTxTimeout); + ev_queue->call(isrHandler, &LoRaMac::OnRadioTxTimeout); } -static void handle_cad_done(bool cad) +void LoRaMac::handle_cad_done(bool cad) { //TODO Not implemented yet - //ev_queue->call(OnRadioCadDone, cad); + //ev_queue->call(isrHandler, &LoRaMac::OnRadioCadDone, cad); } -static void handle_fhss_change_channel(uint8_t cur_channel) +void LoRaMac::handle_fhss_change_channel(uint8_t cur_channel) { // TODO Not implemented yet - //ev_queue->call(OnRadioFHSSChangeChannel, cur_channel); -} -static void handle_mac_state_check_timer_event(void) -{ - ev_queue->call(OnMacStateCheckTimerEvent); + //ev_queue->call(isrHandler, &LoRaMac::OnRadioFHSSChangeChannel, cur_channel); } -static void handle_delayed_tx_timer_event(void) +void LoRaMac::handle_mac_state_check_timer_event(void) { - ev_queue->call(OnTxDelayedTimerEvent); + ev_queue->call(isrHandler, &LoRaMac::OnMacStateCheckTimerEvent); } -static void handle_ack_timeout() +void LoRaMac::handle_delayed_tx_timer_event(void) { - ev_queue->call(OnAckTimeoutTimerEvent); + ev_queue->call(isrHandler, &LoRaMac::OnTxDelayedTimerEvent); } -static void handle_rx1_timer_event(void) +void LoRaMac::handle_ack_timeout() { - ev_queue->call(OnRxWindow1TimerEvent); + ev_queue->call(isrHandler, &LoRaMac::OnAckTimeoutTimerEvent); } -static void handle_rx2_timer_event(void) +void LoRaMac::handle_rx1_timer_event(void) { - ev_queue->call(OnRxWindow2TimerEvent); + ev_queue->call(isrHandler, &LoRaMac::OnRxWindow1TimerEvent); +} + +void LoRaMac::handle_rx2_timer_event(void) +{ + ev_queue->call(isrHandler, &LoRaMac::OnRxWindow2TimerEvent); } /*************************************************************************** * Radio event callbacks - delegated to Radio driver * **************************************************************************/ -static void OnRadioTxDone( void ) +void LoRaMac::OnRadioTxDone( void ) { GetPhyParams_t getPhy; PhyParam_t phyParam; @@ -718,7 +247,7 @@ static void OnRadioTxDone( void ) } else { - handle_rx2_timer_event(); + OpenContinuousRx2Window( ); } // Setup timers @@ -778,7 +307,7 @@ static void OnRadioTxDone( void ) } } -static void PrepareRxDoneAbort( void ) +void LoRaMac::PrepareRxDoneAbort( void ) { LoRaMacState |= LORAMAC_RX_ABORT; @@ -795,7 +324,7 @@ static void PrepareRxDoneAbort( void ) TimerStart( &MacStateCheckTimer ); } -static void OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) +void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) { LoRaMacHeader_t macHdr; LoRaMacFrameCtrl_t fCtrl; @@ -910,7 +439,6 @@ static void OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK; IsLoRaMacNetworkJoined = true; - LoRaMacParams.ChannelsDatarate = LoRaMacParamsDefaults.ChannelsDatarate; } else { @@ -1033,7 +561,7 @@ static void OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK; AdrAckCounter = 0; - MacCommandsBufferToRepeatIndex = 0; + mac_commands.ClearRepeatBuffer(); // Update 32 bits downlink counter if( multicast == 1 ) @@ -1093,12 +621,12 @@ static void OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t { if( fCtrl.Bits.Ack == 1 ) {// Reset MacCommandsBufferIndex when we have received an ACK. - MacCommandsBufferIndex = 0; + mac_commands.ClearCommandBuffer(); } } else {// Reset the variable if we have received any valid frame. - MacCommandsBufferIndex = 0; + mac_commands.ClearCommandBuffer(); } // Process payload and MAC commands @@ -1125,7 +653,9 @@ static void OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t } // Decode frame payload MAC commands - ProcessMacCommands( LoRaMacRxPayload, 0, frameLen, snr ); + mac_commands.ProcessMacCommands( LoRaMacRxPayload, 0, frameLen, snr, + MlmeConfirm, LoRaMacCallbacks, + LoRaMacParams, *lora_phy ); } else { @@ -1137,7 +667,9 @@ static void OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t if( fCtrl.Bits.FOptsLen > 0 ) { // Decode Options field MAC commands. Omit the fPort. - ProcessMacCommands( payload, 8, appPayloadStartIndex - 1, snr ); + mac_commands.ProcessMacCommands( payload, 8, appPayloadStartIndex - 1, snr, + MlmeConfirm, LoRaMacCallbacks, + LoRaMacParams, *lora_phy ); } if (0 != LoRaMacPayloadDecrypt( payload + appPayloadStartIndex, @@ -1163,7 +695,9 @@ static void OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t if( fCtrl.Bits.FOptsLen > 0 ) { // Decode Options field MAC commands - ProcessMacCommands( payload, 8, appPayloadStartIndex, snr ); + mac_commands.ProcessMacCommands( payload, 8, appPayloadStartIndex, snr, + MlmeConfirm, LoRaMacCallbacks, + LoRaMacParams, *lora_phy ); } } @@ -1229,7 +763,7 @@ static void OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t TimerStart( &MacStateCheckTimer ); } -static void OnRadioTxTimeout( void ) +void LoRaMac::OnRadioTxTimeout( void ) { if( LoRaMacDeviceClass != CLASS_C ) { @@ -1237,7 +771,7 @@ static void OnRadioTxTimeout( void ) } else { - handle_rx2_timer_event(); + OpenContinuousRx2Window( ); } McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT; @@ -1245,7 +779,7 @@ static void OnRadioTxTimeout( void ) LoRaMacFlags.Bits.MacDone = 1; } -static void OnRadioRxError( void ) +void LoRaMac::OnRadioRxError( void ) { if( LoRaMacDeviceClass != CLASS_C ) { @@ -1253,10 +787,10 @@ static void OnRadioRxError( void ) } else { - handle_rx2_timer_event(); + OpenContinuousRx2Window( ); } - if( RxSlot == 0 ) + if( RxSlot == RX_SLOT_WIN_1 ) { if( NodeAckRequested == true ) { @@ -1266,6 +800,7 @@ static void OnRadioRxError( void ) if( TimerGetElapsedTime( AggregatedLastTxDoneTime ) >= RxWindow2Delay ) { + TimerStop( &RxWindowTimer2 ); LoRaMacFlags.Bits.MacDone = 1; } } @@ -1280,7 +815,7 @@ static void OnRadioRxError( void ) } } -static void OnRadioRxTimeout( void ) +void LoRaMac::OnRadioRxTimeout( void ) { if( LoRaMacDeviceClass != CLASS_C ) { @@ -1288,10 +823,10 @@ static void OnRadioRxTimeout( void ) } else { - handle_rx2_timer_event(); + OpenContinuousRx2Window( ); } - if( RxSlot == 0 ) + if( RxSlot == RX_SLOT_WIN_1 ) { if( NodeAckRequested == true ) { @@ -1301,6 +836,7 @@ static void OnRadioRxTimeout( void ) if( TimerGetElapsedTime( AggregatedLastTxDoneTime ) >= RxWindow2Delay ) { + TimerStop( &RxWindowTimer2 ); LoRaMacFlags.Bits.MacDone = 1; } } @@ -1322,7 +858,7 @@ static void OnRadioRxTimeout( void ) /*************************************************************************** * Timer event callbacks - deliberated locally * **************************************************************************/ -static void OnMacStateCheckTimerEvent( void ) +void LoRaMac::OnMacStateCheckTimerEvent( void ) { GetPhyParams_t getPhy; PhyParam_t phyParam; @@ -1345,7 +881,7 @@ static void OnMacStateCheckTimerEvent( void ) { // Stop transmit cycle due to tx timeout. LoRaMacState &= ~LORAMAC_TX_RUNNING; - MacCommandsBufferIndex = 0; + mac_commands.ClearCommandBuffer(); McpsConfirm.NbRetries = AckTimeoutRetriesCounter; McpsConfirm.AckReceived = false; McpsConfirm.TxTimeOnAir = 0; @@ -1388,7 +924,7 @@ static void OnMacStateCheckTimerEvent( void ) if( LoRaMacFlags.Bits.McpsInd == 0 ) { // Maximum repetitions without downlink. Reset MacCommandsBufferIndex. Increase ADR Ack counter. // Only process the case when the MAC did not receive a downlink. - MacCommandsBufferIndex = 0; + mac_commands.ClearCommandBuffer(); AdrAckCounter++; } @@ -1452,7 +988,7 @@ static void OnMacStateCheckTimerEvent( void ) // The DR is not applicable for the payload size McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_TX_DR_PAYLOAD_SIZE_ERROR; - MacCommandsBufferIndex = 0; + mac_commands.ClearCommandBuffer(); LoRaMacState &= ~LORAMAC_TX_RUNNING; NodeAckRequested = false; McpsConfirm.AckReceived = false; @@ -1470,7 +1006,7 @@ static void OnMacStateCheckTimerEvent( void ) LoRaMacState &= ~LORAMAC_TX_RUNNING; - MacCommandsBufferIndex = 0; + mac_commands.ClearCommandBuffer(); NodeAckRequested = false; McpsConfirm.AckReceived = false; McpsConfirm.NbRetries = AckTimeoutRetriesCounter; @@ -1490,14 +1026,20 @@ static void OnMacStateCheckTimerEvent( void ) { if( LoRaMacFlags.Bits.McpsReq == 1 ) { - LoRaMacPrimitives->MacMcpsConfirm( &McpsConfirm ); LoRaMacFlags.Bits.McpsReq = 0; + LoRaMacPrimitives->MacMcpsConfirm( &McpsConfirm ); } if( LoRaMacFlags.Bits.MlmeReq == 1 ) { - LoRaMacPrimitives->MacMlmeConfirm( &MlmeConfirm ); LoRaMacFlags.Bits.MlmeReq = 0; + LoRaMacPrimitives->MacMlmeConfirm( &MlmeConfirm ); + } + + // Verify if sticky MAC commands are pending or not + if( mac_commands.IsStickyMacCommandPending( ) == true ) + {// Setup MLME indication + SetMlmeScheduleUplinkIndication( ); } // Procedure done. Reset variables. @@ -1510,22 +1052,30 @@ static void OnMacStateCheckTimerEvent( void ) TimerStart( &MacStateCheckTimer ); } + // Handle MCPS indication if( LoRaMacFlags.Bits.McpsInd == 1 ) { + LoRaMacFlags.Bits.McpsInd = 0; if( LoRaMacDeviceClass == CLASS_C ) {// Activate RX2 window for Class C - handle_rx2_timer_event(); + OpenContinuousRx2Window( ); } if( LoRaMacFlags.Bits.McpsIndSkip == 0 ) { LoRaMacPrimitives->MacMcpsIndication( &McpsIndication ); } LoRaMacFlags.Bits.McpsIndSkip = 0; - LoRaMacFlags.Bits.McpsInd = 0; + } + + // Handle MLME indication + if( LoRaMacFlags.Bits.MlmeInd == 1 ) + { + LoRaMacFlags.Bits.MlmeInd = 0; + LoRaMacPrimitives->MacMlmeIndication( &MlmeIndication ); } } -static void OnTxDelayedTimerEvent( void ) +void LoRaMac::OnTxDelayedTimerEvent( void ) { LoRaMacHeader_t macHdr; LoRaMacFrameCtrl_t fCtrl; @@ -1545,7 +1095,7 @@ static void OnTxDelayedTimerEvent( void ) macHdr.Bits.MType = FRAME_TYPE_JOIN_REQ; fCtrl.Value = 0; - fCtrl.Bits.Adr = AdrCtrlOn; + fCtrl.Bits.Adr = LoRaMacParams.AdrCtrlOn; /* In case of join request retransmissions, the stack must prepare * the frame again, because the network server keeps track of the random @@ -1556,17 +1106,17 @@ static void OnTxDelayedTimerEvent( void ) ScheduleTx( ); } -static void OnRxWindow1TimerEvent( void ) +void LoRaMac::OnRxWindow1TimerEvent( void ) { TimerStop( &RxWindowTimer1 ); - RxSlot = 0; + RxSlot = RX_SLOT_WIN_1; RxWindow1Config.Channel = Channel; RxWindow1Config.DrOffset = LoRaMacParams.Rx1DrOffset; RxWindow1Config.DownlinkDwellTime = LoRaMacParams.DownlinkDwellTime; RxWindow1Config.RepeaterSupport = RepeaterSupport; RxWindow1Config.RxContinuous = false; - RxWindow1Config.Window = RxSlot; + RxWindow1Config.RxSlot = RxSlot; if( LoRaMacDeviceClass == CLASS_C ) { @@ -1577,7 +1127,7 @@ static void OnRxWindow1TimerEvent( void ) RxWindowSetup( RxWindow1Config.RxContinuous, LoRaMacParams.MaxRxWindow ); } -static void OnRxWindow2TimerEvent( void ) +void LoRaMac::OnRxWindow2TimerEvent( void ) { TimerStop( &RxWindowTimer2 ); @@ -1585,7 +1135,7 @@ static void OnRxWindow2TimerEvent( void ) RxWindow2Config.Frequency = LoRaMacParams.Rx2Channel.Frequency; RxWindow2Config.DownlinkDwellTime = LoRaMacParams.DownlinkDwellTime; RxWindow2Config.RepeaterSupport = RepeaterSupport; - RxWindow2Config.Window = 1; + RxWindow2Config.RxSlot = RX_SLOT_WIN_2; if( LoRaMacDeviceClass != CLASS_C ) { @@ -1593,17 +1143,18 @@ static void OnRxWindow2TimerEvent( void ) } else { + // Setup continuous listening for class c RxWindow2Config.RxContinuous = true; } if(lora_phy->rx_config(&RxWindow2Config, ( int8_t* )&McpsIndication.RxDatarate) == true ) { RxWindowSetup( RxWindow2Config.RxContinuous, LoRaMacParams.MaxRxWindow ); - RxSlot = RxWindow2Config.Window; + RxSlot = RX_SLOT_WIN_2; } } -static void OnAckTimeoutTimerEvent( void ) +void LoRaMac::OnAckTimeoutTimerEvent( void ) { TimerStop( &AckTimeoutTimer ); @@ -1618,12 +1169,12 @@ static void OnAckTimeoutTimerEvent( void ) } } -static void RxWindowSetup( bool rxContinuous, uint32_t maxRxWindow ) +void LoRaMac::RxWindowSetup( bool rxContinuous, uint32_t maxRxWindow ) { lora_phy->setup_rx_window(rxContinuous, maxRxWindow); } -static bool ValidatePayloadLength( uint8_t lenN, int8_t datarate, uint8_t fOptsLen ) +bool LoRaMac::ValidatePayloadLength( uint8_t lenN, int8_t datarate, uint8_t fOptsLen ) { GetPhyParams_t getPhy; PhyParam_t phyParam; @@ -1654,339 +1205,15 @@ static bool ValidatePayloadLength( uint8_t lenN, int8_t datarate, uint8_t fOptsL return false; } -static LoRaMacStatus_t AddMacCommand( uint8_t cmd, uint8_t p1, uint8_t p2 ) +void LoRaMac::SetMlmeScheduleUplinkIndication( void ) { - LoRaMacStatus_t status = LORAMAC_STATUS_BUSY; - // The maximum buffer length must take MAC commands to re-send into account. - uint8_t bufLen = LORA_MAC_COMMAND_MAX_LENGTH - MacCommandsBufferToRepeatIndex; - - switch( cmd ) - { - case MOTE_MAC_LINK_CHECK_REQ: - if( MacCommandsBufferIndex < bufLen ) - { - MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; - // No payload for this command - status = LORAMAC_STATUS_OK; - } - break; - case MOTE_MAC_LINK_ADR_ANS: - if( MacCommandsBufferIndex < ( bufLen - 1 ) ) - { - MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; - // Margin - MacCommandsBuffer[MacCommandsBufferIndex++] = p1; - status = LORAMAC_STATUS_OK; - } - break; - case MOTE_MAC_DUTY_CYCLE_ANS: - if( MacCommandsBufferIndex < bufLen ) - { - MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; - // No payload for this answer - status = LORAMAC_STATUS_OK; - } - break; - case MOTE_MAC_RX_PARAM_SETUP_ANS: - if( MacCommandsBufferIndex < ( bufLen - 1 ) ) - { - MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; - // Status: Datarate ACK, Channel ACK - MacCommandsBuffer[MacCommandsBufferIndex++] = p1; - status = LORAMAC_STATUS_OK; - } - break; - case MOTE_MAC_DEV_STATUS_ANS: - if( MacCommandsBufferIndex < ( bufLen - 2 ) ) - { - MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; - // 1st byte Battery - // 2nd byte Margin - MacCommandsBuffer[MacCommandsBufferIndex++] = p1; - MacCommandsBuffer[MacCommandsBufferIndex++] = p2; - status = LORAMAC_STATUS_OK; - } - break; - case MOTE_MAC_NEW_CHANNEL_ANS: - if( MacCommandsBufferIndex < ( bufLen - 1 ) ) - { - MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; - // Status: Datarate range OK, Channel frequency OK - MacCommandsBuffer[MacCommandsBufferIndex++] = p1; - status = LORAMAC_STATUS_OK; - } - break; - case MOTE_MAC_RX_TIMING_SETUP_ANS: - if( MacCommandsBufferIndex < bufLen ) - { - MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; - // No payload for this answer - status = LORAMAC_STATUS_OK; - } - break; - case MOTE_MAC_TX_PARAM_SETUP_ANS: - if( MacCommandsBufferIndex < bufLen ) - { - MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; - // No payload for this answer - status = LORAMAC_STATUS_OK; - } - break; - case MOTE_MAC_DL_CHANNEL_ANS: - if( MacCommandsBufferIndex < bufLen ) - { - MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; - // Status: Uplink frequency exists, Channel frequency OK - MacCommandsBuffer[MacCommandsBufferIndex++] = p1; - status = LORAMAC_STATUS_OK; - } - break; - default: - return LORAMAC_STATUS_SERVICE_UNKNOWN; - } - if( status == LORAMAC_STATUS_OK ) - { - MacCommandsInNextTx = true; - } - return status; -} - -static uint8_t ParseMacCommandsToRepeat( uint8_t* cmdBufIn, uint8_t length, uint8_t* cmdBufOut ) -{ - uint8_t i = 0; - uint8_t cmdCount = 0; - - if( ( cmdBufIn == NULL ) || ( cmdBufOut == NULL ) ) - { - return 0; - } - - for( i = 0; i < length; i++ ) - { - switch( cmdBufIn[i] ) - { - // STICKY - case MOTE_MAC_DL_CHANNEL_ANS: - case MOTE_MAC_RX_PARAM_SETUP_ANS: - { // 1 byte payload - cmdBufOut[cmdCount++] = cmdBufIn[i++]; - cmdBufOut[cmdCount++] = cmdBufIn[i]; - break; - } - case MOTE_MAC_RX_TIMING_SETUP_ANS: - { // 0 byte payload - cmdBufOut[cmdCount++] = cmdBufIn[i]; - break; - } - // NON-STICKY - case MOTE_MAC_DEV_STATUS_ANS: - { // 2 bytes payload - i += 2; - break; - } - case MOTE_MAC_LINK_ADR_ANS: - case MOTE_MAC_NEW_CHANNEL_ANS: - { // 1 byte payload - i++; - break; - } - case MOTE_MAC_TX_PARAM_SETUP_ANS: - case MOTE_MAC_DUTY_CYCLE_ANS: - case MOTE_MAC_LINK_CHECK_REQ: - { // 0 byte payload - break; - } - default: - break; - } - } - - return cmdCount; -} - -static void ProcessMacCommands( uint8_t *payload, uint8_t macIndex, uint8_t commandsSize, uint8_t snr ) -{ - uint8_t status = 0; - - while( macIndex < commandsSize ) - { - // Decode Frame MAC commands - switch( payload[macIndex++] ) - { - case SRV_MAC_LINK_CHECK_ANS: - MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK; - MlmeConfirm.DemodMargin = payload[macIndex++]; - MlmeConfirm.NbGateways = payload[macIndex++]; - break; - case SRV_MAC_LINK_ADR_REQ: - { - LinkAdrReqParams_t linkAdrReq; - int8_t linkAdrDatarate = DR_0; - int8_t linkAdrTxPower = TX_POWER_0; - uint8_t linkAdrNbRep = 0; - uint8_t linkAdrNbBytesParsed = 0; - - // Fill parameter structure - linkAdrReq.Payload = &payload[macIndex - 1]; - linkAdrReq.PayloadSize = commandsSize - ( macIndex - 1 ); - linkAdrReq.AdrEnabled = AdrCtrlOn; - linkAdrReq.UplinkDwellTime = LoRaMacParams.UplinkDwellTime; - linkAdrReq.CurrentDatarate = LoRaMacParams.ChannelsDatarate; - linkAdrReq.CurrentTxPower = LoRaMacParams.ChannelsTxPower; - linkAdrReq.CurrentNbRep = LoRaMacParams.ChannelsNbRep; - - // Process the ADR requests - status = lora_phy->link_ADR_request(&linkAdrReq, &linkAdrDatarate, - &linkAdrTxPower, &linkAdrNbRep, - &linkAdrNbBytesParsed); - - if( ( status & 0x07 ) == 0x07 ) - { - LoRaMacParams.ChannelsDatarate = linkAdrDatarate; - LoRaMacParams.ChannelsTxPower = linkAdrTxPower; - LoRaMacParams.ChannelsNbRep = linkAdrNbRep; - } - - // Add the answers to the buffer - for( uint8_t i = 0; i < ( linkAdrNbBytesParsed / 5 ); i++ ) - { - AddMacCommand( MOTE_MAC_LINK_ADR_ANS, status, 0 ); - } - // Update MAC index - macIndex += linkAdrNbBytesParsed - 1; - } - break; - case SRV_MAC_DUTY_CYCLE_REQ: - MaxDCycle = payload[macIndex++]; - AggregatedDCycle = 1 << MaxDCycle; - AddMacCommand( MOTE_MAC_DUTY_CYCLE_ANS, 0, 0 ); - break; - case SRV_MAC_RX_PARAM_SETUP_REQ: - { - RxParamSetupReqParams_t rxParamSetupReq; - status = 0x07; - - rxParamSetupReq.DrOffset = ( payload[macIndex] >> 4 ) & 0x07; - rxParamSetupReq.Datarate = payload[macIndex] & 0x0F; - macIndex++; - - rxParamSetupReq.Frequency = ( uint32_t )payload[macIndex++]; - rxParamSetupReq.Frequency |= ( uint32_t )payload[macIndex++] << 8; - rxParamSetupReq.Frequency |= ( uint32_t )payload[macIndex++] << 16; - rxParamSetupReq.Frequency *= 100; - - // Perform request on region - status = lora_phy->setup_rx_params(&rxParamSetupReq); - - if( ( status & 0x07 ) == 0x07 ) - { - LoRaMacParams.Rx2Channel.Datarate = rxParamSetupReq.Datarate; - LoRaMacParams.Rx2Channel.Frequency = rxParamSetupReq.Frequency; - LoRaMacParams.Rx1DrOffset = rxParamSetupReq.DrOffset; - } - AddMacCommand( MOTE_MAC_RX_PARAM_SETUP_ANS, status, 0 ); - } - break; - case SRV_MAC_DEV_STATUS_REQ: - { - uint8_t batteryLevel = BAT_LEVEL_NO_MEASURE; - if( ( LoRaMacCallbacks != NULL ) && ( LoRaMacCallbacks->GetBatteryLevel != NULL ) ) - { - batteryLevel = LoRaMacCallbacks->GetBatteryLevel( ); - } - AddMacCommand( MOTE_MAC_DEV_STATUS_ANS, batteryLevel, snr ); - break; - } - case SRV_MAC_NEW_CHANNEL_REQ: - { - NewChannelReqParams_t newChannelReq; - ChannelParams_t chParam; - status = 0x03; - - newChannelReq.ChannelId = payload[macIndex++]; - newChannelReq.NewChannel = &chParam; - - chParam.Frequency = ( uint32_t )payload[macIndex++]; - chParam.Frequency |= ( uint32_t )payload[macIndex++] << 8; - chParam.Frequency |= ( uint32_t )payload[macIndex++] << 16; - chParam.Frequency *= 100; - chParam.Rx1Frequency = 0; - chParam.DrRange.Value = payload[macIndex++]; - - status = lora_phy->request_new_channel(&newChannelReq); - - AddMacCommand( MOTE_MAC_NEW_CHANNEL_ANS, status, 0 ); - } - break; - case SRV_MAC_RX_TIMING_SETUP_REQ: - { - uint8_t delay = payload[macIndex++] & 0x0F; - - if( delay == 0 ) - { - delay++; - } - LoRaMacParams.ReceiveDelay1 = delay * 1000; - LoRaMacParams.ReceiveDelay2 = LoRaMacParams.ReceiveDelay1 + 1000; - AddMacCommand( MOTE_MAC_RX_TIMING_SETUP_ANS, 0, 0 ); - } - break; - case SRV_MAC_TX_PARAM_SETUP_REQ: - { - TxParamSetupReqParams_t txParamSetupReq; - uint8_t eirpDwellTime = payload[macIndex++]; - - txParamSetupReq.UplinkDwellTime = 0; - txParamSetupReq.DownlinkDwellTime = 0; - - if( ( eirpDwellTime & 0x20 ) == 0x20 ) - { - txParamSetupReq.DownlinkDwellTime = 1; - } - if( ( eirpDwellTime & 0x10 ) == 0x10 ) - { - txParamSetupReq.UplinkDwellTime = 1; - } - txParamSetupReq.MaxEirp = eirpDwellTime & 0x0F; - - // Check the status for correctness - if( lora_phy->setup_tx_params(&txParamSetupReq ) != -1 ) - { - // Accept command - LoRaMacParams.UplinkDwellTime = txParamSetupReq.UplinkDwellTime; - LoRaMacParams.DownlinkDwellTime = txParamSetupReq.DownlinkDwellTime; - LoRaMacParams.MaxEirp = LoRaMacMaxEirpTable[txParamSetupReq.MaxEirp]; - // Add command response - AddMacCommand( MOTE_MAC_TX_PARAM_SETUP_ANS, 0, 0 ); - } - } - break; - case SRV_MAC_DL_CHANNEL_REQ: - { - DlChannelReqParams_t dlChannelReq; - status = 0x03; - - dlChannelReq.ChannelId = payload[macIndex++]; - dlChannelReq.Rx1Frequency = ( uint32_t )payload[macIndex++]; - dlChannelReq.Rx1Frequency |= ( uint32_t )payload[macIndex++] << 8; - dlChannelReq.Rx1Frequency |= ( uint32_t )payload[macIndex++] << 16; - dlChannelReq.Rx1Frequency *= 100; - - status = lora_phy->dl_channel_request(&dlChannelReq); - - AddMacCommand( MOTE_MAC_DL_CHANNEL_ANS, status, 0 ); - } - break; - default: - // Unknown command. ABORT MAC commands processing - return; - } - } + MlmeIndication.MlmeIndication = MLME_SCHEDULE_UPLINK; + LoRaMacFlags.Bits.MlmeInd = 1; } // This is not actual transmission. It just schedules a message in response // to MCPS request -LoRaMacStatus_t Send( LoRaMacHeader_t *macHdr, uint8_t fPort, void *fBuffer, uint16_t fBufferSize ) +LoRaMacStatus_t LoRaMac::Send( LoRaMacHeader_t *macHdr, uint8_t fPort, void *fBuffer, uint16_t fBufferSize ) { LoRaMacFrameCtrl_t fCtrl; LoRaMacStatus_t status = LORAMAC_STATUS_PARAMETER_INVALID; @@ -1996,7 +1223,7 @@ LoRaMacStatus_t Send( LoRaMacHeader_t *macHdr, uint8_t fPort, void *fBuffer, uin fCtrl.Bits.FPending = 0; fCtrl.Bits.Ack = false; fCtrl.Bits.AdrAckReq = false; - fCtrl.Bits.Adr = AdrCtrlOn; + fCtrl.Bits.Adr = LoRaMacParams.AdrCtrlOn; // Prepare the frame status = PrepareFrame( macHdr, &fCtrl, fPort, fBuffer, fBufferSize ); @@ -2017,17 +1244,17 @@ LoRaMacStatus_t Send( LoRaMacHeader_t *macHdr, uint8_t fPort, void *fBuffer, uin return status; } -static LoRaMacStatus_t ScheduleTx( void ) +LoRaMacStatus_t LoRaMac::ScheduleTx( void ) { TimerTime_t dutyCycleTimeOff = 0; NextChanParams_t nextChan; // Check if the device is off - if( MaxDCycle == 255 ) + if( LoRaMacParams.MaxDCycle == 255 ) { return LORAMAC_STATUS_DEVICE_OFF; } - if( MaxDCycle == 0 ) + if( LoRaMacParams.MaxDCycle == 0 ) { AggregatedTimeOff = 0; } @@ -2074,7 +1301,7 @@ static LoRaMacStatus_t ScheduleTx( void ) } else { - if( ValidatePayloadLength( LoRaMacTxPayloadLen, LoRaMacParams.ChannelsDatarate, MacCommandsBufferIndex ) == false ) + if( ValidatePayloadLength( LoRaMacTxPayloadLen, LoRaMacParams.ChannelsDatarate, mac_commands.GetLength() ) == false ) { return LORAMAC_STATUS_LENGTH_ERROR; } @@ -2101,7 +1328,7 @@ static LoRaMacStatus_t ScheduleTx( void ) } } -static void CalculateBackOff( uint8_t channel ) +void LoRaMac::CalculateBackOff( uint8_t channel ) { CalcBackOffParams_t calcBackOff; @@ -2117,10 +1344,10 @@ static void CalculateBackOff( uint8_t channel ) lora_phy->calculate_backoff(&calcBackOff); // Update aggregated time-off - AggregatedTimeOff = AggregatedTimeOff + ( TxTimeOnAir * AggregatedDCycle - TxTimeOnAir ); + AggregatedTimeOff = AggregatedTimeOff + ( TxTimeOnAir * LoRaMacParams.AggregatedDCycle - TxTimeOnAir ); } -static void ResetMacParameters( void ) +void LoRaMac::ResetMacParameters( void ) { IsLoRaMacNetworkJoined = false; @@ -2135,11 +1362,12 @@ static void ResetMacParameters( void ) AckTimeoutRetriesCounter = 1; AckTimeoutRetry = false; - MaxDCycle = 0; - AggregatedDCycle = 1; + LoRaMacParams.MaxDCycle = 0; + LoRaMacParams.AggregatedDCycle = 1; - MacCommandsBufferIndex = 0; - MacCommandsBufferToRepeatIndex = 0; + mac_commands.ClearCommandBuffer(); + mac_commands.ClearRepeatBuffer(); + mac_commands.ClearMacCommandsInNextTx(); IsRxWindowsEnabled = true; @@ -2154,7 +1382,6 @@ static void ResetMacParameters( void ) NodeAckRequested = false; SrvAckRequested = false; - MacCommandsInNextTx = false; // Reset Multicast downlink counters MulticastParams_t *cur = MulticastChannels; @@ -2169,7 +1396,22 @@ static void ResetMacParameters( void ) LastTxChannel = Channel; } -void memcpy_convert_endianess( uint8_t *dst, const uint8_t *src, uint16_t size ) +bool LoRaMac::IsFPortAllowed( uint8_t fPort ) +{ + if( ( fPort == 0 ) || ( fPort > 224 ) ) + { + return false; + } + return true; +} + +void LoRaMac::OpenContinuousRx2Window( void ) +{ + handle_rx2_timer_event( ); + RxSlot = RX_SLOT_WIN_CLASS_C; +} + +static void memcpy_convert_endianess( uint8_t *dst, const uint8_t *src, uint16_t size ) { dst = dst + ( size - 1 ); while( size-- ) @@ -2178,7 +1420,7 @@ void memcpy_convert_endianess( uint8_t *dst, const uint8_t *src, uint16_t size ) } } -LoRaMacStatus_t PrepareFrame( LoRaMacHeader_t *macHdr, LoRaMacFrameCtrl_t *fCtrl, uint8_t fPort, void *fBuffer, uint16_t fBufferSize ) +LoRaMacStatus_t LoRaMac::PrepareFrame( LoRaMacHeader_t *macHdr, LoRaMacFrameCtrl_t *fCtrl, uint8_t fPort, void *fBuffer, uint16_t fBufferSize ) { AdrNextParams_t adrNext; uint16_t i; @@ -2230,6 +1472,7 @@ LoRaMacStatus_t PrepareFrame( LoRaMacHeader_t *macHdr, LoRaMacFrameCtrl_t *fCtrl NodeAckRequested = true; //Intentional fallthrough case FRAME_TYPE_DATA_UNCONFIRMED_UP: + { if( IsLoRaMacNetworkJoined == false ) { return LORAMAC_STATUS_NO_NETWORK_JOINED; // No network has been joined yet @@ -2265,48 +1508,46 @@ LoRaMacStatus_t PrepareFrame( LoRaMacHeader_t *macHdr, LoRaMacFrameCtrl_t *fCtrl LoRaMacBuffer[pktHeaderLen++] = ( UpLinkCounter >> 8 ) & 0xFF; // Copy the MAC commands which must be re-send into the MAC command buffer - memcpy( &MacCommandsBuffer[MacCommandsBufferIndex], MacCommandsBufferToRepeat, MacCommandsBufferToRepeatIndex ); - MacCommandsBufferIndex += MacCommandsBufferToRepeatIndex; + mac_commands.CopyRepeatCommandsToBuffer(); + const uint8_t mac_commands_len = mac_commands.GetLength(); if( ( payload != NULL ) && ( LoRaMacTxPayloadLen > 0 ) ) { - if( MacCommandsInNextTx == true ) + if( mac_commands.IsMacCommandsInNextTx() == true ) { - if( MacCommandsBufferIndex <= LORA_MAC_COMMAND_MAX_FOPTS_LENGTH ) + if( mac_commands_len <= LORA_MAC_COMMAND_MAX_FOPTS_LENGTH ) { - fCtrl->Bits.FOptsLen += MacCommandsBufferIndex; + fCtrl->Bits.FOptsLen += mac_commands_len; // Update FCtrl field with new value of OptionsLength LoRaMacBuffer[0x05] = fCtrl->Value; - for( i = 0; i < MacCommandsBufferIndex; i++ ) + + const uint8_t *buffer = mac_commands.GetMacCommandsBuffer(); + for( i = 0; i < mac_commands_len; i++ ) { - LoRaMacBuffer[pktHeaderLen++] = MacCommandsBuffer[i]; + LoRaMacBuffer[pktHeaderLen++] = buffer[i]; } } else { - LoRaMacTxPayloadLen = MacCommandsBufferIndex; - payload = MacCommandsBuffer; + LoRaMacTxPayloadLen = mac_commands_len; + payload = mac_commands.GetMacCommandsBuffer(); framePort = 0; } } } else { - if( ( MacCommandsBufferIndex > 0 ) && ( MacCommandsInNextTx == true ) ) + if( ( mac_commands_len > 0 ) && ( mac_commands.IsMacCommandsInNextTx() == true ) ) { - LoRaMacTxPayloadLen = MacCommandsBufferIndex; - payload = MacCommandsBuffer; + LoRaMacTxPayloadLen = mac_commands_len; + payload = mac_commands.GetMacCommandsBuffer(); framePort = 0; } } - MacCommandsInNextTx = false; + // Store MAC commands which must be re-send in case the device does not receive a downlink anymore - MacCommandsBufferToRepeatIndex = ParseMacCommandsToRepeat( MacCommandsBuffer, MacCommandsBufferIndex, MacCommandsBufferToRepeat ); - if( MacCommandsBufferToRepeatIndex > 0 ) - { - MacCommandsInNextTx = true; - } + mac_commands.ParseMacCommandsToRepeat(); if( ( payload != NULL ) && ( LoRaMacTxPayloadLen > 0 ) ) { @@ -2315,11 +1556,10 @@ LoRaMacStatus_t PrepareFrame( LoRaMacHeader_t *macHdr, LoRaMacFrameCtrl_t *fCtrl if( framePort == 0 ) { // Reset buffer index as the mac commands are being sent on port 0 - MacCommandsBufferIndex = 0; + mac_commands.ClearCommandBuffer(); if (0 != LoRaMacPayloadEncrypt( (uint8_t* ) payload, LoRaMacTxPayloadLen, LoRaMacNwkSKey, LoRaMacDevAddr, UP_LINK, UpLinkCounter, &LoRaMacBuffer[pktHeaderLen] )) { status = LORAMAC_STATUS_CRYPTO_FAIL; } - } else { @@ -2340,8 +1580,8 @@ LoRaMacStatus_t PrepareFrame( LoRaMacHeader_t *macHdr, LoRaMacFrameCtrl_t *fCtrl LoRaMacBuffer[LoRaMacBufferPktLen + 3] = ( mic >> 24 ) & 0xFF; LoRaMacBufferPktLen += LORAMAC_MFR_LEN; - - break; + } + break; case FRAME_TYPE_PROPRIETARY: if( ( fBuffer != NULL ) && ( LoRaMacTxPayloadLen > 0 ) ) { @@ -2356,7 +1596,7 @@ LoRaMacStatus_t PrepareFrame( LoRaMacHeader_t *macHdr, LoRaMacFrameCtrl_t *fCtrl return status; } -LoRaMacStatus_t SendFrameOnChannel( uint8_t channel ) +LoRaMacStatus_t LoRaMac::SendFrameOnChannel( uint8_t channel ) { TxConfigParams_t txConfig; int8_t txPower = 0; @@ -2396,7 +1636,7 @@ LoRaMacStatus_t SendFrameOnChannel( uint8_t channel ) return LORAMAC_STATUS_OK; } -LoRaMacStatus_t SetTxContinuousWave( uint16_t timeout ) +LoRaMacStatus_t LoRaMac::SetTxContinuousWave( uint16_t timeout ) { ContinuousWaveParams_t continuousWave; @@ -2418,7 +1658,7 @@ LoRaMacStatus_t SetTxContinuousWave( uint16_t timeout ) return LORAMAC_STATUS_OK; } -LoRaMacStatus_t SetTxContinuousWave1( uint16_t timeout, uint32_t frequency, uint8_t power ) +LoRaMacStatus_t LoRaMac::SetTxContinuousWave1( uint16_t timeout, uint32_t frequency, uint8_t power ) { lora_phy->setup_tx_cont_wave_mode(frequency, power, timeout); @@ -2431,10 +1671,10 @@ 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, - EventQueue *queue) +LoRaMacStatus_t LoRaMac::LoRaMacInitialization(LoRaMacPrimitives_t *primitives, + LoRaMacCallback_t *callbacks, + LoRaPHY *phy, + EventQueue *queue) { GetPhyParams_t getPhy; PhyParam_t phyParam; @@ -2567,14 +1807,14 @@ LoRaMacStatus_t LoRaMacInitialization(LoRaMacPrimitives_t *primitives, return LORAMAC_STATUS_OK; } -LoRaMacStatus_t LoRaMacQueryTxPossible( uint8_t size, LoRaMacTxInfo_t* txInfo ) +LoRaMacStatus_t LoRaMac::LoRaMacQueryTxPossible( uint8_t size, LoRaMacTxInfo_t* txInfo ) { AdrNextParams_t adrNext; GetPhyParams_t getPhy; PhyParam_t phyParam; int8_t datarate = LoRaMacParamsDefaults.ChannelsDatarate; int8_t txPower = LoRaMacParamsDefaults.ChannelsTxPower; - uint8_t fOptLen = MacCommandsBufferIndex + MacCommandsBufferToRepeatIndex; + uint8_t fOptLen = mac_commands.GetLength() + mac_commands.GetRepeatLength(); if( txInfo == NULL ) { @@ -2583,7 +1823,7 @@ LoRaMacStatus_t LoRaMacQueryTxPossible( uint8_t size, LoRaMacTxInfo_t* txInfo ) // Setup ADR request adrNext.UpdateChanMask = false; - adrNext.AdrEnabled = AdrCtrlOn; + adrNext.AdrEnabled = LoRaMacParams.AdrCtrlOn; adrNext.AdrAckCounter = AdrAckCounter; adrNext.Datarate = LoRaMacParams.ChannelsDatarate; adrNext.TxPower = LoRaMacParams.ChannelsTxPower; @@ -2617,8 +1857,8 @@ LoRaMacStatus_t LoRaMacQueryTxPossible( uint8_t size, LoRaMacTxInfo_t* txInfo ) // The fOpts don't fit into the maximum payload. Omit the MAC commands to // ensure that another uplink is possible. fOptLen = 0; - MacCommandsBufferIndex = 0; - MacCommandsBufferToRepeatIndex = 0; + mac_commands.ClearCommandBuffer(); + mac_commands.ClearRepeatBuffer(); } // Verify if the fOpts and the payload fit into the maximum payload @@ -2629,7 +1869,7 @@ LoRaMacStatus_t LoRaMacQueryTxPossible( uint8_t size, LoRaMacTxInfo_t* txInfo ) return LORAMAC_STATUS_OK; } -LoRaMacStatus_t LoRaMacMibGetRequestConfirm( MibRequestConfirm_t *mibGet ) +LoRaMacStatus_t LoRaMac::LoRaMacMibGetRequestConfirm( MibRequestConfirm_t *mibGet ) { LoRaMacStatus_t status = LORAMAC_STATUS_OK; GetPhyParams_t getPhy; @@ -2654,7 +1894,7 @@ LoRaMacStatus_t LoRaMacMibGetRequestConfirm( MibRequestConfirm_t *mibGet ) } case MIB_ADR: { - mibGet->Param.AdrEnable = AdrCtrlOn; + mibGet->Param.AdrEnable = LoRaMacParams.AdrCtrlOn; break; } case MIB_NET_ID: @@ -2809,7 +2049,7 @@ LoRaMacStatus_t LoRaMacMibGetRequestConfirm( MibRequestConfirm_t *mibGet ) return status; } -LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSet ) +LoRaMacStatus_t LoRaMac::LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSet ) { LoRaMacStatus_t status = LORAMAC_STATUS_OK; ChanMaskSetParams_t chanMaskSet; @@ -2841,7 +2081,14 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSet ) { // Set the NodeAckRequested indicator to default NodeAckRequested = false; - handle_rx2_timer_event(); + // Set the radio into sleep mode in case we are still in RX mode + lora_phy->put_radio_to_sleep(); + // Compute Rx2 windows parameters in case the RX2 datarate has changed + lora_phy->compute_rx_win_params( LoRaMacParams.Rx2Channel.Datarate, + LoRaMacParams.MinRxSymbols, + LoRaMacParams.SystemMaxRxError, + &RxWindow2Config ); + OpenContinuousRx2Window( ); break; } } @@ -2854,7 +2101,7 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSet ) } case MIB_ADR: { - AdrCtrlOn = mibSet->Param.AdrEnable; + LoRaMacParams.AdrCtrlOn = mibSet->Param.AdrEnable; break; } case MIB_NET_ID: @@ -2915,28 +2162,18 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSet ) if( ( LoRaMacDeviceClass == CLASS_C ) && ( IsLoRaMacNetworkJoined == true ) ) { + // We can only compute the RX window parameters directly, if we are already + // in class c mode and joined. We cannot setup an RX window in case of any other + // class type. + // Set the radio into sleep mode in case we are still in RX mode + lora_phy->put_radio_to_sleep(); // Compute Rx2 windows parameters lora_phy->compute_rx_win_params(LoRaMacParams.Rx2Channel.Datarate, LoRaMacParams.MinRxSymbols, LoRaMacParams.SystemMaxRxError, &RxWindow2Config); - RxWindow2Config.Channel = Channel; - RxWindow2Config.Frequency = LoRaMacParams.Rx2Channel.Frequency; - RxWindow2Config.DownlinkDwellTime = LoRaMacParams.DownlinkDwellTime; - RxWindow2Config.RepeaterSupport = RepeaterSupport; - RxWindow2Config.Window = 1; - RxWindow2Config.RxContinuous = true; - - if(lora_phy->rx_config(&RxWindow2Config, ( int8_t* )&McpsIndication.RxDatarate) == true ) - { - RxWindowSetup( RxWindow2Config.RxContinuous, LoRaMacParams.MaxRxWindow ); - RxSlot = RxWindow2Config.Window; - } - else - { - status = LORAMAC_STATUS_PARAMETER_INVALID; - } + OpenContinuousRx2Window( ); } } else @@ -3037,6 +2274,7 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSet ) case MIB_CHANNELS_DATARATE: { verify.DatarateParams.Datarate = mibSet->Param.ChannelsDatarate; + verify.DatarateParams.UplinkDwellTime = LoRaMacParams.UplinkDwellTime; if(lora_phy->verify(&verify, PHY_TX_DR) == true) { @@ -3109,7 +2347,7 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSet ) return status; } -LoRaMacStatus_t LoRaMacChannelAdd( uint8_t id, ChannelParams_t params ) +LoRaMacStatus_t LoRaMac::LoRaMacChannelAdd( uint8_t id, ChannelParams_t params ) { ChannelAddParams_t channelAdd; @@ -3128,7 +2366,7 @@ LoRaMacStatus_t LoRaMacChannelAdd( uint8_t id, ChannelParams_t params ) return lora_phy->add_channel(&channelAdd); } -LoRaMacStatus_t LoRaMacChannelRemove( uint8_t id ) +LoRaMacStatus_t LoRaMac::LoRaMacChannelRemove( uint8_t id ) { ChannelRemoveParams_t channelRemove; @@ -3152,7 +2390,7 @@ LoRaMacStatus_t LoRaMacChannelRemove( uint8_t id ) return LORAMAC_STATUS_OK; } -LoRaMacStatus_t LoRaMacMulticastChannelLink( MulticastParams_t *channelParam ) +LoRaMacStatus_t LoRaMac::LoRaMacMulticastChannelLink( MulticastParams_t *channelParam ) { if( channelParam == NULL ) { @@ -3187,7 +2425,7 @@ LoRaMacStatus_t LoRaMacMulticastChannelLink( MulticastParams_t *channelParam ) return LORAMAC_STATUS_OK; } -LoRaMacStatus_t LoRaMacMulticastChannelUnlink( MulticastParams_t *channelParam ) +LoRaMacStatus_t LoRaMac::LoRaMacMulticastChannelUnlink( MulticastParams_t *channelParam ) { if( channelParam == NULL ) { @@ -3226,7 +2464,7 @@ LoRaMacStatus_t LoRaMacMulticastChannelUnlink( MulticastParams_t *channelParam ) return LORAMAC_STATUS_OK; } -LoRaMacStatus_t LoRaMacMlmeRequest( MlmeReq_t *mlmeRequest ) +LoRaMacStatus_t LoRaMac::LoRaMacMlmeRequest( MlmeReq_t *mlmeRequest ) { LoRaMacStatus_t status = LORAMAC_STATUS_SERVICE_UNKNOWN; LoRaMacHeader_t macHdr; @@ -3239,7 +2477,7 @@ LoRaMacStatus_t LoRaMacMlmeRequest( MlmeReq_t *mlmeRequest ) { return LORAMAC_STATUS_PARAMETER_INVALID; } - if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) + if( LoRaMacState != LORAMAC_IDLE ) { return LORAMAC_STATUS_BUSY; } @@ -3303,10 +2541,10 @@ LoRaMacStatus_t LoRaMacMlmeRequest( MlmeReq_t *mlmeRequest ) case MLME_LINK_CHECK: { LoRaMacFlags.Bits.MlmeReq = 1; - // LoRaMac will send this command piggy-pack + // LoRaMac will send this command piggy-backed MlmeConfirm.MlmeRequest = mlmeRequest->Type; - status = AddMacCommand( MOTE_MAC_LINK_CHECK_REQ, 0, 0 ); + status = mac_commands.AddMacCommand( MOTE_MAC_LINK_CHECK_REQ, 0, 0 ); break; } case MLME_TXCW: @@ -3336,7 +2574,7 @@ LoRaMacStatus_t LoRaMacMlmeRequest( MlmeReq_t *mlmeRequest ) return status; } -LoRaMacStatus_t LoRaMacMcpsRequest( McpsReq_t *mcpsRequest ) +LoRaMacStatus_t LoRaMac::LoRaMacMcpsRequest( McpsReq_t *mcpsRequest ) { GetPhyParams_t getPhy; PhyParam_t phyParam; @@ -3346,15 +2584,14 @@ LoRaMacStatus_t LoRaMacMcpsRequest( McpsReq_t *mcpsRequest ) uint8_t fPort = 0; void *fBuffer; uint16_t fBufferSize; - int8_t datarate; + int8_t datarate = DR_0; bool readyToSend = false; if( mcpsRequest == NULL ) { return LORAMAC_STATUS_PARAMETER_INVALID; } - if( ( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) || - ( ( LoRaMacState & LORAMAC_TX_DELAYED ) == LORAMAC_TX_DELAYED ) ) + if( LoRaMacState != LORAMAC_IDLE ) { return LORAMAC_STATUS_BUSY; } @@ -3407,6 +2644,13 @@ LoRaMacStatus_t LoRaMacMcpsRequest( McpsReq_t *mcpsRequest ) break; } + // Filter fPorts + // TODO: Does not work with PROPRIETARY messages +// if( IsFPortAllowed( fPort ) == false ) +// { +// return LORAMAC_STATUS_PARAMETER_INVALID; +// } + // Get the minimum possible datarate getPhy.Attribute = PHY_MIN_TX_DR; getPhy.UplinkDwellTime = LoRaMacParams.UplinkDwellTime; @@ -3417,7 +2661,7 @@ LoRaMacStatus_t LoRaMacMcpsRequest( McpsReq_t *mcpsRequest ) if( readyToSend == true ) { - if( AdrCtrlOn == false ) + if( LoRaMacParams.AdrCtrlOn == false ) { verify.DatarateParams.Datarate = datarate; verify.DatarateParams.UplinkDwellTime = LoRaMacParams.UplinkDwellTime; @@ -3447,13 +2691,13 @@ LoRaMacStatus_t LoRaMacMcpsRequest( McpsReq_t *mcpsRequest ) return status; } -radio_events_t *GetPhyEventHandlers() +radio_events_t *LoRaMac::GetPhyEventHandlers() { - RadioEvents.tx_done = handle_tx_done; - RadioEvents.rx_done = handle_rx_done; - RadioEvents.rx_error = handle_rx_error; - RadioEvents.tx_timeout = handle_tx_timeout; - RadioEvents.rx_timeout = handle_rx_timeout; + RadioEvents.tx_done = mbed::callback(handle_tx_done); + RadioEvents.rx_done = mbed::callback(handle_rx_done); + RadioEvents.rx_error = mbed::callback(handle_rx_error); + RadioEvents.tx_timeout = mbed::callback(handle_tx_timeout); + RadioEvents.rx_timeout = mbed::callback(handle_rx_timeout); return &RadioEvents; } @@ -3479,18 +2723,18 @@ LoRaMacStatus_t LoRaMac::LoRaMacStopTxTimer( ) return LORAMAC_STATUS_OK; } -void LoRaMacTestRxWindowsOn( bool enable ) +void LoRaMac::LoRaMacTestRxWindowsOn( bool enable ) { IsRxWindowsEnabled = enable; } -void LoRaMacTestSetMic( uint16_t txPacketCounter ) +void LoRaMac::LoRaMacTestSetMic( uint16_t txPacketCounter ) { UpLinkCounter = txPacketCounter; IsUpLinkCounterFixed = true; } -void LoRaMacTestSetDutyCycleOn( bool enable ) +void LoRaMac::LoRaMacTestSetDutyCycleOn( bool enable ) { VerifyParams_t verify; @@ -3502,7 +2746,7 @@ void LoRaMacTestSetDutyCycleOn( bool enable ) } } -void LoRaMacTestSetChannel( uint8_t channel ) +void LoRaMac::LoRaMacTestSetChannel( uint8_t channel ) { Channel = channel; } diff --git a/features/lorawan/lorastack/mac/LoRaMac.h b/features/lorawan/lorastack/mac/LoRaMac.h index 534e2930f4..09381e52f9 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.h +++ b/features/lorawan/lorastack/mac/LoRaMac.h @@ -44,317 +44,879 @@ #include "netsocket/LoRaRadio.h" #include "lorastack/phy/LoRaPHY.h" #include "lorawan/system/lorawan_data_structures.h" - -/*! - * Check the MAC layer state every MAC_STATE_CHECK_TIMEOUT in ms. - */ -#define MAC_STATE_CHECK_TIMEOUT 1000 - -/*! - * The maximum number of times the MAC layer tries to get an acknowledge. - */ -#define MAX_ACK_RETRIES 8 - -/*! - * The frame direction definition for uplink communications. - */ -#define UP_LINK 0 - -/*! - * The frame direction definition for downlink communications. - */ -#define DOWN_LINK 1 +#include "LoRaMacCommand.h" +#include "events/EventQueue.h" /*! - * LoRaMAC max EIRP (dBm) table. + * Maximum PHY layer payload size */ -static const uint8_t LoRaMacMaxEirpTable[] = { 8, 10, 12, 13, 14, 16, 18, 20, 21, 24, 26, 27, 29, 30, 33, 36 }; +#define LORAMAC_PHY_MAXPAYLOAD 255 -/*! - * \brief LoRaMAC layer initialization - * - * \details In addition to the initialization of the LoRaMAC layer, this - * function initializes the callback primitives of the MCPS and - * MLME services. Every data field of \ref LoRaMacPrimitives_t must be - * set to a valid callback function. - * - * \param primitives [in] - A pointer to the structure defining the LoRaMAC - * event functions. Refer to \ref LoRaMacPrimitives_t. - * - * \param callbacks [in] - A pointer to the structure defining the LoRaMAC - * callback functions. Refer to \ref LoRaMacCallback_t. - * - * \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, - events::EventQueue *queue); +class LoRaMac +{ +public: + /*! + * \brief Constructor + */ + LoRaMac(); -/*! - * \brief Queries the LoRaMAC whether it is possible to send the next frame with - * a given payload size. The LoRaMAC takes the scheduled MAC commands into - * account and reports when the frame can be sent. - * - * \param size [in]- The size of the applicable payload to be sent next. - * \param txInfo [out] - The structure \ref LoRaMacTxInfo_t contains - * information on the actual maximum payload possible - * (according to the configured datarate or the next - * datarate according to ADR), and the maximum frame - * size, taking the scheduled MAC commands into account. - * - * \retval `LoRaMacStatus_t` The status of the operation. When the parameters are - * not valid, the function returns \ref LORAMAC_STATUS_PARAMETER_INVALID. - * In case of a length error caused by the applicable payload in combination - * with the MAC commands, the function returns \ref LORAMAC_STATUS_LENGTH_ERROR. - * Please note that if the size of the MAC commands in the queue do - * not fit into the payload size on the related datarate, the LoRaMAC will - * omit the MAC commands. - * If the query is valid, and the LoRaMAC is able to send the frame, - * the function returns \ref LORAMAC_STATUS_OK. - */ -LoRaMacStatus_t LoRaMacQueryTxPossible( uint8_t size, LoRaMacTxInfo_t* txInfo ); + /*! + * \brief Destructor + */ + ~LoRaMac(); -/*! - * \brief LoRaMAC channel add service. - * - * \details Adds a new channel to the channel list and activates the ID in - * the channel mask. Please note that this functionality is not available - * in all regions. Information on the allowed ranges is available at the LoRaWAN Regional Parameters V1.0.2rB. - * - * \param id [in] - The ID of the channel. - * - * \param params [in] - The channel parameters to set. - * - * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: - * \ref LORAMAC_STATUS_OK - * \ref LORAMAC_STATUS_BUSY - * \ref LORAMAC_STATUS_PARAMETER_INVALID - */ -LoRaMacStatus_t LoRaMacChannelAdd( uint8_t id, ChannelParams_t params ); + /*! + * \brief LoRaMAC layer initialization + * + * \details In addition to the initialization of the LoRaMAC layer, this + * function initializes the callback primitives of the MCPS and + * MLME services. Every data field of \ref LoRaMacPrimitives_t must be + * set to a valid callback function. + * + * \param primitives [in] - A pointer to the structure defining the LoRaMAC + * event functions. Refer to \ref LoRaMacPrimitives_t. + * + * \param callbacks [in] - A pointer to the structure defining the LoRaMAC + * callback functions. Refer to \ref LoRaMacCallback_t. + * + * \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, + events::EventQueue *queue); -/*! - * \brief LoRaMAC channel remove service. - * - * \details Deactivates the ID in the channel mask. - * - * \param id - Id of the channel. - * - * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: - * \ref LORAMAC_STATUS_OK - * \ref LORAMAC_STATUS_BUSY - * \ref LORAMAC_STATUS_PARAMETER_INVALID - */ -LoRaMacStatus_t LoRaMacChannelRemove( uint8_t id ); + /*! + * \brief Queries the LoRaMAC whether it is possible to send the next frame with + * a given payload size. The LoRaMAC takes the scheduled MAC commands into + * account and reports when the frame can be sent. + * + * \param size [in]- The size of the applicable payload to be sent next. + * \param txInfo [out] - The structure \ref LoRaMacTxInfo_t contains + * information on the actual maximum payload possible + * (according to the configured datarate or the next + * datarate according to ADR), and the maximum frame + * size, taking the scheduled MAC commands into account. + * + * \retval `LoRaMacStatus_t` The status of the operation. When the parameters are + * not valid, the function returns \ref LORAMAC_STATUS_PARAMETER_INVALID. + * In case of a length error caused by the applicable payload in combination + * with the MAC commands, the function returns \ref LORAMAC_STATUS_LENGTH_ERROR. + * Please note that if the size of the MAC commands in the queue do + * not fit into the payload size on the related datarate, the LoRaMAC will + * omit the MAC commands. + * If the query is valid, and the LoRaMAC is able to send the frame, + * the function returns \ref LORAMAC_STATUS_OK. + */ + LoRaMacStatus_t LoRaMacQueryTxPossible( uint8_t size, LoRaMacTxInfo_t* txInfo ); -/*! - * \brief LoRaMAC multicast channel link service. - * - * \details Links a multicast channel into the linked list. - * - * \param [in] channelParam - The multicast channel parameters to link. - * - * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: - * \ref LORAMAC_STATUS_OK - * \ref LORAMAC_STATUS_BUSY - * \ref LORAMAC_STATUS_PARAMETER_INVALID - */ -LoRaMacStatus_t LoRaMacMulticastChannelLink( MulticastParams_t *channelParam ); + /*! + * \brief LoRaMAC channel add service. + * + * \details Adds a new channel to the channel list and activates the ID in + * the channel mask. Please note that this functionality is not available + * in all regions. Information on the allowed ranges is available at the LoRaWAN Regional Parameters V1.0.2rB. + * + * \param id [in] - The ID of the channel. + * + * \param params [in] - The channel parameters to set. + * + * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: + * \ref LORAMAC_STATUS_OK + * \ref LORAMAC_STATUS_BUSY + * \ref LORAMAC_STATUS_PARAMETER_INVALID + */ + LoRaMacStatus_t LoRaMacChannelAdd( uint8_t id, ChannelParams_t params ); -/*! - * \brief LoRaMAC multicast channel unlink service. - * - * \details Unlinks a multicast channel from the linked list. - * - * \param [in] channelParam - The multicast channel parameters to unlink. - * - * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: - * \ref LORAMAC_STATUS_OK - * \ref LORAMAC_STATUS_BUSY - * \ref LORAMAC_STATUS_PARAMETER_INVALID - */ -LoRaMacStatus_t LoRaMacMulticastChannelUnlink( MulticastParams_t *channelParam ); + /*! + * \brief LoRaMAC channel remove service. + * + * \details Deactivates the ID in the channel mask. + * + * \param id - Id of the channel. + * + * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: + * \ref LORAMAC_STATUS_OK + * \ref LORAMAC_STATUS_BUSY + * \ref LORAMAC_STATUS_PARAMETER_INVALID + */ + LoRaMacStatus_t LoRaMacChannelRemove( uint8_t id ); -/*! - * \brief LoRaMAC MIB-GET. - * - * \details The MAC information base service to get the attributes of the LoRaMac layer. - * - * The following code-snippet shows how to use the API to get the - * parameter `AdrEnable`, defined by the enumeration type - * \ref MIB_ADR. - * \code - * MibRequestConfirm_t mibReq; - * mibReq.Type = MIB_ADR; - * - * if( LoRaMacMibGetRequestConfirm( &mibReq ) == LORAMAC_STATUS_OK ) - * { - * // LoRaMAC updated the parameter mibParam.AdrEnable - * } - * \endcode - * - * \param [in] mibGet - The MIB-GET request to perform. Refer to \ref MibRequestConfirm_t. - * - * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: - * \ref LORAMAC_STATUS_OK - * \ref LORAMAC_STATUS_SERVICE_UNKNOWN - * \ref LORAMAC_STATUS_PARAMETER_INVALID - */ -LoRaMacStatus_t LoRaMacMibGetRequestConfirm( MibRequestConfirm_t *mibGet ); + /*! + * \brief LoRaMAC multicast channel link service. + * + * \details Links a multicast channel into the linked list. + * + * \param [in] channelParam - The multicast channel parameters to link. + * + * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: + * \ref LORAMAC_STATUS_OK + * \ref LORAMAC_STATUS_BUSY + * \ref LORAMAC_STATUS_PARAMETER_INVALID + */ + LoRaMacStatus_t LoRaMacMulticastChannelLink( MulticastParams_t *channelParam ); -/*! - * \brief LoRaMAC MIB-SET. - * - * \details The MAC information base service to set the attributes of the LoRaMac layer. - * - * The following code-snippet shows how to use the API to set the - * parameter `AdrEnable`, defined by the enumeration type - * \ref MIB_ADR. - * - * \code - * MibRequestConfirm_t mibReq; - * mibReq.Type = MIB_ADR; - * mibReq.Param.AdrEnable = true; - * - * if( LoRaMacMibGetRequestConfirm( &mibReq ) == LORAMAC_STATUS_OK ) - * { - * // LoRaMAC updated the parameter - * } - * \endcode - * - * \param [in] mibSet - The MIB-SET request to perform. Refer to \ref MibRequestConfirm_t. - * - * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: - * \ref LORAMAC_STATUS_OK - * \ref LORAMAC_STATUS_BUSY - * \ref LORAMAC_STATUS_SERVICE_UNKNOWN - * \ref LORAMAC_STATUS_PARAMETER_INVALID - */ -LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSet ); + /*! + * \brief LoRaMAC multicast channel unlink service. + * + * \details Unlinks a multicast channel from the linked list. + * + * \param [in] channelParam - The multicast channel parameters to unlink. + * + * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: + * \ref LORAMAC_STATUS_OK + * \ref LORAMAC_STATUS_BUSY + * \ref LORAMAC_STATUS_PARAMETER_INVALID + */ + LoRaMacStatus_t LoRaMacMulticastChannelUnlink( MulticastParams_t *channelParam ); -/*! - * \brief LoRaMAC MLME request - * - * \details The MAC layer management entity handles the management services. The - * following code-snippet shows how to use the API to perform a - * network join request. - * - * \code - * static uint8_t DevEui[] = - * { - * 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - * }; - * static uint8_t AppEui[] = - * { - * 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - * }; - * static uint8_t AppKey[] = - * { - * 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, - * 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C - * }; - * - * MlmeReq_t mlmeReq; - * mlmeReq.Type = MLME_JOIN; - * mlmeReq.Req.Join.DevEui = DevEui; - * mlmeReq.Req.Join.AppEui = AppEui; - * mlmeReq.Req.Join.AppKey = AppKey; - * - * if( LoRaMacMlmeRequest( &mlmeReq ) == LORAMAC_STATUS_OK ) - * { - * // Service started successfully. Waiting for the Mlme-Confirm event - * } - * \endcode - * - * \param [in] mlmeRequest - The MLME request to perform. Refer to \ref MlmeReq_t. - * - * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: - * \ref LORAMAC_STATUS_OK - * \ref LORAMAC_STATUS_BUSY - * \ref LORAMAC_STATUS_SERVICE_UNKNOWN - * \ref LORAMAC_STATUS_PARAMETER_INVALID - * \ref LORAMAC_STATUS_NO_NETWORK_JOINED - * \ref LORAMAC_STATUS_LENGTH_ERROR - * \ref LORAMAC_STATUS_DEVICE_OFF - */ -LoRaMacStatus_t LoRaMacMlmeRequest( MlmeReq_t *mlmeRequest ); + /*! + * \brief LoRaMAC MIB-GET. + * + * \details The MAC information base service to get the attributes of the LoRaMac layer. + * + * The following code-snippet shows how to use the API to get the + * parameter `AdrEnable`, defined by the enumeration type + * \ref MIB_ADR. + * \code + * MibRequestConfirm_t mibReq; + * mibReq.Type = MIB_ADR; + * + * if( LoRaMacMibGetRequestConfirm( &mibReq ) == LORAMAC_STATUS_OK ) + * { + * // LoRaMAC updated the parameter mibParam.AdrEnable + * } + * \endcode + * + * \param [in] mibGet - The MIB-GET request to perform. Refer to \ref MibRequestConfirm_t. + * + * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: + * \ref LORAMAC_STATUS_OK + * \ref LORAMAC_STATUS_SERVICE_UNKNOWN + * \ref LORAMAC_STATUS_PARAMETER_INVALID + */ + LoRaMacStatus_t LoRaMacMibGetRequestConfirm( MibRequestConfirm_t *mibGet ); -/*! - * \brief LoRaMAC MCPS request - * - * \details The MAC Common Part Sublayer handles the data services. The following - * code-snippet shows how to use the API to send an unconfirmed - * LoRaMAC frame. - * - * \code - * uint8_t myBuffer[] = { 1, 2, 3 }; - * - * McpsReq_t mcpsReq; - * mcpsReq.Type = MCPS_UNCONFIRMED; - * mcpsReq.Req.Unconfirmed.fPort = 1; - * mcpsReq.Req.Unconfirmed.fBuffer = myBuffer; - * mcpsReq.Req.Unconfirmed.fBufferSize = sizeof( myBuffer ); - * - * if( LoRaMacMcpsRequest( &mcpsReq ) == LORAMAC_STATUS_OK ) - * { - * // Service started successfully. Waiting for the MCPS-Confirm event - * } - * \endcode - * - * \param [in] mcpsRequest - The MCPS request to perform. Refer to \ref McpsReq_t. - * - * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: - * \ref LORAMAC_STATUS_OK - * \ref LORAMAC_STATUS_BUSY - * \ref LORAMAC_STATUS_SERVICE_UNKNOWN - * \ref LORAMAC_STATUS_PARAMETER_INVALID - * \ref LORAMAC_STATUS_NO_NETWORK_JOINED - * \ref LORAMAC_STATUS_LENGTH_ERROR - * \ref LORAMAC_STATUS_DEVICE_OFF - */ -LoRaMacStatus_t LoRaMacMcpsRequest( McpsReq_t *mcpsRequest ); + /*! + * \brief LoRaMAC MIB-SET. + * + * \details The MAC information base service to set the attributes of the LoRaMac layer. + * + * The following code-snippet shows how to use the API to set the + * parameter `AdrEnable`, defined by the enumeration type + * \ref MIB_ADR. + * + * \code + * MibRequestConfirm_t mibReq; + * mibReq.Type = MIB_ADR; + * mibReq.Param.AdrEnable = true; + * + * if( LoRaMacMibGetRequestConfirm( &mibReq ) == LORAMAC_STATUS_OK ) + * { + * // LoRaMAC updated the parameter + * } + * \endcode + * + * \param [in] mibSet - The MIB-SET request to perform. Refer to \ref MibRequestConfirm_t. + * + * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: + * \ref LORAMAC_STATUS_OK + * \ref LORAMAC_STATUS_BUSY + * \ref LORAMAC_STATUS_SERVICE_UNKNOWN + * \ref LORAMAC_STATUS_PARAMETER_INVALID + */ + LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSet ); -/** - * \brief LoRaMAC layer provides its callback functions for - * PHY layer - * - * \return Pointer to callback functions for radio events - */ -radio_events_t *GetPhyEventHandlers(); + /*! + * \brief LoRaMAC MLME request + * + * \details The MAC layer management entity handles the management services. The + * following code-snippet shows how to use the API to perform a + * network join request. + * + * \code + * static uint8_t DevEui[] = + * { + * 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + * }; + * static uint8_t AppEui[] = + * { + * 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + * }; + * static uint8_t AppKey[] = + * { + * 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, + * 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C + * }; + * + * MlmeReq_t mlmeReq; + * mlmeReq.Type = MLME_JOIN; + * mlmeReq.Req.Join.DevEui = DevEui; + * mlmeReq.Req.Join.AppEui = AppEui; + * mlmeReq.Req.Join.AppKey = AppKey; + * + * if( LoRaMacMlmeRequest( &mlmeReq ) == LORAMAC_STATUS_OK ) + * { + * // Service started successfully. Waiting for the Mlme-Confirm event + * } + * \endcode + * + * \param [in] mlmeRequest - The MLME request to perform. Refer to \ref MlmeReq_t. + * + * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: + * \ref LORAMAC_STATUS_OK + * \ref LORAMAC_STATUS_BUSY + * \ref LORAMAC_STATUS_SERVICE_UNKNOWN + * \ref LORAMAC_STATUS_PARAMETER_INVALID + * \ref LORAMAC_STATUS_NO_NETWORK_JOINED + * \ref LORAMAC_STATUS_LENGTH_ERROR + * \ref LORAMAC_STATUS_DEVICE_OFF + */ + LoRaMacStatus_t LoRaMacMlmeRequest( MlmeReq_t *mlmeRequest ); + + /*! + * \brief LoRaMAC MCPS request + * + * \details The MAC Common Part Sublayer handles the data services. The following + * code-snippet shows how to use the API to send an unconfirmed + * LoRaMAC frame. + * + * \code + * uint8_t myBuffer[] = { 1, 2, 3 }; + * + * McpsReq_t mcpsReq; + * mcpsReq.Type = MCPS_UNCONFIRMED; + * mcpsReq.Req.Unconfirmed.fPort = 1; + * mcpsReq.Req.Unconfirmed.fBuffer = myBuffer; + * mcpsReq.Req.Unconfirmed.fBufferSize = sizeof( myBuffer ); + * + * if( LoRaMacMcpsRequest( &mcpsReq ) == LORAMAC_STATUS_OK ) + * { + * // Service started successfully. Waiting for the MCPS-Confirm event + * } + * \endcode + * + * \param [in] mcpsRequest - The MCPS request to perform. Refer to \ref McpsReq_t. + * + * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: + * \ref LORAMAC_STATUS_OK + * \ref LORAMAC_STATUS_BUSY + * \ref LORAMAC_STATUS_SERVICE_UNKNOWN + * \ref LORAMAC_STATUS_PARAMETER_INVALID + * \ref LORAMAC_STATUS_NO_NETWORK_JOINED + * \ref LORAMAC_STATUS_LENGTH_ERROR + * \ref LORAMAC_STATUS_DEVICE_OFF + */ + LoRaMacStatus_t LoRaMacMcpsRequest( McpsReq_t *mcpsRequest ); + + /** + * \brief LoRaMAC layer provides its callback functions for + * PHY layer + * + * \return Pointer to callback functions for radio events + */ + radio_events_t *GetPhyEventHandlers(); + + /*! + * \brief Configures the events to trigger an MLME-Indication with + * a MLME type of MLME_SCHEDULE_UPLINK. + */ + void SetMlmeScheduleUplinkIndication( void ); #if defined(LORAWAN_COMPLIANCE_TEST) -/** - * \brief LoRaMAC set tx timer. - * - * \details Sets up a timer for next transmission (application specific timers). - * - * \param [in] NextTxTime - Periodic time for next uplink. +public: // Test interface - * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: - * \ref LORAMAC_STATUS_OK - * \ref LORAMAC_STATUS_PARAMETER_INVALID - */ -LoRaMacStatus_t LoRaMacSetTxTimer( uint32_t NextTxTime ); + /** + * \brief LoRaMAC set tx timer. + * + * \details Sets up a timer for next transmission (application specific timers). + * + * \param [in] NextTxTime - Periodic time for next uplink. -/** - * \brief LoRaMAC stop tx timer. - * - * \details Stops the next tx timer. - * - * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: - * \ref LORAMAC_STATUS_OK - * \ref LORAMAC_STATUS_PARAMETER_INVALID - */ -LoRaMacStatus_t LoRaMacStopTxTimer( ); + * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: + * \ref LORAMAC_STATUS_OK + * \ref LORAMAC_STATUS_PARAMETER_INVALID + */ + LoRaMacStatus_t LoRaMacSetTxTimer( uint32_t NextTxTime ); + + /** + * \brief LoRaMAC stop tx timer. + * + * \details Stops the next tx timer. + * + * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: + * \ref LORAMAC_STATUS_OK + * \ref LORAMAC_STATUS_PARAMETER_INVALID + */ + LoRaMacStatus_t LoRaMacStopTxTimer( ); + + /** + * \brief Enabled or disables the reception windows + * + * \details This is a test function. It shall be used for testing purposes only. + * Changing this attribute may lead to a non-conformance LoRaMac operation. + * + * \param [in] enable - Enabled or disables the reception windows + */ + void LoRaMacTestRxWindowsOn( bool enable ); + + /** + * \brief Enables the MIC field test + * + * \details This is a test function. It shall be used for testing purposes only. + * Changing this attribute may lead to a non-conformance LoRaMac operation. + * + * \param [in] txPacketCounter - Fixed Tx packet counter value + */ + void LoRaMacTestSetMic( uint16_t txPacketCounter ); + + /** + * \brief Enabled or disables the duty cycle + * + * \details This is a test function. It shall be used for testing purposes only. + * Changing this attribute may lead to a non-conformance LoRaMac operation. + * + * \param [in] enable - Enabled or disables the duty cycle + */ + void LoRaMacTestSetDutyCycleOn( bool enable ); + + /** + * \brief Sets the channel index + * + * \details This is a test function. It shall be used for testing purposes only. + * Changing this attribute may lead to a non-conformance LoRaMac operation. + * + * \param [in] channel - Channel index + */ + void LoRaMacTestSetChannel( uint8_t channel ); + +private: + /** + * Timer to handle the application data transmission duty cycle + */ + TimerEvent_t TxNextPacketTimer; #endif +private: + /*! + * \brief Function to be executed on Radio Tx Done event + */ + void OnRadioTxDone( void ); + + /*! + * \brief This function prepares the MAC to abort the execution of function + * OnRadioRxDone in case of a reception error. + */ + void PrepareRxDoneAbort( void ); + + /*! + * \brief Function to be executed on Radio Rx Done event + */ + void OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ); + + /*! + * \brief Function executed on Radio Tx Timeout event + */ + void OnRadioTxTimeout( void ); + + /*! + * \brief Function executed on Radio Rx error event + */ + void OnRadioRxError( void ); + + /*! + * \brief Function executed on Radio Rx Timeout event + */ + void OnRadioRxTimeout( void ); + + /*! + * \brief Function executed on Resend Frame timer event. + */ + void OnMacStateCheckTimerEvent( void ); + + /*! + * \brief Function executed on duty cycle delayed Tx timer event + */ + void OnTxDelayedTimerEvent( void ); + + /** + * \brief Function to be executed when next Tx is possible + */ + void OnNextTx( void ); + + /*! + * \brief Function executed on first Rx window timer event + */ + void OnRxWindow1TimerEvent( void ); + + /*! + * \brief Function executed on second Rx window timer event + */ + void OnRxWindow2TimerEvent( void ); + + /*! + * \brief Function executed on AckTimeout timer event + */ + void OnAckTimeoutTimerEvent( void ); + + /*! + * \brief Initializes and opens the reception window + * + * \param [IN] rxContinuous Set to true, if the RX is in continuous mode + * \param [IN] maxRxWindow Maximum RX window timeout + */ + void RxWindowSetup( bool rxContinuous, uint32_t maxRxWindow ); + + /*! + * \brief Validates if the payload fits into the frame, taking the datarate + * into account. + * + * \details Refer to chapter 4.3.2 of the LoRaWAN specification, v1.0 + * + * \param lenN Length of the application payload. The length depends on the + * datarate and is region specific + * + * \param datarate Current datarate + * + * \param fOptsLen Length of the fOpts field + * + * \retval [false: payload does not fit into the frame, true: payload fits into + * the frame] + */ + bool ValidatePayloadLength( uint8_t lenN, int8_t datarate, uint8_t fOptsLen ); + + /*! + * \brief LoRaMAC layer generic send frame + * + * \param [IN] macHdr MAC header field + * \param [IN] fPort MAC payload port + * \param [IN] fBuffer MAC data buffer to be sent + * \param [IN] fBufferSize MAC data buffer size + * \retval status Status of the operation. + */ + LoRaMacStatus_t Send( LoRaMacHeader_t *macHdr, uint8_t fPort, void *fBuffer, uint16_t fBufferSize ); + + /*! + * \brief LoRaMAC layer frame buffer initialization + * + * \param [IN] macHdr MAC header field + * \param [IN] fCtrl MAC frame control field + * \param [IN] fOpts MAC commands buffer + * \param [IN] fPort MAC payload port + * \param [IN] fBuffer MAC data buffer to be sent + * \param [IN] fBufferSize MAC data buffer size + * \retval status Status of the operation. + */ + LoRaMacStatus_t PrepareFrame( LoRaMacHeader_t *macHdr, LoRaMacFrameCtrl_t *fCtrl, uint8_t fPort, void *fBuffer, uint16_t fBufferSize ); + + /* + * \brief Schedules the frame according to the duty cycle + * + * \retval Status of the operation + */ + LoRaMacStatus_t ScheduleTx( void ); + + /* + * \brief Calculates the back-off time for the band of a channel. + * + * \param [IN] channel The last Tx channel index + */ + void CalculateBackOff( uint8_t channel ); + + /*! + * \brief LoRaMAC layer prepared frame buffer transmission with channel specification + * + * \remark PrepareFrame must be called at least once before calling this + * function. + * + * \param [IN] channel Channel to transmit on + * \retval status Status of the operation. + */ + LoRaMacStatus_t SendFrameOnChannel( uint8_t channel ); + + /*! + * \brief Sets the radio in continuous transmission mode + * + * \remark Uses the radio parameters set on the previous transmission. + * + * \param [IN] timeout Time in seconds while the radio is kept in continuous wave mode + * \retval status Status of the operation. + */ + LoRaMacStatus_t SetTxContinuousWave( uint16_t timeout ); + + /*! + * \brief Sets the radio in continuous transmission mode + * + * \remark Uses the radio parameters set on the previous transmission. + * + * \param [IN] timeout Time in seconds while the radio is kept in continuous wave mode + * \param [IN] frequency RF frequency to be set. + * \param [IN] power RF output power to be set. + * \retval status Status of the operation. + */ + LoRaMacStatus_t SetTxContinuousWave1( uint16_t timeout, uint32_t frequency, uint8_t power ); + + /*! + * \brief Resets MAC specific parameters to default + */ + void ResetMacParameters( void ); + + /*! + * \brief Resets MAC specific parameters to default + * + * \param [IN] fPort The fPort + * + * \retval [false: fPort not allowed, true: fPort allowed] + */ + bool IsFPortAllowed( uint8_t fPort ); + + /*! + * \brief Opens up a continuous RX 2 window. This is used for + * class c devices. + */ + void OpenContinuousRx2Window( void ); + + /** + * Prototypes for ISR handlers + */ + static void handle_cad_done(bool cad); + static void handle_tx_done(void); + static void handle_rx_done(uint8_t *payload, uint16_t size, int16_t rssi, + int8_t snr); + static void handle_rx_error(void); + static void handle_rx_timeout(void); + static void handle_tx_timeout(void); + static void handle_fhss_change_channel(uint8_t cur_channel); + static void handle_rx1_timer_event(void); + static void handle_rx2_timer_event(void); + static void handle_ack_timeout(void); + 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); + +private: + /** + * LoRa PHY layer object storage + */ + LoRaPHY *lora_phy; + + LoRaMacCommand mac_commands; + + + /** + * Radio event callback handlers for MAC + */ + radio_events_t RadioEvents; + + + /*! + * Device IEEE EUI + */ + uint8_t *LoRaMacDevEui; + + /*! + * Application IEEE EUI + */ + uint8_t *LoRaMacAppEui; + + /*! + * AES encryption/decryption cipher application key + */ + uint8_t *LoRaMacAppKey; + + /*! + * AES encryption/decryption cipher network session key + */ + uint8_t LoRaMacNwkSKey[16]; + + /*! + * AES encryption/decryption cipher application session key + */ + uint8_t LoRaMacAppSKey[16]; + + /*! + * Device nonce is a random value extracted by issuing a sequence of RSSI + * measurements + */ + uint16_t LoRaMacDevNonce; + + /*! + * Network ID ( 3 bytes ) + */ + uint32_t LoRaMacNetID; + + /*! + * Mote Address + */ + uint32_t LoRaMacDevAddr; + + /*! + * Multicast channels linked list + */ + MulticastParams_t *MulticastChannels; + + /*! + * Actual device class + */ + DeviceClass_t LoRaMacDeviceClass; + + /*! + * Indicates if the node is connected to a private or public network + */ + bool PublicNetwork; + + /*! + * Indicates if the node supports repeaters + */ + bool RepeaterSupport; + + /*! + * Buffer containing the data to be sent or received. + */ + uint8_t LoRaMacBuffer[LORAMAC_PHY_MAXPAYLOAD]; + + /*! + * Length of packet in LoRaMacBuffer + */ + uint16_t LoRaMacBufferPktLen; + + /*! + * Length of the payload in LoRaMacBuffer + */ + uint8_t LoRaMacTxPayloadLen; + + /*! + * Buffer containing the upper layer data. + */ + uint8_t LoRaMacRxPayload[LORAMAC_PHY_MAXPAYLOAD]; + + /*! + * LoRaMAC frame counter. Each time a packet is sent the counter is incremented. + * Only the 16 LSB bits are sent + */ + uint32_t UpLinkCounter; + + /*! + * LoRaMAC frame counter. Each time a packet is received the counter is incremented. + * Only the 16 LSB bits are received + */ + uint32_t DownLinkCounter; + + /*! + * IsPacketCounterFixed enables the MIC field tests by fixing the + * UpLinkCounter value + */ + bool IsUpLinkCounterFixed; + + /*! + * Used for test purposes. Disables the opening of the reception windows. + */ + bool IsRxWindowsEnabled; + + /*! + * Indicates if the MAC layer has already joined a network. + */ + bool IsLoRaMacNetworkJoined; + + /*! + * Counts the number of missed ADR acknowledgements + */ + uint32_t AdrAckCounter; + + /*! + * If the node has sent a FRAME_TYPE_DATA_CONFIRMED_UP this variable indicates + * if the nodes needs to manage the server acknowledgement. + */ + bool NodeAckRequested; + + /*! + * If the server has sent a FRAME_TYPE_DATA_CONFIRMED_DOWN this variable indicates + * if the ACK bit must be set for the next transmission + */ + bool SrvAckRequested; + + /*! + * LoRaMac parameters + */ + LoRaMacParams_t LoRaMacParams; + + /*! + * LoRaMac default parameters + */ + LoRaMacParams_t LoRaMacParamsDefaults; + + /*! + * Uplink messages repetitions counter + */ + uint8_t ChannelsNbRepCounter; + + /*! + * Aggregated duty cycle management + */ + TimerTime_t AggregatedLastTxDoneTime; + TimerTime_t AggregatedTimeOff; + + /*! + * Enables/Disables duty cycle management (Test only) + */ + bool DutyCycleOn; + + /*! + * Current channel index + */ + uint8_t Channel; + + /*! + * Current channel index + */ + uint8_t LastTxChannel; + + /*! + * Set to true, if the last uplink was a join request + */ + bool LastTxIsJoinRequest; + + /*! + * Stores the time at LoRaMac initialization. + * + * \remark Used for the BACKOFF_DC computation. + */ + TimerTime_t LoRaMacInitializationTime; + + /*! + * LoRaMac internal states + */ + enum eLoRaMacState + { + LORAMAC_IDLE = 0x00000000, + LORAMAC_TX_RUNNING = 0x00000001, + LORAMAC_RX = 0x00000002, + LORAMAC_ACK_REQ = 0x00000004, + LORAMAC_ACK_RETRY = 0x00000008, + LORAMAC_TX_DELAYED = 0x00000010, + LORAMAC_TX_CONFIG = 0x00000020, + LORAMAC_RX_ABORT = 0x00000040, + }; + + /*! + * LoRaMac internal state + */ + uint32_t LoRaMacState; + + /*! + * LoRaMac timer used to check the LoRaMacState (runs every second) + */ + TimerEvent_t MacStateCheckTimer; + + /*! + * LoRaMac upper layer event functions + */ + LoRaMacPrimitives_t *LoRaMacPrimitives; + + /*! + * LoRaMac upper layer callback functions + */ + LoRaMacCallback_t *LoRaMacCallbacks; + + /*! + * LoRaMac duty cycle delayed Tx timer + */ + TimerEvent_t TxDelayedTimer; + + /*! + * LoRaMac reception windows timers + */ + TimerEvent_t RxWindowTimer1; + TimerEvent_t RxWindowTimer2; + + /*! + * LoRaMac reception windows delay + * \remark normal frame: RxWindowXDelay = ReceiveDelayX - RADIO_WAKEUP_TIME + * join frame : RxWindowXDelay = JoinAcceptDelayX - RADIO_WAKEUP_TIME + */ + uint32_t RxWindow1Delay; + uint32_t RxWindow2Delay; + + /*! + * LoRaMac Rx windows configuration + */ + RxConfigParams_t RxWindow1Config; + RxConfigParams_t RxWindow2Config; + + /*! + * Acknowledge timeout timer. Used for packet retransmissions. + */ + TimerEvent_t AckTimeoutTimer; + + /*! + * Number of trials to get a frame acknowledged + */ + uint8_t AckTimeoutRetries; + + /*! + * Number of trials to get a frame acknowledged + */ + uint8_t AckTimeoutRetriesCounter; + + /*! + * Indicates if the AckTimeout timer has expired or not + */ + bool AckTimeoutRetry; + + /*! + * Last transmission time on air + */ + TimerTime_t TxTimeOnAir; + + /*! + * Number of trials for the Join Request + */ + uint8_t JoinRequestTrials; + + /*! + * Maximum number of trials for the Join Request + */ + uint8_t MaxJoinRequestTrials; + + /*! + * Structure to hold MCPS indication data. + */ + McpsIndication_t McpsIndication; + + /*! + * Structure to hold MCPS confirm data. + */ + McpsConfirm_t McpsConfirm; + + /*! + * Structure to hold MLME indication data. + */ + MlmeIndication_t MlmeIndication; + + /*! + * Structure to hold MLME confirm data. + */ + MlmeConfirm_t MlmeConfirm; + + /*! + * Holds the current rx window slot + */ + LoRaMacRxSlot_t RxSlot; + + /*! + * LoRaMac tx/rx operation state + */ + LoRaMacFlags_t LoRaMacFlags; + +}; + #endif // __LORAMAC_H__ diff --git a/features/lorawan/lorastack/mac/LoRaMacCommand.cpp b/features/lorawan/lorastack/mac/LoRaMacCommand.cpp new file mode 100644 index 0000000000..108c0c2f9c --- /dev/null +++ b/features/lorawan/lorastack/mac/LoRaMacCommand.cpp @@ -0,0 +1,444 @@ +/** + / _____) _ | | +( (____ _____ ____ _| |_ _____ ____| |__ + \____ \| ___ | (_ _) ___ |/ ___) _ \ + _____) ) ____| | | || |_| ____( (___| | | | +(______/|_____)_|_|_| \__)_____)\____)_| |_| + (C)2013 Semtech + ___ _____ _ ___ _ _____ ___ ___ ___ ___ +/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| +\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| +|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| +embedded.connectivity.solutions=============== + +Description: LoRa MAC layer implementation + +License: Revised BSD License, see LICENSE.TXT file include in the project + +Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE ) + +Copyright (c) 2017, Arm Limited and affiliates. + +SPDX-License-Identifier: BSD-3-Clause +*/ +#include "LoRaMacCommand.h" +#include "LoRaMac.h" + +#if defined(FEATURE_COMMON_PAL) +#include "mbed_trace.h" +#define TRACE_GROUP "LMACC" +#else +#define tr_debug(...) (void(0)) //dummies if feature common pal is not added +#define tr_info(...) (void(0)) //dummies if feature common pal is not added +#define tr_error(...) (void(0)) //dummies if feature common pal is not added +#endif //defined(FEATURE_COMMON_PAL) + +/*! + * LoRaMAC max EIRP (dBm) table. + */ +static const uint8_t LoRaMacMaxEirpTable[] = { 8, 10, 12, 13, 14, 16, 18, 20, 21, 24, 26, 27, 29, 30, 33, 36 }; + + +LoRaMacCommand::LoRaMacCommand(LoRaMac& lora_mac) + : _lora_mac(lora_mac) +{ + MacCommandsInNextTx = false; + MacCommandsBufferIndex = 0; + MacCommandsBufferToRepeatIndex = 0; + //uint8_t MacCommandsBuffer[LORA_MAC_COMMAND_MAX_LENGTH]; + //uint8_t MacCommandsBufferToRepeat[LORA_MAC_COMMAND_MAX_LENGTH]; +} + +LoRaMacCommand::~LoRaMacCommand() +{ +} + +LoRaMacStatus_t LoRaMacCommand::AddMacCommand(uint8_t cmd, uint8_t p1, uint8_t p2) +{ + LoRaMacStatus_t status = LORAMAC_STATUS_BUSY; + // The maximum buffer length must take MAC commands to re-send into account. + const uint8_t bufLen = LORA_MAC_COMMAND_MAX_LENGTH - MacCommandsBufferToRepeatIndex; + + switch( cmd ) + { + case MOTE_MAC_LINK_CHECK_REQ: + if( MacCommandsBufferIndex < bufLen ) + { + MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; + // No payload for this command + status = LORAMAC_STATUS_OK; + } + break; + case MOTE_MAC_LINK_ADR_ANS: + if( MacCommandsBufferIndex < ( bufLen - 1 ) ) + { + MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; + // Margin + MacCommandsBuffer[MacCommandsBufferIndex++] = p1; + status = LORAMAC_STATUS_OK; + } + break; + case MOTE_MAC_DUTY_CYCLE_ANS: + if( MacCommandsBufferIndex < bufLen ) + { + MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; + // No payload for this answer + status = LORAMAC_STATUS_OK; + } + break; + case MOTE_MAC_RX_PARAM_SETUP_ANS: + if( MacCommandsBufferIndex < ( bufLen - 1 ) ) + { + MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; + // Status: Datarate ACK, Channel ACK + MacCommandsBuffer[MacCommandsBufferIndex++] = p1; + // This is a sticky MAC command answer. Setup indication + _lora_mac.SetMlmeScheduleUplinkIndication(); + status = LORAMAC_STATUS_OK; + } + break; + case MOTE_MAC_DEV_STATUS_ANS: + if( MacCommandsBufferIndex < ( bufLen - 2 ) ) + { + MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; + // 1st byte Battery + // 2nd byte Margin + MacCommandsBuffer[MacCommandsBufferIndex++] = p1; + MacCommandsBuffer[MacCommandsBufferIndex++] = p2; + status = LORAMAC_STATUS_OK; + } + break; + case MOTE_MAC_NEW_CHANNEL_ANS: + if( MacCommandsBufferIndex < ( bufLen - 1 ) ) + { + MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; + // Status: Datarate range OK, Channel frequency OK + MacCommandsBuffer[MacCommandsBufferIndex++] = p1; + status = LORAMAC_STATUS_OK; + } + break; + case MOTE_MAC_RX_TIMING_SETUP_ANS: + if( MacCommandsBufferIndex < bufLen ) + { + MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; + // No payload for this answer + // This is a sticky MAC command answer. Setup indication + _lora_mac.SetMlmeScheduleUplinkIndication(); + status = LORAMAC_STATUS_OK; + } + break; + case MOTE_MAC_TX_PARAM_SETUP_ANS: + if( MacCommandsBufferIndex < bufLen ) + { + MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; + // No payload for this answer + status = LORAMAC_STATUS_OK; + } + break; + case MOTE_MAC_DL_CHANNEL_ANS: + if( MacCommandsBufferIndex < bufLen ) + { + MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; + // Status: Uplink frequency exists, Channel frequency OK + MacCommandsBuffer[MacCommandsBufferIndex++] = p1; + // This is a sticky MAC command answer. Setup indication + _lora_mac.SetMlmeScheduleUplinkIndication(); + status = LORAMAC_STATUS_OK; + } + break; + default: + return LORAMAC_STATUS_SERVICE_UNKNOWN; + } + if( status == LORAMAC_STATUS_OK ) + { + MacCommandsInNextTx = true; + } + return status; +} + +void LoRaMacCommand::ClearCommandBuffer() +{ + MacCommandsBufferIndex = 0; +} + +uint8_t LoRaMacCommand::GetLength() const +{ + return MacCommandsBufferIndex; +} + +uint8_t *LoRaMacCommand::GetMacCommandsBuffer() +{ + return MacCommandsBuffer; +} + +void LoRaMacCommand::ParseMacCommandsToRepeat() +{ + uint8_t i = 0; + uint8_t cmdCount = 0; + + for( i = 0; i < MacCommandsBufferIndex; i++ ) + { + switch( MacCommandsBuffer[i] ) + { + // STICKY + case MOTE_MAC_DL_CHANNEL_ANS: + case MOTE_MAC_RX_PARAM_SETUP_ANS: + { // 1 byte payload + MacCommandsBufferToRepeat[cmdCount++] = MacCommandsBuffer[i++]; + MacCommandsBufferToRepeat[cmdCount++] = MacCommandsBuffer[i]; + break; + } + case MOTE_MAC_RX_TIMING_SETUP_ANS: + { // 0 byte payload + MacCommandsBufferToRepeat[cmdCount++] = MacCommandsBuffer[i]; + break; + } + // NON-STICKY + case MOTE_MAC_DEV_STATUS_ANS: + { // 2 bytes payload + i += 2; + break; + } + case MOTE_MAC_LINK_ADR_ANS: + case MOTE_MAC_NEW_CHANNEL_ANS: + { // 1 byte payload + i++; + break; + } + case MOTE_MAC_TX_PARAM_SETUP_ANS: + case MOTE_MAC_DUTY_CYCLE_ANS: + case MOTE_MAC_LINK_CHECK_REQ: + { // 0 byte payload + break; + } + default: + break; + } + } + + if( cmdCount > 0 ) { + MacCommandsInNextTx = true; + } else { + MacCommandsInNextTx = false; + } +} + + +void LoRaMacCommand::ClearRepeatBuffer() +{ + MacCommandsBufferToRepeatIndex = 0; +} + +void LoRaMacCommand::CopyRepeatCommandsToBuffer() +{ + // Copy the MAC commands which must be re-send into the MAC command buffer + memcpy(&MacCommandsBuffer[MacCommandsBufferIndex], MacCommandsBufferToRepeat, MacCommandsBufferToRepeatIndex); + MacCommandsBufferIndex += MacCommandsBufferToRepeatIndex; +} + +uint8_t LoRaMacCommand::GetRepeatLength() const +{ + return MacCommandsBufferToRepeatIndex; +} + +void LoRaMacCommand::ClearMacCommandsInNextTx() +{ + MacCommandsInNextTx = false; +} + +bool LoRaMacCommand::IsMacCommandsInNextTx() const +{ + return MacCommandsInNextTx; +} + +void LoRaMacCommand::ProcessMacCommands(uint8_t *payload, uint8_t macIndex, uint8_t commandsSize, uint8_t snr, + MlmeConfirm_t &MlmeConfirm, LoRaMacCallback_t *LoRaMacCallbacks, + LoRaMacParams_t &LoRaMacParams, LoRaPHY &lora_phy) +{ + uint8_t status = 0; + + while( macIndex < commandsSize ) + { + // Decode Frame MAC commands + switch( payload[macIndex++] ) + { + case SRV_MAC_LINK_CHECK_ANS: + MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK; + MlmeConfirm.DemodMargin = payload[macIndex++]; + MlmeConfirm.NbGateways = payload[macIndex++]; + break; + case SRV_MAC_LINK_ADR_REQ: + { + LinkAdrReqParams_t linkAdrReq; + int8_t linkAdrDatarate = DR_0; + int8_t linkAdrTxPower = TX_POWER_0; + uint8_t linkAdrNbRep = 0; + uint8_t linkAdrNbBytesParsed = 0; + + // Fill parameter structure + linkAdrReq.Payload = &payload[macIndex - 1]; + linkAdrReq.PayloadSize = commandsSize - ( macIndex - 1 ); + linkAdrReq.AdrEnabled = LoRaMacParams.AdrCtrlOn; + linkAdrReq.UplinkDwellTime = LoRaMacParams.UplinkDwellTime; + linkAdrReq.CurrentDatarate = LoRaMacParams.ChannelsDatarate; + linkAdrReq.CurrentTxPower = LoRaMacParams.ChannelsTxPower; + linkAdrReq.CurrentNbRep = LoRaMacParams.ChannelsNbRep; + + // Process the ADR requests + status = lora_phy.link_ADR_request(&linkAdrReq, &linkAdrDatarate, + &linkAdrTxPower, &linkAdrNbRep, + &linkAdrNbBytesParsed); + + if( ( status & 0x07 ) == 0x07 ) + { + LoRaMacParams.ChannelsDatarate = linkAdrDatarate; + LoRaMacParams.ChannelsTxPower = linkAdrTxPower; + LoRaMacParams.ChannelsNbRep = linkAdrNbRep; + } + + // Add the answers to the buffer + for( uint8_t i = 0; i < ( linkAdrNbBytesParsed / 5 ); i++ ) + { + AddMacCommand( MOTE_MAC_LINK_ADR_ANS, status, 0 ); + } + // Update MAC index + macIndex += linkAdrNbBytesParsed - 1; + } + break; + case SRV_MAC_DUTY_CYCLE_REQ: + LoRaMacParams.MaxDCycle = payload[macIndex++]; + LoRaMacParams.AggregatedDCycle = 1 << LoRaMacParams.MaxDCycle; + AddMacCommand( MOTE_MAC_DUTY_CYCLE_ANS, 0, 0 ); + break; + case SRV_MAC_RX_PARAM_SETUP_REQ: + { + RxParamSetupReqParams_t rxParamSetupReq; + status = 0x07; + + rxParamSetupReq.DrOffset = ( payload[macIndex] >> 4 ) & 0x07; + rxParamSetupReq.Datarate = payload[macIndex] & 0x0F; + macIndex++; + + rxParamSetupReq.Frequency = ( uint32_t )payload[macIndex++]; + rxParamSetupReq.Frequency |= ( uint32_t )payload[macIndex++] << 8; + rxParamSetupReq.Frequency |= ( uint32_t )payload[macIndex++] << 16; + rxParamSetupReq.Frequency *= 100; + + // Perform request on region + status = lora_phy.setup_rx_params(&rxParamSetupReq); + + if( ( status & 0x07 ) == 0x07 ) + { + LoRaMacParams.Rx2Channel.Datarate = rxParamSetupReq.Datarate; + LoRaMacParams.Rx2Channel.Frequency = rxParamSetupReq.Frequency; + LoRaMacParams.Rx1DrOffset = rxParamSetupReq.DrOffset; + } + AddMacCommand( MOTE_MAC_RX_PARAM_SETUP_ANS, status, 0 ); + } + break; + case SRV_MAC_DEV_STATUS_REQ: + { + uint8_t batteryLevel = BAT_LEVEL_NO_MEASURE; + if( ( LoRaMacCallbacks != NULL ) && ( LoRaMacCallbacks->GetBatteryLevel != NULL ) ) + { + batteryLevel = LoRaMacCallbacks->GetBatteryLevel( ); + } + AddMacCommand( MOTE_MAC_DEV_STATUS_ANS, batteryLevel, snr ); + break; + } + case SRV_MAC_NEW_CHANNEL_REQ: + { + NewChannelReqParams_t newChannelReq; + ChannelParams_t chParam; + status = 0x03; + + newChannelReq.ChannelId = payload[macIndex++]; + newChannelReq.NewChannel = &chParam; + + chParam.Frequency = ( uint32_t )payload[macIndex++]; + chParam.Frequency |= ( uint32_t )payload[macIndex++] << 8; + chParam.Frequency |= ( uint32_t )payload[macIndex++] << 16; + chParam.Frequency *= 100; + chParam.Rx1Frequency = 0; + chParam.DrRange.Value = payload[macIndex++]; + + status = lora_phy.request_new_channel(&newChannelReq); + + AddMacCommand( MOTE_MAC_NEW_CHANNEL_ANS, status, 0 ); + } + break; + case SRV_MAC_RX_TIMING_SETUP_REQ: + { + uint8_t delay = payload[macIndex++] & 0x0F; + + if( delay == 0 ) + { + delay++; + } + LoRaMacParams.ReceiveDelay1 = delay * 1000; + LoRaMacParams.ReceiveDelay2 = LoRaMacParams.ReceiveDelay1 + 1000; + AddMacCommand( MOTE_MAC_RX_TIMING_SETUP_ANS, 0, 0 ); + } + break; + case SRV_MAC_TX_PARAM_SETUP_REQ: + { + TxParamSetupReqParams_t txParamSetupReq; + uint8_t eirpDwellTime = payload[macIndex++]; + + txParamSetupReq.UplinkDwellTime = 0; + txParamSetupReq.DownlinkDwellTime = 0; + + if( ( eirpDwellTime & 0x20 ) == 0x20 ) + { + txParamSetupReq.DownlinkDwellTime = 1; + } + if( ( eirpDwellTime & 0x10 ) == 0x10 ) + { + txParamSetupReq.UplinkDwellTime = 1; + } + txParamSetupReq.MaxEirp = eirpDwellTime & 0x0F; + + // Check the status for correctness + if( lora_phy.setup_tx_params(&txParamSetupReq ) != -1 ) + { + // Accept command + LoRaMacParams.UplinkDwellTime = txParamSetupReq.UplinkDwellTime; + LoRaMacParams.DownlinkDwellTime = txParamSetupReq.DownlinkDwellTime; + LoRaMacParams.MaxEirp = LoRaMacMaxEirpTable[txParamSetupReq.MaxEirp]; + // Add command response + AddMacCommand( MOTE_MAC_TX_PARAM_SETUP_ANS, 0, 0 ); + } + } + break; + case SRV_MAC_DL_CHANNEL_REQ: + { + DlChannelReqParams_t dlChannelReq; + status = 0x03; + + dlChannelReq.ChannelId = payload[macIndex++]; + dlChannelReq.Rx1Frequency = ( uint32_t )payload[macIndex++]; + dlChannelReq.Rx1Frequency |= ( uint32_t )payload[macIndex++] << 8; + dlChannelReq.Rx1Frequency |= ( uint32_t )payload[macIndex++] << 16; + dlChannelReq.Rx1Frequency *= 100; + + status = lora_phy.dl_channel_request(&dlChannelReq); + + AddMacCommand( MOTE_MAC_DL_CHANNEL_ANS, status, 0 ); + } + break; + default: + // Unknown command. ABORT MAC commands processing + return; + } + } +} + +bool LoRaMacCommand::IsStickyMacCommandPending() +{ + if( MacCommandsBufferToRepeatIndex > 0 ) + { + // Sticky MAC commands pending + return true; + } + return false; +} diff --git a/features/lorawan/lorastack/mac/LoRaMacCommand.h b/features/lorawan/lorastack/mac/LoRaMacCommand.h new file mode 100644 index 0000000000..4fb7865577 --- /dev/null +++ b/features/lorawan/lorastack/mac/LoRaMacCommand.h @@ -0,0 +1,175 @@ +/** + * \file LoRaMacCommand.h + * + * \brief LoRa MAC layer implementation + * + * \copyright Revised BSD License, see LICENSE.TXT file include in the project + * + * \code + * ______ _ + * / _____) _ | | + * ( (____ _____ ____ _| |_ _____ ____| |__ + * \____ \| ___ | (_ _) ___ |/ ___) _ \ + * _____) ) ____| | | || |_| ____( (___| | | | + * (______/|_____)_|_|_| \__)_____)\____)_| |_| + * (C)2013 Semtech + * + * ___ _____ _ ___ _ _____ ___ ___ ___ ___ + * / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| + * \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| + * |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| + * embedded.connectivity.solutions=============== + * + * \endcode + * + * \author Miguel Luis ( Semtech ) + * + * \author Gregory Cristian ( Semtech ) + * + * \author Daniel Jaeckle ( STACKFORCE ) + * + * \defgroup LORAMAC LoRa MAC layer implementation + * This module specifies the API implementation of the LoRaMAC layer. + * This is a placeholder for a detailed description of the LoRaMac + * layer and the supported features. + * + * Copyright (c) 2017, Arm Limited and affiliates. + * SPDX-License-Identifier: BSD-3-Clause + * + */ +#ifndef __LORAMACCOMMAND_H__ +#define __LORAMACCOMMAND_H__ + +#include +#include "lorawan/system/lorawan_data_structures.h" +#include "lorawan/lorastack/phy/LoRaPHY.h" + +/*! + * Maximum MAC commands buffer size + */ +#define LORA_MAC_COMMAND_MAX_LENGTH 128 + +class LoRaMac; + +class LoRaMacCommand +{ +public: + LoRaMacCommand(LoRaMac &lora_mac); + ~LoRaMacCommand(); + + /*! + * \brief Adds a new MAC command to be sent. + * + * \Remark MAC layer internal function + * + * \param [in] cmd MAC command to be added + * [MOTE_MAC_LINK_CHECK_REQ, + * MOTE_MAC_LINK_ADR_ANS, + * MOTE_MAC_DUTY_CYCLE_ANS, + * MOTE_MAC_RX2_PARAM_SET_ANS, + * MOTE_MAC_DEV_STATUS_ANS + * MOTE_MAC_NEW_CHANNEL_ANS] + * \param [in] p1 1st parameter ( optional depends on the command ) + * \param [in] p2 2nd parameter ( optional depends on the command ) + * + * \retval status Function status [0: OK, 1: Unknown command, 2: Buffer full] + */ + LoRaMacStatus_t AddMacCommand(uint8_t cmd, uint8_t p1, uint8_t p2); + + /*! + * \brief Clear MAC command buffer. + */ + void ClearCommandBuffer(); + + /*! + * \brief Get the length of MAC commands + * + * \retval status Length of used MAC buffer (bytes) + */ + uint8_t GetLength() const; + + /*! + * \brief Get MAC command buffer + * + * \retval Pointer to MAC command buffer + */ + uint8_t *GetMacCommandsBuffer(); + + /*! + * \brief Parses the MAC commands which must be resent. + */ + void ParseMacCommandsToRepeat(); + + /*! + * \brief Clear MAC command repeat buffer. + */ + void ClearRepeatBuffer(); + + /*! + * \brief Copy MAC commands from repeat buffer to actual MAC command buffer. + */ + void CopyRepeatCommandsToBuffer(); + + /*! + * \brief Get the length of MAC commands in repeat buffer + * + * \retval status Length of used MAC Repeat buffer (bytes) + */ + uint8_t GetRepeatLength() const; + + /*! + * \brief Clear MAC commands in next TX. + */ + void ClearMacCommandsInNextTx(); + + /*! + * \brief Check if MAC command buffer has commands to be sent in next TX + * + * \retval status True: buffer has MAC commands to be sent, false: no commands in buffer] + */ + bool IsMacCommandsInNextTx() const; + + /*! + * \brief Decodes MAC commands in the fOpts field and in the payload + */ + void ProcessMacCommands(uint8_t *payload, uint8_t macIndex, uint8_t commandsSize, uint8_t snr, + MlmeConfirm_t &MlmeConfirm, LoRaMacCallback_t *LoRaMacCallbacks, + LoRaMacParams_t &LoRaMacParams, LoRaPHY &lora_phy); + + /*! + * \brief Verifies if sticky MAC commands are pending. + * + * \retval [true: sticky MAC commands pending, false: No MAC commands pending] + */ + bool IsStickyMacCommandPending(); + +private: + LoRaMac& _lora_mac; + + /*! + * Indicates if the MAC layer wants to send MAC commands + */ + bool MacCommandsInNextTx; + + /*! + * Contains the current MacCommandsBuffer index + */ + uint8_t MacCommandsBufferIndex; + + /*! + * Contains the current MacCommandsBuffer index for MAC commands to repeat + */ + uint8_t MacCommandsBufferToRepeatIndex; + + /*! + * Buffer containing the MAC layer commands + */ + uint8_t MacCommandsBuffer[LORA_MAC_COMMAND_MAX_LENGTH]; + + /*! + * Buffer containing the MAC layer commands which must be repeated + */ + uint8_t MacCommandsBufferToRepeat[LORA_MAC_COMMAND_MAX_LENGTH]; +}; + +#endif //__LORAMACCOMMAND_H__ diff --git a/features/lorawan/lorastack/mac/LoRaMacTest.h b/features/lorawan/lorastack/mac/LoRaMacTest.h deleted file mode 100644 index cf51a1c29b..0000000000 --- a/features/lorawan/lorastack/mac/LoRaMacTest.h +++ /dev/null @@ -1,68 +0,0 @@ -/** - / _____) _ | | -( (____ _____ ____ _| |_ _____ ____| |__ - \____ \| ___ | (_ _) ___ |/ ___) _ \ - _____) ) ____| | | || |_| ____( (___| | | | -(______/|_____)_|_|_| \__)_____)\____)_| |_| - (C)2013 Semtech - ___ _____ _ ___ _ _____ ___ ___ ___ ___ -/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| -\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| -|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| -embedded.connectivity.solutions=============== - -Description: LoRa MAC layer test function implementation - -License: Revised BSD License, see LICENSE.TXT file include in the project - -Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE ) - - -Copyright (c) 2017, Arm Limited and affiliates. - -SPDX-License-Identifier: BSD-3-Clause -*/ -#ifndef __LORAMACTEST_H__ -#define __LORAMACTEST_H__ - -/** - * \brief Enabled or disables the reception windows - * - * \details This is a test function. It shall be used for testing purposes only. - * Changing this attribute may lead to a non-conformance LoRaMac operation. - * - * \param [in] enable - Enabled or disables the reception windows - */ -void LoRaMacTestRxWindowsOn( bool enable ); - -/** - * \brief Enables the MIC field test - * - * \details This is a test function. It shall be used for testing purposes only. - * Changing this attribute may lead to a non-conformance LoRaMac operation. - * - * \param [in] txPacketCounter - Fixed Tx packet counter value - */ -void LoRaMacTestSetMic( uint16_t txPacketCounter ); - -/** - * \brief Enabled or disables the duty cycle - * - * \details This is a test function. It shall be used for testing purposes only. - * Changing this attribute may lead to a non-conformance LoRaMac operation. - * - * \param [in] enable - Enabled or disables the duty cycle - */ -void LoRaMacTestSetDutyCycleOn( bool enable ); - -/** - * \brief Sets the channel index - * - * \details This is a test function. It shall be used for testing purposes only. - * Changing this attribute may lead to a non-conformance LoRaMac operation. - * - * \param [in] channel - Channel index - */ -void LoRaMacTestSetChannel( uint8_t channel ); - -#endif // __LORAMACTEST_H__ diff --git a/features/lorawan/lorastack/phy/LoRaPHY.cpp b/features/lorawan/lorastack/phy/LoRaPHY.cpp index 7a7c43b724..7f3019e08c 100644 --- a/features/lorawan/lorastack/phy/LoRaPHY.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHY.cpp @@ -355,8 +355,8 @@ uint8_t LoRaPHY::verify_link_ADR_req( RegionCommonLinkAdrReqVerifyParams_t* veri if( status == 0x07 ) { if( nbRepetitions == 0 ) - { // Keep the current one - nbRepetitions = verifyParams->CurrentNbRep; + { // Restore the default value according to the LoRaWAN specification + nbRepetitions = 1; } } diff --git a/features/lorawan/lorastack/phy/LoRaPHYAS923.cpp b/features/lorawan/lorastack/phy/LoRaPHYAS923.cpp index 69ec6ee94c..aa0644eddc 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYAS923.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYAS923.cpp @@ -196,9 +196,9 @@ /*! * Band 0 definition - * { DutyCycle, TxMaxPower, LastTxDoneTime, TimeOff } + * { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff } */ -#define AS923_BAND0 { 100, AS923_MAX_TX_POWER, 0, 0 } // 1.0 % +#define AS923_BAND0 { 100, AS923_MAX_TX_POWER, 0, 0, 0 } // 1.0 % /*! * LoRaMac default channel 1 @@ -823,7 +823,7 @@ bool LoRaPHYAS923::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) return false; } - if( rxConfig->Window == 0 ) + if( rxConfig->RxSlot == RX_SLOT_WIN_1 ) { // Apply window 1 frequency frequency = Channels[rxConfig->Channel].Frequency; diff --git a/features/lorawan/lorastack/phy/LoRaPHYAU915.cpp b/features/lorawan/lorastack/phy/LoRaPHYAU915.cpp index 370b9fa4b0..c402908522 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYAU915.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYAU915.cpp @@ -166,9 +166,9 @@ /*! * Band 0 definition - * { DutyCycle, TxMaxPower, LastTxDoneTime, TimeOff } + * { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff } */ -#define AU915_BAND0 { 1, AU915_MAX_TX_POWER, 0, 0 } // 100.0 % +#define AU915_BAND0 { 1, AU915_MAX_TX_POWER, 0, 0, 0 } // 100.0 % /*! * Defines the first channel for RX window 1 for US band @@ -638,7 +638,7 @@ bool LoRaPHYAU915::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) return false; } - if (rxConfig->Window == 0) { + if (rxConfig->RxSlot == RX_SLOT_WIN_1) { // Apply window 1 frequency frequency = AU915_FIRST_RX1_CHANNEL + (rxConfig->Channel % 8) * AU915_STEPWIDTH_RX1_CHANNEL; diff --git a/features/lorawan/lorastack/phy/LoRaPHYCN470.cpp b/features/lorawan/lorastack/phy/LoRaPHYCN470.cpp index 61031fb923..83a79d5226 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYCN470.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYCN470.cpp @@ -166,9 +166,9 @@ /*! * Band 0 definition - * { DutyCycle, TxMaxPower, LastTxDoneTime, TimeOff } + * { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff } */ -#define CN470_BAND0 { 1, CN470_MAX_TX_POWER, 0, 0 } // 100.0 % +#define CN470_BAND0 { 1, CN470_MAX_TX_POWER, 0, 0, 0 } // 100.0 % /*! * Defines the first channel for RX window 1 for CN470 band @@ -636,7 +636,7 @@ bool LoRaPHYCN470::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) return false; } - if( rxConfig->Window == 0 ) + if( rxConfig->RxSlot == RX_SLOT_WIN_1 ) { // Apply window 1 frequency frequency = CN470_FIRST_RX1_CHANNEL + ( rxConfig->Channel % 48 ) * CN470_STEPWIDTH_RX1_CHANNEL; diff --git a/features/lorawan/lorastack/phy/LoRaPHYCN779.cpp b/features/lorawan/lorastack/phy/LoRaPHYCN779.cpp index 9e527cc147..66435c4aff 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYCN779.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYCN779.cpp @@ -184,9 +184,9 @@ /*! * Band 0 definition - * { DutyCycle, TxMaxPower, LastTxDoneTime, TimeOff } + * { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff } */ -#define CN779_BAND0 { 100, CN779_MAX_TX_POWER, 0, 0 } // 1.0 % +#define CN779_BAND0 { 100, CN779_MAX_TX_POWER, 0, 0, 0 } // 1.0 % /*! * LoRaMac default channel 1 @@ -730,7 +730,7 @@ bool LoRaPHYCN779::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) return false; } - if( rxConfig->Window == 0 ) + if( rxConfig->RxSlot == RX_SLOT_WIN_1) { // Apply window 1 frequency frequency = Channels[rxConfig->Channel].Frequency; diff --git a/features/lorawan/lorastack/phy/LoRaPHYEU433.cpp b/features/lorawan/lorastack/phy/LoRaPHYEU433.cpp index d68d0d5bdb..94c29ca20d 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYEU433.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYEU433.cpp @@ -183,9 +183,9 @@ /*! * Band 0 definition - * { DutyCycle, TxMaxPower, LastTxDoneTime, TimeOff } + * { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff } */ -#define EU433_BAND0 { 100, EU433_MAX_TX_POWER, 0, 0 } // 1.0 % +#define EU433_BAND0 { 100, EU433_MAX_TX_POWER, 0, 0, 0 } // 1.0 % /*! * LoRaMac default channel 1 @@ -731,7 +731,7 @@ bool LoRaPHYEU433::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) return false; } - if( rxConfig->Window == 0 ) + if( rxConfig->RxSlot == RX_SLOT_WIN_1 ) { // Apply window 1 frequency frequency = Channels[rxConfig->Channel].Frequency; diff --git a/features/lorawan/lorastack/phy/LoRaPHYEU868.cpp b/features/lorawan/lorastack/phy/LoRaPHYEU868.cpp index d89054bb6a..06e4065b73 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYEU868.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYEU868.cpp @@ -179,33 +179,33 @@ /*! * Band 0 definition - * { DutyCycle, TxMaxPower, LastTxDoneTime, TimeOff } + * { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff } */ -#define EU868_BAND0 { 100 , EU868_MAX_TX_POWER, 0, 0 } // 1.0 % +#define EU868_BAND0 { 100 , EU868_MAX_TX_POWER, 0, 0, 0 } // 1.0 % /*! * Band 1 definition - * { DutyCycle, TxMaxPower, LastTxDoneTime, TimeOff } + * { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff } */ -#define EU868_BAND1 { 100 , EU868_MAX_TX_POWER, 0, 0 } // 1.0 % +#define EU868_BAND1 { 100 , EU868_MAX_TX_POWER, 0, 0, 0 } // 1.0 % /*! * Band 2 definition - * Band = { DutyCycle, TxMaxPower, LastTxDoneTime, TimeOff } + * Band = { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff } */ -#define EU868_BAND2 { 1000, EU868_MAX_TX_POWER, 0, 0 } // 0.1 % +#define EU868_BAND2 { 1000, EU868_MAX_TX_POWER, 0, 0, 0 } // 0.1 % /*! - * Band 2 definition - * Band = { DutyCycle, TxMaxPower, LastTxDoneTime, TimeOff } + * Band 3 definition + * Band = { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff } */ -#define EU868_BAND3 { 10 , EU868_MAX_TX_POWER, 0, 0 } // 10.0 % +#define EU868_BAND3 { 10 , EU868_MAX_TX_POWER, 0, 0, 0 } // 10.0 % /*! - * Band 2 definition - * Band = { DutyCycle, TxMaxPower, LastTxDoneTime, TimeOff } + * Band 4 definition + * Band = { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff } */ -#define EU868_BAND4 { 100 , EU868_MAX_TX_POWER, 0, 0 } // 1.0 % +#define EU868_BAND4 { 100 , EU868_MAX_TX_POWER, 0, 0, 0 } // 1.0 % /*! * LoRaMac default channel 1 @@ -785,7 +785,7 @@ bool LoRaPHYEU868::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) return false; } - if( rxConfig->Window == 0 ) + if( rxConfig->RxSlot == RX_SLOT_WIN_1 ) { // Apply window 1 frequency frequency = Channels[rxConfig->Channel].Frequency; diff --git a/features/lorawan/lorastack/phy/LoRaPHYIN865.cpp b/features/lorawan/lorastack/phy/LoRaPHYIN865.cpp index 26196569c5..8513dc61c2 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYIN865.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYIN865.cpp @@ -181,9 +181,9 @@ /*! * Band 0 definition - * { DutyCycle, TxMaxPower, LastTxDoneTime, TimeOff } + * { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff } */ -#define IN865_BAND0 { 1 , IN865_MAX_TX_POWER, 0, 0 } // 100.0 % +#define IN865_BAND0 { 1 , IN865_MAX_TX_POWER, 0, 0, 0 } // 100.0 % /*! * LoRaMac default channel 1 @@ -738,7 +738,7 @@ bool LoRaPHYIN865::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) return false; } - if( rxConfig->Window == 0 ) + if( rxConfig->RxSlot == RX_SLOT_WIN_1 ) { // Apply window 1 frequency frequency = Channels[rxConfig->Channel].Frequency; diff --git a/features/lorawan/lorastack/phy/LoRaPHYKR920.cpp b/features/lorawan/lorastack/phy/LoRaPHYKR920.cpp index b0229a2e8b..51806fb358 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYKR920.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYKR920.cpp @@ -186,9 +186,9 @@ /*! * Band 0 definition - * { DutyCycle, TxMaxPower, LastTxDoneTime, TimeOff } + * { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff } */ -#define KR920_BAND0 { 1 , KR920_MAX_TX_POWER, 0, 0 } // 100.0 % +#define KR920_BAND0 { 1 , KR920_MAX_TX_POWER, 0, 0, 0 } // 100.0 % /*! * LoRaMac default channel 1 @@ -759,7 +759,7 @@ bool LoRaPHYKR920::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) return false; } - if( rxConfig->Window == 0 ) + if( rxConfig->RxSlot == RX_SLOT_WIN_1 ) { // Apply window 1 frequency frequency = Channels[rxConfig->Channel].Frequency; diff --git a/features/lorawan/lorastack/phy/LoRaPHYUS915.cpp b/features/lorawan/lorastack/phy/LoRaPHYUS915.cpp index 145d079de1..9ae7ac55a2 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYUS915.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYUS915.cpp @@ -161,9 +161,9 @@ /*! * Band 0 definition - * { DutyCycle, TxMaxPower, LastTxDoneTime, TimeOff } + * { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff } */ -#define US915_BAND0 { 1, US915_MAX_TX_POWER, 0, 0 } // 100.0 % +#define US915_BAND0 { 1, US915_MAX_TX_POWER, 0, 0, 0 } // 100.0 % /*! * Defines the first channel for RX window 1 for US band @@ -683,7 +683,7 @@ bool LoRaPHYUS915::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) return false; } - if( rxConfig->Window == 0 ) + if( rxConfig->RxSlot == RX_SLOT_WIN_1 ) { // Apply window 1 frequency frequency = US915_FIRST_RX1_CHANNEL + ( rxConfig->Channel % 8 ) * US915_STEPWIDTH_RX1_CHANNEL; diff --git a/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.cpp b/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.cpp index 4137f224e9..14cff30065 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.cpp @@ -162,9 +162,9 @@ /*! * Band 0 definition - * { DutyCycle, TxMaxPower, LastTxDoneTime, TimeOff } + * { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff } */ -#define US915_HYBRID_BAND0 { 1, US915_HYBRID_MAX_TX_POWER, 0, 0 } // 100.0 % +#define US915_HYBRID_BAND0 { 1, US915_HYBRID_MAX_TX_POWER, 0, 0, 0 } // 100.0 % /*! * Defines the first channel for RX window 1 for US band @@ -771,7 +771,7 @@ bool LoRaPHYUS915Hybrid::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) return false; } - if( rxConfig->Window == 0 ) + if( rxConfig->RxSlot == RX_SLOT_WIN_1 ) { // Apply window 1 frequency frequency = US915_HYBRID_FIRST_RX1_CHANNEL + ( rxConfig->Channel % 8 ) * US915_HYBRID_STEPWIDTH_RX1_CHANNEL; diff --git a/features/lorawan/lorastack/phy/lora_phy_ds.h b/features/lorawan/lorastack/phy/lora_phy_ds.h index a364a5ef42..c3a4a53db0 100644 --- a/features/lorawan/lorastack/phy/lora_phy_ds.h +++ b/features/lorawan/lorastack/phy/lora_phy_ds.h @@ -908,9 +908,9 @@ typedef struct sRxConfigParams */ bool RxContinuous; /*! - * Sets the RX window. 0: RX window 1, 1: RX window 2. + * Sets the RX window. */ - bool Window; + LoRaMacRxSlot_t RxSlot; }RxConfigParams_t; /*! diff --git a/features/lorawan/system/LoRaWANTimer.h b/features/lorawan/system/LoRaWANTimer.h index 92d403b2be..6b5b9ac5b1 100644 --- a/features/lorawan/system/LoRaWANTimer.h +++ b/features/lorawan/system/LoRaWANTimer.h @@ -101,12 +101,4 @@ TimerTime_t TimerGetCurrentTime( void ); */ TimerTime_t TimerGetElapsedTime( TimerTime_t savedTime ); -/*! - * \brief Return the time elapsed since a fixed moment in time. - * - * \param [in] eventInFuture The fixed moment in the future. - * \retval time The difference between now and a future event. - */ -TimerTime_t TimerGetFutureTime( TimerTime_t eventInFuture ); - #endif // MBED_LORAWAN_SYS_TIMER_H__ diff --git a/features/lorawan/system/lorawan_data_structures.h b/features/lorawan/system/lorawan_data_structures.h index 0e61263e42..e24d7d858e 100644 --- a/features/lorawan/system/lorawan_data_structures.h +++ b/features/lorawan/system/lorawan_data_structures.h @@ -218,6 +218,29 @@ typedef struct sRx2ChannelParams uint8_t Datarate; }Rx2ChannelParams_t; +/*! + * LoRaMAC receive window enumeration + */ +typedef enum eLoRaMacRxSlot +{ + /*! + * LoRaMAC receive window 1 + */ + RX_SLOT_WIN_1, + /*! + * LoRaMAC receive window 2 + */ + RX_SLOT_WIN_2, + /*! + * LoRaMAC receive window 2 for class c - continuous listening + */ + RX_SLOT_WIN_CLASS_C, + /*! + * LoRaMAC class b ping slot window + */ + RX_SLOT_WIN_PING_SLOT +}LoRaMacRxSlot_t; + /*! * The global MAC layer parameters. */ @@ -290,6 +313,21 @@ typedef struct sLoRaMacParams * The antenna gain of the node. */ float AntennaGain; + + /*! + * Maximum duty cycle + * \remark Possibility to shutdown the device. + */ + uint8_t MaxDCycle; + /*! + * Aggregated duty cycle management + */ + uint16_t AggregatedDCycle; + + /*! + * LoRaMac ADR control status + */ + bool AdrCtrlOn; }LoRaMacParams_t; /*! @@ -639,6 +677,10 @@ typedef union eLoRaMacFlags_t * MLME-Req pending */ uint8_t MlmeReq : 1; + /*! + * MLME-Ind pending + */ + uint8_t MlmeInd : 1; /*! * MAC cycle done */ @@ -908,7 +950,7 @@ typedef struct sMcpsIndication * * [0: Rx window 1, 1: Rx window 2] */ - uint8_t RxSlot; + LoRaMacRxSlot_t RxSlot; /*! * Set if an acknowledgement was received. */ @@ -925,11 +967,12 @@ typedef struct sMcpsIndication * \details The following table list the primitives supported by a * specific MAC management service: * - * Name | Request | Indication | Response | Confirm - * --------------------- | :-----: | :--------: | :------: | :-----: - * \ref MLME_JOIN | YES | NO | NO | YES - * \ref MLME_LINK_CHECK | YES | NO | NO | YES - * \ref MLME_TXCW | YES | NO | NO | YES + * Name | Request | Indication | Response | Confirm + * ---------------------------- | :-----: | :--------: | :------: | :-----: + * \ref MLME_JOIN | YES | NO | NO | YES + * \ref MLME_LINK_CHECK | YES | NO | NO | YES + * \ref MLME_TXCW | YES | NO | NO | YES + * \ref MLME_SCHEDULE_UPLINK | NO | YES | NO | NO * * The following table provides links to the function implementations of the * related MLME primitives. @@ -938,6 +981,7 @@ typedef struct sMcpsIndication * ---------------- | :---------------------: * MLME-Request | \ref LoRaMacMlmeRequest * MLME-Confirm | MacMlmeConfirm in \ref LoRaMacPrimitives_t + * MLME-Indication | MacMlmeIndication in \ref LoRaMacPrimitives_t */ typedef enum eMlme { @@ -965,6 +1009,11 @@ typedef enum eMlme * LoRaWAN end-device certification. */ MLME_TXCW_1, + /*! + * Indicates that the application shall perform an uplink as + * soon as possible. + */ + MLME_SCHEDULE_UPLINK }Mlme_t; /*! @@ -1073,6 +1122,17 @@ typedef struct sMlmeConfirm uint8_t NbRetries; }MlmeConfirm_t; +/*! + * LoRaMAC MLME-Indication primitive + */ +typedef struct sMlmeIndication +{ + /*! + * MLME-Indication type + */ + Mlme_t MlmeIndication; +}MlmeIndication_t; + /*! * LoRa MAC Information Base (MIB). * @@ -1618,6 +1678,13 @@ typedef struct sLoRaMacPrimitives * \param [OUT] MLME-Confirm parameters. */ mbed::Callback MacMlmeConfirm; + + /*! + * \brief MLME-Indication primitive + * + * \param [OUT] MLME-Indication parameters + */ + mbed::Callback MacMlmeIndication; }LoRaMacPrimitives_t; /*! diff --git a/features/netsocket/LoRaRadio.h b/features/netsocket/LoRaRadio.h index 4d5f48d597..e63db1da84 100644 --- a/features/netsocket/LoRaRadio.h +++ b/features/netsocket/LoRaRadio.h @@ -131,17 +131,18 @@ typedef struct radio_settings { * */ typedef struct radio_events { - /* Tx Done callback prototype. - * + /** + * Callback when Transmission is done */ - void (*tx_done) (void); + mbed::Callback tx_done; - /* Tx Timeout callback prototype. - * + /** + * Callback when Transmission is timed out */ - void (*tx_timeout) (void); + mbed::Callback tx_timeout; - /* Rx Done callback prototype. + /** + * Rx Done callback prototype. * * @param payload Received buffer pointer. * @param size Received buffer size. @@ -150,29 +151,31 @@ typedef struct radio_events { * FSK : N/A (set to 0) * LoRa: SNR value in dB */ - void (*rx_done) (uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr); + mbed::Callback rx_done; - /* Rx Timeout callback prototype. - * + /** + * Callback when Reception is timed out */ - void (*rx_timeout) (void); + mbed::Callback rx_timeout; - /* Rx Error callback prototype. - * + /** + * Callback when Reception ends up in error */ - void (*rx_error) (void); + mbed::Callback rx_error; - /* FHSS Change Channel callback prototype. - * - * @param current_channel The index number of the current channel. - */ - void (*fhss_change_channel) (uint8_t current_channel); + /** + * FHSS Change Channel callback prototype. + * + * @param current_channel The index number of the current channel. + */ + mbed::Callback fhss_change_channel; - /* CAD Done callback prototype. + /** + * CAD Done callback prototype. * - * @param channel_activity_detected Channel activity detected during the CAD. + * @param channel_busy True, if Channel activity detected. */ - void (*cad_done) (bool channel_activity_detected); + mbed::Callback cad_done; } radio_events_t; /** diff --git a/features/netsocket/LoRaWANBase.h b/features/netsocket/LoRaWANBase.h index b4a6ca815a..98a29f5004 100644 --- a/features/netsocket/LoRaWANBase.h +++ b/features/netsocket/LoRaWANBase.h @@ -64,6 +64,39 @@ public: */ virtual lora_mac_status_t disconnect() = 0; + /** Validate the connectivity with the network. + * + * Application may use this API to submit a request to the stack for + * validation of its connectivity to a Network Server. Under the hood, this + * API schedules a Link Check Request command (LinkCheckReq) for the network + * server and once the response, i.e., LinkCheckAns MAC command is received + * from the Network Server, user provided method is called. + * + * This API is usable only when the link check response is callback set by + * the application. See add_lora_app_callbacks API. If the above mentioned + * callback is not set, a LORA_MAC_STATUS_PARAMETER_INVALID error is thrown. + * + * First parameter to callback function is the demodulation margin and + * the second parameter is the number of gateways that successfully received + * the last request. + * + * A 'Link Check Request' MAC command remains set for every subsequent + * transmission, until/unless application explicitly turns it off using + * remove_link_check_request() API. + * + * @param cb A callback function to receive link check response + * @return LORA_MAC_STATUS_OK on successfully queuing a request, or + * a negative error code on failure. + * + */ + virtual lora_mac_status_t add_link_check_request() = 0; + + /** Detaches Link Request MAC command. + * + * Removes sticky MAC command for link check request. + */ + virtual void remove_link_check_request() = 0; + /** Sets up a particular data rate of choice * * @param data_rate Intended data rate e.g., DR_0, DR_1 etc. From e18d76aa7e71f61a164477492eb374131ced9f67 Mon Sep 17 00:00:00 2001 From: Kimmo Vaisanen Date: Fri, 5 Jan 2018 15:03:22 +0200 Subject: [PATCH 03/23] Change LoRaWANTimer to a C++ class LoRaWANTimer is now called as LoRaWANTimeHandler class as this class handles both current time and timer functionalities. Some refactoring on how LoRa objects are created was needed: - LoRaWANTimeHandler object is created by LoRaWANStack and shares with LoRaMac and PHY. - LoRaPHY object is now member of LoRaWANStack class instead of static variable in source file. --- features/lorawan/LoRaWANStack.cpp | 68 +++------- features/lorawan/LoRaWANStack.h | 38 ++++++ features/lorawan/lorastack/mac/LoRaMac.cpp | 93 +++++++------- features/lorawan/lorastack/mac/LoRaMac.h | 4 +- features/lorawan/lorastack/phy/LoRaPHY.cpp | 13 +- features/lorawan/lorastack/phy/LoRaPHY.h | 3 +- .../lorawan/lorastack/phy/LoRaPHYAS923.cpp | 7 +- features/lorawan/lorastack/phy/LoRaPHYAS923.h | 2 +- .../lorawan/lorastack/phy/LoRaPHYAU915.cpp | 7 +- features/lorawan/lorastack/phy/LoRaPHYAU915.h | 2 +- .../lorawan/lorastack/phy/LoRaPHYCN470.cpp | 7 +- features/lorawan/lorastack/phy/LoRaPHYCN470.h | 2 +- .../lorawan/lorastack/phy/LoRaPHYCN779.cpp | 7 +- features/lorawan/lorastack/phy/LoRaPHYCN779.h | 2 +- .../lorawan/lorastack/phy/LoRaPHYEU433.cpp | 7 +- features/lorawan/lorastack/phy/LoRaPHYEU433.h | 2 +- .../lorawan/lorastack/phy/LoRaPHYEU868.cpp | 7 +- features/lorawan/lorastack/phy/LoRaPHYEU868.h | 2 +- .../lorawan/lorastack/phy/LoRaPHYIN865.cpp | 7 +- features/lorawan/lorastack/phy/LoRaPHYIN865.h | 2 +- .../lorawan/lorastack/phy/LoRaPHYKR920.cpp | 7 +- features/lorawan/lorastack/phy/LoRaPHYKR920.h | 2 +- .../lorawan/lorastack/phy/LoRaPHYUS915.cpp | 7 +- features/lorawan/lorastack/phy/LoRaPHYUS915.h | 2 +- .../lorastack/phy/LoRaPHYUS915Hybrid.cpp | 7 +- .../lorastack/phy/LoRaPHYUS915Hybrid.h | 2 +- features/lorawan/system/LoRaWANTimer.cpp | 23 ++-- features/lorawan/system/LoRaWANTimer.h | 117 +++++++++--------- 28 files changed, 239 insertions(+), 210 deletions(-) diff --git a/features/lorawan/LoRaWANStack.cpp b/features/lorawan/LoRaWANStack.cpp index 261e20add5..1fb676228f 100644 --- a/features/lorawan/LoRaWANStack.cpp +++ b/features/lorawan/LoRaWANStack.cpp @@ -41,42 +41,6 @@ SPDX-License-Identifier: BSD-3-Clause #define INVALID_PORT 0xFF #define MAX_CONFIRMED_MSG_RETRIES 255 -#ifdef MBED_CONF_LORA_PHY - #if MBED_CONF_LORA_PHY == 0 - #include "lorawan/lorastack/phy/LoRaPHYEU868.h" - static SingletonPtr lora_phy; - #elif MBED_CONF_LORA_PHY == 1 - #include "lorawan/lorastack/phy/LoRaPHYAS923.h" - static SingletonPtr lora_phy; - #elif MBED_CONF_LORA_PHY == 2 - #include "lorawan/lorastack/phy/LoRaPHYAU915.h" - static SingletonPtr lora_phy; - #elif MBED_CONF_LORA_PHY == 3 - #include "lorawan/lorastack/phy/LoRaPHYCN470.h" - static SingletonPtr lora_phy; - #elif MBED_CONF_LORA_PHY == 4 - #include "lorawan/lorastack/phy/LoRaPHYCN779.h" - static SingletonPtr lora_phy; - #elif MBED_CONF_LORA_PHY == 5 - #include "lorawan/lorastack/phy/LoRaPHYEU433.h" - static SingletonPtr lora_phy; - #elif MBED_CONF_LORA_PHY == 6 - #include "lorawan/lorastack/phy/LoRaPHYIN865.h" - static SingletonPtr lora_phy; - #elif MBED_CONF_LORA_PHY == 7 - #include "lorawan/lorastack/phy/LoRaPHYKR920.h" - static SingletonPtr lora_phy; - #elif MBED_CONF_LORA_PHY == 8 - #include "lorawan/lorastack/phy/LoRaPHYUS915.h" - static SingletonPtr lora_phy; - #elif MBED_CONF_LORA_PHY == 9 - #include "lorawan/lorastack/phy/LoRaPHYUS915Hybrid.h" - static SingletonPtr lora_phy; - #endif //MBED_CONF_LORA_PHY == VALUE -#else - #error "Must set LoRa PHY layer parameters." -#endif //MBED_CONF_LORA_PHY - using namespace mbed; using namespace events; @@ -128,8 +92,9 @@ lora_mac_status_t LoRaWANStack::set_application_port(uint8_t port) * Constructor and destructor * ****************************************************************************/ LoRaWANStack::LoRaWANStack() -: _device_current_state(DEVICE_STATE_NOT_INITIALIZED), _mac_handlers(NULL), - _num_retry(1), _queue(NULL), _duty_cycle_on(LORAWAN_DUTYCYCLE_ON) +: _loramac(_lora_time), _lora_phy(_lora_time), + _device_current_state(DEVICE_STATE_NOT_INITIALIZED), _mac_handlers(NULL), + _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 @@ -170,7 +135,7 @@ radio_events_t *LoRaWANStack::bind_radio_driver(LoRaRadio& radio) // Store pointer to callback routines inside MAC layer (non-IRQ safe) _mac_handlers = _loramac.GetPhyEventHandlers(); // passes the reference to radio driver down to PHY layer - lora_phy.get()->set_radio_instance(radio); + _lora_phy.set_radio_instance(radio); return _mac_handlers; } @@ -200,12 +165,13 @@ lora_mac_status_t LoRaWANStack::initialize_mac_layer(EventQueue *queue) _compliance_test.app_data_buffer = compliance_test_buffer; #endif - TimerTimeCounterInit(queue); + _lora_time.TimerTimeCounterInit(queue); + LoRaMacPrimitives.MacMcpsConfirm = callback(this, &LoRaWANStack::mcps_confirm); LoRaMacPrimitives.MacMcpsIndication = callback(this, &LoRaWANStack::mcps_indication); LoRaMacPrimitives.MacMlmeConfirm = callback(this, &LoRaWANStack::mlme_confirm); LoRaMacPrimitives.MacMlmeIndication = callback(this, &LoRaWANStack::mlme_indication); - _loramac.LoRaMacInitialization(&LoRaMacPrimitives, &LoRaMacCallbacks, lora_phy.get(), queue); + _loramac.LoRaMacInitialization(&LoRaMacPrimitives, &LoRaMacCallbacks, &_lora_phy, queue); mib_req.type = LORA_MIB_ADR; mib_req.param.adr_enable = LORAWAN_ADR_ON; @@ -276,7 +242,7 @@ lora_mac_status_t LoRaWANStack::send_compliance_test_frame_to_mac() GetPhyParams_t phy_params; PhyParam_t default_datarate; phy_params.Attribute = PHY_DEF_TX_DR; - default_datarate = lora_phy.get_phy_params(&phy_params); + default_datarate = _lora_phy.get_phy_params(&phy_params); prepare_special_tx_frame(_compliance_test.app_port); @@ -338,7 +304,7 @@ lora_mac_status_t LoRaWANStack::send_frame_to_mac() GetPhyParams_t phy_params; PhyParam_t default_datarate; phy_params.Attribute = PHY_DEF_TX_DR; - default_datarate = lora_phy.get()->get_phy_params(&phy_params); + default_datarate = _lora_phy.get_phy_params(&phy_params); mcps_req.type = _tx_msg.type; @@ -514,7 +480,7 @@ lora_mac_status_t LoRaWANStack::add_channels(const lora_channelplan_t &channel_p // Check first how many channels the selected PHY layer supports get_phy.Attribute = PHY_MAX_NB_CHANNELS; - phy_param = lora_phy.get()->get_phy_params(&get_phy); + phy_param = _lora_phy.get_phy_params(&get_phy); max_num_channels = (uint8_t) phy_param.Value; // check if user is setting more channels than supported @@ -558,17 +524,17 @@ lora_mac_status_t LoRaWANStack::drop_channel_list() // Check first how many channels the selected PHY layer supports get_phy.Attribute = PHY_MAX_NB_CHANNELS; - phy_param = lora_phy.get()->get_phy_params(&get_phy); + phy_param = _lora_phy.get_phy_params(&get_phy); max_num_channels = (uint8_t) phy_param.Value; // Now check the channel mask for enabled channels get_phy.Attribute = PHY_CHANNELS_MASK; - phy_param = lora_phy.get()->get_phy_params(&get_phy); + phy_param = _lora_phy.get_phy_params(&get_phy); channel_masks = phy_param.ChannelsMask; // Now check the channel mask for default channels get_phy.Attribute = PHY_CHANNELS_DEFAULT_MASK; - phy_param = lora_phy.get()->get_phy_params(&get_phy); + phy_param = _lora_phy.get_phy_params(&get_phy); default_channel_masks = phy_param.ChannelsMask; for (uint8_t i = 0; i < max_num_channels; i++) { @@ -607,7 +573,7 @@ lora_mac_status_t LoRaWANStack::remove_a_channel(uint8_t channel_id) // Check first how many channels the selected PHY layer supports get_phy.Attribute = PHY_MAX_NB_CHANNELS; - phy_param = lora_phy.get()->get_phy_params(&get_phy); + phy_param = _lora_phy.get_phy_params(&get_phy); max_num_channels = (uint8_t) phy_param.Value; // According to specification channel IDs start from 0 and last valid @@ -619,7 +585,7 @@ lora_mac_status_t LoRaWANStack::remove_a_channel(uint8_t channel_id) // Now check the Default channel mask get_phy.Attribute = PHY_CHANNELS_DEFAULT_MASK; - phy_param = lora_phy.get()->get_phy_params(&get_phy); + phy_param = _lora_phy.get_phy_params(&get_phy); channel_masks = phy_param.ChannelsMask; // check if the channel ID give belongs to a default channel @@ -654,12 +620,12 @@ lora_mac_status_t LoRaWANStack::get_enabled_channels(lora_channelplan_t& channel // Check first how many channels the selected PHY layer supports get_phy.Attribute = PHY_MAX_NB_CHANNELS; - phy_param = lora_phy.get()->get_phy_params(&get_phy); + phy_param = _lora_phy.get_phy_params(&get_phy); max_num_channels = (uint8_t) phy_param.Value; // Now check the Default channel mask get_phy.Attribute = PHY_CHANNELS_MASK; - phy_param = lora_phy.get()->get_phy_params(&get_phy); + phy_param = _lora_phy.get_phy_params(&get_phy); channel_masks = phy_param.ChannelsMask; // Request Mib to get channels diff --git a/features/lorawan/LoRaWANStack.h b/features/lorawan/LoRaWANStack.h index 4dbfe7f313..d04aced43f 100644 --- a/features/lorawan/LoRaWANStack.h +++ b/features/lorawan/LoRaWANStack.h @@ -35,6 +35,42 @@ SPDX-License-Identifier: BSD-3-Clause #include "lorawan/system/lorawan_data_structures.h" #include "LoRaRadio.h" +#ifdef MBED_CONF_LORA_PHY + #if MBED_CONF_LORA_PHY == 0 + #include "lorawan/lorastack/phy/LoRaPHYEU868.h" + #define LoRaPHY_region LoRaPHYEU868 + #elif MBED_CONF_LORA_PHY == 1 + #include "lorawan/lorastack/phy/LoRaPHYAS923.h" + #define LoRaPHY_region LoRaPHYAS923 + #elif MBED_CONF_LORA_PHY == 2 + #include "lorawan/lorastack/phy/LoRaPHYAU915.h" + #define LoRaPHY_region LoRaPHYAU915; + #elif MBED_CONF_LORA_PHY == 3 + #include "lorawan/lorastack/phy/LoRaPHYCN470.h" + #define LoRaPHY_region LoRaPHYCN470 + #elif MBED_CONF_LORA_PHY == 4 + #include "lorawan/lorastack/phy/LoRaPHYCN779.h" + #define LoRaPHY_region LoRaPHYCN779 + #elif MBED_CONF_LORA_PHY == 5 + #include "lorawan/lorastack/phy/LoRaPHYEU433.h" + #define LoRaPHY_region LoRaPHYEU433 + #elif MBED_CONF_LORA_PHY == 6 + #include "lorawan/lorastack/phy/LoRaPHYIN865.h" + #define LoRaPHY_region LoRaPHYIN865 + #elif MBED_CONF_LORA_PHY == 7 + #include "lorawan/lorastack/phy/LoRaPHYKR920.h" + #define LoRaPHY_region LoRaPHYKR920 + #elif MBED_CONF_LORA_PHY == 8 + #include "lorawan/lorastack/phy/LoRaPHYUS915.h" + #define LoRaPHY_region LoRaPHYUS915 + #elif MBED_CONF_LORA_PHY == 9 + #include "lorawan/lorastack/phy/LoRaPHYUS915Hybrid.h" + #define LoRaPHY_region LoRaPHYUS915Hybrid + #endif //MBED_CONF_LORA_PHY == VALUE +#else + #error "Must set LoRa PHY layer parameters." +#endif //MBED_CONF_LORA_PHY + /** * A mask for the network ID. */ @@ -429,7 +465,9 @@ private: */ lora_mac_status_t error_type_converter(LoRaMacStatus_t type); + LoRaWANTimeHandler _lora_time; LoRaMac _loramac; + LoRaPHY_region _lora_phy; #if defined(LORAWAN_COMPLIANCE_TEST) compliance_test_t _compliance_test; diff --git a/features/lorawan/lorastack/mac/LoRaMac.cpp b/features/lorawan/lorastack/mac/LoRaMac.cpp index 81d4b6e046..373c825f97 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.cpp +++ b/features/lorawan/lorastack/mac/LoRaMac.cpp @@ -89,8 +89,9 @@ static LoRaMac* isrHandler = NULL; #define DOWN_LINK 1 -LoRaMac::LoRaMac() - : mac_commands(*this) +LoRaMac::LoRaMac(LoRaWANTimeHandler &lora_time) + : mac_commands(*this), + _lora_time(lora_time) { isrHandler = this; @@ -239,7 +240,7 @@ void LoRaMac::OnRadioTxDone( void ) GetPhyParams_t getPhy; PhyParam_t phyParam; SetBandTxDoneParams_t txDone; - TimerTime_t curTime = TimerGetCurrentTime( ); + TimerTime_t curTime = _lora_time.TimerGetCurrentTime( ); if( LoRaMacDeviceClass != CLASS_C ) { @@ -253,19 +254,19 @@ void LoRaMac::OnRadioTxDone( void ) // Setup timers if( IsRxWindowsEnabled == true ) { - TimerSetValue( &RxWindowTimer1, RxWindow1Delay ); - TimerStart( &RxWindowTimer1 ); + _lora_time.TimerSetValue( &RxWindowTimer1, RxWindow1Delay ); + _lora_time.TimerStart( &RxWindowTimer1 ); if( LoRaMacDeviceClass != CLASS_C ) { - TimerSetValue( &RxWindowTimer2, RxWindow2Delay ); - TimerStart( &RxWindowTimer2 ); + _lora_time.TimerSetValue( &RxWindowTimer2, RxWindow2Delay ); + _lora_time.TimerStart( &RxWindowTimer2 ); } if( ( LoRaMacDeviceClass == CLASS_C ) || ( NodeAckRequested == true ) ) { getPhy.Attribute = PHY_ACK_TIMEOUT; phyParam = lora_phy->get_phy_params(&getPhy); - TimerSetValue( &AckTimeoutTimer, RxWindow2Delay + phyParam.Value ); - TimerStart( &AckTimeoutTimer ); + _lora_time.TimerSetValue( &AckTimeoutTimer, RxWindow2Delay + phyParam.Value ); + _lora_time.TimerStart( &AckTimeoutTimer ); } } else @@ -320,8 +321,8 @@ void LoRaMac::PrepareRxDoneAbort( void ) LoRaMacFlags.Bits.MacDone = 1; // Trig OnMacCheckTimerEvent call as soon as possible - TimerSetValue( &MacStateCheckTimer, 1 ); - TimerStart( &MacStateCheckTimer ); + _lora_time.TimerSetValue( &MacStateCheckTimer, 1 ); + _lora_time.TimerStart( &MacStateCheckTimer ); } void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) @@ -370,7 +371,7 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 lora_phy->put_radio_to_sleep(); - TimerStop( &RxWindowTimer2 ); + _lora_time.TimerStop( &RxWindowTimer2 ); macHdr.Value = payload[pktHeaderLen++]; @@ -711,7 +712,7 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 // Stop the AckTimeout timer as no more retransmissions // are needed. - TimerStop( &AckTimeoutTimer ); + _lora_time.TimerStop( &AckTimeoutTimer ); } else { @@ -721,7 +722,7 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 { // Stop the AckTimeout timer as no more retransmissions // are needed. - TimerStop( &AckTimeoutTimer ); + _lora_time.TimerStop( &AckTimeoutTimer ); } } } @@ -759,8 +760,8 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 LoRaMacFlags.Bits.MacDone = 1; // Trig OnMacCheckTimerEvent call as soon as possible - TimerSetValue( &MacStateCheckTimer, 1 ); - TimerStart( &MacStateCheckTimer ); + _lora_time.TimerSetValue( &MacStateCheckTimer, 1 ); + _lora_time.TimerStart( &MacStateCheckTimer ); } void LoRaMac::OnRadioTxTimeout( void ) @@ -798,9 +799,9 @@ void LoRaMac::OnRadioRxError( void ) } MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX1_ERROR; - if( TimerGetElapsedTime( AggregatedLastTxDoneTime ) >= RxWindow2Delay ) + if( _lora_time.TimerGetElapsedTime( AggregatedLastTxDoneTime ) >= RxWindow2Delay ) { - TimerStop( &RxWindowTimer2 ); + _lora_time.TimerStop( &RxWindowTimer2 ); LoRaMacFlags.Bits.MacDone = 1; } } @@ -834,9 +835,9 @@ void LoRaMac::OnRadioRxTimeout( void ) } MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX1_TIMEOUT; - if( TimerGetElapsedTime( AggregatedLastTxDoneTime ) >= RxWindow2Delay ) + if( _lora_time.TimerGetElapsedTime( AggregatedLastTxDoneTime ) >= RxWindow2Delay ) { - TimerStop( &RxWindowTimer2 ); + _lora_time.TimerStop( &RxWindowTimer2 ); LoRaMacFlags.Bits.MacDone = 1; } } @@ -864,7 +865,7 @@ void LoRaMac::OnMacStateCheckTimerEvent( void ) PhyParam_t phyParam; bool txTimeout = false; - TimerStop( &MacStateCheckTimer ); + _lora_time.TimerStop( &MacStateCheckTimer ); if( LoRaMacFlags.Bits.MacDone == 1 ) { @@ -1048,8 +1049,8 @@ void LoRaMac::OnMacStateCheckTimerEvent( void ) else { // Operation not finished restart timer - TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT ); - TimerStart( &MacStateCheckTimer ); + _lora_time.TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT ); + _lora_time.TimerStart( &MacStateCheckTimer ); } // Handle MCPS indication @@ -1081,7 +1082,7 @@ void LoRaMac::OnTxDelayedTimerEvent( void ) LoRaMacFrameCtrl_t fCtrl; AlternateDrParams_t altDr; - TimerStop( &TxDelayedTimer ); + _lora_time.TimerStop( &TxDelayedTimer ); LoRaMacState &= ~LORAMAC_TX_DELAYED; if( ( LoRaMacFlags.Bits.MlmeReq == 1 ) && ( MlmeConfirm.MlmeRequest == MLME_JOIN ) ) @@ -1108,7 +1109,7 @@ void LoRaMac::OnTxDelayedTimerEvent( void ) void LoRaMac::OnRxWindow1TimerEvent( void ) { - TimerStop( &RxWindowTimer1 ); + _lora_time.TimerStop( &RxWindowTimer1 ); RxSlot = RX_SLOT_WIN_1; RxWindow1Config.Channel = Channel; @@ -1129,7 +1130,7 @@ void LoRaMac::OnRxWindow1TimerEvent( void ) void LoRaMac::OnRxWindow2TimerEvent( void ) { - TimerStop( &RxWindowTimer2 ); + _lora_time.TimerStop( &RxWindowTimer2 ); RxWindow2Config.Channel = Channel; RxWindow2Config.Frequency = LoRaMacParams.Rx2Channel.Frequency; @@ -1156,7 +1157,7 @@ void LoRaMac::OnRxWindow2TimerEvent( void ) void LoRaMac::OnAckTimeoutTimerEvent( void ) { - TimerStop( &AckTimeoutTimer ); + _lora_time.TimerStop( &AckTimeoutTimer ); if( NodeAckRequested == true ) { @@ -1321,8 +1322,8 @@ LoRaMacStatus_t LoRaMac::ScheduleTx( void ) LoRaMacState |= LORAMAC_TX_DELAYED; tr_debug("Next Transmission in %lu ms", dutyCycleTimeOff); - TimerSetValue( &TxDelayedTimer, dutyCycleTimeOff ); - TimerStart( &TxDelayedTimer ); + _lora_time.TimerSetValue( &TxDelayedTimer, dutyCycleTimeOff ); + _lora_time.TimerStart( &TxDelayedTimer ); return LORAMAC_STATUS_OK; } @@ -1336,7 +1337,7 @@ void LoRaMac::CalculateBackOff( uint8_t channel ) DutyCycleOn = LORAWAN_DUTYCYCLE_ON; calcBackOff.DutyCycleEnabled = DutyCycleOn; calcBackOff.Channel = channel; - calcBackOff.ElapsedTime = TimerGetElapsedTime( LoRaMacInitializationTime ); + calcBackOff.ElapsedTime = _lora_time.TimerGetElapsedTime( LoRaMacInitializationTime ); calcBackOff.TxTimeOnAir = TxTimeOnAir; calcBackOff.LastTxIsJoinRequest = LastTxIsJoinRequest; @@ -1620,8 +1621,8 @@ LoRaMacStatus_t LoRaMac::SendFrameOnChannel( uint8_t channel ) MlmeConfirm.TxTimeOnAir = TxTimeOnAir; // Starts the MAC layer status check timer - TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT ); - TimerStart( &MacStateCheckTimer ); + _lora_time.TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT ); + _lora_time.TimerStart( &MacStateCheckTimer ); if( IsLoRaMacNetworkJoined == false ) { @@ -1650,8 +1651,8 @@ LoRaMacStatus_t LoRaMac::SetTxContinuousWave( uint16_t timeout ) lora_phy->set_tx_cont_mode(&continuousWave); // Starts the MAC layer status check timer - TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT ); - TimerStart( &MacStateCheckTimer ); + _lora_time.TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT ); + _lora_time.TimerStart( &MacStateCheckTimer ); LoRaMacState |= LORAMAC_TX_RUNNING; @@ -1663,8 +1664,8 @@ LoRaMacStatus_t LoRaMac::SetTxContinuousWave1( uint16_t timeout, uint32_t freque lora_phy->setup_tx_cont_wave_mode(frequency, power, timeout); // Starts the MAC layer status check timer - TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT ); - TimerStart( &MacStateCheckTimer ); + _lora_time.TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT ); + _lora_time.TimerStart( &MacStateCheckTimer ); LoRaMacState |= LORAMAC_TX_RUNNING; @@ -1793,16 +1794,16 @@ LoRaMacStatus_t LoRaMac::LoRaMacInitialization(LoRaMacPrimitives_t *primitives, lora_phy->put_radio_to_sleep(); // Initialize timers - TimerInit(&MacStateCheckTimer, handle_mac_state_check_timer_event); - TimerSetValue(&MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT); + _lora_time.TimerInit(&MacStateCheckTimer, handle_mac_state_check_timer_event); + _lora_time.TimerSetValue(&MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT); - TimerInit(&TxDelayedTimer, handle_delayed_tx_timer_event); - TimerInit(&RxWindowTimer1, handle_rx1_timer_event); - TimerInit(&RxWindowTimer2, handle_rx2_timer_event); - TimerInit(&AckTimeoutTimer, handle_ack_timeout); + _lora_time.TimerInit(&TxDelayedTimer, handle_delayed_tx_timer_event); + _lora_time.TimerInit(&RxWindowTimer1, handle_rx1_timer_event); + _lora_time.TimerInit(&RxWindowTimer2, handle_rx2_timer_event); + _lora_time.TimerInit(&AckTimeoutTimer, handle_ack_timeout); // Store the current initialization time - LoRaMacInitializationTime = TimerGetCurrentTime(); + LoRaMacInitializationTime = _lora_time.TimerGetCurrentTime(); return LORAMAC_STATUS_OK; } @@ -2709,8 +2710,8 @@ radio_events_t *LoRaMac::GetPhyEventHandlers() LoRaMacStatus_t LoRaMac::LoRaMacSetTxTimer( uint32_t TxDutyCycleTime ) { - TimerSetValue(&TxNextPacketTimer, TxDutyCycleTime); - TimerStart(&TxNextPacketTimer); + _lora_time.TimerSetValue(&TxNextPacketTimer, TxDutyCycleTime); + _lora_time.TimerStart(&TxNextPacketTimer); return LORAMAC_STATUS_OK; } @@ -2718,7 +2719,7 @@ LoRaMacStatus_t LoRaMac::LoRaMacSetTxTimer( uint32_t TxDutyCycleTime ) LoRaMacStatus_t LoRaMac::LoRaMacStopTxTimer( ) { - TimerStop(&TxNextPacketTimer); + _lora_time.TimerStop(&TxNextPacketTimer); return LORAMAC_STATUS_OK; } diff --git a/features/lorawan/lorastack/mac/LoRaMac.h b/features/lorawan/lorastack/mac/LoRaMac.h index 09381e52f9..a346c7bcb8 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.h +++ b/features/lorawan/lorastack/mac/LoRaMac.h @@ -60,7 +60,7 @@ public: /*! * \brief Constructor */ - LoRaMac(); + LoRaMac(LoRaWANTimeHandler &lora_time); /*! * \brief Destructor @@ -611,6 +611,8 @@ private: LoRaMacCommand mac_commands; + LoRaWANTimeHandler &_lora_time; + /** * Radio event callback handlers for MAC diff --git a/features/lorawan/lorastack/phy/LoRaPHY.cpp b/features/lorawan/lorastack/phy/LoRaPHY.cpp index 7f3019e08c..80b20df2b0 100644 --- a/features/lorawan/lorastack/phy/LoRaPHY.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHY.cpp @@ -27,7 +27,7 @@ SPDX-License-Identifier: BSD-3-Clause #include #include #include "lorawan/lorastack/phy/LoRaPHY.h" -#include "lorawan/system/LoRaWANTimer.h" + #define BACKOFF_DC_1_HOUR 100 #define BACKOFF_DC_10_HOURS 1000 @@ -47,7 +47,8 @@ static uint8_t CountChannels( uint16_t mask, uint8_t nbBits ) return nbActiveBits; } -LoRaPHY::LoRaPHY() +LoRaPHY::LoRaPHY(LoRaWANTimeHandler &lora_time) + : _lora_time(lora_time) { } @@ -245,8 +246,8 @@ TimerTime_t LoRaPHY::update_band_timeoff( bool joined, bool dutyCycle, Band_t* b { if( joined == false ) { - uint32_t txDoneTime = MAX( TimerGetElapsedTime( bands[i].LastJoinTxDoneTime ), - ( dutyCycle == true ) ? TimerGetElapsedTime( bands[i].LastTxDoneTime ) : 0 ); + uint32_t txDoneTime = MAX( _lora_time.TimerGetElapsedTime( bands[i].LastJoinTxDoneTime ), + ( dutyCycle == true ) ? _lora_time.TimerGetElapsedTime( bands[i].LastTxDoneTime ) : 0 ); if( bands[i].TimeOff <= txDoneTime ) { @@ -261,13 +262,13 @@ TimerTime_t LoRaPHY::update_band_timeoff( bool joined, bool dutyCycle, Band_t* b { if( dutyCycle == true ) { - if( bands[i].TimeOff <= TimerGetElapsedTime( bands[i].LastTxDoneTime ) ) + if( bands[i].TimeOff <= _lora_time.TimerGetElapsedTime( bands[i].LastTxDoneTime ) ) { bands[i].TimeOff = 0; } if( bands[i].TimeOff != 0 ) { - nextTxDelay = MIN( bands[i].TimeOff - TimerGetElapsedTime( bands[i].LastTxDoneTime ), + nextTxDelay = MIN( bands[i].TimeOff - _lora_time.TimerGetElapsedTime( bands[i].LastTxDoneTime ), nextTxDelay ); } } diff --git a/features/lorawan/lorastack/phy/LoRaPHY.h b/features/lorawan/lorastack/phy/LoRaPHY.h index 2ab7eb7acf..057bcfbf7f 100644 --- a/features/lorawan/lorastack/phy/LoRaPHY.h +++ b/features/lorawan/lorastack/phy/LoRaPHY.h @@ -41,7 +41,7 @@ class LoRaPHY { public: - LoRaPHY(); + LoRaPHY(LoRaWANTimeHandler &lora_time); virtual ~LoRaPHY(); void set_radio_instance(LoRaRadio& radio); @@ -339,6 +339,7 @@ public: protected: LoRaRadio *_radio; + LoRaWANTimeHandler &_lora_time; typedef struct sRegionCommonLinkAdrParams { diff --git a/features/lorawan/lorastack/phy/LoRaPHYAS923.cpp b/features/lorawan/lorastack/phy/LoRaPHYAS923.cpp index aa0644eddc..17e3355775 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYAS923.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYAS923.cpp @@ -363,7 +363,8 @@ uint8_t LoRaPHYAS923::CountNbOfEnabledChannels(bool joined, uint8_t datarate, return nbEnabledChannels; } -LoRaPHYAS923::LoRaPHYAS923() +LoRaPHYAS923::LoRaPHYAS923(LoRaWANTimeHandler &lora_time) + : LoRaPHY(lora_time) { const Band_t band0 = AS923_BAND0; Bands[0] = band0; @@ -1160,7 +1161,7 @@ bool LoRaPHYAS923::set_next_channel(NextChanParams_t* nextChanParams, ChannelsMask[0] |= LC( 1 ) + LC( 2 ); } - if( nextChanParams->AggrTimeOff <= TimerGetElapsedTime( nextChanParams->LastAggrTx ) ) + if( nextChanParams->AggrTimeOff <= _lora_time.TimerGetElapsedTime( nextChanParams->LastAggrTx ) ) { // Reset Aggregated time off *aggregatedTimeOff = 0; @@ -1176,7 +1177,7 @@ bool LoRaPHYAS923::set_next_channel(NextChanParams_t* nextChanParams, else { delayTx++; - nextTxDelay = nextChanParams->AggrTimeOff - TimerGetElapsedTime( nextChanParams->LastAggrTx ); + nextTxDelay = nextChanParams->AggrTimeOff - _lora_time.TimerGetElapsedTime( nextChanParams->LastAggrTx ); } if( nbEnabledChannels > 0 ) diff --git a/features/lorawan/lorastack/phy/LoRaPHYAS923.h b/features/lorawan/lorastack/phy/LoRaPHYAS923.h index 2dabdafccc..34e022fb8b 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYAS923.h +++ b/features/lorawan/lorastack/phy/LoRaPHYAS923.h @@ -52,7 +52,7 @@ class LoRaPHYAS923 : public LoRaPHY { public: - LoRaPHYAS923(); + LoRaPHYAS923(LoRaWANTimeHandler &lora_time); virtual ~LoRaPHYAS923(); /*! diff --git a/features/lorawan/lorastack/phy/LoRaPHYAU915.cpp b/features/lorawan/lorastack/phy/LoRaPHYAU915.cpp index c402908522..407e7db78e 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYAU915.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYAU915.cpp @@ -293,7 +293,8 @@ uint8_t LoRaPHYAU915::CountNbOfEnabledChannels(uint8_t datarate, return nbEnabledChannels; } -LoRaPHYAU915::LoRaPHYAU915() +LoRaPHYAU915::LoRaPHYAU915(LoRaWANTimeHandler &lora_time) + : LoRaPHY(lora_time) { const Band_t band0 = AU915_BAND0; Bands[0] = band0; @@ -904,7 +905,7 @@ bool LoRaPHYAU915::set_next_channel(NextChanParams_t* nextChanParams, } if (nextChanParams->AggrTimeOff - <= TimerGetElapsedTime(nextChanParams->LastAggrTx)) { + <= _lora_time.TimerGetElapsedTime(nextChanParams->LastAggrTx)) { // Reset Aggregated time off *aggregatedTimeOff = 0; @@ -921,7 +922,7 @@ bool LoRaPHYAU915::set_next_channel(NextChanParams_t* nextChanParams, } else { delayTx++; nextTxDelay = nextChanParams->AggrTimeOff - - TimerGetElapsedTime(nextChanParams->LastAggrTx); + - _lora_time.TimerGetElapsedTime(nextChanParams->LastAggrTx); } if (nbEnabledChannels > 0) { diff --git a/features/lorawan/lorastack/phy/LoRaPHYAU915.h b/features/lorawan/lorastack/phy/LoRaPHYAU915.h index ab0651db0a..ae8ff3b39f 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYAU915.h +++ b/features/lorawan/lorastack/phy/LoRaPHYAU915.h @@ -54,7 +54,7 @@ class LoRaPHYAU915 : public LoRaPHY{ public: - LoRaPHYAU915(); + LoRaPHYAU915(LoRaWANTimeHandler &lora_time); virtual ~LoRaPHYAU915(); /*! diff --git a/features/lorawan/lorastack/phy/LoRaPHYCN470.cpp b/features/lorawan/lorastack/phy/LoRaPHYCN470.cpp index 83a79d5226..55918d2957 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYCN470.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYCN470.cpp @@ -279,7 +279,8 @@ uint8_t LoRaPHYCN470::CountNbOfEnabledChannels( uint8_t datarate, uint16_t* chan return nbEnabledChannels; } -LoRaPHYCN470::LoRaPHYCN470() +LoRaPHYCN470::LoRaPHYCN470(LoRaWANTimeHandler &lora_time) + : LoRaPHY(lora_time) { const Band_t band0 = CN470_BAND0; Bands[0] = band0; @@ -900,7 +901,7 @@ bool LoRaPHYCN470::set_next_channel(NextChanParams_t* nextChanParams, ChannelsMask[5] = 0xFFFF; } - if( nextChanParams->AggrTimeOff <= TimerGetElapsedTime( nextChanParams->LastAggrTx ) ) + if( nextChanParams->AggrTimeOff <= _lora_time.TimerGetElapsedTime( nextChanParams->LastAggrTx ) ) { // Reset Aggregated time off *aggregatedTimeOff = 0; @@ -916,7 +917,7 @@ bool LoRaPHYCN470::set_next_channel(NextChanParams_t* nextChanParams, else { delayTx++; - nextTxDelay = nextChanParams->AggrTimeOff - TimerGetElapsedTime( nextChanParams->LastAggrTx ); + nextTxDelay = nextChanParams->AggrTimeOff - _lora_time.TimerGetElapsedTime( nextChanParams->LastAggrTx ); } if( nbEnabledChannels > 0 ) diff --git a/features/lorawan/lorastack/phy/LoRaPHYCN470.h b/features/lorawan/lorastack/phy/LoRaPHYCN470.h index 4c5bcd09bb..8f7f917f94 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYCN470.h +++ b/features/lorawan/lorastack/phy/LoRaPHYCN470.h @@ -54,7 +54,7 @@ class LoRaPHYCN470 : public LoRaPHY { public: - LoRaPHYCN470(); + LoRaPHYCN470(LoRaWANTimeHandler &lora_time); virtual ~LoRaPHYCN470(); /*! diff --git a/features/lorawan/lorastack/phy/LoRaPHYCN779.cpp b/features/lorawan/lorastack/phy/LoRaPHYCN779.cpp index 66435c4aff..da754c4f84 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYCN779.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYCN779.cpp @@ -326,7 +326,8 @@ uint8_t LoRaPHYCN779::CountNbOfEnabledChannels( bool joined, uint8_t datarate, u return nbEnabledChannels; } -LoRaPHYCN779::LoRaPHYCN779() +LoRaPHYCN779::LoRaPHYCN779(LoRaWANTimeHandler &lora_time) + : LoRaPHY(lora_time) { const Band_t band0 = CN779_BAND0; Bands[0] = band0; @@ -1082,7 +1083,7 @@ bool LoRaPHYCN779::set_next_channel(NextChanParams_t* nextChanParams, ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); } - if( nextChanParams->AggrTimeOff <= TimerGetElapsedTime( nextChanParams->LastAggrTx ) ) + if( nextChanParams->AggrTimeOff <= _lora_time.TimerGetElapsedTime( nextChanParams->LastAggrTx ) ) { // Reset Aggregated time off *aggregatedTimeOff = 0; @@ -1098,7 +1099,7 @@ bool LoRaPHYCN779::set_next_channel(NextChanParams_t* nextChanParams, else { delayTx++; - nextTxDelay = nextChanParams->AggrTimeOff - TimerGetElapsedTime( nextChanParams->LastAggrTx ); + nextTxDelay = nextChanParams->AggrTimeOff - _lora_time.TimerGetElapsedTime( nextChanParams->LastAggrTx ); } if( nbEnabledChannels > 0 ) diff --git a/features/lorawan/lorastack/phy/LoRaPHYCN779.h b/features/lorawan/lorastack/phy/LoRaPHYCN779.h index 8be486db5f..8d7640248c 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYCN779.h +++ b/features/lorawan/lorastack/phy/LoRaPHYCN779.h @@ -46,7 +46,7 @@ class LoRaPHYCN779 : public LoRaPHY { public: - LoRaPHYCN779(); + LoRaPHYCN779(LoRaWANTimeHandler &lora_time); virtual ~LoRaPHYCN779(); /*! diff --git a/features/lorawan/lorastack/phy/LoRaPHYEU433.cpp b/features/lorawan/lorastack/phy/LoRaPHYEU433.cpp index 94c29ca20d..dbdaa85e36 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYEU433.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYEU433.cpp @@ -327,7 +327,8 @@ uint8_t LoRaPHYEU433::CountNbOfEnabledChannels( bool joined, uint8_t datarate, u return nbEnabledChannels; } -LoRaPHYEU433::LoRaPHYEU433() +LoRaPHYEU433::LoRaPHYEU433(LoRaWANTimeHandler &lora_time) + : LoRaPHY(lora_time) { const Band_t band0 = EU433_BAND0; Bands[0] = band0; @@ -1087,7 +1088,7 @@ bool LoRaPHYEU433::set_next_channel(NextChanParams_t* nextChanParams, ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); } - if( nextChanParams->AggrTimeOff <= TimerGetElapsedTime( nextChanParams->LastAggrTx ) ) + if( nextChanParams->AggrTimeOff <= _lora_time.TimerGetElapsedTime( nextChanParams->LastAggrTx ) ) { // Reset Aggregated time off *aggregatedTimeOff = 0; @@ -1103,7 +1104,7 @@ bool LoRaPHYEU433::set_next_channel(NextChanParams_t* nextChanParams, else { delayTx++; - nextTxDelay = nextChanParams->AggrTimeOff - TimerGetElapsedTime( nextChanParams->LastAggrTx ); + nextTxDelay = nextChanParams->AggrTimeOff - _lora_time.TimerGetElapsedTime( nextChanParams->LastAggrTx ); } if( nbEnabledChannels > 0 ) diff --git a/features/lorawan/lorastack/phy/LoRaPHYEU433.h b/features/lorawan/lorastack/phy/LoRaPHYEU433.h index 8090b42c4d..27e5735821 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYEU433.h +++ b/features/lorawan/lorastack/phy/LoRaPHYEU433.h @@ -52,7 +52,7 @@ class LoRaPHYEU433 : public LoRaPHY { public: - LoRaPHYEU433(); + LoRaPHYEU433(LoRaWANTimeHandler &lora_time); virtual ~LoRaPHYEU433(); /*! diff --git a/features/lorawan/lorastack/phy/LoRaPHYEU868.cpp b/features/lorawan/lorastack/phy/LoRaPHYEU868.cpp index 06e4065b73..812f7abc8f 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYEU868.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYEU868.cpp @@ -372,7 +372,8 @@ uint8_t LoRaPHYEU868::CountNbOfEnabledChannels( bool joined, uint8_t datarate, u return nbEnabledChannels; } -LoRaPHYEU868::LoRaPHYEU868() +LoRaPHYEU868::LoRaPHYEU868(LoRaWANTimeHandler &lora_time) + : LoRaPHY(lora_time) { const Band_t band0 = EU868_BAND0; const Band_t band1 = EU868_BAND1; @@ -1139,7 +1140,7 @@ bool LoRaPHYEU868::set_next_channel(NextChanParams_t* nextChanParams, ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); } - if( nextChanParams->AggrTimeOff <= TimerGetElapsedTime( nextChanParams->LastAggrTx ) ) + if( nextChanParams->AggrTimeOff <= _lora_time.TimerGetElapsedTime( nextChanParams->LastAggrTx ) ) { // Reset Aggregated time off *aggregatedTimeOff = 0; @@ -1155,7 +1156,7 @@ bool LoRaPHYEU868::set_next_channel(NextChanParams_t* nextChanParams, else { delayTx++; - nextTxDelay = nextChanParams->AggrTimeOff - TimerGetElapsedTime( nextChanParams->LastAggrTx ); + nextTxDelay = nextChanParams->AggrTimeOff - _lora_time.TimerGetElapsedTime( nextChanParams->LastAggrTx ); } if( nbEnabledChannels > 0 ) diff --git a/features/lorawan/lorastack/phy/LoRaPHYEU868.h b/features/lorawan/lorastack/phy/LoRaPHYEU868.h index 0c588c5417..42144a781a 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYEU868.h +++ b/features/lorawan/lorastack/phy/LoRaPHYEU868.h @@ -51,7 +51,7 @@ class LoRaPHYEU868 : public LoRaPHY { public: - LoRaPHYEU868(); + LoRaPHYEU868(LoRaWANTimeHandler &lora_time); virtual ~LoRaPHYEU868(); /*! diff --git a/features/lorawan/lorastack/phy/LoRaPHYIN865.cpp b/features/lorawan/lorastack/phy/LoRaPHYIN865.cpp index 8513dc61c2..0f124138d1 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYIN865.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYIN865.cpp @@ -334,7 +334,8 @@ uint8_t LoRaPHYIN865::CountNbOfEnabledChannels( bool joined, uint8_t datarate, u return nbEnabledChannels; } -LoRaPHYIN865::LoRaPHYIN865() +LoRaPHYIN865::LoRaPHYIN865(LoRaWANTimeHandler &lora_time) + : LoRaPHY(lora_time) { const Band_t band0 = IN865_BAND0; Bands[0] = band0; @@ -1090,7 +1091,7 @@ bool LoRaPHYIN865::set_next_channel(NextChanParams_t* nextChanParams, ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); } - if( nextChanParams->AggrTimeOff <= TimerGetElapsedTime( nextChanParams->LastAggrTx ) ) + if( nextChanParams->AggrTimeOff <= _lora_time.TimerGetElapsedTime( nextChanParams->LastAggrTx ) ) { // Reset Aggregated time off *aggregatedTimeOff = 0; @@ -1106,7 +1107,7 @@ bool LoRaPHYIN865::set_next_channel(NextChanParams_t* nextChanParams, else { delayTx++; - nextTxDelay = nextChanParams->AggrTimeOff - TimerGetElapsedTime( nextChanParams->LastAggrTx ); + nextTxDelay = nextChanParams->AggrTimeOff - _lora_time.TimerGetElapsedTime( nextChanParams->LastAggrTx ); } if( nbEnabledChannels > 0 ) diff --git a/features/lorawan/lorastack/phy/LoRaPHYIN865.h b/features/lorawan/lorastack/phy/LoRaPHYIN865.h index d1be5f5b62..5745239869 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYIN865.h +++ b/features/lorawan/lorastack/phy/LoRaPHYIN865.h @@ -54,7 +54,7 @@ class LoRaPHYIN865 : public LoRaPHY { public: - LoRaPHYIN865(); + LoRaPHYIN865(LoRaWANTimeHandler &lora_time); virtual ~LoRaPHYIN865(); /*! diff --git a/features/lorawan/lorastack/phy/LoRaPHYKR920.cpp b/features/lorawan/lorastack/phy/LoRaPHYKR920.cpp index 51806fb358..9524a28fbd 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYKR920.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYKR920.cpp @@ -359,7 +359,8 @@ uint8_t LoRaPHYKR920::CountNbOfEnabledChannels( bool joined, uint8_t datarate, u return nbEnabledChannels; } -LoRaPHYKR920::LoRaPHYKR920() +LoRaPHYKR920::LoRaPHYKR920(LoRaWANTimeHandler &lora_time) + : LoRaPHY(lora_time) { const Band_t band0 = KR920_BAND0; Bands[0] = band0; @@ -1091,7 +1092,7 @@ bool LoRaPHYKR920::set_next_channel(NextChanParams_t* nextChanParams, ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); } - if( nextChanParams->AggrTimeOff <= TimerGetElapsedTime( nextChanParams->LastAggrTx ) ) + if( nextChanParams->AggrTimeOff <= _lora_time.TimerGetElapsedTime( nextChanParams->LastAggrTx ) ) { // Reset Aggregated time off *aggregatedTimeOff = 0; @@ -1107,7 +1108,7 @@ bool LoRaPHYKR920::set_next_channel(NextChanParams_t* nextChanParams, else { delayTx++; - nextTxDelay = nextChanParams->AggrTimeOff - TimerGetElapsedTime( nextChanParams->LastAggrTx ); + nextTxDelay = nextChanParams->AggrTimeOff - _lora_time.TimerGetElapsedTime( nextChanParams->LastAggrTx ); } if( nbEnabledChannels > 0 ) diff --git a/features/lorawan/lorastack/phy/LoRaPHYKR920.h b/features/lorawan/lorastack/phy/LoRaPHYKR920.h index 329bbd1511..0d0c893f84 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYKR920.h +++ b/features/lorawan/lorastack/phy/LoRaPHYKR920.h @@ -52,7 +52,7 @@ class LoRaPHYKR920 : public LoRaPHY { public: - LoRaPHYKR920(); + LoRaPHYKR920(LoRaWANTimeHandler &lora_time); virtual ~LoRaPHYKR920(); /*! diff --git a/features/lorawan/lorastack/phy/LoRaPHYUS915.cpp b/features/lorawan/lorastack/phy/LoRaPHYUS915.cpp index 9ae7ac55a2..057bdf5c11 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYUS915.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYUS915.cpp @@ -298,7 +298,8 @@ uint8_t LoRaPHYUS915::CountNbOfEnabledChannels( uint8_t datarate, uint16_t* chan return nbEnabledChannels; } -LoRaPHYUS915::LoRaPHYUS915() +LoRaPHYUS915::LoRaPHYUS915(LoRaWANTimeHandler &lora_time) + : LoRaPHY(lora_time) { const Band_t band0 = US915_BAND0; Bands[0] = band0; @@ -959,7 +960,7 @@ bool LoRaPHYUS915::set_next_channel(NextChanParams_t* nextChanParams, } } - if( nextChanParams->AggrTimeOff <= TimerGetElapsedTime( nextChanParams->LastAggrTx ) ) + if( nextChanParams->AggrTimeOff <= _lora_time.TimerGetElapsedTime( nextChanParams->LastAggrTx ) ) { // Reset Aggregated time off *aggregatedTimeOff = 0; @@ -975,7 +976,7 @@ bool LoRaPHYUS915::set_next_channel(NextChanParams_t* nextChanParams, else { delayTx++; - nextTxDelay = nextChanParams->AggrTimeOff - TimerGetElapsedTime( nextChanParams->LastAggrTx ); + nextTxDelay = nextChanParams->AggrTimeOff - _lora_time.TimerGetElapsedTime( nextChanParams->LastAggrTx ); } if( nbEnabledChannels > 0 ) diff --git a/features/lorawan/lorastack/phy/LoRaPHYUS915.h b/features/lorawan/lorastack/phy/LoRaPHYUS915.h index 3c97014c4e..22ca4ef322 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYUS915.h +++ b/features/lorawan/lorastack/phy/LoRaPHYUS915.h @@ -52,7 +52,7 @@ class LoRaPHYUS915 : public LoRaPHY { public: - LoRaPHYUS915(); + LoRaPHYUS915(LoRaWANTimeHandler &lora_time); virtual ~LoRaPHYUS915(); /*! diff --git a/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.cpp b/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.cpp index 14cff30065..393327f094 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.cpp @@ -388,7 +388,8 @@ uint8_t LoRaPHYUS915Hybrid::CountNbOfEnabledChannels( uint8_t datarate, uint16_t return nbEnabledChannels; } -LoRaPHYUS915Hybrid::LoRaPHYUS915Hybrid() +LoRaPHYUS915Hybrid::LoRaPHYUS915Hybrid(LoRaWANTimeHandler &lora_time) + : LoRaPHY(lora_time) { const Band_t band0 = US915_HYBRID_BAND0; Bands[0] = band0; @@ -1050,7 +1051,7 @@ bool LoRaPHYUS915Hybrid::set_next_channel(NextChanParams_t* nextChanParams, } } - if( nextChanParams->AggrTimeOff <= TimerGetElapsedTime( nextChanParams->LastAggrTx ) ) + if( nextChanParams->AggrTimeOff <= _lora_time.TimerGetElapsedTime( nextChanParams->LastAggrTx ) ) { // Reset Aggregated time off *aggregatedTimeOff = 0; @@ -1066,7 +1067,7 @@ bool LoRaPHYUS915Hybrid::set_next_channel(NextChanParams_t* nextChanParams, else { delayTx++; - nextTxDelay = nextChanParams->AggrTimeOff - TimerGetElapsedTime( nextChanParams->LastAggrTx ); + nextTxDelay = nextChanParams->AggrTimeOff - _lora_time.TimerGetElapsedTime( nextChanParams->LastAggrTx ); } if( nbEnabledChannels > 0 ) diff --git a/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.h b/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.h index b84f571770..ae3dfb8f99 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.h +++ b/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.h @@ -53,7 +53,7 @@ class LoRaPHYUS915Hybrid : public LoRaPHY { public: - LoRaPHYUS915Hybrid(); + LoRaPHYUS915Hybrid(LoRaWANTimeHandler &lora_time); virtual ~LoRaPHYUS915Hybrid(); /*! diff --git a/features/lorawan/system/LoRaWANTimer.cpp b/features/lorawan/system/LoRaWANTimer.cpp index f721fa3f30..530b53e3ea 100644 --- a/features/lorawan/system/LoRaWANTimer.cpp +++ b/features/lorawan/system/LoRaWANTimer.cpp @@ -20,41 +20,48 @@ SPDX-License-Identifier: BSD-3-Clause #include "lorawan/system/LoRaWANTimer.h" -static events::EventQueue *_queue = NULL; +LoRaWANTimeHandler::LoRaWANTimeHandler() + : _queue(NULL) +{ +} -void TimerTimeCounterInit(events::EventQueue *queue) +LoRaWANTimeHandler::~LoRaWANTimeHandler() +{ +} + +void LoRaWANTimeHandler::TimerTimeCounterInit(events::EventQueue *queue) { _queue = queue; } -TimerTime_t TimerGetCurrentTime( void ) +TimerTime_t LoRaWANTimeHandler::TimerGetCurrentTime( void ) { const uint32_t current_time = _queue->tick(); return (TimerTime_t)current_time; } -TimerTime_t TimerGetElapsedTime( TimerTime_t savedTime ) +TimerTime_t LoRaWANTimeHandler::TimerGetElapsedTime( TimerTime_t savedTime ) { return TimerGetCurrentTime() - savedTime; } -void TimerInit( TimerEvent_t *obj, void ( *callback )( void ) ) +void LoRaWANTimeHandler::TimerInit( TimerEvent_t *obj, void ( *callback )( void ) ) { obj->value = 0; obj->Callback = callback; } -void TimerStart( TimerEvent_t *obj ) +void LoRaWANTimeHandler::TimerStart( TimerEvent_t *obj ) { obj->Timer.get()->attach_us( mbed::callback( obj->Callback ), obj->value * 1000 ); } -void TimerStop( TimerEvent_t *obj ) +void LoRaWANTimeHandler::TimerStop( TimerEvent_t *obj ) { obj->Timer.get()->detach( ); } -void TimerSetValue( TimerEvent_t *obj, uint32_t value ) +void LoRaWANTimeHandler::TimerSetValue( TimerEvent_t *obj, uint32_t value ) { obj->value = value; } diff --git a/features/lorawan/system/LoRaWANTimer.h b/features/lorawan/system/LoRaWANTimer.h index 6b5b9ac5b1..6e13c0f3cb 100644 --- a/features/lorawan/system/LoRaWANTimer.h +++ b/features/lorawan/system/LoRaWANTimer.h @@ -21,7 +21,7 @@ SPDX-License-Identifier: BSD-3-Clause #ifndef MBED_LORAWAN_SYS_TIMER_H__ #define MBED_LORAWAN_SYS_TIMER_H__ -#include "drivers/Timer.h" +#include #include "drivers/Ticker.h" #include "lorawan/system/lorawan_data_structures.h" #include "events/EventQueue.h" @@ -37,68 +37,71 @@ typedef struct TimerEvent_s SingletonPtr Timer; }TimerEvent_t; -/*! - * \brief Initializes the timer object. - * - * \remark The TimerSetValue function must be called before starting the timer. - * This function initializes the timestamp and reloads the value at 0. - * - * \param [in] obj The structure containing the timer object parameters. - * \param [in] callback The function callback called at the end of the timeout. - */ -void TimerInit( TimerEvent_t *obj, void ( *callback )( void ) ); +class LoRaWANTimeHandler +{ +public: + LoRaWANTimeHandler(); + ~LoRaWANTimeHandler(); -/*! - * \brief Starts and adds the timer object to the list of timer events. - * - * \param [in] obj The structure containing the timer object parameters. - */ -void TimerStart( TimerEvent_t *obj ); + /*! + * \brief Initializes the timer used to get the current time. + * + * \remark The current time corresponds to the time since system startup. + * + * \param [in] queue Handle to EventQueue object + */ + void TimerTimeCounterInit(events::EventQueue *queue); -/*! - * \brief Stops and removes the timer object from the list of timer events. - * - * \param [in] obj The structure containing the timer object parameters. - */ -void TimerStop( TimerEvent_t *obj ); + /*! + * \brief Read the current time. + * + * \retval time The current time. + */ + TimerTime_t TimerGetCurrentTime( void ); -/*! - * \brief Resets the timer object. - * - * \param [in] obj The structure containing the timer object parameters. - */ -void TimerReset( TimerEvent_t *obj ); + /*! + * \brief Return the time elapsed since a fixed moment in time. + * + * \param [in] savedTime The fixed moment in time. + * \retval time The elapsed time. + */ + TimerTime_t TimerGetElapsedTime( TimerTime_t savedTime ); -/*! - * \brief Set a new timeout value. - * - * \param [in] obj The structure containing the timer object parameters. - * \param [in] value The new timeout value. - */ -void TimerSetValue( TimerEvent_t *obj, uint32_t value ); + /*! + * \brief Initializes the timer object. + * + * \remark The TimerSetValue function must be called before starting the timer. + * This function initializes the timestamp and reloads the value at 0. + * + * \param [in] obj The structure containing the timer object parameters. + * \param [in] callback The function callback called at the end of the timeout. + */ + void TimerInit( TimerEvent_t *obj, void ( *callback )( void ) ); -/*! - * \brief Initializes the timer used to get the current time. - * - * \remark The current time corresponds to the time since system startup. - * - * \param [in] queue Handle to EventQueue object - */ -void TimerTimeCounterInit(events::EventQueue *queue); + /*! + * \brief Starts and adds the timer object to the list of timer events. + * + * \param [in] obj The structure containing the timer object parameters. + */ + void TimerStart( TimerEvent_t *obj ); -/*! - * \brief Read the current time. - * - * \retval time The current time. - */ -TimerTime_t TimerGetCurrentTime( void ); + /*! + * \brief Stops and removes the timer object from the list of timer events. + * + * \param [in] obj The structure containing the timer object parameters. + */ + void TimerStop( TimerEvent_t *obj ); -/*! - * \brief Return the time elapsed since a fixed moment in time. - * - * \param [in] savedTime The fixed moment in time. - * \retval time The elapsed time. - */ -TimerTime_t TimerGetElapsedTime( TimerTime_t savedTime ); + /*! + * \brief Set a new timeout value. + * + * \param [in] obj The structure containing the timer object parameters. + * \param [in] value The new timeout value. + */ + void TimerSetValue( TimerEvent_t *obj, uint32_t value ); + +private: + events::EventQueue *_queue; +}; #endif // MBED_LORAWAN_SYS_TIMER_H__ From f62253ca0eb05d43d934c47b0bf453dc3c3e56a6 Mon Sep 17 00:00:00 2001 From: Hasnain Virk Date: Fri, 5 Jan 2018 10:47:09 +0200 Subject: [PATCH 04/23] Changing Timer callback to Mbed Callback Time handler class had a c style callback attached to it which had been hampering us to be fully object oriented. That particular callback is changed to Mbed Callback which is attatched to a specific object hence allowing us to be fully object oriented. --- features/lorawan/lorastack/mac/LoRaMac.cpp | 53 +++++++++------------- features/lorawan/lorastack/mac/LoRaMac.h | 30 ++++++------ features/lorawan/system/LoRaWANTimer.cpp | 2 +- features/lorawan/system/LoRaWANTimer.h | 24 +++++----- 4 files changed, 51 insertions(+), 58 deletions(-) diff --git a/features/lorawan/lorastack/mac/LoRaMac.cpp b/features/lorawan/lorastack/mac/LoRaMac.cpp index 373c825f97..d6211619dc 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.cpp +++ b/features/lorawan/lorastack/mac/LoRaMac.cpp @@ -41,13 +41,6 @@ using namespace events; */ static EventQueue *ev_queue; -/*! - * TODO: We should get rid of this - * - * Static handle to LoRaMac object. This is needed for static callback methods. - */ -static LoRaMac* isrHandler = NULL; - /*! * Maximum length of the fOpts field */ @@ -93,8 +86,6 @@ LoRaMac::LoRaMac(LoRaWANTimeHandler &lora_time) : mac_commands(*this), _lora_time(lora_time) { - isrHandler = this; - lora_phy = NULL; //radio_events_t RadioEvents; LoRaMacDevEui = NULL; @@ -172,64 +163,64 @@ LoRaMac::~LoRaMac() **************************************************************************/ void LoRaMac::handle_tx_done(void) { - ev_queue->call(isrHandler, &LoRaMac::OnRadioTxDone); + ev_queue->call(this, &LoRaMac::OnRadioTxDone); } void LoRaMac::handle_rx_done(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr) { - ev_queue->call(isrHandler, &LoRaMac::OnRadioRxDone, payload, size, rssi, snr); + ev_queue->call(this, &LoRaMac::OnRadioRxDone, payload, size, rssi, snr); } void LoRaMac::handle_rx_error(void) { - ev_queue->call(isrHandler, &LoRaMac::OnRadioRxError); + ev_queue->call(this, &LoRaMac::OnRadioRxError); } void LoRaMac::handle_rx_timeout(void) { - ev_queue->call(isrHandler, &LoRaMac::OnRadioRxTimeout); + ev_queue->call(this, &LoRaMac::OnRadioRxTimeout); } void LoRaMac::handle_tx_timeout(void) { - ev_queue->call(isrHandler, &LoRaMac::OnRadioTxTimeout); + ev_queue->call(this, &LoRaMac::OnRadioTxTimeout); } void LoRaMac::handle_cad_done(bool cad) { //TODO Not implemented yet - //ev_queue->call(isrHandler, &LoRaMac::OnRadioCadDone, cad); + //ev_queue->call(this, &LoRaMac::OnRadioCadDone, cad); } void LoRaMac::handle_fhss_change_channel(uint8_t cur_channel) { // TODO Not implemented yet - //ev_queue->call(isrHandler, &LoRaMac::OnRadioFHSSChangeChannel, cur_channel); + //ev_queue->call(this, &LoRaMac::OnRadioFHSSChangeChannel, cur_channel); } void LoRaMac::handle_mac_state_check_timer_event(void) { - ev_queue->call(isrHandler, &LoRaMac::OnMacStateCheckTimerEvent); + ev_queue->call(this, &LoRaMac::OnMacStateCheckTimerEvent); } void LoRaMac::handle_delayed_tx_timer_event(void) { - ev_queue->call(isrHandler, &LoRaMac::OnTxDelayedTimerEvent); + ev_queue->call(this, &LoRaMac::OnTxDelayedTimerEvent); } void LoRaMac::handle_ack_timeout() { - ev_queue->call(isrHandler, &LoRaMac::OnAckTimeoutTimerEvent); + ev_queue->call(this, &LoRaMac::OnAckTimeoutTimerEvent); } void LoRaMac::handle_rx1_timer_event(void) { - ev_queue->call(isrHandler, &LoRaMac::OnRxWindow1TimerEvent); + ev_queue->call(this, &LoRaMac::OnRxWindow1TimerEvent); } void LoRaMac::handle_rx2_timer_event(void) { - ev_queue->call(isrHandler, &LoRaMac::OnRxWindow2TimerEvent); + ev_queue->call(this, &LoRaMac::OnRxWindow2TimerEvent); } /*************************************************************************** @@ -1794,13 +1785,13 @@ LoRaMacStatus_t LoRaMac::LoRaMacInitialization(LoRaMacPrimitives_t *primitives, lora_phy->put_radio_to_sleep(); // Initialize timers - _lora_time.TimerInit(&MacStateCheckTimer, handle_mac_state_check_timer_event); + _lora_time.TimerInit(&MacStateCheckTimer, mbed::callback(this, &LoRaMac::handle_mac_state_check_timer_event)); _lora_time.TimerSetValue(&MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT); - _lora_time.TimerInit(&TxDelayedTimer, handle_delayed_tx_timer_event); - _lora_time.TimerInit(&RxWindowTimer1, handle_rx1_timer_event); - _lora_time.TimerInit(&RxWindowTimer2, handle_rx2_timer_event); - _lora_time.TimerInit(&AckTimeoutTimer, handle_ack_timeout); + _lora_time.TimerInit(&TxDelayedTimer, mbed::callback(this, &LoRaMac::handle_delayed_tx_timer_event)); + _lora_time.TimerInit(&RxWindowTimer1, mbed::callback(this, &LoRaMac::handle_rx1_timer_event)); + _lora_time.TimerInit(&RxWindowTimer2, mbed::callback(this, &LoRaMac::handle_rx2_timer_event)); + _lora_time.TimerInit(&AckTimeoutTimer, mbed::callback(this, &LoRaMac::handle_ack_timeout)); // Store the current initialization time LoRaMacInitializationTime = _lora_time.TimerGetCurrentTime(); @@ -2694,11 +2685,11 @@ LoRaMacStatus_t LoRaMac::LoRaMacMcpsRequest( McpsReq_t *mcpsRequest ) radio_events_t *LoRaMac::GetPhyEventHandlers() { - RadioEvents.tx_done = mbed::callback(handle_tx_done); - RadioEvents.rx_done = mbed::callback(handle_rx_done); - RadioEvents.rx_error = mbed::callback(handle_rx_error); - RadioEvents.tx_timeout = mbed::callback(handle_tx_timeout); - RadioEvents.rx_timeout = mbed::callback(handle_rx_timeout); + RadioEvents.tx_done = mbed::callback(this, &LoRaMac::handle_tx_done); + RadioEvents.rx_done = mbed::callback(this, &LoRaMac::handle_rx_done); + RadioEvents.rx_error = mbed::callback(this, &LoRaMac::handle_rx_error); + RadioEvents.tx_timeout = mbed::callback(this, &LoRaMac::handle_tx_timeout); + RadioEvents.rx_timeout = mbed::callback(this, &LoRaMac::handle_rx_timeout); return &RadioEvents; } diff --git a/features/lorawan/lorastack/mac/LoRaMac.h b/features/lorawan/lorastack/mac/LoRaMac.h index a346c7bcb8..8746c44b31 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.h +++ b/features/lorawan/lorastack/mac/LoRaMac.h @@ -583,25 +583,25 @@ private: * \brief Opens up a continuous RX 2 window. This is used for * class c devices. */ - void OpenContinuousRx2Window( void ); + void OpenContinuousRx2Window(void); /** * Prototypes for ISR handlers */ - static void handle_cad_done(bool cad); - static void handle_tx_done(void); - static void handle_rx_done(uint8_t *payload, uint16_t size, int16_t rssi, - int8_t snr); - static void handle_rx_error(void); - static void handle_rx_timeout(void); - static void handle_tx_timeout(void); - static void handle_fhss_change_channel(uint8_t cur_channel); - static void handle_rx1_timer_event(void); - static void handle_rx2_timer_event(void); - static void handle_ack_timeout(void); - 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); + void handle_cad_done(bool cad); + void handle_tx_done(void); + void handle_rx_done(uint8_t *payload, uint16_t size, int16_t rssi, + int8_t snr); + void handle_rx_error(void); + void handle_rx_timeout(void); + void handle_tx_timeout(void); + void handle_fhss_change_channel(uint8_t cur_channel); + void handle_rx1_timer_event(void); + void handle_rx2_timer_event(void); + void handle_ack_timeout(void); + void handle_delayed_tx_timer_event(void); + void handle_mac_state_check_timer_event(void); + void handle_next_tx_timer_event(void); private: /** diff --git a/features/lorawan/system/LoRaWANTimer.cpp b/features/lorawan/system/LoRaWANTimer.cpp index 530b53e3ea..eaa80b2e44 100644 --- a/features/lorawan/system/LoRaWANTimer.cpp +++ b/features/lorawan/system/LoRaWANTimer.cpp @@ -45,7 +45,7 @@ TimerTime_t LoRaWANTimeHandler::TimerGetElapsedTime( TimerTime_t savedTime ) return TimerGetCurrentTime() - savedTime; } -void LoRaWANTimeHandler::TimerInit( TimerEvent_t *obj, void ( *callback )( void ) ) +void LoRaWANTimeHandler::TimerInit( TimerEvent_t *obj, mbed::Callback callback) { obj->value = 0; obj->Callback = callback; diff --git a/features/lorawan/system/LoRaWANTimer.h b/features/lorawan/system/LoRaWANTimer.h index 6e13c0f3cb..d5770cde96 100644 --- a/features/lorawan/system/LoRaWANTimer.h +++ b/features/lorawan/system/LoRaWANTimer.h @@ -33,7 +33,7 @@ SPDX-License-Identifier: BSD-3-Clause typedef struct TimerEvent_s { uint32_t value; - void ( *Callback )( void ); + mbed::Callback Callback; SingletonPtr Timer; }TimerEvent_t; @@ -52,6 +52,17 @@ public: */ void TimerTimeCounterInit(events::EventQueue *queue); + /*! + * \brief Initializes the timer object. + * + * \remark The TimerSetValue function must be called before starting the timer. + * This function initializes the timestamp and reloads the value at 0. + * + * \param [in] obj The structure containing the timer object parameters. + * \param [in] callback The function callback called at the end of the timeout. + */ + void TimerInit( TimerEvent_t *obj, mbed::Callback callback); + /*! * \brief Read the current time. * @@ -67,16 +78,7 @@ public: */ TimerTime_t TimerGetElapsedTime( TimerTime_t savedTime ); - /*! - * \brief Initializes the timer object. - * - * \remark The TimerSetValue function must be called before starting the timer. - * This function initializes the timestamp and reloads the value at 0. - * - * \param [in] obj The structure containing the timer object parameters. - * \param [in] callback The function callback called at the end of the timeout. - */ - void TimerInit( TimerEvent_t *obj, void ( *callback )( void ) ); + /*! * \brief Starts and adds the timer object to the list of timer events. From a3106d2fe6f782a8562bfdd9f2c517031ccf2bb1 Mon Sep 17 00:00:00 2001 From: Hasnain Virk Date: Mon, 8 Jan 2018 18:06:40 +0200 Subject: [PATCH 05/23] Timer SingletonPtr & mac protocol data structure Ticker objects embeded in TimerEvent_t data structure were getting constructed even for the non LORAWAN builds. And that's what was bloating the builds. We now lazy initialize them using Mbed-OS utility clas SingletonPtr. A central data structure has been created that carries all the protocol level variables for the Mac layer. This is important as we are going to break down MAC services into subsystems and we will pass around common data using that data structure. --- features/lorawan/lorastack/mac/LoRaMac.cpp | 862 +++++++++--------- features/lorawan/lorastack/mac/LoRaMac.h | 233 +---- features/lorawan/system/LoRaWANTimer.h | 12 - .../lorawan/system/lorawan_data_structures.h | 265 ++++++ 4 files changed, 703 insertions(+), 669 deletions(-) diff --git a/features/lorawan/lorastack/mac/LoRaMac.cpp b/features/lorawan/lorastack/mac/LoRaMac.cpp index d6211619dc..e1d2b1e2e7 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.cpp +++ b/features/lorawan/lorastack/mac/LoRaMac.cpp @@ -83,74 +83,42 @@ static EventQueue *ev_queue; LoRaMac::LoRaMac(LoRaWANTimeHandler &lora_time) - : mac_commands(*this), - _lora_time(lora_time) + : mac_commands(*this), _lora_time(lora_time) { lora_phy = NULL; //radio_events_t RadioEvents; - LoRaMacDevEui = NULL; - LoRaMacAppEui = NULL; - LoRaMacAppKey = NULL; + _params.keys.LoRaMacDevEui = NULL; + _params.keys.LoRaMacAppEui = NULL; + _params.keys.LoRaMacAppKey = NULL; - memset(LoRaMacNwkSKey, 0, sizeof(LoRaMacNwkSKey)); - memset(LoRaMacAppSKey, 0, sizeof(LoRaMacAppSKey)); + memset(_params.keys.LoRaMacNwkSKey, 0, sizeof(_params.keys.LoRaMacNwkSKey)); + memset(_params.keys.LoRaMacAppSKey, 0, sizeof(_params.keys.LoRaMacAppSKey)); + + _params.LoRaMacDevNonce = 0; + _params.LoRaMacNetID = 0; + _params.LoRaMacDevAddr = 0; + _params.LoRaMacBufferPktLen = 0; + _params.LoRaMacTxPayloadLen = 0; + _params.UpLinkCounter = 0; + _params.DownLinkCounter = 0; + _params.IsUpLinkCounterFixed = false; + _params.IsRxWindowsEnabled = true; + _params.IsLoRaMacNetworkJoined = false; + _params.AdrAckCounter = 0; + _params.NodeAckRequested = false; + _params.SrvAckRequested = false; + _params.ChannelsNbRepCounter = 0; + _params.timers.LoRaMacInitializationTime = 0; + _params.LoRaMacState = LORAMAC_IDLE; + _params.AckTimeoutRetries = 1; + _params.AckTimeoutRetriesCounter = 1; + _params.AckTimeoutRetry = false; + _params.timers.TxTimeOnAir = 0; - LoRaMacDevNonce = 0; - LoRaMacNetID = 0; - LoRaMacDevAddr = 0; MulticastChannels = NULL; - //DeviceClass_t LoRaMacDeviceClass; - //bool PublicNetwork; - //bool RepeaterSupport; - //uint8_t LoRaMacBuffer[LORAMAC_PHY_MAXPAYLOAD]; - LoRaMacBufferPktLen = 0; - LoRaMacTxPayloadLen = 0; - //uint8_t LoRaMacRxPayload[LORAMAC_PHY_MAXPAYLOAD]; - UpLinkCounter = 0; - DownLinkCounter = 0; - IsUpLinkCounterFixed = false; - IsRxWindowsEnabled = true; - IsLoRaMacNetworkJoined = false; + LoRaMacParams.AdrCtrlOn = false; - AdrAckCounter = 0; - NodeAckRequested = false; - SrvAckRequested = false; - //LoRaMacParams_t LoRaMacParams; - //LoRaMacParams_t LoRaMacParamsDefaults; - ChannelsNbRepCounter = 0; LoRaMacParams.MaxDCycle = 0; - //uint16_t AggregatedDCycle; - //TimerTime_t AggregatedLastTxDoneTime; - //TimerTime_t AggregatedTimeOff; - //bool DutyCycleOn; - //uint8_t Channel; - //uint8_t LastTxChannel; - //bool LastTxIsJoinRequest; - LoRaMacInitializationTime = 0; - LoRaMacState = LORAMAC_IDLE; - //TimerEvent_t MacStateCheckTimer; - //TimerEvent_t TxNextPacketTimer; - //LoRaMacPrimitives_t *LoRaMacPrimitives; - //LoRaMacCallback_t *LoRaMacCallbacks; - //TimerEvent_t TxDelayedTimer; - //TimerEvent_t RxWindowTimer1; - //TimerEvent_t RxWindowTimer2; - //uint32_t RxWindow1Delay; - //uint32_t RxWindow2Delay; - //RxConfigParams_t RxWindow1Config; - //RxConfigParams_t RxWindow2Config; - //TimerEvent_t AckTimeoutTimer; - AckTimeoutRetries = 1; - AckTimeoutRetriesCounter = 1; - AckTimeoutRetry = false; - TxTimeOnAir = 0; - //uint8_t JoinRequestTrials; - //uint8_t MaxJoinRequestTrials; - //McpsIndication_t McpsIndication; - //McpsConfirm_t McpsConfirm; - //MlmeConfirm_t MlmeConfirm; - //LoRaMacRxSlot_t RxSlot; - //LoRaMacFlags_t LoRaMacFlags; } LoRaMac::~LoRaMac() @@ -233,7 +201,7 @@ void LoRaMac::OnRadioTxDone( void ) SetBandTxDoneParams_t txDone; TimerTime_t curTime = _lora_time.TimerGetCurrentTime( ); - if( LoRaMacDeviceClass != CLASS_C ) + if( _params.LoRaMacDeviceClass != CLASS_C ) { lora_phy->put_radio_to_sleep(); } @@ -243,21 +211,21 @@ void LoRaMac::OnRadioTxDone( void ) } // Setup timers - if( IsRxWindowsEnabled == true ) + if( _params.IsRxWindowsEnabled == true ) { - _lora_time.TimerSetValue( &RxWindowTimer1, RxWindow1Delay ); - _lora_time.TimerStart( &RxWindowTimer1 ); - if( LoRaMacDeviceClass != CLASS_C ) + _lora_time.TimerSetValue( &_params.timers.RxWindowTimer1, RxWindow1Delay ); + _lora_time.TimerStart( &_params.timers.RxWindowTimer1 ); + if( _params.LoRaMacDeviceClass != CLASS_C ) { - _lora_time.TimerSetValue( &RxWindowTimer2, RxWindow2Delay ); - _lora_time.TimerStart( &RxWindowTimer2 ); + _lora_time.TimerSetValue( &_params.timers.RxWindowTimer2, RxWindow2Delay ); + _lora_time.TimerStart( &_params.timers.RxWindowTimer2 ); } - if( ( LoRaMacDeviceClass == CLASS_C ) || ( NodeAckRequested == true ) ) + if( ( _params.LoRaMacDeviceClass == CLASS_C ) || ( _params.NodeAckRequested == true ) ) { getPhy.Attribute = PHY_ACK_TIMEOUT; phyParam = lora_phy->get_phy_params(&getPhy); - _lora_time.TimerSetValue( &AckTimeoutTimer, RxWindow2Delay + phyParam.Value ); - _lora_time.TimerStart( &AckTimeoutTimer ); + _lora_time.TimerSetValue( &_params.timers.AckTimeoutTimer, RxWindow2Delay + phyParam.Value ); + _lora_time.TimerStart( &_params.timers.AckTimeoutTimer ); } } else @@ -265,55 +233,55 @@ void LoRaMac::OnRadioTxDone( void ) McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK; MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT; - if( LoRaMacFlags.Value == 0 ) + if( _params.LoRaMacFlags.Value == 0 ) { - LoRaMacFlags.Bits.McpsReq = 1; + _params.LoRaMacFlags.Bits.McpsReq = 1; } - LoRaMacFlags.Bits.MacDone = 1; + _params.LoRaMacFlags.Bits.MacDone = 1; } // Verify if the last uplink was a join request - if( ( LoRaMacFlags.Bits.MlmeReq == 1 ) && ( MlmeConfirm.MlmeRequest == MLME_JOIN ) ) + if( ( _params.LoRaMacFlags.Bits.MlmeReq == 1 ) && ( MlmeConfirm.MlmeRequest == MLME_JOIN ) ) { - LastTxIsJoinRequest = true; + _params.LastTxIsJoinRequest = true; } else { - LastTxIsJoinRequest = false; + _params.LastTxIsJoinRequest = false; } // Store last Tx channel - LastTxChannel = Channel; + _params.LastTxChannel = _params.Channel; // Update last tx done time for the current channel - txDone.Channel = Channel; - txDone.Joined = IsLoRaMacNetworkJoined; + txDone.Channel = _params.Channel; + txDone.Joined = _params.IsLoRaMacNetworkJoined; txDone.LastTxDoneTime = curTime; lora_phy->set_band_tx_done(&txDone); // Update Aggregated last tx done time - AggregatedLastTxDoneTime = curTime; + _params.timers.AggregatedLastTxDoneTime = curTime; - if( NodeAckRequested == false ) + if( _params.NodeAckRequested == false ) { McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK; - ChannelsNbRepCounter++; + _params.ChannelsNbRepCounter++; } } void LoRaMac::PrepareRxDoneAbort( void ) { - LoRaMacState |= LORAMAC_RX_ABORT; + _params.LoRaMacState |= LORAMAC_RX_ABORT; - if( NodeAckRequested ) + if( _params.NodeAckRequested ) { handle_ack_timeout(); } - LoRaMacFlags.Bits.McpsInd = 1; - LoRaMacFlags.Bits.MacDone = 1; + _params.LoRaMacFlags.Bits.McpsInd = 1; + _params.LoRaMacFlags.Bits.MacDone = 1; // Trig OnMacCheckTimerEvent call as soon as possible - _lora_time.TimerSetValue( &MacStateCheckTimer, 1 ); - _lora_time.TimerStart( &MacStateCheckTimer ); + _lora_time.TimerSetValue( &_params.timers.MacStateCheckTimer, 1 ); + _lora_time.TimerStart( &_params.timers.MacStateCheckTimer ); } void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) @@ -339,8 +307,8 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 uint32_t downLinkCounter = 0; MulticastParams_t *curMulticastParams = NULL; - uint8_t *nwkSKey = LoRaMacNwkSKey; - uint8_t *appSKey = LoRaMacAppSKey; + uint8_t *nwkSKey = _params.keys.LoRaMacNwkSKey; + uint8_t *appSKey = _params.keys.LoRaMacAppSKey; uint8_t multicast = 0; @@ -362,59 +330,68 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 lora_phy->put_radio_to_sleep(); - _lora_time.TimerStop( &RxWindowTimer2 ); + _lora_time.TimerStop( &_params.timers.RxWindowTimer2 ); macHdr.Value = payload[pktHeaderLen++]; switch( macHdr.Bits.MType ) { case FRAME_TYPE_JOIN_ACCEPT: - if( IsLoRaMacNetworkJoined == true ) + if( _params.IsLoRaMacNetworkJoined == true ) { McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_ERROR; PrepareRxDoneAbort( ); return; } - if (0 != LoRaMacJoinDecrypt( payload + 1, size - 1, LoRaMacAppKey, LoRaMacRxPayload + 1 )) { + if (0 != LoRaMacJoinDecrypt( payload + 1, size - 1, + _params.keys.LoRaMacAppKey, + _params.LoRaMacRxPayload + 1 )) { McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL; return; } - LoRaMacRxPayload[0] = macHdr.Value; + _params.LoRaMacRxPayload[0] = macHdr.Value; - if (0 != LoRaMacJoinComputeMic( LoRaMacRxPayload, size - LORAMAC_MFR_LEN, LoRaMacAppKey, &mic )) { + if (0 != LoRaMacJoinComputeMic( _params.LoRaMacRxPayload, + size - LORAMAC_MFR_LEN, + _params.keys.LoRaMacAppKey, + &mic )) { McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL; return; } - micRx |= ( uint32_t )LoRaMacRxPayload[size - LORAMAC_MFR_LEN]; - micRx |= ( ( uint32_t )LoRaMacRxPayload[size - LORAMAC_MFR_LEN + 1] << 8 ); - micRx |= ( ( uint32_t )LoRaMacRxPayload[size - LORAMAC_MFR_LEN + 2] << 16 ); - micRx |= ( ( uint32_t )LoRaMacRxPayload[size - LORAMAC_MFR_LEN + 3] << 24 ); + micRx |= ( uint32_t ) _params.LoRaMacRxPayload[size - LORAMAC_MFR_LEN]; + micRx |= ( ( uint32_t ) _params.LoRaMacRxPayload[size - LORAMAC_MFR_LEN + 1] << 8 ); + micRx |= ( ( uint32_t ) _params.LoRaMacRxPayload[size - LORAMAC_MFR_LEN + 2] << 16 ); + micRx |= ( ( uint32_t ) _params.LoRaMacRxPayload[size - LORAMAC_MFR_LEN + 3] << 24 ); if( micRx == mic ) { - if (0 != LoRaMacJoinComputeSKeys( LoRaMacAppKey, LoRaMacRxPayload + 1, LoRaMacDevNonce, LoRaMacNwkSKey, LoRaMacAppSKey )) { + if (0 != LoRaMacJoinComputeSKeys( _params.keys.LoRaMacAppKey, + _params.LoRaMacRxPayload + 1, + _params.LoRaMacDevNonce, + _params.keys.LoRaMacNwkSKey, + _params.keys.LoRaMacAppSKey )) { McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL; return; } - LoRaMacNetID = ( uint32_t )LoRaMacRxPayload[4]; - LoRaMacNetID |= ( ( uint32_t )LoRaMacRxPayload[5] << 8 ); - LoRaMacNetID |= ( ( uint32_t )LoRaMacRxPayload[6] << 16 ); + _params.LoRaMacNetID = ( uint32_t ) _params.LoRaMacRxPayload[4]; + _params.LoRaMacNetID |= ( ( uint32_t ) _params.LoRaMacRxPayload[5] << 8 ); + _params.LoRaMacNetID |= ( ( uint32_t ) _params.LoRaMacRxPayload[6] << 16 ); - LoRaMacDevAddr = ( uint32_t )LoRaMacRxPayload[7]; - LoRaMacDevAddr |= ( ( uint32_t )LoRaMacRxPayload[8] << 8 ); - LoRaMacDevAddr |= ( ( uint32_t )LoRaMacRxPayload[9] << 16 ); - LoRaMacDevAddr |= ( ( uint32_t )LoRaMacRxPayload[10] << 24 ); + _params.LoRaMacDevAddr = ( uint32_t ) _params.LoRaMacRxPayload[7]; + _params.LoRaMacDevAddr |= ( ( uint32_t ) _params.LoRaMacRxPayload[8] << 8 ); + _params.LoRaMacDevAddr |= ( ( uint32_t ) _params.LoRaMacRxPayload[9] << 16 ); + _params.LoRaMacDevAddr |= ( ( uint32_t ) _params.LoRaMacRxPayload[10] << 24 ); // DLSettings - LoRaMacParams.Rx1DrOffset = ( LoRaMacRxPayload[11] >> 4 ) & 0x07; - LoRaMacParams.Rx2Channel.Datarate = LoRaMacRxPayload[11] & 0x0F; + LoRaMacParams.Rx1DrOffset = ( _params.LoRaMacRxPayload[11] >> 4 ) & 0x07; + LoRaMacParams.Rx2Channel.Datarate = _params.LoRaMacRxPayload[11] & 0x0F; // RxDelay - LoRaMacParams.ReceiveDelay1 = ( LoRaMacRxPayload[12] & 0x0F ); + LoRaMacParams.ReceiveDelay1 = ( _params.LoRaMacRxPayload[12] & 0x0F ); if( LoRaMacParams.ReceiveDelay1 == 0 ) { LoRaMacParams.ReceiveDelay1 = 1; @@ -423,14 +400,14 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 LoRaMacParams.ReceiveDelay2 = LoRaMacParams.ReceiveDelay1 + 1000; // Apply CF list - applyCFList.Payload = &LoRaMacRxPayload[13]; + applyCFList.Payload = &_params.LoRaMacRxPayload[13]; // Size of the regular payload is 12. Plus 1 byte MHDR and 4 bytes MIC applyCFList.Size = size - 17; lora_phy->apply_cf_list(&applyCFList); MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK; - IsLoRaMacNetworkJoined = true; + _params.IsLoRaMacNetworkJoined = true; } else { @@ -446,7 +423,7 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 getPhy.Attribute = PHY_MAX_PAYLOAD; // Get the maximum payload length - if( RepeaterSupport == true ) + if( _params.RepeaterSupport == true ) { getPhy.Attribute = PHY_MAX_PAYLOAD_REPEATER; } @@ -463,7 +440,7 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 address |= ( (uint32_t)payload[pktHeaderLen++] << 16 ); address |= ( (uint32_t)payload[pktHeaderLen++] << 24 ); - if( address != LoRaMacDevAddr ) + if( address != _params.LoRaMacDevAddr ) { curMulticastParams = MulticastChannels; while( curMulticastParams != NULL ) @@ -489,9 +466,9 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 else { multicast = 0; - nwkSKey = LoRaMacNwkSKey; - appSKey = LoRaMacAppSKey; - downLinkCounter = DownLinkCounter; + nwkSKey = _params.keys.LoRaMacNwkSKey; + appSKey = _params.keys.LoRaMacAppSKey; + downLinkCounter = _params.DownLinkCounter; } fCtrl.Value = payload[pktHeaderLen++]; @@ -552,7 +529,7 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK; - AdrAckCounter = 0; + _params.AdrAckCounter = 0; mac_commands.ClearRepeatBuffer(); // Update 32 bits downlink counter @@ -574,11 +551,11 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 { if( macHdr.Bits.MType == FRAME_TYPE_DATA_CONFIRMED_DOWN ) { - SrvAckRequested = true; + _params.SrvAckRequested = true; McpsIndication.McpsIndication = MCPS_CONFIRMED; - if( ( DownLinkCounter == downLinkCounter ) && - ( DownLinkCounter != 0 ) ) + if( ( _params.DownLinkCounter == downLinkCounter ) && + ( _params.DownLinkCounter != 0 ) ) { // Duplicated confirmed downlink. Skip indication. // In this case, the MAC layer shall accept the MAC commands @@ -590,11 +567,11 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 } else { - SrvAckRequested = false; + _params.SrvAckRequested = false; McpsIndication.McpsIndication = MCPS_UNCONFIRMED; - if( ( DownLinkCounter == downLinkCounter ) && - ( DownLinkCounter != 0 ) ) + if( ( _params.DownLinkCounter == downLinkCounter ) && + ( _params.DownLinkCounter != 0 ) ) { McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED; McpsIndication.DownLinkCounter = downLinkCounter; @@ -602,7 +579,7 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 return; } } - DownLinkCounter = downLinkCounter; + _params.DownLinkCounter = downLinkCounter; } // This must be done before parsing the payload and the MAC commands. @@ -640,12 +617,12 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 address, DOWN_LINK, downLinkCounter, - LoRaMacRxPayload )) { + _params.LoRaMacRxPayload )) { McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL; } // Decode frame payload MAC commands - mac_commands.ProcessMacCommands( LoRaMacRxPayload, 0, frameLen, snr, + mac_commands.ProcessMacCommands( _params.LoRaMacRxPayload, 0, frameLen, snr, MlmeConfirm, LoRaMacCallbacks, LoRaMacParams, *lora_phy ); } @@ -670,13 +647,13 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 address, DOWN_LINK, downLinkCounter, - LoRaMacRxPayload )) { + _params.LoRaMacRxPayload )) { McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL; } if( skipIndication == false ) { - McpsIndication.Buffer = LoRaMacRxPayload; + McpsIndication.Buffer = _params.LoRaMacRxPayload; McpsIndication.BufferSize = frameLen; McpsIndication.RxData = true; } @@ -703,24 +680,24 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 // Stop the AckTimeout timer as no more retransmissions // are needed. - _lora_time.TimerStop( &AckTimeoutTimer ); + _lora_time.TimerStop( &_params.timers.AckTimeoutTimer ); } else { McpsConfirm.AckReceived = false; - if( AckTimeoutRetriesCounter > AckTimeoutRetries ) + if( _params.AckTimeoutRetriesCounter > _params.AckTimeoutRetries ) { // Stop the AckTimeout timer as no more retransmissions // are needed. - _lora_time.TimerStop( &AckTimeoutTimer ); + _lora_time.TimerStop( &_params.timers.AckTimeoutTimer ); } } } // Provide always an indication, skip the callback to the user application, // in case of a confirmed downlink retransmission. - LoRaMacFlags.Bits.McpsInd = 1; - LoRaMacFlags.Bits.McpsIndSkip = skipIndication; + _params.LoRaMacFlags.Bits.McpsInd = 1; + _params.LoRaMacFlags.Bits.McpsIndSkip = skipIndication; } else { @@ -733,14 +710,14 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 break; case FRAME_TYPE_PROPRIETARY: { - memcpy( LoRaMacRxPayload, &payload[pktHeaderLen], size ); + memcpy( _params.LoRaMacRxPayload, &payload[pktHeaderLen], size ); McpsIndication.McpsIndication = MCPS_PROPRIETARY; McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_OK; - McpsIndication.Buffer = LoRaMacRxPayload; + McpsIndication.Buffer = _params.LoRaMacRxPayload; McpsIndication.BufferSize = size - pktHeaderLen; - LoRaMacFlags.Bits.McpsInd = 1; + _params.LoRaMacFlags.Bits.McpsInd = 1; break; } default: @@ -748,16 +725,16 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 PrepareRxDoneAbort( ); break; } - LoRaMacFlags.Bits.MacDone = 1; + _params.LoRaMacFlags.Bits.MacDone = 1; // Trig OnMacCheckTimerEvent call as soon as possible - _lora_time.TimerSetValue( &MacStateCheckTimer, 1 ); - _lora_time.TimerStart( &MacStateCheckTimer ); + _lora_time.TimerSetValue( &_params.timers.MacStateCheckTimer, 1 ); + _lora_time.TimerStart( &_params.timers.MacStateCheckTimer ); } void LoRaMac::OnRadioTxTimeout( void ) { - if( LoRaMacDeviceClass != CLASS_C ) + if( _params.LoRaMacDeviceClass != CLASS_C ) { lora_phy->put_radio_to_sleep(); } @@ -768,12 +745,12 @@ void LoRaMac::OnRadioTxTimeout( void ) McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT; MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT; - LoRaMacFlags.Bits.MacDone = 1; + _params.LoRaMacFlags.Bits.MacDone = 1; } void LoRaMac::OnRadioRxError( void ) { - if( LoRaMacDeviceClass != CLASS_C ) + if( _params.LoRaMacDeviceClass != CLASS_C ) { lora_phy->put_radio_to_sleep(); } @@ -784,32 +761,32 @@ void LoRaMac::OnRadioRxError( void ) if( RxSlot == RX_SLOT_WIN_1 ) { - if( NodeAckRequested == true ) + if( _params.NodeAckRequested == true ) { McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX1_ERROR; } MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX1_ERROR; - if( _lora_time.TimerGetElapsedTime( AggregatedLastTxDoneTime ) >= RxWindow2Delay ) + if( _lora_time.TimerGetElapsedTime( _params.timers.AggregatedLastTxDoneTime ) >= RxWindow2Delay ) { - _lora_time.TimerStop( &RxWindowTimer2 ); - LoRaMacFlags.Bits.MacDone = 1; + _lora_time.TimerStop( &_params.timers.RxWindowTimer2 ); + _params.LoRaMacFlags.Bits.MacDone = 1; } } else { - if( NodeAckRequested == true ) + if( _params.NodeAckRequested == true ) { McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX2_ERROR; } MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX2_ERROR; - LoRaMacFlags.Bits.MacDone = 1; + _params.LoRaMacFlags.Bits.MacDone = 1; } } void LoRaMac::OnRadioRxTimeout( void ) { - if( LoRaMacDeviceClass != CLASS_C ) + if( _params.LoRaMacDeviceClass != CLASS_C ) { lora_phy->put_radio_to_sleep(); } @@ -820,29 +797,29 @@ void LoRaMac::OnRadioRxTimeout( void ) if( RxSlot == RX_SLOT_WIN_1 ) { - if( NodeAckRequested == true ) + if( _params.NodeAckRequested == true ) { McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX1_TIMEOUT; } MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX1_TIMEOUT; - if( _lora_time.TimerGetElapsedTime( AggregatedLastTxDoneTime ) >= RxWindow2Delay ) + if( _lora_time.TimerGetElapsedTime( _params.timers.AggregatedLastTxDoneTime ) >= RxWindow2Delay ) { - _lora_time.TimerStop( &RxWindowTimer2 ); - LoRaMacFlags.Bits.MacDone = 1; + _lora_time.TimerStop( &_params.timers.RxWindowTimer2 ); + _params.LoRaMacFlags.Bits.MacDone = 1; } } else { - if( NodeAckRequested == true ) + if( _params.NodeAckRequested == true ) { McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT; } MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT; - if( LoRaMacDeviceClass != CLASS_C ) + if( _params.LoRaMacDeviceClass != CLASS_C ) { - LoRaMacFlags.Bits.MacDone = 1; + _params.LoRaMacFlags.Bits.MacDone = 1; } } } @@ -856,54 +833,54 @@ void LoRaMac::OnMacStateCheckTimerEvent( void ) PhyParam_t phyParam; bool txTimeout = false; - _lora_time.TimerStop( &MacStateCheckTimer ); + _lora_time.TimerStop( &_params.timers.MacStateCheckTimer ); - if( LoRaMacFlags.Bits.MacDone == 1 ) + if( _params.LoRaMacFlags.Bits.MacDone == 1 ) { - if( ( LoRaMacState & LORAMAC_RX_ABORT ) == LORAMAC_RX_ABORT ) + if( ( _params.LoRaMacState & LORAMAC_RX_ABORT ) == LORAMAC_RX_ABORT ) { - LoRaMacState &= ~LORAMAC_RX_ABORT; - LoRaMacState &= ~LORAMAC_TX_RUNNING; + _params.LoRaMacState &= ~LORAMAC_RX_ABORT; + _params.LoRaMacState &= ~LORAMAC_TX_RUNNING; } - if( ( LoRaMacFlags.Bits.MlmeReq == 1 ) || ( ( LoRaMacFlags.Bits.McpsReq == 1 ) ) ) + if( ( _params.LoRaMacFlags.Bits.MlmeReq == 1 ) || ( ( _params.LoRaMacFlags.Bits.McpsReq == 1 ) ) ) { if( ( McpsConfirm.Status == LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT ) || ( MlmeConfirm.Status == LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT ) ) { // Stop transmit cycle due to tx timeout. - LoRaMacState &= ~LORAMAC_TX_RUNNING; + _params.LoRaMacState &= ~LORAMAC_TX_RUNNING; mac_commands.ClearCommandBuffer(); - McpsConfirm.NbRetries = AckTimeoutRetriesCounter; + McpsConfirm.NbRetries = _params.AckTimeoutRetriesCounter; McpsConfirm.AckReceived = false; McpsConfirm.TxTimeOnAir = 0; txTimeout = true; } } - if( ( NodeAckRequested == false ) && ( txTimeout == false ) ) + if( ( _params.NodeAckRequested == false ) && ( txTimeout == false ) ) { - if( ( LoRaMacFlags.Bits.MlmeReq == 1 ) || ( ( LoRaMacFlags.Bits.McpsReq == 1 ) ) ) + if( ( _params.LoRaMacFlags.Bits.MlmeReq == 1 ) || ( ( _params.LoRaMacFlags.Bits.McpsReq == 1 ) ) ) { - if( ( LoRaMacFlags.Bits.MlmeReq == 1 ) && ( MlmeConfirm.MlmeRequest == MLME_JOIN ) ) + if( ( _params.LoRaMacFlags.Bits.MlmeReq == 1 ) && ( MlmeConfirm.MlmeRequest == MLME_JOIN ) ) {// Procedure for the join request - MlmeConfirm.NbRetries = JoinRequestTrials; + MlmeConfirm.NbRetries = _params.JoinRequestTrials; if( MlmeConfirm.Status == LORAMAC_EVENT_INFO_STATUS_OK ) {// Node joined successfully - UpLinkCounter = 0; - ChannelsNbRepCounter = 0; - LoRaMacState &= ~LORAMAC_TX_RUNNING; + _params.UpLinkCounter = 0; + _params.ChannelsNbRepCounter = 0; + _params.LoRaMacState &= ~LORAMAC_TX_RUNNING; } else { - if( JoinRequestTrials >= MaxJoinRequestTrials ) + if( _params.JoinRequestTrials >= _params.MaxJoinRequestTrials ) { - LoRaMacState &= ~LORAMAC_TX_RUNNING; + _params.LoRaMacState &= ~LORAMAC_TX_RUNNING; } else { - LoRaMacFlags.Bits.MacDone = 0; + _params.LoRaMacFlags.Bits.MacDone = 0; // Sends the same frame again handle_delayed_tx_timer_event(); } @@ -911,27 +888,27 @@ void LoRaMac::OnMacStateCheckTimerEvent( void ) } else {// Procedure for all other frames - if( ( ChannelsNbRepCounter >= LoRaMacParams.ChannelsNbRep ) || ( LoRaMacFlags.Bits.McpsInd == 1 ) ) + if( ( _params.ChannelsNbRepCounter >= LoRaMacParams.ChannelsNbRep ) || ( _params.LoRaMacFlags.Bits.McpsInd == 1 ) ) { - if( LoRaMacFlags.Bits.McpsInd == 0 ) + if( _params.LoRaMacFlags.Bits.McpsInd == 0 ) { // Maximum repetitions without downlink. Reset MacCommandsBufferIndex. Increase ADR Ack counter. // Only process the case when the MAC did not receive a downlink. mac_commands.ClearCommandBuffer(); - AdrAckCounter++; + _params.AdrAckCounter++; } - ChannelsNbRepCounter = 0; + _params.ChannelsNbRepCounter = 0; - if( IsUpLinkCounterFixed == false ) + if( _params.IsUpLinkCounterFixed == false ) { - UpLinkCounter++; + _params.UpLinkCounter++; } - LoRaMacState &= ~LORAMAC_TX_RUNNING; + _params.LoRaMacState &= ~LORAMAC_TX_RUNNING; } else { - LoRaMacFlags.Bits.MacDone = 0; + _params.LoRaMacFlags.Bits.MacDone = 0; // Sends the same frame again handle_delayed_tx_timer_event(); } @@ -939,30 +916,32 @@ void LoRaMac::OnMacStateCheckTimerEvent( void ) } } - if( LoRaMacFlags.Bits.McpsInd == 1 ) + if( _params.LoRaMacFlags.Bits.McpsInd == 1 ) {// Procedure if we received a frame - if( ( McpsConfirm.AckReceived == true ) || ( AckTimeoutRetriesCounter > AckTimeoutRetries ) ) + if( ( McpsConfirm.AckReceived == true ) || + ( _params.AckTimeoutRetriesCounter > _params.AckTimeoutRetries ) ) { - AckTimeoutRetry = false; - NodeAckRequested = false; - if( IsUpLinkCounterFixed == false ) + _params.AckTimeoutRetry = false; + _params.NodeAckRequested = false; + if( _params.IsUpLinkCounterFixed == false ) { - UpLinkCounter++; + _params.UpLinkCounter++; } - McpsConfirm.NbRetries = AckTimeoutRetriesCounter; + McpsConfirm.NbRetries = _params.AckTimeoutRetriesCounter; - LoRaMacState &= ~LORAMAC_TX_RUNNING; + _params.LoRaMacState &= ~LORAMAC_TX_RUNNING; } } - if( ( AckTimeoutRetry == true ) && ( ( LoRaMacState & LORAMAC_TX_DELAYED ) == 0 ) ) + if( ( _params.AckTimeoutRetry == true ) && ( ( _params.LoRaMacState & LORAMAC_TX_DELAYED ) == 0 ) ) {// Retransmissions procedure for confirmed uplinks - AckTimeoutRetry = false; - if( ( AckTimeoutRetriesCounter < AckTimeoutRetries ) && ( AckTimeoutRetriesCounter <= MAX_ACK_RETRIES ) ) + _params.AckTimeoutRetry = false; + if( ( _params.AckTimeoutRetriesCounter < _params.AckTimeoutRetries ) && + ( _params.AckTimeoutRetriesCounter <= MAX_ACK_RETRIES ) ) { - AckTimeoutRetriesCounter++; + _params.AckTimeoutRetriesCounter++; - if( ( AckTimeoutRetriesCounter % 2 ) == 1 ) + if( ( _params.AckTimeoutRetriesCounter % 2 ) == 1 ) { getPhy.Attribute = PHY_NEXT_LOWER_TX_DR; getPhy.UplinkDwellTime = LoRaMacParams.UplinkDwellTime; @@ -973,7 +952,7 @@ void LoRaMac::OnMacStateCheckTimerEvent( void ) // Try to send the frame again if( ScheduleTx( ) == LORAMAC_STATUS_OK ) { - LoRaMacFlags.Bits.MacDone = 0; + _params.LoRaMacFlags.Bits.MacDone = 0; } else { @@ -981,14 +960,14 @@ void LoRaMac::OnMacStateCheckTimerEvent( void ) McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_TX_DR_PAYLOAD_SIZE_ERROR; mac_commands.ClearCommandBuffer(); - LoRaMacState &= ~LORAMAC_TX_RUNNING; - NodeAckRequested = false; + _params.LoRaMacState &= ~LORAMAC_TX_RUNNING; + _params.NodeAckRequested = false; McpsConfirm.AckReceived = false; - McpsConfirm.NbRetries = AckTimeoutRetriesCounter; + McpsConfirm.NbRetries = _params.AckTimeoutRetriesCounter; McpsConfirm.Datarate = LoRaMacParams.ChannelsDatarate; - if( IsUpLinkCounterFixed == false ) + if( _params.IsUpLinkCounterFixed == false ) { - UpLinkCounter++; + _params.UpLinkCounter++; } } } @@ -996,35 +975,35 @@ void LoRaMac::OnMacStateCheckTimerEvent( void ) { lora_phy->load_defaults(INIT_TYPE_RESTORE); - LoRaMacState &= ~LORAMAC_TX_RUNNING; + _params.LoRaMacState &= ~LORAMAC_TX_RUNNING; mac_commands.ClearCommandBuffer(); - NodeAckRequested = false; + _params.NodeAckRequested = false; McpsConfirm.AckReceived = false; - McpsConfirm.NbRetries = AckTimeoutRetriesCounter; - if( IsUpLinkCounterFixed == false ) + McpsConfirm.NbRetries = _params.AckTimeoutRetriesCounter; + if( _params.IsUpLinkCounterFixed == false ) { - UpLinkCounter++; + _params.UpLinkCounter++; } } } } // Handle reception for Class B and Class C - if( ( LoRaMacState & LORAMAC_RX ) == LORAMAC_RX ) + if( ( _params.LoRaMacState & LORAMAC_RX ) == LORAMAC_RX ) { - LoRaMacState &= ~LORAMAC_RX; + _params.LoRaMacState &= ~LORAMAC_RX; } - if( LoRaMacState == LORAMAC_IDLE ) + if( _params.LoRaMacState == LORAMAC_IDLE ) { - if( LoRaMacFlags.Bits.McpsReq == 1 ) + if( _params.LoRaMacFlags.Bits.McpsReq == 1 ) { - LoRaMacFlags.Bits.McpsReq = 0; + _params.LoRaMacFlags.Bits.McpsReq = 0; LoRaMacPrimitives->MacMcpsConfirm( &McpsConfirm ); } - if( LoRaMacFlags.Bits.MlmeReq == 1 ) + if( _params.LoRaMacFlags.Bits.MlmeReq == 1 ) { - LoRaMacFlags.Bits.MlmeReq = 0; + _params.LoRaMacFlags.Bits.MlmeReq = 0; LoRaMacPrimitives->MacMlmeConfirm( &MlmeConfirm ); } @@ -1035,34 +1014,35 @@ void LoRaMac::OnMacStateCheckTimerEvent( void ) } // Procedure done. Reset variables. - LoRaMacFlags.Bits.MacDone = 0; + _params.LoRaMacFlags.Bits.MacDone = 0; } else { // Operation not finished restart timer - _lora_time.TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT ); - _lora_time.TimerStart( &MacStateCheckTimer ); + _lora_time.TimerSetValue( &_params.timers.MacStateCheckTimer, + MAC_STATE_CHECK_TIMEOUT ); + _lora_time.TimerStart( &_params.timers.MacStateCheckTimer ); } // Handle MCPS indication - if( LoRaMacFlags.Bits.McpsInd == 1 ) + if( _params.LoRaMacFlags.Bits.McpsInd == 1 ) { - LoRaMacFlags.Bits.McpsInd = 0; - if( LoRaMacDeviceClass == CLASS_C ) + _params.LoRaMacFlags.Bits.McpsInd = 0; + if( _params.LoRaMacDeviceClass == CLASS_C ) {// Activate RX2 window for Class C OpenContinuousRx2Window( ); } - if( LoRaMacFlags.Bits.McpsIndSkip == 0 ) + if( _params.LoRaMacFlags.Bits.McpsIndSkip == 0 ) { LoRaMacPrimitives->MacMcpsIndication( &McpsIndication ); } - LoRaMacFlags.Bits.McpsIndSkip = 0; + _params.LoRaMacFlags.Bits.McpsIndSkip = 0; } // Handle MLME indication - if( LoRaMacFlags.Bits.MlmeInd == 1 ) + if( _params.LoRaMacFlags.Bits.MlmeInd == 1 ) { - LoRaMacFlags.Bits.MlmeInd = 0; + _params.LoRaMacFlags.Bits.MlmeInd = 0; LoRaMacPrimitives->MacMlmeIndication( &MlmeIndication ); } } @@ -1073,14 +1053,14 @@ void LoRaMac::OnTxDelayedTimerEvent( void ) LoRaMacFrameCtrl_t fCtrl; AlternateDrParams_t altDr; - _lora_time.TimerStop( &TxDelayedTimer ); - LoRaMacState &= ~LORAMAC_TX_DELAYED; + _lora_time.TimerStop( &_params.timers.TxDelayedTimer ); + _params.LoRaMacState &= ~LORAMAC_TX_DELAYED; - if( ( LoRaMacFlags.Bits.MlmeReq == 1 ) && ( MlmeConfirm.MlmeRequest == MLME_JOIN ) ) + if( ( _params.LoRaMacFlags.Bits.MlmeReq == 1 ) && ( MlmeConfirm.MlmeRequest == MLME_JOIN ) ) { ResetMacParameters( ); - altDr.NbTrials = JoinRequestTrials + 1; + altDr.NbTrials = _params.JoinRequestTrials + 1; LoRaMacParams.ChannelsDatarate = lora_phy->get_alternate_DR(&altDr); macHdr.Value = 0; @@ -1100,17 +1080,17 @@ void LoRaMac::OnTxDelayedTimerEvent( void ) void LoRaMac::OnRxWindow1TimerEvent( void ) { - _lora_time.TimerStop( &RxWindowTimer1 ); + _lora_time.TimerStop( &_params.timers.RxWindowTimer1 ); RxSlot = RX_SLOT_WIN_1; - RxWindow1Config.Channel = Channel; + RxWindow1Config.Channel = _params.Channel; RxWindow1Config.DrOffset = LoRaMacParams.Rx1DrOffset; RxWindow1Config.DownlinkDwellTime = LoRaMacParams.DownlinkDwellTime; - RxWindow1Config.RepeaterSupport = RepeaterSupport; + RxWindow1Config.RepeaterSupport = _params.RepeaterSupport; RxWindow1Config.RxContinuous = false; RxWindow1Config.RxSlot = RxSlot; - if( LoRaMacDeviceClass == CLASS_C ) + if( _params.LoRaMacDeviceClass == CLASS_C ) { lora_phy->put_radio_to_standby(); } @@ -1121,15 +1101,15 @@ void LoRaMac::OnRxWindow1TimerEvent( void ) void LoRaMac::OnRxWindow2TimerEvent( void ) { - _lora_time.TimerStop( &RxWindowTimer2 ); + _lora_time.TimerStop( &_params.timers.RxWindowTimer2 ); - RxWindow2Config.Channel = Channel; + RxWindow2Config.Channel = _params.Channel; RxWindow2Config.Frequency = LoRaMacParams.Rx2Channel.Frequency; RxWindow2Config.DownlinkDwellTime = LoRaMacParams.DownlinkDwellTime; - RxWindow2Config.RepeaterSupport = RepeaterSupport; + RxWindow2Config.RepeaterSupport = _params.RepeaterSupport; RxWindow2Config.RxSlot = RX_SLOT_WIN_2; - if( LoRaMacDeviceClass != CLASS_C ) + if( _params.LoRaMacDeviceClass != CLASS_C ) { RxWindow2Config.RxContinuous = false; } @@ -1148,16 +1128,16 @@ void LoRaMac::OnRxWindow2TimerEvent( void ) void LoRaMac::OnAckTimeoutTimerEvent( void ) { - _lora_time.TimerStop( &AckTimeoutTimer ); + _lora_time.TimerStop( &_params.timers.AckTimeoutTimer ); - if( NodeAckRequested == true ) + if( _params.NodeAckRequested == true ) { - AckTimeoutRetry = true; - LoRaMacState &= ~LORAMAC_ACK_REQ; + _params.AckTimeoutRetry = true; + _params.LoRaMacState &= ~LORAMAC_ACK_REQ; } - if( LoRaMacDeviceClass == CLASS_C ) + if( _params.LoRaMacDeviceClass == CLASS_C ) { - LoRaMacFlags.Bits.MacDone = 1; + _params.LoRaMacFlags.Bits.MacDone = 1; } } @@ -1179,7 +1159,7 @@ bool LoRaMac::ValidatePayloadLength( uint8_t lenN, int8_t datarate, uint8_t fOpt getPhy.Attribute = PHY_MAX_PAYLOAD; // Get the maximum payload length - if( RepeaterSupport == true ) + if( _params.RepeaterSupport == true ) { getPhy.Attribute = PHY_MAX_PAYLOAD_REPEATER; } @@ -1200,7 +1180,7 @@ bool LoRaMac::ValidatePayloadLength( uint8_t lenN, int8_t datarate, uint8_t fOpt void LoRaMac::SetMlmeScheduleUplinkIndication( void ) { MlmeIndication.MlmeIndication = MLME_SCHEDULE_UPLINK; - LoRaMacFlags.Bits.MlmeInd = 1; + _params.LoRaMacFlags.Bits.MlmeInd = 1; } // This is not actual transmission. It just schedules a message in response @@ -1229,7 +1209,7 @@ LoRaMacStatus_t LoRaMac::Send( LoRaMacHeader_t *macHdr, uint8_t fPort, void *fBu // Reset confirm parameters McpsConfirm.NbRetries = 0; McpsConfirm.AckReceived = false; - McpsConfirm.UpLinkCounter = UpLinkCounter; + McpsConfirm.UpLinkCounter = _params.UpLinkCounter; status = ScheduleTx( ); @@ -1248,21 +1228,22 @@ LoRaMacStatus_t LoRaMac::ScheduleTx( void ) } if( LoRaMacParams.MaxDCycle == 0 ) { - AggregatedTimeOff = 0; + _params.timers.AggregatedTimeOff = 0; } // Update Backoff - CalculateBackOff( LastTxChannel ); + CalculateBackOff( _params.LastTxChannel ); - nextChan.AggrTimeOff = AggregatedTimeOff; + nextChan.AggrTimeOff = _params.timers.AggregatedTimeOff; nextChan.Datarate = LoRaMacParams.ChannelsDatarate; - DutyCycleOn = LORAWAN_DUTYCYCLE_ON; - nextChan.DutyCycleEnabled = DutyCycleOn; - nextChan.Joined = IsLoRaMacNetworkJoined; - nextChan.LastAggrTx = AggregatedLastTxDoneTime; + _params.DutyCycleOn = LORAWAN_DUTYCYCLE_ON; + nextChan.DutyCycleEnabled = _params.DutyCycleOn; + nextChan.Joined = _params.IsLoRaMacNetworkJoined; + nextChan.LastAggrTx = _params.timers.AggregatedLastTxDoneTime; // Select channel - while( lora_phy->set_next_channel(&nextChan, &Channel, &dutyCycleTimeOff, &AggregatedTimeOff ) == false ) + while( lora_phy->set_next_channel(&nextChan, &_params.Channel, &dutyCycleTimeOff, + &_params.timers.AggregatedTimeOff ) == false ) { // Set the default datarate LoRaMacParams.ChannelsDatarate = LoRaMacParamsDefaults.ChannelsDatarate; @@ -1270,7 +1251,7 @@ LoRaMacStatus_t LoRaMac::ScheduleTx( void ) nextChan.Datarate = LoRaMacParams.ChannelsDatarate; } - tr_debug("Next Channel Idx=%d, DR=%d", Channel, nextChan.Datarate); + tr_debug("Next Channel Idx=%d, DR=%d", _params.Channel, nextChan.Datarate); // Compute Rx1 windows parameters uint8_t dr_offset = lora_phy->apply_DR_offset(LoRaMacParams.DownlinkDwellTime, @@ -1286,14 +1267,16 @@ LoRaMacStatus_t LoRaMac::ScheduleTx( void ) LoRaMacParams.SystemMaxRxError, &RxWindow2Config ); - if( IsLoRaMacNetworkJoined == false ) + if( _params.IsLoRaMacNetworkJoined == false ) { RxWindow1Delay = LoRaMacParams.JoinAcceptDelay1 + RxWindow1Config.WindowOffset; RxWindow2Delay = LoRaMacParams.JoinAcceptDelay2 + RxWindow2Config.WindowOffset; } else { - if( ValidatePayloadLength( LoRaMacTxPayloadLen, LoRaMacParams.ChannelsDatarate, mac_commands.GetLength() ) == false ) + if( ValidatePayloadLength( _params.LoRaMacTxPayloadLen, + LoRaMacParams.ChannelsDatarate, + mac_commands.GetLength() ) == false ) { return LORAMAC_STATUS_LENGTH_ERROR; } @@ -1305,16 +1288,16 @@ LoRaMacStatus_t LoRaMac::ScheduleTx( void ) if( dutyCycleTimeOff == 0 ) { // Try to send now - return SendFrameOnChannel( Channel ); + return SendFrameOnChannel( _params.Channel ); } else { // Send later - prepare timer - LoRaMacState |= LORAMAC_TX_DELAYED; + _params.LoRaMacState |= LORAMAC_TX_DELAYED; tr_debug("Next Transmission in %lu ms", dutyCycleTimeOff); - _lora_time.TimerSetValue( &TxDelayedTimer, dutyCycleTimeOff ); - _lora_time.TimerStart( &TxDelayedTimer ); + _lora_time.TimerSetValue( &_params.timers.TxDelayedTimer, dutyCycleTimeOff ); + _lora_time.TimerStart( &_params.timers.TxDelayedTimer ); return LORAMAC_STATUS_OK; } @@ -1324,35 +1307,36 @@ void LoRaMac::CalculateBackOff( uint8_t channel ) { CalcBackOffParams_t calcBackOff; - calcBackOff.Joined = IsLoRaMacNetworkJoined; - DutyCycleOn = LORAWAN_DUTYCYCLE_ON; - calcBackOff.DutyCycleEnabled = DutyCycleOn; + calcBackOff.Joined = _params.IsLoRaMacNetworkJoined; + _params.DutyCycleOn = LORAWAN_DUTYCYCLE_ON; + calcBackOff.DutyCycleEnabled = _params.DutyCycleOn; calcBackOff.Channel = channel; - calcBackOff.ElapsedTime = _lora_time.TimerGetElapsedTime( LoRaMacInitializationTime ); - calcBackOff.TxTimeOnAir = TxTimeOnAir; - calcBackOff.LastTxIsJoinRequest = LastTxIsJoinRequest; + calcBackOff.ElapsedTime = _lora_time.TimerGetElapsedTime( _params.timers.LoRaMacInitializationTime ); + calcBackOff.TxTimeOnAir = _params.timers.TxTimeOnAir; + calcBackOff.LastTxIsJoinRequest = _params.LastTxIsJoinRequest; // Update regional back-off lora_phy->calculate_backoff(&calcBackOff); // Update aggregated time-off - AggregatedTimeOff = AggregatedTimeOff + ( TxTimeOnAir * LoRaMacParams.AggregatedDCycle - TxTimeOnAir ); + _params.timers.AggregatedTimeOff = _params.timers.AggregatedTimeOff + + ( _params.timers.TxTimeOnAir * LoRaMacParams.AggregatedDCycle - _params.timers.TxTimeOnAir ); } void LoRaMac::ResetMacParameters( void ) { - IsLoRaMacNetworkJoined = false; + _params.IsLoRaMacNetworkJoined = false; // Counters - UpLinkCounter = 0; - DownLinkCounter = 0; - AdrAckCounter = 0; + _params.UpLinkCounter = 0; + _params.DownLinkCounter = 0; + _params.AdrAckCounter = 0; - ChannelsNbRepCounter = 0; + _params.ChannelsNbRepCounter = 0; - AckTimeoutRetries = 1; - AckTimeoutRetriesCounter = 1; - AckTimeoutRetry = false; + _params.AckTimeoutRetries = 1; + _params.AckTimeoutRetriesCounter = 1; + _params.AckTimeoutRetry = false; LoRaMacParams.MaxDCycle = 0; LoRaMacParams.AggregatedDCycle = 1; @@ -1361,7 +1345,7 @@ void LoRaMac::ResetMacParameters( void ) mac_commands.ClearRepeatBuffer(); mac_commands.ClearMacCommandsInNextTx(); - IsRxWindowsEnabled = true; + _params.IsRxWindowsEnabled = true; LoRaMacParams.ChannelsTxPower = LoRaMacParamsDefaults.ChannelsTxPower; LoRaMacParams.ChannelsDatarate = LoRaMacParamsDefaults.ChannelsDatarate; @@ -1372,8 +1356,8 @@ void LoRaMac::ResetMacParameters( void ) LoRaMacParams.MaxEirp = LoRaMacParamsDefaults.MaxEirp; LoRaMacParams.AntennaGain = LoRaMacParamsDefaults.AntennaGain; - NodeAckRequested = false; - SrvAckRequested = false; + _params.NodeAckRequested = false; + _params.SrvAckRequested = false; // Reset Multicast downlink counters MulticastParams_t *cur = MulticastChannels; @@ -1384,8 +1368,8 @@ void LoRaMac::ResetMacParameters( void ) } // Initialize channel index. - Channel = 0; - LastTxChannel = Channel; + _params.Channel = 0; + _params.LastTxChannel = _params.Channel; } bool LoRaMac::IsFPortAllowed( uint8_t fPort ) @@ -1422,50 +1406,54 @@ LoRaMacStatus_t LoRaMac::PrepareFrame( LoRaMacHeader_t *macHdr, LoRaMacFrameCtrl uint8_t framePort = fPort; LoRaMacStatus_t status = LORAMAC_STATUS_OK; - LoRaMacBufferPktLen = 0; + _params.LoRaMacBufferPktLen = 0; - NodeAckRequested = false; + _params.NodeAckRequested = false; if( fBuffer == NULL ) { fBufferSize = 0; } - LoRaMacTxPayloadLen = fBufferSize; + _params.LoRaMacTxPayloadLen = fBufferSize; - LoRaMacBuffer[pktHeaderLen++] = macHdr->Value; + _params.LoRaMacBuffer[pktHeaderLen++] = macHdr->Value; switch( macHdr->Bits.MType ) { case FRAME_TYPE_JOIN_REQ: - LoRaMacBufferPktLen = pktHeaderLen; + _params.LoRaMacBufferPktLen = pktHeaderLen; - memcpy_convert_endianess( LoRaMacBuffer + LoRaMacBufferPktLen, LoRaMacAppEui, 8 ); - LoRaMacBufferPktLen += 8; - memcpy_convert_endianess( LoRaMacBuffer + LoRaMacBufferPktLen, LoRaMacDevEui, 8 ); - LoRaMacBufferPktLen += 8; + memcpy_convert_endianess( _params.LoRaMacBuffer + _params.LoRaMacBufferPktLen, + _params.keys.LoRaMacAppEui, 8 ); + _params.LoRaMacBufferPktLen += 8; + memcpy_convert_endianess( _params.LoRaMacBuffer + _params.LoRaMacBufferPktLen, + _params.keys.LoRaMacDevEui, 8 ); + _params.LoRaMacBufferPktLen += 8; - LoRaMacDevNonce = lora_phy->get_radio_rng(); + _params.LoRaMacDevNonce = lora_phy->get_radio_rng(); - LoRaMacBuffer[LoRaMacBufferPktLen++] = LoRaMacDevNonce & 0xFF; - LoRaMacBuffer[LoRaMacBufferPktLen++] = ( LoRaMacDevNonce >> 8 ) & 0xFF; + _params.LoRaMacBuffer[_params.LoRaMacBufferPktLen++] = _params.LoRaMacDevNonce & 0xFF; + _params.LoRaMacBuffer[_params.LoRaMacBufferPktLen++] = ( _params.LoRaMacDevNonce >> 8 ) & 0xFF; - if (0 != LoRaMacJoinComputeMic( LoRaMacBuffer, LoRaMacBufferPktLen & 0xFF, LoRaMacAppKey, &mic )) { + if (0 != LoRaMacJoinComputeMic( _params.LoRaMacBuffer, + _params.LoRaMacBufferPktLen & 0xFF, + _params.keys.LoRaMacAppKey, &mic )) { return LORAMAC_STATUS_CRYPTO_FAIL; } - LoRaMacBuffer[LoRaMacBufferPktLen++] = mic & 0xFF; - LoRaMacBuffer[LoRaMacBufferPktLen++] = ( mic >> 8 ) & 0xFF; - LoRaMacBuffer[LoRaMacBufferPktLen++] = ( mic >> 16 ) & 0xFF; - LoRaMacBuffer[LoRaMacBufferPktLen++] = ( mic >> 24 ) & 0xFF; + _params.LoRaMacBuffer[_params.LoRaMacBufferPktLen++] = mic & 0xFF; + _params.LoRaMacBuffer[_params.LoRaMacBufferPktLen++] = ( mic >> 8 ) & 0xFF; + _params. LoRaMacBuffer[_params.LoRaMacBufferPktLen++] = ( mic >> 16 ) & 0xFF; + _params.LoRaMacBuffer[_params.LoRaMacBufferPktLen++] = ( mic >> 24 ) & 0xFF; break; case FRAME_TYPE_DATA_CONFIRMED_UP: - NodeAckRequested = true; + _params.NodeAckRequested = true; //Intentional fallthrough case FRAME_TYPE_DATA_UNCONFIRMED_UP: { - if( IsLoRaMacNetworkJoined == false ) + if( _params.IsLoRaMacNetworkJoined == false ) { return LORAMAC_STATUS_NO_NETWORK_JOINED; // No network has been joined yet } @@ -1473,7 +1461,7 @@ LoRaMacStatus_t LoRaMac::PrepareFrame( LoRaMacHeader_t *macHdr, LoRaMacFrameCtrl // Adr next request adrNext.UpdateChanMask = true; adrNext.AdrEnabled = fCtrl->Bits.Adr; - adrNext.AdrAckCounter = AdrAckCounter; + adrNext.AdrAckCounter = _params.AdrAckCounter; adrNext.Datarate = LoRaMacParams.ChannelsDatarate; adrNext.TxPower = LoRaMacParams.ChannelsTxPower; adrNext.UplinkDwellTime = LoRaMacParams.UplinkDwellTime; @@ -1481,29 +1469,29 @@ LoRaMacStatus_t LoRaMac::PrepareFrame( LoRaMacHeader_t *macHdr, LoRaMacFrameCtrl fCtrl->Bits.AdrAckReq = lora_phy->get_next_ADR(&adrNext, &LoRaMacParams.ChannelsDatarate, &LoRaMacParams.ChannelsTxPower, - &AdrAckCounter); + &_params.AdrAckCounter); - if( SrvAckRequested == true ) + if( _params.SrvAckRequested == true ) { - SrvAckRequested = false; + _params.SrvAckRequested = false; fCtrl->Bits.Ack = 1; } - LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr ) & 0xFF; - LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr >> 8 ) & 0xFF; - LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr >> 16 ) & 0xFF; - LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr >> 24 ) & 0xFF; + _params.LoRaMacBuffer[pktHeaderLen++] = ( _params.LoRaMacDevAddr ) & 0xFF; + _params.LoRaMacBuffer[pktHeaderLen++] = ( _params.LoRaMacDevAddr >> 8 ) & 0xFF; + _params.LoRaMacBuffer[pktHeaderLen++] = ( _params.LoRaMacDevAddr >> 16 ) & 0xFF; + _params.LoRaMacBuffer[pktHeaderLen++] = ( _params.LoRaMacDevAddr >> 24 ) & 0xFF; - LoRaMacBuffer[pktHeaderLen++] = fCtrl->Value; + _params.LoRaMacBuffer[pktHeaderLen++] = fCtrl->Value; - LoRaMacBuffer[pktHeaderLen++] = UpLinkCounter & 0xFF; - LoRaMacBuffer[pktHeaderLen++] = ( UpLinkCounter >> 8 ) & 0xFF; + _params.LoRaMacBuffer[pktHeaderLen++] = _params.UpLinkCounter & 0xFF; + _params.LoRaMacBuffer[pktHeaderLen++] = ( _params.UpLinkCounter >> 8 ) & 0xFF; // Copy the MAC commands which must be re-send into the MAC command buffer mac_commands.CopyRepeatCommandsToBuffer(); const uint8_t mac_commands_len = mac_commands.GetLength(); - if( ( payload != NULL ) && ( LoRaMacTxPayloadLen > 0 ) ) + if( ( payload != NULL ) && ( _params.LoRaMacTxPayloadLen > 0 ) ) { if( mac_commands.IsMacCommandsInNextTx() == true ) { @@ -1512,17 +1500,17 @@ LoRaMacStatus_t LoRaMac::PrepareFrame( LoRaMacHeader_t *macHdr, LoRaMacFrameCtrl fCtrl->Bits.FOptsLen += mac_commands_len; // Update FCtrl field with new value of OptionsLength - LoRaMacBuffer[0x05] = fCtrl->Value; + _params.LoRaMacBuffer[0x05] = fCtrl->Value; const uint8_t *buffer = mac_commands.GetMacCommandsBuffer(); for( i = 0; i < mac_commands_len; i++ ) { - LoRaMacBuffer[pktHeaderLen++] = buffer[i]; + _params.LoRaMacBuffer[pktHeaderLen++] = buffer[i]; } } else { - LoRaMacTxPayloadLen = mac_commands_len; + _params.LoRaMacTxPayloadLen = mac_commands_len; payload = mac_commands.GetMacCommandsBuffer(); framePort = 0; } @@ -1532,7 +1520,7 @@ LoRaMacStatus_t LoRaMac::PrepareFrame( LoRaMacHeader_t *macHdr, LoRaMacFrameCtrl { if( ( mac_commands_len > 0 ) && ( mac_commands.IsMacCommandsInNextTx() == true ) ) { - LoRaMacTxPayloadLen = mac_commands_len; + _params.LoRaMacTxPayloadLen = mac_commands_len; payload = mac_commands.GetMacCommandsBuffer(); framePort = 0; } @@ -1541,44 +1529,62 @@ LoRaMacStatus_t LoRaMac::PrepareFrame( LoRaMacHeader_t *macHdr, LoRaMacFrameCtrl // Store MAC commands which must be re-send in case the device does not receive a downlink anymore mac_commands.ParseMacCommandsToRepeat(); - if( ( payload != NULL ) && ( LoRaMacTxPayloadLen > 0 ) ) + if( ( payload != NULL ) && ( _params.LoRaMacTxPayloadLen > 0 ) ) { - LoRaMacBuffer[pktHeaderLen++] = framePort; + _params.LoRaMacBuffer[pktHeaderLen++] = framePort; if( framePort == 0 ) { // Reset buffer index as the mac commands are being sent on port 0 mac_commands.ClearCommandBuffer(); - if (0 != LoRaMacPayloadEncrypt( (uint8_t* ) payload, LoRaMacTxPayloadLen, LoRaMacNwkSKey, LoRaMacDevAddr, UP_LINK, UpLinkCounter, &LoRaMacBuffer[pktHeaderLen] )) { + if (0 != LoRaMacPayloadEncrypt( (uint8_t* ) payload, + _params.LoRaMacTxPayloadLen, + _params.keys.LoRaMacNwkSKey, + _params.LoRaMacDevAddr, + UP_LINK, + _params.UpLinkCounter, + &_params.LoRaMacBuffer[pktHeaderLen] )) { status = LORAMAC_STATUS_CRYPTO_FAIL; } } else { - if (0 != LoRaMacPayloadEncrypt( (uint8_t* ) payload, LoRaMacTxPayloadLen, LoRaMacAppSKey, LoRaMacDevAddr, UP_LINK, UpLinkCounter, &LoRaMacBuffer[pktHeaderLen] )) { + if (0 != LoRaMacPayloadEncrypt( (uint8_t* ) payload, + _params.LoRaMacTxPayloadLen, + _params.keys.LoRaMacAppSKey, + _params.LoRaMacDevAddr, + UP_LINK, + _params.UpLinkCounter, + &_params.LoRaMacBuffer[pktHeaderLen] )) { status = LORAMAC_STATUS_CRYPTO_FAIL; } } } - LoRaMacBufferPktLen = pktHeaderLen + LoRaMacTxPayloadLen; + _params.LoRaMacBufferPktLen = pktHeaderLen + _params.LoRaMacTxPayloadLen; - if (0 != LoRaMacComputeMic( LoRaMacBuffer, LoRaMacBufferPktLen, LoRaMacNwkSKey, LoRaMacDevAddr, UP_LINK, UpLinkCounter, &mic )) { + if (0 != LoRaMacComputeMic( _params.LoRaMacBuffer, + _params.LoRaMacBufferPktLen, + _params.keys.LoRaMacNwkSKey, + _params.LoRaMacDevAddr, + UP_LINK, + _params.UpLinkCounter, + &mic )) { status = LORAMAC_STATUS_CRYPTO_FAIL; } - LoRaMacBuffer[LoRaMacBufferPktLen + 0] = mic & 0xFF; - LoRaMacBuffer[LoRaMacBufferPktLen + 1] = ( mic >> 8 ) & 0xFF; - LoRaMacBuffer[LoRaMacBufferPktLen + 2] = ( mic >> 16 ) & 0xFF; - LoRaMacBuffer[LoRaMacBufferPktLen + 3] = ( mic >> 24 ) & 0xFF; + _params.LoRaMacBuffer[_params.LoRaMacBufferPktLen + 0] = mic & 0xFF; + _params.LoRaMacBuffer[_params.LoRaMacBufferPktLen + 1] = ( mic >> 8 ) & 0xFF; + _params.LoRaMacBuffer[_params.LoRaMacBufferPktLen + 2] = ( mic >> 16 ) & 0xFF; + _params.LoRaMacBuffer[_params.LoRaMacBufferPktLen + 3] = ( mic >> 24 ) & 0xFF; - LoRaMacBufferPktLen += LORAMAC_MFR_LEN; + _params.LoRaMacBufferPktLen += LORAMAC_MFR_LEN; } break; case FRAME_TYPE_PROPRIETARY: - if( ( fBuffer != NULL ) && ( LoRaMacTxPayloadLen > 0 ) ) + if( ( fBuffer != NULL ) && (_params.LoRaMacTxPayloadLen > 0 ) ) { - memcpy( LoRaMacBuffer + pktHeaderLen, ( uint8_t* ) fBuffer, LoRaMacTxPayloadLen ); - LoRaMacBufferPktLen = pktHeaderLen + LoRaMacTxPayloadLen; + memcpy( _params.LoRaMacBuffer + pktHeaderLen, ( uint8_t* ) fBuffer, _params.LoRaMacTxPayloadLen ); + _params.LoRaMacBufferPktLen = pktHeaderLen + _params.LoRaMacTxPayloadLen; } break; default: @@ -1598,9 +1604,9 @@ LoRaMacStatus_t LoRaMac::SendFrameOnChannel( uint8_t channel ) txConfig.TxPower = LoRaMacParams.ChannelsTxPower; txConfig.MaxEirp = LoRaMacParams.MaxEirp; txConfig.AntennaGain = LoRaMacParams.AntennaGain; - txConfig.PktLen = LoRaMacBufferPktLen; + txConfig.PktLen = _params.LoRaMacBufferPktLen; - lora_phy->tx_config(&txConfig, &txPower, &TxTimeOnAir); + lora_phy->tx_config(&txConfig, &txPower, &_params.timers.TxTimeOnAir); MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR; McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR; @@ -1608,22 +1614,22 @@ LoRaMacStatus_t LoRaMac::SendFrameOnChannel( uint8_t channel ) McpsConfirm.TxPower = txPower; // Store the time on air - McpsConfirm.TxTimeOnAir = TxTimeOnAir; - MlmeConfirm.TxTimeOnAir = TxTimeOnAir; + McpsConfirm.TxTimeOnAir = _params.timers.TxTimeOnAir; + MlmeConfirm.TxTimeOnAir = _params.timers.TxTimeOnAir; // Starts the MAC layer status check timer - _lora_time.TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT ); - _lora_time.TimerStart( &MacStateCheckTimer ); + _lora_time.TimerSetValue( &_params.timers.MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT ); + _lora_time.TimerStart( &_params.timers.MacStateCheckTimer ); - if( IsLoRaMacNetworkJoined == false ) + if( _params.IsLoRaMacNetworkJoined == false ) { - JoinRequestTrials++; + _params.JoinRequestTrials++; } // Send now - lora_phy->handle_send(LoRaMacBuffer, LoRaMacBufferPktLen); + lora_phy->handle_send(_params.LoRaMacBuffer, _params.LoRaMacBufferPktLen); - LoRaMacState |= LORAMAC_TX_RUNNING; + _params.LoRaMacState |= LORAMAC_TX_RUNNING; return LORAMAC_STATUS_OK; } @@ -1632,7 +1638,7 @@ LoRaMacStatus_t LoRaMac::SetTxContinuousWave( uint16_t timeout ) { ContinuousWaveParams_t continuousWave; - continuousWave.Channel = Channel; + continuousWave.Channel = _params.Channel; continuousWave.Datarate = LoRaMacParams.ChannelsDatarate; continuousWave.TxPower = LoRaMacParams.ChannelsTxPower; continuousWave.MaxEirp = LoRaMacParams.MaxEirp; @@ -1642,10 +1648,10 @@ LoRaMacStatus_t LoRaMac::SetTxContinuousWave( uint16_t timeout ) lora_phy->set_tx_cont_mode(&continuousWave); // Starts the MAC layer status check timer - _lora_time.TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT ); - _lora_time.TimerStart( &MacStateCheckTimer ); + _lora_time.TimerSetValue( &_params.timers.MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT ); + _lora_time.TimerStart( &_params.timers.MacStateCheckTimer ); - LoRaMacState |= LORAMAC_TX_RUNNING; + _params.LoRaMacState |= LORAMAC_TX_RUNNING; return LORAMAC_STATUS_OK; } @@ -1655,10 +1661,10 @@ LoRaMacStatus_t LoRaMac::SetTxContinuousWave1( uint16_t timeout, uint32_t freque lora_phy->setup_tx_cont_wave_mode(frequency, power, timeout); // Starts the MAC layer status check timer - _lora_time.TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT ); - _lora_time.TimerStart( &MacStateCheckTimer ); + _lora_time.TimerSetValue( &_params.timers.MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT ); + _lora_time.TimerStart( &_params.timers.MacStateCheckTimer ); - LoRaMacState |= LORAMAC_TX_RUNNING; + _params.LoRaMacState |= LORAMAC_TX_RUNNING; return LORAMAC_STATUS_OK; } @@ -1684,24 +1690,24 @@ LoRaMacStatus_t LoRaMac::LoRaMacInitialization(LoRaMacPrimitives_t *primitives, LoRaMacPrimitives = primitives; LoRaMacCallbacks = callbacks; - LoRaMacFlags.Value = 0; + _params.LoRaMacFlags.Value = 0; - LoRaMacDeviceClass = CLASS_A; - LoRaMacState = LORAMAC_IDLE; + _params.LoRaMacDeviceClass = CLASS_A; + _params.LoRaMacState = LORAMAC_IDLE; - JoinRequestTrials = 0; - MaxJoinRequestTrials = 1; - RepeaterSupport = false; + _params.JoinRequestTrials = 0; + _params.MaxJoinRequestTrials = 1; + _params.RepeaterSupport = false; // Reset duty cycle times - AggregatedLastTxDoneTime = 0; - AggregatedTimeOff = 0; + _params.timers.AggregatedLastTxDoneTime = 0; + _params.timers.AggregatedTimeOff = 0; // Reset to defaults getPhy.Attribute = PHY_DUTY_CYCLE; phyParam = lora_phy->get_phy_params(&getPhy); // load default at this moment. Later can be changed using json - DutyCycleOn = ( bool ) phyParam.Value; + _params.DutyCycleOn = ( bool ) phyParam.Value; getPhy.Attribute = PHY_DEF_TX_POWER; phyParam = lora_phy->get_phy_params( &getPhy ); @@ -1780,21 +1786,26 @@ LoRaMacStatus_t LoRaMac::LoRaMacInitialization(LoRaMacPrimitives_t *primitives, // Random seed initialization srand(lora_phy->get_radio_rng()); - PublicNetwork = LORAWAN_PUBLIC_NETWORK; - lora_phy->setup_public_network_mode(PublicNetwork); + _params.PublicNetwork = LORAWAN_PUBLIC_NETWORK; + lora_phy->setup_public_network_mode(_params.PublicNetwork); lora_phy->put_radio_to_sleep(); // Initialize timers - _lora_time.TimerInit(&MacStateCheckTimer, mbed::callback(this, &LoRaMac::handle_mac_state_check_timer_event)); - _lora_time.TimerSetValue(&MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT); + _lora_time.TimerInit(&_params.timers.MacStateCheckTimer, + mbed::callback(this, &LoRaMac::handle_mac_state_check_timer_event)); + _lora_time.TimerSetValue(&_params.timers.MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT); - _lora_time.TimerInit(&TxDelayedTimer, mbed::callback(this, &LoRaMac::handle_delayed_tx_timer_event)); - _lora_time.TimerInit(&RxWindowTimer1, mbed::callback(this, &LoRaMac::handle_rx1_timer_event)); - _lora_time.TimerInit(&RxWindowTimer2, mbed::callback(this, &LoRaMac::handle_rx2_timer_event)); - _lora_time.TimerInit(&AckTimeoutTimer, mbed::callback(this, &LoRaMac::handle_ack_timeout)); + _lora_time.TimerInit(&_params.timers.TxDelayedTimer, + mbed::callback(this, &LoRaMac::handle_delayed_tx_timer_event)); + _lora_time.TimerInit(&_params.timers.RxWindowTimer1, + mbed::callback(this, &LoRaMac::handle_rx1_timer_event)); + _lora_time.TimerInit(&_params.timers.RxWindowTimer2, + mbed::callback(this, &LoRaMac::handle_rx2_timer_event)); + _lora_time.TimerInit(&_params.timers.AckTimeoutTimer, + mbed::callback(this, &LoRaMac::handle_ack_timeout)); // Store the current initialization time - LoRaMacInitializationTime = _lora_time.TimerGetCurrentTime(); + _params.timers.LoRaMacInitializationTime = _lora_time.TimerGetCurrentTime(); return LORAMAC_STATUS_OK; } @@ -1816,14 +1827,14 @@ LoRaMacStatus_t LoRaMac::LoRaMacQueryTxPossible( uint8_t size, LoRaMacTxInfo_t* // Setup ADR request adrNext.UpdateChanMask = false; adrNext.AdrEnabled = LoRaMacParams.AdrCtrlOn; - adrNext.AdrAckCounter = AdrAckCounter; + adrNext.AdrAckCounter = _params.AdrAckCounter; adrNext.Datarate = LoRaMacParams.ChannelsDatarate; adrNext.TxPower = LoRaMacParams.ChannelsTxPower; adrNext.UplinkDwellTime = LoRaMacParams.UplinkDwellTime; // We call the function for information purposes only. We don't want to // apply the datarate, the tx power and the ADR ack counter. - lora_phy->get_next_ADR(&adrNext, &datarate, &txPower, &AdrAckCounter); + lora_phy->get_next_ADR(&adrNext, &datarate, &txPower, &_params.AdrAckCounter); // Setup PHY request getPhy.UplinkDwellTime = LoRaMacParams.UplinkDwellTime; @@ -1831,7 +1842,7 @@ LoRaMacStatus_t LoRaMac::LoRaMacQueryTxPossible( uint8_t size, LoRaMacTxInfo_t* getPhy.Attribute = PHY_MAX_PAYLOAD; // Change request in case repeater is supported - if( RepeaterSupport == true ) + if( _params.RepeaterSupport == true ) { getPhy.Attribute = PHY_MAX_PAYLOAD_REPEATER; } @@ -1876,12 +1887,12 @@ LoRaMacStatus_t LoRaMac::LoRaMacMibGetRequestConfirm( MibRequestConfirm_t *mibGe { case MIB_DEVICE_CLASS: { - mibGet->Param.Class = LoRaMacDeviceClass; + mibGet->Param.Class = _params.LoRaMacDeviceClass; break; } case MIB_NETWORK_JOINED: { - mibGet->Param.IsNetworkJoined = IsLoRaMacNetworkJoined; + mibGet->Param.IsNetworkJoined = _params.IsLoRaMacNetworkJoined; break; } case MIB_ADR: @@ -1891,32 +1902,32 @@ LoRaMacStatus_t LoRaMac::LoRaMacMibGetRequestConfirm( MibRequestConfirm_t *mibGe } case MIB_NET_ID: { - mibGet->Param.NetID = LoRaMacNetID; + mibGet->Param.NetID = _params.LoRaMacNetID; break; } case MIB_DEV_ADDR: { - mibGet->Param.DevAddr = LoRaMacDevAddr; + mibGet->Param.DevAddr = _params.LoRaMacDevAddr; break; } case MIB_NWK_SKEY: { - mibGet->Param.NwkSKey = LoRaMacNwkSKey; + mibGet->Param.NwkSKey =_params.keys.LoRaMacNwkSKey; break; } case MIB_APP_SKEY: { - mibGet->Param.AppSKey = LoRaMacAppSKey; + mibGet->Param.AppSKey = _params.keys.LoRaMacAppSKey; break; } case MIB_PUBLIC_NETWORK: { - mibGet->Param.EnablePublicNetwork = PublicNetwork; + mibGet->Param.EnablePublicNetwork = _params.PublicNetwork; break; } case MIB_REPEATER_SUPPORT: { - mibGet->Param.EnableRepeaterSupport = RepeaterSupport; + mibGet->Param.EnableRepeaterSupport = _params.RepeaterSupport; break; } case MIB_CHANNELS: @@ -2005,12 +2016,12 @@ LoRaMacStatus_t LoRaMac::LoRaMacMibGetRequestConfirm( MibRequestConfirm_t *mibGe } case MIB_UPLINK_COUNTER: { - mibGet->Param.UpLinkCounter = UpLinkCounter; + mibGet->Param.UpLinkCounter = _params.UpLinkCounter; break; } case MIB_DOWNLINK_COUNTER: { - mibGet->Param.DownLinkCounter = DownLinkCounter; + mibGet->Param.DownLinkCounter = _params.DownLinkCounter; break; } case MIB_MULTICAST_CHANNEL: @@ -2056,8 +2067,8 @@ LoRaMacStatus_t LoRaMac::LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSe { case MIB_DEVICE_CLASS: { - LoRaMacDeviceClass = mibSet->Param.Class; - switch( LoRaMacDeviceClass ) + _params.LoRaMacDeviceClass = mibSet->Param.Class; + switch( _params.LoRaMacDeviceClass ) { case CLASS_A: { @@ -2072,7 +2083,7 @@ LoRaMacStatus_t LoRaMac::LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSe case CLASS_C: { // Set the NodeAckRequested indicator to default - NodeAckRequested = false; + _params.NodeAckRequested = false; // Set the radio into sleep mode in case we are still in RX mode lora_phy->put_radio_to_sleep(); // Compute Rx2 windows parameters in case the RX2 datarate has changed @@ -2088,7 +2099,7 @@ LoRaMacStatus_t LoRaMac::LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSe } case MIB_NETWORK_JOINED: { - IsLoRaMacNetworkJoined = mibSet->Param.IsNetworkJoined; + _params.IsLoRaMacNetworkJoined = mibSet->Param.IsNetworkJoined; break; } case MIB_ADR: @@ -2098,20 +2109,20 @@ LoRaMacStatus_t LoRaMac::LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSe } case MIB_NET_ID: { - LoRaMacNetID = mibSet->Param.NetID; + _params.LoRaMacNetID = mibSet->Param.NetID; break; } case MIB_DEV_ADDR: { - LoRaMacDevAddr = mibSet->Param.DevAddr; + _params.LoRaMacDevAddr = mibSet->Param.DevAddr; break; } case MIB_NWK_SKEY: { if( mibSet->Param.NwkSKey != NULL ) { - memcpy( LoRaMacNwkSKey, mibSet->Param.NwkSKey, - sizeof( LoRaMacNwkSKey ) ); + memcpy( _params.keys.LoRaMacNwkSKey, mibSet->Param.NwkSKey, + sizeof( _params.keys.LoRaMacNwkSKey ) ); } else { @@ -2123,8 +2134,8 @@ LoRaMacStatus_t LoRaMac::LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSe { if( mibSet->Param.AppSKey != NULL ) { - memcpy( LoRaMacAppSKey, mibSet->Param.AppSKey, - sizeof( LoRaMacAppSKey ) ); + memcpy( _params.keys.LoRaMacAppSKey, mibSet->Param.AppSKey, + sizeof( _params.keys.LoRaMacAppSKey ) ); } else { @@ -2134,13 +2145,13 @@ LoRaMacStatus_t LoRaMac::LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSe } case MIB_PUBLIC_NETWORK: { - PublicNetwork = mibSet->Param.EnablePublicNetwork; - lora_phy->setup_public_network_mode(PublicNetwork); + _params.PublicNetwork = mibSet->Param.EnablePublicNetwork; + lora_phy->setup_public_network_mode(_params.PublicNetwork); break; } case MIB_REPEATER_SUPPORT: { - RepeaterSupport = mibSet->Param.EnableRepeaterSupport; + _params.RepeaterSupport = mibSet->Param.EnableRepeaterSupport; break; } case MIB_RX2_CHANNEL: @@ -2152,7 +2163,8 @@ LoRaMacStatus_t LoRaMac::LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSe { LoRaMacParams.Rx2Channel = mibSet->Param.Rx2Channel; - if( ( LoRaMacDeviceClass == CLASS_C ) && ( IsLoRaMacNetworkJoined == true ) ) + if( ( _params.LoRaMacDeviceClass == CLASS_C ) && + ( _params.IsLoRaMacNetworkJoined == true ) ) { // We can only compute the RX window parameters directly, if we are already // in class c mode and joined. We cannot setup an RX window in case of any other @@ -2308,12 +2320,12 @@ LoRaMacStatus_t LoRaMac::LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSe } case MIB_UPLINK_COUNTER: { - UpLinkCounter = mibSet->Param.UpLinkCounter; + _params.UpLinkCounter = mibSet->Param.UpLinkCounter; break; } case MIB_DOWNLINK_COUNTER: { - DownLinkCounter = mibSet->Param.DownLinkCounter; + _params.DownLinkCounter = mibSet->Param.DownLinkCounter; break; } case MIB_SYSTEM_MAX_RX_ERROR: @@ -2344,9 +2356,9 @@ LoRaMacStatus_t LoRaMac::LoRaMacChannelAdd( uint8_t id, ChannelParams_t params ) ChannelAddParams_t channelAdd; // Validate if the MAC is in a correct state - if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) + if( ( _params.LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) { - if( ( LoRaMacState & LORAMAC_TX_CONFIG ) != LORAMAC_TX_CONFIG ) + if( ( _params.LoRaMacState & LORAMAC_TX_CONFIG ) != LORAMAC_TX_CONFIG ) { return LORAMAC_STATUS_BUSY; } @@ -2362,9 +2374,9 @@ LoRaMacStatus_t LoRaMac::LoRaMacChannelRemove( uint8_t id ) { ChannelRemoveParams_t channelRemove; - if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) + if( ( _params.LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) { - if( ( LoRaMacState & LORAMAC_TX_CONFIG ) != LORAMAC_TX_CONFIG ) + if( ( _params.LoRaMacState & LORAMAC_TX_CONFIG ) != LORAMAC_TX_CONFIG ) { return LORAMAC_STATUS_BUSY; } @@ -2388,7 +2400,7 @@ LoRaMacStatus_t LoRaMac::LoRaMacMulticastChannelLink( MulticastParams_t *channel { return LORAMAC_STATUS_PARAMETER_INVALID; } - if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) + if( ( _params.LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) { return LORAMAC_STATUS_BUSY; } @@ -2423,7 +2435,7 @@ LoRaMacStatus_t LoRaMac::LoRaMacMulticastChannelUnlink( MulticastParams_t *chann { return LORAMAC_STATUS_PARAMETER_INVALID; } - if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) + if( ( _params.LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) { return LORAMAC_STATUS_BUSY; } @@ -2469,7 +2481,7 @@ LoRaMacStatus_t LoRaMac::LoRaMacMlmeRequest( MlmeReq_t *mlmeRequest ) { return LORAMAC_STATUS_PARAMETER_INVALID; } - if( LoRaMacState != LORAMAC_IDLE ) + if( _params.LoRaMacState != LORAMAC_IDLE ) { return LORAMAC_STATUS_BUSY; } @@ -2482,7 +2494,7 @@ LoRaMacStatus_t LoRaMac::LoRaMacMlmeRequest( MlmeReq_t *mlmeRequest ) { case MLME_JOIN: { - if( ( LoRaMacState & LORAMAC_TX_DELAYED ) == LORAMAC_TX_DELAYED ) + if( (_params. LoRaMacState & LORAMAC_TX_DELAYED ) == LORAMAC_TX_DELAYED ) { return LORAMAC_STATUS_BUSY; } @@ -2506,16 +2518,16 @@ LoRaMacStatus_t LoRaMac::LoRaMacMlmeRequest( MlmeReq_t *mlmeRequest ) mlmeRequest->Req.Join.NbTrials = ( uint8_t ) phyParam.Value; } - LoRaMacFlags.Bits.MlmeReq = 1; + _params.LoRaMacFlags.Bits.MlmeReq = 1; MlmeConfirm.MlmeRequest = mlmeRequest->Type; - LoRaMacDevEui = mlmeRequest->Req.Join.DevEui; - LoRaMacAppEui = mlmeRequest->Req.Join.AppEui; - LoRaMacAppKey = mlmeRequest->Req.Join.AppKey; - MaxJoinRequestTrials = mlmeRequest->Req.Join.NbTrials; + _params.keys.LoRaMacDevEui = mlmeRequest->Req.Join.DevEui; + _params.keys.LoRaMacAppEui = mlmeRequest->Req.Join.AppEui; + _params.keys.LoRaMacAppKey = mlmeRequest->Req.Join.AppKey; + _params.MaxJoinRequestTrials = mlmeRequest->Req.Join.NbTrials; // Reset variable JoinRequestTrials - JoinRequestTrials = 0; + _params.JoinRequestTrials = 0; // Setup header information macHdr.Value = 0; @@ -2523,7 +2535,7 @@ LoRaMacStatus_t LoRaMac::LoRaMacMlmeRequest( MlmeReq_t *mlmeRequest ) ResetMacParameters( ); - altDr.NbTrials = JoinRequestTrials + 1; + altDr.NbTrials = _params.JoinRequestTrials + 1; LoRaMacParams.ChannelsDatarate = lora_phy->get_alternate_DR(&altDr); @@ -2532,7 +2544,7 @@ LoRaMacStatus_t LoRaMac::LoRaMacMlmeRequest( MlmeReq_t *mlmeRequest ) } case MLME_LINK_CHECK: { - LoRaMacFlags.Bits.MlmeReq = 1; + _params.LoRaMacFlags.Bits.MlmeReq = 1; // LoRaMac will send this command piggy-backed MlmeConfirm.MlmeRequest = mlmeRequest->Type; @@ -2542,14 +2554,14 @@ LoRaMacStatus_t LoRaMac::LoRaMacMlmeRequest( MlmeReq_t *mlmeRequest ) case MLME_TXCW: { MlmeConfirm.MlmeRequest = mlmeRequest->Type; - LoRaMacFlags.Bits.MlmeReq = 1; + _params.LoRaMacFlags.Bits.MlmeReq = 1; status = SetTxContinuousWave( mlmeRequest->Req.TxCw.Timeout ); break; } case MLME_TXCW_1: { MlmeConfirm.MlmeRequest = mlmeRequest->Type; - LoRaMacFlags.Bits.MlmeReq = 1; + _params.LoRaMacFlags.Bits.MlmeReq = 1; status = SetTxContinuousWave1( mlmeRequest->Req.TxCw.Timeout, mlmeRequest->Req.TxCw.Frequency, mlmeRequest->Req.TxCw.Power ); break; } @@ -2559,8 +2571,8 @@ LoRaMacStatus_t LoRaMac::LoRaMacMlmeRequest( MlmeReq_t *mlmeRequest ) if( status != LORAMAC_STATUS_OK ) { - NodeAckRequested = false; - LoRaMacFlags.Bits.MlmeReq = 0; + _params.NodeAckRequested = false; + _params.LoRaMacFlags.Bits.MlmeReq = 0; } return status; @@ -2583,7 +2595,7 @@ LoRaMacStatus_t LoRaMac::LoRaMacMcpsRequest( McpsReq_t *mcpsRequest ) { return LORAMAC_STATUS_PARAMETER_INVALID; } - if( LoRaMacState != LORAMAC_IDLE ) + if( _params.LoRaMacState != LORAMAC_IDLE ) { return LORAMAC_STATUS_BUSY; } @@ -2593,14 +2605,14 @@ LoRaMacStatus_t LoRaMac::LoRaMacMcpsRequest( McpsReq_t *mcpsRequest ) McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR; // AckTimeoutRetriesCounter must be reset every time a new request (unconfirmed or confirmed) is performed. - AckTimeoutRetriesCounter = 1; + _params.AckTimeoutRetriesCounter = 1; switch( mcpsRequest->Type ) { case MCPS_UNCONFIRMED: { readyToSend = true; - AckTimeoutRetries = 1; + _params.AckTimeoutRetries = 1; macHdr.Bits.MType = FRAME_TYPE_DATA_UNCONFIRMED_UP; fPort = mcpsRequest->Req.Unconfirmed.fPort; @@ -2612,7 +2624,7 @@ LoRaMacStatus_t LoRaMac::LoRaMacMcpsRequest( McpsReq_t *mcpsRequest ) case MCPS_CONFIRMED: { readyToSend = true; - AckTimeoutRetries = mcpsRequest->Req.Confirmed.NbTrials; + _params.AckTimeoutRetries = mcpsRequest->Req.Confirmed.NbTrials; macHdr.Bits.MType = FRAME_TYPE_DATA_CONFIRMED_UP; fPort = mcpsRequest->Req.Confirmed.fPort; @@ -2624,7 +2636,7 @@ LoRaMacStatus_t LoRaMac::LoRaMacMcpsRequest( McpsReq_t *mcpsRequest ) case MCPS_PROPRIETARY: { readyToSend = true; - AckTimeoutRetries = 1; + _params.AckTimeoutRetries = 1; macHdr.Bits.MType = FRAME_TYPE_PROPRIETARY; fBuffer = mcpsRequest->Req.Proprietary.fBuffer; @@ -2672,11 +2684,11 @@ LoRaMacStatus_t LoRaMac::LoRaMacMcpsRequest( McpsReq_t *mcpsRequest ) if( status == LORAMAC_STATUS_OK ) { McpsConfirm.McpsRequest = mcpsRequest->Type; - LoRaMacFlags.Bits.McpsReq = 1; + _params.LoRaMacFlags.Bits.McpsReq = 1; } else { - NodeAckRequested = false; + _params.NodeAckRequested = false; } } @@ -2717,13 +2729,13 @@ LoRaMacStatus_t LoRaMac::LoRaMacStopTxTimer( ) void LoRaMac::LoRaMacTestRxWindowsOn( bool enable ) { - IsRxWindowsEnabled = enable; + _params.IsRxWindowsEnabled = enable; } void LoRaMac::LoRaMacTestSetMic( uint16_t txPacketCounter ) { - UpLinkCounter = txPacketCounter; - IsUpLinkCounterFixed = true; + _params.UpLinkCounter = txPacketCounter; + _params.IsUpLinkCounterFixed = true; } void LoRaMac::LoRaMacTestSetDutyCycleOn( bool enable ) @@ -2734,12 +2746,12 @@ void LoRaMac::LoRaMacTestSetDutyCycleOn( bool enable ) if(lora_phy->verify(&verify, PHY_DUTY_CYCLE) == true) { - DutyCycleOn = enable; + _params.DutyCycleOn = enable; } } void LoRaMac::LoRaMacTestSetChannel( uint8_t channel ) { - Channel = channel; + _params.Channel = channel; } #endif diff --git a/features/lorawan/lorastack/mac/LoRaMac.h b/features/lorawan/lorastack/mac/LoRaMac.h index 8746c44b31..d12f180004 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.h +++ b/features/lorawan/lorastack/mac/LoRaMac.h @@ -613,138 +613,18 @@ private: LoRaWANTimeHandler &_lora_time; + lora_mac_protocol_params _params; /** * Radio event callback handlers for MAC */ radio_events_t RadioEvents; - - /*! - * Device IEEE EUI - */ - uint8_t *LoRaMacDevEui; - - /*! - * Application IEEE EUI - */ - uint8_t *LoRaMacAppEui; - - /*! - * AES encryption/decryption cipher application key - */ - uint8_t *LoRaMacAppKey; - - /*! - * AES encryption/decryption cipher network session key - */ - uint8_t LoRaMacNwkSKey[16]; - - /*! - * AES encryption/decryption cipher application session key - */ - uint8_t LoRaMacAppSKey[16]; - - /*! - * Device nonce is a random value extracted by issuing a sequence of RSSI - * measurements - */ - uint16_t LoRaMacDevNonce; - - /*! - * Network ID ( 3 bytes ) - */ - uint32_t LoRaMacNetID; - - /*! - * Mote Address - */ - uint32_t LoRaMacDevAddr; - /*! * Multicast channels linked list */ MulticastParams_t *MulticastChannels; - /*! - * Actual device class - */ - DeviceClass_t LoRaMacDeviceClass; - - /*! - * Indicates if the node is connected to a private or public network - */ - bool PublicNetwork; - - /*! - * Indicates if the node supports repeaters - */ - bool RepeaterSupport; - - /*! - * Buffer containing the data to be sent or received. - */ - uint8_t LoRaMacBuffer[LORAMAC_PHY_MAXPAYLOAD]; - - /*! - * Length of packet in LoRaMacBuffer - */ - uint16_t LoRaMacBufferPktLen; - - /*! - * Length of the payload in LoRaMacBuffer - */ - uint8_t LoRaMacTxPayloadLen; - - /*! - * Buffer containing the upper layer data. - */ - uint8_t LoRaMacRxPayload[LORAMAC_PHY_MAXPAYLOAD]; - - /*! - * LoRaMAC frame counter. Each time a packet is sent the counter is incremented. - * Only the 16 LSB bits are sent - */ - uint32_t UpLinkCounter; - - /*! - * LoRaMAC frame counter. Each time a packet is received the counter is incremented. - * Only the 16 LSB bits are received - */ - uint32_t DownLinkCounter; - - /*! - * IsPacketCounterFixed enables the MIC field tests by fixing the - * UpLinkCounter value - */ - bool IsUpLinkCounterFixed; - - /*! - * Used for test purposes. Disables the opening of the reception windows. - */ - bool IsRxWindowsEnabled; - - /*! - * Indicates if the MAC layer has already joined a network. - */ - bool IsLoRaMacNetworkJoined; - - /*! - * Counts the number of missed ADR acknowledgements - */ - uint32_t AdrAckCounter; - - /*! - * If the node has sent a FRAME_TYPE_DATA_CONFIRMED_UP this variable indicates - * if the nodes needs to manage the server acknowledgement. - */ - bool NodeAckRequested; - - /*! - * If the server has sent a FRAME_TYPE_DATA_CONFIRMED_DOWN this variable indicates - * if the ACK bit must be set for the next transmission - */ - bool SrvAckRequested; /*! * LoRaMac parameters @@ -756,69 +636,6 @@ private: */ LoRaMacParams_t LoRaMacParamsDefaults; - /*! - * Uplink messages repetitions counter - */ - uint8_t ChannelsNbRepCounter; - - /*! - * Aggregated duty cycle management - */ - TimerTime_t AggregatedLastTxDoneTime; - TimerTime_t AggregatedTimeOff; - - /*! - * Enables/Disables duty cycle management (Test only) - */ - bool DutyCycleOn; - - /*! - * Current channel index - */ - uint8_t Channel; - - /*! - * Current channel index - */ - uint8_t LastTxChannel; - - /*! - * Set to true, if the last uplink was a join request - */ - bool LastTxIsJoinRequest; - - /*! - * Stores the time at LoRaMac initialization. - * - * \remark Used for the BACKOFF_DC computation. - */ - TimerTime_t LoRaMacInitializationTime; - - /*! - * LoRaMac internal states - */ - enum eLoRaMacState - { - LORAMAC_IDLE = 0x00000000, - LORAMAC_TX_RUNNING = 0x00000001, - LORAMAC_RX = 0x00000002, - LORAMAC_ACK_REQ = 0x00000004, - LORAMAC_ACK_RETRY = 0x00000008, - LORAMAC_TX_DELAYED = 0x00000010, - LORAMAC_TX_CONFIG = 0x00000020, - LORAMAC_RX_ABORT = 0x00000040, - }; - - /*! - * LoRaMac internal state - */ - uint32_t LoRaMacState; - - /*! - * LoRaMac timer used to check the LoRaMacState (runs every second) - */ - TimerEvent_t MacStateCheckTimer; - /*! * LoRaMac upper layer event functions */ @@ -829,16 +646,7 @@ private: */ LoRaMacCallback_t *LoRaMacCallbacks; - /*! - * LoRaMac duty cycle delayed Tx timer - */ - TimerEvent_t TxDelayedTimer; - /*! - * LoRaMac reception windows timers - */ - TimerEvent_t RxWindowTimer1; - TimerEvent_t RxWindowTimer2; /*! * LoRaMac reception windows delay @@ -854,40 +662,6 @@ private: RxConfigParams_t RxWindow1Config; RxConfigParams_t RxWindow2Config; - /*! - * Acknowledge timeout timer. Used for packet retransmissions. - */ - TimerEvent_t AckTimeoutTimer; - - /*! - * Number of trials to get a frame acknowledged - */ - uint8_t AckTimeoutRetries; - - /*! - * Number of trials to get a frame acknowledged - */ - uint8_t AckTimeoutRetriesCounter; - - /*! - * Indicates if the AckTimeout timer has expired or not - */ - bool AckTimeoutRetry; - - /*! - * Last transmission time on air - */ - TimerTime_t TxTimeOnAir; - - /*! - * Number of trials for the Join Request - */ - uint8_t JoinRequestTrials; - - /*! - * Maximum number of trials for the Join Request - */ - uint8_t MaxJoinRequestTrials; /*! * Structure to hold MCPS indication data. @@ -914,11 +688,6 @@ private: */ LoRaMacRxSlot_t RxSlot; - /*! - * LoRaMac tx/rx operation state - */ - LoRaMacFlags_t LoRaMacFlags; - }; #endif // __LORAMAC_H__ diff --git a/features/lorawan/system/LoRaWANTimer.h b/features/lorawan/system/LoRaWANTimer.h index d5770cde96..90263110bb 100644 --- a/features/lorawan/system/LoRaWANTimer.h +++ b/features/lorawan/system/LoRaWANTimer.h @@ -22,20 +22,8 @@ SPDX-License-Identifier: BSD-3-Clause #define MBED_LORAWAN_SYS_TIMER_H__ #include -#include "drivers/Ticker.h" #include "lorawan/system/lorawan_data_structures.h" #include "events/EventQueue.h" -#include "platform/SingletonPtr.h" - -/*! - * \brief Timer object description - */ -typedef struct TimerEvent_s -{ - uint32_t value; - mbed::Callback Callback; - SingletonPtr Timer; -}TimerEvent_t; class LoRaWANTimeHandler { diff --git a/features/lorawan/system/lorawan_data_structures.h b/features/lorawan/system/lorawan_data_structures.h index e24d7d858e..6711dffdab 100644 --- a/features/lorawan/system/lorawan_data_structures.h +++ b/features/lorawan/system/lorawan_data_structures.h @@ -24,7 +24,9 @@ #define LORAWAN_SYSTEM_LORAWAN_DATA_STRUCTURES_H_ #include +#include "drivers/Ticker.h" #include "platform/Callback.h" +#include "platform/SingletonPtr.h" /*! * \brief Timer time variable definition @@ -2939,6 +2941,269 @@ typedef struct loramac_downlink_status { uint8_t buffer_size; } loramac_downlink_status_t; +/*! + * \brief Timer object description + */ +typedef struct TimerEvent_s +{ + uint32_t value; + mbed::Callback Callback; + SingletonPtr Timer; +} TimerEvent_t; + +/*! + * LoRaMac internal states + */ +enum eLoRaMacState +{ + LORAMAC_IDLE = 0x00000000, + LORAMAC_TX_RUNNING = 0x00000001, + LORAMAC_RX = 0x00000002, + LORAMAC_ACK_REQ = 0x00000004, + LORAMAC_ACK_RETRY = 0x00000008, + LORAMAC_TX_DELAYED = 0x00000010, + LORAMAC_TX_CONFIG = 0x00000020, + LORAMAC_RX_ABORT = 0x00000040, +}; + +typedef struct { + /*! + * Device IEEE EUI + */ + uint8_t *LoRaMacDevEui; + + /*! + * Application IEEE EUI + */ + uint8_t *LoRaMacAppEui; + + /*! + * AES encryption/decryption cipher application key + */ + uint8_t *LoRaMacAppKey; + + /*! + * AES encryption/decryption cipher network session key + */ + uint8_t LoRaMacNwkSKey[16]; + + /*! + * AES encryption/decryption cipher application session key + */ + uint8_t LoRaMacAppSKey[16]; + +} lora_mac_keys; + +typedef struct { + /*! + * Aggregated duty cycle management + */ + TimerTime_t AggregatedLastTxDoneTime; + TimerTime_t AggregatedTimeOff; + + /*! + * Stores the time at LoRaMac initialization. + * + * \remark Used for the BACKOFF_DC computation. + */ + TimerTime_t LoRaMacInitializationTime; + + + /*! + * Last transmission time on air + */ + TimerTime_t TxTimeOnAir; + + /*! + * LoRaMac timer used to check the LoRaMacState (runs every second) + */ + TimerEvent_t MacStateCheckTimer; + + /*! + * LoRaMac duty cycle delayed Tx timer + */ + TimerEvent_t TxDelayedTimer; + + /*! + * LoRaMac reception windows timers + */ + TimerEvent_t RxWindowTimer1; + TimerEvent_t RxWindowTimer2; + + /*! + * Acknowledge timeout timer. Used for packet retransmissions. + */ + TimerEvent_t AckTimeoutTimer; + + } lora_mac_timers; + +typedef struct { + + /*! + * Actual device class + */ + DeviceClass_t LoRaMacDeviceClass; + + /*! + * Indicates if the node is connected to a private or public network + */ + bool PublicNetwork; + + /*! + * Indicates if the node supports repeaters + */ + bool RepeaterSupport; + + /*! + * IsPacketCounterFixed enables the MIC field tests by fixing the + * UpLinkCounter value + */ + bool IsUpLinkCounterFixed; + + /*! + * Used for test purposes. Disables the opening of the reception windows. + */ + bool IsRxWindowsEnabled; + + /*! + * Indicates if the MAC layer has already joined a network. + */ + bool IsLoRaMacNetworkJoined; + + /*! + * If the node has sent a FRAME_TYPE_DATA_CONFIRMED_UP this variable indicates + * if the nodes needs to manage the server acknowledgement. + */ + bool NodeAckRequested; + + /*! + * If the server has sent a FRAME_TYPE_DATA_CONFIRMED_DOWN this variable indicates + * if the ACK bit must be set for the next transmission + */ + bool SrvAckRequested; + + /*! + * Enables/Disables duty cycle management (Test only) + */ + bool DutyCycleOn; + + /*! + * Set to true, if the last uplink was a join request + */ + bool LastTxIsJoinRequest; + + /*! + * Indicates if the AckTimeout timer has expired or not + */ + bool AckTimeoutRetry; + + /*! + * Current channel index + */ + uint8_t Channel; + + /*! + * Current channel index + */ + uint8_t LastTxChannel; + + /*! + * Uplink messages repetitions counter + */ + uint8_t ChannelsNbRepCounter; + + /*! + * Buffer containing the data to be sent or received. + */ + uint8_t LoRaMacBuffer[LORAMAC_PHY_MAXPAYLOAD]; + + /*! + * Length of the payload in LoRaMacBuffer + */ + uint8_t LoRaMacTxPayloadLen; + + /*! + * Buffer containing the upper layer data. + */ + uint8_t LoRaMacRxPayload[LORAMAC_PHY_MAXPAYLOAD]; + + /*! + * Number of trials to get a frame acknowledged + */ + uint8_t AckTimeoutRetries; + + /*! + * Number of trials to get a frame acknowledged + */ + uint8_t AckTimeoutRetriesCounter; + + /*! + * Number of trials for the Join Request + */ + uint8_t JoinRequestTrials; + + /*! + * Maximum number of trials for the Join Request + */ + uint8_t MaxJoinRequestTrials; + + /*! + * Mac keys + */ + lora_mac_keys keys; + + /*! + * LoRaMac tx/rx operation state + */ + LoRaMacFlags_t LoRaMacFlags; + + /*! + * Length of packet in LoRaMacBuffer + */ + uint16_t LoRaMacBufferPktLen; + + /*! + * Device nonce is a random value extracted by issuing a sequence of RSSI + * measurements + */ + uint16_t LoRaMacDevNonce; + + /*! + * Network ID ( 3 bytes ) + */ + uint32_t LoRaMacNetID; + + /*! + * Mote Address + */ + uint32_t LoRaMacDevAddr; + + /*! + * LoRaMAC frame counter. Each time a packet is sent the counter is incremented. + * Only the 16 LSB bits are sent + */ + uint32_t UpLinkCounter; + + /*! + * LoRaMAC frame counter. Each time a packet is received the counter is incremented. + * Only the 16 LSB bits are received + */ + uint32_t DownLinkCounter; + + /*! + * Counts the number of missed ADR acknowledgements + */ + uint32_t AdrAckCounter; + + /*! + * LoRaMac internal state + */ + uint32_t LoRaMacState; + + lora_mac_timers timers; + +} lora_mac_protocol_params; + /** LoRaWAN callback functions * */ From a100ab022638c2c6bb1a881847d070e726bde0be Mon Sep 17 00:00:00 2001 From: Hasnain Virk Date: Mon, 8 Jan 2018 18:07:37 +0200 Subject: [PATCH 06/23] [IOTCELL-289] Adding Mlme class handle MAC layer will services will be broken down into independent subsystems. This is the first of those efforts. We have introduced LoRaMacMlme class that handles everything related to MLME subsystem or subservice. To accomodate subsystems we have grouped all protocol level variables into one big data structure. A pointer to that data structure will be passed around the subsystems in order to regulate the entire system. LoRaMac::Send() and LoRaMac::SetTxContWave*() APIs are made public as they are needed to be accessed by the subsystems. --- features/lorawan/lorastack/mac/LoRaMac.cpp | 484 +++++++----------- features/lorawan/lorastack/mac/LoRaMac.h | 138 +++-- .../lorawan/lorastack/mac/LoRaMacCommand.cpp | 4 +- .../lorawan/lorastack/mac/LoRaMacCommand.h | 2 +- .../lorawan/lorastack/mac/LoRaMacMlme.cpp | 163 ++++++ features/lorawan/lorastack/mac/LoRaMacMlme.h | 110 ++++ .../lorawan/system/lorawan_data_structures.h | 28 +- 7 files changed, 555 insertions(+), 374 deletions(-) create mode 100644 features/lorawan/lorastack/mac/LoRaMacMlme.cpp create mode 100644 features/lorawan/lorastack/mac/LoRaMacMlme.h diff --git a/features/lorawan/lorastack/mac/LoRaMac.cpp b/features/lorawan/lorastack/mac/LoRaMac.cpp index e1d2b1e2e7..3773403f06 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.cpp +++ b/features/lorawan/lorastack/mac/LoRaMac.cpp @@ -117,8 +117,8 @@ LoRaMac::LoRaMac(LoRaWANTimeHandler &lora_time) MulticastChannels = NULL; - LoRaMacParams.AdrCtrlOn = false; - LoRaMacParams.MaxDCycle = 0; + _params.sys_params.AdrCtrlOn = false; + _params.sys_params.MaxDCycle = 0; } LoRaMac::~LoRaMac() @@ -200,6 +200,7 @@ void LoRaMac::OnRadioTxDone( void ) PhyParam_t phyParam; SetBandTxDoneParams_t txDone; TimerTime_t curTime = _lora_time.TimerGetCurrentTime( ); + MlmeConfirm_t mlme_confirm = mlme.get_confirmation(); if( _params.LoRaMacDeviceClass != CLASS_C ) { @@ -213,25 +214,25 @@ void LoRaMac::OnRadioTxDone( void ) // Setup timers if( _params.IsRxWindowsEnabled == true ) { - _lora_time.TimerSetValue( &_params.timers.RxWindowTimer1, RxWindow1Delay ); + _lora_time.TimerSetValue( &_params.timers.RxWindowTimer1, _params.RxWindow1Delay ); _lora_time.TimerStart( &_params.timers.RxWindowTimer1 ); if( _params.LoRaMacDeviceClass != CLASS_C ) { - _lora_time.TimerSetValue( &_params.timers.RxWindowTimer2, RxWindow2Delay ); + _lora_time.TimerSetValue( &_params.timers.RxWindowTimer2, _params.RxWindow2Delay ); _lora_time.TimerStart( &_params.timers.RxWindowTimer2 ); } if( ( _params.LoRaMacDeviceClass == CLASS_C ) || ( _params.NodeAckRequested == true ) ) { getPhy.Attribute = PHY_ACK_TIMEOUT; phyParam = lora_phy->get_phy_params(&getPhy); - _lora_time.TimerSetValue( &_params.timers.AckTimeoutTimer, RxWindow2Delay + phyParam.Value ); + _lora_time.TimerSetValue( &_params.timers.AckTimeoutTimer, _params.RxWindow2Delay + phyParam.Value ); _lora_time.TimerStart( &_params.timers.AckTimeoutTimer ); } } else { McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK; - MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT; + mlme_confirm.Status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT; if( _params.LoRaMacFlags.Value == 0 ) { @@ -241,7 +242,7 @@ void LoRaMac::OnRadioTxDone( void ) } // Verify if the last uplink was a join request - if( ( _params.LoRaMacFlags.Bits.MlmeReq == 1 ) && ( MlmeConfirm.MlmeRequest == MLME_JOIN ) ) + if( ( _params.LoRaMacFlags.Bits.MlmeReq == 1 ) && ( mlme_confirm.MlmeRequest == MLME_JOIN ) ) { _params.LastTxIsJoinRequest = true; } @@ -317,7 +318,7 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 McpsConfirm.AckReceived = false; McpsIndication.Rssi = rssi; McpsIndication.Snr = snr; - McpsIndication.RxSlot = RxSlot; + McpsIndication.RxSlot = _params.RxSlot; McpsIndication.Port = 0; McpsIndication.Multicast = 0; McpsIndication.FramePending = 0; @@ -387,17 +388,17 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 _params.LoRaMacDevAddr |= ( ( uint32_t ) _params.LoRaMacRxPayload[10] << 24 ); // DLSettings - LoRaMacParams.Rx1DrOffset = ( _params.LoRaMacRxPayload[11] >> 4 ) & 0x07; - LoRaMacParams.Rx2Channel.Datarate = _params.LoRaMacRxPayload[11] & 0x0F; + _params.sys_params.Rx1DrOffset = ( _params.LoRaMacRxPayload[11] >> 4 ) & 0x07; + _params.sys_params.Rx2Channel.Datarate = _params.LoRaMacRxPayload[11] & 0x0F; // RxDelay - LoRaMacParams.ReceiveDelay1 = ( _params.LoRaMacRxPayload[12] & 0x0F ); - if( LoRaMacParams.ReceiveDelay1 == 0 ) + _params.sys_params.ReceiveDelay1 = ( _params.LoRaMacRxPayload[12] & 0x0F ); + if( _params.sys_params.ReceiveDelay1 == 0 ) { - LoRaMacParams.ReceiveDelay1 = 1; + _params.sys_params.ReceiveDelay1 = 1; } - LoRaMacParams.ReceiveDelay1 *= 1000; - LoRaMacParams.ReceiveDelay2 = LoRaMacParams.ReceiveDelay1 + 1000; + _params.sys_params.ReceiveDelay1 *= 1000; + _params.sys_params.ReceiveDelay2 = _params.sys_params.ReceiveDelay1 + 1000; // Apply CF list applyCFList.Payload = &_params.LoRaMacRxPayload[13]; @@ -406,19 +407,19 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 lora_phy->apply_cf_list(&applyCFList); - MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK; + mlme.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_OK; _params.IsLoRaMacNetworkJoined = true; } else { - MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL; + mlme.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL; } break; case FRAME_TYPE_DATA_CONFIRMED_DOWN: case FRAME_TYPE_DATA_UNCONFIRMED_DOWN: { // Check if the received payload size is valid - getPhy.UplinkDwellTime = LoRaMacParams.DownlinkDwellTime; + getPhy.UplinkDwellTime = _params.sys_params.DownlinkDwellTime; getPhy.Datarate = McpsIndication.RxDatarate; getPhy.Attribute = PHY_MAX_PAYLOAD; @@ -428,7 +429,7 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 getPhy.Attribute = PHY_MAX_PAYLOAD_REPEATER; } phyParam = lora_phy->get_phy_params(&getPhy); - if( MAX( 0, ( int16_t )( ( int16_t )size - ( int16_t )LORA_MAC_FRMPAYLOAD_OVERHEAD ) ) > phyParam.Value ) + if( MAX( 0, ( int16_t )( ( int16_t )size - ( int16_t )LORA_MAC_FRMPAYLOAD_OVERHEAD ) ) > (int32_t)phyParam.Value ) { McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_ERROR; PrepareRxDoneAbort( ); @@ -623,8 +624,8 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 // Decode frame payload MAC commands mac_commands.ProcessMacCommands( _params.LoRaMacRxPayload, 0, frameLen, snr, - MlmeConfirm, LoRaMacCallbacks, - LoRaMacParams, *lora_phy ); + mlme.get_confirmation(), LoRaMacCallbacks, + _params.sys_params, *lora_phy ); } else { @@ -637,8 +638,8 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 { // Decode Options field MAC commands. Omit the fPort. mac_commands.ProcessMacCommands( payload, 8, appPayloadStartIndex - 1, snr, - MlmeConfirm, LoRaMacCallbacks, - LoRaMacParams, *lora_phy ); + mlme.get_confirmation(), LoRaMacCallbacks, + _params.sys_params, *lora_phy ); } if (0 != LoRaMacPayloadDecrypt( payload + appPayloadStartIndex, @@ -665,8 +666,8 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 { // Decode Options field MAC commands mac_commands.ProcessMacCommands( payload, 8, appPayloadStartIndex, snr, - MlmeConfirm, LoRaMacCallbacks, - LoRaMacParams, *lora_phy ); + mlme.get_confirmation(), LoRaMacCallbacks, + _params.sys_params, *lora_phy ); } } @@ -744,7 +745,9 @@ void LoRaMac::OnRadioTxTimeout( void ) } McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT; - MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT; + + mlme.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT; + _params.LoRaMacFlags.Bits.MacDone = 1; } @@ -759,15 +762,16 @@ void LoRaMac::OnRadioRxError( void ) OpenContinuousRx2Window( ); } - if( RxSlot == RX_SLOT_WIN_1 ) + if( _params.RxSlot == RX_SLOT_WIN_1 ) { if( _params.NodeAckRequested == true ) { McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX1_ERROR; } - MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX1_ERROR; - if( _lora_time.TimerGetElapsedTime( _params.timers.AggregatedLastTxDoneTime ) >= RxWindow2Delay ) + mlme.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_RX1_ERROR; + + if( _lora_time.TimerGetElapsedTime( _params.timers.AggregatedLastTxDoneTime ) >= _params.RxWindow2Delay ) { _lora_time.TimerStop( &_params.timers.RxWindowTimer2 ); _params.LoRaMacFlags.Bits.MacDone = 1; @@ -779,7 +783,9 @@ void LoRaMac::OnRadioRxError( void ) { McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX2_ERROR; } - MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX2_ERROR; + + mlme.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_RX2_ERROR; + _params.LoRaMacFlags.Bits.MacDone = 1; } } @@ -795,15 +801,15 @@ void LoRaMac::OnRadioRxTimeout( void ) OpenContinuousRx2Window( ); } - if( RxSlot == RX_SLOT_WIN_1 ) + if( _params.RxSlot == RX_SLOT_WIN_1 ) { if( _params.NodeAckRequested == true ) { McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX1_TIMEOUT; } - MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX1_TIMEOUT; + mlme.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_RX1_TIMEOUT; - if( _lora_time.TimerGetElapsedTime( _params.timers.AggregatedLastTxDoneTime ) >= RxWindow2Delay ) + if( _lora_time.TimerGetElapsedTime( _params.timers.AggregatedLastTxDoneTime ) >= _params.RxWindow2Delay ) { _lora_time.TimerStop( &_params.timers.RxWindowTimer2 ); _params.LoRaMacFlags.Bits.MacDone = 1; @@ -815,7 +821,8 @@ void LoRaMac::OnRadioRxTimeout( void ) { McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT; } - MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT; + + mlme.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT; if( _params.LoRaMacDeviceClass != CLASS_C ) { @@ -846,7 +853,7 @@ void LoRaMac::OnMacStateCheckTimerEvent( void ) if( ( _params.LoRaMacFlags.Bits.MlmeReq == 1 ) || ( ( _params.LoRaMacFlags.Bits.McpsReq == 1 ) ) ) { if( ( McpsConfirm.Status == LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT ) || - ( MlmeConfirm.Status == LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT ) ) + ( mlme.get_confirmation().Status == LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT ) ) { // Stop transmit cycle due to tx timeout. _params.LoRaMacState &= ~LORAMAC_TX_RUNNING; @@ -862,11 +869,11 @@ void LoRaMac::OnMacStateCheckTimerEvent( void ) { if( ( _params.LoRaMacFlags.Bits.MlmeReq == 1 ) || ( ( _params.LoRaMacFlags.Bits.McpsReq == 1 ) ) ) { - if( ( _params.LoRaMacFlags.Bits.MlmeReq == 1 ) && ( MlmeConfirm.MlmeRequest == MLME_JOIN ) ) + if( ( _params.LoRaMacFlags.Bits.MlmeReq == 1 ) && ( mlme.get_confirmation().MlmeRequest == MLME_JOIN ) ) {// Procedure for the join request - MlmeConfirm.NbRetries = _params.JoinRequestTrials; + mlme.get_confirmation().NbRetries = _params.JoinRequestTrials; - if( MlmeConfirm.Status == LORAMAC_EVENT_INFO_STATUS_OK ) + if( mlme.get_confirmation().Status == LORAMAC_EVENT_INFO_STATUS_OK ) {// Node joined successfully _params.UpLinkCounter = 0; _params.ChannelsNbRepCounter = 0; @@ -888,7 +895,7 @@ void LoRaMac::OnMacStateCheckTimerEvent( void ) } else {// Procedure for all other frames - if( ( _params.ChannelsNbRepCounter >= LoRaMacParams.ChannelsNbRep ) || ( _params.LoRaMacFlags.Bits.McpsInd == 1 ) ) + if( ( _params.ChannelsNbRepCounter >= _params.sys_params.ChannelsNbRep ) || ( _params.LoRaMacFlags.Bits.McpsInd == 1 ) ) { if( _params.LoRaMacFlags.Bits.McpsInd == 0 ) { // Maximum repetitions without downlink. Reset MacCommandsBufferIndex. Increase ADR Ack counter. @@ -944,10 +951,10 @@ void LoRaMac::OnMacStateCheckTimerEvent( void ) if( ( _params.AckTimeoutRetriesCounter % 2 ) == 1 ) { getPhy.Attribute = PHY_NEXT_LOWER_TX_DR; - getPhy.UplinkDwellTime = LoRaMacParams.UplinkDwellTime; - getPhy.Datarate = LoRaMacParams.ChannelsDatarate; + getPhy.UplinkDwellTime = _params.sys_params.UplinkDwellTime; + getPhy.Datarate = _params.sys_params.ChannelsDatarate; phyParam = lora_phy->get_phy_params( &getPhy ); - LoRaMacParams.ChannelsDatarate = phyParam.Value; + _params.sys_params.ChannelsDatarate = phyParam.Value; } // Try to send the frame again if( ScheduleTx( ) == LORAMAC_STATUS_OK ) @@ -964,7 +971,7 @@ void LoRaMac::OnMacStateCheckTimerEvent( void ) _params.NodeAckRequested = false; McpsConfirm.AckReceived = false; McpsConfirm.NbRetries = _params.AckTimeoutRetriesCounter; - McpsConfirm.Datarate = LoRaMacParams.ChannelsDatarate; + McpsConfirm.Datarate = _params.sys_params.ChannelsDatarate; if( _params.IsUpLinkCounterFixed == false ) { _params.UpLinkCounter++; @@ -1004,7 +1011,7 @@ void LoRaMac::OnMacStateCheckTimerEvent( void ) if( _params.LoRaMacFlags.Bits.MlmeReq == 1 ) { _params.LoRaMacFlags.Bits.MlmeReq = 0; - LoRaMacPrimitives->MacMlmeConfirm( &MlmeConfirm ); + LoRaMacPrimitives->MacMlmeConfirm(&mlme.get_confirmation()); } // Verify if sticky MAC commands are pending or not @@ -1043,7 +1050,7 @@ void LoRaMac::OnMacStateCheckTimerEvent( void ) if( _params.LoRaMacFlags.Bits.MlmeInd == 1 ) { _params.LoRaMacFlags.Bits.MlmeInd = 0; - LoRaMacPrimitives->MacMlmeIndication( &MlmeIndication ); + LoRaMacPrimitives->MacMlmeIndication(&mlme.get_indication()); } } @@ -1056,18 +1063,18 @@ void LoRaMac::OnTxDelayedTimerEvent( void ) _lora_time.TimerStop( &_params.timers.TxDelayedTimer ); _params.LoRaMacState &= ~LORAMAC_TX_DELAYED; - if( ( _params.LoRaMacFlags.Bits.MlmeReq == 1 ) && ( MlmeConfirm.MlmeRequest == MLME_JOIN ) ) + if( ( _params.LoRaMacFlags.Bits.MlmeReq == 1 ) && ( mlme.get_confirmation().MlmeRequest == MLME_JOIN ) ) { ResetMacParameters( ); altDr.NbTrials = _params.JoinRequestTrials + 1; - LoRaMacParams.ChannelsDatarate = lora_phy->get_alternate_DR(&altDr); + _params.sys_params.ChannelsDatarate = lora_phy->get_alternate_DR(&altDr); macHdr.Value = 0; macHdr.Bits.MType = FRAME_TYPE_JOIN_REQ; fCtrl.Value = 0; - fCtrl.Bits.Adr = LoRaMacParams.AdrCtrlOn; + fCtrl.Bits.Adr = _params.sys_params.AdrCtrlOn; /* In case of join request retransmissions, the stack must prepare * the frame again, because the network server keeps track of the random @@ -1081,14 +1088,14 @@ void LoRaMac::OnTxDelayedTimerEvent( void ) void LoRaMac::OnRxWindow1TimerEvent( void ) { _lora_time.TimerStop( &_params.timers.RxWindowTimer1 ); - RxSlot = RX_SLOT_WIN_1; + _params.RxSlot = RX_SLOT_WIN_1; RxWindow1Config.Channel = _params.Channel; - RxWindow1Config.DrOffset = LoRaMacParams.Rx1DrOffset; - RxWindow1Config.DownlinkDwellTime = LoRaMacParams.DownlinkDwellTime; + RxWindow1Config.DrOffset = _params.sys_params.Rx1DrOffset; + RxWindow1Config.DownlinkDwellTime = _params.sys_params.DownlinkDwellTime; RxWindow1Config.RepeaterSupport = _params.RepeaterSupport; RxWindow1Config.RxContinuous = false; - RxWindow1Config.RxSlot = RxSlot; + RxWindow1Config.RxSlot = _params.RxSlot; if( _params.LoRaMacDeviceClass == CLASS_C ) { @@ -1096,7 +1103,7 @@ void LoRaMac::OnRxWindow1TimerEvent( void ) } lora_phy->rx_config(&RxWindow1Config, ( int8_t* )&McpsIndication.RxDatarate); - RxWindowSetup( RxWindow1Config.RxContinuous, LoRaMacParams.MaxRxWindow ); + RxWindowSetup( RxWindow1Config.RxContinuous, _params.sys_params.MaxRxWindow ); } void LoRaMac::OnRxWindow2TimerEvent( void ) @@ -1104,8 +1111,8 @@ void LoRaMac::OnRxWindow2TimerEvent( void ) _lora_time.TimerStop( &_params.timers.RxWindowTimer2 ); RxWindow2Config.Channel = _params.Channel; - RxWindow2Config.Frequency = LoRaMacParams.Rx2Channel.Frequency; - RxWindow2Config.DownlinkDwellTime = LoRaMacParams.DownlinkDwellTime; + RxWindow2Config.Frequency = _params.sys_params.Rx2Channel.Frequency; + RxWindow2Config.DownlinkDwellTime = _params.sys_params.DownlinkDwellTime; RxWindow2Config.RepeaterSupport = _params.RepeaterSupport; RxWindow2Config.RxSlot = RX_SLOT_WIN_2; @@ -1121,8 +1128,8 @@ void LoRaMac::OnRxWindow2TimerEvent( void ) if(lora_phy->rx_config(&RxWindow2Config, ( int8_t* )&McpsIndication.RxDatarate) == true ) { - RxWindowSetup( RxWindow2Config.RxContinuous, LoRaMacParams.MaxRxWindow ); - RxSlot = RX_SLOT_WIN_2; + RxWindowSetup( RxWindow2Config.RxContinuous, _params.sys_params.MaxRxWindow ); + _params.RxSlot = RX_SLOT_WIN_2; } } @@ -1154,7 +1161,7 @@ bool LoRaMac::ValidatePayloadLength( uint8_t lenN, int8_t datarate, uint8_t fOpt uint16_t payloadSize = 0; // Setup PHY request - getPhy.UplinkDwellTime = LoRaMacParams.UplinkDwellTime; + getPhy.UplinkDwellTime = _params.sys_params.UplinkDwellTime; getPhy.Datarate = datarate; getPhy.Attribute = PHY_MAX_PAYLOAD; @@ -1179,7 +1186,7 @@ bool LoRaMac::ValidatePayloadLength( uint8_t lenN, int8_t datarate, uint8_t fOpt void LoRaMac::SetMlmeScheduleUplinkIndication( void ) { - MlmeIndication.MlmeIndication = MLME_SCHEDULE_UPLINK; + mlme.get_indication().MlmeIndication = MLME_SCHEDULE_UPLINK; _params.LoRaMacFlags.Bits.MlmeInd = 1; } @@ -1195,7 +1202,7 @@ LoRaMacStatus_t LoRaMac::Send( LoRaMacHeader_t *macHdr, uint8_t fPort, void *fBu fCtrl.Bits.FPending = 0; fCtrl.Bits.Ack = false; fCtrl.Bits.AdrAckReq = false; - fCtrl.Bits.Adr = LoRaMacParams.AdrCtrlOn; + fCtrl.Bits.Adr = _params.sys_params.AdrCtrlOn; // Prepare the frame status = PrepareFrame( macHdr, &fCtrl, fPort, fBuffer, fBufferSize ); @@ -1222,11 +1229,11 @@ LoRaMacStatus_t LoRaMac::ScheduleTx( void ) NextChanParams_t nextChan; // Check if the device is off - if( LoRaMacParams.MaxDCycle == 255 ) + if( _params.sys_params.MaxDCycle == 255 ) { return LORAMAC_STATUS_DEVICE_OFF; } - if( LoRaMacParams.MaxDCycle == 0 ) + if( _params.sys_params.MaxDCycle == 0 ) { _params.timers.AggregatedTimeOff = 0; } @@ -1235,7 +1242,7 @@ LoRaMacStatus_t LoRaMac::ScheduleTx( void ) CalculateBackOff( _params.LastTxChannel ); nextChan.AggrTimeOff = _params.timers.AggregatedTimeOff; - nextChan.Datarate = LoRaMacParams.ChannelsDatarate; + nextChan.Datarate = _params.sys_params.ChannelsDatarate; _params.DutyCycleOn = LORAWAN_DUTYCYCLE_ON; nextChan.DutyCycleEnabled = _params.DutyCycleOn; nextChan.Joined = _params.IsLoRaMacNetworkJoined; @@ -1246,42 +1253,42 @@ LoRaMacStatus_t LoRaMac::ScheduleTx( void ) &_params.timers.AggregatedTimeOff ) == false ) { // Set the default datarate - LoRaMacParams.ChannelsDatarate = LoRaMacParamsDefaults.ChannelsDatarate; + _params.sys_params.ChannelsDatarate = _params.def_sys_params.ChannelsDatarate; // Update datarate in the function parameters - nextChan.Datarate = LoRaMacParams.ChannelsDatarate; + nextChan.Datarate = _params.sys_params.ChannelsDatarate; } tr_debug("Next Channel Idx=%d, DR=%d", _params.Channel, nextChan.Datarate); // Compute Rx1 windows parameters - uint8_t dr_offset = lora_phy->apply_DR_offset(LoRaMacParams.DownlinkDwellTime, - LoRaMacParams.ChannelsDatarate, - LoRaMacParams.Rx1DrOffset); + uint8_t dr_offset = lora_phy->apply_DR_offset(_params.sys_params.DownlinkDwellTime, + _params.sys_params.ChannelsDatarate, + _params.sys_params.Rx1DrOffset); - lora_phy->compute_rx_win_params(dr_offset, LoRaMacParams.MinRxSymbols, - LoRaMacParams.SystemMaxRxError, + lora_phy->compute_rx_win_params(dr_offset, _params.sys_params.MinRxSymbols, + _params.sys_params.SystemMaxRxError, &RxWindow1Config ); // Compute Rx2 windows parameters - lora_phy->compute_rx_win_params(LoRaMacParams.Rx2Channel.Datarate, - LoRaMacParams.MinRxSymbols, - LoRaMacParams.SystemMaxRxError, + lora_phy->compute_rx_win_params(_params.sys_params.Rx2Channel.Datarate, + _params.sys_params.MinRxSymbols, + _params.sys_params.SystemMaxRxError, &RxWindow2Config ); if( _params.IsLoRaMacNetworkJoined == false ) { - RxWindow1Delay = LoRaMacParams.JoinAcceptDelay1 + RxWindow1Config.WindowOffset; - RxWindow2Delay = LoRaMacParams.JoinAcceptDelay2 + RxWindow2Config.WindowOffset; + _params.RxWindow1Delay = _params.sys_params.JoinAcceptDelay1 + RxWindow1Config.WindowOffset; + _params.RxWindow2Delay = _params.sys_params.JoinAcceptDelay2 + RxWindow2Config.WindowOffset; } else { if( ValidatePayloadLength( _params.LoRaMacTxPayloadLen, - LoRaMacParams.ChannelsDatarate, + _params.sys_params.ChannelsDatarate, mac_commands.GetLength() ) == false ) { return LORAMAC_STATUS_LENGTH_ERROR; } - RxWindow1Delay = LoRaMacParams.ReceiveDelay1 + RxWindow1Config.WindowOffset; - RxWindow2Delay = LoRaMacParams.ReceiveDelay2 + RxWindow2Config.WindowOffset; + _params.RxWindow1Delay = _params.sys_params.ReceiveDelay1 + RxWindow1Config.WindowOffset; + _params.RxWindow2Delay = _params.sys_params.ReceiveDelay2 + RxWindow2Config.WindowOffset; } // Schedule transmission of frame @@ -1320,7 +1327,7 @@ void LoRaMac::CalculateBackOff( uint8_t channel ) // Update aggregated time-off _params.timers.AggregatedTimeOff = _params.timers.AggregatedTimeOff + - ( _params.timers.TxTimeOnAir * LoRaMacParams.AggregatedDCycle - _params.timers.TxTimeOnAir ); + ( _params.timers.TxTimeOnAir * _params.sys_params.AggregatedDCycle - _params.timers.TxTimeOnAir ); } void LoRaMac::ResetMacParameters( void ) @@ -1338,8 +1345,8 @@ void LoRaMac::ResetMacParameters( void ) _params.AckTimeoutRetriesCounter = 1; _params.AckTimeoutRetry = false; - LoRaMacParams.MaxDCycle = 0; - LoRaMacParams.AggregatedDCycle = 1; + _params.sys_params.MaxDCycle = 0; + _params.sys_params.AggregatedDCycle = 1; mac_commands.ClearCommandBuffer(); mac_commands.ClearRepeatBuffer(); @@ -1347,14 +1354,14 @@ void LoRaMac::ResetMacParameters( void ) _params.IsRxWindowsEnabled = true; - LoRaMacParams.ChannelsTxPower = LoRaMacParamsDefaults.ChannelsTxPower; - LoRaMacParams.ChannelsDatarate = LoRaMacParamsDefaults.ChannelsDatarate; - LoRaMacParams.Rx1DrOffset = LoRaMacParamsDefaults.Rx1DrOffset; - LoRaMacParams.Rx2Channel = LoRaMacParamsDefaults.Rx2Channel; - LoRaMacParams.UplinkDwellTime = LoRaMacParamsDefaults.UplinkDwellTime; - LoRaMacParams.DownlinkDwellTime = LoRaMacParamsDefaults.DownlinkDwellTime; - LoRaMacParams.MaxEirp = LoRaMacParamsDefaults.MaxEirp; - LoRaMacParams.AntennaGain = LoRaMacParamsDefaults.AntennaGain; + _params.sys_params.ChannelsTxPower = _params.def_sys_params.ChannelsTxPower; + _params.sys_params.ChannelsDatarate = _params.def_sys_params.ChannelsDatarate; + _params.sys_params.Rx1DrOffset = _params.def_sys_params.Rx1DrOffset; + _params.sys_params.Rx2Channel = _params.def_sys_params.Rx2Channel; + _params.sys_params.UplinkDwellTime = _params.def_sys_params.UplinkDwellTime; + _params.sys_params.DownlinkDwellTime = _params.def_sys_params.DownlinkDwellTime; + _params.sys_params.MaxEirp = _params.def_sys_params.MaxEirp; + _params.sys_params.AntennaGain = _params.def_sys_params.AntennaGain; _params.NodeAckRequested = false; _params.SrvAckRequested = false; @@ -1384,7 +1391,7 @@ bool LoRaMac::IsFPortAllowed( uint8_t fPort ) void LoRaMac::OpenContinuousRx2Window( void ) { handle_rx2_timer_event( ); - RxSlot = RX_SLOT_WIN_CLASS_C; + _params.RxSlot = RX_SLOT_WIN_CLASS_C; } static void memcpy_convert_endianess( uint8_t *dst, const uint8_t *src, uint16_t size ) @@ -1462,13 +1469,13 @@ LoRaMacStatus_t LoRaMac::PrepareFrame( LoRaMacHeader_t *macHdr, LoRaMacFrameCtrl adrNext.UpdateChanMask = true; adrNext.AdrEnabled = fCtrl->Bits.Adr; adrNext.AdrAckCounter = _params.AdrAckCounter; - adrNext.Datarate = LoRaMacParams.ChannelsDatarate; - adrNext.TxPower = LoRaMacParams.ChannelsTxPower; - adrNext.UplinkDwellTime = LoRaMacParams.UplinkDwellTime; + adrNext.Datarate = _params.sys_params.ChannelsDatarate; + adrNext.TxPower = _params.sys_params.ChannelsTxPower; + adrNext.UplinkDwellTime = _params.sys_params.UplinkDwellTime; fCtrl->Bits.AdrAckReq = lora_phy->get_next_ADR(&adrNext, - &LoRaMacParams.ChannelsDatarate, - &LoRaMacParams.ChannelsTxPower, + &_params.sys_params.ChannelsDatarate, + &_params.sys_params.ChannelsTxPower, &_params.AdrAckCounter); if( _params.SrvAckRequested == true ) @@ -1600,22 +1607,23 @@ LoRaMacStatus_t LoRaMac::SendFrameOnChannel( uint8_t channel ) int8_t txPower = 0; txConfig.Channel = channel; - txConfig.Datarate = LoRaMacParams.ChannelsDatarate; - txConfig.TxPower = LoRaMacParams.ChannelsTxPower; - txConfig.MaxEirp = LoRaMacParams.MaxEirp; - txConfig.AntennaGain = LoRaMacParams.AntennaGain; + txConfig.Datarate = _params.sys_params.ChannelsDatarate; + txConfig.TxPower = _params.sys_params.ChannelsTxPower; + txConfig.MaxEirp = _params.sys_params.MaxEirp; + txConfig.AntennaGain = _params.sys_params.AntennaGain; txConfig.PktLen = _params.LoRaMacBufferPktLen; lora_phy->tx_config(&txConfig, &txPower, &_params.timers.TxTimeOnAir); - MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR; + mlme.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_ERROR; + McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR; - McpsConfirm.Datarate = LoRaMacParams.ChannelsDatarate; + McpsConfirm.Datarate = _params.sys_params.ChannelsDatarate; McpsConfirm.TxPower = txPower; // Store the time on air McpsConfirm.TxTimeOnAir = _params.timers.TxTimeOnAir; - MlmeConfirm.TxTimeOnAir = _params.timers.TxTimeOnAir; + mlme.get_confirmation().TxTimeOnAir = _params.timers.TxTimeOnAir; // Starts the MAC layer status check timer _lora_time.TimerSetValue( &_params.timers.MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT ); @@ -1639,10 +1647,10 @@ LoRaMacStatus_t LoRaMac::SetTxContinuousWave( uint16_t timeout ) ContinuousWaveParams_t continuousWave; continuousWave.Channel = _params.Channel; - continuousWave.Datarate = LoRaMacParams.ChannelsDatarate; - continuousWave.TxPower = LoRaMacParams.ChannelsTxPower; - continuousWave.MaxEirp = LoRaMacParams.MaxEirp; - continuousWave.AntennaGain = LoRaMacParams.AntennaGain; + continuousWave.Datarate = _params.sys_params.ChannelsDatarate; + continuousWave.TxPower = _params.sys_params.ChannelsTxPower; + continuousWave.MaxEirp = _params.sys_params.MaxEirp; + continuousWave.AntennaGain = _params.sys_params.AntennaGain; continuousWave.Timeout = timeout; lora_phy->set_tx_cont_mode(&continuousWave); @@ -1687,6 +1695,9 @@ LoRaMacStatus_t LoRaMac::LoRaMacInitialization(LoRaMacPrimitives_t *primitives, lora_phy = phy; + // Activate Mlme subsystem + mlme.activate_mlme_subsystem(this, lora_phy, &mac_commands); + LoRaMacPrimitives = primitives; LoRaMacCallbacks = callbacks; @@ -1711,75 +1722,75 @@ LoRaMacStatus_t LoRaMac::LoRaMacInitialization(LoRaMacPrimitives_t *primitives, getPhy.Attribute = PHY_DEF_TX_POWER; phyParam = lora_phy->get_phy_params( &getPhy ); - LoRaMacParamsDefaults.ChannelsTxPower = phyParam.Value; + _params.def_sys_params.ChannelsTxPower = phyParam.Value; getPhy.Attribute = PHY_DEF_TX_DR; phyParam = lora_phy->get_phy_params( &getPhy ); - LoRaMacParamsDefaults.ChannelsDatarate = phyParam.Value; + _params.def_sys_params.ChannelsDatarate = phyParam.Value; getPhy.Attribute = PHY_MAX_RX_WINDOW; phyParam = lora_phy->get_phy_params( &getPhy ); - LoRaMacParamsDefaults.MaxRxWindow = phyParam.Value; + _params.def_sys_params.MaxRxWindow = phyParam.Value; getPhy.Attribute = PHY_RECEIVE_DELAY1; phyParam = lora_phy->get_phy_params( &getPhy ); - LoRaMacParamsDefaults.ReceiveDelay1 = phyParam.Value; + _params.def_sys_params.ReceiveDelay1 = phyParam.Value; getPhy.Attribute = PHY_RECEIVE_DELAY2; phyParam = lora_phy->get_phy_params( &getPhy ); - LoRaMacParamsDefaults.ReceiveDelay2 = phyParam.Value; + _params.def_sys_params.ReceiveDelay2 = phyParam.Value; getPhy.Attribute = PHY_JOIN_ACCEPT_DELAY1; phyParam = lora_phy->get_phy_params( &getPhy ); - LoRaMacParamsDefaults.JoinAcceptDelay1 = phyParam.Value; + _params.def_sys_params.JoinAcceptDelay1 = phyParam.Value; getPhy.Attribute = PHY_JOIN_ACCEPT_DELAY2; phyParam = lora_phy->get_phy_params( &getPhy ); - LoRaMacParamsDefaults.JoinAcceptDelay2 = phyParam.Value; + _params.def_sys_params.JoinAcceptDelay2 = phyParam.Value; getPhy.Attribute = PHY_DEF_DR1_OFFSET; phyParam = lora_phy->get_phy_params( &getPhy ); - LoRaMacParamsDefaults.Rx1DrOffset = phyParam.Value; + _params.def_sys_params.Rx1DrOffset = phyParam.Value; getPhy.Attribute = PHY_DEF_RX2_FREQUENCY; phyParam = lora_phy->get_phy_params( &getPhy ); - LoRaMacParamsDefaults.Rx2Channel.Frequency = phyParam.Value; + _params.def_sys_params.Rx2Channel.Frequency = phyParam.Value; getPhy.Attribute = PHY_DEF_RX2_DR; phyParam = lora_phy->get_phy_params( &getPhy ); - LoRaMacParamsDefaults.Rx2Channel.Datarate = phyParam.Value; + _params.def_sys_params.Rx2Channel.Datarate = phyParam.Value; getPhy.Attribute = PHY_DEF_UPLINK_DWELL_TIME; phyParam = lora_phy->get_phy_params( &getPhy ); - LoRaMacParamsDefaults.UplinkDwellTime = phyParam.Value; + _params.def_sys_params.UplinkDwellTime = phyParam.Value; getPhy.Attribute = PHY_DEF_DOWNLINK_DWELL_TIME; phyParam = lora_phy->get_phy_params( &getPhy ); - LoRaMacParamsDefaults.DownlinkDwellTime = phyParam.Value; + _params.def_sys_params.DownlinkDwellTime = phyParam.Value; getPhy.Attribute = PHY_DEF_MAX_EIRP; phyParam = lora_phy->get_phy_params( &getPhy ); - LoRaMacParamsDefaults.MaxEirp = phyParam.fValue; + _params.def_sys_params.MaxEirp = phyParam.fValue; getPhy.Attribute = PHY_DEF_ANTENNA_GAIN; phyParam = lora_phy->get_phy_params( &getPhy ); - LoRaMacParamsDefaults.AntennaGain = phyParam.fValue; + _params.def_sys_params.AntennaGain = phyParam.fValue; lora_phy->load_defaults(INIT_TYPE_INIT); // Init parameters which are not set in function ResetMacParameters - LoRaMacParamsDefaults.ChannelsNbRep = 1; - LoRaMacParamsDefaults.SystemMaxRxError = 10; - LoRaMacParamsDefaults.MinRxSymbols = 6; + _params.def_sys_params.ChannelsNbRep = 1; + _params.def_sys_params.SystemMaxRxError = 10; + _params.def_sys_params.MinRxSymbols = 6; - LoRaMacParams.SystemMaxRxError = LoRaMacParamsDefaults.SystemMaxRxError; - LoRaMacParams.MinRxSymbols = LoRaMacParamsDefaults.MinRxSymbols; - LoRaMacParams.MaxRxWindow = LoRaMacParamsDefaults.MaxRxWindow; - LoRaMacParams.ReceiveDelay1 = LoRaMacParamsDefaults.ReceiveDelay1; - LoRaMacParams.ReceiveDelay2 = LoRaMacParamsDefaults.ReceiveDelay2; - LoRaMacParams.JoinAcceptDelay1 = LoRaMacParamsDefaults.JoinAcceptDelay1; - LoRaMacParams.JoinAcceptDelay2 = LoRaMacParamsDefaults.JoinAcceptDelay2; - LoRaMacParams.ChannelsNbRep = LoRaMacParamsDefaults.ChannelsNbRep; + _params.sys_params.SystemMaxRxError = _params.def_sys_params.SystemMaxRxError; + _params.sys_params.MinRxSymbols = _params.def_sys_params.MinRxSymbols; + _params.sys_params.MaxRxWindow = _params.def_sys_params.MaxRxWindow; + _params.sys_params.ReceiveDelay1 = _params.def_sys_params.ReceiveDelay1; + _params.sys_params.ReceiveDelay2 = _params.def_sys_params.ReceiveDelay2; + _params.sys_params.JoinAcceptDelay1 = _params.def_sys_params.JoinAcceptDelay1; + _params.sys_params.JoinAcceptDelay2 = _params.def_sys_params.JoinAcceptDelay2; + _params.sys_params.ChannelsNbRep = _params.def_sys_params.ChannelsNbRep; ResetMacParameters( ); @@ -1815,8 +1826,8 @@ LoRaMacStatus_t LoRaMac::LoRaMacQueryTxPossible( uint8_t size, LoRaMacTxInfo_t* AdrNextParams_t adrNext; GetPhyParams_t getPhy; PhyParam_t phyParam; - int8_t datarate = LoRaMacParamsDefaults.ChannelsDatarate; - int8_t txPower = LoRaMacParamsDefaults.ChannelsTxPower; + int8_t datarate = _params.def_sys_params.ChannelsDatarate; + int8_t txPower = _params.def_sys_params.ChannelsTxPower; uint8_t fOptLen = mac_commands.GetLength() + mac_commands.GetRepeatLength(); if( txInfo == NULL ) @@ -1826,18 +1837,18 @@ LoRaMacStatus_t LoRaMac::LoRaMacQueryTxPossible( uint8_t size, LoRaMacTxInfo_t* // Setup ADR request adrNext.UpdateChanMask = false; - adrNext.AdrEnabled = LoRaMacParams.AdrCtrlOn; + adrNext.AdrEnabled = _params.sys_params.AdrCtrlOn; adrNext.AdrAckCounter = _params.AdrAckCounter; - adrNext.Datarate = LoRaMacParams.ChannelsDatarate; - adrNext.TxPower = LoRaMacParams.ChannelsTxPower; - adrNext.UplinkDwellTime = LoRaMacParams.UplinkDwellTime; + adrNext.Datarate = _params.sys_params.ChannelsDatarate; + adrNext.TxPower = _params.sys_params.ChannelsTxPower; + adrNext.UplinkDwellTime = _params.sys_params.UplinkDwellTime; // We call the function for information purposes only. We don't want to // apply the datarate, the tx power and the ADR ack counter. lora_phy->get_next_ADR(&adrNext, &datarate, &txPower, &_params.AdrAckCounter); // Setup PHY request - getPhy.UplinkDwellTime = LoRaMacParams.UplinkDwellTime; + getPhy.UplinkDwellTime = _params.sys_params.UplinkDwellTime; getPhy.Datarate = datarate; getPhy.Attribute = PHY_MAX_PAYLOAD; @@ -1897,7 +1908,7 @@ LoRaMacStatus_t LoRaMac::LoRaMacMibGetRequestConfirm( MibRequestConfirm_t *mibGe } case MIB_ADR: { - mibGet->Param.AdrEnable = LoRaMacParams.AdrCtrlOn; + mibGet->Param.AdrEnable = _params.sys_params.AdrCtrlOn; break; } case MIB_NET_ID: @@ -1940,12 +1951,12 @@ LoRaMacStatus_t LoRaMac::LoRaMacMibGetRequestConfirm( MibRequestConfirm_t *mibGe } case MIB_RX2_CHANNEL: { - mibGet->Param.Rx2Channel = LoRaMacParams.Rx2Channel; + mibGet->Param.Rx2Channel = _params.sys_params.Rx2Channel; break; } case MIB_RX2_DEFAULT_CHANNEL: { - mibGet->Param.Rx2Channel = LoRaMacParamsDefaults.Rx2Channel; + mibGet->Param.Rx2Channel = _params.def_sys_params.Rx2Channel; break; } case MIB_CHANNELS_DEFAULT_MASK: @@ -1966,52 +1977,52 @@ LoRaMacStatus_t LoRaMac::LoRaMacMibGetRequestConfirm( MibRequestConfirm_t *mibGe } case MIB_CHANNELS_NB_REP: { - mibGet->Param.ChannelNbRep = LoRaMacParams.ChannelsNbRep; + mibGet->Param.ChannelNbRep = _params.sys_params.ChannelsNbRep; break; } case MIB_MAX_RX_WINDOW_DURATION: { - mibGet->Param.MaxRxWindow = LoRaMacParams.MaxRxWindow; + mibGet->Param.MaxRxWindow = _params.sys_params.MaxRxWindow; break; } case MIB_RECEIVE_DELAY_1: { - mibGet->Param.ReceiveDelay1 = LoRaMacParams.ReceiveDelay1; + mibGet->Param.ReceiveDelay1 = _params.sys_params.ReceiveDelay1; break; } case MIB_RECEIVE_DELAY_2: { - mibGet->Param.ReceiveDelay2 = LoRaMacParams.ReceiveDelay2; + mibGet->Param.ReceiveDelay2 = _params.sys_params.ReceiveDelay2; break; } case MIB_JOIN_ACCEPT_DELAY_1: { - mibGet->Param.JoinAcceptDelay1 = LoRaMacParams.JoinAcceptDelay1; + mibGet->Param.JoinAcceptDelay1 = _params.sys_params.JoinAcceptDelay1; break; } case MIB_JOIN_ACCEPT_DELAY_2: { - mibGet->Param.JoinAcceptDelay2 = LoRaMacParams.JoinAcceptDelay2; + mibGet->Param.JoinAcceptDelay2 = _params.sys_params.JoinAcceptDelay2; break; } case MIB_CHANNELS_DEFAULT_DATARATE: { - mibGet->Param.ChannelsDefaultDatarate = LoRaMacParamsDefaults.ChannelsDatarate; + mibGet->Param.ChannelsDefaultDatarate = _params.def_sys_params.ChannelsDatarate; break; } case MIB_CHANNELS_DATARATE: { - mibGet->Param.ChannelsDatarate = LoRaMacParams.ChannelsDatarate; + mibGet->Param.ChannelsDatarate = _params.sys_params.ChannelsDatarate; break; } case MIB_CHANNELS_DEFAULT_TX_POWER: { - mibGet->Param.ChannelsDefaultTxPower = LoRaMacParamsDefaults.ChannelsTxPower; + mibGet->Param.ChannelsDefaultTxPower = _params.def_sys_params.ChannelsTxPower; break; } case MIB_CHANNELS_TX_POWER: { - mibGet->Param.ChannelsTxPower = LoRaMacParams.ChannelsTxPower; + mibGet->Param.ChannelsTxPower = _params.sys_params.ChannelsTxPower; break; } case MIB_UPLINK_COUNTER: @@ -2031,17 +2042,17 @@ LoRaMacStatus_t LoRaMac::LoRaMacMibGetRequestConfirm( MibRequestConfirm_t *mibGe } case MIB_SYSTEM_MAX_RX_ERROR: { - mibGet->Param.SystemMaxRxError = LoRaMacParams.SystemMaxRxError; + mibGet->Param.SystemMaxRxError = _params.sys_params.SystemMaxRxError; break; } case MIB_MIN_RX_SYMBOLS: { - mibGet->Param.MinRxSymbols = LoRaMacParams.MinRxSymbols; + mibGet->Param.MinRxSymbols = _params.sys_params.MinRxSymbols; break; } case MIB_ANTENNA_GAIN: { - mibGet->Param.AntennaGain = LoRaMacParams.AntennaGain; + mibGet->Param.AntennaGain = _params.sys_params.AntennaGain; break; } default: @@ -2087,9 +2098,9 @@ LoRaMacStatus_t LoRaMac::LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSe // Set the radio into sleep mode in case we are still in RX mode lora_phy->put_radio_to_sleep(); // Compute Rx2 windows parameters in case the RX2 datarate has changed - lora_phy->compute_rx_win_params( LoRaMacParams.Rx2Channel.Datarate, - LoRaMacParams.MinRxSymbols, - LoRaMacParams.SystemMaxRxError, + lora_phy->compute_rx_win_params( _params.sys_params.Rx2Channel.Datarate, + _params.sys_params.MinRxSymbols, + _params.sys_params.SystemMaxRxError, &RxWindow2Config ); OpenContinuousRx2Window( ); break; @@ -2104,7 +2115,7 @@ LoRaMacStatus_t LoRaMac::LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSe } case MIB_ADR: { - LoRaMacParams.AdrCtrlOn = mibSet->Param.AdrEnable; + _params.sys_params.AdrCtrlOn = mibSet->Param.AdrEnable; break; } case MIB_NET_ID: @@ -2157,11 +2168,11 @@ LoRaMacStatus_t LoRaMac::LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSe case MIB_RX2_CHANNEL: { verify.DatarateParams.Datarate = mibSet->Param.Rx2Channel.Datarate; - verify.DatarateParams.DownlinkDwellTime = LoRaMacParams.DownlinkDwellTime; + verify.DatarateParams.DownlinkDwellTime = _params.sys_params.DownlinkDwellTime; if( lora_phy->verify(&verify, PHY_RX_DR) == true ) { - LoRaMacParams.Rx2Channel = mibSet->Param.Rx2Channel; + _params.sys_params.Rx2Channel = mibSet->Param.Rx2Channel; if( ( _params.LoRaMacDeviceClass == CLASS_C ) && ( _params.IsLoRaMacNetworkJoined == true ) ) @@ -2172,9 +2183,9 @@ LoRaMacStatus_t LoRaMac::LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSe // Set the radio into sleep mode in case we are still in RX mode lora_phy->put_radio_to_sleep(); // Compute Rx2 windows parameters - lora_phy->compute_rx_win_params(LoRaMacParams.Rx2Channel.Datarate, - LoRaMacParams.MinRxSymbols, - LoRaMacParams.SystemMaxRxError, + lora_phy->compute_rx_win_params(_params.sys_params.Rx2Channel.Datarate, + _params.sys_params.MinRxSymbols, + _params.sys_params.SystemMaxRxError, &RxWindow2Config); OpenContinuousRx2Window( ); @@ -2189,11 +2200,11 @@ LoRaMacStatus_t LoRaMac::LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSe case MIB_RX2_DEFAULT_CHANNEL: { verify.DatarateParams.Datarate = mibSet->Param.Rx2Channel.Datarate; - verify.DatarateParams.DownlinkDwellTime = LoRaMacParams.DownlinkDwellTime; + verify.DatarateParams.DownlinkDwellTime = _params.sys_params.DownlinkDwellTime; if( lora_phy->verify(&verify, PHY_RX_DR) == true ) { - LoRaMacParamsDefaults.Rx2Channel = mibSet->Param.Rx2DefaultChannel; + _params.def_sys_params.Rx2Channel = mibSet->Param.Rx2DefaultChannel; } else { @@ -2228,7 +2239,7 @@ LoRaMacStatus_t LoRaMac::LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSe if( ( mibSet->Param.ChannelNbRep >= 1 ) && ( mibSet->Param.ChannelNbRep <= 15 ) ) { - LoRaMacParams.ChannelsNbRep = mibSet->Param.ChannelNbRep; + _params.sys_params.ChannelsNbRep = mibSet->Param.ChannelNbRep; } else { @@ -2238,27 +2249,27 @@ LoRaMacStatus_t LoRaMac::LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSe } case MIB_MAX_RX_WINDOW_DURATION: { - LoRaMacParams.MaxRxWindow = mibSet->Param.MaxRxWindow; + _params.sys_params.MaxRxWindow = mibSet->Param.MaxRxWindow; break; } case MIB_RECEIVE_DELAY_1: { - LoRaMacParams.ReceiveDelay1 = mibSet->Param.ReceiveDelay1; + _params.sys_params.ReceiveDelay1 = mibSet->Param.ReceiveDelay1; break; } case MIB_RECEIVE_DELAY_2: { - LoRaMacParams.ReceiveDelay2 = mibSet->Param.ReceiveDelay2; + _params.sys_params.ReceiveDelay2 = mibSet->Param.ReceiveDelay2; break; } case MIB_JOIN_ACCEPT_DELAY_1: { - LoRaMacParams.JoinAcceptDelay1 = mibSet->Param.JoinAcceptDelay1; + _params.sys_params.JoinAcceptDelay1 = mibSet->Param.JoinAcceptDelay1; break; } case MIB_JOIN_ACCEPT_DELAY_2: { - LoRaMacParams.JoinAcceptDelay2 = mibSet->Param.JoinAcceptDelay2; + _params.sys_params.JoinAcceptDelay2 = mibSet->Param.JoinAcceptDelay2; break; } case MIB_CHANNELS_DEFAULT_DATARATE: @@ -2267,7 +2278,7 @@ LoRaMacStatus_t LoRaMac::LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSe if(lora_phy->verify(&verify, PHY_DEF_TX_DR) == true) { - LoRaMacParamsDefaults.ChannelsDatarate = verify.DatarateParams.Datarate; + _params.def_sys_params.ChannelsDatarate = verify.DatarateParams.Datarate; } else { @@ -2278,11 +2289,11 @@ LoRaMacStatus_t LoRaMac::LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSe case MIB_CHANNELS_DATARATE: { verify.DatarateParams.Datarate = mibSet->Param.ChannelsDatarate; - verify.DatarateParams.UplinkDwellTime = LoRaMacParams.UplinkDwellTime; + verify.DatarateParams.UplinkDwellTime = _params.sys_params.UplinkDwellTime; if(lora_phy->verify(&verify, PHY_TX_DR) == true) { - LoRaMacParams.ChannelsDatarate = verify.DatarateParams.Datarate; + _params.sys_params.ChannelsDatarate = verify.DatarateParams.Datarate; } else { @@ -2296,7 +2307,7 @@ LoRaMacStatus_t LoRaMac::LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSe if(lora_phy->verify(&verify, PHY_DEF_TX_POWER) == true) { - LoRaMacParamsDefaults.ChannelsTxPower = verify.TxPower; + _params.def_sys_params.ChannelsTxPower = verify.TxPower; } else { @@ -2310,7 +2321,7 @@ LoRaMacStatus_t LoRaMac::LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSe if(lora_phy->verify(&verify, PHY_TX_POWER) == true) { - LoRaMacParams.ChannelsTxPower = verify.TxPower; + _params.sys_params.ChannelsTxPower = verify.TxPower; } else { @@ -2330,17 +2341,17 @@ LoRaMacStatus_t LoRaMac::LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSe } case MIB_SYSTEM_MAX_RX_ERROR: { - LoRaMacParams.SystemMaxRxError = LoRaMacParamsDefaults.SystemMaxRxError = mibSet->Param.SystemMaxRxError; + _params.sys_params.SystemMaxRxError = _params.def_sys_params.SystemMaxRxError = mibSet->Param.SystemMaxRxError; break; } case MIB_MIN_RX_SYMBOLS: { - LoRaMacParams.MinRxSymbols = LoRaMacParamsDefaults.MinRxSymbols = mibSet->Param.MinRxSymbols; + _params.sys_params.MinRxSymbols = _params.def_sys_params.MinRxSymbols = mibSet->Param.MinRxSymbols; break; } case MIB_ANTENNA_GAIN: { - LoRaMacParams.AntennaGain = mibSet->Param.AntennaGain; + _params.sys_params.AntennaGain = mibSet->Param.AntennaGain; break; } default: @@ -2470,112 +2481,7 @@ LoRaMacStatus_t LoRaMac::LoRaMacMulticastChannelUnlink( MulticastParams_t *chann LoRaMacStatus_t LoRaMac::LoRaMacMlmeRequest( MlmeReq_t *mlmeRequest ) { - LoRaMacStatus_t status = LORAMAC_STATUS_SERVICE_UNKNOWN; - LoRaMacHeader_t macHdr; - AlternateDrParams_t altDr; - VerifyParams_t verify; - GetPhyParams_t getPhy; - PhyParam_t phyParam; - - if( mlmeRequest == NULL ) - { - return LORAMAC_STATUS_PARAMETER_INVALID; - } - if( _params.LoRaMacState != LORAMAC_IDLE ) - { - return LORAMAC_STATUS_BUSY; - } - - memset( ( uint8_t* ) &MlmeConfirm, 0, sizeof( MlmeConfirm ) ); - - MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR; - - switch( mlmeRequest->Type ) - { - case MLME_JOIN: - { - if( (_params. LoRaMacState & LORAMAC_TX_DELAYED ) == LORAMAC_TX_DELAYED ) - { - return LORAMAC_STATUS_BUSY; - } - - if( ( mlmeRequest->Req.Join.DevEui == NULL ) || - ( mlmeRequest->Req.Join.AppEui == NULL ) || - ( mlmeRequest->Req.Join.AppKey == NULL ) || - ( mlmeRequest->Req.Join.NbTrials == 0 ) ) - { - return LORAMAC_STATUS_PARAMETER_INVALID; - } - - // Verify the parameter NbTrials for the join procedure - verify.NbJoinTrials = mlmeRequest->Req.Join.NbTrials; - - if(lora_phy->verify(&verify, PHY_NB_JOIN_TRIALS) == false) - { - // Value not supported, get default - getPhy.Attribute = PHY_DEF_NB_JOIN_TRIALS; - phyParam = lora_phy->get_phy_params( &getPhy ); - mlmeRequest->Req.Join.NbTrials = ( uint8_t ) phyParam.Value; - } - - _params.LoRaMacFlags.Bits.MlmeReq = 1; - MlmeConfirm.MlmeRequest = mlmeRequest->Type; - - _params.keys.LoRaMacDevEui = mlmeRequest->Req.Join.DevEui; - _params.keys.LoRaMacAppEui = mlmeRequest->Req.Join.AppEui; - _params.keys.LoRaMacAppKey = mlmeRequest->Req.Join.AppKey; - _params.MaxJoinRequestTrials = mlmeRequest->Req.Join.NbTrials; - - // Reset variable JoinRequestTrials - _params.JoinRequestTrials = 0; - - // Setup header information - macHdr.Value = 0; - macHdr.Bits.MType = FRAME_TYPE_JOIN_REQ; - - ResetMacParameters( ); - - altDr.NbTrials = _params.JoinRequestTrials + 1; - - LoRaMacParams.ChannelsDatarate = lora_phy->get_alternate_DR(&altDr); - - status = Send( &macHdr, 0, NULL, 0 ); - break; - } - case MLME_LINK_CHECK: - { - _params.LoRaMacFlags.Bits.MlmeReq = 1; - // LoRaMac will send this command piggy-backed - MlmeConfirm.MlmeRequest = mlmeRequest->Type; - - status = mac_commands.AddMacCommand( MOTE_MAC_LINK_CHECK_REQ, 0, 0 ); - break; - } - case MLME_TXCW: - { - MlmeConfirm.MlmeRequest = mlmeRequest->Type; - _params.LoRaMacFlags.Bits.MlmeReq = 1; - status = SetTxContinuousWave( mlmeRequest->Req.TxCw.Timeout ); - break; - } - case MLME_TXCW_1: - { - MlmeConfirm.MlmeRequest = mlmeRequest->Type; - _params.LoRaMacFlags.Bits.MlmeReq = 1; - status = SetTxContinuousWave1( mlmeRequest->Req.TxCw.Timeout, mlmeRequest->Req.TxCw.Frequency, mlmeRequest->Req.TxCw.Power ); - break; - } - default: - break; - } - - if( status != LORAMAC_STATUS_OK ) - { - _params.NodeAckRequested = false; - _params.LoRaMacFlags.Bits.MlmeReq = 0; - } - - return status; + return mlme.set_request(mlmeRequest, &_params); } LoRaMacStatus_t LoRaMac::LoRaMacMcpsRequest( McpsReq_t *mcpsRequest ) @@ -2657,7 +2563,7 @@ LoRaMacStatus_t LoRaMac::LoRaMacMcpsRequest( McpsReq_t *mcpsRequest ) // Get the minimum possible datarate getPhy.Attribute = PHY_MIN_TX_DR; - getPhy.UplinkDwellTime = LoRaMacParams.UplinkDwellTime; + getPhy.UplinkDwellTime = _params.sys_params.UplinkDwellTime; phyParam = lora_phy->get_phy_params( &getPhy ); // Apply the minimum possible datarate. // Some regions have limitations for the minimum datarate. @@ -2665,14 +2571,14 @@ LoRaMacStatus_t LoRaMac::LoRaMacMcpsRequest( McpsReq_t *mcpsRequest ) if( readyToSend == true ) { - if( LoRaMacParams.AdrCtrlOn == false ) + if( _params.sys_params.AdrCtrlOn == false ) { verify.DatarateParams.Datarate = datarate; - verify.DatarateParams.UplinkDwellTime = LoRaMacParams.UplinkDwellTime; + verify.DatarateParams.UplinkDwellTime = _params.sys_params.UplinkDwellTime; if(lora_phy->verify(&verify, PHY_TX_DR) == true) { - LoRaMacParams.ChannelsDatarate = verify.DatarateParams.Datarate; + _params.sys_params.ChannelsDatarate = verify.DatarateParams.Datarate; } else { diff --git a/features/lorawan/lorastack/mac/LoRaMac.h b/features/lorawan/lorastack/mac/LoRaMac.h index d12f180004..0e2ca5cd64 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.h +++ b/features/lorawan/lorastack/mac/LoRaMac.h @@ -44,10 +44,9 @@ #include "netsocket/LoRaRadio.h" #include "lorastack/phy/LoRaPHY.h" #include "lorawan/system/lorawan_data_structures.h" -#include "LoRaMacCommand.h" +#include "lorastack/mac/LoRaMacCommand.h" #include "events/EventQueue.h" - - +#include "lorastack/mac/LoRaMacMlme.h" /*! * Maximum PHY layer payload size */ @@ -332,6 +331,44 @@ public: */ void SetMlmeScheduleUplinkIndication( void ); + /*! + * \brief LoRaMAC layer generic send frame + * + * \param [IN] macHdr MAC header field + * \param [IN] fPort MAC payload port + * \param [IN] fBuffer MAC data buffer to be sent + * \param [IN] fBufferSize MAC data buffer size + * \retval status Status of the operation. + */ + LoRaMacStatus_t Send( LoRaMacHeader_t *macHdr, uint8_t fPort, void *fBuffer, uint16_t fBufferSize ); + + /*! + * \brief Sets the radio in continuous transmission mode + * + * \remark Uses the radio parameters set on the previous transmission. + * + * \param [IN] timeout Time in seconds while the radio is kept in continuous wave mode + * \retval status Status of the operation. + */ + LoRaMacStatus_t SetTxContinuousWave( uint16_t timeout ); + + /*! + * \brief Sets the radio in continuous transmission mode + * + * \remark Uses the radio parameters set on the previous transmission. + * + * \param [IN] timeout Time in seconds while the radio is kept in continuous wave mode + * \param [IN] frequency RF frequency to be set. + * \param [IN] power RF output power to be set. + * \retval status Status of the operation. + */ + LoRaMacStatus_t SetTxContinuousWave1( uint16_t timeout, uint32_t frequency, uint8_t power ); + + /*! + * \brief Resets MAC specific parameters to default + */ + void ResetMacParameters( void ); + #if defined(LORAWAN_COMPLIANCE_TEST) public: // Test interface @@ -494,17 +531,6 @@ private: */ bool ValidatePayloadLength( uint8_t lenN, int8_t datarate, uint8_t fOptsLen ); - /*! - * \brief LoRaMAC layer generic send frame - * - * \param [IN] macHdr MAC header field - * \param [IN] fPort MAC payload port - * \param [IN] fBuffer MAC data buffer to be sent - * \param [IN] fBufferSize MAC data buffer size - * \retval status Status of the operation. - */ - LoRaMacStatus_t Send( LoRaMacHeader_t *macHdr, uint8_t fPort, void *fBuffer, uint16_t fBufferSize ); - /*! * \brief LoRaMAC layer frame buffer initialization * @@ -543,33 +569,6 @@ private: */ LoRaMacStatus_t SendFrameOnChannel( uint8_t channel ); - /*! - * \brief Sets the radio in continuous transmission mode - * - * \remark Uses the radio parameters set on the previous transmission. - * - * \param [IN] timeout Time in seconds while the radio is kept in continuous wave mode - * \retval status Status of the operation. - */ - LoRaMacStatus_t SetTxContinuousWave( uint16_t timeout ); - - /*! - * \brief Sets the radio in continuous transmission mode - * - * \remark Uses the radio parameters set on the previous transmission. - * - * \param [IN] timeout Time in seconds while the radio is kept in continuous wave mode - * \param [IN] frequency RF frequency to be set. - * \param [IN] power RF output power to be set. - * \retval status Status of the operation. - */ - LoRaMacStatus_t SetTxContinuousWave1( uint16_t timeout, uint32_t frequency, uint8_t power ); - - /*! - * \brief Resets MAC specific parameters to default - */ - void ResetMacParameters( void ); - /*! * \brief Resets MAC specific parameters to default * @@ -609,10 +608,24 @@ private: */ LoRaPHY *lora_phy; + /** + * MAC command handle + */ LoRaMacCommand mac_commands; + /** + * MLME subsystem handle + */ + LoRaMacMlme mlme; + + /** + * Timer subsystem handle + */ LoRaWANTimeHandler &_lora_time; + /** + * Central MAC layer data storage + */ lora_mac_protocol_params _params; /** @@ -625,17 +638,6 @@ private: */ MulticastParams_t *MulticastChannels; - - /*! - * LoRaMac parameters - */ - LoRaMacParams_t LoRaMacParams; - - /*! - * LoRaMac default parameters - */ - LoRaMacParams_t LoRaMacParamsDefaults; - /*! * LoRaMac upper layer event functions */ @@ -646,23 +648,6 @@ private: */ LoRaMacCallback_t *LoRaMacCallbacks; - - - /*! - * LoRaMac reception windows delay - * \remark normal frame: RxWindowXDelay = ReceiveDelayX - RADIO_WAKEUP_TIME - * join frame : RxWindowXDelay = JoinAcceptDelayX - RADIO_WAKEUP_TIME - */ - uint32_t RxWindow1Delay; - uint32_t RxWindow2Delay; - - /*! - * LoRaMac Rx windows configuration - */ - RxConfigParams_t RxWindow1Config; - RxConfigParams_t RxWindow2Config; - - /*! * Structure to hold MCPS indication data. */ @@ -674,19 +659,10 @@ private: McpsConfirm_t McpsConfirm; /*! - * Structure to hold MLME indication data. + * Receive Window configurations for PHY layer */ - MlmeIndication_t MlmeIndication; - - /*! - * Structure to hold MLME confirm data. - */ - MlmeConfirm_t MlmeConfirm; - - /*! - * Holds the current rx window slot - */ - LoRaMacRxSlot_t RxSlot; + RxConfigParams_t RxWindow1Config; + RxConfigParams_t RxWindow2Config; }; diff --git a/features/lorawan/lorastack/mac/LoRaMacCommand.cpp b/features/lorawan/lorastack/mac/LoRaMacCommand.cpp index 108c0c2f9c..394d01aeec 100644 --- a/features/lorawan/lorastack/mac/LoRaMacCommand.cpp +++ b/features/lorawan/lorastack/mac/LoRaMacCommand.cpp @@ -252,8 +252,8 @@ bool LoRaMacCommand::IsMacCommandsInNextTx() const } void LoRaMacCommand::ProcessMacCommands(uint8_t *payload, uint8_t macIndex, uint8_t commandsSize, uint8_t snr, - MlmeConfirm_t &MlmeConfirm, LoRaMacCallback_t *LoRaMacCallbacks, - LoRaMacParams_t &LoRaMacParams, LoRaPHY &lora_phy) + MlmeConfirm_t& MlmeConfirm, LoRaMacCallback_t *LoRaMacCallbacks, + lora_mac_system_params_t &LoRaMacParams, LoRaPHY &lora_phy) { uint8_t status = 0; diff --git a/features/lorawan/lorastack/mac/LoRaMacCommand.h b/features/lorawan/lorastack/mac/LoRaMacCommand.h index 4fb7865577..9f0da64705 100644 --- a/features/lorawan/lorastack/mac/LoRaMacCommand.h +++ b/features/lorawan/lorastack/mac/LoRaMacCommand.h @@ -134,7 +134,7 @@ public: */ void ProcessMacCommands(uint8_t *payload, uint8_t macIndex, uint8_t commandsSize, uint8_t snr, MlmeConfirm_t &MlmeConfirm, LoRaMacCallback_t *LoRaMacCallbacks, - LoRaMacParams_t &LoRaMacParams, LoRaPHY &lora_phy); + lora_mac_system_params_t &LoRaMacParams, LoRaPHY &lora_phy); /*! * \brief Verifies if sticky MAC commands are pending. diff --git a/features/lorawan/lorastack/mac/LoRaMacMlme.cpp b/features/lorawan/lorastack/mac/LoRaMacMlme.cpp new file mode 100644 index 0000000000..e42f4eb28f --- /dev/null +++ b/features/lorawan/lorastack/mac/LoRaMacMlme.cpp @@ -0,0 +1,163 @@ +/** + / _____) _ | | +( (____ _____ ____ _| |_ _____ ____| |__ + \____ \| ___ | (_ _) ___ |/ ___) _ \ + _____) ) ____| | | || |_| ____( (___| | | | +(______/|_____)_|_|_| \__)_____)\____)_| |_| + (C)2013 Semtech + ___ _____ _ ___ _ _____ ___ ___ ___ ___ +/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| +\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| +|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| +embedded.connectivity.solutions=============== + +Description: LoRaWAN stack layer that controls both MAC and PHY underneath + +License: Revised BSD License, see LICENSE.TXT file include in the project + +Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE ) + + +Copyright (c) 2017, Arm Limited and affiliates. + +SPDX-License-Identifier: BSD-3-Clause +*/ + +#include "LoRaMac.h" +#include "lorastack/mac/LoRaMacMlme.h" + +LoRaMacMlme::LoRaMacMlme() +: _lora_mac(NULL), _lora_phy(NULL), _mac_cmd(NULL) +{ +} + +LoRaMacMlme::~LoRaMacMlme() +{ +} + +void LoRaMacMlme::activate_mlme_subsystem(LoRaMac *mac, LoRaPHY *phy, + LoRaMacCommand *cmd) +{ + _lora_mac = mac; + _lora_phy = phy; + _mac_cmd = cmd; +} + +LoRaMacStatus_t LoRaMacMlme::set_request(MlmeReq_t *mlmeRequest, + lora_mac_protocol_params *params) +{ + if (mlmeRequest && params && _lora_mac && _lora_phy && _mac_cmd) { + + LoRaMacStatus_t status = LORAMAC_STATUS_SERVICE_UNKNOWN; + LoRaMacHeader_t macHdr; + AlternateDrParams_t altDr; + VerifyParams_t verify; + GetPhyParams_t getPhy; + PhyParam_t phyParam; + + + if (params->LoRaMacState != LORAMAC_IDLE) { + return LORAMAC_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 (mlmeRequest->Type) { + case MLME_JOIN: { + if ((params->LoRaMacState & LORAMAC_TX_DELAYED) + == LORAMAC_TX_DELAYED) { + return LORAMAC_STATUS_BUSY; + } + + if ((mlmeRequest->Req.Join.DevEui == NULL) + || (mlmeRequest->Req.Join.AppEui == NULL) + || (mlmeRequest->Req.Join.AppKey == NULL) + || (mlmeRequest->Req.Join.NbTrials == 0)) { + return LORAMAC_STATUS_PARAMETER_INVALID; + } + + // Verify the parameter NbTrials for the join procedure + verify.NbJoinTrials = mlmeRequest->Req.Join.NbTrials; + + if (_lora_phy->verify(&verify, PHY_NB_JOIN_TRIALS) == false) { + // Value not supported, get default + getPhy.Attribute = PHY_DEF_NB_JOIN_TRIALS; + phyParam = _lora_phy->get_phy_params(&getPhy); + mlmeRequest->Req.Join.NbTrials = (uint8_t) phyParam.Value; + } + + params->LoRaMacFlags.Bits.MlmeReq = 1; + confirmation.MlmeRequest = mlmeRequest->Type; + + params->keys.LoRaMacDevEui = mlmeRequest->Req.Join.DevEui; + params->keys.LoRaMacAppEui = mlmeRequest->Req.Join.AppEui; + params->keys.LoRaMacAppKey = mlmeRequest->Req.Join.AppKey; + params->MaxJoinRequestTrials = mlmeRequest->Req.Join.NbTrials; + + // Reset variable JoinRequestTrials + params->JoinRequestTrials = 0; + + // Setup header information + macHdr.Value = 0; + macHdr.Bits.MType = FRAME_TYPE_JOIN_REQ; + + _lora_mac->ResetMacParameters(); + + altDr.NbTrials = params->JoinRequestTrials + 1; + + params->sys_params.ChannelsDatarate = + _lora_phy->get_alternate_DR(&altDr); + + status = _lora_mac->Send(&macHdr, 0, NULL, 0); + break; + } + case MLME_LINK_CHECK: { + params->LoRaMacFlags.Bits.MlmeReq = 1; + // LoRaMac will send this command piggy-backed + confirmation.MlmeRequest = mlmeRequest->Type; + + status = _mac_cmd->AddMacCommand(MOTE_MAC_LINK_CHECK_REQ, 0, 0); + break; + } + case MLME_TXCW: { + confirmation.MlmeRequest = mlmeRequest->Type; + params->LoRaMacFlags.Bits.MlmeReq = 1; + status = _lora_mac->SetTxContinuousWave(mlmeRequest->Req.TxCw.Timeout); + break; + } + case MLME_TXCW_1: { + confirmation.MlmeRequest = mlmeRequest->Type; + params->LoRaMacFlags.Bits.MlmeReq = 1; + status = _lora_mac->SetTxContinuousWave1(mlmeRequest->Req.TxCw.Timeout, + mlmeRequest->Req.TxCw.Frequency, + mlmeRequest->Req.TxCw.Power); + break; + } + default: + break; + } + + if (status != LORAMAC_STATUS_OK) { + params->NodeAckRequested = false; + params->LoRaMacFlags.Bits.MlmeReq = 0; + } + + return status; + } + + return LORAMAC_STATUS_PARAMETER_INVALID; +} + +MlmeIndication_t& LoRaMacMlme::get_indication() +{ + return indication; +} + +MlmeConfirm_t& LoRaMacMlme::get_confirmation() +{ + return confirmation; +} diff --git a/features/lorawan/lorastack/mac/LoRaMacMlme.h b/features/lorawan/lorastack/mac/LoRaMacMlme.h new file mode 100644 index 0000000000..978a88a5e1 --- /dev/null +++ b/features/lorawan/lorastack/mac/LoRaMacMlme.h @@ -0,0 +1,110 @@ +/** + / _____) _ | | +( (____ _____ ____ _| |_ _____ ____| |__ + \____ \| ___ | (_ _) ___ |/ ___) _ \ + _____) ) ____| | | || |_| ____( (___| | | | +(______/|_____)_|_|_| \__)_____)\____)_| |_| + (C)2013 Semtech + ___ _____ _ ___ _ _____ ___ ___ ___ ___ +/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| +\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| +|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| +embedded.connectivity.solutions=============== + +Description: LoRaWAN stack layer that controls both MAC and PHY underneath + +License: Revised BSD License, see LICENSE.TXT file include in the project + +Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE ) + + +Copyright (c) 2017, Arm Limited and affiliates. + +SPDX-License-Identifier: BSD-3-Clause +*/ + +#ifndef MBED_OS_LORAWAN_MAC_MLME_H_ +#define MBED_OS_LORAWAN_MAC_MLME_H_ + +#include "lorawan/system/lorawan_data_structures.h" +#include "lorastack/phy/LoRaPHY.h" +#include "lorastack/mac/LoRaMacCommand.h" + +// forward declaration +class LoRaMac; + +class LoRaMacMlme { + +public: + + /** Constructor + * + * Sets local handles to NULL. These handles will be set when the subsystem + * is activated by the MAC layer. + */ + LoRaMacMlme(); + + /** Destructor + * + * Does nothing + */ + ~LoRaMacMlme(); + + /** Activating MLME subsystem + * + * Stores pointers to MAC and PHY layer handles + * + * @param mac pointer to MAC layer + * @param phy pointer to PHY layer + * @param cmd pointer to MAC commands + */ + void activate_mlme_subsystem(LoRaMac *mac, LoRaPHY *phy, LoRaMacCommand *cmd); + + /** 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 mlmeRequest pointer to MLME request structure + * @param params pointer to MAC protocol parameters + * + * @return LORA_MAC_STATUS_OK if everything goes well otherwise + * a negative error code is returned. + */ + LoRaMacStatus_t set_request(MlmeReq_t *mlmeRequest, lora_mac_protocol_params *params); + + /** Grants access to MLME confirmation data + * + * @return a reference to MLME confirm data structure + */ + MlmeConfirm_t& get_confirmation(); + + /** Grants access to MLME indication data + * + * @return a reference to MLME indication data structure + */ + MlmeIndication_t& get_indication(); + + +private: + + /** + * Pointers to MAC and PHY handles + */ + LoRaMac *_lora_mac; + LoRaPHY *_lora_phy; + LoRaMacCommand *_mac_cmd; + + /** + * Structure to hold MLME indication data. + */ + MlmeIndication_t indication; + + /** + * Structure to hold MLME confirm data. + */ + MlmeConfirm_t confirmation; +}; + +#endif /* MBED_OS_LORAWAN_MAC_MLME_H_ */ diff --git a/features/lorawan/system/lorawan_data_structures.h b/features/lorawan/system/lorawan_data_structures.h index 6711dffdab..915f48707c 100644 --- a/features/lorawan/system/lorawan_data_structures.h +++ b/features/lorawan/system/lorawan_data_structures.h @@ -330,7 +330,7 @@ typedef struct sLoRaMacParams * LoRaMac ADR control status */ bool AdrCtrlOn; -}LoRaMacParams_t; +} lora_mac_system_params_t; /*! * LoRaMAC multicast channel parameter. @@ -3044,6 +3044,11 @@ typedef struct { */ DeviceClass_t LoRaMacDeviceClass; + /*! + * Holds the type of current Receive window slot + */ + LoRaMacRxSlot_t RxSlot; + /*! * Indicates if the node is connected to a private or public network */ @@ -3200,8 +3205,29 @@ typedef struct { */ uint32_t LoRaMacState; + /*! + * LoRaMac reception windows delay + * \remark normal frame: RxWindowXDelay = ReceiveDelayX - RADIO_WAKEUP_TIME + * join frame : RxWindowXDelay = JoinAcceptDelayX - RADIO_WAKEUP_TIME + */ + uint32_t RxWindow1Delay; + uint32_t RxWindow2Delay; + + /*! + * Timer objects and stored values + */ lora_mac_timers timers; + /*! + * LoRaMac parameters + */ + lora_mac_system_params_t sys_params; + + /*! + * LoRaMac default parameters + */ + lora_mac_system_params_t def_sys_params; + } lora_mac_protocol_params; /** LoRaWAN callback functions From 255bd30a48315a76daaf2b580eb64a1bab2bc702 Mon Sep 17 00:00:00 2001 From: Hasnain Virk Date: Tue, 9 Jan 2018 16:00:41 +0200 Subject: [PATCH 07/23] [IOTCELL-290] Adding MCPS subsystem Like MLME, MCPS has also been alloted its own class. This is the 2nd stage of breaking down the MAC services into subsystems. --- features/lorawan/lorastack/mac/LoRaMac.cpp | 283 ++++++------------ features/lorawan/lorastack/mac/LoRaMac.h | 16 +- .../lorawan/lorastack/mac/LoRaMacMcps.cpp | 154 ++++++++++ features/lorawan/lorastack/mac/LoRaMacMcps.h | 114 +++++++ 4 files changed, 361 insertions(+), 206 deletions(-) create mode 100644 features/lorawan/lorastack/mac/LoRaMacMcps.cpp create mode 100644 features/lorawan/lorastack/mac/LoRaMacMcps.h diff --git a/features/lorawan/lorastack/mac/LoRaMac.cpp b/features/lorawan/lorastack/mac/LoRaMac.cpp index 3773403f06..fcd48705f2 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.cpp +++ b/features/lorawan/lorastack/mac/LoRaMac.cpp @@ -231,7 +231,7 @@ void LoRaMac::OnRadioTxDone( void ) } else { - McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK; + mcps.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_OK; mlme_confirm.Status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT; if( _params.LoRaMacFlags.Value == 0 ) @@ -263,7 +263,7 @@ void LoRaMac::OnRadioTxDone( void ) if( _params.NodeAckRequested == false ) { - McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK; + mcps.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_OK; _params.ChannelsNbRepCounter++; } } @@ -315,19 +315,19 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 bool isMicOk = false; - McpsConfirm.AckReceived = false; - McpsIndication.Rssi = rssi; - McpsIndication.Snr = snr; - McpsIndication.RxSlot = _params.RxSlot; - McpsIndication.Port = 0; - McpsIndication.Multicast = 0; - McpsIndication.FramePending = 0; - McpsIndication.Buffer = NULL; - McpsIndication.BufferSize = 0; - McpsIndication.RxData = false; - McpsIndication.AckReceived = false; - McpsIndication.DownLinkCounter = 0; - McpsIndication.McpsIndication = MCPS_UNCONFIRMED; + mcps.get_confirmation().AckReceived = false; + mcps.get_indication().Rssi = rssi; + mcps.get_indication().Snr = snr; + mcps.get_indication().RxSlot = _params.RxSlot; + mcps.get_indication().Port = 0; + mcps.get_indication().Multicast = 0; + mcps.get_indication().FramePending = 0; + mcps.get_indication().Buffer = NULL; + mcps.get_indication().BufferSize = 0; + mcps.get_indication().RxData = false; + mcps.get_indication().AckReceived = false; + mcps.get_indication().DownLinkCounter = 0; + mcps.get_indication().McpsIndication = MCPS_UNCONFIRMED; lora_phy->put_radio_to_sleep(); @@ -340,7 +340,7 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 case FRAME_TYPE_JOIN_ACCEPT: if( _params.IsLoRaMacNetworkJoined == true ) { - McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_ERROR; + mcps.get_indication().Status = LORAMAC_EVENT_INFO_STATUS_ERROR; PrepareRxDoneAbort( ); return; } @@ -348,7 +348,7 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 if (0 != LoRaMacJoinDecrypt( payload + 1, size - 1, _params.keys.LoRaMacAppKey, _params.LoRaMacRxPayload + 1 )) { - McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL; + mcps.get_indication().Status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL; return; } @@ -358,7 +358,7 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 size - LORAMAC_MFR_LEN, _params.keys.LoRaMacAppKey, &mic )) { - McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL; + mcps.get_indication().Status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL; return; } @@ -374,7 +374,7 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 _params.LoRaMacDevNonce, _params.keys.LoRaMacNwkSKey, _params.keys.LoRaMacAppSKey )) { - McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL; + mcps.get_indication().Status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL; return; } @@ -420,7 +420,7 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 { // Check if the received payload size is valid getPhy.UplinkDwellTime = _params.sys_params.DownlinkDwellTime; - getPhy.Datarate = McpsIndication.RxDatarate; + getPhy.Datarate = mcps.get_indication().RxDatarate; getPhy.Attribute = PHY_MAX_PAYLOAD; // Get the maximum payload length @@ -431,7 +431,7 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 phyParam = lora_phy->get_phy_params(&getPhy); if( MAX( 0, ( int16_t )( ( int16_t )size - ( int16_t )LORA_MAC_FRMPAYLOAD_OVERHEAD ) ) > (int32_t)phyParam.Value ) { - McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_ERROR; + mcps.get_indication().Status = LORAMAC_EVENT_INFO_STATUS_ERROR; PrepareRxDoneAbort( ); return; } @@ -459,7 +459,7 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 if( multicast == 0 ) { // We are not the destination of this frame. - McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_ADDRESS_FAIL; + mcps.get_indication().Status = LORAMAC_EVENT_INFO_STATUS_ADDRESS_FAIL; PrepareRxDoneAbort( ); return; } @@ -513,22 +513,22 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 phyParam = lora_phy->get_phy_params( &getPhy ); if( sequenceCounterDiff >= phyParam.Value ) { - McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_TOO_MANY_FRAMES_LOSS; - McpsIndication.DownLinkCounter = downLinkCounter; + mcps.get_indication().Status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_TOO_MANY_FRAMES_LOSS; + mcps.get_indication().DownLinkCounter = downLinkCounter; PrepareRxDoneAbort( ); return; } if( isMicOk == true ) { - McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_OK; - McpsIndication.Multicast = multicast; - McpsIndication.FramePending = fCtrl.Bits.FPending; - McpsIndication.Buffer = NULL; - McpsIndication.BufferSize = 0; - McpsIndication.DownLinkCounter = downLinkCounter; + mcps.get_indication().Status = LORAMAC_EVENT_INFO_STATUS_OK; + mcps.get_indication().Multicast = multicast; + mcps.get_indication().FramePending = fCtrl.Bits.FPending; + mcps.get_indication().Buffer = NULL; + mcps.get_indication().BufferSize = 0; + mcps.get_indication().DownLinkCounter = downLinkCounter; - McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK; + mcps.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_OK; _params.AdrAckCounter = 0; mac_commands.ClearRepeatBuffer(); @@ -536,13 +536,13 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 // Update 32 bits downlink counter if( multicast == 1 ) { - McpsIndication.McpsIndication = MCPS_MULTICAST; + mcps.get_indication().McpsIndication = MCPS_MULTICAST; if( ( curMulticastParams->DownLinkCounter == downLinkCounter ) && ( curMulticastParams->DownLinkCounter != 0 ) ) { - McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED; - McpsIndication.DownLinkCounter = downLinkCounter; + mcps.get_indication().Status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED; + mcps.get_indication().DownLinkCounter = downLinkCounter; PrepareRxDoneAbort( ); return; } @@ -553,7 +553,7 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 if( macHdr.Bits.MType == FRAME_TYPE_DATA_CONFIRMED_DOWN ) { _params.SrvAckRequested = true; - McpsIndication.McpsIndication = MCPS_CONFIRMED; + mcps.get_indication().McpsIndication = MCPS_CONFIRMED; if( ( _params.DownLinkCounter == downLinkCounter ) && ( _params.DownLinkCounter != 0 ) ) @@ -569,13 +569,13 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 else { _params.SrvAckRequested = false; - McpsIndication.McpsIndication = MCPS_UNCONFIRMED; + mcps.get_indication().McpsIndication = MCPS_UNCONFIRMED; if( ( _params.DownLinkCounter == downLinkCounter ) && ( _params.DownLinkCounter != 0 ) ) { - McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED; - McpsIndication.DownLinkCounter = downLinkCounter; + mcps.get_indication().Status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED; + mcps.get_indication().DownLinkCounter = downLinkCounter; PrepareRxDoneAbort( ); return; } @@ -587,7 +587,7 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 // We need to reset the MacCommandsBufferIndex here, since we need // to take retransmissions and repetitions into account. Error cases // will be handled in function OnMacStateCheckTimerEvent. - if( McpsConfirm.McpsRequest == MCPS_CONFIRMED ) + if( mcps.get_confirmation().McpsRequest == MCPS_CONFIRMED ) { if( fCtrl.Bits.Ack == 1 ) {// Reset MacCommandsBufferIndex when we have received an ACK. @@ -605,7 +605,7 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 port = payload[appPayloadStartIndex++]; frameLen = ( size - 4 ) - appPayloadStartIndex; - McpsIndication.Port = port; + mcps.get_indication().Port = port; if( port == 0 ) { @@ -619,7 +619,7 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 DOWN_LINK, downLinkCounter, _params.LoRaMacRxPayload )) { - McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL; + mcps.get_indication().Status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL; } // Decode frame payload MAC commands @@ -649,14 +649,14 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 DOWN_LINK, downLinkCounter, _params.LoRaMacRxPayload )) { - McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL; + mcps.get_indication().Status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL; } if( skipIndication == false ) { - McpsIndication.Buffer = _params.LoRaMacRxPayload; - McpsIndication.BufferSize = frameLen; - McpsIndication.RxData = true; + mcps.get_indication().Buffer = _params.LoRaMacRxPayload; + mcps.get_indication().BufferSize = frameLen; + mcps.get_indication().RxData = true; } } } @@ -676,8 +676,8 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 // Check if the frame is an acknowledgement if( fCtrl.Bits.Ack == 1 ) { - McpsConfirm.AckReceived = true; - McpsIndication.AckReceived = true; + mcps.get_confirmation().AckReceived = true; + mcps.get_indication().AckReceived = true; // Stop the AckTimeout timer as no more retransmissions // are needed. @@ -685,7 +685,7 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 } else { - McpsConfirm.AckReceived = false; + mcps.get_confirmation().AckReceived = false; if( _params.AckTimeoutRetriesCounter > _params.AckTimeoutRetries ) { @@ -702,7 +702,7 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 } else { - McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_MIC_FAIL; + mcps.get_indication().Status = LORAMAC_EVENT_INFO_STATUS_MIC_FAIL; PrepareRxDoneAbort( ); return; @@ -713,16 +713,16 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 { memcpy( _params.LoRaMacRxPayload, &payload[pktHeaderLen], size ); - McpsIndication.McpsIndication = MCPS_PROPRIETARY; - McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_OK; - McpsIndication.Buffer = _params.LoRaMacRxPayload; - McpsIndication.BufferSize = size - pktHeaderLen; + mcps.get_indication().McpsIndication = MCPS_PROPRIETARY; + mcps.get_indication().Status = LORAMAC_EVENT_INFO_STATUS_OK; + mcps.get_indication().Buffer = _params.LoRaMacRxPayload; + mcps.get_indication().BufferSize = size - pktHeaderLen; _params.LoRaMacFlags.Bits.McpsInd = 1; break; } default: - McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_ERROR; + mcps.get_indication().Status = LORAMAC_EVENT_INFO_STATUS_ERROR; PrepareRxDoneAbort( ); break; } @@ -744,7 +744,7 @@ void LoRaMac::OnRadioTxTimeout( void ) OpenContinuousRx2Window( ); } - McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT; + mcps.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT; mlme.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT; @@ -766,7 +766,7 @@ void LoRaMac::OnRadioRxError( void ) { if( _params.NodeAckRequested == true ) { - McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX1_ERROR; + mcps.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_RX1_ERROR; } mlme.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_RX1_ERROR; @@ -781,7 +781,7 @@ void LoRaMac::OnRadioRxError( void ) { if( _params.NodeAckRequested == true ) { - McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX2_ERROR; + mcps.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_RX2_ERROR; } mlme.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_RX2_ERROR; @@ -805,7 +805,7 @@ void LoRaMac::OnRadioRxTimeout( void ) { if( _params.NodeAckRequested == true ) { - McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX1_TIMEOUT; + mcps.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_RX1_TIMEOUT; } mlme.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_RX1_TIMEOUT; @@ -819,7 +819,7 @@ void LoRaMac::OnRadioRxTimeout( void ) { if( _params.NodeAckRequested == true ) { - McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT; + mcps.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT; } mlme.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT; @@ -852,15 +852,15 @@ void LoRaMac::OnMacStateCheckTimerEvent( void ) if( ( _params.LoRaMacFlags.Bits.MlmeReq == 1 ) || ( ( _params.LoRaMacFlags.Bits.McpsReq == 1 ) ) ) { - if( ( McpsConfirm.Status == LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT ) || + if( ( mcps.get_confirmation().Status == LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT ) || ( mlme.get_confirmation().Status == LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT ) ) { // Stop transmit cycle due to tx timeout. _params.LoRaMacState &= ~LORAMAC_TX_RUNNING; mac_commands.ClearCommandBuffer(); - McpsConfirm.NbRetries = _params.AckTimeoutRetriesCounter; - McpsConfirm.AckReceived = false; - McpsConfirm.TxTimeOnAir = 0; + mcps.get_confirmation().NbRetries = _params.AckTimeoutRetriesCounter; + mcps.get_confirmation().AckReceived = false; + mcps.get_confirmation().TxTimeOnAir = 0; txTimeout = true; } } @@ -925,7 +925,7 @@ void LoRaMac::OnMacStateCheckTimerEvent( void ) if( _params.LoRaMacFlags.Bits.McpsInd == 1 ) {// Procedure if we received a frame - if( ( McpsConfirm.AckReceived == true ) || + if( ( mcps.get_confirmation().AckReceived == true ) || ( _params.AckTimeoutRetriesCounter > _params.AckTimeoutRetries ) ) { _params.AckTimeoutRetry = false; @@ -934,7 +934,7 @@ void LoRaMac::OnMacStateCheckTimerEvent( void ) { _params.UpLinkCounter++; } - McpsConfirm.NbRetries = _params.AckTimeoutRetriesCounter; + mcps.get_confirmation().NbRetries = _params.AckTimeoutRetriesCounter; _params.LoRaMacState &= ~LORAMAC_TX_RUNNING; } @@ -964,14 +964,14 @@ void LoRaMac::OnMacStateCheckTimerEvent( void ) else { // The DR is not applicable for the payload size - McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_TX_DR_PAYLOAD_SIZE_ERROR; + mcps.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_TX_DR_PAYLOAD_SIZE_ERROR; mac_commands.ClearCommandBuffer(); _params.LoRaMacState &= ~LORAMAC_TX_RUNNING; _params.NodeAckRequested = false; - McpsConfirm.AckReceived = false; - McpsConfirm.NbRetries = _params.AckTimeoutRetriesCounter; - McpsConfirm.Datarate = _params.sys_params.ChannelsDatarate; + mcps.get_confirmation().AckReceived = false; + mcps.get_confirmation().NbRetries = _params.AckTimeoutRetriesCounter; + mcps.get_confirmation().Datarate = _params.sys_params.ChannelsDatarate; if( _params.IsUpLinkCounterFixed == false ) { _params.UpLinkCounter++; @@ -986,8 +986,8 @@ void LoRaMac::OnMacStateCheckTimerEvent( void ) mac_commands.ClearCommandBuffer(); _params.NodeAckRequested = false; - McpsConfirm.AckReceived = false; - McpsConfirm.NbRetries = _params.AckTimeoutRetriesCounter; + mcps.get_confirmation().AckReceived = false; + mcps.get_confirmation().NbRetries = _params.AckTimeoutRetriesCounter; if( _params.IsUpLinkCounterFixed == false ) { _params.UpLinkCounter++; @@ -1005,7 +1005,7 @@ void LoRaMac::OnMacStateCheckTimerEvent( void ) if( _params.LoRaMacFlags.Bits.McpsReq == 1 ) { _params.LoRaMacFlags.Bits.McpsReq = 0; - LoRaMacPrimitives->MacMcpsConfirm( &McpsConfirm ); + LoRaMacPrimitives->MacMcpsConfirm( &mcps.get_confirmation() ); } if( _params.LoRaMacFlags.Bits.MlmeReq == 1 ) @@ -1041,7 +1041,7 @@ void LoRaMac::OnMacStateCheckTimerEvent( void ) } if( _params.LoRaMacFlags.Bits.McpsIndSkip == 0 ) { - LoRaMacPrimitives->MacMcpsIndication( &McpsIndication ); + LoRaMacPrimitives->MacMcpsIndication( &mcps.get_indication() ); } _params.LoRaMacFlags.Bits.McpsIndSkip = 0; } @@ -1102,7 +1102,7 @@ void LoRaMac::OnRxWindow1TimerEvent( void ) lora_phy->put_radio_to_standby(); } - lora_phy->rx_config(&RxWindow1Config, ( int8_t* )&McpsIndication.RxDatarate); + lora_phy->rx_config(&RxWindow1Config, ( int8_t* )&mcps.get_indication().RxDatarate); RxWindowSetup( RxWindow1Config.RxContinuous, _params.sys_params.MaxRxWindow ); } @@ -1126,7 +1126,7 @@ void LoRaMac::OnRxWindow2TimerEvent( void ) RxWindow2Config.RxContinuous = true; } - if(lora_phy->rx_config(&RxWindow2Config, ( int8_t* )&McpsIndication.RxDatarate) == true ) + if(lora_phy->rx_config(&RxWindow2Config, ( int8_t* )&mcps.get_indication().RxDatarate) == true ) { RxWindowSetup( RxWindow2Config.RxContinuous, _params.sys_params.MaxRxWindow ); _params.RxSlot = RX_SLOT_WIN_2; @@ -1214,9 +1214,9 @@ LoRaMacStatus_t LoRaMac::Send( LoRaMacHeader_t *macHdr, uint8_t fPort, void *fBu } // Reset confirm parameters - McpsConfirm.NbRetries = 0; - McpsConfirm.AckReceived = false; - McpsConfirm.UpLinkCounter = _params.UpLinkCounter; + mcps.get_confirmation().NbRetries = 0; + mcps.get_confirmation().AckReceived = false; + mcps.get_confirmation().UpLinkCounter = _params.UpLinkCounter; status = ScheduleTx( ); @@ -1617,12 +1617,12 @@ LoRaMacStatus_t LoRaMac::SendFrameOnChannel( uint8_t channel ) mlme.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_ERROR; - McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR; - McpsConfirm.Datarate = _params.sys_params.ChannelsDatarate; - McpsConfirm.TxPower = txPower; + mcps.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_ERROR; + mcps.get_confirmation().Datarate = _params.sys_params.ChannelsDatarate; + mcps.get_confirmation().TxPower = txPower; // Store the time on air - McpsConfirm.TxTimeOnAir = _params.timers.TxTimeOnAir; + mcps.get_confirmation().TxTimeOnAir = _params.timers.TxTimeOnAir; mlme.get_confirmation().TxTimeOnAir = _params.timers.TxTimeOnAir; // Starts the MAC layer status check timer @@ -1695,9 +1695,12 @@ LoRaMacStatus_t LoRaMac::LoRaMacInitialization(LoRaMacPrimitives_t *primitives, lora_phy = phy; - // Activate Mlme subsystem + // Activate MLME subsystem mlme.activate_mlme_subsystem(this, lora_phy, &mac_commands); + // Activate MCPS subsystem + mcps.activate_mcps_subsystem(this, lora_phy); + LoRaMacPrimitives = primitives; LoRaMacCallbacks = callbacks; @@ -2486,119 +2489,7 @@ LoRaMacStatus_t LoRaMac::LoRaMacMlmeRequest( MlmeReq_t *mlmeRequest ) LoRaMacStatus_t LoRaMac::LoRaMacMcpsRequest( McpsReq_t *mcpsRequest ) { - GetPhyParams_t getPhy; - PhyParam_t phyParam; - LoRaMacStatus_t status = LORAMAC_STATUS_SERVICE_UNKNOWN; - LoRaMacHeader_t macHdr; - VerifyParams_t verify; - uint8_t fPort = 0; - void *fBuffer; - uint16_t fBufferSize; - int8_t datarate = DR_0; - bool readyToSend = false; - - if( mcpsRequest == NULL ) - { - return LORAMAC_STATUS_PARAMETER_INVALID; - } - if( _params.LoRaMacState != LORAMAC_IDLE ) - { - return LORAMAC_STATUS_BUSY; - } - - macHdr.Value = 0; - memset ( ( uint8_t* ) &McpsConfirm, 0, sizeof( McpsConfirm ) ); - McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR; - - // AckTimeoutRetriesCounter must be reset every time a new request (unconfirmed or confirmed) is performed. - _params.AckTimeoutRetriesCounter = 1; - - switch( mcpsRequest->Type ) - { - case MCPS_UNCONFIRMED: - { - readyToSend = true; - _params.AckTimeoutRetries = 1; - - macHdr.Bits.MType = FRAME_TYPE_DATA_UNCONFIRMED_UP; - fPort = mcpsRequest->Req.Unconfirmed.fPort; - fBuffer = mcpsRequest->Req.Unconfirmed.fBuffer; - fBufferSize = mcpsRequest->Req.Unconfirmed.fBufferSize; - datarate = mcpsRequest->Req.Unconfirmed.Datarate; - break; - } - case MCPS_CONFIRMED: - { - readyToSend = true; - _params.AckTimeoutRetries = mcpsRequest->Req.Confirmed.NbTrials; - - macHdr.Bits.MType = FRAME_TYPE_DATA_CONFIRMED_UP; - fPort = mcpsRequest->Req.Confirmed.fPort; - fBuffer = mcpsRequest->Req.Confirmed.fBuffer; - fBufferSize = mcpsRequest->Req.Confirmed.fBufferSize; - datarate = mcpsRequest->Req.Confirmed.Datarate; - break; - } - case MCPS_PROPRIETARY: - { - readyToSend = true; - _params.AckTimeoutRetries = 1; - - macHdr.Bits.MType = FRAME_TYPE_PROPRIETARY; - fBuffer = mcpsRequest->Req.Proprietary.fBuffer; - fBufferSize = mcpsRequest->Req.Proprietary.fBufferSize; - datarate = mcpsRequest->Req.Proprietary.Datarate; - break; - } - default: - break; - } - - // Filter fPorts - // TODO: Does not work with PROPRIETARY messages -// if( IsFPortAllowed( fPort ) == false ) -// { -// return LORAMAC_STATUS_PARAMETER_INVALID; -// } - - // Get the minimum possible datarate - getPhy.Attribute = PHY_MIN_TX_DR; - getPhy.UplinkDwellTime = _params.sys_params.UplinkDwellTime; - phyParam = lora_phy->get_phy_params( &getPhy ); - // Apply the minimum possible datarate. - // Some regions have limitations for the minimum datarate. - datarate = MAX( datarate, phyParam.Value ); - - if( readyToSend == true ) - { - if( _params.sys_params.AdrCtrlOn == false ) - { - verify.DatarateParams.Datarate = datarate; - verify.DatarateParams.UplinkDwellTime = _params.sys_params.UplinkDwellTime; - - if(lora_phy->verify(&verify, PHY_TX_DR) == true) - { - _params.sys_params.ChannelsDatarate = verify.DatarateParams.Datarate; - } - else - { - return LORAMAC_STATUS_PARAMETER_INVALID; - } - } - - status = Send( &macHdr, fPort, fBuffer, fBufferSize ); - if( status == LORAMAC_STATUS_OK ) - { - McpsConfirm.McpsRequest = mcpsRequest->Type; - _params.LoRaMacFlags.Bits.McpsReq = 1; - } - else - { - _params.NodeAckRequested = false; - } - } - - return status; + return mcps.set_request(mcpsRequest, &_params); } radio_events_t *LoRaMac::GetPhyEventHandlers() diff --git a/features/lorawan/lorastack/mac/LoRaMac.h b/features/lorawan/lorastack/mac/LoRaMac.h index 0e2ca5cd64..b3ba9ded12 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.h +++ b/features/lorawan/lorastack/mac/LoRaMac.h @@ -47,6 +47,7 @@ #include "lorastack/mac/LoRaMacCommand.h" #include "events/EventQueue.h" #include "lorastack/mac/LoRaMacMlme.h" +#include "lorastack/mac/LoRaMacMcps.h" /*! * Maximum PHY layer payload size */ @@ -618,6 +619,11 @@ private: */ LoRaMacMlme mlme; + /** + * MCPS subsystem handle + */ + LoRaMacMcps mcps; + /** * Timer subsystem handle */ @@ -648,16 +654,6 @@ private: */ LoRaMacCallback_t *LoRaMacCallbacks; - /*! - * Structure to hold MCPS indication data. - */ - McpsIndication_t McpsIndication; - - /*! - * Structure to hold MCPS confirm data. - */ - McpsConfirm_t McpsConfirm; - /*! * Receive Window configurations for PHY layer */ diff --git a/features/lorawan/lorastack/mac/LoRaMacMcps.cpp b/features/lorawan/lorastack/mac/LoRaMacMcps.cpp new file mode 100644 index 0000000000..a6848ce618 --- /dev/null +++ b/features/lorawan/lorastack/mac/LoRaMacMcps.cpp @@ -0,0 +1,154 @@ +/** + / _____) _ | | +( (____ _____ ____ _| |_ _____ ____| |__ + \____ \| ___ | (_ _) ___ |/ ___) _ \ + _____) ) ____| | | || |_| ____( (___| | | | +(______/|_____)_|_|_| \__)_____)\____)_| |_| + (C)2013 Semtech + ___ _____ _ ___ _ _____ ___ ___ ___ ___ +/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| +\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| +|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| +embedded.connectivity.solutions=============== + +Description: LoRaWAN stack layer that controls both MAC and PHY underneath + +License: Revised BSD License, see LICENSE.TXT file include in the project + +Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE ) + + +Copyright (c) 2017, Arm Limited and affiliates. + +SPDX-License-Identifier: BSD-3-Clause +*/ + +#include "LoRaMac.h" +#include "lorastack/mac/LoRaMacMcps.h" + +LoRaMacMcps::LoRaMacMcps() +: _lora_mac(NULL), _lora_phy(NULL) +{ +} + +LoRaMacMcps::~LoRaMacMcps() +{ +} + +void LoRaMacMcps::activate_mcps_subsystem(LoRaMac *mac, LoRaPHY *phy) +{ + _lora_mac = mac; + _lora_phy = phy; +} + +LoRaMacStatus_t LoRaMacMcps::set_request(McpsReq_t *mcpsRequest, + lora_mac_protocol_params *params) +{ + + if (mcpsRequest == NULL || _lora_phy == NULL || _lora_mac == NULL) { + return LORAMAC_STATUS_PARAMETER_INVALID; + } + + if (params->LoRaMacState != LORAMAC_IDLE) { + return LORAMAC_STATUS_BUSY; + } + + GetPhyParams_t getPhy; + PhyParam_t phyParam; + LoRaMacStatus_t status = LORAMAC_STATUS_SERVICE_UNKNOWN; + LoRaMacHeader_t macHdr; + VerifyParams_t verify; + uint8_t fPort = 0; + void *fBuffer; + uint16_t fBufferSize; + int8_t datarate = DR_0; + bool readyToSend = false; + + macHdr.Value = 0; + + // Before performing any MCPS request, clear the confirmation structure + memset((uint8_t*) &confirmation, 0, sizeof(confirmation)); + + confirmation.Status = LORAMAC_EVENT_INFO_STATUS_ERROR; + + // AckTimeoutRetriesCounter must be reset every time a new request (unconfirmed or confirmed) is performed. + params->AckTimeoutRetriesCounter = 1; + + switch (mcpsRequest->Type) { + case MCPS_UNCONFIRMED: { + readyToSend = true; + params->AckTimeoutRetries = 1; + + macHdr.Bits.MType = FRAME_TYPE_DATA_UNCONFIRMED_UP; + fPort = mcpsRequest->Req.Unconfirmed.fPort; + fBuffer = mcpsRequest->Req.Unconfirmed.fBuffer; + fBufferSize = mcpsRequest->Req.Unconfirmed.fBufferSize; + datarate = mcpsRequest->Req.Unconfirmed.Datarate; + break; + } + case MCPS_CONFIRMED: { + readyToSend = true; + params->AckTimeoutRetries = mcpsRequest->Req.Confirmed.NbTrials; + + macHdr.Bits.MType = FRAME_TYPE_DATA_CONFIRMED_UP; + fPort = mcpsRequest->Req.Confirmed.fPort; + fBuffer = mcpsRequest->Req.Confirmed.fBuffer; + fBufferSize = mcpsRequest->Req.Confirmed.fBufferSize; + datarate = mcpsRequest->Req.Confirmed.Datarate; + break; + } + case MCPS_PROPRIETARY: { + readyToSend = true; + params->AckTimeoutRetries = 1; + + macHdr.Bits.MType = FRAME_TYPE_PROPRIETARY; + fBuffer = mcpsRequest->Req.Proprietary.fBuffer; + fBufferSize = mcpsRequest->Req.Proprietary.fBufferSize; + datarate = mcpsRequest->Req.Proprietary.Datarate; + break; + } + default: + break; + } + + // Filter fPorts + // TODO: Does not work with PROPRIETARY messages + // if( IsFPortAllowed( fPort ) == false ) + // { + // return LORAMAC_STATUS_PARAMETER_INVALID; + // } + + // Get the minimum possible datarate + getPhy.Attribute = PHY_MIN_TX_DR; + getPhy.UplinkDwellTime = params->sys_params.UplinkDwellTime; + phyParam = _lora_phy->get_phy_params(&getPhy); + + // Apply the minimum possible datarate. + // Some regions have limitations for the minimum datarate. + datarate = MAX(datarate, phyParam.Value); + + if (readyToSend == true) { + if (params->sys_params.AdrCtrlOn == false) { + verify.DatarateParams.Datarate = datarate; + verify.DatarateParams.UplinkDwellTime = + params->sys_params.UplinkDwellTime; + + if (_lora_phy->verify(&verify, PHY_TX_DR) == true) { + params->sys_params.ChannelsDatarate = + verify.DatarateParams.Datarate; + } else { + return LORAMAC_STATUS_PARAMETER_INVALID; + } + } + + status = _lora_mac->Send(&macHdr, fPort, fBuffer, fBufferSize); + if (status == LORAMAC_STATUS_OK) { + confirmation.McpsRequest = mcpsRequest->Type; + params->LoRaMacFlags.Bits.McpsReq = 1; + } else { + params->NodeAckRequested = false; + } + } + + return status; +} diff --git a/features/lorawan/lorastack/mac/LoRaMacMcps.h b/features/lorawan/lorastack/mac/LoRaMacMcps.h new file mode 100644 index 0000000000..4eb912ce40 --- /dev/null +++ b/features/lorawan/lorastack/mac/LoRaMacMcps.h @@ -0,0 +1,114 @@ +/** + / _____) _ | | +( (____ _____ ____ _| |_ _____ ____| |__ + \____ \| ___ | (_ _) ___ |/ ___) _ \ + _____) ) ____| | | || |_| ____( (___| | | | +(______/|_____)_|_|_| \__)_____)\____)_| |_| + (C)2013 Semtech + ___ _____ _ ___ _ _____ ___ ___ ___ ___ +/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| +\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| +|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| +embedded.connectivity.solutions=============== + +Description: LoRaWAN stack layer that controls both MAC and PHY underneath + +License: Revised BSD License, see LICENSE.TXT file include in the project + +Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE ) + + +Copyright (c) 2017, Arm Limited and affiliates. + +SPDX-License-Identifier: BSD-3-Clause +*/ + +#ifndef MBED_OS_LORAWAN_MAC_MCPS_H_ +#define MBED_OS_LORAWAN_MAC_MCPS_H_ + +#include "lorawan/system/lorawan_data_structures.h" +#include "lorastack/phy/LoRaPHY.h" + +// forward declaration +class LoRaMac; + +class LoRaMacMcps { + +public: + + /** Constructor + * + * Sets local handles to NULL. These handles will be set when the subsystem + * is activated by the MAC layer. + */ + LoRaMacMcps(); + + /** Destructor + * + * Does nothing + */ + ~LoRaMacMcps(); + + /** Activating MCPS subsystem + * + * Stores pointers to MAC and PHY layer handles + * + * @param mac pointer to MAC layer + * @param phy pointer to PHY layer + * @param cmd pointer to MAC commands + */ + void activate_mcps_subsystem(LoRaMac *mac, LoRaPHY *phy); + + /** Sets up an MCPS Request + * + * Sets up an MCPS 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 mcpsRequest pointer to MCPS request structure + * @param params pointer to MAC protocol parameters + * + * @return LORA_MAC_STATUS_OK if everything goes well otherwise + * a negative error code is returned. + */ + LoRaMacStatus_t set_request(McpsReq_t *mcpsRequest, lora_mac_protocol_params *params); + + /** Grants access to MCPS confirmation data + * + * @return a reference to MCPS confirm data structure + */ + inline McpsConfirm_t& get_confirmation() + { + return confirmation; + } + + /** Grants access to MCPS indication data + * + * @return a reference to MCPS indication data structure + */ + inline McpsIndication_t& get_indication() + { + return indication; + } + + +private: + + /** + * Pointers to MAC and PHY handles + */ + LoRaMac *_lora_mac; + LoRaPHY *_lora_phy; + + /** + * Structure to hold MCPS indication data. + */ + McpsIndication_t indication; + + /** + * Structure to hold MCPS confirm data. + */ + McpsConfirm_t confirmation; +}; + +#endif /* MBED_OS_LORAWAN_MAC_MCPS_H_ */ From 49885d2bbaabe000226d880d53fafe93aba8f651 Mon Sep 17 00:00:00 2001 From: Hasnain Virk Date: Tue, 9 Jan 2018 16:40:25 +0200 Subject: [PATCH 08/23] Changing MLME data access methods to inline As indicated in one of the reveiws, it makes more sense to change the data access methods to inline as they are just one liners. --- features/lorawan/lorastack/mac/LoRaMacMlme.cpp | 10 ---------- features/lorawan/lorastack/mac/LoRaMacMlme.h | 11 ++++++++--- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/features/lorawan/lorastack/mac/LoRaMacMlme.cpp b/features/lorawan/lorastack/mac/LoRaMacMlme.cpp index e42f4eb28f..00a6e5455f 100644 --- a/features/lorawan/lorastack/mac/LoRaMacMlme.cpp +++ b/features/lorawan/lorastack/mac/LoRaMacMlme.cpp @@ -151,13 +151,3 @@ LoRaMacStatus_t LoRaMacMlme::set_request(MlmeReq_t *mlmeRequest, return LORAMAC_STATUS_PARAMETER_INVALID; } - -MlmeIndication_t& LoRaMacMlme::get_indication() -{ - return indication; -} - -MlmeConfirm_t& LoRaMacMlme::get_confirmation() -{ - return confirmation; -} diff --git a/features/lorawan/lorastack/mac/LoRaMacMlme.h b/features/lorawan/lorastack/mac/LoRaMacMlme.h index 978a88a5e1..6a80073201 100644 --- a/features/lorawan/lorastack/mac/LoRaMacMlme.h +++ b/features/lorawan/lorastack/mac/LoRaMacMlme.h @@ -78,14 +78,19 @@ public: * * @return a reference to MLME confirm data structure */ - MlmeConfirm_t& get_confirmation(); + inline MlmeConfirm_t& get_confirmation() + { + return confirmation; + } /** Grants access to MLME indication data * * @return a reference to MLME indication data structure */ - MlmeIndication_t& get_indication(); - + inline MlmeIndication_t& get_indication() + { + return indication; + } private: From b47c59ce2a14070602f586b843f15bde294b491d Mon Sep 17 00:00:00 2001 From: Hasnain Virk Date: Tue, 9 Jan 2018 17:46:19 +0200 Subject: [PATCH 09/23] [IOTCELL-288] Adding MIB subsystem As a part of MAC layer breakdown into independent subsystems, we have introduced a class for MIB service. Major changes from the baseline are: - making OpenRxWindow() public in LoRaMac.cpp - Moving various data structures to central protocol data structure --- features/lorawan/lorastack/mac/LoRaMac.cpp | 558 ++---------------- features/lorawan/lorastack/mac/LoRaMac.h | 30 +- features/lorawan/lorastack/mac/LoRaMacMcps.h | 1 - features/lorawan/lorastack/mac/LoRaMacMib.cpp | 475 +++++++++++++++ features/lorawan/lorastack/mac/LoRaMacMib.h | 100 ++++ features/lorawan/lorastack/phy/lora_phy_ds.h | 51 -- .../lorawan/system/lorawan_data_structures.h | 62 ++ 7 files changed, 695 insertions(+), 582 deletions(-) create mode 100644 features/lorawan/lorastack/mac/LoRaMacMib.cpp create mode 100644 features/lorawan/lorastack/mac/LoRaMacMib.h diff --git a/features/lorawan/lorastack/mac/LoRaMac.cpp b/features/lorawan/lorastack/mac/LoRaMac.cpp index fcd48705f2..187d5a7b64 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.cpp +++ b/features/lorawan/lorastack/mac/LoRaMac.cpp @@ -115,7 +115,7 @@ LoRaMac::LoRaMac(LoRaWANTimeHandler &lora_time) _params.AckTimeoutRetry = false; _params.timers.TxTimeOnAir = 0; - MulticastChannels = NULL; + _params.MulticastChannels = NULL; _params.sys_params.AdrCtrlOn = false; _params.sys_params.MaxDCycle = 0; @@ -443,7 +443,7 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 if( address != _params.LoRaMacDevAddr ) { - curMulticastParams = MulticastChannels; + curMulticastParams = _params.MulticastChannels; while( curMulticastParams != NULL ) { if( address == curMulticastParams->Address ) @@ -1090,45 +1090,45 @@ void LoRaMac::OnRxWindow1TimerEvent( void ) _lora_time.TimerStop( &_params.timers.RxWindowTimer1 ); _params.RxSlot = RX_SLOT_WIN_1; - RxWindow1Config.Channel = _params.Channel; - RxWindow1Config.DrOffset = _params.sys_params.Rx1DrOffset; - RxWindow1Config.DownlinkDwellTime = _params.sys_params.DownlinkDwellTime; - RxWindow1Config.RepeaterSupport = _params.RepeaterSupport; - RxWindow1Config.RxContinuous = false; - RxWindow1Config.RxSlot = _params.RxSlot; + _params.RxWindow1Config.Channel = _params.Channel; + _params.RxWindow1Config.DrOffset = _params.sys_params.Rx1DrOffset; + _params.RxWindow1Config.DownlinkDwellTime = _params.sys_params.DownlinkDwellTime; + _params.RxWindow1Config.RepeaterSupport = _params.RepeaterSupport; + _params.RxWindow1Config.RxContinuous = false; + _params.RxWindow1Config.RxSlot = _params.RxSlot; if( _params.LoRaMacDeviceClass == CLASS_C ) { lora_phy->put_radio_to_standby(); } - lora_phy->rx_config(&RxWindow1Config, ( int8_t* )&mcps.get_indication().RxDatarate); - RxWindowSetup( RxWindow1Config.RxContinuous, _params.sys_params.MaxRxWindow ); + lora_phy->rx_config(&_params.RxWindow1Config, ( int8_t* )&mcps.get_indication().RxDatarate); + RxWindowSetup( _params.RxWindow1Config.RxContinuous, _params.sys_params.MaxRxWindow ); } void LoRaMac::OnRxWindow2TimerEvent( void ) { _lora_time.TimerStop( &_params.timers.RxWindowTimer2 ); - RxWindow2Config.Channel = _params.Channel; - RxWindow2Config.Frequency = _params.sys_params.Rx2Channel.Frequency; - RxWindow2Config.DownlinkDwellTime = _params.sys_params.DownlinkDwellTime; - RxWindow2Config.RepeaterSupport = _params.RepeaterSupport; - RxWindow2Config.RxSlot = RX_SLOT_WIN_2; + _params.RxWindow2Config.Channel = _params.Channel; + _params.RxWindow2Config.Frequency = _params.sys_params.Rx2Channel.Frequency; + _params.RxWindow2Config.DownlinkDwellTime = _params.sys_params.DownlinkDwellTime; + _params.RxWindow2Config.RepeaterSupport = _params.RepeaterSupport; + _params.RxWindow2Config.RxSlot = RX_SLOT_WIN_2; if( _params.LoRaMacDeviceClass != CLASS_C ) { - RxWindow2Config.RxContinuous = false; + _params.RxWindow2Config.RxContinuous = false; } else { // Setup continuous listening for class c - RxWindow2Config.RxContinuous = true; + _params.RxWindow2Config.RxContinuous = true; } - if(lora_phy->rx_config(&RxWindow2Config, ( int8_t* )&mcps.get_indication().RxDatarate) == true ) + if(lora_phy->rx_config(&_params.RxWindow2Config, ( int8_t* )&mcps.get_indication().RxDatarate) == true ) { - RxWindowSetup( RxWindow2Config.RxContinuous, _params.sys_params.MaxRxWindow ); + RxWindowSetup( _params.RxWindow2Config.RxContinuous, _params.sys_params.MaxRxWindow ); _params.RxSlot = RX_SLOT_WIN_2; } } @@ -1267,17 +1267,17 @@ LoRaMacStatus_t LoRaMac::ScheduleTx( void ) lora_phy->compute_rx_win_params(dr_offset, _params.sys_params.MinRxSymbols, _params.sys_params.SystemMaxRxError, - &RxWindow1Config ); + &_params.RxWindow1Config ); // Compute Rx2 windows parameters lora_phy->compute_rx_win_params(_params.sys_params.Rx2Channel.Datarate, _params.sys_params.MinRxSymbols, _params.sys_params.SystemMaxRxError, - &RxWindow2Config ); + &_params.RxWindow2Config ); if( _params.IsLoRaMacNetworkJoined == false ) { - _params.RxWindow1Delay = _params.sys_params.JoinAcceptDelay1 + RxWindow1Config.WindowOffset; - _params.RxWindow2Delay = _params.sys_params.JoinAcceptDelay2 + RxWindow2Config.WindowOffset; + _params.RxWindow1Delay = _params.sys_params.JoinAcceptDelay1 + _params.RxWindow1Config.WindowOffset; + _params.RxWindow2Delay = _params.sys_params.JoinAcceptDelay2 + _params.RxWindow2Config.WindowOffset; } else { @@ -1287,8 +1287,8 @@ LoRaMacStatus_t LoRaMac::ScheduleTx( void ) { return LORAMAC_STATUS_LENGTH_ERROR; } - _params.RxWindow1Delay = _params.sys_params.ReceiveDelay1 + RxWindow1Config.WindowOffset; - _params.RxWindow2Delay = _params.sys_params.ReceiveDelay2 + RxWindow2Config.WindowOffset; + _params.RxWindow1Delay = _params.sys_params.ReceiveDelay1 + _params.RxWindow1Config.WindowOffset; + _params.RxWindow2Delay = _params.sys_params.ReceiveDelay2 + _params.RxWindow2Config.WindowOffset; } // Schedule transmission of frame @@ -1367,7 +1367,7 @@ void LoRaMac::ResetMacParameters( void ) _params.SrvAckRequested = false; // Reset Multicast downlink counters - MulticastParams_t *cur = MulticastChannels; + MulticastParams_t *cur = _params.MulticastChannels; while( cur != NULL ) { cur->DownLinkCounter = 0; @@ -1701,6 +1701,9 @@ LoRaMacStatus_t LoRaMac::LoRaMacInitialization(LoRaMacPrimitives_t *primitives, // Activate MCPS subsystem mcps.activate_mcps_subsystem(this, lora_phy); + // Activate MIB subsystem + mib.activate_mib_subsystem(this, lora_phy); + LoRaMacPrimitives = primitives; LoRaMacCallbacks = callbacks; @@ -1886,485 +1889,6 @@ LoRaMacStatus_t LoRaMac::LoRaMacQueryTxPossible( uint8_t size, LoRaMacTxInfo_t* return LORAMAC_STATUS_OK; } -LoRaMacStatus_t LoRaMac::LoRaMacMibGetRequestConfirm( MibRequestConfirm_t *mibGet ) -{ - LoRaMacStatus_t status = LORAMAC_STATUS_OK; - GetPhyParams_t getPhy; - PhyParam_t phyParam; - - if( mibGet == NULL ) - { - return LORAMAC_STATUS_PARAMETER_INVALID; - } - - switch( mibGet->Type ) - { - case MIB_DEVICE_CLASS: - { - mibGet->Param.Class = _params.LoRaMacDeviceClass; - break; - } - case MIB_NETWORK_JOINED: - { - mibGet->Param.IsNetworkJoined = _params.IsLoRaMacNetworkJoined; - break; - } - case MIB_ADR: - { - mibGet->Param.AdrEnable = _params.sys_params.AdrCtrlOn; - break; - } - case MIB_NET_ID: - { - mibGet->Param.NetID = _params.LoRaMacNetID; - break; - } - case MIB_DEV_ADDR: - { - mibGet->Param.DevAddr = _params.LoRaMacDevAddr; - break; - } - case MIB_NWK_SKEY: - { - mibGet->Param.NwkSKey =_params.keys.LoRaMacNwkSKey; - break; - } - case MIB_APP_SKEY: - { - mibGet->Param.AppSKey = _params.keys.LoRaMacAppSKey; - break; - } - case MIB_PUBLIC_NETWORK: - { - mibGet->Param.EnablePublicNetwork = _params.PublicNetwork; - break; - } - case MIB_REPEATER_SUPPORT: - { - mibGet->Param.EnableRepeaterSupport = _params.RepeaterSupport; - break; - } - case MIB_CHANNELS: - { - getPhy.Attribute = PHY_CHANNELS; - phyParam = lora_phy->get_phy_params( &getPhy ); - - mibGet->Param.ChannelList = phyParam.Channels; - break; - } - case MIB_RX2_CHANNEL: - { - mibGet->Param.Rx2Channel = _params.sys_params.Rx2Channel; - break; - } - case MIB_RX2_DEFAULT_CHANNEL: - { - mibGet->Param.Rx2Channel = _params.def_sys_params.Rx2Channel; - break; - } - case MIB_CHANNELS_DEFAULT_MASK: - { - getPhy.Attribute = PHY_CHANNELS_DEFAULT_MASK; - phyParam = lora_phy->get_phy_params( &getPhy ); - - mibGet->Param.ChannelsDefaultMask = phyParam.ChannelsMask; - break; - } - case MIB_CHANNELS_MASK: - { - getPhy.Attribute = PHY_CHANNELS_MASK; - phyParam = lora_phy->get_phy_params( &getPhy ); - - mibGet->Param.ChannelsMask = phyParam.ChannelsMask; - break; - } - case MIB_CHANNELS_NB_REP: - { - mibGet->Param.ChannelNbRep = _params.sys_params.ChannelsNbRep; - break; - } - case MIB_MAX_RX_WINDOW_DURATION: - { - mibGet->Param.MaxRxWindow = _params.sys_params.MaxRxWindow; - break; - } - case MIB_RECEIVE_DELAY_1: - { - mibGet->Param.ReceiveDelay1 = _params.sys_params.ReceiveDelay1; - break; - } - case MIB_RECEIVE_DELAY_2: - { - mibGet->Param.ReceiveDelay2 = _params.sys_params.ReceiveDelay2; - break; - } - case MIB_JOIN_ACCEPT_DELAY_1: - { - mibGet->Param.JoinAcceptDelay1 = _params.sys_params.JoinAcceptDelay1; - break; - } - case MIB_JOIN_ACCEPT_DELAY_2: - { - mibGet->Param.JoinAcceptDelay2 = _params.sys_params.JoinAcceptDelay2; - break; - } - case MIB_CHANNELS_DEFAULT_DATARATE: - { - mibGet->Param.ChannelsDefaultDatarate = _params.def_sys_params.ChannelsDatarate; - break; - } - case MIB_CHANNELS_DATARATE: - { - mibGet->Param.ChannelsDatarate = _params.sys_params.ChannelsDatarate; - break; - } - case MIB_CHANNELS_DEFAULT_TX_POWER: - { - mibGet->Param.ChannelsDefaultTxPower = _params.def_sys_params.ChannelsTxPower; - break; - } - case MIB_CHANNELS_TX_POWER: - { - mibGet->Param.ChannelsTxPower = _params.sys_params.ChannelsTxPower; - break; - } - case MIB_UPLINK_COUNTER: - { - mibGet->Param.UpLinkCounter = _params.UpLinkCounter; - break; - } - case MIB_DOWNLINK_COUNTER: - { - mibGet->Param.DownLinkCounter = _params.DownLinkCounter; - break; - } - case MIB_MULTICAST_CHANNEL: - { - mibGet->Param.MulticastList = MulticastChannels; - break; - } - case MIB_SYSTEM_MAX_RX_ERROR: - { - mibGet->Param.SystemMaxRxError = _params.sys_params.SystemMaxRxError; - break; - } - case MIB_MIN_RX_SYMBOLS: - { - mibGet->Param.MinRxSymbols = _params.sys_params.MinRxSymbols; - break; - } - case MIB_ANTENNA_GAIN: - { - mibGet->Param.AntennaGain = _params.sys_params.AntennaGain; - break; - } - default: - status = LORAMAC_STATUS_SERVICE_UNKNOWN; - break; - } - - return status; -} - -LoRaMacStatus_t LoRaMac::LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSet ) -{ - LoRaMacStatus_t status = LORAMAC_STATUS_OK; - ChanMaskSetParams_t chanMaskSet; - VerifyParams_t verify; - - if( mibSet == NULL ) - { - return LORAMAC_STATUS_PARAMETER_INVALID; - } - - switch( mibSet->Type ) - { - case MIB_DEVICE_CLASS: - { - _params.LoRaMacDeviceClass = mibSet->Param.Class; - switch( _params.LoRaMacDeviceClass ) - { - case CLASS_A: - { - // Set the radio into sleep to setup a defined state - lora_phy->put_radio_to_sleep(); - break; - } - case CLASS_B: - { - break; - } - case CLASS_C: - { - // Set the NodeAckRequested indicator to default - _params.NodeAckRequested = false; - // Set the radio into sleep mode in case we are still in RX mode - lora_phy->put_radio_to_sleep(); - // Compute Rx2 windows parameters in case the RX2 datarate has changed - lora_phy->compute_rx_win_params( _params.sys_params.Rx2Channel.Datarate, - _params.sys_params.MinRxSymbols, - _params.sys_params.SystemMaxRxError, - &RxWindow2Config ); - OpenContinuousRx2Window( ); - break; - } - } - break; - } - case MIB_NETWORK_JOINED: - { - _params.IsLoRaMacNetworkJoined = mibSet->Param.IsNetworkJoined; - break; - } - case MIB_ADR: - { - _params.sys_params.AdrCtrlOn = mibSet->Param.AdrEnable; - break; - } - case MIB_NET_ID: - { - _params.LoRaMacNetID = mibSet->Param.NetID; - break; - } - case MIB_DEV_ADDR: - { - _params.LoRaMacDevAddr = mibSet->Param.DevAddr; - break; - } - case MIB_NWK_SKEY: - { - if( mibSet->Param.NwkSKey != NULL ) - { - memcpy( _params.keys.LoRaMacNwkSKey, mibSet->Param.NwkSKey, - sizeof( _params.keys.LoRaMacNwkSKey ) ); - } - else - { - status = LORAMAC_STATUS_PARAMETER_INVALID; - } - break; - } - case MIB_APP_SKEY: - { - if( mibSet->Param.AppSKey != NULL ) - { - memcpy( _params.keys.LoRaMacAppSKey, mibSet->Param.AppSKey, - sizeof( _params.keys.LoRaMacAppSKey ) ); - } - else - { - status = LORAMAC_STATUS_PARAMETER_INVALID; - } - break; - } - case MIB_PUBLIC_NETWORK: - { - _params.PublicNetwork = mibSet->Param.EnablePublicNetwork; - lora_phy->setup_public_network_mode(_params.PublicNetwork); - break; - } - case MIB_REPEATER_SUPPORT: - { - _params.RepeaterSupport = mibSet->Param.EnableRepeaterSupport; - break; - } - case MIB_RX2_CHANNEL: - { - verify.DatarateParams.Datarate = mibSet->Param.Rx2Channel.Datarate; - verify.DatarateParams.DownlinkDwellTime = _params.sys_params.DownlinkDwellTime; - - if( lora_phy->verify(&verify, PHY_RX_DR) == true ) - { - _params.sys_params.Rx2Channel = mibSet->Param.Rx2Channel; - - if( ( _params.LoRaMacDeviceClass == CLASS_C ) && - ( _params.IsLoRaMacNetworkJoined == true ) ) - { - // We can only compute the RX window parameters directly, if we are already - // in class c mode and joined. We cannot setup an RX window in case of any other - // class type. - // Set the radio into sleep mode in case we are still in RX mode - lora_phy->put_radio_to_sleep(); - // Compute Rx2 windows parameters - lora_phy->compute_rx_win_params(_params.sys_params.Rx2Channel.Datarate, - _params.sys_params.MinRxSymbols, - _params.sys_params.SystemMaxRxError, - &RxWindow2Config); - - OpenContinuousRx2Window( ); - } - } - else - { - status = LORAMAC_STATUS_PARAMETER_INVALID; - } - break; - } - case MIB_RX2_DEFAULT_CHANNEL: - { - verify.DatarateParams.Datarate = mibSet->Param.Rx2Channel.Datarate; - verify.DatarateParams.DownlinkDwellTime = _params.sys_params.DownlinkDwellTime; - - if( lora_phy->verify(&verify, PHY_RX_DR) == true ) - { - _params.def_sys_params.Rx2Channel = mibSet->Param.Rx2DefaultChannel; - } - else - { - status = LORAMAC_STATUS_PARAMETER_INVALID; - } - break; - } - case MIB_CHANNELS_DEFAULT_MASK: - { - chanMaskSet.ChannelsMaskIn = mibSet->Param.ChannelsMask; - chanMaskSet.ChannelsMaskType = CHANNELS_DEFAULT_MASK; - - if(lora_phy->set_channel_mask(&chanMaskSet) == false ) - { - status = LORAMAC_STATUS_PARAMETER_INVALID; - } - break; - } - case MIB_CHANNELS_MASK: - { - chanMaskSet.ChannelsMaskIn = mibSet->Param.ChannelsMask; - chanMaskSet.ChannelsMaskType = CHANNELS_MASK; - - if(lora_phy->set_channel_mask(&chanMaskSet) == false ) - { - status = LORAMAC_STATUS_PARAMETER_INVALID; - } - break; - } - case MIB_CHANNELS_NB_REP: - { - if( ( mibSet->Param.ChannelNbRep >= 1 ) && - ( mibSet->Param.ChannelNbRep <= 15 ) ) - { - _params.sys_params.ChannelsNbRep = mibSet->Param.ChannelNbRep; - } - else - { - status = LORAMAC_STATUS_PARAMETER_INVALID; - } - break; - } - case MIB_MAX_RX_WINDOW_DURATION: - { - _params.sys_params.MaxRxWindow = mibSet->Param.MaxRxWindow; - break; - } - case MIB_RECEIVE_DELAY_1: - { - _params.sys_params.ReceiveDelay1 = mibSet->Param.ReceiveDelay1; - break; - } - case MIB_RECEIVE_DELAY_2: - { - _params.sys_params.ReceiveDelay2 = mibSet->Param.ReceiveDelay2; - break; - } - case MIB_JOIN_ACCEPT_DELAY_1: - { - _params.sys_params.JoinAcceptDelay1 = mibSet->Param.JoinAcceptDelay1; - break; - } - case MIB_JOIN_ACCEPT_DELAY_2: - { - _params.sys_params.JoinAcceptDelay2 = mibSet->Param.JoinAcceptDelay2; - break; - } - case MIB_CHANNELS_DEFAULT_DATARATE: - { - verify.DatarateParams.Datarate = mibSet->Param.ChannelsDefaultDatarate; - - if(lora_phy->verify(&verify, PHY_DEF_TX_DR) == true) - { - _params.def_sys_params.ChannelsDatarate = verify.DatarateParams.Datarate; - } - else - { - status = LORAMAC_STATUS_PARAMETER_INVALID; - } - break; - } - case MIB_CHANNELS_DATARATE: - { - verify.DatarateParams.Datarate = mibSet->Param.ChannelsDatarate; - verify.DatarateParams.UplinkDwellTime = _params.sys_params.UplinkDwellTime; - - if(lora_phy->verify(&verify, PHY_TX_DR) == true) - { - _params.sys_params.ChannelsDatarate = verify.DatarateParams.Datarate; - } - else - { - status = LORAMAC_STATUS_PARAMETER_INVALID; - } - break; - } - case MIB_CHANNELS_DEFAULT_TX_POWER: - { - verify.TxPower = mibSet->Param.ChannelsDefaultTxPower; - - if(lora_phy->verify(&verify, PHY_DEF_TX_POWER) == true) - { - _params.def_sys_params.ChannelsTxPower = verify.TxPower; - } - else - { - status = LORAMAC_STATUS_PARAMETER_INVALID; - } - break; - } - case MIB_CHANNELS_TX_POWER: - { - verify.TxPower = mibSet->Param.ChannelsTxPower; - - if(lora_phy->verify(&verify, PHY_TX_POWER) == true) - { - _params.sys_params.ChannelsTxPower = verify.TxPower; - } - else - { - status = LORAMAC_STATUS_PARAMETER_INVALID; - } - break; - } - case MIB_UPLINK_COUNTER: - { - _params.UpLinkCounter = mibSet->Param.UpLinkCounter; - break; - } - case MIB_DOWNLINK_COUNTER: - { - _params.DownLinkCounter = mibSet->Param.DownLinkCounter; - break; - } - case MIB_SYSTEM_MAX_RX_ERROR: - { - _params.sys_params.SystemMaxRxError = _params.def_sys_params.SystemMaxRxError = mibSet->Param.SystemMaxRxError; - break; - } - case MIB_MIN_RX_SYMBOLS: - { - _params.sys_params.MinRxSymbols = _params.def_sys_params.MinRxSymbols = mibSet->Param.MinRxSymbols; - break; - } - case MIB_ANTENNA_GAIN: - { - _params.sys_params.AntennaGain = mibSet->Param.AntennaGain; - break; - } - default: - status = LORAMAC_STATUS_SERVICE_UNKNOWN; - break; - } - - return status; -} - LoRaMacStatus_t LoRaMac::LoRaMacChannelAdd( uint8_t id, ChannelParams_t params ) { ChannelAddParams_t channelAdd; @@ -2422,14 +1946,14 @@ LoRaMacStatus_t LoRaMac::LoRaMacMulticastChannelLink( MulticastParams_t *channel // Reset downlink counter channelParam->DownLinkCounter = 0; - if( MulticastChannels == NULL ) + if( _params.MulticastChannels == NULL ) { // New node is the fist element - MulticastChannels = channelParam; + _params.MulticastChannels = channelParam; } else { - MulticastParams_t *cur = MulticastChannels; + MulticastParams_t *cur = _params.MulticastChannels; // Search the last node in the list while( cur->Next != NULL ) @@ -2454,16 +1978,16 @@ LoRaMacStatus_t LoRaMac::LoRaMacMulticastChannelUnlink( MulticastParams_t *chann return LORAMAC_STATUS_BUSY; } - if( MulticastChannels != NULL ) + if( _params.MulticastChannels != NULL ) { - if( MulticastChannels == channelParam ) + if( _params.MulticastChannels == channelParam ) { // First element - MulticastChannels = channelParam->Next; + _params.MulticastChannels = channelParam->Next; } else { - MulticastParams_t *cur = MulticastChannels; + MulticastParams_t *cur = _params.MulticastChannels; // Search the node in the list while( cur->Next && cur->Next != channelParam ) @@ -2492,6 +2016,16 @@ LoRaMacStatus_t LoRaMac::LoRaMacMcpsRequest( McpsReq_t *mcpsRequest ) return mcps.set_request(mcpsRequest, &_params); } +LoRaMacStatus_t LoRaMac::LoRaMacMibGetRequestConfirm( MibRequestConfirm_t *mibGet ) +{ + return mib.get_request(mibGet, &_params); +} + +LoRaMacStatus_t LoRaMac::LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSet ) +{ + return mib.set_request(mibSet, &_params); +} + radio_events_t *LoRaMac::GetPhyEventHandlers() { RadioEvents.tx_done = mbed::callback(this, &LoRaMac::handle_tx_done); diff --git a/features/lorawan/lorastack/mac/LoRaMac.h b/features/lorawan/lorastack/mac/LoRaMac.h index b3ba9ded12..74bd006815 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.h +++ b/features/lorawan/lorastack/mac/LoRaMac.h @@ -48,6 +48,7 @@ #include "events/EventQueue.h" #include "lorastack/mac/LoRaMacMlme.h" #include "lorastack/mac/LoRaMacMcps.h" +#include "lorastack/mac/LoRaMacMib.h" /*! * Maximum PHY layer payload size */ @@ -370,6 +371,12 @@ public: */ void ResetMacParameters( void ); + /*! + * \brief Opens up a continuous RX 2 window. This is used for + * class c devices. + */ + void OpenContinuousRx2Window(void); + #if defined(LORAWAN_COMPLIANCE_TEST) public: // Test interface @@ -579,12 +586,6 @@ private: */ bool IsFPortAllowed( uint8_t fPort ); - /*! - * \brief Opens up a continuous RX 2 window. This is used for - * class c devices. - */ - void OpenContinuousRx2Window(void); - /** * Prototypes for ISR handlers */ @@ -624,6 +625,11 @@ private: */ LoRaMacMcps mcps; + /** + * MCPS subsystem handle + */ + LoRaMacMib mib; + /** * Timer subsystem handle */ @@ -639,11 +645,6 @@ private: */ radio_events_t RadioEvents; - /*! - * Multicast channels linked list - */ - MulticastParams_t *MulticastChannels; - /*! * LoRaMac upper layer event functions */ @@ -653,13 +654,6 @@ private: * LoRaMac upper layer callback functions */ LoRaMacCallback_t *LoRaMacCallbacks; - - /*! - * Receive Window configurations for PHY layer - */ - RxConfigParams_t RxWindow1Config; - RxConfigParams_t RxWindow2Config; - }; #endif // __LORAMAC_H__ diff --git a/features/lorawan/lorastack/mac/LoRaMacMcps.h b/features/lorawan/lorastack/mac/LoRaMacMcps.h index 4eb912ce40..e73ba57856 100644 --- a/features/lorawan/lorastack/mac/LoRaMacMcps.h +++ b/features/lorawan/lorastack/mac/LoRaMacMcps.h @@ -55,7 +55,6 @@ public: * * @param mac pointer to MAC layer * @param phy pointer to PHY layer - * @param cmd pointer to MAC commands */ void activate_mcps_subsystem(LoRaMac *mac, LoRaPHY *phy); diff --git a/features/lorawan/lorastack/mac/LoRaMacMib.cpp b/features/lorawan/lorastack/mac/LoRaMacMib.cpp new file mode 100644 index 0000000000..dd726e0faa --- /dev/null +++ b/features/lorawan/lorastack/mac/LoRaMacMib.cpp @@ -0,0 +1,475 @@ +/** + / _____) _ | | +( (____ _____ ____ _| |_ _____ ____| |__ + \____ \| ___ | (_ _) ___ |/ ___) _ \ + _____) ) ____| | | || |_| ____( (___| | | | +(______/|_____)_|_|_| \__)_____)\____)_| |_| + (C)2013 Semtech + ___ _____ _ ___ _ _____ ___ ___ ___ ___ +/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| +\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| +|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| +embedded.connectivity.solutions=============== + +Description: LoRaWAN stack layer that controls both MAC and PHY underneath + +License: Revised BSD License, see LICENSE.TXT file include in the project + +Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE ) + + +Copyright (c) 2017, Arm Limited and affiliates. + +SPDX-License-Identifier: BSD-3-Clause +*/ + +#include "lorastack/mac/LoRaMac.h" +#include "lorastack/mac/LoRaMacMib.h" + +LoRaMacMib::LoRaMacMib() +: _lora_mac(NULL), _lora_phy(NULL) +{ +} + +LoRaMacMib::~LoRaMacMib() +{ +} + +void LoRaMacMib::activate_mib_subsystem(LoRaMac *mac, LoRaPHY *phy) +{ + _lora_mac = mac; + _lora_phy = phy; +} + +LoRaMacStatus_t LoRaMacMib::set_request(MibRequestConfirm_t *mibSet, + lora_mac_protocol_params *params) +{ + if (mibSet == NULL || _lora_phy == NULL || _lora_mac == NULL) { + return LORAMAC_STATUS_PARAMETER_INVALID; + } + + LoRaMacStatus_t status = LORAMAC_STATUS_OK; + ChanMaskSetParams_t chanMaskSet; + VerifyParams_t verify; + + + switch (mibSet->Type) { + case MIB_DEVICE_CLASS: { + params->LoRaMacDeviceClass = mibSet->Param.Class; + switch (params->LoRaMacDeviceClass) { + case CLASS_A: { + // Set the radio into sleep to setup a defined state + _lora_phy->put_radio_to_sleep(); + break; + } + case CLASS_B: { + break; + } + case CLASS_C: { + // Set the NodeAckRequested indicator to default + params->NodeAckRequested = false; + // Set the radio into sleep mode in case we are still in RX mode + _lora_phy->put_radio_to_sleep(); + // Compute Rx2 windows parameters in case the RX2 datarate has changed + _lora_phy->compute_rx_win_params( + params->sys_params.Rx2Channel.Datarate, + params->sys_params.MinRxSymbols, + params->sys_params.SystemMaxRxError, + ¶ms->RxWindow2Config); + _lora_mac->OpenContinuousRx2Window(); + break; + } + } + break; + } + case MIB_NETWORK_JOINED: { + params->IsLoRaMacNetworkJoined = mibSet->Param.IsNetworkJoined; + break; + } + case MIB_ADR: { + params->sys_params.AdrCtrlOn = mibSet->Param.AdrEnable; + break; + } + case MIB_NET_ID: { + params->LoRaMacNetID = mibSet->Param.NetID; + break; + } + case MIB_DEV_ADDR: { + params->LoRaMacDevAddr = mibSet->Param.DevAddr; + break; + } + case MIB_NWK_SKEY: { + if (mibSet->Param.NwkSKey != NULL) { + memcpy(params->keys.LoRaMacNwkSKey, mibSet->Param.NwkSKey, + sizeof(params->keys.LoRaMacNwkSKey)); + } else { + status = LORAMAC_STATUS_PARAMETER_INVALID; + } + break; + } + case MIB_APP_SKEY: { + if (mibSet->Param.AppSKey != NULL) { + memcpy(params->keys.LoRaMacAppSKey, mibSet->Param.AppSKey, + sizeof(params->keys.LoRaMacAppSKey)); + } else { + status = LORAMAC_STATUS_PARAMETER_INVALID; + } + break; + } + case MIB_PUBLIC_NETWORK: { + params->PublicNetwork = mibSet->Param.EnablePublicNetwork; + _lora_phy->setup_public_network_mode(params->PublicNetwork); + break; + } + case MIB_REPEATER_SUPPORT: { + params->RepeaterSupport = mibSet->Param.EnableRepeaterSupport; + break; + } + case MIB_RX2_CHANNEL: { + verify.DatarateParams.Datarate = mibSet->Param.Rx2Channel.Datarate; + verify.DatarateParams.DownlinkDwellTime = + params->sys_params.DownlinkDwellTime; + + if (_lora_phy->verify(&verify, PHY_RX_DR) == true) { + params->sys_params.Rx2Channel = mibSet->Param.Rx2Channel; + + if ((params->LoRaMacDeviceClass == CLASS_C) + && (params->IsLoRaMacNetworkJoined == true)) { + // We can only compute the RX window parameters directly, if we are already + // in class c mode and joined. We cannot setup an RX window in case of any other + // class type. + // Set the radio into sleep mode in case we are still in RX mode + _lora_phy->put_radio_to_sleep(); + // Compute Rx2 windows parameters + _lora_phy->compute_rx_win_params( + params->sys_params.Rx2Channel.Datarate, + params->sys_params.MinRxSymbols, + params->sys_params.SystemMaxRxError, + ¶ms->RxWindow2Config); + + _lora_mac->OpenContinuousRx2Window(); + } + } else { + status = LORAMAC_STATUS_PARAMETER_INVALID; + } + break; + } + case MIB_RX2_DEFAULT_CHANNEL: { + verify.DatarateParams.Datarate = mibSet->Param.Rx2Channel.Datarate; + verify.DatarateParams.DownlinkDwellTime = + params->sys_params.DownlinkDwellTime; + + if (_lora_phy->verify(&verify, PHY_RX_DR) == true) { + params->def_sys_params.Rx2Channel = + mibSet->Param.Rx2DefaultChannel; + } else { + status = LORAMAC_STATUS_PARAMETER_INVALID; + } + break; + } + case MIB_CHANNELS_DEFAULT_MASK: { + chanMaskSet.ChannelsMaskIn = mibSet->Param.ChannelsMask; + chanMaskSet.ChannelsMaskType = CHANNELS_DEFAULT_MASK; + + if (_lora_phy->set_channel_mask(&chanMaskSet) == false) { + status = LORAMAC_STATUS_PARAMETER_INVALID; + } + break; + } + case MIB_CHANNELS_MASK: { + chanMaskSet.ChannelsMaskIn = mibSet->Param.ChannelsMask; + chanMaskSet.ChannelsMaskType = CHANNELS_MASK; + + if (_lora_phy->set_channel_mask(&chanMaskSet) == false) { + status = LORAMAC_STATUS_PARAMETER_INVALID; + } + break; + } + case MIB_CHANNELS_NB_REP: { + if ((mibSet->Param.ChannelNbRep >= 1) + && (mibSet->Param.ChannelNbRep <= 15)) { + params->sys_params.ChannelsNbRep = mibSet->Param.ChannelNbRep; + } else { + status = LORAMAC_STATUS_PARAMETER_INVALID; + } + break; + } + case MIB_MAX_RX_WINDOW_DURATION: { + params->sys_params.MaxRxWindow = mibSet->Param.MaxRxWindow; + break; + } + case MIB_RECEIVE_DELAY_1: { + params->sys_params.ReceiveDelay1 = mibSet->Param.ReceiveDelay1; + break; + } + case MIB_RECEIVE_DELAY_2: { + params->sys_params.ReceiveDelay2 = mibSet->Param.ReceiveDelay2; + break; + } + case MIB_JOIN_ACCEPT_DELAY_1: { + params->sys_params.JoinAcceptDelay1 = + mibSet->Param.JoinAcceptDelay1; + break; + } + case MIB_JOIN_ACCEPT_DELAY_2: { + params->sys_params.JoinAcceptDelay2 = + mibSet->Param.JoinAcceptDelay2; + break; + } + case MIB_CHANNELS_DEFAULT_DATARATE: { + verify.DatarateParams.Datarate = + mibSet->Param.ChannelsDefaultDatarate; + + if (_lora_phy->verify(&verify, PHY_DEF_TX_DR) == true) { + params->def_sys_params.ChannelsDatarate = + verify.DatarateParams.Datarate; + } else { + status = LORAMAC_STATUS_PARAMETER_INVALID; + } + break; + } + case MIB_CHANNELS_DATARATE: { + verify.DatarateParams.Datarate = mibSet->Param.ChannelsDatarate; + verify.DatarateParams.UplinkDwellTime = + params->sys_params.UplinkDwellTime; + + if (_lora_phy->verify(&verify, PHY_TX_DR) == true) { + params->sys_params.ChannelsDatarate = + verify.DatarateParams.Datarate; + } else { + status = LORAMAC_STATUS_PARAMETER_INVALID; + } + break; + } + case MIB_CHANNELS_DEFAULT_TX_POWER: { + verify.TxPower = mibSet->Param.ChannelsDefaultTxPower; + + if (_lora_phy->verify(&verify, PHY_DEF_TX_POWER) == true) { + params->def_sys_params.ChannelsTxPower = verify.TxPower; + } else { + status = LORAMAC_STATUS_PARAMETER_INVALID; + } + break; + } + case MIB_CHANNELS_TX_POWER: { + verify.TxPower = mibSet->Param.ChannelsTxPower; + + if (_lora_phy->verify(&verify, PHY_TX_POWER) == true) { + params->sys_params.ChannelsTxPower = verify.TxPower; + } else { + status = LORAMAC_STATUS_PARAMETER_INVALID; + } + break; + } + case MIB_UPLINK_COUNTER: { + params->UpLinkCounter = mibSet->Param.UpLinkCounter; + break; + } + case MIB_DOWNLINK_COUNTER: { + params->DownLinkCounter = mibSet->Param.DownLinkCounter; + break; + } + case MIB_SYSTEM_MAX_RX_ERROR: { + params->sys_params.SystemMaxRxError = + params->def_sys_params.SystemMaxRxError = + mibSet->Param.SystemMaxRxError; + break; + } + case MIB_MIN_RX_SYMBOLS: { + params->sys_params.MinRxSymbols = + params->def_sys_params.MinRxSymbols = + mibSet->Param.MinRxSymbols; + break; + } + case MIB_ANTENNA_GAIN: { + params->sys_params.AntennaGain = mibSet->Param.AntennaGain; + break; + } + default: + status = LORAMAC_STATUS_SERVICE_UNKNOWN; + break; + } + + return status; +} + +LoRaMacStatus_t LoRaMacMib::get_request(MibRequestConfirm_t *mibGet, + lora_mac_protocol_params *params) +{ + LoRaMacStatus_t status = LORAMAC_STATUS_OK; + GetPhyParams_t getPhy; + PhyParam_t phyParam; + + if( mibGet == NULL ) + { + return LORAMAC_STATUS_PARAMETER_INVALID; + } + + switch( mibGet->Type ) + { + case MIB_DEVICE_CLASS: + { + mibGet->Param.Class = params->LoRaMacDeviceClass; + break; + } + case MIB_NETWORK_JOINED: + { + mibGet->Param.IsNetworkJoined = params->IsLoRaMacNetworkJoined; + break; + } + case MIB_ADR: + { + mibGet->Param.AdrEnable = params->sys_params.AdrCtrlOn; + break; + } + case MIB_NET_ID: + { + mibGet->Param.NetID = params->LoRaMacNetID; + break; + } + case MIB_DEV_ADDR: + { + mibGet->Param.DevAddr = params->LoRaMacDevAddr; + break; + } + case MIB_NWK_SKEY: + { + mibGet->Param.NwkSKey =params->keys.LoRaMacNwkSKey; + break; + } + case MIB_APP_SKEY: + { + mibGet->Param.AppSKey = params->keys.LoRaMacAppSKey; + break; + } + case MIB_PUBLIC_NETWORK: + { + mibGet->Param.EnablePublicNetwork = params->PublicNetwork; + break; + } + case MIB_REPEATER_SUPPORT: + { + mibGet->Param.EnableRepeaterSupport = params->RepeaterSupport; + break; + } + case MIB_CHANNELS: + { + getPhy.Attribute = PHY_CHANNELS; + phyParam = _lora_phy->get_phy_params( &getPhy ); + + mibGet->Param.ChannelList = phyParam.Channels; + break; + } + case MIB_RX2_CHANNEL: + { + mibGet->Param.Rx2Channel = params->sys_params.Rx2Channel; + break; + } + case MIB_RX2_DEFAULT_CHANNEL: + { + mibGet->Param.Rx2Channel = params->def_sys_params.Rx2Channel; + break; + } + case MIB_CHANNELS_DEFAULT_MASK: + { + getPhy.Attribute = PHY_CHANNELS_DEFAULT_MASK; + phyParam = _lora_phy->get_phy_params( &getPhy ); + + mibGet->Param.ChannelsDefaultMask = phyParam.ChannelsMask; + break; + } + case MIB_CHANNELS_MASK: + { + getPhy.Attribute = PHY_CHANNELS_MASK; + phyParam = _lora_phy->get_phy_params( &getPhy ); + + mibGet->Param.ChannelsMask = phyParam.ChannelsMask; + break; + } + case MIB_CHANNELS_NB_REP: + { + mibGet->Param.ChannelNbRep = params->sys_params.ChannelsNbRep; + break; + } + case MIB_MAX_RX_WINDOW_DURATION: + { + mibGet->Param.MaxRxWindow = params->sys_params.MaxRxWindow; + break; + } + case MIB_RECEIVE_DELAY_1: + { + mibGet->Param.ReceiveDelay1 = params->sys_params.ReceiveDelay1; + break; + } + case MIB_RECEIVE_DELAY_2: + { + mibGet->Param.ReceiveDelay2 = params->sys_params.ReceiveDelay2; + break; + } + case MIB_JOIN_ACCEPT_DELAY_1: + { + mibGet->Param.JoinAcceptDelay1 = params->sys_params.JoinAcceptDelay1; + break; + } + case MIB_JOIN_ACCEPT_DELAY_2: + { + mibGet->Param.JoinAcceptDelay2 = params->sys_params.JoinAcceptDelay2; + break; + } + case MIB_CHANNELS_DEFAULT_DATARATE: + { + mibGet->Param.ChannelsDefaultDatarate = params->def_sys_params.ChannelsDatarate; + break; + } + case MIB_CHANNELS_DATARATE: + { + mibGet->Param.ChannelsDatarate = params->sys_params.ChannelsDatarate; + break; + } + case MIB_CHANNELS_DEFAULT_TX_POWER: + { + mibGet->Param.ChannelsDefaultTxPower = params->def_sys_params.ChannelsTxPower; + break; + } + case MIB_CHANNELS_TX_POWER: + { + mibGet->Param.ChannelsTxPower = params->sys_params.ChannelsTxPower; + break; + } + case MIB_UPLINK_COUNTER: + { + mibGet->Param.UpLinkCounter = params->UpLinkCounter; + break; + } + case MIB_DOWNLINK_COUNTER: + { + mibGet->Param.DownLinkCounter = params->DownLinkCounter; + break; + } + case MIB_MULTICAST_CHANNEL: + { + mibGet->Param.MulticastList = params->MulticastChannels; + break; + } + case MIB_SYSTEM_MAX_RX_ERROR: + { + mibGet->Param.SystemMaxRxError = params->sys_params.SystemMaxRxError; + break; + } + case MIB_MIN_RX_SYMBOLS: + { + mibGet->Param.MinRxSymbols = params->sys_params.MinRxSymbols; + break; + } + case MIB_ANTENNA_GAIN: + { + mibGet->Param.AntennaGain = params->sys_params.AntennaGain; + break; + } + default: + status = LORAMAC_STATUS_SERVICE_UNKNOWN; + break; + } + + return status; +} diff --git a/features/lorawan/lorastack/mac/LoRaMacMib.h b/features/lorawan/lorastack/mac/LoRaMacMib.h new file mode 100644 index 0000000000..0cbf7f7ed9 --- /dev/null +++ b/features/lorawan/lorastack/mac/LoRaMacMib.h @@ -0,0 +1,100 @@ +/** + / _____) _ | | +( (____ _____ ____ _| |_ _____ ____| |__ + \____ \| ___ | (_ _) ___ |/ ___) _ \ + _____) ) ____| | | || |_| ____( (___| | | | +(______/|_____)_|_|_| \__)_____)\____)_| |_| + (C)2013 Semtech + ___ _____ _ ___ _ _____ ___ ___ ___ ___ +/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| +\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| +|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| +embedded.connectivity.solutions=============== + +Description: LoRaWAN stack layer that controls both MAC and PHY underneath + +License: Revised BSD License, see LICENSE.TXT file include in the project + +Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE ) + + +Copyright (c) 2017, Arm Limited and affiliates. + +SPDX-License-Identifier: BSD-3-Clause +*/ + +#ifndef MBED_OS_LORAWAN_MAC_MIB_H_ +#define MBED_OS_LORAWAN_MAC_MIB_H_ + +#include "lorawan/system/lorawan_data_structures.h" +#include "lorastack/phy/LoRaPHY.h" + +// forward declaration +class LoRaMac; + +class LoRaMacMib { + +public: + + /** Constructor + * + * Sets local handles to NULL. These handles will be set when the subsystem + * is activated by the MAC layer. + */ + LoRaMacMib(); + + /** Destructor + * + * Does nothing + */ + ~LoRaMacMib(); + + /** Activating MLME subsystem + * + * Stores pointers to MAC and PHY layer handles + * + * @param mac pointer to MAC layer + * @param phy pointer to PHY layer + */ + void activate_mib_subsystem(LoRaMac *mac, LoRaPHY *phy); + + /** Sets up a MIB Request + * + * Used to configure MAC protocol parameters using appropriate + * key/value pair in the MIB request structure. Use this API to set + * any system wide configurable parameter exposed by MIB service. + * + * @param mibSet [in] pointer to MIB request structure + * @param params pointer to MAC protocol parameters which will be modified + * + * @return LORA_MAC_STATUS_OK if everything goes well otherwise + * a negative error code is returned. + */ + LoRaMacStatus_t set_request(MibRequestConfirm_t *mibSet, lora_mac_protocol_params *params); + + /** Provides access to the given MIB parameter + * + * Used to extract information about system wide MAC protocol parameters + * which are exposed by MIB service. + * + * @param mibGet [out] pointer to MIB request structure which will be filled in + * @param params pointer to MAC protocol parameters + * + * @return LORA_MAC_STATUS_OK if everything goes well otherwise + * a negative error code is returned. + */ + LoRaMacStatus_t get_request(MibRequestConfirm_t *mibGet, lora_mac_protocol_params *params); + +private: + + /** + * Pointers to MAC and PHY handles + */ + LoRaMac *_lora_mac; + LoRaPHY *_lora_phy; +}; + + + + +#endif /* MBED_OS_LORAWAN_MAC_MIB_H_ */ diff --git a/features/lorawan/lorastack/phy/lora_phy_ds.h b/features/lorawan/lorastack/phy/lora_phy_ds.h index c3a4a53db0..3a9c10d9c7 100644 --- a/features/lorawan/lorastack/phy/lora_phy_ds.h +++ b/features/lorawan/lorastack/phy/lora_phy_ds.h @@ -862,57 +862,6 @@ typedef struct sAdrNextParams uint8_t UplinkDwellTime; }AdrNextParams_t; -/*! - * The parameter structure for the function RegionRxConfig. - */ -typedef struct sRxConfigParams -{ - /*! - * The RX channel. - */ - uint8_t Channel; - /*! - * The RX datarate. - */ - int8_t Datarate; - /*! - * The RX bandwidth. - */ - uint8_t Bandwidth; - /*! - * The RX datarate offset. - */ - int8_t DrOffset; - /*! - * The RX frequency. - */ - uint32_t Frequency; - /*! - * The RX window timeout - */ - uint32_t WindowTimeout; - /*! - * The RX window offset - */ - int32_t WindowOffset; - /*! - * The downlink dwell time. - */ - uint8_t DownlinkDwellTime; - /*! - * Set to true, if a repeater is supported. - */ - bool RepeaterSupport; - /*! - * Set to true, if RX should be continuous. - */ - bool RxContinuous; - /*! - * Sets the RX window. - */ - LoRaMacRxSlot_t RxSlot; -}RxConfigParams_t; - /*! * The parameter structure for the function RegionTxConfig. */ diff --git a/features/lorawan/system/lorawan_data_structures.h b/features/lorawan/system/lorawan_data_structures.h index 915f48707c..7538e853e6 100644 --- a/features/lorawan/system/lorawan_data_structures.h +++ b/features/lorawan/system/lorawan_data_structures.h @@ -2941,6 +2941,57 @@ typedef struct loramac_downlink_status { uint8_t buffer_size; } loramac_downlink_status_t; +/*! + * The parameter structure for the function RegionRxConfig. + */ +typedef struct sRxConfigParams +{ + /*! + * The RX channel. + */ + uint8_t Channel; + /*! + * The RX datarate. + */ + int8_t Datarate; + /*! + * The RX bandwidth. + */ + uint8_t Bandwidth; + /*! + * The RX datarate offset. + */ + int8_t DrOffset; + /*! + * The RX frequency. + */ + uint32_t Frequency; + /*! + * The RX window timeout + */ + uint32_t WindowTimeout; + /*! + * The RX window offset + */ + int32_t WindowOffset; + /*! + * The downlink dwell time. + */ + uint8_t DownlinkDwellTime; + /*! + * Set to true, if a repeater is supported. + */ + bool RepeaterSupport; + /*! + * Set to true, if RX should be continuous. + */ + bool RxContinuous; + /*! + * Sets the RX window. + */ + LoRaMacRxSlot_t RxSlot; +}RxConfigParams_t; + /*! * \brief Timer object description */ @@ -3228,6 +3279,17 @@ typedef struct { */ lora_mac_system_params_t def_sys_params; + /*! + * Receive Window configurations for PHY layer + */ + RxConfigParams_t RxWindow1Config; + RxConfigParams_t RxWindow2Config; + + /*! + * Multicast channels linked list + */ + MulticastParams_t *MulticastChannels; + } lora_mac_protocol_params; /** LoRaWAN callback functions From 34c034dfffd1f655dd9dbd378a3b0de0736b72e9 Mon Sep 17 00:00:00 2001 From: Kimmo Vaisanen Date: Thu, 11 Jan 2018 11:49:52 +0200 Subject: [PATCH 10/23] Remove duplicate configuration flags This commit changes code to use directly mbed os configuration system generated compilation flags. --- features/lorawan/LoRaWANInterface.cpp | 18 +- features/lorawan/LoRaWANStack.cpp | 32 +-- features/lorawan/lorastack/mac/LoRaMac.cpp | 6 +- features/lorawan/lorastack/mac/LoRaMac.h | 4 - features/lorawan/mbed_lib.json | 12 +- .../lorawan/system/lorawan_data_structures.h | 190 ++---------------- 6 files changed, 47 insertions(+), 215 deletions(-) diff --git a/features/lorawan/LoRaWANInterface.cpp b/features/lorawan/LoRaWANInterface.cpp index 0e1268a876..0e9887cfc8 100644 --- a/features/lorawan/LoRaWANInterface.cpp +++ b/features/lorawan/LoRaWANInterface.cpp @@ -61,10 +61,10 @@ lora_mac_status_t LoRaWANInterface::connect() lorawan_connect_t connection_params; - if (OVER_THE_AIR_ACTIVATION != 0) { - static uint8_t dev_eui[] = LORAWAN_DEVICE_EUI; - static uint8_t app_eui[] = LORAWAN_APPLICATION_EUI; - static uint8_t app_key[] = LORAWAN_APPLICATION_KEY; + if (MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION) { + static uint8_t dev_eui[] = MBED_CONF_LORA_DEVICE_EUI; + static uint8_t app_eui[] = MBED_CONF_LORA_APPLICATION_EUI; + static uint8_t app_key[] = MBED_CONF_LORA_APPLICATION_KEY; /** * * OTAA join @@ -73,14 +73,14 @@ lora_mac_status_t LoRaWANInterface::connect() connection_params.connection_u.otaa.app_eui = app_eui; connection_params.connection_u.otaa.dev_eui = dev_eui; connection_params.connection_u.otaa.app_key = app_key; - connection_params.connection_u.otaa.nb_trials = LORAWAN_NB_TRIALS; + connection_params.connection_u.otaa.nb_trials = MBED_CONF_LORA_NB_TRIALS; return connect(connection_params); } else { - static uint8_t nwk_skey[] = LORAWAN_NWKSKEY; - static uint8_t app_skey[] = LORAWAN_APPSKEY; - static uint32_t dev_addr = LORAWAN_DEVICE_ADDRESS; - static uint32_t nwk_id = (LORAWAN_DEVICE_ADDRESS & LORAWAN_NETWORK_ID_MASK); + static uint8_t nwk_skey[] = MBED_CONF_LORA_NWKSKEY; + static uint8_t app_skey[] = MBED_CONF_LORA_APPSKEY; + static uint32_t dev_addr = MBED_CONF_LORA_DEVICE_ADDRESS; + static uint32_t nwk_id = (MBED_CONF_LORA_DEVICE_ADDRESS & LORAWAN_NETWORK_ID_MASK); /** * diff --git a/features/lorawan/LoRaWANStack.cpp b/features/lorawan/LoRaWANStack.cpp index 1fb676228f..106c3784aa 100644 --- a/features/lorawan/LoRaWANStack.cpp +++ b/features/lorawan/LoRaWANStack.cpp @@ -94,7 +94,7 @@ lora_mac_status_t LoRaWANStack::set_application_port(uint8_t port) LoRaWANStack::LoRaWANStack() : _loramac(_lora_time), _lora_phy(_lora_time), _device_current_state(DEVICE_STATE_NOT_INITIALIZED), _mac_handlers(NULL), - _num_retry(1), _queue(NULL), _duty_cycle_on(LORAWAN_DUTYCYCLE_ON) + _num_retry(1), _queue(NULL), _duty_cycle_on(MBED_CONF_LORA_DUTY_CYCLE_ON) { #ifdef MBED_CONF_LORA_APP_PORT // is_port_valid() is not virtual, so we can call it in constructor @@ -152,7 +152,7 @@ lora_mac_status_t LoRaWANStack::initialize_mac_layer(EventQueue *queue) static lora_mac_mib_request_confirm_t mib_req; #if defined(LORAWAN_COMPLIANCE_TEST) - static uint8_t compliance_test_buffer[LORAWAN_TX_MAX_SIZE]; + static uint8_t compliance_test_buffer[MBED_CONF_LORA_TX_MAX_SIZE]; #endif tr_debug("Initializing MAC layer"); @@ -174,11 +174,11 @@ lora_mac_status_t LoRaWANStack::initialize_mac_layer(EventQueue *queue) _loramac.LoRaMacInitialization(&LoRaMacPrimitives, &LoRaMacCallbacks, &_lora_phy, queue); mib_req.type = LORA_MIB_ADR; - mib_req.param.adr_enable = LORAWAN_ADR_ON; + mib_req.param.adr_enable = MBED_CONF_LORA_ADR_ON; mib_set_request(&mib_req); mib_req.type = LORA_MIB_PUBLIC_NETWORK; - mib_req.param.enable_public_network = LORAWAN_PUBLIC_NETWORK; + mib_req.param.enable_public_network = MBED_CONF_LORA_PUBLIC_NETWORK; mib_set_request(&mib_req); // Reset counters to zero. Will change in future with 1.1 support. @@ -217,7 +217,7 @@ void LoRaWANStack::prepare_special_tx_frame(uint8_t port) _tx_msg.f_buffer_size = _compliance_test.app_data_size; _tx_msg.f_buffer[0] = _compliance_test.app_data_buffer[0]; - for(uint8_t i = 1; i < MIN(_compliance_test.app_data_size, LORAWAN_TX_MAX_SIZE); ++i) { + for(uint8_t i = 1; i < MIN(_compliance_test.app_data_size, MBED_CONF_LORA_TX_MAX_SIZE); ++i) { _tx_msg.f_buffer[i] = _compliance_test.app_data_buffer[i]; } break; @@ -838,13 +838,13 @@ int16_t LoRaWANStack::handle_tx(uint8_t port, const uint8_t* data, uint16_t max_possible_size = check_possible_tx_size(length); - if (max_possible_size > LORAWAN_TX_MAX_SIZE) { + if (max_possible_size > MBED_CONF_LORA_TX_MAX_SIZE) { // LORAWAN_APP_DATA_MAX_SIZE should at least be // either equal to or bigger than maximum possible // tx size because our tx message buffer takes its // length from that macro. Force maximum possible tx unit // to be equal to the buffer size user chose. - max_possible_size = LORAWAN_TX_MAX_SIZE; + max_possible_size = MBED_CONF_LORA_TX_MAX_SIZE; } if (max_possible_size < length) { @@ -1118,8 +1118,8 @@ void LoRaWANStack::mcps_confirm_handler(lora_mac_mcps_confirm_t *mcps_confirm) // or some other error happened. Discard buffer, unset the tx-ongoing // flag and let the application know _tx_msg.tx_ongoing = false; - memset(_tx_msg.f_buffer, 0, LORAWAN_TX_MAX_SIZE); - _tx_msg.f_buffer_size = LORAWAN_TX_MAX_SIZE; + memset(_tx_msg.f_buffer, 0, MBED_CONF_LORA_TX_MAX_SIZE); + _tx_msg.f_buffer_size = MBED_CONF_LORA_TX_MAX_SIZE; tr_error("mcps_confirm_handler: Error code = %d", mcps_confirm->status); @@ -1309,17 +1309,17 @@ void LoRaWANStack::compliance_test_handler(lora_mac_mcps_indication_t *mcps_indi switch (_compliance_test.state) { case 0: // Check compliance test disable command (ii) _compliance_test.is_tx_confirmed = true; - _compliance_test.app_port = LORAWAN_APP_PORT; + _compliance_test.app_port = MBED_CONF_LORA_APP_PORT; _compliance_test.app_data_size = LORAWAN_COMPLIANCE_TEST_DATA_SIZE; _compliance_test.downlink_counter = 0; _compliance_test.running = false; lora_mac_mib_request_confirm_t mib_req; mib_req.type = LORA_MIB_ADR; - mib_req.param.adr_enable = LORAWAN_ADR_ON; + mib_req.param.adr_enable = MBED_CONF_LORA_ADR_ON; mib_set_request(&mib_req); #if MBED_CONF_LORA_PHY == 0 - _loramac.LoRaMacTestSetDutyCycleOn(LORAWAN_DUTYCYCLE_ON); + _loramac.LoRaMacTestSetDutyCycleOn(MBED_CONF_LORA_DUTY_CYCLE_ON); #endif // Go to idle state after compliance test mode. tr_debug("Compliance test disabled."); @@ -1362,16 +1362,16 @@ void LoRaWANStack::compliance_test_handler(lora_mac_mcps_indication_t *mcps_indi // Disable TestMode and revert back to normal operation _compliance_test.is_tx_confirmed = true; - _compliance_test.app_port = LORAWAN_APP_PORT; + _compliance_test.app_port = MBED_CONF_LORA_APP_PORT; _compliance_test.app_data_size = LORAWAN_COMPLIANCE_TEST_DATA_SIZE; _compliance_test.downlink_counter = 0; _compliance_test.running = false; mib_request.type = LORA_MIB_ADR; - mib_request.param.adr_enable = LORAWAN_ADR_ON; + mib_request.param.adr_enable = MBED_CONF_LORA_ADR_ON; mib_set_request(&mib_request); #if MBED_CONF_LORA_PHY == 0 - _loramac.LoRaMacTestSetDutyCycleOn(LORAWAN_DUTYCYCLE_ON); + _loramac.LoRaMacTestSetDutyCycleOn(MBED_CONF_LORA_DUTY_CYCLE_ON); #endif mlme_request.type = LORA_MLME_JOIN; mlme_request.req.join.dev_eui = _lw_session.connection.connection_u.otaa.dev_eui; @@ -1828,7 +1828,7 @@ lora_mac_status_t LoRaWANStack::lora_state_machine() mib_set_request(&mib_req); // reset buffers to original state - memset(_tx_msg.f_buffer, 0, LORAWAN_TX_MAX_SIZE); + memset(_tx_msg.f_buffer, 0, MBED_CONF_LORA_TX_MAX_SIZE); _tx_msg.pending_size = 0; _tx_msg.f_buffer_size = 0; _tx_msg.tx_ongoing = false; diff --git a/features/lorawan/lorastack/mac/LoRaMac.cpp b/features/lorawan/lorastack/mac/LoRaMac.cpp index 187d5a7b64..f1b5c28cec 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.cpp +++ b/features/lorawan/lorastack/mac/LoRaMac.cpp @@ -1243,7 +1243,7 @@ LoRaMacStatus_t LoRaMac::ScheduleTx( void ) nextChan.AggrTimeOff = _params.timers.AggregatedTimeOff; nextChan.Datarate = _params.sys_params.ChannelsDatarate; - _params.DutyCycleOn = LORAWAN_DUTYCYCLE_ON; + _params.DutyCycleOn = MBED_CONF_LORA_DUTY_CYCLE_ON; nextChan.DutyCycleEnabled = _params.DutyCycleOn; nextChan.Joined = _params.IsLoRaMacNetworkJoined; nextChan.LastAggrTx = _params.timers.AggregatedLastTxDoneTime; @@ -1315,7 +1315,7 @@ void LoRaMac::CalculateBackOff( uint8_t channel ) CalcBackOffParams_t calcBackOff; calcBackOff.Joined = _params.IsLoRaMacNetworkJoined; - _params.DutyCycleOn = LORAWAN_DUTYCYCLE_ON; + _params.DutyCycleOn = MBED_CONF_LORA_DUTY_CYCLE_ON; calcBackOff.DutyCycleEnabled = _params.DutyCycleOn; calcBackOff.Channel = channel; calcBackOff.ElapsedTime = _lora_time.TimerGetElapsedTime( _params.timers.LoRaMacInitializationTime ); @@ -1803,7 +1803,7 @@ LoRaMacStatus_t LoRaMac::LoRaMacInitialization(LoRaMacPrimitives_t *primitives, // Random seed initialization srand(lora_phy->get_radio_rng()); - _params.PublicNetwork = LORAWAN_PUBLIC_NETWORK; + _params.PublicNetwork = MBED_CONF_LORA_PUBLIC_NETWORK; lora_phy->setup_public_network_mode(_params.PublicNetwork); lora_phy->put_radio_to_sleep(); diff --git a/features/lorawan/lorastack/mac/LoRaMac.h b/features/lorawan/lorastack/mac/LoRaMac.h index 74bd006815..21580a1447 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.h +++ b/features/lorawan/lorastack/mac/LoRaMac.h @@ -49,10 +49,6 @@ #include "lorastack/mac/LoRaMacMlme.h" #include "lorastack/mac/LoRaMacMcps.h" #include "lorastack/mac/LoRaMacMib.h" -/*! - * Maximum PHY layer payload size - */ -#define LORAMAC_PHY_MAXPAYLOAD 255 class LoRaMac diff --git a/features/lorawan/mbed_lib.json b/features/lorawan/mbed_lib.json index df3e3ee9af..0a7f80776d 100644 --- a/features/lorawan/mbed_lib.json +++ b/features/lorawan/mbed_lib.json @@ -25,10 +25,6 @@ "help": "AES encryption/decryption cipher application key", "value": "{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}" }, - "network-id": { - "help": "Current network ID", - "value": 0 - }, "device-address": { "help": "Device address on the network", "value": "0x00000000" @@ -58,12 +54,12 @@ "value": true }, "duty-cycle-on": { - "help": "Enables/disables duty cycling. NOTE: Disable only for testing. Mandatory in many regions.", - "value": true + "help": "Enables/disables duty cycling. NOTE: Disable only for testing. Mandatory in many regions.", + "value": true }, "lbt-on": { - "help": "Enables/disables LBT. NOTE: [This feature is not yet integrated].", - "value": false + "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 7538e853e6..b1d48845e3 100644 --- a/features/lorawan/system/lorawan_data_structures.h +++ b/features/lorawan/system/lorawan_data_structures.h @@ -90,6 +90,20 @@ typedef uint32_t TimerTime_t; */ #define LORA_MAX_NB_CHANNELS 16 +/** + * Maximum PHY layer payload size for reception. + */ +#define LORAMAC_PHY_MAXPAYLOAD 255 + +/** + * + * Default user application maximum data size for transmission + */ +// reject if user tries to set more than MTU +#if MBED_CONF_LORA_TX_MAX_SIZE > 255 + #warning "Cannot set TX Max size more than MTU=255" +#endif + /*! * LoRaWAN device classes definition. * @@ -1706,180 +1720,6 @@ typedef struct sLoRaMacCallback }LoRaMacCallback_t; -/** - * The AES encryption/decryption cipher application session key. - */ -#ifdef MBED_CONF_LORA_APPSKEY -#define LORAWAN_APPSKEY MBED_CONF_LORA_APPSKEY -#else -#define LORAWAN_APPSKEY {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} -#endif - -/** - * The AES encryption/decryption cipher network session key. - */ -#ifdef MBED_CONF_LORA_NWKSKEY -#define LORAWAN_NWKSKEY MBED_CONF_LORA_NWKSKEY -#else -#define LORAWAN_NWKSKEY {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} -#endif - -/** - * The device address on the network (big endian). - */ -#ifdef MBED_CONF_LORA_DEVICE_ADDRESS -#define LORAWAN_DEVICE_ADDRESS MBED_CONF_LORA_DEVICE_ADDRESS -#else -#define LORAWAN_DEVICE_ADDRESS 0 -#endif - -/** - * The current network ID. - */ -#ifdef MBED_CONF_LORA_NETWORK_ID -#define LORAWAN_NETWORK_ID MBED_CONF_LORA_NETWORK_ID -#else -#define LORAWAN_NETWORK_ID 0 -#endif - -/** - * The AES encryption/decryption cipher application key. - */ -#ifdef MBED_CONF_LORA_APPLICATION_KEY -#define LORAWAN_APPLICATION_KEY MBED_CONF_LORA_APPLICATION_KEY -#else -#define LORAWAN_APPLICATION_KEY {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} -#endif - -/** - * The application IEEE EUI. - */ - -#ifdef MBED_CONF_LORA_APPLICATION_EUI -#define LORAWAN_APPLICATION_EUI MBED_CONF_LORA_APPLICATION_EUI -#else -#define LORAWAN_APPLICATION_EUI {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} -#endif - -/** - * The mote device IEEE EUI. - */ -#ifdef MBED_CONF_LORA_DEVICE_EUI -#define LORAWAN_DEVICE_EUI MBED_CONF_LORA_DEVICE_EUI -#else -#define LORAWAN_DEVICE_EUI {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} -#endif - -/** - * Indicates how many times join can be tried. - */ -#ifdef MBED_CONF_LORA_NB_TRIALS -#define LORAWAN_NB_TRIALS MBED_CONF_LORA_NB_TRIALS -#else -#define LORAWAN_NB_TRIALS 8 -#endif - -/** - * When set to true, the application uses the Over-the-Air activation procedure. - */ -#if defined(MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION) == 1 -#define OVER_THE_AIR_ACTIVATION MBED_CONF_LORA_OVER_THE_AIR_ACTIVATION -#else -#define OVER_THE_AIR_ACTIVATION false -#endif - -/** - * LoRaWAN connects to a public network or private network, true = public network. - */ -#if defined(MBED_CONF_LORA_PUBLIC_NETWORK) == 1 -#define LORAWAN_PUBLIC_NETWORK MBED_CONF_LORA_PUBLIC_NETWORK -#else -#define LORAWAN_PUBLIC_NETWORK false -#endif - -/** - * Maximum PHY layer payload size for reception. - * This is not user configurable. Its hard coded in LoRaMac.cpp - * and we don't want to change that file too much - */ -#define LORAMAC_PHY_MAXPAYLOAD 255 - -/** - * - * Default user application maximum data size for trasnmission - */ -// reject if user tries to set more than MTU -#if defined MBED_CONF_LORA_TX_MAX_SIZE && MBED_CONF_LORA_TX_MAX_SIZE > 255 -#warning "Cannot set TX Max size more than MTU=255" -#define LORAWAN_TX_MAX_SIZE 255 -#elif defined MBED_CONF_LORA_TX_MAX_SIZE && MBED_CONF_LORA_TX_MAX_SIZE < 255 -#define LORAWAN_TX_MAX_SIZE MBED_CONF_LORA_TX_MAX_SIZE -#else -#define LORAWAN_TX_MAX_SIZE 64 -#endif - -/** - * - * Defines the application data transmission timer cycle, value in [ms] - * Used only when automatic duty cycling is off - */ -#ifdef MBED_CONF_APP_TX_TIMER -#define TX_TIMER MBED_CONF_APP_TX_TIMER -#else -#define TX_TIMER 5000 -#endif - -/** - * - * Defines a random delay for application data transmission cycle, value in [ms] - * Used only when automatic duty cycling is off - */ -#ifdef MBED_CONF_APP_TX_TIMER_RND -#define TX_TIMER_RND MBED_CONF_APP_TX_TIMER_RND -#else -#define TX_TIMER_RND 1000 -#endif - -/** - * - * LoRaWAN Adaptive Data Rate - * - * \remark Please note that when ADR is enabled, the end-device should be static. - */ -#if defined(MBED_CONF_LORA_ADR_ON) == 1 -#define LORAWAN_ADR_ON MBED_CONF_LORA_ADR_ON -#else -#define LORAWAN_ADR_ON false -#endif - -/** - * - * The default application port. - */ -#ifdef MBED_CONF_LORA_APP_PORT -#define LORAWAN_APP_PORT MBED_CONF_LORA_APP_PORT -#else -#define LORAWAN_APP_PORT 0x15 -#endif - -/** - * Default duty cycling setting - */ -#if defined(MBED_CONF_LORA_DUTY_CYCLE_ON) == 1 -#define LORAWAN_DUTYCYCLE_ON MBED_CONF_LORA_DUTY_CYCLE_ON -#else -#define LORAWAN_DUTYCYCLE_ON false -#endif - -/** - * Listen-before-talk setting - */ -#if defined(MBED_CONF_LORA_LBT_ON) == 1 -#define LORAWAN_LBT_ON MBED_CONF_LORA_LBT_ON -#else -#define LORAWAN_LBT_ON false -#endif - /** End-device states. * */ @@ -2100,7 +1940,7 @@ typedef struct lora_mac_tx_message { * * Base pointer to the buffer */ - uint8_t f_buffer[LORAWAN_TX_MAX_SIZE]; + uint8_t f_buffer[MBED_CONF_LORA_TX_MAX_SIZE]; /** Payload size. * From 6ea541c0540222b7282bea53a609a7efd1e70135 Mon Sep 17 00:00:00 2001 From: Hasnain Virk Date: Thu, 11 Jan 2018 13:55:08 +0200 Subject: [PATCH 11/23] [IOTCELL-286] Adding Channel Plan subsystem Channel planning was distributed over LoRaWANStack and LoRaMac previously. We now centralize it by allocating the service to its own class. Thus making the workflow consistent, i.e., Request for channel plan = Application->Interface->stack->Mac->ChannelPlan Major change apart from adding the channel plan subsystem are the API changes in LoRaMac class. --- features/lorawan/LoRaWANInterface.h | 3 + features/lorawan/LoRaWANStack.cpp | 157 +----------- features/lorawan/lorastack/mac/LoRaMac.cpp | 38 +-- features/lorawan/lorastack/mac/LoRaMac.h | 59 ++++- .../lorastack/mac/LoRaMacChannelPlan.cpp | 236 ++++++++++++++++++ .../lorastack/mac/LoRaMacChannelPlan.h | 115 +++++++++ 6 files changed, 429 insertions(+), 179 deletions(-) create mode 100644 features/lorawan/lorastack/mac/LoRaMacChannelPlan.cpp create mode 100644 features/lorawan/lorastack/mac/LoRaMacChannelPlan.h diff --git a/features/lorawan/LoRaWANInterface.h b/features/lorawan/LoRaWANInterface.h index 49c36678eb..ba722e50dd 100644 --- a/features/lorawan/LoRaWANInterface.h +++ b/features/lorawan/LoRaWANInterface.h @@ -226,6 +226,9 @@ public: * is already active, the request is silently ignored. A negative error * code is returned if there is any problem with parameters. * + * Please note that this API can also be used to add a single channel to the + * existing channel plan. + * * There is no reverse mechanism in the 1.0.2 specification for a node to request * a particular channel. Only the network server can initiate such a request. * You need to ensure that the corresponding base station supports the channel or channels being added. diff --git a/features/lorawan/LoRaWANStack.cpp b/features/lorawan/LoRaWANStack.cpp index 106c3784aa..fac53a1141 100644 --- a/features/lorawan/LoRaWANStack.cpp +++ b/features/lorawan/LoRaWANStack.cpp @@ -471,91 +471,19 @@ lora_mac_status_t LoRaWANStack::add_channels(const lora_channelplan_t &channel_p return LORA_MAC_STATUS_NOT_INITIALIZED; } - ChannelParams_t mac_layer_ch_params; - LoRaMacStatus_t status; + LoRaMacStatus_t status = _loramac.AddChannelPlan(channel_plan); - GetPhyParams_t get_phy; - PhyParam_t phy_param; - uint8_t max_num_channels; - - // Check first how many channels the selected PHY layer supports - get_phy.Attribute = PHY_MAX_NB_CHANNELS; - phy_param = _lora_phy.get_phy_params(&get_phy); - max_num_channels = (uint8_t) phy_param.Value; - - // check if user is setting more channels than supported - if (channel_plan.nb_channels > max_num_channels) { - return LORA_MAC_STATUS_PARAMETER_INVALID; - } - - for (uint8_t i = 0; i < channel_plan.nb_channels; i++) { - mac_layer_ch_params.Band = channel_plan.channels[i].ch_param.band; - mac_layer_ch_params.DrRange.Fields.Max = channel_plan.channels[i].ch_param.dr_range.lora_mac_fields_s.max; - mac_layer_ch_params.DrRange.Fields.Min = channel_plan.channels[i].ch_param.dr_range.lora_mac_fields_s.min; - mac_layer_ch_params.DrRange.Value = channel_plan.channels[i].ch_param.dr_range.value; - mac_layer_ch_params.Frequency = channel_plan.channels[i].ch_param.frequency; - mac_layer_ch_params.Rx1Frequency =channel_plan.channels[i].ch_param.rx1_frequency; - - status = _loramac.LoRaMacChannelAdd(channel_plan.channels[i].id, mac_layer_ch_params); - - if (status != LORAMAC_STATUS_OK) { - return error_type_converter(status); - } - } - - return LORA_MAC_STATUS_OK; + return error_type_converter(status); } lora_mac_status_t LoRaWANStack::drop_channel_list() { - if (_device_current_state == DEVICE_STATE_NOT_INITIALIZED ) - { + if (_device_current_state == DEVICE_STATE_NOT_INITIALIZED) { tr_error("Stack not initialized!"); return LORA_MAC_STATUS_NOT_INITIALIZED; } - lora_mac_status_t status = LORA_MAC_STATUS_OK; - - GetPhyParams_t get_phy; - PhyParam_t phy_param; - uint8_t max_num_channels; - uint16_t *channel_masks; - uint16_t *default_channel_masks; - - // Check first how many channels the selected PHY layer supports - get_phy.Attribute = PHY_MAX_NB_CHANNELS; - phy_param = _lora_phy.get_phy_params(&get_phy); - max_num_channels = (uint8_t) phy_param.Value; - - // Now check the channel mask for enabled channels - get_phy.Attribute = PHY_CHANNELS_MASK; - phy_param = _lora_phy.get_phy_params(&get_phy); - channel_masks = phy_param.ChannelsMask; - - // Now check the channel mask for default channels - get_phy.Attribute = PHY_CHANNELS_DEFAULT_MASK; - phy_param = _lora_phy.get_phy_params(&get_phy); - default_channel_masks = phy_param.ChannelsMask; - - for (uint8_t i = 0; i < max_num_channels; i++) { - // skip any default channels - if ((default_channel_masks[0] & (1U<= max_num_channels) { - return LORA_MAC_STATUS_PARAMETER_INVALID; - } - - // Now check the Default channel mask - get_phy.Attribute = PHY_CHANNELS_DEFAULT_MASK; - phy_param = _lora_phy.get_phy_params(&get_phy); - channel_masks = phy_param.ChannelsMask; - - // check if the channel ID give belongs to a default channel - // Mostly the default channels are in the first mask if the region - // have multiple channel masks for various sub-bands. So we check the first - // mask only and return an error code if user sent a default channel id - if ((channel_masks[0] & (1U << channel_id)) != 0) { - tr_error("Not allowed to remove a Default Channel."); - return LORA_MAC_STATUS_PARAMETER_INVALID; - } - - return error_type_converter(_loramac.LoRaMacChannelRemove(channel_id)); + return error_type_converter(_loramac.RemoveSingleChannel(channel_id)); } lora_mac_status_t LoRaWANStack::get_enabled_channels(lora_channelplan_t& channel_plan) @@ -610,49 +507,7 @@ lora_mac_status_t LoRaWANStack::get_enabled_channels(lora_channelplan_t& channel return LORA_MAC_STATUS_BUSY; } - lora_mac_mib_request_confirm_t mib_params; - - GetPhyParams_t get_phy; - PhyParam_t phy_param; - uint8_t max_num_channels; - uint16_t *channel_masks; - uint8_t count = 0; - - // Check first how many channels the selected PHY layer supports - get_phy.Attribute = PHY_MAX_NB_CHANNELS; - phy_param = _lora_phy.get_phy_params(&get_phy); - max_num_channels = (uint8_t) phy_param.Value; - - // Now check the Default channel mask - get_phy.Attribute = PHY_CHANNELS_MASK; - phy_param = _lora_phy.get_phy_params(&get_phy); - channel_masks = phy_param.ChannelsMask; - - // Request Mib to get channels - memset(&mib_params, 0, sizeof(mib_params)); - mib_params.type = LORA_MIB_CHANNELS; - mib_get_request(&mib_params); - - for (uint8_t i = 0; i < max_num_channels; i++) { - // skip the channels which are not enabled - if ((channel_masks[0] & (1U << i)) == 0) { - continue; - } - - // otherwise add them to the channel_plan struct - channel_plan.channels[count].id = i; - channel_plan.channels[count].ch_param.frequency = mib_params.param.channel_list[i].frequency; - channel_plan.channels[count].ch_param.dr_range.value = mib_params.param.channel_list[i].dr_range.value; - channel_plan.channels[count].ch_param.dr_range.lora_mac_fields_s.min = mib_params.param.channel_list[i].dr_range.lora_mac_fields_s.min; - channel_plan.channels[count].ch_param.dr_range.lora_mac_fields_s.max = mib_params.param.channel_list[i].dr_range.lora_mac_fields_s.max; - channel_plan.channels[count].ch_param.band = mib_params.param.channel_list[i].band; - channel_plan.channels[count].ch_param.rx1_frequency = mib_params.param.channel_list[i].rx1_frequency; - count++; - } - - channel_plan.nb_channels = count; - - return LORA_MAC_STATUS_OK; + return error_type_converter(_loramac.GetChannelPlan(channel_plan)); } lora_mac_status_t LoRaWANStack::enable_adaptive_datarate(bool adr_enabled) diff --git a/features/lorawan/lorastack/mac/LoRaMac.cpp b/features/lorawan/lorastack/mac/LoRaMac.cpp index f1b5c28cec..03201fa84d 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.cpp +++ b/features/lorawan/lorastack/mac/LoRaMac.cpp @@ -1704,6 +1704,9 @@ LoRaMacStatus_t LoRaMac::LoRaMacInitialization(LoRaMacPrimitives_t *primitives, // Activate MIB subsystem mib.activate_mib_subsystem(this, lora_phy); + // Activate channel planning subsystem + ch_plan.activate_channelplan_subsystem(lora_phy, &mib); + LoRaMacPrimitives = primitives; LoRaMacCallbacks = callbacks; @@ -1889,10 +1892,8 @@ LoRaMacStatus_t LoRaMac::LoRaMacQueryTxPossible( uint8_t size, LoRaMacTxInfo_t* return LORAMAC_STATUS_OK; } -LoRaMacStatus_t LoRaMac::LoRaMacChannelAdd( uint8_t id, ChannelParams_t params ) +LoRaMacStatus_t LoRaMac::AddChannelPlan(const lora_channelplan_t& plan) { - ChannelAddParams_t channelAdd; - // Validate if the MAC is in a correct state if( ( _params.LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) { @@ -1902,16 +1903,11 @@ LoRaMacStatus_t LoRaMac::LoRaMacChannelAdd( uint8_t id, ChannelParams_t params ) } } - channelAdd.NewChannel = ¶ms; - channelAdd.ChannelId = id; - - return lora_phy->add_channel(&channelAdd); + return ch_plan.set_plan(plan); } -LoRaMacStatus_t LoRaMac::LoRaMacChannelRemove( uint8_t id ) +LoRaMacStatus_t LoRaMac::RemoveChannelPlan() { - ChannelRemoveParams_t channelRemove; - if( ( _params.LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) { if( ( _params.LoRaMacState & LORAMAC_TX_CONFIG ) != LORAMAC_TX_CONFIG ) @@ -1920,16 +1916,26 @@ LoRaMacStatus_t LoRaMac::LoRaMacChannelRemove( uint8_t id ) } } - channelRemove.ChannelId = id; + return ch_plan.remove_plan(); - if(lora_phy->remove_channel(&channelRemove) == false) +} + +LoRaMacStatus_t LoRaMac::GetChannelPlan(lora_channelplan_t& plan) +{ + return ch_plan.get_plan(plan, &_params); +} + +LoRaMacStatus_t LoRaMac::RemoveSingleChannel(uint8_t id) +{ + if( ( _params.LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) { - return LORAMAC_STATUS_PARAMETER_INVALID; + if( ( _params.LoRaMacState & LORAMAC_TX_CONFIG ) != LORAMAC_TX_CONFIG ) + { + return LORAMAC_STATUS_BUSY; + } } - lora_phy->put_radio_to_sleep(); - - return LORAMAC_STATUS_OK; + return ch_plan.remove_single_channel(id); } LoRaMacStatus_t LoRaMac::LoRaMacMulticastChannelLink( MulticastParams_t *channelParam ) diff --git a/features/lorawan/lorastack/mac/LoRaMac.h b/features/lorawan/lorastack/mac/LoRaMac.h index 21580a1447..031ada4a2e 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.h +++ b/features/lorawan/lorastack/mac/LoRaMac.h @@ -49,7 +49,7 @@ #include "lorastack/mac/LoRaMacMlme.h" #include "lorastack/mac/LoRaMacMcps.h" #include "lorastack/mac/LoRaMacMib.h" - +#include "lorastack/mac/LoRaMacChannelPlan.h" class LoRaMac { @@ -117,27 +117,57 @@ public: LoRaMacStatus_t LoRaMacQueryTxPossible( uint8_t size, LoRaMacTxInfo_t* txInfo ); /*! - * \brief LoRaMAC channel add service. + * \brief Adds a channel plan to the system. * - * \details Adds a new channel to the channel list and activates the ID in - * the channel mask. Please note that this functionality is not available - * in all regions. Information on the allowed ranges is available at the LoRaWAN Regional Parameters V1.0.2rB. + * \details Adds a whole channel plan or a single new channel to the. + * Please note that this functionality is not available in all regions. + * Information on the allowed ranges is available at the + * LoRaWAN Regional Parameters V1.0.2rB. * - * \param id [in] - The ID of the channel. - * - * \param params [in] - The channel parameters to set. + * \param plan [in] - A reference to application provided channel plan. * * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: * \ref LORAMAC_STATUS_OK * \ref LORAMAC_STATUS_BUSY * \ref LORAMAC_STATUS_PARAMETER_INVALID */ - LoRaMacStatus_t LoRaMacChannelAdd( uint8_t id, ChannelParams_t params ); + LoRaMacStatus_t AddChannelPlan(const lora_channelplan_t& plan); /*! - * \brief LoRaMAC channel remove service. + * \brief Removes a channel plan from the system. * - * \details Deactivates the ID in the channel mask. + * \details Removes the whole active channel plan except the 'Default Channels'.. + * Please note that this functionality is not available in all regions. + * Information on the allowed ranges is available at the + * LoRaWAN Regional Parameters V1.0.2rB. + * + * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: + * \ref LORAMAC_STATUS_OK + * \ref LORAMAC_STATUS_BUSY + * \ref LORAMAC_STATUS_PARAMETER_INVALID + */ + LoRaMacStatus_t RemoveChannelPlan(); + + /*! + * \brief Access active channel plan. + * + * \details Provides access to the current active channel plan. + * + * \param plan [out] - A reference to application provided channel plan data + * structure which will be filled in with active channel + * plan. + * + * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: + * \ref LORAMAC_STATUS_OK + * \ref LORAMAC_STATUS_BUSY + * \ref LORAMAC_STATUS_PARAMETER_INVALID + */ + LoRaMacStatus_t GetChannelPlan(lora_channelplan_t& plan); + + /*! + * \brief Remove a given channel from the active plan. + * + * \details Deactivates the given channel. * * \param id - Id of the channel. * @@ -146,7 +176,7 @@ public: * \ref LORAMAC_STATUS_BUSY * \ref LORAMAC_STATUS_PARAMETER_INVALID */ - LoRaMacStatus_t LoRaMacChannelRemove( uint8_t id ); + LoRaMacStatus_t RemoveSingleChannel( uint8_t id ); /*! * \brief LoRaMAC multicast channel link service. @@ -626,6 +656,11 @@ private: */ LoRaMacMib mib; + /** + * Channel planning subsystem + */ + LoRaMacChannelPlan ch_plan; + /** * Timer subsystem handle */ diff --git a/features/lorawan/lorastack/mac/LoRaMacChannelPlan.cpp b/features/lorawan/lorastack/mac/LoRaMacChannelPlan.cpp new file mode 100644 index 0000000000..6f576b98b3 --- /dev/null +++ b/features/lorawan/lorastack/mac/LoRaMacChannelPlan.cpp @@ -0,0 +1,236 @@ +/** + / _____) _ | | +( (____ _____ ____ _| |_ _____ ____| |__ + \____ \| ___ | (_ _) ___ |/ ___) _ \ + _____) ) ____| | | || |_| ____( (___| | | | +(______/|_____)_|_|_| \__)_____)\____)_| |_| + (C)2013 Semtech + ___ _____ _ ___ _ _____ ___ ___ ___ ___ +/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| +\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| +|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| +embedded.connectivity.solutions=============== + +Description: LoRaWAN stack layer that controls both MAC and PHY underneath + +License: Revised BSD License, see LICENSE.TXT file include in the project + +Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE ) + + +Copyright (c) 2017, Arm Limited and affiliates. + +SPDX-License-Identifier: BSD-3-Clause +*/ + +#include "lorastack/mac/LoRaMacChannelPlan.h" + +LoRaMacChannelPlan::LoRaMacChannelPlan() : _lora_phy(NULL), _mib(NULL) +{ +} + +LoRaMacChannelPlan::~LoRaMacChannelPlan() +{ +} + +void LoRaMacChannelPlan::activate_channelplan_subsystem(LoRaPHY *phy, LoRaMacMib *mib) +{ + _lora_phy = phy; + _mib = mib; +} + +LoRaMacStatus_t LoRaMacChannelPlan::set_plan(const lora_channelplan_t& plan) +{ + ChannelAddParams_t channelAdd; + ChannelParams_t mac_layer_ch_params; + LoRaMacStatus_t status; + + GetPhyParams_t get_phy; + PhyParam_t phy_param; + uint8_t max_num_channels; + + // Check first how many channels the selected PHY layer supports + get_phy.Attribute = PHY_MAX_NB_CHANNELS; + phy_param = _lora_phy->get_phy_params(&get_phy); + max_num_channels = (uint8_t) phy_param.Value; + + // check if user is setting more channels than supported + if (plan.nb_channels > max_num_channels) { + return LORAMAC_STATUS_PARAMETER_INVALID; + } + + for (uint8_t i = 0; i < plan.nb_channels; i++) { + mac_layer_ch_params.Band = plan.channels[i].ch_param.band; + mac_layer_ch_params.DrRange.Fields.Max = + plan.channels[i].ch_param.dr_range.lora_mac_fields_s.max; + mac_layer_ch_params.DrRange.Fields.Min = + plan.channels[i].ch_param.dr_range.lora_mac_fields_s.min; + mac_layer_ch_params.DrRange.Value = + plan.channels[i].ch_param.dr_range.value; + mac_layer_ch_params.Frequency = + plan.channels[i].ch_param.frequency; + mac_layer_ch_params.Rx1Frequency = + plan.channels[i].ch_param.rx1_frequency; + + channelAdd.ChannelId = plan.channels[i].id; + channelAdd.NewChannel = &mac_layer_ch_params; + + status = _lora_phy->add_channel(&channelAdd); + + if (status != LORAMAC_STATUS_OK) { + return status; + } + } + + return LORAMAC_STATUS_OK; +} + +LoRaMacStatus_t LoRaMacChannelPlan::get_plan(lora_channelplan_t& plan, + lora_mac_protocol_params *params) +{ + if (params == NULL) { + return LORAMAC_STATUS_PARAMETER_INVALID; + } + + MibRequestConfirm_t mib_params; + LoRaMacStatus_t status; + + GetPhyParams_t get_phy; + PhyParam_t phy_param; + uint8_t max_num_channels; + uint16_t *channel_masks; + uint8_t count = 0; + + // Check first how many channels the selected PHY layer supports + get_phy.Attribute = PHY_MAX_NB_CHANNELS; + phy_param = _lora_phy->get_phy_params(&get_phy); + max_num_channels = (uint8_t) phy_param.Value; + + // Now check the Default channel mask + get_phy.Attribute = PHY_CHANNELS_MASK; + phy_param = _lora_phy->get_phy_params(&get_phy); + channel_masks = phy_param.ChannelsMask; + + // Request Mib to get channels + memset(&mib_params, 0, sizeof(mib_params)); + mib_params.Type = MIB_CHANNELS; + + status = _mib->get_request(&mib_params, params); + + if (status != LORAMAC_STATUS_OK) { + return status; + } + + for (uint8_t i = 0; i < max_num_channels; i++) { + // skip the channels which are not enabled + if ((channel_masks[0] & (1U << i)) == 0) { + continue; + } + + // otherwise add them to the channel_plan struct + plan.channels[count].id = i; + plan.channels[count].ch_param.frequency = mib_params.Param.ChannelList[i].Frequency; + plan.channels[count].ch_param.dr_range.value = mib_params.Param.ChannelList[i].DrRange.Value; + plan.channels[count].ch_param.dr_range.lora_mac_fields_s.min = mib_params.Param.ChannelList[i].DrRange.Fields.Min; + plan.channels[count].ch_param.dr_range.lora_mac_fields_s.max = mib_params.Param.ChannelList[i].DrRange.Fields.Max; + plan.channels[count].ch_param.band = mib_params.Param.ChannelList[i].Band; + plan.channels[count].ch_param.rx1_frequency = mib_params.Param.ChannelList[i].Rx1Frequency; + count++; + } + + plan.nb_channels = count; + + return LORAMAC_STATUS_OK; +} + +LoRaMacStatus_t LoRaMacChannelPlan::remove_plan() +{ + LoRaMacStatus_t status = LORAMAC_STATUS_OK; + + GetPhyParams_t get_phy; + PhyParam_t phy_param; + uint8_t max_num_channels; + uint16_t *channel_masks; + uint16_t *default_channel_masks; + + // Check first how many channels the selected PHY layer supports + get_phy.Attribute = PHY_MAX_NB_CHANNELS; + phy_param = _lora_phy->get_phy_params(&get_phy); + max_num_channels = (uint8_t) phy_param.Value; + + // Now check the channel mask for enabled channels + get_phy.Attribute = PHY_CHANNELS_MASK; + phy_param = _lora_phy->get_phy_params(&get_phy); + channel_masks = phy_param.ChannelsMask; + + // Now check the channel mask for default channels + get_phy.Attribute = PHY_CHANNELS_DEFAULT_MASK; + phy_param = _lora_phy->get_phy_params(&get_phy); + default_channel_masks = phy_param.ChannelsMask; + + for (uint8_t i = 0; i < max_num_channels; i++) { + // skip any default channels + if ((default_channel_masks[0] & (1U<get_phy_params(&get_phy); + max_num_channels = (uint8_t) phy_param.Value; + + // According to specification channel IDs start from 0 and last valid + // channel ID is N-1 where N=MAX_NUM_CHANNELS. + // So any ID which is larger or equal to the Max number of channels is invalid + if (channel_id >= max_num_channels) { + return LORAMAC_STATUS_PARAMETER_INVALID; + } + + // Now check the Default channel mask + get_phy.Attribute = PHY_CHANNELS_DEFAULT_MASK; + phy_param = _lora_phy->get_phy_params(&get_phy); + channel_masks = phy_param.ChannelsMask; + + // check if the channel ID give belongs to a default channel + // Mostly the default channels are in the first mask if the region + // have multiple channel masks for various sub-bands. So we check the first + // mask only and return an error code if user sent a default channel id + if ((channel_masks[0] & (1U << channel_id)) != 0) { + return LORAMAC_STATUS_PARAMETER_INVALID; + } + + channelRemove.ChannelId = channel_id; + + if(_lora_phy->remove_channel(&channelRemove) == false) + { + return LORAMAC_STATUS_PARAMETER_INVALID; + } + + _lora_phy->put_radio_to_sleep(); + + return LORAMAC_STATUS_OK; +} + diff --git a/features/lorawan/lorastack/mac/LoRaMacChannelPlan.h b/features/lorawan/lorastack/mac/LoRaMacChannelPlan.h new file mode 100644 index 0000000000..e57d37d951 --- /dev/null +++ b/features/lorawan/lorastack/mac/LoRaMacChannelPlan.h @@ -0,0 +1,115 @@ +/** + / _____) _ | | +( (____ _____ ____ _| |_ _____ ____| |__ + \____ \| ___ | (_ _) ___ |/ ___) _ \ + _____) ) ____| | | || |_| ____( (___| | | | +(______/|_____)_|_|_| \__)_____)\____)_| |_| + (C)2013 Semtech + ___ _____ _ ___ _ _____ ___ ___ ___ ___ +/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| +\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| +|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| +embedded.connectivity.solutions=============== + +Description: LoRaWAN stack layer that controls both MAC and PHY underneath + +License: Revised BSD License, see LICENSE.TXT file include in the project + +Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE ) + + +Copyright (c) 2017, Arm Limited and affiliates. + +SPDX-License-Identifier: BSD-3-Clause +*/ + +#ifndef MBED_LORAWAN_LORAMACCHANNELPLAN_H_ +#define MBED_LORAWAN_LORAMACCHANNELPLAN_H_ + +#include "lorawan/system/lorawan_data_structures.h" +#include "lorastack/phy/LoRaPHY.h" +#include "lorastack/mac/LoRaMacMib.h" + +class LoRaMacChannelPlan { + +public: + + /** Constructor + * + * Sets local handles to NULL. These handles will be set when the subsystem + * is activated by the MAC layer. + */ + LoRaMacChannelPlan(); + + /** Destructor + * + * Does nothing + */ + ~LoRaMacChannelPlan(); + + /** Activates Channel Planning subsystem + * + * Stores pointers to PHY layer MIB subsystem + * + * @param phy pointer to PHY layer + * @param mib pointer to MIB subsystem + */ + void activate_channelplan_subsystem(LoRaPHY *phy,LoRaMacMib *mib); + + /** Set a given channel plan + * + * Used to set application provided channel plan. This API can be used to + * set a single channel as well to the existing channel plan. + * + * @param plan a reference to application channel plan. PHY layer takes a + * copy of the channel parameters provided within. + * + * @return LORA_MAC_STATUS_OK if everything goes well otherwise + * a negative error code is returned. + */ + LoRaMacStatus_t set_plan(const lora_channelplan_t& plan); + + /** Access the active channel plan + * + * Used to get active channel plan. + * + * @param plan a reference to application provided channel plan structure + * which gets filled in with active channel plan data. + * + * @param params pointer to active MAC layer parameters. + * + * @return LORA_MAC_STATUS_OK if everything goes well otherwise + * a negative error code is returned. + */ + LoRaMacStatus_t get_plan(lora_channelplan_t& plan, lora_mac_protocol_params *params); + + /** Remove the active channel plan + * + * Drops the whole channel list except the 'Default Channels' ofcourse. + * + * @return LORA_MAC_STATUS_OK if everything goes well otherwise + * a negative error code is returned. + */ + LoRaMacStatus_t remove_plan(); + + /** Remove a single channel from the plan + * + * @param id the channel id which needs to be removed + * + * @return LORA_MAC_STATUS_OK if everything goes well otherwise + * a negative error code is returned. + */ + LoRaMacStatus_t remove_single_channel(uint8_t id); + +private: + + /** + * Local handles + */ + LoRaPHY *_lora_phy; + LoRaMacMib * _mib; +}; + + + +#endif /* MBED_LORAWAN_LORAMACCHANNELPLAN_H_ */ From c02774343a93c9a57238a856cf110cf0bf0f01fb Mon Sep 17 00:00:00 2001 From: Hasnain Virk Date: Fri, 12 Jan 2018 16:39:31 +0200 Subject: [PATCH 12/23] [IOTCELL-282] Code cleanup/simplification and rules Baseline is changed to use a single set of data structures that simplifies the code in the LoRaWANStack and Mac layer. We are now following certian rules for naming data structures. - All structures visible outside their domain are prefixed as 'lorawan_' - All mac structures are prefixed as 'loramac_' - All subsystem or module strucutures carry their name in prefix, like 'mcps_' PHY layer still have legacy camel case data structures which will be entertained later while we will be simplifying PHY layer. Test cases are also updated with the new data structure naming conventions. One major difference from the previous baseline is the removal of static buffer from mcps indication. And we do not copy data from stack buffer to rx_msg buffer. This saves at least 512 bytes. It may look like now that if we have received something but the user have not read from the buffer, then the buffer will be overwritten and we will lose previous frame. Yes, we will. But the same will happen even if we would have copied the buffer into rx_msg because then the rx_msg gets overwritten. So we decide to abandon copying the buffer at multiple locations. We inform the user about reception, if the user doesn't read and the data gets overwritten, then so be it. --- features/lorawan/LoRaWANInterface.cpp | 45 +- features/lorawan/LoRaWANInterface.h | 62 +- features/lorawan/LoRaWANStack.cpp | 1077 +++-------- features/lorawan/LoRaWANStack.h | 112 +- features/lorawan/lorastack/mac/LoRaMac.cpp | 1363 +++++++------- features/lorawan/lorastack/mac/LoRaMac.h | 158 +- .../lorastack/mac/LoRaMacChannelPlan.cpp | 76 +- .../lorastack/mac/LoRaMacChannelPlan.h | 16 +- .../lorawan/lorastack/mac/LoRaMacCommand.cpp | 96 +- .../lorawan/lorastack/mac/LoRaMacCommand.h | 10 +- .../lorawan/lorastack/mac/LoRaMacCrypto.cpp | 12 +- .../lorawan/lorastack/mac/LoRaMacMcps.cpp | 78 +- features/lorawan/lorastack/mac/LoRaMacMcps.h | 12 +- features/lorawan/lorastack/mac/LoRaMacMib.cpp | 237 ++- features/lorawan/lorastack/mac/LoRaMacMib.h | 10 +- .../lorawan/lorastack/mac/LoRaMacMlme.cpp | 84 +- features/lorawan/lorastack/mac/LoRaMacMlme.h | 12 +- features/lorawan/lorastack/phy/LoRaPHY.cpp | 56 +- features/lorawan/lorastack/phy/LoRaPHY.h | 30 +- .../lorawan/lorastack/phy/LoRaPHYAS923.cpp | 146 +- features/lorawan/lorastack/phy/LoRaPHYAS923.h | 18 +- .../lorawan/lorastack/phy/LoRaPHYAU915.cpp | 82 +- features/lorawan/lorastack/phy/LoRaPHYAU915.h | 20 +- .../lorawan/lorastack/phy/LoRaPHYCN470.cpp | 72 +- features/lorawan/lorastack/phy/LoRaPHYCN470.h | 18 +- .../lorawan/lorastack/phy/LoRaPHYCN779.cpp | 140 +- features/lorawan/lorastack/phy/LoRaPHYCN779.h | 18 +- .../lorawan/lorastack/phy/LoRaPHYEU433.cpp | 146 +- features/lorawan/lorastack/phy/LoRaPHYEU433.h | 18 +- .../lorawan/lorastack/phy/LoRaPHYEU868.cpp | 148 +- features/lorawan/lorastack/phy/LoRaPHYEU868.h | 18 +- .../lorawan/lorastack/phy/LoRaPHYIN865.cpp | 140 +- features/lorawan/lorastack/phy/LoRaPHYIN865.h | 18 +- .../lorawan/lorastack/phy/LoRaPHYKR920.cpp | 138 +- features/lorawan/lorastack/phy/LoRaPHYKR920.h | 18 +- .../lorawan/lorastack/phy/LoRaPHYUS915.cpp | 76 +- features/lorawan/lorastack/phy/LoRaPHYUS915.h | 18 +- .../lorastack/phy/LoRaPHYUS915Hybrid.cpp | 72 +- .../lorastack/phy/LoRaPHYUS915Hybrid.h | 18 +- features/lorawan/lorastack/phy/lora_phy_ds.h | 16 +- features/lorawan/system/LoRaWANTimer.cpp | 20 +- features/lorawan/system/LoRaWANTimer.h | 12 +- .../lorawan/system/lorawan_data_structures.h | 1615 +++++------------ features/netsocket/LoRaWANBase.h | 58 +- 44 files changed, 2588 insertions(+), 4021 deletions(-) diff --git a/features/lorawan/LoRaWANInterface.cpp b/features/lorawan/LoRaWANInterface.cpp index 0e9887cfc8..b11759744c 100644 --- a/features/lorawan/LoRaWANInterface.cpp +++ b/features/lorawan/LoRaWANInterface.cpp @@ -42,16 +42,16 @@ LoRaWANInterface::~LoRaWANInterface() { } -lora_mac_status_t LoRaWANInterface::initialize(EventQueue *queue) +lorawan_status_t LoRaWANInterface::initialize(EventQueue *queue) { if(!queue) { - return LORA_MAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } return stk_obj().initialize_mac_layer(queue); } -lora_mac_status_t LoRaWANInterface::connect() +lorawan_status_t LoRaWANInterface::connect() { // connection attempt without parameters. // System tries to look for configuration in mbed_lib.json that can be @@ -96,28 +96,28 @@ lora_mac_status_t LoRaWANInterface::connect() } } -lora_mac_status_t LoRaWANInterface::connect(const lorawan_connect_t &connect) +lorawan_status_t LoRaWANInterface::connect(const lorawan_connect_t &connect) { - lora_mac_status_t mac_status; + lorawan_status_t mac_status; if (connect.connect_type == LORAWAN_CONNECTION_OTAA) { mac_status = stk_obj().join_request_by_otaa(connect); } else if (connect.connect_type == LORAWAN_CONNECTION_ABP) { mac_status = stk_obj().activation_by_personalization(connect); } else { - return LORA_MAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } return mac_status; } -lora_mac_status_t LoRaWANInterface::disconnect() +lorawan_status_t LoRaWANInterface::disconnect() { stk_obj().shutdown(); - return LORA_MAC_STATUS_OK; + return LORAWAN_STATUS_OK; } -lora_mac_status_t LoRaWANInterface::add_link_check_request() +lorawan_status_t LoRaWANInterface::add_link_check_request() { _link_check_requested = true; return stk_obj().set_link_check_request(); @@ -128,42 +128,42 @@ void LoRaWANInterface::remove_link_check_request() _link_check_requested = false; } -lora_mac_status_t LoRaWANInterface::set_datarate(uint8_t data_rate) +lorawan_status_t LoRaWANInterface::set_datarate(uint8_t data_rate) { return stk_obj().set_channel_data_rate(data_rate); } -lora_mac_status_t LoRaWANInterface::set_confirmed_msg_retries(uint8_t count) +lorawan_status_t LoRaWANInterface::set_confirmed_msg_retries(uint8_t count) { return stk_obj().set_confirmed_msg_retry(count); } -lora_mac_status_t LoRaWANInterface::enable_adaptive_datarate() +lorawan_status_t LoRaWANInterface::enable_adaptive_datarate() { return stk_obj().enable_adaptive_datarate(true); } -lora_mac_status_t LoRaWANInterface::disable_adaptive_datarate() +lorawan_status_t LoRaWANInterface::disable_adaptive_datarate() { return stk_obj().enable_adaptive_datarate(false); } -lora_mac_status_t LoRaWANInterface::set_channel_plan(const lora_channelplan_t &channel_plan) +lorawan_status_t LoRaWANInterface::set_channel_plan(const lorawan_channelplan_t &channel_plan) { return stk_obj().add_channels(channel_plan); } -lora_mac_status_t LoRaWANInterface::get_channel_plan(lora_channelplan_t &channel_plan) +lorawan_status_t LoRaWANInterface::get_channel_plan(lorawan_channelplan_t &channel_plan) { return stk_obj().get_enabled_channels(channel_plan); } -lora_mac_status_t LoRaWANInterface::remove_channel(uint8_t id) +lorawan_status_t LoRaWANInterface::remove_channel(uint8_t id) { return stk_obj().remove_a_channel(id); } -lora_mac_status_t LoRaWANInterface::remove_channel_plan() +lorawan_status_t LoRaWANInterface::remove_channel_plan() { return stk_obj().drop_channel_list(); } @@ -180,7 +180,7 @@ int16_t LoRaWANInterface::send(uint8_t port, const uint8_t* data, if (data) { return stk_obj().handle_tx(port, data, length, flags); } else { - return LORA_MAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } } @@ -190,19 +190,18 @@ int16_t LoRaWANInterface::receive(uint8_t port, uint8_t* data, uint16_t length, if (data && length > 0) { return stk_obj().handle_rx(port, data, length, flags); } else { - return LORA_MAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } } -lora_mac_status_t LoRaWANInterface::add_app_callbacks(lorawan_app_callbacks_t *callbacks) +lorawan_status_t LoRaWANInterface::add_app_callbacks(lorawan_app_callbacks_t *callbacks) { if (!callbacks || !callbacks->events) { // Event Callback is mandatory - return LORA_MAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } stk_obj().set_lora_callbacks(callbacks); - - return LORA_MAC_STATUS_OK; + return LORAWAN_STATUS_OK; } diff --git a/features/lorawan/LoRaWANInterface.h b/features/lorawan/LoRaWANInterface.h index ba722e50dd..f64fe1609b 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 lora_mac_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 * @@ -52,7 +52,7 @@ public: * You need to configure the connection properly via the Mbed OS configuration * system. * - * When connecting via OTAA, the return code for success (LORA_MAC_STATUS_CONNECT_IN_PROGRESS) is negative. + * When connecting via OTAA, the return code for success (LORAWAN_STATUS_CONNECT_IN_PROGRESS) is negative. * However, this is not a real error. It tells you that the connection is in progress and you will * be notified of the completion via an event. By default, after the Join Accept message * is received, base stations may provide the node with a CF-List that replaces @@ -78,17 +78,17 @@ public: * is important, at least for ABP. That's why we try to restore frame counters from * session information after a disconnection. * - * @return LORA_MAC_STATUS_OK or LORA_MAC_STATUS_CONNECT_IN_PROGRESS + * @return LORAWAN_STATUS_OK or LORAWAN_STATUS_CONNECT_IN_PROGRESS * on success, or a negative error code on failure. */ - virtual lora_mac_status_t connect(); + virtual lorawan_status_t connect(); /** Connect OTAA or ABP with parameters * * All connection parameters are chosen by the user and provided in the * data structure passed down. * - * When connecting via OTAA, the return code for success (LORA_MAC_STATUS_CONNECT_IN_PROGRESS) is negative. + * When connecting via OTAA, the return code for success (LORAWAN_STATUS_CONNECT_IN_PROGRESS) is negative. * However, this is not a real error. It tells you that connection is in progress and you will * be notified of completion via an event. By default, after Join Accept message * is received, base stations may provide the node with a CF-List which replaces @@ -118,17 +118,17 @@ public: * * @param connect Options for an end device connection to the gateway. * - * @return LORA_MAC_STATUS_OK or LORA_MAC_STATUS_CONNECT_IN_PROGRESS, + * @return LORAWAN_STATUS_OK or LORAWAN_STATUS_CONNECT_IN_PROGRESS, * a negative error code on failure. */ - virtual lora_mac_status_t connect(const lorawan_connect_t &connect); + virtual lorawan_status_t connect(const lorawan_connect_t &connect); /** Disconnect the current session. * - * @return LORA_MAC_STATUS_OK on success, a negative error code on + * @return LORAWAN_STATUS_OK on success, a negative error code on * failure. */ - virtual lora_mac_status_t disconnect(); + virtual lorawan_status_t disconnect(); /** Validate the connectivity with the network. * @@ -145,7 +145,7 @@ public: * * This API is usable only when the 'link_check_resp' callback is set by * the application. See add_lora_app_callbacks API. If the above mentioned - * callback is not set, a LORA_MAC_STATUS_PARAMETER_INVALID error is thrown. + * callback is not set, a LORAWAN_STATUS_PARAMETER_INVALID error is thrown. * * First parameter to callback function is the demodulation margin and * the second parameter is the number of gateways that successfully received @@ -155,11 +155,11 @@ public: * transmission, until/unless application explicitly turns it off using * remove_link_check_request() API. * - * @return LORA_MAC_STATUS_OK on successfully queuing a request, or + * @return LORAWAN_STATUS_OK on successfully queuing a request, or * a negative error code on failure. * */ - virtual lora_mac_status_t add_link_check_request(); + virtual lorawan_status_t add_link_check_request(); /** Removes link check request sticky MAC command. * @@ -176,28 +176,28 @@ public: * @param data_rate The intended data rate, for example DR_0 or DR_1. * Please note, that the macro DR_* can mean different * things in different regions. - * @return LORA_MAC_STATUS_OK if everything goes well, otherwise + * @return LORAWAN_STATUS_OK if everything goes well, otherwise * a negative error code. */ - virtual lora_mac_status_t set_datarate(uint8_t data_rate); + virtual lorawan_status_t set_datarate(uint8_t data_rate); /** Enables adaptive data rate (ADR). * * The underlying LoRaPHY and LoRaMac layers handle the data rate automatically * for the user, based upon the radio conditions (network congestion). * - * @return LORA_MAC_STATUS_OK or negative error code otherwise. + * @return LORAWAN_STATUS_OK or negative error code otherwise. */ - virtual lora_mac_status_t enable_adaptive_datarate(); + virtual lorawan_status_t enable_adaptive_datarate(); /** Disables adaptive data rate. * * When adaptive data rate (ADR) is disabled, you can either set a certain * data rate or the MAC layer selects a default value. * - * @return LORA_MAC_STATUS_OK or negative error code otherwise. + * @return LORAWAN_STATUS_OK or negative error code otherwise. */ - virtual lora_mac_status_t disable_adaptive_datarate(); + virtual lorawan_status_t disable_adaptive_datarate(); /** Sets up the retry counter for confirmed messages. * @@ -212,9 +212,9 @@ public: * * @param count The number of retries for confirmed messages. * - * @return LORA_MAC_STATUS_OK or a negative error code. + * @return LORAWAN_STATUS_OK or a negative error code. */ - virtual lora_mac_status_t set_confirmed_msg_retries(uint8_t count); + virtual lorawan_status_t set_confirmed_msg_retries(uint8_t count); /** Sets the channel plan. * @@ -240,10 +240,10 @@ public: * * @param channel_plan The channel plan to set. * - * @return LORA_MAC_STATUS_OK on success, a negative error + * @return LORAWAN_STATUS_OK on success, a negative error * code on failure. */ - virtual lora_mac_status_t set_channel_plan(const lora_channelplan_t &channel_plan); + virtual lorawan_status_t set_channel_plan(const lorawan_channelplan_t &channel_plan); /** Gets the channel plans from the LoRa stack. * @@ -254,20 +254,20 @@ public: * * @param channel_plan The current channel plan information. * - * @return LORA_MAC_STATUS_OK on success, a negative error + * @return LORAWAN_STATUS_OK on success, a negative error * code on failure. */ - virtual lora_mac_status_t get_channel_plan(lora_channelplan_t &channel_plan); + virtual lorawan_status_t get_channel_plan(lorawan_channelplan_t &channel_plan); /** Removes an active channel plan. * * You cannot remove default channels (the channels the base stations are listening to). * When a plan is abolished, only the non-default channels are removed. * - * @return LORA_MAC_STATUS_OK on success, a negative error + * @return LORAWAN_STATUS_OK on success, a negative error * code on failure. */ - virtual lora_mac_status_t remove_channel_plan(); + virtual lorawan_status_t remove_channel_plan(); /** Removes a single channel. * @@ -275,10 +275,10 @@ public: * * @param index The channel index. * - * @return LORA_MAC_STATUS_OK on success, a negative error + * @return LORAWAN_STATUS_OK on success, a negative error * code on failure. */ - virtual lora_mac_status_t remove_channel(uint8_t index); + virtual lorawan_status_t remove_channel(uint8_t index); /** Send message to gateway * @@ -311,7 +311,7 @@ public: * * * @return The number of bytes sent, or - * LORA_MAC_STATUS_WOULD_BLOCK if another TX is + * LORAWAN_STATUS_WOULD_BLOCK if another TX is * ongoing, or a negative error code on failure. */ virtual int16_t send(uint8_t port, const uint8_t* data, uint16_t length, @@ -352,7 +352,7 @@ public: * @return It could be one of these: * i) 0 if there is nothing else to read. * ii) Number of bytes written to user buffer. - * iii) LORA_MAC_STATUS_WOULD_BLOCK if there is + * iii) LORAWAN_STATUS_WOULD_BLOCK if there is * nothing available to read at the moment. * iv) A negative error code on failure. */ @@ -427,7 +427,7 @@ public: * @param callbacks A pointer to the structure containing application * callbacks. */ - virtual lora_mac_status_t add_app_callbacks(lorawan_app_callbacks_t *callbacks); + virtual lorawan_status_t add_app_callbacks(lorawan_app_callbacks_t *callbacks); private: bool _link_check_requested; diff --git a/features/lorawan/LoRaWANStack.cpp b/features/lorawan/LoRaWANStack.cpp index fac53a1141..6cfaba80e6 100644 --- a/features/lorawan/LoRaWANStack.cpp +++ b/features/lorawan/LoRaWANStack.cpp @@ -44,13 +44,6 @@ SPDX-License-Identifier: BSD-3-Clause using namespace mbed; using namespace events; -/** - * Helper function prototypes - */ -static Mcps_t interpret_mcps_confirm_type(const lora_mac_mcps_t& local); -static Mib_t interpret_mib_req_confirm_type(const lora_mac_mib_t& mib_local); -static lora_mac_event_info_status_t interpret_event_info_type(const LoRaMacEventInfoStatus_t& remote); - #if defined(LORAWAN_COMPLIANCE_TEST) /** * @@ -78,14 +71,14 @@ bool LoRaWANStack::is_port_valid(uint8_t port) } } -lora_mac_status_t LoRaWANStack::set_application_port(uint8_t port) +lorawan_status_t LoRaWANStack::set_application_port(uint8_t port) { if (is_port_valid(port)) { _app_port = port; - return LORA_MAC_STATUS_OK; + return LORAWAN_STATUS_OK; } - return LORA_MAC_STATUS_PORT_INVALID; + return LORAWAN_STATUS_PORT_INVALID; } /***************************************************************************** @@ -138,18 +131,16 @@ 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(EventQueue *queue) +lorawan_status_t LoRaWANStack::initialize_mac_layer(EventQueue *queue) { if (DEVICE_STATE_NOT_INITIALIZED != _device_current_state) { tr_debug("Initialized already"); - return LORA_MAC_STATUS_OK; + return LORAWAN_STATUS_OK; } - static LoRaMacPrimitives_t LoRaMacPrimitives; - static LoRaMacCallback_t LoRaMacCallbacks; - static lora_mac_mib_request_confirm_t mib_req; + static loramac_primitives_t LoRaMacPrimitives; + static loramac_mib_req_confirm_t mib_req; #if defined(LORAWAN_COMPLIANCE_TEST) static uint8_t compliance_test_buffer[MBED_CONF_LORA_TX_MAX_SIZE]; @@ -167,18 +158,18 @@ lora_mac_status_t LoRaWANStack::initialize_mac_layer(EventQueue *queue) _lora_time.TimerTimeCounterInit(queue); - LoRaMacPrimitives.MacMcpsConfirm = callback(this, &LoRaWANStack::mcps_confirm); - LoRaMacPrimitives.MacMcpsIndication = callback(this, &LoRaWANStack::mcps_indication); - LoRaMacPrimitives.MacMlmeConfirm = callback(this, &LoRaWANStack::mlme_confirm); - LoRaMacPrimitives.MacMlmeIndication = callback(this, &LoRaWANStack::mlme_indication); - _loramac.LoRaMacInitialization(&LoRaMacPrimitives, &LoRaMacCallbacks, &_lora_phy, queue); + LoRaMacPrimitives.mcps_confirm = callback(this, &LoRaWANStack::mcps_confirm_handler); + LoRaMacPrimitives.mcps_indication = callback(this, &LoRaWANStack::mcps_indication_handler); + LoRaMacPrimitives.mlme_confirm = callback(this, &LoRaWANStack::mlme_confirm_handler); + LoRaMacPrimitives.mlme_indication = callback(this, &LoRaWANStack::mlme_indication_handler); + _loramac.LoRaMacInitialization(&LoRaMacPrimitives, &_lora_phy, queue); - mib_req.type = LORA_MIB_ADR; - mib_req.param.adr_enable = MBED_CONF_LORA_ADR_ON; + mib_req.type = MIB_ADR; + mib_req.param.is_adr_enable = MBED_CONF_LORA_ADR_ON; mib_set_request(&mib_req); - mib_req.type = LORA_MIB_PUBLIC_NETWORK; - mib_req.param.enable_public_network = MBED_CONF_LORA_PUBLIC_NETWORK; + mib_req.type = MIB_PUBLIC_NETWORK; + mib_req.param.enable_public_nwk = MBED_CONF_LORA_PUBLIC_NETWORK; mib_set_request(&mib_req); // Reset counters to zero. Will change in future with 1.1 support. @@ -235,9 +226,9 @@ void LoRaWANStack::prepare_special_tx_frame(uint8_t port) * * \return returns the state of the LoRa MAC */ -lora_mac_status_t LoRaWANStack::send_compliance_test_frame_to_mac() +lorawan_status_t LoRaWANStack::send_compliance_test_frame_to_mac() { - lora_mac_mcps_req_t mcps_req; + loramac_mcps_req_t mcps_req; GetPhyParams_t phy_params; PhyParam_t default_datarate; @@ -247,32 +238,32 @@ lora_mac_status_t LoRaWANStack::send_compliance_test_frame_to_mac() prepare_special_tx_frame(_compliance_test.app_port); if (!_compliance_test.is_tx_confirmed) { - mcps_req.type = LORA_MCPS_UNCONFIRMED; - mcps_req.req.unconfirmed.f_port = _compliance_test.app_port; + mcps_req.type = MCPS_UNCONFIRMED; + mcps_req.req.unconfirmed.fport = _compliance_test.app_port; mcps_req.f_buffer = _tx_msg.f_buffer; mcps_req.f_buffer_size = _tx_msg.f_buffer_size; - mcps_req.req.unconfirmed.datarate = default_datarate.Value; + mcps_req.req.unconfirmed.data_rate = default_datarate.Value; - tr_info("Transmit unconfirmed compliance test frame %d bytes.", mcps_req.f_buffer_size); + tr_info("Transmit unconfirmed compliance test frame %d bytes.", mcps_req.req.unconfirmed.fbuffer_size); for (uint8_t i = 0; i < mcps_req.f_buffer_size; ++i) { tr_info("Byte %d, data is 0x%x", i+1, ((uint8_t*)mcps_req.f_buffer)[i]); } } else if (_compliance_test.is_tx_confirmed) { - mcps_req.type = LORA_MCPS_CONFIRMED; - mcps_req.req.confirmed.f_port = _compliance_test.app_port; + mcps_req.type = MCPS_CONFIRMED; + mcps_req.req.confirmed.fport = _compliance_test.app_port; mcps_req.f_buffer = _tx_msg.f_buffer; mcps_req.f_buffer_size = _tx_msg.f_buffer_size; mcps_req.req.confirmed.nb_trials = _num_retry; - mcps_req.req.confirmed.datarate = default_datarate.Value; + mcps_req.req.confirmed.data_rate = default_datarate.Value; - tr_info("Transmit confirmed compliance test frame %d bytes.", mcps_req.f_buffer_size); + tr_info("Transmit confirmed compliance test frame %d bytes.", mcps_req.req.confirmed.fbuffer_size); for (uint8_t i = 0; i < mcps_req.f_buffer_size; ++i) { tr_info("Byte %d, data is 0x%x", i+1, ((uint8_t*)mcps_req.f_buffer)[i]); } } else { - return LORA_MAC_STATUS_SERVICE_UNKNOWN; + return LORAWAN_STATUS_SERVICE_UNKNOWN; } return mcps_request_handler(&mcps_req); @@ -281,25 +272,25 @@ lora_mac_status_t LoRaWANStack::send_compliance_test_frame_to_mac() uint16_t LoRaWANStack::check_possible_tx_size(uint16_t size) { - LoRaMacTxInfo_t txInfo; - if (_loramac.LoRaMacQueryTxPossible(size, &txInfo) == LORAMAC_STATUS_LENGTH_ERROR) { + loramac_tx_info_t tx_info; + if (_loramac.LoRaMacQueryTxPossible(size, &tx_info) == LORAWAN_STATUS_LENGTH_ERROR) { // Cannot transmit this much. Return how much data can be sent // at the moment - return txInfo.MaxPossiblePayload; + return tx_info.max_possible_payload_size; } - return txInfo.CurrentPayloadSize; + return tx_info.current_payload_size; } /** Hands over the frame to MAC layer * * \return returns the state of the LoRa MAC */ -lora_mac_status_t LoRaWANStack::send_frame_to_mac() +lorawan_status_t LoRaWANStack::send_frame_to_mac() { - lora_mac_mcps_req_t mcps_req; - lora_mac_status_t status; - lora_mac_mib_request_confirm_t mib_get_params; + loramac_mcps_req_t mcps_req; + lorawan_status_t status; + loramac_mib_req_confirm_t mib_get_params; GetPhyParams_t phy_params; PhyParam_t default_datarate; @@ -308,33 +299,48 @@ lora_mac_status_t LoRaWANStack::send_frame_to_mac() mcps_req.type = _tx_msg.type; - if (LORA_MCPS_UNCONFIRMED == mcps_req.type) { - mcps_req.req.unconfirmed.f_port = _tx_msg.message_u.unconfirmed.f_port; + if (MCPS_UNCONFIRMED == mcps_req.type) { + mcps_req.req.unconfirmed.fport = _tx_msg.message_u.unconfirmed.fport; mcps_req.f_buffer = _tx_msg.f_buffer; mcps_req.f_buffer_size = _tx_msg.f_buffer_size; - mcps_req.req.unconfirmed.datarate = default_datarate.Value; - } else if (LORA_MCPS_CONFIRMED == mcps_req.type) { - mcps_req.req.confirmed.f_port = _tx_msg.message_u.confirmed.f_port; + mib_get_params.type = MIB_CHANNELS_DATARATE; + if(mib_get_request(&mib_get_params) != LORAWAN_STATUS_OK) { + tr_debug("Couldn't get MIB parameters: Using default data rate"); + mcps_req.req.unconfirmed.data_rate = default_datarate.Value; + } else { + mcps_req.req.unconfirmed.data_rate = mib_get_params.param.channel_data_rate; + } + + } else if (mcps_req.type == MCPS_CONFIRMED) { + mcps_req.req.confirmed.fport = _tx_msg.message_u.confirmed.fport; mcps_req.f_buffer = _tx_msg.f_buffer; mcps_req.f_buffer_size = _tx_msg.f_buffer_size; mcps_req.req.confirmed.nb_trials = _tx_msg.message_u.confirmed.nb_trials; - mib_get_params.type = LORA_MIB_CHANNELS_DATARATE; - if(mib_get_request(&mib_get_params) != LORA_MAC_STATUS_OK) { - tr_debug("Couldn't get MIB parameters: Using default data rate"); - mcps_req.req.confirmed.datarate = default_datarate.Value; - } else { - mcps_req.req.confirmed.datarate = mib_get_params.param.channels_datarate; - } + mib_get_params.type = MIB_CHANNELS_DATARATE; + if(mib_get_request(&mib_get_params) != LORAWAN_STATUS_OK) { + tr_debug("Couldn't get MIB parameters: Using default data rate"); + mcps_req.req.confirmed.data_rate = default_datarate.Value; + } else { + mcps_req.req.confirmed.data_rate = mib_get_params.param.channel_data_rate; + } - } else if (LORA_MCPS_PROPRIETARY == mcps_req.type) { + } else if ( mcps_req.type == MCPS_PROPRIETARY) { mcps_req.f_buffer = _tx_msg.f_buffer; mcps_req.f_buffer_size = _tx_msg.f_buffer_size; - mcps_req.req.proprietary.datarate = default_datarate.Value; + + mib_get_params.type = MIB_CHANNELS_DATARATE; + if(mib_get_request(&mib_get_params) != LORAWAN_STATUS_OK) { + tr_debug("Couldn't get MIB parameters: Using default data rate"); + mcps_req.req.proprietary.data_rate = default_datarate.Value; + } else { + mcps_req.req.proprietary.data_rate = mib_get_params.param.channel_data_rate; + } + } else { - return LORA_MAC_STATUS_SERVICE_UNKNOWN; + return LORAWAN_STATUS_SERVICE_UNKNOWN; } status = mcps_request_handler(&mcps_req); @@ -342,15 +348,15 @@ lora_mac_status_t LoRaWANStack::send_frame_to_mac() return status; } -lora_mac_status_t LoRaWANStack::set_confirmed_msg_retry(uint8_t count) +lorawan_status_t LoRaWANStack::set_confirmed_msg_retry(uint8_t count) { if (count >= MAX_CONFIRMED_MSG_RETRIES) { - return LORA_MAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } _num_retry = count; - return LORA_MAC_STATUS_OK; + return LORAWAN_STATUS_OK; } void LoRaWANStack::set_device_state(device_states_t new_state) @@ -358,84 +364,14 @@ void LoRaWANStack::set_device_state(device_states_t new_state) _device_current_state = new_state; } -/** Wrapper function to MCPS-Confirm event function - * - * \param mcps_confirm Pointer to the confirm structure, - * containing confirm attributes. - */ -void LoRaWANStack::mcps_confirm(McpsConfirm_t *mcps_confirm) -{ - lora_mac_mcps_confirm_t lora_mcps_confirm; - lora_mcps_confirm.ack_received = mcps_confirm->AckReceived; - lora_mcps_confirm.nb_retries = mcps_confirm->NbRetries; - lora_mcps_confirm.datarate = mcps_confirm->Datarate; - lora_mcps_confirm.tx_power = mcps_confirm->TxPower; - lora_mcps_confirm.uplink_counter = mcps_confirm->UpLinkCounter; - lora_mcps_confirm.uplink_frequency = mcps_confirm->UpLinkFrequency; - - // Interprets from Mcps_t to lora_mac_mcps_t - mcps_confirm->McpsRequest = interpret_mcps_confirm_type(lora_mcps_confirm.mcps_request); - // Interprets from LoRaMacEventInfoStatus_t to lora_mac_event_info_status_t - lora_mcps_confirm.status = interpret_event_info_type(mcps_confirm->Status); - lora_mcps_confirm.tx_time_on_air = mcps_confirm->TxTimeOnAir; - - mcps_confirm_handler(&lora_mcps_confirm); -} - -/** Wrapper function to MCPS-Indication event function - * - * \param mcps_indication Pointer to the indication structure, - * containing indication attributes. - */ -void LoRaWANStack::mcps_indication(McpsIndication_t *mcps_indication) -{ - lora_mac_mcps_indication_t lora_mcps_indication; - - lora_mcps_indication.ack_received = mcps_indication->AckReceived; - memcpy(lora_mcps_indication.buffer, mcps_indication->Buffer, mcps_indication->BufferSize); - lora_mcps_indication.buffer_size = mcps_indication->BufferSize; - lora_mcps_indication.downlink_counter = mcps_indication->DownLinkCounter; - lora_mcps_indication.frame_pending = mcps_indication->FramePending; - lora_mcps_indication.mcps_indication = (lora_mac_mcps_t)mcps_indication->McpsIndication; - lora_mcps_indication.multicast = mcps_indication->Multicast; - lora_mcps_indication.port = mcps_indication->Port; - lora_mcps_indication.rssi = mcps_indication->Rssi; - lora_mcps_indication.rx_data = mcps_indication->RxData; - lora_mcps_indication.rx_datarate = mcps_indication->RxDatarate; - lora_mcps_indication.rx_slot = mcps_indication->RxSlot; - lora_mcps_indication.snr = mcps_indication->Snr; - lora_mcps_indication.status = (lora_mac_event_info_status_t)mcps_indication->Status; - - mcps_indication_handler(&lora_mcps_indication); -} - -/** Wrapper function to MLME-Confirm event function - * - * \param mlme_confirm Pointer to the confirm structure, - * containing confirm attributes. - */ -void LoRaWANStack::mlme_confirm(MlmeConfirm_t *mlme_confirm) -{ - lora_mac_mlme_confirm_t lora_mlme_confirm; - - lora_mlme_confirm.demod_margin = mlme_confirm->DemodMargin; - lora_mlme_confirm.mlme_request = (lora_mac_mlme_t)mlme_confirm->MlmeRequest; - lora_mlme_confirm.nb_gateways = mlme_confirm->NbGateways; - lora_mlme_confirm.nb_retries = mlme_confirm->NbRetries; - lora_mlme_confirm.status = (lora_mac_event_info_status_t)mlme_confirm->Status; - lora_mlme_confirm.tx_time_on_air = mlme_confirm->TxTimeOnAir; - - mlme_confirm_handler(&lora_mlme_confirm); -} - /*! * \brief MLME-Indication event function * * \param [IN] mlmeIndication - Pointer to the indication structure. */ -void LoRaWANStack::mlme_indication( MlmeIndication_t *mlmeIndication ) +void LoRaWANStack::mlme_indication_handler(loramac_mlme_indication_t *mlmeIndication) { - switch( mlmeIndication->MlmeIndication ) + switch( mlmeIndication->indication_type ) { case MLME_SCHEDULE_UPLINK: {// The MAC signals that we shall provide an uplink as soon as possible @@ -460,94 +396,96 @@ void LoRaWANStack::set_lora_callbacks(lorawan_app_callbacks_t *cbs) if (cbs->link_check_resp) { _callbacks.link_check_resp = cbs->link_check_resp; } + + if (cbs->battery_level) { + _callbacks.battery_level = cbs->battery_level; + } } } -lora_mac_status_t LoRaWANStack::add_channels(const lora_channelplan_t &channel_plan) +lorawan_status_t LoRaWANStack::add_channels(const lorawan_channelplan_t &channel_plan) { // If device is not initialized, stop right away if (_device_current_state == DEVICE_STATE_NOT_INITIALIZED) { tr_error("Stack not initialized!"); - return LORA_MAC_STATUS_NOT_INITIALIZED; + return LORAWAN_STATUS_NOT_INITIALIZED; } - LoRaMacStatus_t status = _loramac.AddChannelPlan(channel_plan); - - return error_type_converter(status); + return _loramac.AddChannelPlan(channel_plan); } -lora_mac_status_t LoRaWANStack::drop_channel_list() +lorawan_status_t LoRaWANStack::drop_channel_list() { if (_device_current_state == DEVICE_STATE_NOT_INITIALIZED) { tr_error("Stack not initialized!"); - return LORA_MAC_STATUS_NOT_INITIALIZED; + return LORAWAN_STATUS_NOT_INITIALIZED; } - return error_type_converter(_loramac.RemoveChannelPlan()); + return _loramac.RemoveChannelPlan(); } -lora_mac_status_t LoRaWANStack::remove_a_channel(uint8_t channel_id) +lorawan_status_t LoRaWANStack::remove_a_channel(uint8_t channel_id) { if (_device_current_state == DEVICE_STATE_NOT_INITIALIZED ) { tr_error("Stack not initialized!"); - return LORA_MAC_STATUS_NOT_INITIALIZED; + return LORAWAN_STATUS_NOT_INITIALIZED; } - return error_type_converter(_loramac.RemoveSingleChannel(channel_id)); + return _loramac.RemoveSingleChannel(channel_id); } -lora_mac_status_t LoRaWANStack::get_enabled_channels(lora_channelplan_t& channel_plan) +lorawan_status_t LoRaWANStack::get_enabled_channels(lorawan_channelplan_t& channel_plan) { if (_device_current_state == DEVICE_STATE_JOINING || _device_current_state == DEVICE_STATE_NOT_INITIALIZED || _device_current_state == DEVICE_STATE_INIT) { tr_error("Cannot get channel plan until Joined!"); - return LORA_MAC_STATUS_BUSY; + return LORAWAN_STATUS_BUSY; } - return error_type_converter(_loramac.GetChannelPlan(channel_plan)); + return _loramac.GetChannelPlan(channel_plan); } -lora_mac_status_t LoRaWANStack::enable_adaptive_datarate(bool adr_enabled) +lorawan_status_t LoRaWANStack::enable_adaptive_datarate(bool adr_enabled) { if (DEVICE_STATE_NOT_INITIALIZED == _device_current_state) { tr_error("Stack not initialized!"); - return LORA_MAC_STATUS_NOT_INITIALIZED; + return LORAWAN_STATUS_NOT_INITIALIZED; } - lora_mac_mib_request_confirm_t adr_mib_params; + loramac_mib_req_confirm_t adr_mib_params; - adr_mib_params.type = LORA_MIB_ADR; - adr_mib_params.param.adr_enable = adr_enabled; + adr_mib_params.type = MIB_ADR; + adr_mib_params.param.is_adr_enable = adr_enabled; return mib_set_request(&adr_mib_params); } -lora_mac_status_t LoRaWANStack::set_channel_data_rate(uint8_t data_rate) +lorawan_status_t LoRaWANStack::set_channel_data_rate(uint8_t data_rate) { if (DEVICE_STATE_NOT_INITIALIZED == _device_current_state) { tr_error("Stack not initialized!"); - return LORA_MAC_STATUS_NOT_INITIALIZED; + return LORAWAN_STATUS_NOT_INITIALIZED; } - lora_mac_mib_request_confirm_t mib_params; - mib_params.type = LORA_MIB_ADR; + loramac_mib_req_confirm_t mib_params; + mib_params.type = MIB_ADR; if (mib_get_request(&mib_params) == true) { tr_error("Cannot set data rate. Please turn off ADR first."); - return LORA_MAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } - mib_params.type = LORA_MIB_CHANNELS_DATARATE; - mib_params.param.channels_datarate = data_rate; + mib_params.type = MIB_CHANNELS_DATARATE; + mib_params.param.channel_data_rate = data_rate; return mib_set_request(&mib_params); } -void LoRaWANStack::commission_device(const lora_dev_commission_t &commission_data) +void LoRaWANStack::commission_device(const lorawan_dev_commission_t &commission_data) { _lw_session.connection.connect_type = commission_data.connection.connect_type; _lw_session.downlink_counter = commission_data.downlink_counter; @@ -576,14 +514,14 @@ void LoRaWANStack::commission_device(const lora_dev_commission_t &commission_dat * * Join OTAA */ -lora_mac_status_t LoRaWANStack::join_request_by_otaa(const lorawan_connect_t ¶ms) +lorawan_status_t LoRaWANStack::join_request_by_otaa(const lorawan_connect_t ¶ms) { - lora_dev_commission_t commission; + lorawan_dev_commission_t commission; if (DEVICE_STATE_NOT_INITIALIZED == _device_current_state) { tr_error("Stack not initialized!"); - return LORA_MAC_STATUS_NOT_INITIALIZED; + return LORAWAN_STATUS_NOT_INITIALIZED; } tr_debug("Initiating OTAA"); @@ -609,14 +547,14 @@ lora_mac_status_t LoRaWANStack::join_request_by_otaa(const lorawan_connect_t &pa * * Connect ABP */ -lora_mac_status_t LoRaWANStack::activation_by_personalization(const lorawan_connect_t ¶ms) +lorawan_status_t LoRaWANStack::activation_by_personalization(const lorawan_connect_t ¶ms) { - lora_mac_status_t status; - lora_dev_commission_t commission; + lorawan_status_t status; + lorawan_dev_commission_t commission; if (DEVICE_STATE_NOT_INITIALIZED == _device_current_state) { tr_error("Stack not initialized!"); - return LORA_MAC_STATUS_NOT_INITIALIZED; + return LORAWAN_STATUS_NOT_INITIALIZED; } tr_debug("Initiating ABP"); @@ -652,33 +590,33 @@ int16_t LoRaWANStack::handle_tx(uint8_t port, const uint8_t* data, uint16_t length, uint8_t flags) { if (!_lw_session.active) { - return LORA_MAC_STATUS_NO_ACTIVE_SESSIONS; + return LORAWAN_STATUS_NO_ACTIVE_SESSIONS; } if (_tx_msg.tx_ongoing) { - return LORA_MAC_STATUS_WOULD_BLOCK; + return LORAWAN_STATUS_WOULD_BLOCK; } #if defined(LORAWAN_COMPLIANCE_TEST) if (_compliance_test.running) { - return LORA_MAC_STATUS_COMPLIANCE_TEST_ON; + return LORAWAN_STATUS_COMPLIANCE_TEST_ON; } #endif - lora_mac_mib_request_confirm_t mib_req; - lora_mac_status_t status; - mib_req.type = LORA_MIB_NETWORK_JOINED; + loramac_mib_req_confirm_t mib_req; + lorawan_status_t status; + mib_req.type = MIB_NETWORK_JOINED; status = mib_get_request(&mib_req); - if (status == LORA_MAC_STATUS_OK) { - if (mib_req.param.is_network_joined == false) { - return LORA_MAC_STATUS_NO_NETWORK_JOINED; + if (status == LORAWAN_STATUS_OK) { + if (mib_req.param.is_nwk_joined == false) { + return LORAWAN_STATUS_NO_NETWORK_JOINED; } } status = set_application_port(port); - if (status != LORA_MAC_STATUS_OK) { + if (status != LORAWAN_STATUS_OK) { tr_error("Illegal application port definition."); return status; } @@ -686,7 +624,7 @@ int16_t LoRaWANStack::handle_tx(uint8_t port, const uint8_t* data, if (flags == 0 || (flags & MSG_FLAG_MASK) == (MSG_CONFIRMED_FLAG|MSG_UNCONFIRMED_FLAG)) { tr_error("CONFIRMED and UNCONFIRMED are mutually exclusive for send()"); - return LORA_MAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } _tx_msg.port = port; @@ -725,8 +663,8 @@ int16_t LoRaWANStack::handle_tx(uint8_t port, const uint8_t* data, || (flags & MSG_FLAG_MASK) == MSG_UNCONFIRMED_MULTICAST || (flags & MSG_FLAG_MASK) == MSG_UNCONFIRMED_PROPRIETARY) { - _tx_msg.type = LORA_MCPS_UNCONFIRMED; - _tx_msg.message_u.unconfirmed.f_port = _app_port; + _tx_msg.type = MCPS_UNCONFIRMED; + _tx_msg.message_u.unconfirmed.fport = _app_port; } // Handles all confirmed messages, including proprietary and multicast @@ -734,8 +672,8 @@ int16_t LoRaWANStack::handle_tx(uint8_t port, const uint8_t* data, || (flags & MSG_FLAG_MASK) == MSG_CONFIRMED_MULTICAST || (flags & MSG_FLAG_MASK) == MSG_CONFIRMED_PROPRIETARY) { - _tx_msg.type = LORA_MCPS_CONFIRMED; - _tx_msg.message_u.confirmed.f_port = _app_port; + _tx_msg.type = MCPS_CONFIRMED; + _tx_msg.message_u.confirmed.fport = _app_port; _tx_msg.message_u.confirmed.nb_trials = _num_retry; } @@ -752,35 +690,35 @@ int16_t LoRaWANStack::handle_rx(const uint8_t port, uint8_t* data, uint16_t length, uint8_t flags) { if (!_lw_session.active) { - return LORA_MAC_STATUS_NO_ACTIVE_SESSIONS; + return LORAWAN_STATUS_NO_ACTIVE_SESSIONS; } // No messages to read. if (!_rx_msg.receive_ready) { - return LORA_MAC_STATUS_WOULD_BLOCK; + return LORAWAN_STATUS_WOULD_BLOCK; } #if defined(LORAWAN_COMPLIANCE_TEST) if (_compliance_test.running) { - return LORA_MAC_STATUS_COMPLIANCE_TEST_ON; + return LORAWAN_STATUS_COMPLIANCE_TEST_ON; } #endif if (data == NULL) { - return LORA_MAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } - uint8_t *base_ptr = _rx_msg.rx_message.mcps_indication.buffer; - uint16_t base_size = _rx_msg.rx_message.mcps_indication.buffer_size; + uint8_t *base_ptr = _rx_msg.msg.mcps_indication.buffer; + uint16_t base_size = _rx_msg.msg.mcps_indication.buffer_size; bool read_complete = false; - if (_rx_msg.rx_message.mcps_indication.port != port) { + if (_rx_msg.msg.mcps_indication.port != port) { // Nothing yet received for this particular port - return LORA_MAC_STATUS_WOULD_BLOCK; + return LORAWAN_STATUS_WOULD_BLOCK; } // check if message received is a Confirmed message and user subscribed to it or not - if (_rx_msg.rx_message.mcps_indication.mcps_indication == LORA_MCPS_CONFIRMED + if (_rx_msg.msg.mcps_indication.type == MCPS_CONFIRMED && ((flags & MSG_FLAG_MASK) == MSG_CONFIRMED_FLAG || (flags & MSG_FLAG_MASK) == MSG_CONFIRMED_MULTICAST || (flags & MSG_FLAG_MASK) == MSG_CONFIRMED_PROPRIETARY)) { @@ -789,7 +727,7 @@ int16_t LoRaWANStack::handle_rx(const uint8_t port, uint8_t* data, } // check if message received is a Unconfirmed message and user subscribed to it or not - if (_rx_msg.rx_message.mcps_indication.mcps_indication == LORA_MCPS_UNCONFIRMED + if (_rx_msg.msg.mcps_indication.type == MCPS_UNCONFIRMED && ((flags & MSG_FLAG_MASK) == MSG_UNCONFIRMED_FLAG || (flags & MSG_FLAG_MASK) == MSG_UNCONFIRMED_MULTICAST || (flags & MSG_FLAG_MASK) == MSG_UNCONFIRMED_PROPRIETARY)) { @@ -798,10 +736,10 @@ int16_t LoRaWANStack::handle_rx(const uint8_t port, uint8_t* data, // check the length of received message whether we can fit into user // buffer completely or not - if (_rx_msg.rx_message.mcps_indication.buffer_size > length && + if (_rx_msg.msg.mcps_indication.buffer_size > length && _rx_msg.prev_read_size == 0) { // we can't fit into user buffer. Invoke counter measures - _rx_msg.pending_size = _rx_msg.rx_message.mcps_indication.buffer_size - length; + _rx_msg.pending_size = _rx_msg.msg.mcps_indication.buffer_size - length; base_size = length; _rx_msg.prev_read_size = base_size; memcpy(data, base_ptr, base_size); @@ -823,47 +761,20 @@ int16_t LoRaWANStack::handle_rx(const uint8_t port, uint8_t* data, // anything pending. If not, memset the buffer to zero and indicate // that no read is in progress if (read_complete) { - memset(_rx_msg.rx_message.mcps_indication.buffer, 0, LORAMAC_PHY_MAXPAYLOAD); + memset(_rx_msg.msg.mcps_indication.buffer, 0, LORAMAC_PHY_MAXPAYLOAD); _rx_msg.receive_ready = false; } return base_size; } -lora_mac_status_t LoRaWANStack::mlme_request_handler(lora_mac_mlme_req_t *mlme_request) +lorawan_status_t LoRaWANStack::mlme_request_handler(loramac_mlme_req_t *mlme_request) { - MlmeReq_t request; - - if (NULL == mlme_request) { - return LORA_MAC_STATUS_PARAMETER_INVALID; + if (mlme_request == NULL) { + return LORAWAN_STATUS_PARAMETER_INVALID; } - request.Type = (Mlme_t)mlme_request->type; - - switch (mlme_request->type) { - case LORA_MLME_JOIN: - request.Req.Join.AppEui = mlme_request->req.join.app_eui; - request.Req.Join.AppKey = mlme_request->req.join.app_key; - request.Req.Join.DevEui = mlme_request->req.join.dev_eui; - request.Req.Join.NbTrials = mlme_request->req.join.nb_trials; - break; - // This is handled in semtech stack. Only type value is needed. - case LORA_MLME_LINK_CHECK: - break; - case LORA_MLME_TXCW: - /* no break */ - /* Fall through */ - case LORA_MLME_TXCW_1: - request.Req.TxCw.Frequency = mlme_request->req.tx_cw.frequency; - request.Req.TxCw.Power = mlme_request->req.tx_cw.power; - request.Req.TxCw.Timeout = mlme_request->req.tx_cw.timeout; - break; - default: - return LORA_MAC_STATUS_SERVICE_UNKNOWN; - break; - } - - return error_type_converter(_loramac.LoRaMacMlmeRequest(&request)); + return _loramac.LoRaMacMlmeRequest(mlme_request); } /** MLME-Confirm event function @@ -871,15 +782,15 @@ lora_mac_status_t LoRaWANStack::mlme_request_handler(lora_mac_mlme_req_t *mlme_r * \param mlme_confirm Pointer to the confirm structure, * containing confirm attributes. */ -void LoRaWANStack::mlme_confirm_handler(lora_mac_mlme_confirm_t *mlme_confirm) +void LoRaWANStack::mlme_confirm_handler(loramac_mlme_confirm_t *mlme_confirm) { if (NULL == mlme_confirm) { return; } - switch (mlme_confirm->mlme_request) { - case LORA_MLME_JOIN: - if (mlme_confirm->status == LORA_EVENT_INFO_STATUS_OK) { + switch (mlme_confirm->req_type) { + case MLME_JOIN: + if (mlme_confirm->status == LORAMAC_EVENT_INFO_STATUS_OK) { // Status is OK, node has joined the network set_device_state(DEVICE_STATE_JOINED); lora_state_machine(); @@ -893,8 +804,8 @@ void LoRaWANStack::mlme_confirm_handler(lora_mac_mlme_confirm_t *mlme_confirm) } } break; - case LORA_MLME_LINK_CHECK: - if (mlme_confirm->status == LORA_EVENT_INFO_STATUS_OK) { + case MLME_LINK_CHECK: + if (mlme_confirm->status == LORAMAC_EVENT_INFO_STATUS_OK) { // Check DemodMargin // Check NbGateways #if defined(LORAWAN_COMPLIANCE_TEST) @@ -907,8 +818,9 @@ void LoRaWANStack::mlme_confirm_handler(lora_mac_mlme_confirm_t *mlme_confirm) { // normal operation as oppose to compliance testing if (_callbacks.link_check_resp) { - _queue->call(_callbacks.link_check_resp, mlme_confirm->demod_margin, - mlme_confirm->nb_gateways); + _queue->call(_callbacks.link_check_resp, + mlme_confirm->demod_margin, + mlme_confirm->nb_gateways); } } } @@ -919,41 +831,13 @@ void LoRaWANStack::mlme_confirm_handler(lora_mac_mlme_confirm_t *mlme_confirm) } } -lora_mac_status_t LoRaWANStack::mcps_request_handler(lora_mac_mcps_req_t *mcps_request) +lorawan_status_t LoRaWANStack::mcps_request_handler(loramac_mcps_req_t *mcps_request) { - McpsReq_t request; - - if (NULL == mcps_request) { - return LORA_MAC_STATUS_PARAMETER_INVALID; + if (mcps_request == NULL) { + return LORAWAN_STATUS_PARAMETER_INVALID; } - request.Type = (Mcps_t)mcps_request->type; - - switch (mcps_request->type) { - case LORA_MCPS_UNCONFIRMED: - request.Req.Unconfirmed.Datarate = mcps_request->req.unconfirmed.datarate; - request.Req.Unconfirmed.fBuffer = mcps_request->f_buffer; - request.Req.Unconfirmed.fBufferSize = mcps_request->f_buffer_size; - request.Req.Unconfirmed.fPort = mcps_request->req.unconfirmed.f_port; - break; - case LORA_MCPS_CONFIRMED: - request.Req.Confirmed.Datarate = mcps_request->req.confirmed.datarate; - request.Req.Confirmed.fBuffer = mcps_request->f_buffer; - request.Req.Confirmed.fBufferSize = mcps_request->f_buffer_size; - request.Req.Confirmed.fPort = mcps_request->req.confirmed.f_port; - request.Req.Confirmed.NbTrials = mcps_request->req.confirmed.nb_trials; - break; - case LORA_MCPS_PROPRIETARY: - request.Req.Proprietary.Datarate = mcps_request->req.proprietary.datarate; - request.Req.Proprietary.fBuffer = mcps_request->f_buffer; - request.Req.Proprietary.fBufferSize = mcps_request->f_buffer_size; - break; - default: - return LORA_MAC_STATUS_SERVICE_UNKNOWN; - break; - } - - return error_type_converter(_loramac.LoRaMacMcpsRequest(&request)); + return _loramac.LoRaMacMcpsRequest(mcps_request); } /** MCPS-Confirm event function @@ -961,14 +845,14 @@ lora_mac_status_t LoRaWANStack::mcps_request_handler(lora_mac_mcps_req_t *mcps_r * \param mcps_confirm Pointer to the confirm structure, * containing confirm attributes. */ -void LoRaWANStack::mcps_confirm_handler(lora_mac_mcps_confirm_t *mcps_confirm) +void LoRaWANStack::mcps_confirm_handler(loramac_mcps_confirm_t *mcps_confirm) { if (mcps_confirm == NULL) { tr_error("mcps_confirm: struct [in] is null."); return; } - if (mcps_confirm->status != LORA_EVENT_INFO_STATUS_OK) { + if (mcps_confirm->status != LORAMAC_EVENT_INFO_STATUS_OK) { // Couldn't schedule packet, ack not recieved in CONFIRMED case // or some other error happened. Discard buffer, unset the tx-ongoing // flag and let the application know @@ -979,12 +863,12 @@ void LoRaWANStack::mcps_confirm_handler(lora_mac_mcps_confirm_t *mcps_confirm) tr_error("mcps_confirm_handler: Error code = %d", mcps_confirm->status); // If sending timed out, we have a special event for that - if (mcps_confirm->status == LORA_EVENT_INFO_STATUS_TX_TIMEOUT) { + if (mcps_confirm->status == LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT) { if (_callbacks.events) { _queue->call(_callbacks.events, TX_TIMEOUT); } return; - } if (mcps_confirm->status == LORA_EVENT_INFO_STATUS_RX2_TIMEOUT) { + } if (mcps_confirm->status == LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT) { tr_debug("Did not receive Ack"); } @@ -997,7 +881,7 @@ void LoRaWANStack::mcps_confirm_handler(lora_mac_mcps_confirm_t *mcps_confirm) // If No errors encountered, let's proceed with the status. // CONFIRMED needs special handling because of acks - if (mcps_confirm->mcps_request == LORA_MCPS_CONFIRMED) { + if (mcps_confirm->req_type == MCPS_CONFIRMED) { // In confirmed case, we need to check if we have received the Ack or not. // This is actually just being paranoid about ack because LoRaMac.cpp doesn't // call this callback until an ack is received. @@ -1009,7 +893,7 @@ void LoRaWANStack::mcps_confirm_handler(lora_mac_mcps_confirm_t *mcps_confirm) // This part is common to both CONFIRMED and UNCONFIRMED. // Tell the application about successful transmission and store // data rate plus frame counter. - _lw_session.uplink_counter = mcps_confirm->uplink_counter; + _lw_session.uplink_counter = mcps_confirm->ul_frame_counter; _tx_msg.tx_ongoing = false; if (_callbacks.events) { _queue->call(_callbacks.events, TX_DONE); @@ -1021,28 +905,28 @@ void LoRaWANStack::mcps_confirm_handler(lora_mac_mcps_confirm_t *mcps_confirm) * \param mcps_indication Pointer to the indication structure, * containing indication attributes. */ -void LoRaWANStack::mcps_indication_handler(lora_mac_mcps_indication_t *mcps_indication) +void LoRaWANStack::mcps_indication_handler(loramac_mcps_indication_t *mcps_indication) { if (mcps_indication == NULL) { tr_error("mcps_indication: struct [in] is null."); return; } - if (mcps_indication->status != LORA_EVENT_INFO_STATUS_OK) { + if (mcps_indication->status != LORAMAC_EVENT_INFO_STATUS_OK) { if (_callbacks.events) { _queue->call(_callbacks.events, RX_ERROR); } return; } - switch (mcps_indication->mcps_indication) { - case LORA_MCPS_UNCONFIRMED: + switch (mcps_indication->type) { + case MCPS_UNCONFIRMED: break; - case LORA_MCPS_CONFIRMED: + case MCPS_CONFIRMED: break; - case LORA_MCPS_PROPRIETARY: + case MCPS_PROPRIETARY: break; - case LORA_MCPS_MULTICAST: + case MCPS_MULTICAST: break; default: break; @@ -1066,7 +950,7 @@ void LoRaWANStack::mcps_indication_handler(lora_mac_mcps_indication_t *mcps_indi } #endif - if (mcps_indication->rx_data == true) { + if (mcps_indication->is_data_recvd == true) { switch (mcps_indication->port) { case 224: #if defined(LORAWAN_COMPLIANCE_TEST) @@ -1078,11 +962,11 @@ void LoRaWANStack::mcps_indication_handler(lora_mac_mcps_indication_t *mcps_indi break; default: if (is_port_valid(mcps_indication->port) == true || - mcps_indication->mcps_indication == LORA_MCPS_PROPRIETARY) { + mcps_indication->type == MCPS_PROPRIETARY) { // Valid message arrived. // Save message to buffer with session information. - if (_rx_msg.rx_message.mcps_indication.buffer_size > LORAMAC_PHY_MAXPAYLOAD) { + if (_rx_msg.msg.mcps_indication.buffer_size > LORAMAC_PHY_MAXPAYLOAD) { // This may never happen as both radio and MAC are limited // to the size 255 bytes tr_debug("Cannot receive more than buffer capacity!"); @@ -1092,15 +976,15 @@ void LoRaWANStack::mcps_indication_handler(lora_mac_mcps_indication_t *mcps_indi return; } else { _rx_msg.type = LORAMAC_RX_MCPS_INDICATION; - _rx_msg.rx_message.mcps_indication.buffer_size = mcps_indication->buffer_size; - _rx_msg.rx_message.mcps_indication.port = mcps_indication->port; - // Copy message for user - memcpy(_rx_msg.rx_message.mcps_indication.buffer, - mcps_indication->buffer, mcps_indication->buffer_size); + _rx_msg.msg.mcps_indication.buffer_size = mcps_indication->buffer_size; + _rx_msg.msg.mcps_indication.port = mcps_indication->port; + + // no copy, just set the pointer for the user + _rx_msg.msg.mcps_indication.buffer = mcps_indication->buffer; } // Notify application about received frame.. - tr_debug("Received %d bytes", _rx_msg.rx_message.mcps_indication.buffer_size); + tr_debug("Received %d bytes", _rx_msg.msg.mcps_indication.buffer_size); _rx_msg.receive_ready = true; if (_callbacks.events) { _queue->call(_callbacks.events, RX_DONE); @@ -1110,7 +994,7 @@ void LoRaWANStack::mcps_indication_handler(lora_mac_mcps_indication_t *mcps_indi // with CONFIRMED flag set. We always set a CONFIRMED flag so // that we could retry a certain number of times if the uplink // failed for some reason - if (mcps_indication->frame_pending) { + if (mcps_indication->fpending_status) { handle_tx(mcps_indication->port, NULL, 0, MSG_CONFIRMED_FLAG); } } else { @@ -1127,7 +1011,7 @@ void LoRaWANStack::mcps_indication_handler(lora_mac_mcps_indication_t *mcps_indi * \param mcps_indication Pointer to the indication structure, * containing indication attributes. */ -void LoRaWANStack::compliance_test_handler(lora_mac_mcps_indication_t *mcps_indication) +void LoRaWANStack::compliance_test_handler(loramac_mcps_indication_t *mcps_indication) { if (_compliance_test.running == false) { // Check compliance test enable command (i) @@ -1146,9 +1030,9 @@ void LoRaWANStack::compliance_test_handler(lora_mac_mcps_indication_t *mcps_indi _compliance_test.running = true; _compliance_test.state = 1; - lora_mac_mib_request_confirm_t mib_req; - mib_req.type = LORA_MIB_ADR; - mib_req.param.adr_enable = true; + loramac_mib_req_confirm_t mib_req; + mib_req.type = MIB_ADR; + mib_req.param.is_adr_enable = true; mib_set_request(&mib_req); #if MBED_CONF_LORA_PHY == 0 @@ -1169,9 +1053,9 @@ void LoRaWANStack::compliance_test_handler(lora_mac_mcps_indication_t *mcps_indi _compliance_test.downlink_counter = 0; _compliance_test.running = false; - lora_mac_mib_request_confirm_t mib_req; - mib_req.type = LORA_MIB_ADR; - mib_req.param.adr_enable = MBED_CONF_LORA_ADR_ON; + loramac_mib_req_confirm_t mib_req; + mib_req.type = MIB_ADR; + mib_req.param.is_adr_enable = MBED_CONF_LORA_ADR_ON; mib_set_request(&mib_req); #if MBED_CONF_LORA_PHY == 0 _loramac.LoRaMacTestSetDutyCycleOn(MBED_CONF_LORA_DUTY_CYCLE_ON); @@ -1207,13 +1091,13 @@ void LoRaWANStack::compliance_test_handler(lora_mac_mcps_indication_t *mcps_indi send_compliance_test_frame_to_mac(); break; case 5: // (viii) - lora_mac_mlme_req_t mlme_req; - mlme_req.type = LORA_MLME_LINK_CHECK; + loramac_mlme_req_t mlme_req; + mlme_req.type = MLME_LINK_CHECK; mlme_request_handler(&mlme_req); break; case 6: // (ix) - lora_mac_mlme_req_t mlme_request; - lora_mac_mib_request_confirm_t mib_request; + loramac_mlme_req_t mlme_request; + loramac_mib_req_confirm_t mib_request; // Disable TestMode and revert back to normal operation _compliance_test.is_tx_confirmed = true; @@ -1222,13 +1106,13 @@ void LoRaWANStack::compliance_test_handler(lora_mac_mcps_indication_t *mcps_indi _compliance_test.downlink_counter = 0; _compliance_test.running = false; - mib_request.type = LORA_MIB_ADR; - mib_request.param.adr_enable = MBED_CONF_LORA_ADR_ON; + mib_request.type = MIB_ADR; + mib_request.param.is_adr_enable = MBED_CONF_LORA_ADR_ON; mib_set_request(&mib_request); #if MBED_CONF_LORA_PHY == 0 _loramac.LoRaMacTestSetDutyCycleOn(MBED_CONF_LORA_DUTY_CYCLE_ON); #endif - mlme_request.type = LORA_MLME_JOIN; + mlme_request.type = MLME_JOIN; mlme_request.req.join.dev_eui = _lw_session.connection.connection_u.otaa.dev_eui; mlme_request.req.join.app_eui = _lw_session.connection.connection_u.otaa.app_eui; mlme_request.req.join.app_key = _lw_session.connection.connection_u.otaa.app_key; @@ -1237,17 +1121,17 @@ void LoRaWANStack::compliance_test_handler(lora_mac_mcps_indication_t *mcps_indi break; case 7: // (x) if (mcps_indication->buffer_size == 3) { - lora_mac_mlme_req_t mlme_req; - mlme_req.type = LORA_MLME_TXCW; - mlme_req.req.tx_cw.timeout = (uint16_t)((mcps_indication->buffer[1] << 8) | mcps_indication->buffer[2]); + loramac_mlme_req_t mlme_req; + mlme_req.type = MLME_TXCW; + mlme_req.req.cw_tx_mode.timeout = (uint16_t)((mcps_indication->buffer[1] << 8) | mcps_indication->buffer[2]); mlme_request_handler(&mlme_req); } else if (mcps_indication->buffer_size == 7) { - lora_mac_mlme_req_t mlme_req; - mlme_req.type = LORA_MLME_TXCW_1; - mlme_req.req.tx_cw.timeout = (uint16_t)((mcps_indication->buffer[1] << 8) | mcps_indication->buffer[2]); - mlme_req.req.tx_cw.frequency = (uint32_t)((mcps_indication->buffer[3] << 16) | (mcps_indication->buffer[4] << 8) + loramac_mlme_req_t mlme_req; + mlme_req.type = MLME_TXCW_1; + mlme_req.req.cw_tx_mode.timeout = (uint16_t)((mcps_indication->buffer[1] << 8) | mcps_indication->buffer[2]); + mlme_req.req.cw_tx_mode.frequency = (uint32_t)((mcps_indication->buffer[3] << 16) | (mcps_indication->buffer[4] << 8) | mcps_indication->buffer[5]) * 100; - mlme_req.req.tx_cw.power = mcps_indication->buffer[6]; + mlme_req.req.cw_tx_mode.power = mcps_indication->buffer[6]; mlme_request_handler(&mlme_req); } _compliance_test.state = 1; @@ -1257,401 +1141,36 @@ void LoRaWANStack::compliance_test_handler(lora_mac_mcps_indication_t *mcps_indi } #endif -lora_mac_status_t LoRaWANStack::mib_set_request(lora_mac_mib_request_confirm_t *mib_set_params) +lorawan_status_t LoRaWANStack::mib_set_request(loramac_mib_req_confirm_t *mib_set_params) { - MibRequestConfirm_t stack_mib_set; - ChannelParams_t stack_channel_params; - MulticastParams_t *stack_multicast_params = NULL; - MulticastParams_t *head = NULL; - lora_mac_status_t status; - if (NULL == mib_set_params) { - return LORA_MAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } - // Interpreting from lora_mac_mib_t to Mib_t - stack_mib_set.Type = interpret_mib_req_confirm_type(mib_set_params->type); - - switch (mib_set_params->type) { - case LORA_MIB_DEVICE_CLASS: - stack_mib_set.Param.Class = (DeviceClass_t)mib_set_params->param.lora_class; - break; - - case LORA_MIB_NETWORK_JOINED: - stack_mib_set.Param.IsNetworkJoined = mib_set_params->param.is_network_joined; - break; - - case LORA_MIB_ADR: - stack_mib_set.Param.AdrEnable = mib_set_params->param.adr_enable; - break; - - case LORA_MIB_NET_ID: - stack_mib_set.Param.NetID = mib_set_params->param.net_id; - break; - - case LORA_MIB_DEV_ADDR: - stack_mib_set.Param.DevAddr = mib_set_params->param.dev_addr; - break; - - case LORA_MIB_NWK_SKEY: - stack_mib_set.Param.NwkSKey = mib_set_params->param.nwk_skey; - break; - - case LORA_MIB_APP_SKEY: - stack_mib_set.Param.AppSKey = mib_set_params->param.app_skey; - break; - - case LORA_MIB_PUBLIC_NETWORK: - stack_mib_set.Param.EnablePublicNetwork = mib_set_params->param.enable_public_network; - break; - - case LORA_MIB_REPEATER_SUPPORT: - stack_mib_set.Param.EnableRepeaterSupport = mib_set_params->param.enable_repeater_support; - break; - - case LORA_MIB_CHANNELS: - stack_channel_params.Frequency = mib_set_params->param.channel_list->frequency; - stack_channel_params.DrRange.Value = mib_set_params->param.channel_list->dr_range.value; - stack_channel_params.DrRange.Fields.Min = mib_set_params->param.channel_list->dr_range.lora_mac_fields_s.min; - stack_channel_params.DrRange.Fields.Max = mib_set_params->param.channel_list->dr_range.lora_mac_fields_s.max; - stack_channel_params.Band = mib_set_params->param.channel_list->band; - stack_channel_params.Rx1Frequency = mib_set_params->param.channel_list->rx1_frequency; - stack_mib_set.Param.ChannelList = &stack_channel_params; - break; - - case LORA_MIB_RX2_CHANNEL: - stack_mib_set.Param.Rx2Channel.Frequency = mib_set_params->param.rx2_channel.frequency; - stack_mib_set.Param.Rx2Channel.Datarate = mib_set_params->param.rx2_channel.datarate; - break; - - case LORA_MIB_RX2_DEFAULT_CHANNEL: - stack_mib_set.Param.Rx2DefaultChannel.Frequency = mib_set_params->param.rx2_default_channel.frequency; - stack_mib_set.Param.Rx2DefaultChannel.Datarate = mib_set_params->param.rx2_default_channel.datarate; - break; - - case LORA_MIB_CHANNELS_MASK: - stack_mib_set.Param.ChannelsMask = mib_set_params->param.channels_mask; - break; - - case LORA_MIB_CHANNELS_DEFAULT_MASK: - stack_mib_set.Param.ChannelsDefaultMask = mib_set_params->param.channels_default_mask; - break; - - case LORA_MIB_CHANNELS_NB_REP: - stack_mib_set.Param.ChannelNbRep = mib_set_params->param.channel_nb_rep; - break; - - case LORA_MIB_MAX_RX_WINDOW_DURATION: - stack_mib_set.Param.MaxRxWindow = mib_set_params->param.max_rx_window; - break; - - case LORA_MIB_RECEIVE_DELAY_1: - stack_mib_set.Param.ReceiveDelay1 = mib_set_params->param.receive_delay1; - break; - - case LORA_MIB_RECEIVE_DELAY_2: - stack_mib_set.Param.ReceiveDelay2 = mib_set_params->param.receive_delay2; - break; - - case LORA_MIB_JOIN_ACCEPT_DELAY_1: - stack_mib_set.Param.JoinAcceptDelay1 = mib_set_params->param.join_accept_delay1; - break; - - case LORA_MIB_JOIN_ACCEPT_DELAY_2: - stack_mib_set.Param.JoinAcceptDelay2 = mib_set_params->param.join_accept_delay2; - break; - - case LORA_MIB_CHANNELS_DEFAULT_DATARATE: - stack_mib_set.Param.ChannelsDefaultDatarate = mib_set_params->param.channels_default_datarate; - break; - - case LORA_MIB_CHANNELS_DATARATE: - stack_mib_set.Param.ChannelsDatarate = mib_set_params->param.channels_datarate; - break; - - case LORA_MIB_CHANNELS_TX_POWER: - stack_mib_set.Param.ChannelsTxPower = mib_set_params->param.channels_tx_power; - break; - - case LORA_MIB_CHANNELS_DEFAULT_TX_POWER: - stack_mib_set.Param.ChannelsDefaultTxPower = mib_set_params->param.channels_default_tx_power; - break; - - case LORA_MIB_UPLINK_COUNTER: - stack_mib_set.Param.UpLinkCounter = mib_set_params->param.uplink_counter; - break; - - case LORA_MIB_DOWNLINK_COUNTER: - stack_mib_set.Param.DownLinkCounter = mib_set_params->param.downlink_counter; - break; - - case LORA_MIB_MULTICAST_CHANNEL: - /* - * Parse multicast list (C++ linked list) - */ - while (mib_set_params->param.multicast_list != NULL) { - if (stack_multicast_params == NULL) { - stack_multicast_params = new MulticastParams_t; - head = stack_multicast_params; - } else { - while (stack_multicast_params != NULL) { - stack_multicast_params = stack_multicast_params->Next; - } - - stack_multicast_params = new MulticastParams_t; - } - - stack_multicast_params->Address = mib_set_params->param.multicast_list->address; - for (int i = 0; i < 16; i++) { - stack_multicast_params->NwkSKey[i] = mib_set_params->param.multicast_list->nwk_skey[i]; - stack_multicast_params->AppSKey[i] = mib_set_params->param.multicast_list->app_skey[i]; - } - - stack_multicast_params->DownLinkCounter = mib_set_params->param.multicast_list->downlink_counter; - } - - stack_mib_set.Param.MulticastList = head; - break; - - case LORA_MIB_SYSTEM_MAX_RX_ERROR: - stack_mib_set.Param.SystemMaxRxError = mib_set_params->param.system_max_rx_error; - break; - - case LORA_MIB_MIN_RX_SYMBOLS: - stack_mib_set.Param.MinRxSymbols = mib_set_params->param.min_rx_symbols; - break; - - default: - return LORA_MAC_STATUS_SERVICE_UNKNOWN; - break; - } - - /* - * Set MIB data to LoRa stack - */ - status = error_type_converter(_loramac.LoRaMacMibSetRequestConfirm(&stack_mib_set)); - /* - * Release memory if reserved by multicast list - */ - if (NULL != head) { - while (NULL != head) { - delete head; - head = NULL; - head = stack_mib_set.Param.MulticastList->Next; - } - stack_mib_set.Param.MulticastList = NULL; - } - - return status; + return _loramac.LoRaMacMibSetRequestConfirm(mib_set_params); } -lora_mac_status_t LoRaWANStack::mib_get_request(lora_mac_mib_request_confirm_t *mib_get_params) +lorawan_status_t LoRaWANStack::mib_get_request(loramac_mib_req_confirm_t *mib_get_params) { - MibRequestConfirm_t stack_mib_get; - MulticastParams_t *origin_multicast_list = NULL; - lora_mac_multicast_params_t *new_multicast_list = NULL; - lora_mac_status_t mac_status = LORA_MAC_STATUS_OK; - if(NULL == mib_get_params) { - return LORA_MAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } - // Interprets from lora_mac_mib_t to Mib_t - stack_mib_get.Type = interpret_mib_req_confirm_type(mib_get_params->type); - mac_status = error_type_converter(_loramac.LoRaMacMibGetRequestConfirm(&stack_mib_get)); + return _loramac.LoRaMacMibGetRequestConfirm(mib_get_params); - if (LORA_MAC_STATUS_OK != mac_status) { - return LORA_MAC_STATUS_SERVICE_UNKNOWN; - } - switch(mib_get_params->type) { - case LORA_MIB_DEVICE_CLASS: - mib_get_params->param.lora_class = (lora_mac_device_class_t)stack_mib_get.Param.Class; - break; - case LORA_MIB_NETWORK_JOINED: - mib_get_params->param.is_network_joined = stack_mib_get.Param.IsNetworkJoined; - break; - case LORA_MIB_ADR: - mib_get_params->param.adr_enable = stack_mib_get.Param.AdrEnable; - break; - case LORA_MIB_NET_ID: - mib_get_params->param.net_id = stack_mib_get.Param.NetID; - break; - case LORA_MIB_DEV_ADDR: - mib_get_params->param.dev_addr = stack_mib_get.Param.DevAddr; - break; - case LORA_MIB_NWK_SKEY: - mib_get_params->param.nwk_skey = stack_mib_get.Param.NwkSKey; - break; - case LORA_MIB_APP_SKEY: - mib_get_params->param.app_skey = stack_mib_get.Param.AppSKey; - break; - case LORA_MIB_PUBLIC_NETWORK: - mib_get_params->param.enable_public_network = stack_mib_get.Param.EnablePublicNetwork; - break; - case LORA_MIB_REPEATER_SUPPORT: - mib_get_params->param.enable_repeater_support = stack_mib_get.Param.EnableRepeaterSupport; - break; - case LORA_MIB_CHANNELS: - mib_get_params->param.channel_list = (lora_mac_channel_params_t *) stack_mib_get.Param.ChannelList; - break; - case LORA_MIB_RX2_CHANNEL: - mib_get_params->param.rx2_channel.datarate = stack_mib_get.Param.Rx2Channel.Datarate; - mib_get_params->param.rx2_channel.frequency = stack_mib_get.Param.Rx2Channel.Frequency; - break; - case LORA_MIB_RX2_DEFAULT_CHANNEL: - mib_get_params->param.rx2_default_channel.datarate = stack_mib_get.Param.Rx2DefaultChannel.Datarate; - mib_get_params->param.rx2_default_channel.frequency = stack_mib_get.Param.Rx2DefaultChannel.Frequency; - break; - case LORA_MIB_CHANNELS_DEFAULT_MASK: - mib_get_params->param.channels_default_mask = stack_mib_get.Param.ChannelsDefaultMask; - break; - case LORA_MIB_CHANNELS_MASK: - mib_get_params->param.channels_mask = stack_mib_get.Param.ChannelsMask; - break; - case LORA_MIB_CHANNELS_NB_REP: - mib_get_params->param.channel_nb_rep = stack_mib_get.Param.ChannelNbRep; - break; - case LORA_MIB_MAX_RX_WINDOW_DURATION: - mib_get_params->param.max_rx_window = stack_mib_get.Param.MaxRxWindow; - break; - case LORA_MIB_RECEIVE_DELAY_1: - mib_get_params->param.receive_delay1 = stack_mib_get.Param.ReceiveDelay1; - break; - case LORA_MIB_RECEIVE_DELAY_2: - mib_get_params->param.receive_delay2 = stack_mib_get.Param.ReceiveDelay2; - break; - case LORA_MIB_JOIN_ACCEPT_DELAY_1: - mib_get_params->param.join_accept_delay1 = stack_mib_get.Param.JoinAcceptDelay1; - break; - case LORA_MIB_JOIN_ACCEPT_DELAY_2: - mib_get_params->param.join_accept_delay2 = stack_mib_get.Param.JoinAcceptDelay2; - break; - case LORA_MIB_CHANNELS_DEFAULT_DATARATE: - mib_get_params->param.channels_default_datarate = stack_mib_get.Param.ChannelsDefaultDatarate; - break; - case LORA_MIB_CHANNELS_DATARATE: - mib_get_params->param.channels_datarate = stack_mib_get.Param.ChannelsDatarate; - break; - case LORA_MIB_CHANNELS_DEFAULT_TX_POWER: - mib_get_params->param.channels_default_tx_power = stack_mib_get.Param.ChannelsDefaultTxPower; - break; - case LORA_MIB_CHANNELS_TX_POWER: - mib_get_params->param.channels_tx_power = stack_mib_get.Param.ChannelsTxPower; - break; - case LORA_MIB_UPLINK_COUNTER: - mib_get_params->param.uplink_counter = stack_mib_get.Param.UpLinkCounter; - break; - case LORA_MIB_DOWNLINK_COUNTER: - mib_get_params->param.downlink_counter = stack_mib_get.Param.DownLinkCounter; - break; - case LORA_MIB_MULTICAST_CHANNEL: - /* - * Parse multicast list (C++ linked list) - */ - origin_multicast_list = stack_mib_get.Param.MulticastList; - - while (NULL != origin_multicast_list) { - if (NULL == new_multicast_list) { - new_multicast_list = new lora_mac_multicast_params_t; - new_multicast_list->next = NULL; - - mib_get_params->param.multicast_list = new_multicast_list; - } else { - while (NULL != new_multicast_list) { - new_multicast_list = new_multicast_list->next; - } - new_multicast_list = new lora_mac_multicast_params_t; - new_multicast_list->next = NULL; - } - - new_multicast_list->address = origin_multicast_list->Address; - for (int i = 0; i < 16; ++i) { - new_multicast_list->nwk_skey[i] = origin_multicast_list->NwkSKey[i]; - new_multicast_list->app_skey[i] = origin_multicast_list->AppSKey[i]; - } - new_multicast_list->downlink_counter = origin_multicast_list->DownLinkCounter; - - origin_multicast_list = origin_multicast_list->Next; - } - break; - case LORA_MIB_SYSTEM_MAX_RX_ERROR: - mib_get_params->param.system_max_rx_error = stack_mib_get.Param.SystemMaxRxError; - break; - case LORA_MIB_MIN_RX_SYMBOLS: - mib_get_params->param.min_rx_symbols = stack_mib_get.Param.MinRxSymbols; - break; - default: - return LORA_MAC_STATUS_SERVICE_UNKNOWN; - break; - } - - return mac_status; } -lora_mac_status_t LoRaWANStack::error_type_converter(LoRaMacStatus_t type) -{ - switch (type) { - case LORAMAC_STATUS_OK: - return LORA_MAC_STATUS_OK; - break; - - case LORAMAC_STATUS_BUSY: - return LORA_MAC_STATUS_BUSY; - break; - - case LORAMAC_STATUS_SERVICE_UNKNOWN: - return LORA_MAC_STATUS_SERVICE_UNKNOWN; - break; - - case LORAMAC_STATUS_PARAMETER_INVALID: - return LORA_MAC_STATUS_PARAMETER_INVALID; - break; - - case LORAMAC_STATUS_FREQUENCY_INVALID: - return LORA_MAC_STATUS_FREQUENCY_INVALID; - break; - - case LORAMAC_STATUS_DATARATE_INVALID: - return LORA_MAC_STATUS_DATARATE_INVALID; - break; - - case LORAMAC_STATUS_FREQ_AND_DR_INVALID: - return LORA_MAC_STATUS_FREQ_AND_DR_INVALID; - break; - - case LORAMAC_STATUS_NO_NETWORK_JOINED: - return LORA_MAC_STATUS_NO_NETWORK_JOINED; - break; - - case LORAMAC_STATUS_LENGTH_ERROR: - return LORA_MAC_STATUS_LENGTH_ERROR; - break; - - case LORAMAC_STATUS_DEVICE_OFF: - return LORA_MAC_STATUS_DEVICE_OFF; - break; - - case LORAMAC_STATUS_CRYPTO_FAIL: - return LORA_MAC_STATUS_CRYPTO_FAIL; - break; - - default: - return LORA_MAC_STATUS_SERVICE_UNKNOWN; - break; - } -} - -lora_mac_status_t LoRaWANStack::set_link_check_request() +lorawan_status_t LoRaWANStack::set_link_check_request() { if (!_callbacks.link_check_resp) { tr_error("Must assign a callback function for link check request. "); - return LORA_MAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } - lora_mac_mlme_req_t mlme_req; + loramac_mlme_req_t mlme_req; - mlme_req.type = LORA_MLME_LINK_CHECK; + mlme_req.type = MLME_LINK_CHECK; return mlme_request_handler(&mlme_req); } @@ -1661,10 +1180,10 @@ void LoRaWANStack::shutdown() lora_state_machine(); } -lora_mac_status_t LoRaWANStack::lora_state_machine() +lorawan_status_t LoRaWANStack::lora_state_machine() { - lora_mac_mib_request_confirm_t mib_req; - lora_mac_status_t status = LORA_MAC_STATUS_DEVICE_OFF; + loramac_mib_req_confirm_t mib_req; + lorawan_status_t status = LORAWAN_STATUS_DEVICE_OFF; switch (_device_current_state) { case DEVICE_STATE_SHUTDOWN: @@ -1678,8 +1197,8 @@ lora_mac_status_t LoRaWANStack::lora_state_machine() #if defined(LORAWAN_COMPLIANCE_TEST) _loramac.LoRaMacStopTxTimer(); #endif - mib_req.type = LORA_MIB_NETWORK_JOINED; - mib_req.param.is_network_joined = false; + mib_req.type = MIB_NETWORK_JOINED; + mib_req.param.is_nwk_joined = false; mib_set_request(&mib_req); // reset buffers to original state @@ -1687,10 +1206,10 @@ lora_mac_status_t LoRaWANStack::lora_state_machine() _tx_msg.pending_size = 0; _tx_msg.f_buffer_size = 0; _tx_msg.tx_ongoing = false; - memset(_rx_msg.rx_message.mcps_indication.buffer, 0, LORAMAC_PHY_MAXPAYLOAD); + _rx_msg.msg.mcps_indication.buffer = NULL; _rx_msg.receive_ready = false; _rx_msg.prev_read_size = 0; - _rx_msg.rx_message.mcps_indication.buffer_size = 0; + _rx_msg.msg.mcps_indication.buffer_size = 0; // disable the session _lw_session.active = false; @@ -1699,14 +1218,14 @@ lora_mac_status_t LoRaWANStack::lora_state_machine() if (_callbacks.events) { _queue->call(_callbacks.events, DISCONNECTED); } - status = LORA_MAC_STATUS_DEVICE_OFF; + status = LORAWAN_STATUS_DEVICE_OFF; break; case DEVICE_STATE_NOT_INITIALIZED: // Device is disconnected. - status = LORA_MAC_STATUS_DEVICE_OFF; + status = LORAWAN_STATUS_DEVICE_OFF; break; case DEVICE_STATE_INIT: - status = LORA_MAC_STATUS_OK; + status = LORAWAN_STATUS_OK; break; case DEVICE_STATE_JOINING: if (_lw_session.connection.connect_type == LORAWAN_CONNECTION_OTAA) { @@ -1714,8 +1233,8 @@ lora_mac_status_t LoRaWANStack::lora_state_machine() * OTAA join */ tr_debug("Send Join-request.."); - lora_mac_mlme_req_t mlme_req; - mlme_req.type = LORA_MLME_JOIN; + loramac_mlme_req_t mlme_req; + mlme_req.type = MLME_JOIN; mlme_req.req.join.dev_eui = _lw_session.connection.connection_u.otaa.dev_eui; mlme_req.req.join.app_eui = _lw_session.connection.connection_u.otaa.app_eui; @@ -1724,14 +1243,14 @@ lora_mac_status_t LoRaWANStack::lora_state_machine() // Send join request to server. status = mlme_request_handler(&mlme_req); - if (status != LORA_MAC_STATUS_OK) { + if (status != LORAWAN_STATUS_OK) { return status; } // Otherwise request was successful and OTAA connect is in //progress - return LORA_MAC_STATUS_CONNECT_IN_PROGRESS; + return LORAWAN_STATUS_CONNECT_IN_PROGRESS; } else { - status = LORA_MAC_STATUS_PARAMETER_INVALID; + status = LORAWAN_STATUS_PARAMETER_INVALID; break; } break; @@ -1748,30 +1267,30 @@ lora_mac_status_t LoRaWANStack::lora_state_machine() /* * ABP connection */ - mib_req.type = LORA_MIB_NET_ID; + mib_req.type = MIB_NET_ID; mib_req.param.net_id = _lw_session.connection.connection_u.abp.nwk_id; mib_set_request(&mib_req); - mib_req.type = LORA_MIB_DEV_ADDR; + mib_req.type = MIB_DEV_ADDR; mib_req.param.dev_addr = _lw_session.connection.connection_u.abp.dev_addr; mib_set_request(&mib_req); - mib_req.type = LORA_MIB_NWK_SKEY; + mib_req.type = MIB_NWK_SKEY; mib_req.param.nwk_skey = _lw_session.connection.connection_u.abp.nwk_skey; mib_set_request(&mib_req); - mib_req.type = LORA_MIB_APP_SKEY; + mib_req.type = MIB_APP_SKEY; mib_req.param.app_skey = _lw_session.connection.connection_u.abp.app_skey; mib_set_request(&mib_req); - mib_req.type = LORA_MIB_NETWORK_JOINED; - mib_req.param.is_network_joined = true; + mib_req.type = MIB_NETWORK_JOINED; + mib_req.param.is_nwk_joined = true; mib_set_request(&mib_req); tr_debug("ABP Connection OK!"); // tell the application we are okay // if users provide wrong keys, it's their responsibility // there is no way to test ABP authentication success - status = LORA_MAC_STATUS_OK; + status = LORAWAN_STATUS_OK; // Session is now active _lw_session.active = true; if (_callbacks.events) { @@ -1781,16 +1300,16 @@ lora_mac_status_t LoRaWANStack::lora_state_machine() case DEVICE_STATE_SEND: // If a transmission is ongoing, don't interrupt if (_tx_msg.tx_ongoing) { - status = LORA_MAC_STATUS_OK; + status = LORAWAN_STATUS_OK; } else { _tx_msg.tx_ongoing = true; status = send_frame_to_mac(); switch (status) { - case LORA_MAC_STATUS_OK: + case LORAWAN_STATUS_OK: tr_debug("Frame scheduled to TX.."); break; - case LORA_MAC_STATUS_CRYPTO_FAIL: + case LORAWAN_STATUS_CRYPTO_FAIL: tr_error("Crypto failed. Clearing TX buffers"); if (_callbacks.events) { _queue->call(_callbacks.events, TX_CRYPTO_ERROR); @@ -1809,7 +1328,7 @@ lora_mac_status_t LoRaWANStack::lora_state_machine() break; case DEVICE_STATE_IDLE: //Do nothing - status = LORA_MAC_STATUS_IDLE; + status = LORAWAN_STATUS_IDLE; break; #if defined(LORAWAN_COMPLIANCE_TEST) case DEVICE_STATE_COMPLIANCE_TEST: @@ -1821,141 +1340,13 @@ lora_mac_status_t LoRaWANStack::lora_state_machine() if (_compliance_test.running == true) { send_compliance_test_frame_to_mac(); } - status = LORA_MAC_STATUS_COMPLIANCE_TEST_ON; + status = LORAWAN_STATUS_COMPLIANCE_TEST_ON; break; #endif default: - status = LORA_MAC_STATUS_SERVICE_UNKNOWN; + status = LORAWAN_STATUS_SERVICE_UNKNOWN; break; } return status; } - -static Mcps_t interpret_mcps_confirm_type(const lora_mac_mcps_t& local) -{ - switch (local) { - case LORA_MCPS_UNCONFIRMED: - return MCPS_UNCONFIRMED; - case LORA_MCPS_CONFIRMED: - return MCPS_CONFIRMED; - case LORA_MCPS_MULTICAST: - return MCPS_MULTICAST; - case LORA_MCPS_PROPRIETARY: - return MCPS_PROPRIETARY; - default: - MBED_ASSERT("Unknown Mcps_t"); - } - - // Never reaches here - return MCPS_UNCONFIRMED; -} - -static lora_mac_event_info_status_t interpret_event_info_type(const LoRaMacEventInfoStatus_t& remote) -{ - switch (remote) { - case LORAMAC_EVENT_INFO_STATUS_OK: - return LORA_EVENT_INFO_STATUS_OK; - case LORAMAC_EVENT_INFO_STATUS_ERROR: - return LORA_EVENT_INFO_STATUS_ERROR; - case LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT: - return LORA_EVENT_INFO_STATUS_TX_TIMEOUT; - case LORAMAC_EVENT_INFO_STATUS_RX1_TIMEOUT: - return LORA_EVENT_INFO_STATUS_RX1_TIMEOUT; - case LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT: - return LORA_EVENT_INFO_STATUS_RX2_TIMEOUT; - case LORAMAC_EVENT_INFO_STATUS_RX1_ERROR: - return LORA_EVENT_INFO_STATUS_RX1_ERROR; - case LORAMAC_EVENT_INFO_STATUS_RX2_ERROR: - return LORA_EVENT_INFO_STATUS_RX2_ERROR; - case LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL: - return LORA_EVENT_INFO_STATUS_JOIN_FAIL; - case LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED: - return LORA_EVENT_INFO_STATUS_DOWNLINK_REPEATED; - case LORAMAC_EVENT_INFO_STATUS_TX_DR_PAYLOAD_SIZE_ERROR: - return LORA_EVENT_INFO_STATUS_TX_DR_PAYLOAD_SIZE_ERROR; - case LORAMAC_EVENT_INFO_STATUS_DOWNLINK_TOO_MANY_FRAMES_LOSS: - return LORA_EVENT_INFO_STATUS_DOWNLINK_TOO_MANY_FRAMES_LOSS; - case LORAMAC_EVENT_INFO_STATUS_ADDRESS_FAIL: - return LORA_EVENT_INFO_STATUS_ADDRESS_FAIL; - case LORAMAC_EVENT_INFO_STATUS_MIC_FAIL: - return LORA_EVENT_INFO_STATUS_MIC_FAIL; - case LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL: - return LORA_EVENT_INFO_STATUS_CRYPTO_FAIL; - default: - MBED_ASSERT("Unknown LoRaMacEventInfoStatus_t"); - } - - // Never reaches here actually - return LORA_EVENT_INFO_STATUS_OK; -} - -static Mib_t interpret_mib_req_confirm_type(const lora_mac_mib_t& local) -{ - switch (local) { - case LORA_MIB_DEVICE_CLASS: - return MIB_DEVICE_CLASS; - case LORA_MIB_NETWORK_JOINED: - return MIB_NETWORK_JOINED; - case LORA_MIB_ADR: - return MIB_ADR; - case LORA_MIB_NET_ID: - return MIB_NET_ID; - case LORA_MIB_DEV_ADDR: - return MIB_DEV_ADDR; - case LORA_MIB_NWK_SKEY: - return MIB_NWK_SKEY; - case LORA_MIB_APP_SKEY: - return MIB_APP_SKEY; - case LORA_MIB_PUBLIC_NETWORK: - return MIB_PUBLIC_NETWORK; - case LORA_MIB_REPEATER_SUPPORT: - return MIB_REPEATER_SUPPORT; - case LORA_MIB_CHANNELS: - return MIB_CHANNELS; - case LORA_MIB_RX2_CHANNEL: - return MIB_RX2_CHANNEL; - case LORA_MIB_RX2_DEFAULT_CHANNEL: - return MIB_RX2_DEFAULT_CHANNEL; - case LORA_MIB_CHANNELS_MASK: - return MIB_CHANNELS_MASK; - case LORA_MIB_CHANNELS_DEFAULT_MASK: - return MIB_CHANNELS_DEFAULT_MASK; - case LORA_MIB_CHANNELS_NB_REP: - return MIB_CHANNELS_NB_REP; - case LORA_MIB_MAX_RX_WINDOW_DURATION: - return MIB_MAX_RX_WINDOW_DURATION; - case LORA_MIB_RECEIVE_DELAY_1: - return MIB_RECEIVE_DELAY_1; - case LORA_MIB_RECEIVE_DELAY_2: - return MIB_RECEIVE_DELAY_2; - case LORA_MIB_JOIN_ACCEPT_DELAY_1: - return MIB_JOIN_ACCEPT_DELAY_1; - case LORA_MIB_JOIN_ACCEPT_DELAY_2: - return MIB_JOIN_ACCEPT_DELAY_2; - case LORA_MIB_CHANNELS_DEFAULT_DATARATE: - return MIB_CHANNELS_DEFAULT_DATARATE; - case LORA_MIB_CHANNELS_DATARATE: - return MIB_CHANNELS_DATARATE; - case LORA_MIB_CHANNELS_TX_POWER: - return MIB_CHANNELS_TX_POWER; - case LORA_MIB_CHANNELS_DEFAULT_TX_POWER: - return MIB_CHANNELS_DEFAULT_TX_POWER; - case LORA_MIB_UPLINK_COUNTER: - return MIB_UPLINK_COUNTER; - case LORA_MIB_DOWNLINK_COUNTER: - return MIB_DOWNLINK_COUNTER; - case LORA_MIB_MULTICAST_CHANNEL: - return MIB_MULTICAST_CHANNEL; - case LORA_MIB_SYSTEM_MAX_RX_ERROR: - return MIB_SYSTEM_MAX_RX_ERROR; - case LORA_MIB_MIN_RX_SYMBOLS: - return MIB_MIN_RX_SYMBOLS; - default: - MBED_ASSERT("Cannot Interpret Mib_t"); - } - - // Never actually reaches here - return MIB_DEVICE_CLASS; -} - diff --git a/features/lorawan/LoRaWANStack.h b/features/lorawan/LoRaWANStack.h index d04aced43f..27ae1744a3 100644 --- a/features/lorawan/LoRaWANStack.h +++ b/features/lorawan/LoRaWANStack.h @@ -97,9 +97,9 @@ public: /** End device initialization. * @param queue A pointer to an EventQueue passed from the application. - * @return LORA_MAC_STATUS_OK on success, a negative error code on failure. + * @return LORAWAN_STATUS_OK on success, a negative error code on failure. */ - lora_mac_status_t initialize_mac_layer(events::EventQueue *queue); + lorawan_status_t initialize_mac_layer(events::EventQueue *queue); /** Sets all callbacks for the application. * @@ -126,35 +126,35 @@ public: * * @param channel_plan A list of channels or a single channel. * - * @return LORA_MAC_STATUS_OK on success, a negative error + * @return LORAWAN_STATUS_OK on success, a negative error * code on failure. */ - lora_mac_status_t add_channels(const lora_channelplan_t &channel_plan); + lorawan_status_t add_channels(const lorawan_channelplan_t &channel_plan); /** Removes a channel from the list. * * @param channel_id Index of the channel being removed * - * @return LORA_MAC_STATUS_OK on success, a negative error + * @return LORAWAN_STATUS_OK on success, a negative error * code on failure. */ - lora_mac_status_t remove_a_channel(uint8_t channel_id); + lorawan_status_t remove_a_channel(uint8_t channel_id); /** Removes a previously set channel plan. * - * @return LORA_MAC_STATUS_OK on success, a negative error + * @return LORAWAN_STATUS_OK on success, a negative error * code on failure. */ - lora_mac_status_t drop_channel_list(); + lorawan_status_t drop_channel_list(); /** Gets a list of currently enabled channels . * * @param channel_plan The channel plan structure to store final result. * - * @return LORA_MAC_STATUS_OK on success, a negative error + * @return LORAWAN_STATUS_OK on success, a negative error * code on failure. */ - lora_mac_status_t get_enabled_channels(lora_channelplan_t &channel_plan); + lorawan_status_t get_enabled_channels(lorawan_channelplan_t &channel_plan); /** Sets up a retry counter for confirmed messages. * @@ -164,9 +164,9 @@ public: * * @param count The number of retries for confirmed messages. * - * @return LORA_MAC_STATUS_OK or a negative error code. + * @return LORAWAN_STATUS_OK or a negative error code. */ - lora_mac_status_t set_confirmed_msg_retry(uint8_t count); + lorawan_status_t set_confirmed_msg_retry(uint8_t count); /** Sets up the data rate. * @@ -177,26 +177,26 @@ public: * Note that the macro DR_* can mean different * things in different regions. * - * @return LORA_MAC_STATUS_OK if everything goes well, otherwise + * @return LORAWAN_STATUS_OK if everything goes well, otherwise * a negative error code. */ - lora_mac_status_t set_channel_data_rate(uint8_t data_rate); + lorawan_status_t set_channel_data_rate(uint8_t data_rate); /** Enables ADR. * * @param adr_enabled 0 ADR disabled, 1 ADR enabled. * - * @return LORA_MAC_STATUS_OK on success, a negative error + * @return LORAWAN_STATUS_OK on success, a negative error * code on failure. */ - lora_mac_status_t enable_adaptive_datarate(bool adr_enabled); + lorawan_status_t enable_adaptive_datarate(bool adr_enabled); /** Commissions a LoRa device. * * @param commission_data A structure representing all the commission * information. */ - void commission_device(const lora_dev_commission_t &commission_data); + void commission_device(const lorawan_dev_commission_t &commission_data); /** End device OTAA join. * @@ -205,11 +205,11 @@ public: * * @param params The `lorawan_connect_t` type structure. * - * @return LORA_MAC_STATUS_OK or - * LORA_MAC_STATUS_CONNECT_IN_PROGRESS on success, + * @return LORAWAN_STATUS_OK or + * LORAWAN_STATUS_CONNECT_IN_PROGRESS on success, * or a negative error code on failure. */ - lora_mac_status_t join_request_by_otaa(const lorawan_connect_t ¶ms); + lorawan_status_t join_request_by_otaa(const lorawan_connect_t ¶ms); /** End device ABP join. * @@ -218,11 +218,11 @@ public: * * @param params The `lorawan_connect_t` type structure. * - * @return LORA_MAC_STATUS_OK or - * LORA_MAC_STATUS_CONNECT_IN_PROGRESS on success, + * @return LORAWAN_STATUS_OK or + * LORAWAN_STATUS_CONNECT_IN_PROGRESS on success, * or a negative error code on failure. */ - lora_mac_status_t activation_by_personalization(const lorawan_connect_t ¶ms); + lorawan_status_t activation_by_personalization(const lorawan_connect_t ¶ms); /** Send message to gateway * @@ -255,7 +255,7 @@ public: * * * @return The number of bytes sent, or - * LORA_MAC_STATUS_WOULD_BLOCK if another TX is + * LORAWAN_STATUS_WOULD_BLOCK if another TX is * ongoing, or a negative error code on failure. */ int16_t handle_tx(uint8_t port, const uint8_t* data, @@ -296,7 +296,7 @@ public: * @return It could be one of these: * i) 0 if there is nothing else to read. * ii) Number of bytes written to user buffer. - * iii) LORA_MAC_STATUS_WOULD_BLOCK if there is + * iii) LORAWAN_STATUS_WOULD_BLOCK if there is * nothing available to read at the moment. * iv) A negative error code on failure. */ @@ -311,13 +311,13 @@ public: * from the Network Server, an event is generated. * * A callback function for the link check response must be set prior to using - * this API, otherwise a LORA_MAC_STATUS_PARAMETER_INVALID error is thrown. + * this API, otherwise a LORAWAN_STATUS_PARAMETER_INVALID error is thrown. * - * @return LORA_MAC_STATUS_OK on successfully queuing a request, or + * @return LORAWAN_STATUS_OK on successfully queuing a request, or * a negative error code on failure. * */ - lora_mac_status_t set_link_check_request(); + lorawan_status_t set_link_check_request(); /** Shuts down the LoRaWAN protocol. * @@ -338,7 +338,7 @@ private: * State machine for stack controller layer. * Needs to be wriggled for every state change */ - lora_mac_status_t lora_state_machine(); + lorawan_status_t lora_state_machine(); /** * Sets the current state of the device. @@ -351,56 +351,35 @@ private: /** * Hands over the packet to Mac layer by posting an MCPS request. */ - lora_mac_status_t send_frame_to_mac(); - - /** - * Callback function for MCPS confirm. Mac layer calls this function once - * an MCPS confirmation is received. This method translates Mac layer data - * structure into stack layer data structure. - */ - void mcps_confirm(McpsConfirm_t *mcps_confirm); - - /** - * Callback function for MCPS indication. Mac layer calls this function once - * an MCPS indication is received. This method translates Mac layer data - * structure into stack layer data structure. - */ - void mcps_indication(McpsIndication_t *mcps_indication); - - /** - * Callback function for MLME confirm. Mac layer calls this function once - * an MLME confirmation is received. This method translates Mac layer data - * structure into stack layer data structure. - */ - void mlme_confirm(MlmeConfirm_t *mlme_confirm); + lorawan_status_t send_frame_to_mac(); /** * Callback function for MLME indication. Mac layer calls this function once * an MLME indication is received. This method translates Mac layer data * structure into stack layer data structure. */ - void mlme_indication( MlmeIndication_t *mlmeIndication ); + void mlme_indication_handler(loramac_mlme_indication_t *mlmeIndication); /** * Handles an MLME request coming from the upper layers and delegates * it to the Mac layer, for example, a Join request goes as an MLME request * to the Mac layer. */ - lora_mac_status_t mlme_request_handler(lora_mac_mlme_req_t *mlme_request); + lorawan_status_t mlme_request_handler(loramac_mlme_req_t *mlme_request); /** * Handles an MLME confirmation coming from the Mac layer and uses it to * update the state for example, a Join Accept triggers an MLME confirmation, * that eventually comes here and we take necessary steps accordingly. */ - void mlme_confirm_handler(lora_mac_mlme_confirm_t *mlme_confirm); + void mlme_confirm_handler(loramac_mlme_confirm_t *mlme_confirm); /** * Handles an MCPS request while attempting to hand over a packet from * upper layers to Mac layer. For example in response to send_frame_to_mac(), * an MCPS request is generated. */ - lora_mac_status_t mcps_request_handler(lora_mac_mcps_req_t *mcps_request); + lorawan_status_t mcps_request_handler(loramac_mcps_req_t *mcps_request); /** * Handles an MCPS confirmation coming from the Mac layer in response to an @@ -408,7 +387,7 @@ private: * e.g., letting the application know that ack was not received in case of * a CONFIRMED message or scheduling error etc. */ - void mcps_confirm_handler(lora_mac_mcps_confirm_t *mcps_confirm); + void mcps_confirm_handler(loramac_mcps_confirm_t *mcps_confirm); /** * Handles an MCPS indication coming from the Mac layer, e.g., once we @@ -416,22 +395,22 @@ private: * and consequently this handler posts an event to the application that * there is something available to read. */ - void mcps_indication_handler(lora_mac_mcps_indication_t *mcps_indication); + void mcps_indication_handler(loramac_mcps_indication_t *mcps_indication); /** * Sets a MIB request, i.e., update a particular parameter etc. */ - lora_mac_status_t mib_set_request(lora_mac_mib_request_confirm_t *mib_set_params); + lorawan_status_t mib_set_request(loramac_mib_req_confirm_t *mib_set_params); /** * Requests the MIB to inquire about a particular parameter. */ - lora_mac_status_t mib_get_request(lora_mac_mib_request_confirm_t *mib_get_params); + lorawan_status_t mib_get_request(loramac_mib_req_confirm_t *mib_get_params); /** * Sets up user application port */ - lora_mac_status_t set_application_port(uint8_t port); + lorawan_status_t set_application_port(uint8_t port); /** * Helper function to figure out if the user defined data size is possible @@ -452,19 +431,14 @@ private: /** * Used only for compliance testing */ - void compliance_test_handler(lora_mac_mcps_indication_t *mcps_indication); + void compliance_test_handler(loramac_mcps_indication_t *mcps_indication); /** * Used only for compliance testing */ - lora_mac_status_t send_compliance_test_frame_to_mac(); + lorawan_status_t send_compliance_test_frame_to_mac(); #endif - /** - * converts error codes from Mac layer to controller layer - */ - lora_mac_status_t error_type_converter(LoRaMacStatus_t type); - LoRaWANTimeHandler _lora_time; LoRaMac _loramac; LoRaPHY_region _lora_phy; @@ -477,8 +451,8 @@ private: lorawan_app_callbacks_t _callbacks; radio_events_t *_mac_handlers; lorawan_session_t _lw_session; - lora_mac_tx_message_t _tx_msg; - lora_mac_rx_message_t _rx_msg; + loramac_tx_message_t _tx_msg; + loramac_rx_message_t _rx_msg; uint8_t _app_port; uint8_t _num_retry; events::EventQueue *_queue; diff --git a/features/lorawan/lorastack/mac/LoRaMac.cpp b/features/lorawan/lorastack/mac/LoRaMac.cpp index 03201fa84d..434da73dce 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.cpp +++ b/features/lorawan/lorastack/mac/LoRaMac.cpp @@ -87,38 +87,38 @@ LoRaMac::LoRaMac(LoRaWANTimeHandler &lora_time) { lora_phy = NULL; //radio_events_t RadioEvents; - _params.keys.LoRaMacDevEui = NULL; - _params.keys.LoRaMacAppEui = NULL; - _params.keys.LoRaMacAppKey = NULL; + _params.keys.dev_eui = NULL; + _params.keys.app_eui = NULL; + _params.keys.app_key = NULL; - memset(_params.keys.LoRaMacNwkSKey, 0, sizeof(_params.keys.LoRaMacNwkSKey)); - memset(_params.keys.LoRaMacAppSKey, 0, sizeof(_params.keys.LoRaMacAppSKey)); + memset(_params.keys.nwk_skey, 0, sizeof(_params.keys.nwk_skey)); + memset(_params.keys.app_skey, 0, sizeof(_params.keys.app_skey)); - _params.LoRaMacDevNonce = 0; - _params.LoRaMacNetID = 0; - _params.LoRaMacDevAddr = 0; - _params.LoRaMacBufferPktLen = 0; - _params.LoRaMacTxPayloadLen = 0; - _params.UpLinkCounter = 0; - _params.DownLinkCounter = 0; - _params.IsUpLinkCounterFixed = false; - _params.IsRxWindowsEnabled = true; - _params.IsLoRaMacNetworkJoined = false; - _params.AdrAckCounter = 0; - _params.NodeAckRequested = false; - _params.SrvAckRequested = false; - _params.ChannelsNbRepCounter = 0; - _params.timers.LoRaMacInitializationTime = 0; - _params.LoRaMacState = LORAMAC_IDLE; - _params.AckTimeoutRetries = 1; - _params.AckTimeoutRetriesCounter = 1; - _params.AckTimeoutRetry = false; - _params.timers.TxTimeOnAir = 0; + _params.dev_nonce = 0; + _params.net_id = 0; + _params.dev_addr = 0; + _params.buffer_pkt_len = 0; + _params.payload_length = 0; + _params.ul_frame_counter = 0; + _params.dl_frame_counter = 0; + _params.is_ul_frame_counter_fixed = false; + _params.is_rx_window_enabled = true; + _params.is_nwk_joined = false; + _params.adr_ack_counter = 0; + _params.is_node_ack_requested = false; + _params.is_srv_ack_requested = false; + _params.ul_nb_rep_counter = 0; + _params.timers.mac_init_time = 0; + _params.mac_state = LORAMAC_IDLE; + _params.max_ack_timeout_retries = 1; + _params.ack_timeout_retry_counter = 1; + _params.is_ack_retry_timeout_expired = false; + _params.timers.tx_toa = 0; - _params.MulticastChannels = NULL; + _params.multicast_channels = NULL; - _params.sys_params.AdrCtrlOn = false; - _params.sys_params.MaxDCycle = 0; + _params.sys_params.adr_on = false; + _params.sys_params.max_duty_cycle = 0; } LoRaMac::~LoRaMac() @@ -199,10 +199,10 @@ void LoRaMac::OnRadioTxDone( void ) GetPhyParams_t getPhy; PhyParam_t phyParam; SetBandTxDoneParams_t txDone; - TimerTime_t curTime = _lora_time.TimerGetCurrentTime( ); - MlmeConfirm_t mlme_confirm = mlme.get_confirmation(); + lorawan_time_t curTime = _lora_time.TimerGetCurrentTime( ); + loramac_mlme_confirm_t mlme_confirm = mlme.get_confirmation(); - if( _params.LoRaMacDeviceClass != CLASS_C ) + if( _params.dev_class != CLASS_C ) { lora_phy->put_radio_to_sleep(); } @@ -212,83 +212,83 @@ void LoRaMac::OnRadioTxDone( void ) } // Setup timers - if( _params.IsRxWindowsEnabled == true ) + if( _params.is_rx_window_enabled == true ) { - _lora_time.TimerSetValue( &_params.timers.RxWindowTimer1, _params.RxWindow1Delay ); - _lora_time.TimerStart( &_params.timers.RxWindowTimer1 ); - if( _params.LoRaMacDeviceClass != CLASS_C ) + _lora_time.TimerSetValue( &_params.timers.rx_window1_timer, _params.rx_window1_delay ); + _lora_time.TimerStart( &_params.timers.rx_window1_timer ); + if( _params.dev_class != CLASS_C ) { - _lora_time.TimerSetValue( &_params.timers.RxWindowTimer2, _params.RxWindow2Delay ); - _lora_time.TimerStart( &_params.timers.RxWindowTimer2 ); + _lora_time.TimerSetValue( &_params.timers.rx_window2_timer, _params.rx_window2_delay ); + _lora_time.TimerStart( &_params.timers.rx_window2_timer ); } - if( ( _params.LoRaMacDeviceClass == CLASS_C ) || ( _params.NodeAckRequested == true ) ) + if( ( _params.dev_class == CLASS_C ) || ( _params.is_node_ack_requested == true ) ) { getPhy.Attribute = PHY_ACK_TIMEOUT; phyParam = lora_phy->get_phy_params(&getPhy); - _lora_time.TimerSetValue( &_params.timers.AckTimeoutTimer, _params.RxWindow2Delay + phyParam.Value ); - _lora_time.TimerStart( &_params.timers.AckTimeoutTimer ); + _lora_time.TimerSetValue( &_params.timers.ack_timeout_timer, _params.rx_window2_delay + phyParam.Value ); + _lora_time.TimerStart( &_params.timers.ack_timeout_timer ); } } else { - mcps.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_OK; - mlme_confirm.Status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT; + mcps.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_OK; + mlme_confirm.status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT; - if( _params.LoRaMacFlags.Value == 0 ) + if( _params.flags.value == 0 ) { - _params.LoRaMacFlags.Bits.McpsReq = 1; + _params.flags.bits.mcps_req = 1; } - _params.LoRaMacFlags.Bits.MacDone = 1; + _params.flags.bits.mac_done = 1; } // Verify if the last uplink was a join request - if( ( _params.LoRaMacFlags.Bits.MlmeReq == 1 ) && ( mlme_confirm.MlmeRequest == MLME_JOIN ) ) + if( ( _params.flags.bits.mlme_req == 1 ) && ( mlme_confirm.req_type == MLME_JOIN ) ) { - _params.LastTxIsJoinRequest = true; + _params.is_last_tx_join_request = true; } else { - _params.LastTxIsJoinRequest = false; + _params.is_last_tx_join_request = false; } // Store last Tx channel - _params.LastTxChannel = _params.Channel; + _params.last_channel_idx = _params.channel; // Update last tx done time for the current channel - txDone.Channel = _params.Channel; - txDone.Joined = _params.IsLoRaMacNetworkJoined; + txDone.Channel = _params.channel; + txDone.Joined = _params.is_nwk_joined; txDone.LastTxDoneTime = curTime; lora_phy->set_band_tx_done(&txDone); // Update Aggregated last tx done time - _params.timers.AggregatedLastTxDoneTime = curTime; + _params.timers.aggregated_last_tx_time = curTime; - if( _params.NodeAckRequested == false ) + if( _params.is_node_ack_requested == false ) { - mcps.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_OK; - _params.ChannelsNbRepCounter++; + mcps.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_OK; + _params.ul_nb_rep_counter++; } } void LoRaMac::PrepareRxDoneAbort( void ) { - _params.LoRaMacState |= LORAMAC_RX_ABORT; + _params.mac_state |= LORAMAC_RX_ABORT; - if( _params.NodeAckRequested ) + if( _params.is_node_ack_requested ) { handle_ack_timeout(); } - _params.LoRaMacFlags.Bits.McpsInd = 1; - _params.LoRaMacFlags.Bits.MacDone = 1; + _params.flags.bits.mcps_ind = 1; + _params.flags.bits.mac_done = 1; // Trig OnMacCheckTimerEvent call as soon as possible - _lora_time.TimerSetValue( &_params.timers.MacStateCheckTimer, 1 ); - _lora_time.TimerStart( &_params.timers.MacStateCheckTimer ); + _lora_time.TimerSetValue( &_params.timers.mac_state_check_timer, 1 ); + _lora_time.TimerStart( &_params.timers.mac_state_check_timer ); } void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) { - LoRaMacHeader_t macHdr; - LoRaMacFrameCtrl_t fCtrl; + loramac_mhdr_t macHdr; + loramac_frame_ctrl_t fCtrl; ApplyCFListParams_t applyCFList; GetPhyParams_t getPhy; PhyParam_t phyParam; @@ -307,131 +307,129 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 uint16_t sequenceCounterDiff = 0; uint32_t downLinkCounter = 0; - MulticastParams_t *curMulticastParams = NULL; - uint8_t *nwkSKey = _params.keys.LoRaMacNwkSKey; - uint8_t *appSKey = _params.keys.LoRaMacAppSKey; + multicast_params_t *curMulticastParams = NULL; + uint8_t *nwkSKey = _params.keys.nwk_skey; + uint8_t *appSKey = _params.keys.app_skey; uint8_t multicast = 0; bool isMicOk = false; - mcps.get_confirmation().AckReceived = false; - mcps.get_indication().Rssi = rssi; - mcps.get_indication().Snr = snr; - mcps.get_indication().RxSlot = _params.RxSlot; - mcps.get_indication().Port = 0; - mcps.get_indication().Multicast = 0; - mcps.get_indication().FramePending = 0; - mcps.get_indication().Buffer = NULL; - mcps.get_indication().BufferSize = 0; - mcps.get_indication().RxData = false; - mcps.get_indication().AckReceived = false; - mcps.get_indication().DownLinkCounter = 0; - mcps.get_indication().McpsIndication = MCPS_UNCONFIRMED; + mcps.get_confirmation().ack_received = false; + mcps.get_indication().rssi = rssi; + mcps.get_indication().snr = snr; + mcps.get_indication().rx_slot = _params.rx_slot; + mcps.get_indication().port = 0; + mcps.get_indication().multicast = 0; + mcps.get_indication().fpending_status = 0; + mcps.get_indication().buffer = NULL; + mcps.get_indication().buffer_size = 0; + mcps.get_indication().is_data_recvd = false; + mcps.get_indication().is_ack_recvd = false; + mcps.get_indication().dl_frame_counter = 0; + mcps.get_indication().type = MCPS_UNCONFIRMED; lora_phy->put_radio_to_sleep(); - _lora_time.TimerStop( &_params.timers.RxWindowTimer2 ); + _lora_time.TimerStop( &_params.timers.rx_window2_timer ); - macHdr.Value = payload[pktHeaderLen++]; + macHdr.value = payload[pktHeaderLen++]; - switch( macHdr.Bits.MType ) + switch( macHdr.bits.mtype ) { case FRAME_TYPE_JOIN_ACCEPT: - if( _params.IsLoRaMacNetworkJoined == true ) + if( _params.is_nwk_joined == true ) { - mcps.get_indication().Status = LORAMAC_EVENT_INFO_STATUS_ERROR; + mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_ERROR; PrepareRxDoneAbort( ); return; } if (0 != LoRaMacJoinDecrypt( payload + 1, size - 1, - _params.keys.LoRaMacAppKey, - _params.LoRaMacRxPayload + 1 )) { - mcps.get_indication().Status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL; + _params.keys.app_key, + _params.payload + 1 )) { + mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL; return; } - _params.LoRaMacRxPayload[0] = macHdr.Value; + _params.payload[0] = macHdr.value; - if (0 != LoRaMacJoinComputeMic( _params.LoRaMacRxPayload, - size - LORAMAC_MFR_LEN, - _params.keys.LoRaMacAppKey, - &mic )) { - mcps.get_indication().Status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL; + if (0 != LoRaMacJoinComputeMic( _params.payload, size - LORAMAC_MFR_LEN, + _params.keys.app_key, &mic )) { + mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL; return; } - micRx |= ( uint32_t ) _params.LoRaMacRxPayload[size - LORAMAC_MFR_LEN]; - micRx |= ( ( uint32_t ) _params.LoRaMacRxPayload[size - LORAMAC_MFR_LEN + 1] << 8 ); - micRx |= ( ( uint32_t ) _params.LoRaMacRxPayload[size - LORAMAC_MFR_LEN + 2] << 16 ); - micRx |= ( ( uint32_t ) _params.LoRaMacRxPayload[size - LORAMAC_MFR_LEN + 3] << 24 ); + micRx |= ( uint32_t ) _params.payload[size - LORAMAC_MFR_LEN]; + micRx |= ( ( uint32_t ) _params.payload[size - LORAMAC_MFR_LEN + 1] << 8 ); + micRx |= ( ( uint32_t ) _params.payload[size - LORAMAC_MFR_LEN + 2] << 16 ); + micRx |= ( ( uint32_t ) _params.payload[size - LORAMAC_MFR_LEN + 3] << 24 ); if( micRx == mic ) { - if (0 != LoRaMacJoinComputeSKeys( _params.keys.LoRaMacAppKey, - _params.LoRaMacRxPayload + 1, - _params.LoRaMacDevNonce, - _params.keys.LoRaMacNwkSKey, - _params.keys.LoRaMacAppSKey )) { - mcps.get_indication().Status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL; + if (0 != LoRaMacJoinComputeSKeys( _params.keys.app_key, + _params.payload + 1, + _params.dev_nonce, + _params.keys.nwk_skey, + _params.keys.app_skey )) { + mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL; return; } - _params.LoRaMacNetID = ( uint32_t ) _params.LoRaMacRxPayload[4]; - _params.LoRaMacNetID |= ( ( uint32_t ) _params.LoRaMacRxPayload[5] << 8 ); - _params.LoRaMacNetID |= ( ( uint32_t ) _params.LoRaMacRxPayload[6] << 16 ); + _params.net_id = ( uint32_t ) _params.payload[4]; + _params.net_id |= ( ( uint32_t ) _params.payload[5] << 8 ); + _params.net_id |= ( ( uint32_t ) _params.payload[6] << 16 ); - _params.LoRaMacDevAddr = ( uint32_t ) _params.LoRaMacRxPayload[7]; - _params.LoRaMacDevAddr |= ( ( uint32_t ) _params.LoRaMacRxPayload[8] << 8 ); - _params.LoRaMacDevAddr |= ( ( uint32_t ) _params.LoRaMacRxPayload[9] << 16 ); - _params.LoRaMacDevAddr |= ( ( uint32_t ) _params.LoRaMacRxPayload[10] << 24 ); + _params.dev_addr = ( uint32_t ) _params.payload[7]; + _params.dev_addr |= ( ( uint32_t ) _params.payload[8] << 8 ); + _params.dev_addr |= ( ( uint32_t ) _params.payload[9] << 16 ); + _params.dev_addr |= ( ( uint32_t ) _params.payload[10] << 24 ); // DLSettings - _params.sys_params.Rx1DrOffset = ( _params.LoRaMacRxPayload[11] >> 4 ) & 0x07; - _params.sys_params.Rx2Channel.Datarate = _params.LoRaMacRxPayload[11] & 0x0F; + _params.sys_params.rx1_dr_offset = ( _params.payload[11] >> 4 ) & 0x07; + _params.sys_params.rx2_channel.datarate = _params.payload[11] & 0x0F; // RxDelay - _params.sys_params.ReceiveDelay1 = ( _params.LoRaMacRxPayload[12] & 0x0F ); - if( _params.sys_params.ReceiveDelay1 == 0 ) + _params.sys_params.recv_delay1 = ( _params.payload[12] & 0x0F ); + if( _params.sys_params.recv_delay1 == 0 ) { - _params.sys_params.ReceiveDelay1 = 1; + _params.sys_params.recv_delay1 = 1; } - _params.sys_params.ReceiveDelay1 *= 1000; - _params.sys_params.ReceiveDelay2 = _params.sys_params.ReceiveDelay1 + 1000; + _params.sys_params.recv_delay1 *= 1000; + _params.sys_params.recv_delay2 = _params.sys_params.recv_delay1 + 1000; // Apply CF list - applyCFList.Payload = &_params.LoRaMacRxPayload[13]; + applyCFList.Payload = &_params.payload[13]; // Size of the regular payload is 12. Plus 1 byte MHDR and 4 bytes MIC applyCFList.Size = size - 17; lora_phy->apply_cf_list(&applyCFList); - mlme.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_OK; - _params.IsLoRaMacNetworkJoined = true; + mlme.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_OK; + _params.is_nwk_joined = true; } else { - mlme.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL; + mlme.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL; } break; case FRAME_TYPE_DATA_CONFIRMED_DOWN: case FRAME_TYPE_DATA_UNCONFIRMED_DOWN: { // Check if the received payload size is valid - getPhy.UplinkDwellTime = _params.sys_params.DownlinkDwellTime; - getPhy.Datarate = mcps.get_indication().RxDatarate; + getPhy.UplinkDwellTime = _params.sys_params.downlink_dwell_time; + getPhy.Datarate = mcps.get_indication().rx_datarate; getPhy.Attribute = PHY_MAX_PAYLOAD; // Get the maximum payload length - if( _params.RepeaterSupport == true ) + if( _params.is_repeater_supported == true ) { getPhy.Attribute = PHY_MAX_PAYLOAD_REPEATER; } phyParam = lora_phy->get_phy_params(&getPhy); if( MAX( 0, ( int16_t )( ( int16_t )size - ( int16_t )LORA_MAC_FRMPAYLOAD_OVERHEAD ) ) > (int32_t)phyParam.Value ) { - mcps.get_indication().Status = LORAMAC_EVENT_INFO_STATUS_ERROR; + mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_ERROR; PrepareRxDoneAbort( ); return; } @@ -441,17 +439,17 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 address |= ( (uint32_t)payload[pktHeaderLen++] << 16 ); address |= ( (uint32_t)payload[pktHeaderLen++] << 24 ); - if( address != _params.LoRaMacDevAddr ) + if( address != _params.dev_addr ) { - curMulticastParams = _params.MulticastChannels; + curMulticastParams = _params.multicast_channels; while( curMulticastParams != NULL ) { - if( address == curMulticastParams->Address ) + if( address == curMulticastParams->address ) { multicast = 1; - nwkSKey = curMulticastParams->NwkSKey; - appSKey = curMulticastParams->AppSKey; - downLinkCounter = curMulticastParams->DownLinkCounter; + nwkSKey = curMulticastParams->nwk_skey; + appSKey = curMulticastParams->app_skey; + downLinkCounter = curMulticastParams->dl_frame_counter; break; } curMulticastParams = curMulticastParams->Next; @@ -459,7 +457,7 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 if( multicast == 0 ) { // We are not the destination of this frame. - mcps.get_indication().Status = LORAMAC_EVENT_INFO_STATUS_ADDRESS_FAIL; + mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_ADDRESS_FAIL; PrepareRxDoneAbort( ); return; } @@ -467,17 +465,17 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 else { multicast = 0; - nwkSKey = _params.keys.LoRaMacNwkSKey; - appSKey = _params.keys.LoRaMacAppSKey; - downLinkCounter = _params.DownLinkCounter; + nwkSKey = _params.keys.nwk_skey; + appSKey = _params.keys.app_skey; + downLinkCounter = _params.dl_frame_counter; } - fCtrl.Value = payload[pktHeaderLen++]; + fCtrl.value = payload[pktHeaderLen++]; sequenceCounter = ( uint16_t )payload[pktHeaderLen++]; sequenceCounter |= ( uint16_t )payload[pktHeaderLen++] << 8; - appPayloadStartIndex = 8 + fCtrl.Bits.FOptsLen; + appPayloadStartIndex = 8 + fCtrl.bits.fopts_len; micRx |= ( uint32_t )payload[size - LORAMAC_MFR_LEN]; micRx |= ( ( uint32_t )payload[size - LORAMAC_MFR_LEN + 1] << 8 ); @@ -513,50 +511,50 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 phyParam = lora_phy->get_phy_params( &getPhy ); if( sequenceCounterDiff >= phyParam.Value ) { - mcps.get_indication().Status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_TOO_MANY_FRAMES_LOSS; - mcps.get_indication().DownLinkCounter = downLinkCounter; + mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_TOO_MANY_FRAMES_LOSS; + mcps.get_indication().dl_frame_counter = downLinkCounter; PrepareRxDoneAbort( ); return; } if( isMicOk == true ) { - mcps.get_indication().Status = LORAMAC_EVENT_INFO_STATUS_OK; - mcps.get_indication().Multicast = multicast; - mcps.get_indication().FramePending = fCtrl.Bits.FPending; - mcps.get_indication().Buffer = NULL; - mcps.get_indication().BufferSize = 0; - mcps.get_indication().DownLinkCounter = downLinkCounter; + mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_OK; + mcps.get_indication().multicast = multicast; + mcps.get_indication().fpending_status = fCtrl.bits.fpending; + mcps.get_indication().buffer = NULL; + mcps.get_indication().buffer_size = 0; + mcps.get_indication().dl_frame_counter = downLinkCounter; - mcps.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_OK; + mcps.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_OK; - _params.AdrAckCounter = 0; + _params.adr_ack_counter = 0; mac_commands.ClearRepeatBuffer(); // Update 32 bits downlink counter if( multicast == 1 ) { - mcps.get_indication().McpsIndication = MCPS_MULTICAST; + mcps.get_indication().type = MCPS_MULTICAST; - if( ( curMulticastParams->DownLinkCounter == downLinkCounter ) && - ( curMulticastParams->DownLinkCounter != 0 ) ) + if( ( curMulticastParams->dl_frame_counter == downLinkCounter ) && + ( curMulticastParams->dl_frame_counter != 0 ) ) { - mcps.get_indication().Status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED; - mcps.get_indication().DownLinkCounter = downLinkCounter; + mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED; + mcps.get_indication().dl_frame_counter = downLinkCounter; PrepareRxDoneAbort( ); return; } - curMulticastParams->DownLinkCounter = downLinkCounter; + curMulticastParams->dl_frame_counter = downLinkCounter; } else { - if( macHdr.Bits.MType == FRAME_TYPE_DATA_CONFIRMED_DOWN ) + if( macHdr.bits.mtype == FRAME_TYPE_DATA_CONFIRMED_DOWN ) { - _params.SrvAckRequested = true; - mcps.get_indication().McpsIndication = MCPS_CONFIRMED; + _params.is_srv_ack_requested = true; + mcps.get_indication().type = MCPS_CONFIRMED; - if( ( _params.DownLinkCounter == downLinkCounter ) && - ( _params.DownLinkCounter != 0 ) ) + if( ( _params.dl_frame_counter == downLinkCounter ) && + ( _params.dl_frame_counter != 0 ) ) { // Duplicated confirmed downlink. Skip indication. // In this case, the MAC layer shall accept the MAC commands @@ -568,28 +566,28 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 } else { - _params.SrvAckRequested = false; - mcps.get_indication().McpsIndication = MCPS_UNCONFIRMED; + _params.is_srv_ack_requested = false; + mcps.get_indication().type = MCPS_UNCONFIRMED; - if( ( _params.DownLinkCounter == downLinkCounter ) && - ( _params.DownLinkCounter != 0 ) ) + if( ( _params.dl_frame_counter == downLinkCounter ) && + ( _params.dl_frame_counter != 0 ) ) { - mcps.get_indication().Status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED; - mcps.get_indication().DownLinkCounter = downLinkCounter; + mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED; + mcps.get_indication().dl_frame_counter = downLinkCounter; PrepareRxDoneAbort( ); return; } } - _params.DownLinkCounter = downLinkCounter; + _params.dl_frame_counter = downLinkCounter; } // This must be done before parsing the payload and the MAC commands. // We need to reset the MacCommandsBufferIndex here, since we need // to take retransmissions and repetitions into account. Error cases // will be handled in function OnMacStateCheckTimerEvent. - if( mcps.get_confirmation().McpsRequest == MCPS_CONFIRMED ) + if( mcps.get_confirmation().req_type == MCPS_CONFIRMED ) { - if( fCtrl.Bits.Ack == 1 ) + if( fCtrl.bits.ack == 1 ) {// Reset MacCommandsBufferIndex when we have received an ACK. mac_commands.ClearCommandBuffer(); } @@ -605,12 +603,12 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 port = payload[appPayloadStartIndex++]; frameLen = ( size - 4 ) - appPayloadStartIndex; - mcps.get_indication().Port = port; + mcps.get_indication().port = port; if( port == 0 ) { // Only allow frames which do not have fOpts - if( fCtrl.Bits.FOptsLen == 0 ) + if( fCtrl.bits.fopts_len == 0 ) { if (0 != LoRaMacPayloadDecrypt( payload + appPayloadStartIndex, frameLen, @@ -618,13 +616,13 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 address, DOWN_LINK, downLinkCounter, - _params.LoRaMacRxPayload )) { - mcps.get_indication().Status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL; + _params.payload )) { + mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL; } // Decode frame payload MAC commands - mac_commands.ProcessMacCommands( _params.LoRaMacRxPayload, 0, frameLen, snr, - mlme.get_confirmation(), LoRaMacCallbacks, + mac_commands.ProcessMacCommands( _params.payload, 0, frameLen, snr, + mlme.get_confirmation(), _params.sys_params, *lora_phy ); } else @@ -634,11 +632,11 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 } else { - if( fCtrl.Bits.FOptsLen > 0 ) + if( fCtrl.bits.fopts_len > 0 ) { // Decode Options field MAC commands. Omit the fPort. mac_commands.ProcessMacCommands( payload, 8, appPayloadStartIndex - 1, snr, - mlme.get_confirmation(), LoRaMacCallbacks, + mlme.get_confirmation(), _params.sys_params, *lora_phy ); } @@ -648,25 +646,25 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 address, DOWN_LINK, downLinkCounter, - _params.LoRaMacRxPayload )) { - mcps.get_indication().Status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL; + _params.payload )) { + mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL; } if( skipIndication == false ) { - mcps.get_indication().Buffer = _params.LoRaMacRxPayload; - mcps.get_indication().BufferSize = frameLen; - mcps.get_indication().RxData = true; + mcps.get_indication().buffer = _params.payload; + mcps.get_indication().buffer_size = frameLen; + mcps.get_indication().is_data_recvd = true; } } } else { - if( fCtrl.Bits.FOptsLen > 0 ) + if( fCtrl.bits.fopts_len > 0 ) { // Decode Options field MAC commands mac_commands.ProcessMacCommands( payload, 8, appPayloadStartIndex, snr, - mlme.get_confirmation(), LoRaMacCallbacks, + mlme.get_confirmation(), _params.sys_params, *lora_phy ); } } @@ -674,35 +672,35 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 if( skipIndication == false ) { // Check if the frame is an acknowledgement - if( fCtrl.Bits.Ack == 1 ) + if( fCtrl.bits.ack == 1 ) { - mcps.get_confirmation().AckReceived = true; - mcps.get_indication().AckReceived = true; + mcps.get_confirmation().ack_received = true; + mcps.get_indication().is_ack_recvd = true; // Stop the AckTimeout timer as no more retransmissions // are needed. - _lora_time.TimerStop( &_params.timers.AckTimeoutTimer ); + _lora_time.TimerStop( &_params.timers.ack_timeout_timer ); } else { - mcps.get_confirmation().AckReceived = false; + mcps.get_confirmation().ack_received = false; - if( _params.AckTimeoutRetriesCounter > _params.AckTimeoutRetries ) + if( _params.ack_timeout_retry_counter > _params.max_ack_timeout_retries ) { // Stop the AckTimeout timer as no more retransmissions // are needed. - _lora_time.TimerStop( &_params.timers.AckTimeoutTimer ); + _lora_time.TimerStop( &_params.timers.ack_timeout_timer ); } } } // Provide always an indication, skip the callback to the user application, // in case of a confirmed downlink retransmission. - _params.LoRaMacFlags.Bits.McpsInd = 1; - _params.LoRaMacFlags.Bits.McpsIndSkip = skipIndication; + _params.flags.bits.mcps_ind = 1; + _params.flags.bits.mcps_ind_skip = skipIndication; } else { - mcps.get_indication().Status = LORAMAC_EVENT_INFO_STATUS_MIC_FAIL; + mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_MIC_FAIL; PrepareRxDoneAbort( ); return; @@ -711,31 +709,31 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 break; case FRAME_TYPE_PROPRIETARY: { - memcpy( _params.LoRaMacRxPayload, &payload[pktHeaderLen], size ); + memcpy( _params.payload, &payload[pktHeaderLen], size ); - mcps.get_indication().McpsIndication = MCPS_PROPRIETARY; - mcps.get_indication().Status = LORAMAC_EVENT_INFO_STATUS_OK; - mcps.get_indication().Buffer = _params.LoRaMacRxPayload; - mcps.get_indication().BufferSize = size - pktHeaderLen; + mcps.get_indication().type = MCPS_PROPRIETARY; + mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_OK; + mcps.get_indication().buffer = _params.payload; + mcps.get_indication().buffer_size = size - pktHeaderLen; - _params.LoRaMacFlags.Bits.McpsInd = 1; + _params.flags.bits.mcps_ind = 1; break; } default: - mcps.get_indication().Status = LORAMAC_EVENT_INFO_STATUS_ERROR; + mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_ERROR; PrepareRxDoneAbort( ); break; } - _params.LoRaMacFlags.Bits.MacDone = 1; + _params.flags.bits.mac_done = 1; // Trig OnMacCheckTimerEvent call as soon as possible - _lora_time.TimerSetValue( &_params.timers.MacStateCheckTimer, 1 ); - _lora_time.TimerStart( &_params.timers.MacStateCheckTimer ); + _lora_time.TimerSetValue( &_params.timers.mac_state_check_timer, 1 ); + _lora_time.TimerStart( &_params.timers.mac_state_check_timer ); } void LoRaMac::OnRadioTxTimeout( void ) { - if( _params.LoRaMacDeviceClass != CLASS_C ) + if( _params.dev_class != CLASS_C ) { lora_phy->put_radio_to_sleep(); } @@ -744,16 +742,16 @@ void LoRaMac::OnRadioTxTimeout( void ) OpenContinuousRx2Window( ); } - mcps.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT; + mcps.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT; - mlme.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT; + mlme.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT; - _params.LoRaMacFlags.Bits.MacDone = 1; + _params.flags.bits.mac_done = 1; } void LoRaMac::OnRadioRxError( void ) { - if( _params.LoRaMacDeviceClass != CLASS_C ) + if( _params.dev_class != CLASS_C ) { lora_phy->put_radio_to_sleep(); } @@ -762,37 +760,37 @@ void LoRaMac::OnRadioRxError( void ) OpenContinuousRx2Window( ); } - if( _params.RxSlot == RX_SLOT_WIN_1 ) + if( _params.rx_slot == RX_SLOT_WIN_1 ) { - if( _params.NodeAckRequested == true ) + if( _params.is_node_ack_requested == true ) { - mcps.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_RX1_ERROR; + mcps.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_RX1_ERROR; } - mlme.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_RX1_ERROR; + mlme.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_RX1_ERROR; - if( _lora_time.TimerGetElapsedTime( _params.timers.AggregatedLastTxDoneTime ) >= _params.RxWindow2Delay ) + if( _lora_time.TimerGetElapsedTime( _params.timers.aggregated_last_tx_time ) >= _params.rx_window2_delay ) { - _lora_time.TimerStop( &_params.timers.RxWindowTimer2 ); - _params.LoRaMacFlags.Bits.MacDone = 1; + _lora_time.TimerStop( &_params.timers.rx_window2_timer ); + _params.flags.bits.mac_done = 1; } } else { - if( _params.NodeAckRequested == true ) + if( _params.is_node_ack_requested == true ) { - mcps.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_RX2_ERROR; + mcps.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_RX2_ERROR; } - mlme.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_RX2_ERROR; + mlme.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_RX2_ERROR; - _params.LoRaMacFlags.Bits.MacDone = 1; + _params.flags.bits.mac_done = 1; } } void LoRaMac::OnRadioRxTimeout( void ) { - if( _params.LoRaMacDeviceClass != CLASS_C ) + if( _params.dev_class != CLASS_C ) { lora_phy->put_radio_to_sleep(); } @@ -801,32 +799,32 @@ void LoRaMac::OnRadioRxTimeout( void ) OpenContinuousRx2Window( ); } - if( _params.RxSlot == RX_SLOT_WIN_1 ) + if( _params.rx_slot == RX_SLOT_WIN_1 ) { - if( _params.NodeAckRequested == true ) + if( _params.is_node_ack_requested == true ) { - mcps.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_RX1_TIMEOUT; + mcps.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_RX1_TIMEOUT; } - mlme.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_RX1_TIMEOUT; + mlme.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_RX1_TIMEOUT; - if( _lora_time.TimerGetElapsedTime( _params.timers.AggregatedLastTxDoneTime ) >= _params.RxWindow2Delay ) + if( _lora_time.TimerGetElapsedTime( _params.timers.aggregated_last_tx_time ) >= _params.rx_window2_delay ) { - _lora_time.TimerStop( &_params.timers.RxWindowTimer2 ); - _params.LoRaMacFlags.Bits.MacDone = 1; + _lora_time.TimerStop( &_params.timers.rx_window2_timer ); + _params.flags.bits.mac_done = 1; } } else { - if( _params.NodeAckRequested == true ) + if( _params.is_node_ack_requested == true ) { - mcps.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT; + mcps.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT; } - mlme.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT; + mlme.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT; - if( _params.LoRaMacDeviceClass != CLASS_C ) + if( _params.dev_class != CLASS_C ) { - _params.LoRaMacFlags.Bits.MacDone = 1; + _params.flags.bits.mac_done = 1; } } } @@ -840,54 +838,54 @@ void LoRaMac::OnMacStateCheckTimerEvent( void ) PhyParam_t phyParam; bool txTimeout = false; - _lora_time.TimerStop( &_params.timers.MacStateCheckTimer ); + _lora_time.TimerStop( &_params.timers.mac_state_check_timer ); - if( _params.LoRaMacFlags.Bits.MacDone == 1 ) + if( _params.flags.bits.mac_done == 1 ) { - if( ( _params.LoRaMacState & LORAMAC_RX_ABORT ) == LORAMAC_RX_ABORT ) + if( ( _params.mac_state & LORAMAC_RX_ABORT ) == LORAMAC_RX_ABORT ) { - _params.LoRaMacState &= ~LORAMAC_RX_ABORT; - _params.LoRaMacState &= ~LORAMAC_TX_RUNNING; + _params.mac_state &= ~LORAMAC_RX_ABORT; + _params.mac_state &= ~LORAMAC_TX_RUNNING; } - if( ( _params.LoRaMacFlags.Bits.MlmeReq == 1 ) || ( ( _params.LoRaMacFlags.Bits.McpsReq == 1 ) ) ) + if( ( _params.flags.bits.mlme_req == 1 ) || ( ( _params.flags.bits.mcps_req == 1 ) ) ) { - if( ( mcps.get_confirmation().Status == LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT ) || - ( mlme.get_confirmation().Status == LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT ) ) + if( ( mcps.get_confirmation().status == LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT ) || + ( mlme.get_confirmation().status == LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT ) ) { // Stop transmit cycle due to tx timeout. - _params.LoRaMacState &= ~LORAMAC_TX_RUNNING; + _params.mac_state &= ~LORAMAC_TX_RUNNING; mac_commands.ClearCommandBuffer(); - mcps.get_confirmation().NbRetries = _params.AckTimeoutRetriesCounter; - mcps.get_confirmation().AckReceived = false; - mcps.get_confirmation().TxTimeOnAir = 0; + mcps.get_confirmation().nb_retries = _params.ack_timeout_retry_counter; + mcps.get_confirmation().ack_received = false; + mcps.get_confirmation().tx_toa = 0; txTimeout = true; } } - if( ( _params.NodeAckRequested == false ) && ( txTimeout == false ) ) + if( ( _params.is_node_ack_requested == false ) && ( txTimeout == false ) ) { - if( ( _params.LoRaMacFlags.Bits.MlmeReq == 1 ) || ( ( _params.LoRaMacFlags.Bits.McpsReq == 1 ) ) ) + if( ( _params.flags.bits.mlme_req == 1 ) || ( ( _params.flags.bits.mcps_req == 1 ) ) ) { - if( ( _params.LoRaMacFlags.Bits.MlmeReq == 1 ) && ( mlme.get_confirmation().MlmeRequest == MLME_JOIN ) ) + if( ( _params.flags.bits.mlme_req == 1 ) && ( mlme.get_confirmation().req_type == MLME_JOIN ) ) {// Procedure for the join request - mlme.get_confirmation().NbRetries = _params.JoinRequestTrials; + mlme.get_confirmation().nb_retries = _params.join_request_trial_counter; - if( mlme.get_confirmation().Status == LORAMAC_EVENT_INFO_STATUS_OK ) + if( mlme.get_confirmation().status == LORAMAC_EVENT_INFO_STATUS_OK ) {// Node joined successfully - _params.UpLinkCounter = 0; - _params.ChannelsNbRepCounter = 0; - _params.LoRaMacState &= ~LORAMAC_TX_RUNNING; + _params.ul_frame_counter = 0; + _params.ul_nb_rep_counter = 0; + _params.mac_state &= ~LORAMAC_TX_RUNNING; } else { - if( _params.JoinRequestTrials >= _params.MaxJoinRequestTrials ) + if( _params.join_request_trial_counter >= _params.max_join_request_trials ) { - _params.LoRaMacState &= ~LORAMAC_TX_RUNNING; + _params.mac_state &= ~LORAMAC_TX_RUNNING; } else { - _params.LoRaMacFlags.Bits.MacDone = 0; + _params.flags.bits.mac_done = 0; // Sends the same frame again handle_delayed_tx_timer_event(); } @@ -895,27 +893,27 @@ void LoRaMac::OnMacStateCheckTimerEvent( void ) } else {// Procedure for all other frames - if( ( _params.ChannelsNbRepCounter >= _params.sys_params.ChannelsNbRep ) || ( _params.LoRaMacFlags.Bits.McpsInd == 1 ) ) + if( ( _params.ul_nb_rep_counter >= _params.sys_params.retry_num ) || ( _params.flags.bits.mcps_ind == 1 ) ) { - if( _params.LoRaMacFlags.Bits.McpsInd == 0 ) + if( _params.flags.bits.mcps_ind == 0 ) { // Maximum repetitions without downlink. Reset MacCommandsBufferIndex. Increase ADR Ack counter. // Only process the case when the MAC did not receive a downlink. mac_commands.ClearCommandBuffer(); - _params.AdrAckCounter++; + _params.adr_ack_counter++; } - _params.ChannelsNbRepCounter = 0; + _params.ul_nb_rep_counter = 0; - if( _params.IsUpLinkCounterFixed == false ) + if( _params.is_ul_frame_counter_fixed == false ) { - _params.UpLinkCounter++; + _params.ul_frame_counter++; } - _params.LoRaMacState &= ~LORAMAC_TX_RUNNING; + _params.mac_state &= ~LORAMAC_TX_RUNNING; } else { - _params.LoRaMacFlags.Bits.MacDone = 0; + _params.flags.bits.mac_done = 0; // Sends the same frame again handle_delayed_tx_timer_event(); } @@ -923,58 +921,58 @@ void LoRaMac::OnMacStateCheckTimerEvent( void ) } } - if( _params.LoRaMacFlags.Bits.McpsInd == 1 ) + if( _params.flags.bits.mcps_ind == 1 ) {// Procedure if we received a frame - if( ( mcps.get_confirmation().AckReceived == true ) || - ( _params.AckTimeoutRetriesCounter > _params.AckTimeoutRetries ) ) + if( ( mcps.get_confirmation().ack_received == true ) || + ( _params.ack_timeout_retry_counter > _params.max_ack_timeout_retries ) ) { - _params.AckTimeoutRetry = false; - _params.NodeAckRequested = false; - if( _params.IsUpLinkCounterFixed == false ) + _params.is_ack_retry_timeout_expired = false; + _params.is_node_ack_requested = false; + if( _params.is_ul_frame_counter_fixed == false ) { - _params.UpLinkCounter++; + _params.ul_frame_counter++; } - mcps.get_confirmation().NbRetries = _params.AckTimeoutRetriesCounter; + mcps.get_confirmation().nb_retries = _params.ack_timeout_retry_counter; - _params.LoRaMacState &= ~LORAMAC_TX_RUNNING; + _params.mac_state &= ~LORAMAC_TX_RUNNING; } } - if( ( _params.AckTimeoutRetry == true ) && ( ( _params.LoRaMacState & LORAMAC_TX_DELAYED ) == 0 ) ) + if( ( _params.is_ack_retry_timeout_expired == true ) && ( ( _params.mac_state & LORAMAC_TX_DELAYED ) == 0 ) ) {// Retransmissions procedure for confirmed uplinks - _params.AckTimeoutRetry = false; - if( ( _params.AckTimeoutRetriesCounter < _params.AckTimeoutRetries ) && - ( _params.AckTimeoutRetriesCounter <= MAX_ACK_RETRIES ) ) + _params.is_ack_retry_timeout_expired = false; + if( ( _params.ack_timeout_retry_counter < _params.max_ack_timeout_retries ) && + ( _params.ack_timeout_retry_counter <= MAX_ACK_RETRIES ) ) { - _params.AckTimeoutRetriesCounter++; + _params.ack_timeout_retry_counter++; - if( ( _params.AckTimeoutRetriesCounter % 2 ) == 1 ) + if( ( _params.ack_timeout_retry_counter % 2 ) == 1 ) { getPhy.Attribute = PHY_NEXT_LOWER_TX_DR; - getPhy.UplinkDwellTime = _params.sys_params.UplinkDwellTime; - getPhy.Datarate = _params.sys_params.ChannelsDatarate; + getPhy.UplinkDwellTime = _params.sys_params.uplink_dwell_time; + getPhy.Datarate = _params.sys_params.channel_data_rate; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.ChannelsDatarate = phyParam.Value; + _params.sys_params.channel_data_rate = phyParam.Value; } // Try to send the frame again - if( ScheduleTx( ) == LORAMAC_STATUS_OK ) + if( ScheduleTx( ) == LORAWAN_STATUS_OK ) { - _params.LoRaMacFlags.Bits.MacDone = 0; + _params.flags.bits.mac_done = 0; } else { // The DR is not applicable for the payload size - mcps.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_TX_DR_PAYLOAD_SIZE_ERROR; + mcps.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_TX_DR_PAYLOAD_SIZE_ERROR; mac_commands.ClearCommandBuffer(); - _params.LoRaMacState &= ~LORAMAC_TX_RUNNING; - _params.NodeAckRequested = false; - mcps.get_confirmation().AckReceived = false; - mcps.get_confirmation().NbRetries = _params.AckTimeoutRetriesCounter; - mcps.get_confirmation().Datarate = _params.sys_params.ChannelsDatarate; - if( _params.IsUpLinkCounterFixed == false ) + _params.mac_state &= ~LORAMAC_TX_RUNNING; + _params.is_node_ack_requested = false; + mcps.get_confirmation().ack_received = false; + mcps.get_confirmation().nb_retries = _params.ack_timeout_retry_counter; + mcps.get_confirmation().data_rate = _params.sys_params.channel_data_rate; + if( _params.is_ul_frame_counter_fixed == false ) { - _params.UpLinkCounter++; + _params.ul_frame_counter++; } } } @@ -982,36 +980,36 @@ void LoRaMac::OnMacStateCheckTimerEvent( void ) { lora_phy->load_defaults(INIT_TYPE_RESTORE); - _params.LoRaMacState &= ~LORAMAC_TX_RUNNING; + _params.mac_state &= ~LORAMAC_TX_RUNNING; mac_commands.ClearCommandBuffer(); - _params.NodeAckRequested = false; - mcps.get_confirmation().AckReceived = false; - mcps.get_confirmation().NbRetries = _params.AckTimeoutRetriesCounter; - if( _params.IsUpLinkCounterFixed == false ) + _params.is_node_ack_requested = false; + mcps.get_confirmation().ack_received = false; + mcps.get_confirmation().nb_retries = _params.ack_timeout_retry_counter; + if( _params.is_ul_frame_counter_fixed == false ) { - _params.UpLinkCounter++; + _params.ul_frame_counter++; } } } } // Handle reception for Class B and Class C - if( ( _params.LoRaMacState & LORAMAC_RX ) == LORAMAC_RX ) + if( ( _params.mac_state & LORAMAC_RX ) == LORAMAC_RX ) { - _params.LoRaMacState &= ~LORAMAC_RX; + _params.mac_state &= ~LORAMAC_RX; } - if( _params.LoRaMacState == LORAMAC_IDLE ) + if( _params.mac_state == LORAMAC_IDLE ) { - if( _params.LoRaMacFlags.Bits.McpsReq == 1 ) + if( _params.flags.bits.mcps_req == 1 ) { - _params.LoRaMacFlags.Bits.McpsReq = 0; - LoRaMacPrimitives->MacMcpsConfirm( &mcps.get_confirmation() ); + _params.flags.bits.mcps_req = 0; + LoRaMacPrimitives->mcps_confirm( &mcps.get_confirmation() ); } - if( _params.LoRaMacFlags.Bits.MlmeReq == 1 ) + if( _params.flags.bits.mlme_req == 1 ) { - _params.LoRaMacFlags.Bits.MlmeReq = 0; - LoRaMacPrimitives->MacMlmeConfirm(&mlme.get_confirmation()); + _params.flags.bits.mlme_req = 0; + LoRaMacPrimitives->mlme_confirm(&mlme.get_confirmation()); } // Verify if sticky MAC commands are pending or not @@ -1021,60 +1019,60 @@ void LoRaMac::OnMacStateCheckTimerEvent( void ) } // Procedure done. Reset variables. - _params.LoRaMacFlags.Bits.MacDone = 0; + _params.flags.bits.mac_done = 0; } else { // Operation not finished restart timer - _lora_time.TimerSetValue( &_params.timers.MacStateCheckTimer, + _lora_time.TimerSetValue( &_params.timers.mac_state_check_timer, MAC_STATE_CHECK_TIMEOUT ); - _lora_time.TimerStart( &_params.timers.MacStateCheckTimer ); + _lora_time.TimerStart( &_params.timers.mac_state_check_timer ); } // Handle MCPS indication - if( _params.LoRaMacFlags.Bits.McpsInd == 1 ) + if( _params.flags.bits.mcps_ind == 1 ) { - _params.LoRaMacFlags.Bits.McpsInd = 0; - if( _params.LoRaMacDeviceClass == CLASS_C ) + _params.flags.bits.mcps_ind = 0; + if( _params.dev_class== CLASS_C ) {// Activate RX2 window for Class C OpenContinuousRx2Window( ); } - if( _params.LoRaMacFlags.Bits.McpsIndSkip == 0 ) + if( _params.flags.bits.mcps_ind_skip == 0 ) { - LoRaMacPrimitives->MacMcpsIndication( &mcps.get_indication() ); + LoRaMacPrimitives->mcps_indication( &mcps.get_indication() ); } - _params.LoRaMacFlags.Bits.McpsIndSkip = 0; + _params.flags.bits.mcps_ind_skip = 0; } // Handle MLME indication - if( _params.LoRaMacFlags.Bits.MlmeInd == 1 ) + if( _params.flags.bits.mlme_ind == 1 ) { - _params.LoRaMacFlags.Bits.MlmeInd = 0; - LoRaMacPrimitives->MacMlmeIndication(&mlme.get_indication()); + _params.flags.bits.mlme_ind = 0; + LoRaMacPrimitives->mlme_indication(&mlme.get_indication()); } } void LoRaMac::OnTxDelayedTimerEvent( void ) { - LoRaMacHeader_t macHdr; - LoRaMacFrameCtrl_t fCtrl; + loramac_mhdr_t macHdr; + loramac_frame_ctrl_t fCtrl; AlternateDrParams_t altDr; - _lora_time.TimerStop( &_params.timers.TxDelayedTimer ); - _params.LoRaMacState &= ~LORAMAC_TX_DELAYED; + _lora_time.TimerStop( &_params.timers.tx_delayed_timer ); + _params.mac_state &= ~LORAMAC_TX_DELAYED; - if( ( _params.LoRaMacFlags.Bits.MlmeReq == 1 ) && ( mlme.get_confirmation().MlmeRequest == MLME_JOIN ) ) + if( ( _params.flags.bits.mlme_req == 1 ) && ( mlme.get_confirmation().req_type == MLME_JOIN ) ) { ResetMacParameters( ); - altDr.NbTrials = _params.JoinRequestTrials + 1; - _params.sys_params.ChannelsDatarate = lora_phy->get_alternate_DR(&altDr); + altDr.NbTrials = _params.join_request_trial_counter + 1; + _params.sys_params.channel_data_rate = lora_phy->get_alternate_DR(&altDr); - macHdr.Value = 0; - macHdr.Bits.MType = FRAME_TYPE_JOIN_REQ; + macHdr.value = 0; + macHdr.bits.mtype = FRAME_TYPE_JOIN_REQ; - fCtrl.Value = 0; - fCtrl.Bits.Adr = _params.sys_params.AdrCtrlOn; + fCtrl.value = 0; + fCtrl.bits.adr = _params.sys_params.adr_on; /* In case of join request retransmissions, the stack must prepare * the frame again, because the network server keeps track of the random @@ -1087,64 +1085,64 @@ void LoRaMac::OnTxDelayedTimerEvent( void ) void LoRaMac::OnRxWindow1TimerEvent( void ) { - _lora_time.TimerStop( &_params.timers.RxWindowTimer1 ); - _params.RxSlot = RX_SLOT_WIN_1; + _lora_time.TimerStop( &_params.timers.rx_window1_timer ); + _params.rx_slot= RX_SLOT_WIN_1; - _params.RxWindow1Config.Channel = _params.Channel; - _params.RxWindow1Config.DrOffset = _params.sys_params.Rx1DrOffset; - _params.RxWindow1Config.DownlinkDwellTime = _params.sys_params.DownlinkDwellTime; - _params.RxWindow1Config.RepeaterSupport = _params.RepeaterSupport; - _params.RxWindow1Config.RxContinuous = false; - _params.RxWindow1Config.RxSlot = _params.RxSlot; + _params.rx_window1_config.channel = _params.channel; + _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; + _params.rx_window1_config.is_rx_continuous = false; + _params.rx_window1_config.rx_slot = _params.rx_slot; - if( _params.LoRaMacDeviceClass == CLASS_C ) + if( _params.dev_class== CLASS_C ) { lora_phy->put_radio_to_standby(); } - lora_phy->rx_config(&_params.RxWindow1Config, ( int8_t* )&mcps.get_indication().RxDatarate); - RxWindowSetup( _params.RxWindow1Config.RxContinuous, _params.sys_params.MaxRxWindow ); + lora_phy->rx_config(&_params.rx_window1_config, ( int8_t* )&mcps.get_indication().rx_datarate); + RxWindowSetup( _params.rx_window1_config.is_rx_continuous, _params.sys_params.max_rx_win_time ); } void LoRaMac::OnRxWindow2TimerEvent( void ) { - _lora_time.TimerStop( &_params.timers.RxWindowTimer2 ); + _lora_time.TimerStop( &_params.timers.rx_window2_timer ); - _params.RxWindow2Config.Channel = _params.Channel; - _params.RxWindow2Config.Frequency = _params.sys_params.Rx2Channel.Frequency; - _params.RxWindow2Config.DownlinkDwellTime = _params.sys_params.DownlinkDwellTime; - _params.RxWindow2Config.RepeaterSupport = _params.RepeaterSupport; - _params.RxWindow2Config.RxSlot = RX_SLOT_WIN_2; + _params.rx_window2_config.channel = _params.channel; + _params.rx_window2_config.frequency = _params.sys_params.rx2_channel.frequency; + _params.rx_window2_config.dl_dwell_time = _params.sys_params.downlink_dwell_time; + _params.rx_window2_config.is_repeater_supported = _params.is_repeater_supported; + _params.rx_window2_config.rx_slot = RX_SLOT_WIN_2; - if( _params.LoRaMacDeviceClass != CLASS_C ) + if( _params.dev_class!= CLASS_C ) { - _params.RxWindow2Config.RxContinuous = false; + _params.rx_window2_config.is_rx_continuous = false; } else { // Setup continuous listening for class c - _params.RxWindow2Config.RxContinuous = true; + _params.rx_window2_config.is_rx_continuous = true; } - if(lora_phy->rx_config(&_params.RxWindow2Config, ( int8_t* )&mcps.get_indication().RxDatarate) == true ) + if(lora_phy->rx_config(&_params.rx_window2_config, ( int8_t* )&mcps.get_indication().rx_datarate) == true ) { - RxWindowSetup( _params.RxWindow2Config.RxContinuous, _params.sys_params.MaxRxWindow ); - _params.RxSlot = RX_SLOT_WIN_2; + RxWindowSetup( _params.rx_window2_config.is_rx_continuous, _params.sys_params.max_rx_win_time ); + _params.rx_slot= RX_SLOT_WIN_2; } } void LoRaMac::OnAckTimeoutTimerEvent( void ) { - _lora_time.TimerStop( &_params.timers.AckTimeoutTimer ); + _lora_time.TimerStop( &_params.timers.ack_timeout_timer ); - if( _params.NodeAckRequested == true ) + if( _params.is_node_ack_requested == true ) { - _params.AckTimeoutRetry = true; - _params.LoRaMacState &= ~LORAMAC_ACK_REQ; + _params.is_ack_retry_timeout_expired = true; + _params.mac_state &= ~LORAMAC_ACK_REQ; } - if( _params.LoRaMacDeviceClass == CLASS_C ) + if( _params.dev_class== CLASS_C ) { - _params.LoRaMacFlags.Bits.MacDone = 1; + _params.flags.bits.mac_done = 1; } } @@ -1161,12 +1159,12 @@ bool LoRaMac::ValidatePayloadLength( uint8_t lenN, int8_t datarate, uint8_t fOpt uint16_t payloadSize = 0; // Setup PHY request - getPhy.UplinkDwellTime = _params.sys_params.UplinkDwellTime; + getPhy.UplinkDwellTime = _params.sys_params.uplink_dwell_time; getPhy.Datarate = datarate; getPhy.Attribute = PHY_MAX_PAYLOAD; // Get the maximum payload length - if( _params.RepeaterSupport == true ) + if( _params.is_repeater_supported == true ) { getPhy.Attribute = PHY_MAX_PAYLOAD_REPEATER; } @@ -1186,127 +1184,127 @@ bool LoRaMac::ValidatePayloadLength( uint8_t lenN, int8_t datarate, uint8_t fOpt void LoRaMac::SetMlmeScheduleUplinkIndication( void ) { - mlme.get_indication().MlmeIndication = MLME_SCHEDULE_UPLINK; - _params.LoRaMacFlags.Bits.MlmeInd = 1; + mlme.get_indication().indication_type = MLME_SCHEDULE_UPLINK; + _params.flags.bits.mlme_ind = 1; } // This is not actual transmission. It just schedules a message in response // to MCPS request -LoRaMacStatus_t LoRaMac::Send( LoRaMacHeader_t *macHdr, uint8_t fPort, void *fBuffer, uint16_t fBufferSize ) +lorawan_status_t LoRaMac::Send( loramac_mhdr_t *macHdr, uint8_t fPort, void *fBuffer, uint16_t fBufferSize ) { - LoRaMacFrameCtrl_t fCtrl; - LoRaMacStatus_t status = LORAMAC_STATUS_PARAMETER_INVALID; + loramac_frame_ctrl_t fCtrl; + lorawan_status_t status = LORAWAN_STATUS_PARAMETER_INVALID; - fCtrl.Value = 0; - fCtrl.Bits.FOptsLen = 0; - fCtrl.Bits.FPending = 0; - fCtrl.Bits.Ack = false; - fCtrl.Bits.AdrAckReq = false; - fCtrl.Bits.Adr = _params.sys_params.AdrCtrlOn; + fCtrl.value = 0; + fCtrl.bits.fopts_len = 0; + fCtrl.bits.fpending = 0; + fCtrl.bits.ack = false; + fCtrl.bits.adr_ack_req = false; + fCtrl.bits.adr = _params.sys_params.adr_on; // Prepare the frame status = PrepareFrame( macHdr, &fCtrl, fPort, fBuffer, fBufferSize ); // Validate status - if( status != LORAMAC_STATUS_OK ) + if( status != LORAWAN_STATUS_OK ) { return status; } // Reset confirm parameters - mcps.get_confirmation().NbRetries = 0; - mcps.get_confirmation().AckReceived = false; - mcps.get_confirmation().UpLinkCounter = _params.UpLinkCounter; + mcps.get_confirmation().nb_retries = 0; + mcps.get_confirmation().ack_received = false; + mcps.get_confirmation().ul_frame_counter = _params.ul_frame_counter; status = ScheduleTx( ); return status; } -LoRaMacStatus_t LoRaMac::ScheduleTx( void ) +lorawan_status_t LoRaMac::ScheduleTx( void ) { - TimerTime_t dutyCycleTimeOff = 0; + lorawan_time_t dutyCycleTimeOff = 0; NextChanParams_t nextChan; // Check if the device is off - if( _params.sys_params.MaxDCycle == 255 ) + if( _params.sys_params.max_duty_cycle == 255 ) { - return LORAMAC_STATUS_DEVICE_OFF; + return LORAWAN_STATUS_DEVICE_OFF; } - if( _params.sys_params.MaxDCycle == 0 ) + if( _params.sys_params.max_duty_cycle == 0 ) { - _params.timers.AggregatedTimeOff = 0; + _params.timers.aggregated_timeoff = 0; } // Update Backoff - CalculateBackOff( _params.LastTxChannel ); + CalculateBackOff( _params.last_channel_idx ); - nextChan.AggrTimeOff = _params.timers.AggregatedTimeOff; - nextChan.Datarate = _params.sys_params.ChannelsDatarate; - _params.DutyCycleOn = MBED_CONF_LORA_DUTY_CYCLE_ON; - nextChan.DutyCycleEnabled = _params.DutyCycleOn; - nextChan.Joined = _params.IsLoRaMacNetworkJoined; - nextChan.LastAggrTx = _params.timers.AggregatedLastTxDoneTime; + nextChan.AggrTimeOff = _params.timers.aggregated_timeoff; + nextChan.Datarate = _params.sys_params.channel_data_rate; + _params.is_dutycycle_on = MBED_CONF_LORA_DUTY_CYCLE_ON; + nextChan.DutyCycleEnabled = _params.is_dutycycle_on; + nextChan.Joined = _params.is_nwk_joined; + nextChan.LastAggrTx = _params.timers.aggregated_last_tx_time; // Select channel - while( lora_phy->set_next_channel(&nextChan, &_params.Channel, &dutyCycleTimeOff, - &_params.timers.AggregatedTimeOff ) == false ) + while( lora_phy->set_next_channel(&nextChan, &_params.channel, &dutyCycleTimeOff, + &_params.timers.aggregated_timeoff ) == false ) { // Set the default datarate - _params.sys_params.ChannelsDatarate = _params.def_sys_params.ChannelsDatarate; + _params.sys_params.channel_data_rate = _params.def_sys_params.channel_data_rate; // Update datarate in the function parameters - nextChan.Datarate = _params.sys_params.ChannelsDatarate; + nextChan.Datarate = _params.sys_params.channel_data_rate; } - tr_debug("Next Channel Idx=%d, DR=%d", _params.Channel, nextChan.Datarate); + tr_debug("Next Channel Idx=%d, DR=%d", _params.channel, nextChan.Datarate); // Compute Rx1 windows parameters - uint8_t dr_offset = lora_phy->apply_DR_offset(_params.sys_params.DownlinkDwellTime, - _params.sys_params.ChannelsDatarate, - _params.sys_params.Rx1DrOffset); + uint8_t dr_offset = lora_phy->apply_DR_offset(_params.sys_params.downlink_dwell_time, + _params.sys_params.channel_data_rate, + _params.sys_params.rx1_dr_offset); - lora_phy->compute_rx_win_params(dr_offset, _params.sys_params.MinRxSymbols, - _params.sys_params.SystemMaxRxError, - &_params.RxWindow1Config ); + lora_phy->compute_rx_win_params(dr_offset, _params.sys_params.min_rx_symb, + _params.sys_params.max_sys_rx_error, + &_params.rx_window1_config ); // Compute Rx2 windows parameters - lora_phy->compute_rx_win_params(_params.sys_params.Rx2Channel.Datarate, - _params.sys_params.MinRxSymbols, - _params.sys_params.SystemMaxRxError, - &_params.RxWindow2Config ); + lora_phy->compute_rx_win_params(_params.sys_params.rx2_channel.datarate, + _params.sys_params.min_rx_symb, + _params.sys_params.max_sys_rx_error, + &_params.rx_window2_config ); - if( _params.IsLoRaMacNetworkJoined == false ) + if( _params.is_nwk_joined == false ) { - _params.RxWindow1Delay = _params.sys_params.JoinAcceptDelay1 + _params.RxWindow1Config.WindowOffset; - _params.RxWindow2Delay = _params.sys_params.JoinAcceptDelay2 + _params.RxWindow2Config.WindowOffset; + _params.rx_window1_delay = _params.sys_params.join_accept_delay1 + _params.rx_window1_config.window_offset; + _params.rx_window2_delay = _params.sys_params.join_accept_delay2 + _params.rx_window2_config.window_offset; } else { - if( ValidatePayloadLength( _params.LoRaMacTxPayloadLen, - _params.sys_params.ChannelsDatarate, + if( ValidatePayloadLength( _params.payload_length, + _params.sys_params.channel_data_rate, mac_commands.GetLength() ) == false ) { - return LORAMAC_STATUS_LENGTH_ERROR; + return LORAWAN_STATUS_LENGTH_ERROR; } - _params.RxWindow1Delay = _params.sys_params.ReceiveDelay1 + _params.RxWindow1Config.WindowOffset; - _params.RxWindow2Delay = _params.sys_params.ReceiveDelay2 + _params.RxWindow2Config.WindowOffset; + _params.rx_window1_delay = _params.sys_params.recv_delay1 + _params.rx_window1_config.window_offset; + _params.rx_window2_delay = _params.sys_params.recv_delay2 + _params.rx_window2_config.window_offset; } // Schedule transmission of frame if( dutyCycleTimeOff == 0 ) { // Try to send now - return SendFrameOnChannel( _params.Channel ); + return SendFrameOnChannel( _params.channel ); } else { // Send later - prepare timer - _params.LoRaMacState |= LORAMAC_TX_DELAYED; + _params.mac_state |= LORAMAC_TX_DELAYED; tr_debug("Next Transmission in %lu ms", dutyCycleTimeOff); - _lora_time.TimerSetValue( &_params.timers.TxDelayedTimer, dutyCycleTimeOff ); - _lora_time.TimerStart( &_params.timers.TxDelayedTimer ); + _lora_time.TimerSetValue( &_params.timers.tx_delayed_timer, dutyCycleTimeOff ); + _lora_time.TimerStart( &_params.timers.tx_delayed_timer ); - return LORAMAC_STATUS_OK; + return LORAWAN_STATUS_OK; } } @@ -1314,69 +1312,69 @@ void LoRaMac::CalculateBackOff( uint8_t channel ) { CalcBackOffParams_t calcBackOff; - calcBackOff.Joined = _params.IsLoRaMacNetworkJoined; - _params.DutyCycleOn = MBED_CONF_LORA_DUTY_CYCLE_ON; - calcBackOff.DutyCycleEnabled = _params.DutyCycleOn; + calcBackOff.Joined = _params.is_nwk_joined; + _params.is_dutycycle_on = MBED_CONF_LORA_DUTY_CYCLE_ON; + calcBackOff.DutyCycleEnabled = _params.is_dutycycle_on; calcBackOff.Channel = channel; - calcBackOff.ElapsedTime = _lora_time.TimerGetElapsedTime( _params.timers.LoRaMacInitializationTime ); - calcBackOff.TxTimeOnAir = _params.timers.TxTimeOnAir; - calcBackOff.LastTxIsJoinRequest = _params.LastTxIsJoinRequest; + calcBackOff.ElapsedTime = _lora_time.TimerGetElapsedTime( _params.timers.mac_init_time ); + calcBackOff.TxTimeOnAir = _params.timers.tx_toa; + calcBackOff.LastTxIsJoinRequest = _params.is_last_tx_join_request; // Update regional back-off lora_phy->calculate_backoff(&calcBackOff); // Update aggregated time-off - _params.timers.AggregatedTimeOff = _params.timers.AggregatedTimeOff + - ( _params.timers.TxTimeOnAir * _params.sys_params.AggregatedDCycle - _params.timers.TxTimeOnAir ); + _params.timers.aggregated_timeoff = _params.timers.aggregated_timeoff + + ( _params.timers.tx_toa * _params.sys_params.aggregated_duty_cycle - _params.timers.tx_toa ); } void LoRaMac::ResetMacParameters( void ) { - _params.IsLoRaMacNetworkJoined = false; + _params.is_nwk_joined = false; // Counters - _params.UpLinkCounter = 0; - _params.DownLinkCounter = 0; - _params.AdrAckCounter = 0; + _params.ul_frame_counter = 0; + _params.dl_frame_counter = 0; + _params.adr_ack_counter = 0; - _params.ChannelsNbRepCounter = 0; + _params.ul_nb_rep_counter = 0; - _params.AckTimeoutRetries = 1; - _params.AckTimeoutRetriesCounter = 1; - _params.AckTimeoutRetry = false; + _params.max_ack_timeout_retries = 1; + _params.ack_timeout_retry_counter = 1; + _params.is_ack_retry_timeout_expired = false; - _params.sys_params.MaxDCycle = 0; - _params.sys_params.AggregatedDCycle = 1; + _params.sys_params.max_duty_cycle = 0; + _params.sys_params.aggregated_duty_cycle = 1; mac_commands.ClearCommandBuffer(); mac_commands.ClearRepeatBuffer(); mac_commands.ClearMacCommandsInNextTx(); - _params.IsRxWindowsEnabled = true; + _params.is_rx_window_enabled = true; - _params.sys_params.ChannelsTxPower = _params.def_sys_params.ChannelsTxPower; - _params.sys_params.ChannelsDatarate = _params.def_sys_params.ChannelsDatarate; - _params.sys_params.Rx1DrOffset = _params.def_sys_params.Rx1DrOffset; - _params.sys_params.Rx2Channel = _params.def_sys_params.Rx2Channel; - _params.sys_params.UplinkDwellTime = _params.def_sys_params.UplinkDwellTime; - _params.sys_params.DownlinkDwellTime = _params.def_sys_params.DownlinkDwellTime; - _params.sys_params.MaxEirp = _params.def_sys_params.MaxEirp; - _params.sys_params.AntennaGain = _params.def_sys_params.AntennaGain; + _params.sys_params.channel_tx_power = _params.def_sys_params.channel_tx_power; + _params.sys_params.channel_data_rate = _params.def_sys_params.channel_data_rate; + _params.sys_params.rx1_dr_offset = _params.def_sys_params.rx1_dr_offset; + _params.sys_params.rx2_channel = _params.def_sys_params.rx2_channel; + _params.sys_params.uplink_dwell_time = _params.def_sys_params.uplink_dwell_time; + _params.sys_params.downlink_dwell_time = _params.def_sys_params.downlink_dwell_time; + _params.sys_params.max_eirp = _params.def_sys_params.max_eirp; + _params.sys_params.antenna_gain = _params.def_sys_params.antenna_gain; - _params.NodeAckRequested = false; - _params.SrvAckRequested = false; + _params.is_node_ack_requested = false; + _params.is_srv_ack_requested = false; // Reset Multicast downlink counters - MulticastParams_t *cur = _params.MulticastChannels; + multicast_params_t *cur = _params.multicast_channels; while( cur != NULL ) { - cur->DownLinkCounter = 0; + cur->dl_frame_counter = 0; cur = cur->Next; } // Initialize channel index. - _params.Channel = 0; - _params.LastTxChannel = _params.Channel; + _params.channel = 0; + _params.last_channel_idx = _params.channel; } bool LoRaMac::IsFPortAllowed( uint8_t fPort ) @@ -1391,7 +1389,7 @@ bool LoRaMac::IsFPortAllowed( uint8_t fPort ) void LoRaMac::OpenContinuousRx2Window( void ) { handle_rx2_timer_event( ); - _params.RxSlot = RX_SLOT_WIN_CLASS_C; + _params.rx_slot = RX_SLOT_WIN_CLASS_C; } static void memcpy_convert_endianess( uint8_t *dst, const uint8_t *src, uint16_t size ) @@ -1403,7 +1401,7 @@ static void memcpy_convert_endianess( uint8_t *dst, const uint8_t *src, uint16_t } } -LoRaMacStatus_t LoRaMac::PrepareFrame( LoRaMacHeader_t *macHdr, LoRaMacFrameCtrl_t *fCtrl, uint8_t fPort, void *fBuffer, uint16_t fBufferSize ) +lorawan_status_t LoRaMac::PrepareFrame( loramac_mhdr_t *macHdr, loramac_frame_ctrl_t *fCtrl, uint8_t fPort, void *fBuffer, uint16_t fBufferSize ) { AdrNextParams_t adrNext; uint16_t i; @@ -1411,113 +1409,113 @@ LoRaMacStatus_t LoRaMac::PrepareFrame( LoRaMacHeader_t *macHdr, LoRaMacFrameCtrl uint32_t mic = 0; const void* payload = fBuffer; uint8_t framePort = fPort; - LoRaMacStatus_t status = LORAMAC_STATUS_OK; + lorawan_status_t status = LORAWAN_STATUS_OK; - _params.LoRaMacBufferPktLen = 0; + _params.buffer_pkt_len = 0; - _params.NodeAckRequested = false; + _params.is_node_ack_requested = false; if( fBuffer == NULL ) { fBufferSize = 0; } - _params.LoRaMacTxPayloadLen = fBufferSize; + _params.payload_length = fBufferSize; - _params.LoRaMacBuffer[pktHeaderLen++] = macHdr->Value; + _params.buffer[pktHeaderLen++] = macHdr->value; - switch( macHdr->Bits.MType ) + switch( macHdr->bits.mtype ) { case FRAME_TYPE_JOIN_REQ: - _params.LoRaMacBufferPktLen = pktHeaderLen; + _params.buffer_pkt_len = pktHeaderLen; - memcpy_convert_endianess( _params.LoRaMacBuffer + _params.LoRaMacBufferPktLen, - _params.keys.LoRaMacAppEui, 8 ); - _params.LoRaMacBufferPktLen += 8; - memcpy_convert_endianess( _params.LoRaMacBuffer + _params.LoRaMacBufferPktLen, - _params.keys.LoRaMacDevEui, 8 ); - _params.LoRaMacBufferPktLen += 8; + memcpy_convert_endianess( _params.buffer + _params.buffer_pkt_len, + _params.keys.app_eui, 8 ); + _params.buffer_pkt_len += 8; + memcpy_convert_endianess( _params.buffer + _params.buffer_pkt_len, + _params.keys.dev_eui, 8 ); + _params.buffer_pkt_len += 8; - _params.LoRaMacDevNonce = lora_phy->get_radio_rng(); + _params.dev_nonce = lora_phy->get_radio_rng(); - _params.LoRaMacBuffer[_params.LoRaMacBufferPktLen++] = _params.LoRaMacDevNonce & 0xFF; - _params.LoRaMacBuffer[_params.LoRaMacBufferPktLen++] = ( _params.LoRaMacDevNonce >> 8 ) & 0xFF; + _params.buffer[_params.buffer_pkt_len++] = _params.dev_nonce & 0xFF; + _params.buffer[_params.buffer_pkt_len++] = ( _params.dev_nonce >> 8 ) & 0xFF; - if (0 != LoRaMacJoinComputeMic( _params.LoRaMacBuffer, - _params.LoRaMacBufferPktLen & 0xFF, - _params.keys.LoRaMacAppKey, &mic )) { - return LORAMAC_STATUS_CRYPTO_FAIL; + if (0 != LoRaMacJoinComputeMic( _params.buffer, + _params.buffer_pkt_len & 0xFF, + _params.keys.app_key, &mic )) { + return LORAWAN_STATUS_CRYPTO_FAIL; } - _params.LoRaMacBuffer[_params.LoRaMacBufferPktLen++] = mic & 0xFF; - _params.LoRaMacBuffer[_params.LoRaMacBufferPktLen++] = ( mic >> 8 ) & 0xFF; - _params. LoRaMacBuffer[_params.LoRaMacBufferPktLen++] = ( mic >> 16 ) & 0xFF; - _params.LoRaMacBuffer[_params.LoRaMacBufferPktLen++] = ( mic >> 24 ) & 0xFF; + _params.buffer[_params.buffer_pkt_len++] = mic & 0xFF; + _params.buffer[_params.buffer_pkt_len++] = ( mic >> 8 ) & 0xFF; + _params. buffer[_params.buffer_pkt_len++] = ( mic >> 16 ) & 0xFF; + _params.buffer[_params.buffer_pkt_len++] = ( mic >> 24 ) & 0xFF; break; case FRAME_TYPE_DATA_CONFIRMED_UP: - _params.NodeAckRequested = true; + _params.is_node_ack_requested = true; //Intentional fallthrough case FRAME_TYPE_DATA_UNCONFIRMED_UP: { - if( _params.IsLoRaMacNetworkJoined == false ) + if( _params.is_nwk_joined == false ) { - return LORAMAC_STATUS_NO_NETWORK_JOINED; // No network has been joined yet + return LORAWAN_STATUS_NO_NETWORK_JOINED; // No network has been joined yet } // Adr next request adrNext.UpdateChanMask = true; - adrNext.AdrEnabled = fCtrl->Bits.Adr; - adrNext.AdrAckCounter = _params.AdrAckCounter; - adrNext.Datarate = _params.sys_params.ChannelsDatarate; - adrNext.TxPower = _params.sys_params.ChannelsTxPower; - adrNext.UplinkDwellTime = _params.sys_params.UplinkDwellTime; + adrNext.AdrEnabled = fCtrl->bits.adr; + adrNext.AdrAckCounter = _params.adr_ack_counter; + adrNext.Datarate = _params.sys_params.channel_data_rate; + adrNext.TxPower = _params.sys_params.channel_tx_power; + adrNext.UplinkDwellTime = _params.sys_params.uplink_dwell_time; - fCtrl->Bits.AdrAckReq = lora_phy->get_next_ADR(&adrNext, - &_params.sys_params.ChannelsDatarate, - &_params.sys_params.ChannelsTxPower, - &_params.AdrAckCounter); + fCtrl->bits.adr_ack_req = lora_phy->get_next_ADR(&adrNext, + &_params.sys_params.channel_data_rate, + &_params.sys_params.channel_tx_power, + &_params.adr_ack_counter); - if( _params.SrvAckRequested == true ) + if( _params.is_srv_ack_requested == true ) { - _params.SrvAckRequested = false; - fCtrl->Bits.Ack = 1; + _params.is_srv_ack_requested = false; + fCtrl->bits.ack = 1; } - _params.LoRaMacBuffer[pktHeaderLen++] = ( _params.LoRaMacDevAddr ) & 0xFF; - _params.LoRaMacBuffer[pktHeaderLen++] = ( _params.LoRaMacDevAddr >> 8 ) & 0xFF; - _params.LoRaMacBuffer[pktHeaderLen++] = ( _params.LoRaMacDevAddr >> 16 ) & 0xFF; - _params.LoRaMacBuffer[pktHeaderLen++] = ( _params.LoRaMacDevAddr >> 24 ) & 0xFF; + _params.buffer[pktHeaderLen++] = ( _params.dev_addr ) & 0xFF; + _params.buffer[pktHeaderLen++] = ( _params.dev_addr >> 8 ) & 0xFF; + _params.buffer[pktHeaderLen++] = ( _params.dev_addr >> 16 ) & 0xFF; + _params.buffer[pktHeaderLen++] = ( _params.dev_addr >> 24 ) & 0xFF; - _params.LoRaMacBuffer[pktHeaderLen++] = fCtrl->Value; + _params.buffer[pktHeaderLen++] = fCtrl->value; - _params.LoRaMacBuffer[pktHeaderLen++] = _params.UpLinkCounter & 0xFF; - _params.LoRaMacBuffer[pktHeaderLen++] = ( _params.UpLinkCounter >> 8 ) & 0xFF; + _params.buffer[pktHeaderLen++] = _params.ul_frame_counter & 0xFF; + _params.buffer[pktHeaderLen++] = ( _params.ul_frame_counter >> 8 ) & 0xFF; // Copy the MAC commands which must be re-send into the MAC command buffer mac_commands.CopyRepeatCommandsToBuffer(); const uint8_t mac_commands_len = mac_commands.GetLength(); - if( ( payload != NULL ) && ( _params.LoRaMacTxPayloadLen > 0 ) ) + if( ( payload != NULL ) && ( _params.payload_length > 0 ) ) { if( mac_commands.IsMacCommandsInNextTx() == true ) { if( mac_commands_len <= LORA_MAC_COMMAND_MAX_FOPTS_LENGTH ) { - fCtrl->Bits.FOptsLen += mac_commands_len; + fCtrl->bits.fopts_len += mac_commands_len; // Update FCtrl field with new value of OptionsLength - _params.LoRaMacBuffer[0x05] = fCtrl->Value; + _params.buffer[0x05] = fCtrl->value; const uint8_t *buffer = mac_commands.GetMacCommandsBuffer(); for( i = 0; i < mac_commands_len; i++ ) { - _params.LoRaMacBuffer[pktHeaderLen++] = buffer[i]; + _params.buffer[pktHeaderLen++] = buffer[i]; } } else { - _params.LoRaMacTxPayloadLen = mac_commands_len; + _params.payload_length = mac_commands_len; payload = mac_commands.GetMacCommandsBuffer(); framePort = 0; } @@ -1527,7 +1525,7 @@ LoRaMacStatus_t LoRaMac::PrepareFrame( LoRaMacHeader_t *macHdr, LoRaMacFrameCtrl { if( ( mac_commands_len > 0 ) && ( mac_commands.IsMacCommandsInNextTx() == true ) ) { - _params.LoRaMacTxPayloadLen = mac_commands_len; + _params.payload_length = mac_commands_len; payload = mac_commands.GetMacCommandsBuffer(); framePort = 0; } @@ -1536,149 +1534,148 @@ LoRaMacStatus_t LoRaMac::PrepareFrame( LoRaMacHeader_t *macHdr, LoRaMacFrameCtrl // Store MAC commands which must be re-send in case the device does not receive a downlink anymore mac_commands.ParseMacCommandsToRepeat(); - if( ( payload != NULL ) && ( _params.LoRaMacTxPayloadLen > 0 ) ) + if( ( payload != NULL ) && ( _params.payload_length > 0 ) ) { - _params.LoRaMacBuffer[pktHeaderLen++] = framePort; + _params.buffer[pktHeaderLen++] = framePort; if( framePort == 0 ) { // Reset buffer index as the mac commands are being sent on port 0 mac_commands.ClearCommandBuffer(); if (0 != LoRaMacPayloadEncrypt( (uint8_t* ) payload, - _params.LoRaMacTxPayloadLen, - _params.keys.LoRaMacNwkSKey, - _params.LoRaMacDevAddr, + _params.payload_length, + _params.keys.nwk_skey, + _params.dev_addr, UP_LINK, - _params.UpLinkCounter, - &_params.LoRaMacBuffer[pktHeaderLen] )) { - status = LORAMAC_STATUS_CRYPTO_FAIL; + _params.ul_frame_counter, + &_params.buffer[pktHeaderLen] )) { + status = LORAWAN_STATUS_CRYPTO_FAIL; } } else { if (0 != LoRaMacPayloadEncrypt( (uint8_t* ) payload, - _params.LoRaMacTxPayloadLen, - _params.keys.LoRaMacAppSKey, - _params.LoRaMacDevAddr, + _params.payload_length, + _params.keys.app_skey, + _params.dev_addr, UP_LINK, - _params.UpLinkCounter, - &_params.LoRaMacBuffer[pktHeaderLen] )) { - status = LORAMAC_STATUS_CRYPTO_FAIL; + _params.ul_frame_counter, + &_params.buffer[pktHeaderLen] )) { + status = LORAWAN_STATUS_CRYPTO_FAIL; } } } - _params.LoRaMacBufferPktLen = pktHeaderLen + _params.LoRaMacTxPayloadLen; + _params.buffer_pkt_len = pktHeaderLen + _params.payload_length; - if (0 != LoRaMacComputeMic( _params.LoRaMacBuffer, - _params.LoRaMacBufferPktLen, - _params.keys.LoRaMacNwkSKey, - _params.LoRaMacDevAddr, + if (0 != LoRaMacComputeMic( _params.buffer, + _params.buffer_pkt_len, + _params.keys.nwk_skey, + _params.dev_addr, UP_LINK, - _params.UpLinkCounter, + _params.ul_frame_counter, &mic )) { - status = LORAMAC_STATUS_CRYPTO_FAIL; + status = LORAWAN_STATUS_CRYPTO_FAIL; } - _params.LoRaMacBuffer[_params.LoRaMacBufferPktLen + 0] = mic & 0xFF; - _params.LoRaMacBuffer[_params.LoRaMacBufferPktLen + 1] = ( mic >> 8 ) & 0xFF; - _params.LoRaMacBuffer[_params.LoRaMacBufferPktLen + 2] = ( mic >> 16 ) & 0xFF; - _params.LoRaMacBuffer[_params.LoRaMacBufferPktLen + 3] = ( mic >> 24 ) & 0xFF; + _params.buffer[_params.buffer_pkt_len + 0] = mic & 0xFF; + _params.buffer[_params.buffer_pkt_len + 1] = ( mic >> 8 ) & 0xFF; + _params.buffer[_params.buffer_pkt_len + 2] = ( mic >> 16 ) & 0xFF; + _params.buffer[_params.buffer_pkt_len + 3] = ( mic >> 24 ) & 0xFF; - _params.LoRaMacBufferPktLen += LORAMAC_MFR_LEN; + _params.buffer_pkt_len += LORAMAC_MFR_LEN; } break; case FRAME_TYPE_PROPRIETARY: - if( ( fBuffer != NULL ) && (_params.LoRaMacTxPayloadLen > 0 ) ) + if( ( fBuffer != NULL ) && (_params.payload_length > 0 ) ) { - memcpy( _params.LoRaMacBuffer + pktHeaderLen, ( uint8_t* ) fBuffer, _params.LoRaMacTxPayloadLen ); - _params.LoRaMacBufferPktLen = pktHeaderLen + _params.LoRaMacTxPayloadLen; + memcpy( _params.buffer + pktHeaderLen, ( uint8_t* ) fBuffer, _params.payload_length ); + _params.buffer_pkt_len = pktHeaderLen + _params.payload_length; } break; default: - status = LORAMAC_STATUS_SERVICE_UNKNOWN; + status = LORAWAN_STATUS_SERVICE_UNKNOWN; } return status; } -LoRaMacStatus_t LoRaMac::SendFrameOnChannel( uint8_t channel ) +lorawan_status_t LoRaMac::SendFrameOnChannel( uint8_t channel ) { TxConfigParams_t txConfig; int8_t txPower = 0; txConfig.Channel = channel; - txConfig.Datarate = _params.sys_params.ChannelsDatarate; - txConfig.TxPower = _params.sys_params.ChannelsTxPower; - txConfig.MaxEirp = _params.sys_params.MaxEirp; - txConfig.AntennaGain = _params.sys_params.AntennaGain; - txConfig.PktLen = _params.LoRaMacBufferPktLen; + txConfig.Datarate = _params.sys_params.channel_data_rate; + txConfig.TxPower = _params.sys_params.channel_tx_power; + txConfig.MaxEirp = _params.sys_params.max_eirp; + txConfig.AntennaGain = _params.sys_params.antenna_gain; + txConfig.PktLen = _params.buffer_pkt_len; - lora_phy->tx_config(&txConfig, &txPower, &_params.timers.TxTimeOnAir); + lora_phy->tx_config(&txConfig, &txPower, &_params.timers.tx_toa); - mlme.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_ERROR; + mlme.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_ERROR; - mcps.get_confirmation().Status = LORAMAC_EVENT_INFO_STATUS_ERROR; - mcps.get_confirmation().Datarate = _params.sys_params.ChannelsDatarate; - mcps.get_confirmation().TxPower = txPower; + mcps.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_ERROR; + mcps.get_confirmation().data_rate = _params.sys_params.channel_data_rate; + mcps.get_confirmation().tx_power = txPower; // Store the time on air - mcps.get_confirmation().TxTimeOnAir = _params.timers.TxTimeOnAir; - mlme.get_confirmation().TxTimeOnAir = _params.timers.TxTimeOnAir; + mcps.get_confirmation().tx_toa = _params.timers.tx_toa; + mlme.get_confirmation().tx_toa = _params.timers.tx_toa; // Starts the MAC layer status check timer - _lora_time.TimerSetValue( &_params.timers.MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT ); - _lora_time.TimerStart( &_params.timers.MacStateCheckTimer ); + _lora_time.TimerSetValue( &_params.timers.mac_state_check_timer, MAC_STATE_CHECK_TIMEOUT ); + _lora_time.TimerStart( &_params.timers.mac_state_check_timer ); - if( _params.IsLoRaMacNetworkJoined == false ) + if( _params.is_nwk_joined == false ) { - _params.JoinRequestTrials++; + _params.join_request_trial_counter++; } // Send now - lora_phy->handle_send(_params.LoRaMacBuffer, _params.LoRaMacBufferPktLen); + lora_phy->handle_send(_params.buffer, _params.buffer_pkt_len); - _params.LoRaMacState |= LORAMAC_TX_RUNNING; + _params.mac_state |= LORAMAC_TX_RUNNING; - return LORAMAC_STATUS_OK; + return LORAWAN_STATUS_OK; } -LoRaMacStatus_t LoRaMac::SetTxContinuousWave( uint16_t timeout ) +lorawan_status_t LoRaMac::SetTxContinuousWave( uint16_t timeout ) { ContinuousWaveParams_t continuousWave; - continuousWave.Channel = _params.Channel; - continuousWave.Datarate = _params.sys_params.ChannelsDatarate; - continuousWave.TxPower = _params.sys_params.ChannelsTxPower; - continuousWave.MaxEirp = _params.sys_params.MaxEirp; - continuousWave.AntennaGain = _params.sys_params.AntennaGain; + continuousWave.Channel = _params.channel; + continuousWave.Datarate = _params.sys_params.channel_data_rate; + continuousWave.TxPower = _params.sys_params.channel_tx_power; + continuousWave.MaxEirp = _params.sys_params.max_eirp; + continuousWave.AntennaGain = _params.sys_params.antenna_gain; continuousWave.Timeout = timeout; lora_phy->set_tx_cont_mode(&continuousWave); // Starts the MAC layer status check timer - _lora_time.TimerSetValue( &_params.timers.MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT ); - _lora_time.TimerStart( &_params.timers.MacStateCheckTimer ); + _lora_time.TimerSetValue( &_params.timers.mac_state_check_timer, MAC_STATE_CHECK_TIMEOUT ); + _lora_time.TimerStart( &_params.timers.mac_state_check_timer ); - _params.LoRaMacState |= LORAMAC_TX_RUNNING; + _params.mac_state |= LORAMAC_TX_RUNNING; - return LORAMAC_STATUS_OK; + return LORAWAN_STATUS_OK; } -LoRaMacStatus_t LoRaMac::SetTxContinuousWave1( uint16_t timeout, uint32_t frequency, uint8_t power ) +lorawan_status_t LoRaMac::SetTxContinuousWave1( uint16_t timeout, uint32_t frequency, uint8_t power ) { lora_phy->setup_tx_cont_wave_mode(frequency, power, timeout); // Starts the MAC layer status check timer - _lora_time.TimerSetValue( &_params.timers.MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT ); - _lora_time.TimerStart( &_params.timers.MacStateCheckTimer ); + _lora_time.TimerSetValue( &_params.timers.mac_state_check_timer, MAC_STATE_CHECK_TIMEOUT ); + _lora_time.TimerStart( &_params.timers.mac_state_check_timer ); - _params.LoRaMacState |= LORAMAC_TX_RUNNING; + _params.mac_state |= LORAMAC_TX_RUNNING; - return LORAMAC_STATUS_OK; + return LORAWAN_STATUS_OK; } -LoRaMacStatus_t LoRaMac::LoRaMacInitialization(LoRaMacPrimitives_t *primitives, - LoRaMacCallback_t *callbacks, +lorawan_status_t LoRaMac::LoRaMacInitialization(loramac_primitives_t *primitives, LoRaPHY *phy, EventQueue *queue) { @@ -1688,9 +1685,9 @@ LoRaMacStatus_t LoRaMac::LoRaMacInitialization(LoRaMacPrimitives_t *primitives, //store event queue pointer ev_queue = queue; - if(!primitives || !callbacks) + if(!primitives) { - return LORAMAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } lora_phy = phy; @@ -1708,175 +1705,174 @@ LoRaMacStatus_t LoRaMac::LoRaMacInitialization(LoRaMacPrimitives_t *primitives, ch_plan.activate_channelplan_subsystem(lora_phy, &mib); LoRaMacPrimitives = primitives; - LoRaMacCallbacks = callbacks; - _params.LoRaMacFlags.Value = 0; + _params.flags.value = 0; - _params.LoRaMacDeviceClass = CLASS_A; - _params.LoRaMacState = LORAMAC_IDLE; + _params.dev_class = CLASS_A; + _params.mac_state = LORAMAC_IDLE; - _params.JoinRequestTrials = 0; - _params.MaxJoinRequestTrials = 1; - _params.RepeaterSupport = false; + _params.join_request_trial_counter = 0; + _params.max_join_request_trials = 1; + _params.is_repeater_supported = false; // Reset duty cycle times - _params.timers.AggregatedLastTxDoneTime = 0; - _params.timers.AggregatedTimeOff = 0; + _params.timers.aggregated_last_tx_time = 0; + _params.timers.aggregated_timeoff = 0; // Reset to defaults getPhy.Attribute = PHY_DUTY_CYCLE; phyParam = lora_phy->get_phy_params(&getPhy); // load default at this moment. Later can be changed using json - _params.DutyCycleOn = ( bool ) phyParam.Value; + _params.is_dutycycle_on = ( bool ) phyParam.Value; getPhy.Attribute = PHY_DEF_TX_POWER; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.def_sys_params.ChannelsTxPower = phyParam.Value; + _params.def_sys_params.channel_tx_power = phyParam.Value; getPhy.Attribute = PHY_DEF_TX_DR; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.def_sys_params.ChannelsDatarate = phyParam.Value; + _params.def_sys_params.channel_data_rate = phyParam.Value; getPhy.Attribute = PHY_MAX_RX_WINDOW; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.def_sys_params.MaxRxWindow = phyParam.Value; + _params.def_sys_params.max_rx_win_time = phyParam.Value; getPhy.Attribute = PHY_RECEIVE_DELAY1; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.def_sys_params.ReceiveDelay1 = phyParam.Value; + _params.def_sys_params.recv_delay1 = phyParam.Value; getPhy.Attribute = PHY_RECEIVE_DELAY2; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.def_sys_params.ReceiveDelay2 = phyParam.Value; + _params.def_sys_params.recv_delay2 = phyParam.Value; getPhy.Attribute = PHY_JOIN_ACCEPT_DELAY1; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.def_sys_params.JoinAcceptDelay1 = phyParam.Value; + _params.def_sys_params.join_accept_delay1 = phyParam.Value; getPhy.Attribute = PHY_JOIN_ACCEPT_DELAY2; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.def_sys_params.JoinAcceptDelay2 = phyParam.Value; + _params.def_sys_params.join_accept_delay2 = phyParam.Value; getPhy.Attribute = PHY_DEF_DR1_OFFSET; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.def_sys_params.Rx1DrOffset = phyParam.Value; + _params.def_sys_params.rx1_dr_offset = phyParam.Value; getPhy.Attribute = PHY_DEF_RX2_FREQUENCY; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.def_sys_params.Rx2Channel.Frequency = phyParam.Value; + _params.def_sys_params.rx2_channel.frequency = phyParam.Value; getPhy.Attribute = PHY_DEF_RX2_DR; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.def_sys_params.Rx2Channel.Datarate = phyParam.Value; + _params.def_sys_params.rx2_channel.datarate = phyParam.Value; getPhy.Attribute = PHY_DEF_UPLINK_DWELL_TIME; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.def_sys_params.UplinkDwellTime = phyParam.Value; + _params.def_sys_params.uplink_dwell_time = phyParam.Value; getPhy.Attribute = PHY_DEF_DOWNLINK_DWELL_TIME; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.def_sys_params.DownlinkDwellTime = phyParam.Value; + _params.def_sys_params.downlink_dwell_time = phyParam.Value; getPhy.Attribute = PHY_DEF_MAX_EIRP; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.def_sys_params.MaxEirp = phyParam.fValue; + _params.def_sys_params.max_eirp = phyParam.fValue; getPhy.Attribute = PHY_DEF_ANTENNA_GAIN; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.def_sys_params.AntennaGain = phyParam.fValue; + _params.def_sys_params.antenna_gain = phyParam.fValue; lora_phy->load_defaults(INIT_TYPE_INIT); // Init parameters which are not set in function ResetMacParameters - _params.def_sys_params.ChannelsNbRep = 1; - _params.def_sys_params.SystemMaxRxError = 10; - _params.def_sys_params.MinRxSymbols = 6; + _params.def_sys_params.retry_num = 1; + _params.def_sys_params.max_sys_rx_error = 10; + _params.def_sys_params.min_rx_symb = 6; - _params.sys_params.SystemMaxRxError = _params.def_sys_params.SystemMaxRxError; - _params.sys_params.MinRxSymbols = _params.def_sys_params.MinRxSymbols; - _params.sys_params.MaxRxWindow = _params.def_sys_params.MaxRxWindow; - _params.sys_params.ReceiveDelay1 = _params.def_sys_params.ReceiveDelay1; - _params.sys_params.ReceiveDelay2 = _params.def_sys_params.ReceiveDelay2; - _params.sys_params.JoinAcceptDelay1 = _params.def_sys_params.JoinAcceptDelay1; - _params.sys_params.JoinAcceptDelay2 = _params.def_sys_params.JoinAcceptDelay2; - _params.sys_params.ChannelsNbRep = _params.def_sys_params.ChannelsNbRep; + _params.sys_params.max_sys_rx_error = _params.def_sys_params.max_sys_rx_error; + _params.sys_params.min_rx_symb = _params.def_sys_params.min_rx_symb; + _params.sys_params.max_rx_win_time = _params.def_sys_params.max_rx_win_time; + _params.sys_params.recv_delay1 = _params.def_sys_params.recv_delay1; + _params.sys_params.recv_delay2 = _params.def_sys_params.recv_delay2; + _params.sys_params.join_accept_delay1 = _params.def_sys_params.join_accept_delay1; + _params.sys_params.join_accept_delay2 = _params.def_sys_params.join_accept_delay2; + _params.sys_params.retry_num = _params.def_sys_params.retry_num; ResetMacParameters( ); // Random seed initialization srand(lora_phy->get_radio_rng()); - _params.PublicNetwork = MBED_CONF_LORA_PUBLIC_NETWORK; - lora_phy->setup_public_network_mode(_params.PublicNetwork); + _params.is_nwk_public = MBED_CONF_LORA_PUBLIC_NETWORK; + lora_phy->setup_public_network_mode(_params.is_nwk_public); lora_phy->put_radio_to_sleep(); // Initialize timers - _lora_time.TimerInit(&_params.timers.MacStateCheckTimer, + _lora_time.TimerInit(&_params.timers.mac_state_check_timer, mbed::callback(this, &LoRaMac::handle_mac_state_check_timer_event)); - _lora_time.TimerSetValue(&_params.timers.MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT); + _lora_time.TimerSetValue(&_params.timers.mac_state_check_timer, MAC_STATE_CHECK_TIMEOUT); - _lora_time.TimerInit(&_params.timers.TxDelayedTimer, + _lora_time.TimerInit(&_params.timers.tx_delayed_timer, mbed::callback(this, &LoRaMac::handle_delayed_tx_timer_event)); - _lora_time.TimerInit(&_params.timers.RxWindowTimer1, + _lora_time.TimerInit(&_params.timers.rx_window1_timer, mbed::callback(this, &LoRaMac::handle_rx1_timer_event)); - _lora_time.TimerInit(&_params.timers.RxWindowTimer2, + _lora_time.TimerInit(&_params.timers.rx_window2_timer, mbed::callback(this, &LoRaMac::handle_rx2_timer_event)); - _lora_time.TimerInit(&_params.timers.AckTimeoutTimer, + _lora_time.TimerInit(&_params.timers.ack_timeout_timer, mbed::callback(this, &LoRaMac::handle_ack_timeout)); // Store the current initialization time - _params.timers.LoRaMacInitializationTime = _lora_time.TimerGetCurrentTime(); + _params.timers.mac_init_time = _lora_time.TimerGetCurrentTime(); - return LORAMAC_STATUS_OK; + return LORAWAN_STATUS_OK; } -LoRaMacStatus_t LoRaMac::LoRaMacQueryTxPossible( uint8_t size, LoRaMacTxInfo_t* txInfo ) +lorawan_status_t LoRaMac::LoRaMacQueryTxPossible( uint8_t size, loramac_tx_info_t* txInfo ) { AdrNextParams_t adrNext; GetPhyParams_t getPhy; PhyParam_t phyParam; - int8_t datarate = _params.def_sys_params.ChannelsDatarate; - int8_t txPower = _params.def_sys_params.ChannelsTxPower; + int8_t datarate = _params.def_sys_params.channel_data_rate; + int8_t txPower = _params.def_sys_params.channel_tx_power; uint8_t fOptLen = mac_commands.GetLength() + mac_commands.GetRepeatLength(); if( txInfo == NULL ) { - return LORAMAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } // Setup ADR request adrNext.UpdateChanMask = false; - adrNext.AdrEnabled = _params.sys_params.AdrCtrlOn; - adrNext.AdrAckCounter = _params.AdrAckCounter; - adrNext.Datarate = _params.sys_params.ChannelsDatarate; - adrNext.TxPower = _params.sys_params.ChannelsTxPower; - adrNext.UplinkDwellTime = _params.sys_params.UplinkDwellTime; + adrNext.AdrEnabled = _params.sys_params.adr_on; + adrNext.AdrAckCounter = _params.adr_ack_counter; + adrNext.Datarate = _params.sys_params.channel_data_rate; + adrNext.TxPower = _params.sys_params.channel_tx_power; + adrNext.UplinkDwellTime = _params.sys_params.uplink_dwell_time; // We call the function for information purposes only. We don't want to // apply the datarate, the tx power and the ADR ack counter. - lora_phy->get_next_ADR(&adrNext, &datarate, &txPower, &_params.AdrAckCounter); + lora_phy->get_next_ADR(&adrNext, &datarate, &txPower, &_params.adr_ack_counter); // Setup PHY request - getPhy.UplinkDwellTime = _params.sys_params.UplinkDwellTime; + getPhy.UplinkDwellTime = _params.sys_params.uplink_dwell_time; getPhy.Datarate = datarate; getPhy.Attribute = PHY_MAX_PAYLOAD; // Change request in case repeater is supported - if( _params.RepeaterSupport == true ) + if( _params.is_repeater_supported == true ) { getPhy.Attribute = PHY_MAX_PAYLOAD_REPEATER; } phyParam = lora_phy->get_phy_params( &getPhy ); - txInfo->CurrentPayloadSize = phyParam.Value; + txInfo->current_payload_size = phyParam.Value; // Verify if the fOpts fit into the maximum payload - if( txInfo->CurrentPayloadSize >= fOptLen ) + if( txInfo->current_payload_size >= fOptLen ) { - txInfo->MaxPossiblePayload = txInfo->CurrentPayloadSize - fOptLen; + txInfo->max_possible_payload_size = txInfo->current_payload_size - fOptLen; } else { - txInfo->MaxPossiblePayload = txInfo->CurrentPayloadSize; + txInfo->max_possible_payload_size = txInfo->current_payload_size; // The fOpts don't fit into the maximum payload. Omit the MAC commands to // ensure that another uplink is possible. fOptLen = 0; @@ -1887,32 +1883,32 @@ LoRaMacStatus_t LoRaMac::LoRaMacQueryTxPossible( uint8_t size, LoRaMacTxInfo_t* // Verify if the fOpts and the payload fit into the maximum payload if( ValidatePayloadLength( size, datarate, fOptLen ) == false ) { - return LORAMAC_STATUS_LENGTH_ERROR; + return LORAWAN_STATUS_LENGTH_ERROR; } - return LORAMAC_STATUS_OK; + return LORAWAN_STATUS_OK; } -LoRaMacStatus_t LoRaMac::AddChannelPlan(const lora_channelplan_t& plan) +lorawan_status_t LoRaMac::AddChannelPlan(const lorawan_channelplan_t& plan) { // Validate if the MAC is in a correct state - if( ( _params.LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) + if( ( _params.mac_state & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) { - if( ( _params.LoRaMacState & LORAMAC_TX_CONFIG ) != LORAMAC_TX_CONFIG ) + if( ( _params.mac_state & LORAMAC_TX_CONFIG ) != LORAMAC_TX_CONFIG ) { - return LORAMAC_STATUS_BUSY; + return LORAWAN_STATUS_BUSY; } } return ch_plan.set_plan(plan); } -LoRaMacStatus_t LoRaMac::RemoveChannelPlan() +lorawan_status_t LoRaMac::RemoveChannelPlan() { - if( ( _params.LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) + if( ( _params.mac_state & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) { - if( ( _params.LoRaMacState & LORAMAC_TX_CONFIG ) != LORAMAC_TX_CONFIG ) + if( ( _params.mac_state & LORAMAC_TX_CONFIG ) != LORAMAC_TX_CONFIG ) { - return LORAMAC_STATUS_BUSY; + return LORAWAN_STATUS_BUSY; } } @@ -1920,46 +1916,46 @@ LoRaMacStatus_t LoRaMac::RemoveChannelPlan() } -LoRaMacStatus_t LoRaMac::GetChannelPlan(lora_channelplan_t& plan) +lorawan_status_t LoRaMac::GetChannelPlan(lorawan_channelplan_t& plan) { return ch_plan.get_plan(plan, &_params); } -LoRaMacStatus_t LoRaMac::RemoveSingleChannel(uint8_t id) +lorawan_status_t LoRaMac::RemoveSingleChannel(uint8_t id) { - if( ( _params.LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) + if( ( _params.mac_state & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) { - if( ( _params.LoRaMacState & LORAMAC_TX_CONFIG ) != LORAMAC_TX_CONFIG ) + if( ( _params.mac_state & LORAMAC_TX_CONFIG ) != LORAMAC_TX_CONFIG ) { - return LORAMAC_STATUS_BUSY; + return LORAWAN_STATUS_BUSY; } } return ch_plan.remove_single_channel(id); } -LoRaMacStatus_t LoRaMac::LoRaMacMulticastChannelLink( MulticastParams_t *channelParam ) +lorawan_status_t LoRaMac::LoRaMacMulticastChannelLink( multicast_params_t *channelParam ) { if( channelParam == NULL ) { - return LORAMAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } - if( ( _params.LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) + if( ( _params.mac_state & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) { - return LORAMAC_STATUS_BUSY; + return LORAWAN_STATUS_BUSY; } // Reset downlink counter - channelParam->DownLinkCounter = 0; + channelParam->dl_frame_counter = 0; - if( _params.MulticastChannels == NULL ) + if( _params.multicast_channels == NULL ) { // New node is the fist element - _params.MulticastChannels = channelParam; + _params.multicast_channels = channelParam; } else { - MulticastParams_t *cur = _params.MulticastChannels; + multicast_params_t *cur = _params.multicast_channels; // Search the last node in the list while( cur->Next != NULL ) @@ -1970,30 +1966,30 @@ LoRaMacStatus_t LoRaMac::LoRaMacMulticastChannelLink( MulticastParams_t *channel cur->Next = channelParam; } - return LORAMAC_STATUS_OK; + return LORAWAN_STATUS_OK; } -LoRaMacStatus_t LoRaMac::LoRaMacMulticastChannelUnlink( MulticastParams_t *channelParam ) +lorawan_status_t LoRaMac::LoRaMacMulticastChannelUnlink( multicast_params_t *channelParam ) { if( channelParam == NULL ) { - return LORAMAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } - if( ( _params.LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) + if( ( _params.mac_state & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) { - return LORAMAC_STATUS_BUSY; + return LORAWAN_STATUS_BUSY; } - if( _params.MulticastChannels != NULL ) + if( _params.multicast_channels != NULL ) { - if( _params.MulticastChannels == channelParam ) + if( _params.multicast_channels == channelParam ) { // First element - _params.MulticastChannels = channelParam->Next; + _params.multicast_channels = channelParam->Next; } else { - MulticastParams_t *cur = _params.MulticastChannels; + multicast_params_t *cur = _params.multicast_channels; // Search the node in the list while( cur->Next && cur->Next != channelParam ) @@ -2009,25 +2005,29 @@ LoRaMacStatus_t LoRaMac::LoRaMacMulticastChannelUnlink( MulticastParams_t *chann channelParam->Next = NULL; } - return LORAMAC_STATUS_OK; + return LORAWAN_STATUS_OK; } -LoRaMacStatus_t LoRaMac::LoRaMacMlmeRequest( MlmeReq_t *mlmeRequest ) +lorawan_status_t LoRaMac::LoRaMacMlmeRequest( loramac_mlme_req_t *mlmeRequest ) { return mlme.set_request(mlmeRequest, &_params); } -LoRaMacStatus_t LoRaMac::LoRaMacMcpsRequest( McpsReq_t *mcpsRequest ) +lorawan_status_t LoRaMac::LoRaMacMcpsRequest( loramac_mcps_req_t *mcpsRequest ) { + if (_params.mac_state != LORAMAC_IDLE) { + return LORAWAN_STATUS_BUSY; + } + return mcps.set_request(mcpsRequest, &_params); } -LoRaMacStatus_t LoRaMac::LoRaMacMibGetRequestConfirm( MibRequestConfirm_t *mibGet ) +lorawan_status_t LoRaMac::LoRaMacMibGetRequestConfirm( loramac_mib_req_confirm_t *mibGet ) { return mib.get_request(mibGet, &_params); } -LoRaMacStatus_t LoRaMac::LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSet ) +lorawan_status_t LoRaMac::LoRaMacMibSetRequestConfirm( loramac_mib_req_confirm_t *mibSet ) { return mib.set_request(mibSet, &_params); } @@ -2048,31 +2048,30 @@ radio_events_t *LoRaMac::GetPhyEventHandlers() * Compliance testing * **************************************************************************/ -LoRaMacStatus_t LoRaMac::LoRaMacSetTxTimer( uint32_t TxDutyCycleTime ) +lorawan_status_t LoRaMac::LoRaMacSetTxTimer( uint32_t TxDutyCycleTime ) { - _lora_time.TimerSetValue(&TxNextPacketTimer, TxDutyCycleTime); - _lora_time.TimerStart(&TxNextPacketTimer); + _lora_time.TimerSetValue(&tx_next_packet_timer, TxDutyCycleTime); + _lora_time.TimerStart(&tx_next_packet_timer); - return LORAMAC_STATUS_OK; + return LORAWAN_STATUS_OK; } -LoRaMacStatus_t LoRaMac::LoRaMacStopTxTimer( ) - + lorawan_status_t LoRaMac::LoRaMacStopTxTimer( ) { - _lora_time.TimerStop(&TxNextPacketTimer); + _lora_time.TimerStop(&tx_next_packet_timer); - return LORAMAC_STATUS_OK; + return LORAWAN_STATUS_OK; } void LoRaMac::LoRaMacTestRxWindowsOn( bool enable ) { - _params.IsRxWindowsEnabled = enable; + _params.is_rx_window_enabled = enable; } void LoRaMac::LoRaMacTestSetMic( uint16_t txPacketCounter ) { - _params.UpLinkCounter = txPacketCounter; - _params.IsUpLinkCounterFixed = true; + _params.ul_frame_counter = txPacketCounter; + _params.is_ul_frame_counter_fixed = true; } void LoRaMac::LoRaMacTestSetDutyCycleOn( bool enable ) @@ -2083,12 +2082,12 @@ void LoRaMac::LoRaMacTestSetDutyCycleOn( bool enable ) if(lora_phy->verify(&verify, PHY_DUTY_CYCLE) == true) { - _params.DutyCycleOn = enable; + _params.is_dutycycle_on = enable; } } void LoRaMac::LoRaMacTestSetChannel( uint8_t channel ) { - _params.Channel = channel; + _params.channel = channel; } #endif diff --git a/features/lorawan/lorastack/mac/LoRaMac.h b/features/lorawan/lorastack/mac/LoRaMac.h index 031ada4a2e..668381d3f2 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.h +++ b/features/lorawan/lorastack/mac/LoRaMac.h @@ -83,12 +83,11 @@ public: * \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. + * \ref LORAWAN_STATUS_OK + * \ref LORAWAN_STATUS_PARAMETER_INVALID + * \ref LORAWAN_STATUS_REGION_NOT_SUPPORTED. */ - LoRaMacStatus_t LoRaMacInitialization(LoRaMacPrimitives_t *primitives, - LoRaMacCallback_t *callbacks, + lorawan_status_t LoRaMacInitialization(loramac_primitives_t *primitives, LoRaPHY *phy, events::EventQueue *queue); @@ -105,16 +104,16 @@ public: * size, taking the scheduled MAC commands into account. * * \retval `LoRaMacStatus_t` The status of the operation. When the parameters are - * not valid, the function returns \ref LORAMAC_STATUS_PARAMETER_INVALID. + * not valid, the function returns \ref LORAWAN_STATUS_PARAMETER_INVALID. * In case of a length error caused by the applicable payload in combination - * with the MAC commands, the function returns \ref LORAMAC_STATUS_LENGTH_ERROR. + * with the MAC commands, the function returns \ref LORAWAN_STATUS_LENGTH_ERROR. * Please note that if the size of the MAC commands in the queue do * not fit into the payload size on the related datarate, the LoRaMAC will * omit the MAC commands. * If the query is valid, and the LoRaMAC is able to send the frame, - * the function returns \ref LORAMAC_STATUS_OK. + * the function returns \ref LORAWAN_STATUS_OK. */ - LoRaMacStatus_t LoRaMacQueryTxPossible( uint8_t size, LoRaMacTxInfo_t* txInfo ); + lorawan_status_t LoRaMacQueryTxPossible( uint8_t size, loramac_tx_info_t* txInfo ); /*! * \brief Adds a channel plan to the system. @@ -127,11 +126,11 @@ public: * \param plan [in] - A reference to application provided channel plan. * * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: - * \ref LORAMAC_STATUS_OK - * \ref LORAMAC_STATUS_BUSY - * \ref LORAMAC_STATUS_PARAMETER_INVALID + * \ref LORAWAN_STATUS_OK + * \ref LORAWAN_STATUS_BUSY + * \ref LORAWAN_STATUS_PARAMETER_INVALID */ - LoRaMacStatus_t AddChannelPlan(const lora_channelplan_t& plan); + lorawan_status_t AddChannelPlan(const lorawan_channelplan_t& plan); /*! * \brief Removes a channel plan from the system. @@ -142,11 +141,11 @@ public: * LoRaWAN Regional Parameters V1.0.2rB. * * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: - * \ref LORAMAC_STATUS_OK - * \ref LORAMAC_STATUS_BUSY - * \ref LORAMAC_STATUS_PARAMETER_INVALID + * \ref LORAWAN_STATUS_OK + * \ref LORAWAN_STATUS_BUSY + * \ref LORAWAN_STATUS_PARAMETER_INVALID */ - LoRaMacStatus_t RemoveChannelPlan(); + lorawan_status_t RemoveChannelPlan(); /*! * \brief Access active channel plan. @@ -158,11 +157,11 @@ public: * plan. * * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: - * \ref LORAMAC_STATUS_OK - * \ref LORAMAC_STATUS_BUSY - * \ref LORAMAC_STATUS_PARAMETER_INVALID + * \ref LORAWAN_STATUS_OK + * \ref LORAWAN_STATUS_BUSY + * \ref LORAWAN_STATUS_PARAMETER_INVALID */ - LoRaMacStatus_t GetChannelPlan(lora_channelplan_t& plan); + lorawan_status_t GetChannelPlan(lorawan_channelplan_t& plan); /*! * \brief Remove a given channel from the active plan. @@ -172,11 +171,11 @@ public: * \param id - Id of the channel. * * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: - * \ref LORAMAC_STATUS_OK - * \ref LORAMAC_STATUS_BUSY - * \ref LORAMAC_STATUS_PARAMETER_INVALID + * \ref LORAWAN_STATUS_OK + * \ref LORAWAN_STATUS_BUSY + * \ref LORAWAN_STATUS_PARAMETER_INVALID */ - LoRaMacStatus_t RemoveSingleChannel( uint8_t id ); + lorawan_status_t RemoveSingleChannel( uint8_t id ); /*! * \brief LoRaMAC multicast channel link service. @@ -186,11 +185,11 @@ public: * \param [in] channelParam - The multicast channel parameters to link. * * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: - * \ref LORAMAC_STATUS_OK - * \ref LORAMAC_STATUS_BUSY - * \ref LORAMAC_STATUS_PARAMETER_INVALID + * \ref LORAWAN_STATUS_OK + * \ref LORAWAN_STATUS_BUSY + * \ref LORAWAN_STATUS_PARAMETER_INVALID */ - LoRaMacStatus_t LoRaMacMulticastChannelLink( MulticastParams_t *channelParam ); + lorawan_status_t LoRaMacMulticastChannelLink( multicast_params_t *channelParam ); /*! * \brief LoRaMAC multicast channel unlink service. @@ -200,11 +199,11 @@ public: * \param [in] channelParam - The multicast channel parameters to unlink. * * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: - * \ref LORAMAC_STATUS_OK - * \ref LORAMAC_STATUS_BUSY - * \ref LORAMAC_STATUS_PARAMETER_INVALID + * \ref LORAWAN_STATUS_OK + * \ref LORAWAN_STATUS_BUSY + * \ref LORAWAN_STATUS_PARAMETER_INVALID */ - LoRaMacStatus_t LoRaMacMulticastChannelUnlink( MulticastParams_t *channelParam ); + lorawan_status_t LoRaMacMulticastChannelUnlink( multicast_params_t *channelParam ); /*! * \brief LoRaMAC MIB-GET. @@ -218,7 +217,7 @@ public: * MibRequestConfirm_t mibReq; * mibReq.Type = MIB_ADR; * - * if( LoRaMacMibGetRequestConfirm( &mibReq ) == LORAMAC_STATUS_OK ) + * if( LoRaMacMibGetRequestConfirm( &mibReq ) == LORAWAN_STATUS_OK ) * { * // LoRaMAC updated the parameter mibParam.AdrEnable * } @@ -227,11 +226,11 @@ public: * \param [in] mibGet - The MIB-GET request to perform. Refer to \ref MibRequestConfirm_t. * * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: - * \ref LORAMAC_STATUS_OK - * \ref LORAMAC_STATUS_SERVICE_UNKNOWN - * \ref LORAMAC_STATUS_PARAMETER_INVALID + * \ref LORAWAN_STATUS_OK + * \ref LORAWAN_STATUS_SERVICE_UNKNOWN + * \ref LORAWAN_STATUS_PARAMETER_INVALID */ - LoRaMacStatus_t LoRaMacMibGetRequestConfirm( MibRequestConfirm_t *mibGet ); + lorawan_status_t LoRaMacMibGetRequestConfirm( loramac_mib_req_confirm_t *mibGet ); /*! * \brief LoRaMAC MIB-SET. @@ -247,7 +246,7 @@ public: * mibReq.Type = MIB_ADR; * mibReq.Param.AdrEnable = true; * - * if( LoRaMacMibGetRequestConfirm( &mibReq ) == LORAMAC_STATUS_OK ) + * if( LoRaMacMibGetRequestConfirm( &mibReq ) == LORAWAN_STATUS_OK ) * { * // LoRaMAC updated the parameter * } @@ -256,12 +255,12 @@ public: * \param [in] mibSet - The MIB-SET request to perform. Refer to \ref MibRequestConfirm_t. * * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: - * \ref LORAMAC_STATUS_OK - * \ref LORAMAC_STATUS_BUSY - * \ref LORAMAC_STATUS_SERVICE_UNKNOWN - * \ref LORAMAC_STATUS_PARAMETER_INVALID + * \ref LORAWAN_STATUS_OK + * \ref LORAWAN_STATUS_BUSY + * \ref LORAWAN_STATUS_SERVICE_UNKNOWN + * \ref LORAWAN_STATUS_PARAMETER_INVALID */ - LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSet ); + lorawan_status_t LoRaMacMibSetRequestConfirm( loramac_mib_req_confirm_t *mibSet ); /*! * \brief LoRaMAC MLME request @@ -291,7 +290,7 @@ public: * mlmeReq.Req.Join.AppEui = AppEui; * mlmeReq.Req.Join.AppKey = AppKey; * - * if( LoRaMacMlmeRequest( &mlmeReq ) == LORAMAC_STATUS_OK ) + * if( LoRaMacMlmeRequest( &mlmeReq ) == LORAWAN_STATUS_OK ) * { * // Service started successfully. Waiting for the Mlme-Confirm event * } @@ -300,15 +299,15 @@ public: * \param [in] mlmeRequest - The MLME request to perform. Refer to \ref MlmeReq_t. * * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: - * \ref LORAMAC_STATUS_OK - * \ref LORAMAC_STATUS_BUSY - * \ref LORAMAC_STATUS_SERVICE_UNKNOWN - * \ref LORAMAC_STATUS_PARAMETER_INVALID - * \ref LORAMAC_STATUS_NO_NETWORK_JOINED - * \ref LORAMAC_STATUS_LENGTH_ERROR - * \ref LORAMAC_STATUS_DEVICE_OFF + * \ref LORAWAN_STATUS_OK + * \ref LORAWAN_STATUS_BUSY + * \ref LORAWAN_STATUS_SERVICE_UNKNOWN + * \ref LORAWAN_STATUS_PARAMETER_INVALID + * \ref LORAWAN_STATUS_NO_NETWORK_JOINED + * \ref LORAWAN_STATUS_LENGTH_ERROR + * \ref LORAWAN_STATUS_DEVICE_OFF */ - LoRaMacStatus_t LoRaMacMlmeRequest( MlmeReq_t *mlmeRequest ); + lorawan_status_t LoRaMacMlmeRequest( loramac_mlme_req_t *mlmeRequest ); /*! * \brief LoRaMAC MCPS request @@ -326,7 +325,7 @@ public: * mcpsReq.Req.Unconfirmed.fBuffer = myBuffer; * mcpsReq.Req.Unconfirmed.fBufferSize = sizeof( myBuffer ); * - * if( LoRaMacMcpsRequest( &mcpsReq ) == LORAMAC_STATUS_OK ) + * if( LoRaMacMcpsRequest( &mcpsReq ) == LORAWAN_STATUS_OK ) * { * // Service started successfully. Waiting for the MCPS-Confirm event * } @@ -335,15 +334,15 @@ public: * \param [in] mcpsRequest - The MCPS request to perform. Refer to \ref McpsReq_t. * * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: - * \ref LORAMAC_STATUS_OK - * \ref LORAMAC_STATUS_BUSY - * \ref LORAMAC_STATUS_SERVICE_UNKNOWN - * \ref LORAMAC_STATUS_PARAMETER_INVALID - * \ref LORAMAC_STATUS_NO_NETWORK_JOINED - * \ref LORAMAC_STATUS_LENGTH_ERROR - * \ref LORAMAC_STATUS_DEVICE_OFF + * \ref LORAWAN_STATUS_OK + * \ref LORAWAN_STATUS_BUSY + * \ref LORAWAN_STATUS_SERVICE_UNKNOWN + * \ref LORAWAN_STATUS_PARAMETER_INVALID + * \ref LORAWAN_STATUS_NO_NETWORK_JOINED + * \ref LORAWAN_STATUS_LENGTH_ERROR + * \ref LORAWAN_STATUS_DEVICE_OFF */ - LoRaMacStatus_t LoRaMacMcpsRequest( McpsReq_t *mcpsRequest ); + lorawan_status_t LoRaMacMcpsRequest( loramac_mcps_req_t *mcpsRequest ); /** * \brief LoRaMAC layer provides its callback functions for @@ -368,7 +367,7 @@ public: * \param [IN] fBufferSize MAC data buffer size * \retval status Status of the operation. */ - LoRaMacStatus_t Send( LoRaMacHeader_t *macHdr, uint8_t fPort, void *fBuffer, uint16_t fBufferSize ); + lorawan_status_t Send( loramac_mhdr_t *macHdr, uint8_t fPort, void *fBuffer, uint16_t fBufferSize ); /*! * \brief Sets the radio in continuous transmission mode @@ -378,7 +377,7 @@ public: * \param [IN] timeout Time in seconds while the radio is kept in continuous wave mode * \retval status Status of the operation. */ - LoRaMacStatus_t SetTxContinuousWave( uint16_t timeout ); + lorawan_status_t SetTxContinuousWave( uint16_t timeout ); /*! * \brief Sets the radio in continuous transmission mode @@ -390,7 +389,7 @@ public: * \param [IN] power RF output power to be set. * \retval status Status of the operation. */ - LoRaMacStatus_t SetTxContinuousWave1( uint16_t timeout, uint32_t frequency, uint8_t power ); + lorawan_status_t SetTxContinuousWave1( uint16_t timeout, uint32_t frequency, uint8_t power ); /*! * \brief Resets MAC specific parameters to default @@ -414,10 +413,10 @@ public: // Test interface * \param [in] NextTxTime - Periodic time for next uplink. * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: - * \ref LORAMAC_STATUS_OK - * \ref LORAMAC_STATUS_PARAMETER_INVALID + * \ref LORAWAN_STATUS_OK + * \ref LORAWAN_STATUS_PARAMETER_INVALID */ - LoRaMacStatus_t LoRaMacSetTxTimer( uint32_t NextTxTime ); + lorawan_status_t LoRaMacSetTxTimer( uint32_t NextTxTime ); /** * \brief LoRaMAC stop tx timer. @@ -425,10 +424,10 @@ public: // Test interface * \details Stops the next tx timer. * * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: - * \ref LORAMAC_STATUS_OK - * \ref LORAMAC_STATUS_PARAMETER_INVALID + * \ref LORAWAN_STATUS_OK + * \ref LORAWAN_STATUS_PARAMETER_INVALID */ - LoRaMacStatus_t LoRaMacStopTxTimer( ); + lorawan_status_t LoRaMacStopTxTimer( ); /** * \brief Enabled or disables the reception windows @@ -474,7 +473,7 @@ private: /** * Timer to handle the application data transmission duty cycle */ - TimerEvent_t TxNextPacketTimer; + timer_event_t tx_next_packet_timer; #endif private: @@ -576,14 +575,14 @@ private: * \param [IN] fBufferSize MAC data buffer size * \retval status Status of the operation. */ - LoRaMacStatus_t PrepareFrame( LoRaMacHeader_t *macHdr, LoRaMacFrameCtrl_t *fCtrl, uint8_t fPort, void *fBuffer, uint16_t fBufferSize ); + lorawan_status_t PrepareFrame( loramac_mhdr_t *macHdr, loramac_frame_ctrl_t *fCtrl, uint8_t fPort, void *fBuffer, uint16_t fBufferSize ); /* * \brief Schedules the frame according to the duty cycle * * \retval Status of the operation */ - LoRaMacStatus_t ScheduleTx( void ); + lorawan_status_t ScheduleTx( void ); /* * \brief Calculates the back-off time for the band of a channel. @@ -601,7 +600,7 @@ private: * \param [IN] channel Channel to transmit on * \retval status Status of the operation. */ - LoRaMacStatus_t SendFrameOnChannel( uint8_t channel ); + lorawan_status_t SendFrameOnChannel( uint8_t channel ); /*! * \brief Resets MAC specific parameters to default @@ -669,7 +668,7 @@ private: /** * Central MAC layer data storage */ - lora_mac_protocol_params _params; + loramac_protocol_params _params; /** * Radio event callback handlers for MAC @@ -679,12 +678,7 @@ private: /*! * LoRaMac upper layer event functions */ - LoRaMacPrimitives_t *LoRaMacPrimitives; - - /*! - * LoRaMac upper layer callback functions - */ - LoRaMacCallback_t *LoRaMacCallbacks; + loramac_primitives_t *LoRaMacPrimitives; }; #endif // __LORAMAC_H__ diff --git a/features/lorawan/lorastack/mac/LoRaMacChannelPlan.cpp b/features/lorawan/lorastack/mac/LoRaMacChannelPlan.cpp index 6f576b98b3..b84c8ca1f3 100644 --- a/features/lorawan/lorastack/mac/LoRaMacChannelPlan.cpp +++ b/features/lorawan/lorastack/mac/LoRaMacChannelPlan.cpp @@ -39,11 +39,11 @@ void LoRaMacChannelPlan::activate_channelplan_subsystem(LoRaPHY *phy, LoRaMacMib _mib = mib; } -LoRaMacStatus_t LoRaMacChannelPlan::set_plan(const lora_channelplan_t& plan) +lorawan_status_t LoRaMacChannelPlan::set_plan(const lorawan_channelplan_t& plan) { ChannelAddParams_t channelAdd; - ChannelParams_t mac_layer_ch_params; - LoRaMacStatus_t status; + channel_params_t mac_layer_ch_params; + lorawan_status_t status; GetPhyParams_t get_phy; PhyParam_t phy_param; @@ -56,20 +56,20 @@ LoRaMacStatus_t LoRaMacChannelPlan::set_plan(const lora_channelplan_t& plan) // check if user is setting more channels than supported if (plan.nb_channels > max_num_channels) { - return LORAMAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } for (uint8_t i = 0; i < plan.nb_channels; i++) { - mac_layer_ch_params.Band = plan.channels[i].ch_param.band; - mac_layer_ch_params.DrRange.Fields.Max = - plan.channels[i].ch_param.dr_range.lora_mac_fields_s.max; - mac_layer_ch_params.DrRange.Fields.Min = - plan.channels[i].ch_param.dr_range.lora_mac_fields_s.min; - mac_layer_ch_params.DrRange.Value = + mac_layer_ch_params.band = plan.channels[i].ch_param.band; + mac_layer_ch_params.dr_range.fields.max = + plan.channels[i].ch_param.dr_range.fields.max; + mac_layer_ch_params.dr_range.fields.min = + plan.channels[i].ch_param.dr_range.fields.min; + mac_layer_ch_params.dr_range.value = plan.channels[i].ch_param.dr_range.value; - mac_layer_ch_params.Frequency = + mac_layer_ch_params.frequency = plan.channels[i].ch_param.frequency; - mac_layer_ch_params.Rx1Frequency = + mac_layer_ch_params.rx1_frequency = plan.channels[i].ch_param.rx1_frequency; channelAdd.ChannelId = plan.channels[i].id; @@ -77,23 +77,23 @@ LoRaMacStatus_t LoRaMacChannelPlan::set_plan(const lora_channelplan_t& plan) status = _lora_phy->add_channel(&channelAdd); - if (status != LORAMAC_STATUS_OK) { + if (status != LORAWAN_STATUS_OK) { return status; } } - return LORAMAC_STATUS_OK; + return LORAWAN_STATUS_OK; } -LoRaMacStatus_t LoRaMacChannelPlan::get_plan(lora_channelplan_t& plan, - lora_mac_protocol_params *params) +lorawan_status_t LoRaMacChannelPlan::get_plan(lorawan_channelplan_t& plan, + loramac_protocol_params *params) { if (params == NULL) { - return LORAMAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } - MibRequestConfirm_t mib_params; - LoRaMacStatus_t status; + loramac_mib_req_confirm_t mib_confirm; + lorawan_status_t status; GetPhyParams_t get_phy; PhyParam_t phy_param; @@ -112,12 +112,12 @@ LoRaMacStatus_t LoRaMacChannelPlan::get_plan(lora_channelplan_t& plan, channel_masks = phy_param.ChannelsMask; // Request Mib to get channels - memset(&mib_params, 0, sizeof(mib_params)); - mib_params.Type = MIB_CHANNELS; + memset(&mib_confirm, 0, sizeof(mib_confirm)); + mib_confirm.type = MIB_CHANNELS; - status = _mib->get_request(&mib_params, params); + status = _mib->get_request(&mib_confirm, params); - if (status != LORAMAC_STATUS_OK) { + if (status != LORAWAN_STATUS_OK) { return status; } @@ -129,23 +129,23 @@ LoRaMacStatus_t LoRaMacChannelPlan::get_plan(lora_channelplan_t& plan, // otherwise add them to the channel_plan struct plan.channels[count].id = i; - plan.channels[count].ch_param.frequency = mib_params.Param.ChannelList[i].Frequency; - plan.channels[count].ch_param.dr_range.value = mib_params.Param.ChannelList[i].DrRange.Value; - plan.channels[count].ch_param.dr_range.lora_mac_fields_s.min = mib_params.Param.ChannelList[i].DrRange.Fields.Min; - plan.channels[count].ch_param.dr_range.lora_mac_fields_s.max = mib_params.Param.ChannelList[i].DrRange.Fields.Max; - plan.channels[count].ch_param.band = mib_params.Param.ChannelList[i].Band; - plan.channels[count].ch_param.rx1_frequency = mib_params.Param.ChannelList[i].Rx1Frequency; + plan.channels[count].ch_param.frequency = mib_confirm.param.channel_list[i].frequency; + plan.channels[count].ch_param.dr_range.value = mib_confirm.param.channel_list[i].dr_range.value; + plan.channels[count].ch_param.dr_range.fields.min = mib_confirm.param.channel_list[i].dr_range.fields.min; + plan.channels[count].ch_param.dr_range.fields.max = mib_confirm.param.channel_list[i].dr_range.fields.max; + plan.channels[count].ch_param.band = mib_confirm.param.channel_list[i].band; + plan.channels[count].ch_param.rx1_frequency = mib_confirm.param.channel_list[i].rx1_frequency; count++; } plan.nb_channels = count; - return LORAMAC_STATUS_OK; + return LORAWAN_STATUS_OK; } -LoRaMacStatus_t LoRaMacChannelPlan::remove_plan() +lorawan_status_t LoRaMacChannelPlan::remove_plan() { - LoRaMacStatus_t status = LORAMAC_STATUS_OK; + lorawan_status_t status = LORAWAN_STATUS_OK; GetPhyParams_t get_phy; PhyParam_t phy_param; @@ -181,7 +181,7 @@ LoRaMacStatus_t LoRaMacChannelPlan::remove_plan() status = remove_single_channel(i); - if (status != LORAMAC_STATUS_OK) { + if (status != LORAWAN_STATUS_OK) { return status; } } @@ -189,7 +189,7 @@ LoRaMacStatus_t LoRaMacChannelPlan::remove_plan() return status; } -LoRaMacStatus_t LoRaMacChannelPlan::remove_single_channel(uint8_t channel_id) +lorawan_status_t LoRaMacChannelPlan::remove_single_channel(uint8_t channel_id) { GetPhyParams_t get_phy; PhyParam_t phy_param; @@ -206,7 +206,7 @@ LoRaMacStatus_t LoRaMacChannelPlan::remove_single_channel(uint8_t channel_id) // channel ID is N-1 where N=MAX_NUM_CHANNELS. // So any ID which is larger or equal to the Max number of channels is invalid if (channel_id >= max_num_channels) { - return LORAMAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } // Now check the Default channel mask @@ -219,18 +219,18 @@ LoRaMacStatus_t LoRaMacChannelPlan::remove_single_channel(uint8_t channel_id) // have multiple channel masks for various sub-bands. So we check the first // mask only and return an error code if user sent a default channel id if ((channel_masks[0] & (1U << channel_id)) != 0) { - return LORAMAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } channelRemove.ChannelId = channel_id; if(_lora_phy->remove_channel(&channelRemove) == false) { - return LORAMAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } _lora_phy->put_radio_to_sleep(); - return LORAMAC_STATUS_OK; + return LORAWAN_STATUS_OK; } diff --git a/features/lorawan/lorastack/mac/LoRaMacChannelPlan.h b/features/lorawan/lorastack/mac/LoRaMacChannelPlan.h index e57d37d951..facce4abde 100644 --- a/features/lorawan/lorastack/mac/LoRaMacChannelPlan.h +++ b/features/lorawan/lorastack/mac/LoRaMacChannelPlan.h @@ -64,10 +64,10 @@ public: * @param plan a reference to application channel plan. PHY layer takes a * copy of the channel parameters provided within. * - * @return LORA_MAC_STATUS_OK if everything goes well otherwise + * @return LORAWAN_STATUS_OK if everything goes well otherwise * a negative error code is returned. */ - LoRaMacStatus_t set_plan(const lora_channelplan_t& plan); + lorawan_status_t set_plan(const lorawan_channelplan_t& plan); /** Access the active channel plan * @@ -78,28 +78,28 @@ public: * * @param params pointer to active MAC layer parameters. * - * @return LORA_MAC_STATUS_OK if everything goes well otherwise + * @return LORAWAN_STATUS_OK if everything goes well otherwise * a negative error code is returned. */ - LoRaMacStatus_t get_plan(lora_channelplan_t& plan, lora_mac_protocol_params *params); + lorawan_status_t get_plan(lorawan_channelplan_t& plan, loramac_protocol_params *params); /** Remove the active channel plan * * Drops the whole channel list except the 'Default Channels' ofcourse. * - * @return LORA_MAC_STATUS_OK if everything goes well otherwise + * @return LORAWAN_STATUS_OK if everything goes well otherwise * a negative error code is returned. */ - LoRaMacStatus_t remove_plan(); + lorawan_status_t remove_plan(); /** Remove a single channel from the plan * * @param id the channel id which needs to be removed * - * @return LORA_MAC_STATUS_OK if everything goes well otherwise + * @return LORAWAN_STATUS_OK if everything goes well otherwise * a negative error code is returned. */ - LoRaMacStatus_t remove_single_channel(uint8_t id); + lorawan_status_t remove_single_channel(uint8_t id); private: diff --git a/features/lorawan/lorastack/mac/LoRaMacCommand.cpp b/features/lorawan/lorastack/mac/LoRaMacCommand.cpp index 394d01aeec..14c0fc7c57 100644 --- a/features/lorawan/lorastack/mac/LoRaMacCommand.cpp +++ b/features/lorawan/lorastack/mac/LoRaMacCommand.cpp @@ -53,9 +53,9 @@ LoRaMacCommand::~LoRaMacCommand() { } -LoRaMacStatus_t LoRaMacCommand::AddMacCommand(uint8_t cmd, uint8_t p1, uint8_t p2) +lorawan_status_t LoRaMacCommand::AddMacCommand(uint8_t cmd, uint8_t p1, uint8_t p2) { - LoRaMacStatus_t status = LORAMAC_STATUS_BUSY; + lorawan_status_t status = LORAWAN_STATUS_BUSY; // The maximum buffer length must take MAC commands to re-send into account. const uint8_t bufLen = LORA_MAC_COMMAND_MAX_LENGTH - MacCommandsBufferToRepeatIndex; @@ -66,7 +66,7 @@ LoRaMacStatus_t LoRaMacCommand::AddMacCommand(uint8_t cmd, uint8_t p1, uint8_t p { MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; // No payload for this command - status = LORAMAC_STATUS_OK; + status = LORAWAN_STATUS_OK; } break; case MOTE_MAC_LINK_ADR_ANS: @@ -75,7 +75,7 @@ LoRaMacStatus_t LoRaMacCommand::AddMacCommand(uint8_t cmd, uint8_t p1, uint8_t p MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; // Margin MacCommandsBuffer[MacCommandsBufferIndex++] = p1; - status = LORAMAC_STATUS_OK; + status = LORAWAN_STATUS_OK; } break; case MOTE_MAC_DUTY_CYCLE_ANS: @@ -83,7 +83,7 @@ LoRaMacStatus_t LoRaMacCommand::AddMacCommand(uint8_t cmd, uint8_t p1, uint8_t p { MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; // No payload for this answer - status = LORAMAC_STATUS_OK; + status = LORAWAN_STATUS_OK; } break; case MOTE_MAC_RX_PARAM_SETUP_ANS: @@ -94,7 +94,7 @@ LoRaMacStatus_t LoRaMacCommand::AddMacCommand(uint8_t cmd, uint8_t p1, uint8_t p MacCommandsBuffer[MacCommandsBufferIndex++] = p1; // This is a sticky MAC command answer. Setup indication _lora_mac.SetMlmeScheduleUplinkIndication(); - status = LORAMAC_STATUS_OK; + status = LORAWAN_STATUS_OK; } break; case MOTE_MAC_DEV_STATUS_ANS: @@ -105,7 +105,7 @@ LoRaMacStatus_t LoRaMacCommand::AddMacCommand(uint8_t cmd, uint8_t p1, uint8_t p // 2nd byte Margin MacCommandsBuffer[MacCommandsBufferIndex++] = p1; MacCommandsBuffer[MacCommandsBufferIndex++] = p2; - status = LORAMAC_STATUS_OK; + status = LORAWAN_STATUS_OK; } break; case MOTE_MAC_NEW_CHANNEL_ANS: @@ -114,7 +114,7 @@ LoRaMacStatus_t LoRaMacCommand::AddMacCommand(uint8_t cmd, uint8_t p1, uint8_t p MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; // Status: Datarate range OK, Channel frequency OK MacCommandsBuffer[MacCommandsBufferIndex++] = p1; - status = LORAMAC_STATUS_OK; + status = LORAWAN_STATUS_OK; } break; case MOTE_MAC_RX_TIMING_SETUP_ANS: @@ -124,7 +124,7 @@ LoRaMacStatus_t LoRaMacCommand::AddMacCommand(uint8_t cmd, uint8_t p1, uint8_t p // No payload for this answer // This is a sticky MAC command answer. Setup indication _lora_mac.SetMlmeScheduleUplinkIndication(); - status = LORAMAC_STATUS_OK; + status = LORAWAN_STATUS_OK; } break; case MOTE_MAC_TX_PARAM_SETUP_ANS: @@ -132,7 +132,7 @@ LoRaMacStatus_t LoRaMacCommand::AddMacCommand(uint8_t cmd, uint8_t p1, uint8_t p { MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; // No payload for this answer - status = LORAMAC_STATUS_OK; + status = LORAWAN_STATUS_OK; } break; case MOTE_MAC_DL_CHANNEL_ANS: @@ -143,13 +143,13 @@ LoRaMacStatus_t LoRaMacCommand::AddMacCommand(uint8_t cmd, uint8_t p1, uint8_t p MacCommandsBuffer[MacCommandsBufferIndex++] = p1; // This is a sticky MAC command answer. Setup indication _lora_mac.SetMlmeScheduleUplinkIndication(); - status = LORAMAC_STATUS_OK; + status = LORAWAN_STATUS_OK; } break; default: - return LORAMAC_STATUS_SERVICE_UNKNOWN; + return LORAWAN_STATUS_SERVICE_UNKNOWN; } - if( status == LORAMAC_STATUS_OK ) + if( status == LORAWAN_STATUS_OK ) { MacCommandsInNextTx = true; } @@ -251,9 +251,11 @@ bool LoRaMacCommand::IsMacCommandsInNextTx() const return MacCommandsInNextTx; } -void LoRaMacCommand::ProcessMacCommands(uint8_t *payload, uint8_t macIndex, uint8_t commandsSize, uint8_t snr, - MlmeConfirm_t& MlmeConfirm, LoRaMacCallback_t *LoRaMacCallbacks, - lora_mac_system_params_t &LoRaMacParams, LoRaPHY &lora_phy) +void LoRaMacCommand::ProcessMacCommands(uint8_t *payload, uint8_t macIndex, + uint8_t commandsSize, uint8_t snr, + loramac_mlme_confirm_t& MlmeConfirm, + lora_mac_system_params_t &LoRaMacParams, + LoRaPHY &lora_phy) { uint8_t status = 0; @@ -263,9 +265,9 @@ void LoRaMacCommand::ProcessMacCommands(uint8_t *payload, uint8_t macIndex, uint switch( payload[macIndex++] ) { case SRV_MAC_LINK_CHECK_ANS: - MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK; - MlmeConfirm.DemodMargin = payload[macIndex++]; - MlmeConfirm.NbGateways = payload[macIndex++]; + MlmeConfirm.status = LORAMAC_EVENT_INFO_STATUS_OK; + MlmeConfirm.demod_margin = payload[macIndex++]; + MlmeConfirm.nb_gateways = payload[macIndex++]; break; case SRV_MAC_LINK_ADR_REQ: { @@ -278,11 +280,11 @@ void LoRaMacCommand::ProcessMacCommands(uint8_t *payload, uint8_t macIndex, uint // Fill parameter structure linkAdrReq.Payload = &payload[macIndex - 1]; linkAdrReq.PayloadSize = commandsSize - ( macIndex - 1 ); - linkAdrReq.AdrEnabled = LoRaMacParams.AdrCtrlOn; - linkAdrReq.UplinkDwellTime = LoRaMacParams.UplinkDwellTime; - linkAdrReq.CurrentDatarate = LoRaMacParams.ChannelsDatarate; - linkAdrReq.CurrentTxPower = LoRaMacParams.ChannelsTxPower; - linkAdrReq.CurrentNbRep = LoRaMacParams.ChannelsNbRep; + linkAdrReq.AdrEnabled = LoRaMacParams.adr_on; + linkAdrReq.UplinkDwellTime = LoRaMacParams.uplink_dwell_time; + linkAdrReq.CurrentDatarate = LoRaMacParams.channel_data_rate; + linkAdrReq.CurrentTxPower = LoRaMacParams.channel_tx_power; + linkAdrReq.CurrentNbRep = LoRaMacParams.retry_num; // Process the ADR requests status = lora_phy.link_ADR_request(&linkAdrReq, &linkAdrDatarate, @@ -291,9 +293,9 @@ void LoRaMacCommand::ProcessMacCommands(uint8_t *payload, uint8_t macIndex, uint if( ( status & 0x07 ) == 0x07 ) { - LoRaMacParams.ChannelsDatarate = linkAdrDatarate; - LoRaMacParams.ChannelsTxPower = linkAdrTxPower; - LoRaMacParams.ChannelsNbRep = linkAdrNbRep; + LoRaMacParams.channel_data_rate = linkAdrDatarate; + LoRaMacParams.channel_tx_power = linkAdrTxPower; + LoRaMacParams.retry_num = linkAdrNbRep; } // Add the answers to the buffer @@ -306,8 +308,8 @@ void LoRaMacCommand::ProcessMacCommands(uint8_t *payload, uint8_t macIndex, uint } break; case SRV_MAC_DUTY_CYCLE_REQ: - LoRaMacParams.MaxDCycle = payload[macIndex++]; - LoRaMacParams.AggregatedDCycle = 1 << LoRaMacParams.MaxDCycle; + LoRaMacParams.max_duty_cycle = payload[macIndex++]; + LoRaMacParams.aggregated_duty_cycle = 1 << LoRaMacParams.max_duty_cycle; AddMacCommand( MOTE_MAC_DUTY_CYCLE_ANS, 0, 0 ); break; case SRV_MAC_RX_PARAM_SETUP_REQ: @@ -329,9 +331,9 @@ void LoRaMacCommand::ProcessMacCommands(uint8_t *payload, uint8_t macIndex, uint if( ( status & 0x07 ) == 0x07 ) { - LoRaMacParams.Rx2Channel.Datarate = rxParamSetupReq.Datarate; - LoRaMacParams.Rx2Channel.Frequency = rxParamSetupReq.Frequency; - LoRaMacParams.Rx1DrOffset = rxParamSetupReq.DrOffset; + LoRaMacParams.rx2_channel.datarate = rxParamSetupReq.Datarate; + LoRaMacParams.rx2_channel.frequency = rxParamSetupReq.Frequency; + LoRaMacParams.rx1_dr_offset = rxParamSetupReq.DrOffset; } AddMacCommand( MOTE_MAC_RX_PARAM_SETUP_ANS, status, 0 ); } @@ -339,28 +341,26 @@ void LoRaMacCommand::ProcessMacCommands(uint8_t *payload, uint8_t macIndex, uint case SRV_MAC_DEV_STATUS_REQ: { uint8_t batteryLevel = BAT_LEVEL_NO_MEASURE; - if( ( LoRaMacCallbacks != NULL ) && ( LoRaMacCallbacks->GetBatteryLevel != NULL ) ) - { - batteryLevel = LoRaMacCallbacks->GetBatteryLevel( ); - } + // we don't have a mechanism at the moment to measure + // battery levels AddMacCommand( MOTE_MAC_DEV_STATUS_ANS, batteryLevel, snr ); break; } case SRV_MAC_NEW_CHANNEL_REQ: { NewChannelReqParams_t newChannelReq; - ChannelParams_t chParam; + channel_params_t chParam; status = 0x03; newChannelReq.ChannelId = payload[macIndex++]; newChannelReq.NewChannel = &chParam; - chParam.Frequency = ( uint32_t )payload[macIndex++]; - chParam.Frequency |= ( uint32_t )payload[macIndex++] << 8; - chParam.Frequency |= ( uint32_t )payload[macIndex++] << 16; - chParam.Frequency *= 100; - chParam.Rx1Frequency = 0; - chParam.DrRange.Value = payload[macIndex++]; + chParam.frequency = ( uint32_t )payload[macIndex++]; + chParam.frequency |= ( uint32_t )payload[macIndex++] << 8; + chParam.frequency |= ( uint32_t )payload[macIndex++] << 16; + chParam.frequency *= 100; + chParam.rx1_frequency = 0; + chParam.dr_range.value = payload[macIndex++]; status = lora_phy.request_new_channel(&newChannelReq); @@ -375,8 +375,8 @@ void LoRaMacCommand::ProcessMacCommands(uint8_t *payload, uint8_t macIndex, uint { delay++; } - LoRaMacParams.ReceiveDelay1 = delay * 1000; - LoRaMacParams.ReceiveDelay2 = LoRaMacParams.ReceiveDelay1 + 1000; + LoRaMacParams.recv_delay1 = delay * 1000; + LoRaMacParams.recv_delay2 = LoRaMacParams.recv_delay1 + 1000; AddMacCommand( MOTE_MAC_RX_TIMING_SETUP_ANS, 0, 0 ); } break; @@ -402,9 +402,9 @@ void LoRaMacCommand::ProcessMacCommands(uint8_t *payload, uint8_t macIndex, uint if( lora_phy.setup_tx_params(&txParamSetupReq ) != -1 ) { // Accept command - LoRaMacParams.UplinkDwellTime = txParamSetupReq.UplinkDwellTime; - LoRaMacParams.DownlinkDwellTime = txParamSetupReq.DownlinkDwellTime; - LoRaMacParams.MaxEirp = LoRaMacMaxEirpTable[txParamSetupReq.MaxEirp]; + LoRaMacParams.uplink_dwell_time = txParamSetupReq.UplinkDwellTime; + LoRaMacParams.downlink_dwell_time = txParamSetupReq.DownlinkDwellTime; + LoRaMacParams.max_eirp = LoRaMacMaxEirpTable[txParamSetupReq.MaxEirp]; // Add command response AddMacCommand( MOTE_MAC_TX_PARAM_SETUP_ANS, 0, 0 ); } diff --git a/features/lorawan/lorastack/mac/LoRaMacCommand.h b/features/lorawan/lorastack/mac/LoRaMacCommand.h index 9f0da64705..a6796e61a3 100644 --- a/features/lorawan/lorastack/mac/LoRaMacCommand.h +++ b/features/lorawan/lorastack/mac/LoRaMacCommand.h @@ -74,7 +74,7 @@ public: * * \retval status Function status [0: OK, 1: Unknown command, 2: Buffer full] */ - LoRaMacStatus_t AddMacCommand(uint8_t cmd, uint8_t p1, uint8_t p2); + lorawan_status_t AddMacCommand(uint8_t cmd, uint8_t p1, uint8_t p2); /*! * \brief Clear MAC command buffer. @@ -132,9 +132,11 @@ public: /*! * \brief Decodes MAC commands in the fOpts field and in the payload */ - void ProcessMacCommands(uint8_t *payload, uint8_t macIndex, uint8_t commandsSize, uint8_t snr, - MlmeConfirm_t &MlmeConfirm, LoRaMacCallback_t *LoRaMacCallbacks, - lora_mac_system_params_t &LoRaMacParams, LoRaPHY &lora_phy); + void ProcessMacCommands(uint8_t *payload, uint8_t macIndex, + uint8_t commandsSize, uint8_t snr, + loramac_mlme_confirm_t& MlmeConfirm, + lora_mac_system_params_t& LoRaMacParams, + LoRaPHY& lora_phy); /*! * \brief Verifies if sticky MAC commands are pending. diff --git a/features/lorawan/lorastack/mac/LoRaMacCrypto.cpp b/features/lorawan/lorastack/mac/LoRaMacCrypto.cpp index 56998c36a9..5919c37a6f 100644 --- a/features/lorawan/lorastack/mac/LoRaMacCrypto.cpp +++ b/features/lorawan/lorastack/mac/LoRaMacCrypto.cpp @@ -300,7 +300,7 @@ int LoRaMacComputeMic( const uint8_t *, uint16_t , const uint8_t *, uint32_t, MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS"); // Never actually reaches here - return LORA_MAC_STATUS_CRYPTO_FAIL; + return LORAWAN_STATUS_CRYPTO_FAIL; } int LoRaMacPayloadEncrypt( const uint8_t *, uint16_t , const uint8_t *, uint32_t, @@ -309,7 +309,7 @@ int LoRaMacPayloadEncrypt( const uint8_t *, uint16_t , const uint8_t *, uint32_t MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS"); // Never actually reaches here - return LORA_MAC_STATUS_CRYPTO_FAIL; + return LORAWAN_STATUS_CRYPTO_FAIL; } int LoRaMacPayloadDecrypt( const uint8_t *, uint16_t , const uint8_t *, uint32_t, @@ -318,14 +318,14 @@ int LoRaMacPayloadDecrypt( const uint8_t *, uint16_t , const uint8_t *, uint32_t MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS"); // Never actually reaches here - return LORA_MAC_STATUS_CRYPTO_FAIL; + return LORAWAN_STATUS_CRYPTO_FAIL; } int LoRaMacJoinComputeMic( const uint8_t *, uint16_t , const uint8_t *, uint32_t * ) { MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS"); // Never actually reaches here - return LORA_MAC_STATUS_CRYPTO_FAIL; + return LORAWAN_STATUS_CRYPTO_FAIL; } int LoRaMacJoinDecrypt( const uint8_t *, uint16_t , const uint8_t *, uint8_t * ) @@ -333,7 +333,7 @@ int LoRaMacJoinDecrypt( const uint8_t *, uint16_t , const uint8_t *, uint8_t * ) MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS"); // Never actually reaches here - return LORA_MAC_STATUS_CRYPTO_FAIL; + return LORAWAN_STATUS_CRYPTO_FAIL; } int LoRaMacJoinComputeSKeys( const uint8_t *, const uint8_t *, uint16_t , uint8_t *, uint8_t * ) @@ -341,7 +341,7 @@ int LoRaMacJoinComputeSKeys( const uint8_t *, const uint8_t *, uint16_t , uint8_ MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS"); // Never actually reaches here - return LORA_MAC_STATUS_CRYPTO_FAIL; + return LORAWAN_STATUS_CRYPTO_FAIL; } #endif diff --git a/features/lorawan/lorastack/mac/LoRaMacMcps.cpp b/features/lorawan/lorastack/mac/LoRaMacMcps.cpp index a6848ce618..ab538df94d 100644 --- a/features/lorawan/lorastack/mac/LoRaMacMcps.cpp +++ b/features/lorawan/lorastack/mac/LoRaMacMcps.cpp @@ -41,22 +41,18 @@ void LoRaMacMcps::activate_mcps_subsystem(LoRaMac *mac, LoRaPHY *phy) _lora_phy = phy; } -LoRaMacStatus_t LoRaMacMcps::set_request(McpsReq_t *mcpsRequest, - lora_mac_protocol_params *params) +lorawan_status_t LoRaMacMcps::set_request(loramac_mcps_req_t *mcpsRequest, + loramac_protocol_params *params) { if (mcpsRequest == NULL || _lora_phy == NULL || _lora_mac == NULL) { - return LORAMAC_STATUS_PARAMETER_INVALID; - } - - if (params->LoRaMacState != LORAMAC_IDLE) { - return LORAMAC_STATUS_BUSY; + return LORAWAN_STATUS_PARAMETER_INVALID; } GetPhyParams_t getPhy; PhyParam_t phyParam; - LoRaMacStatus_t status = LORAMAC_STATUS_SERVICE_UNKNOWN; - LoRaMacHeader_t macHdr; + lorawan_status_t status = LORAWAN_STATUS_SERVICE_UNKNOWN; + loramac_mhdr_t macHdr; VerifyParams_t verify; uint8_t fPort = 0; void *fBuffer; @@ -64,47 +60,47 @@ LoRaMacStatus_t LoRaMacMcps::set_request(McpsReq_t *mcpsRequest, int8_t datarate = DR_0; bool readyToSend = false; - macHdr.Value = 0; + macHdr.value = 0; // Before performing any MCPS request, clear the confirmation structure memset((uint8_t*) &confirmation, 0, sizeof(confirmation)); - confirmation.Status = LORAMAC_EVENT_INFO_STATUS_ERROR; + confirmation.status = LORAMAC_EVENT_INFO_STATUS_ERROR; - // AckTimeoutRetriesCounter must be reset every time a new request (unconfirmed or confirmed) is performed. - params->AckTimeoutRetriesCounter = 1; + // ack_timeout_retry_counter must be reset every time a new request (unconfirmed or confirmed) is performed. + params->ack_timeout_retry_counter = 1; - switch (mcpsRequest->Type) { + switch (mcpsRequest->type) { case MCPS_UNCONFIRMED: { readyToSend = true; - params->AckTimeoutRetries = 1; + params->max_ack_timeout_retries = 1; - macHdr.Bits.MType = FRAME_TYPE_DATA_UNCONFIRMED_UP; - fPort = mcpsRequest->Req.Unconfirmed.fPort; - fBuffer = mcpsRequest->Req.Unconfirmed.fBuffer; - fBufferSize = mcpsRequest->Req.Unconfirmed.fBufferSize; - datarate = mcpsRequest->Req.Unconfirmed.Datarate; + macHdr.bits.mtype = FRAME_TYPE_DATA_UNCONFIRMED_UP; + fPort = mcpsRequest->req.unconfirmed.fport; + fBuffer = mcpsRequest->f_buffer; + fBufferSize = mcpsRequest->f_buffer_size; + datarate = mcpsRequest->req.unconfirmed.data_rate; break; } case MCPS_CONFIRMED: { readyToSend = true; - params->AckTimeoutRetries = mcpsRequest->Req.Confirmed.NbTrials; + params->max_ack_timeout_retries = mcpsRequest->req.confirmed.nb_trials; - macHdr.Bits.MType = FRAME_TYPE_DATA_CONFIRMED_UP; - fPort = mcpsRequest->Req.Confirmed.fPort; - fBuffer = mcpsRequest->Req.Confirmed.fBuffer; - fBufferSize = mcpsRequest->Req.Confirmed.fBufferSize; - datarate = mcpsRequest->Req.Confirmed.Datarate; + macHdr.bits.mtype = FRAME_TYPE_DATA_CONFIRMED_UP; + fPort = mcpsRequest->req.confirmed.fport; + fBuffer = mcpsRequest->f_buffer; + fBufferSize = mcpsRequest->f_buffer_size; + datarate = mcpsRequest->req.confirmed.data_rate; break; } case MCPS_PROPRIETARY: { readyToSend = true; - params->AckTimeoutRetries = 1; + params->max_ack_timeout_retries = 1; - macHdr.Bits.MType = FRAME_TYPE_PROPRIETARY; - fBuffer = mcpsRequest->Req.Proprietary.fBuffer; - fBufferSize = mcpsRequest->Req.Proprietary.fBufferSize; - datarate = mcpsRequest->Req.Proprietary.Datarate; + macHdr.bits.mtype = FRAME_TYPE_PROPRIETARY; + fBuffer = mcpsRequest->f_buffer; + fBufferSize = mcpsRequest->f_buffer_size; + datarate = mcpsRequest->req.proprietary.data_rate; break; } default: @@ -115,12 +111,12 @@ LoRaMacStatus_t LoRaMacMcps::set_request(McpsReq_t *mcpsRequest, // TODO: Does not work with PROPRIETARY messages // if( IsFPortAllowed( fPort ) == false ) // { - // return LORAMAC_STATUS_PARAMETER_INVALID; + // return LORAWAN_STATUS_PARAMETER_INVALID; // } // Get the minimum possible datarate getPhy.Attribute = PHY_MIN_TX_DR; - getPhy.UplinkDwellTime = params->sys_params.UplinkDwellTime; + getPhy.UplinkDwellTime = params->sys_params.uplink_dwell_time; phyParam = _lora_phy->get_phy_params(&getPhy); // Apply the minimum possible datarate. @@ -128,25 +124,25 @@ LoRaMacStatus_t LoRaMacMcps::set_request(McpsReq_t *mcpsRequest, datarate = MAX(datarate, phyParam.Value); if (readyToSend == true) { - if (params->sys_params.AdrCtrlOn == false) { + if (params->sys_params.adr_on == false) { verify.DatarateParams.Datarate = datarate; verify.DatarateParams.UplinkDwellTime = - params->sys_params.UplinkDwellTime; + params->sys_params.uplink_dwell_time; if (_lora_phy->verify(&verify, PHY_TX_DR) == true) { - params->sys_params.ChannelsDatarate = + params->sys_params.channel_data_rate = verify.DatarateParams.Datarate; } else { - return LORAMAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } } status = _lora_mac->Send(&macHdr, fPort, fBuffer, fBufferSize); - if (status == LORAMAC_STATUS_OK) { - confirmation.McpsRequest = mcpsRequest->Type; - params->LoRaMacFlags.Bits.McpsReq = 1; + if (status == LORAWAN_STATUS_OK) { + confirmation.req_type = mcpsRequest->type; + params->flags.bits.mcps_req = 1; } else { - params->NodeAckRequested = false; + params->is_node_ack_requested = false; } } diff --git a/features/lorawan/lorastack/mac/LoRaMacMcps.h b/features/lorawan/lorastack/mac/LoRaMacMcps.h index e73ba57856..3989c66753 100644 --- a/features/lorawan/lorastack/mac/LoRaMacMcps.h +++ b/features/lorawan/lorastack/mac/LoRaMacMcps.h @@ -67,16 +67,16 @@ public: * @param mcpsRequest pointer to MCPS request structure * @param params pointer to MAC protocol parameters * - * @return LORA_MAC_STATUS_OK if everything goes well otherwise + * @return LORAWAN_STATUS_OK if everything goes well otherwise * a negative error code is returned. */ - LoRaMacStatus_t set_request(McpsReq_t *mcpsRequest, lora_mac_protocol_params *params); + lorawan_status_t set_request(loramac_mcps_req_t *mcpsRequest, loramac_protocol_params *params); /** Grants access to MCPS confirmation data * * @return a reference to MCPS confirm data structure */ - inline McpsConfirm_t& get_confirmation() + inline loramac_mcps_confirm_t& get_confirmation() { return confirmation; } @@ -85,7 +85,7 @@ public: * * @return a reference to MCPS indication data structure */ - inline McpsIndication_t& get_indication() + inline loramac_mcps_indication_t& get_indication() { return indication; } @@ -102,12 +102,12 @@ private: /** * Structure to hold MCPS indication data. */ - McpsIndication_t indication; + loramac_mcps_indication_t indication; /** * Structure to hold MCPS confirm data. */ - McpsConfirm_t confirmation; + loramac_mcps_confirm_t confirmation; }; #endif /* MBED_OS_LORAWAN_MAC_MCPS_H_ */ diff --git a/features/lorawan/lorastack/mac/LoRaMacMib.cpp b/features/lorawan/lorastack/mac/LoRaMacMib.cpp index dd726e0faa..9cd3745dc0 100644 --- a/features/lorawan/lorastack/mac/LoRaMacMib.cpp +++ b/features/lorawan/lorastack/mac/LoRaMacMib.cpp @@ -41,22 +41,22 @@ void LoRaMacMib::activate_mib_subsystem(LoRaMac *mac, LoRaPHY *phy) _lora_phy = phy; } -LoRaMacStatus_t LoRaMacMib::set_request(MibRequestConfirm_t *mibSet, - lora_mac_protocol_params *params) +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) { - return LORAMAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } - LoRaMacStatus_t status = LORAMAC_STATUS_OK; + lorawan_status_t status = LORAWAN_STATUS_OK; ChanMaskSetParams_t chanMaskSet; VerifyParams_t verify; - switch (mibSet->Type) { + switch (mibSet->type) { case MIB_DEVICE_CLASS: { - params->LoRaMacDeviceClass = mibSet->Param.Class; - switch (params->LoRaMacDeviceClass) { + params->dev_class = mibSet->param.dev_class; + switch (params->dev_class) { case CLASS_A: { // Set the radio into sleep to setup a defined state _lora_phy->put_radio_to_sleep(); @@ -66,16 +66,16 @@ LoRaMacStatus_t LoRaMacMib::set_request(MibRequestConfirm_t *mibSet, break; } case CLASS_C: { - // Set the NodeAckRequested indicator to default - params->NodeAckRequested = false; + // Set the is_node_ack_requested indicator to default + params->is_node_ack_requested = false; // Set the radio into sleep mode in case we are still in RX mode _lora_phy->put_radio_to_sleep(); // Compute Rx2 windows parameters in case the RX2 datarate has changed _lora_phy->compute_rx_win_params( - params->sys_params.Rx2Channel.Datarate, - params->sys_params.MinRxSymbols, - params->sys_params.SystemMaxRxError, - ¶ms->RxWindow2Config); + params->sys_params.rx2_channel.datarate, + params->sys_params.min_rx_symb, + params->sys_params.max_sys_rx_error, + ¶ms->rx_window2_config); _lora_mac->OpenContinuousRx2Window(); break; } @@ -83,58 +83,57 @@ LoRaMacStatus_t LoRaMacMib::set_request(MibRequestConfirm_t *mibSet, break; } case MIB_NETWORK_JOINED: { - params->IsLoRaMacNetworkJoined = mibSet->Param.IsNetworkJoined; + params->is_nwk_joined = mibSet->param.is_nwk_joined; break; } case MIB_ADR: { - params->sys_params.AdrCtrlOn = mibSet->Param.AdrEnable; + params->sys_params.adr_on = mibSet->param.is_adr_enable; break; } case MIB_NET_ID: { - params->LoRaMacNetID = mibSet->Param.NetID; + params->net_id = mibSet->param.net_id; break; } case MIB_DEV_ADDR: { - params->LoRaMacDevAddr = mibSet->Param.DevAddr; + params->dev_addr = mibSet->param.dev_addr; break; } case MIB_NWK_SKEY: { - if (mibSet->Param.NwkSKey != NULL) { - memcpy(params->keys.LoRaMacNwkSKey, mibSet->Param.NwkSKey, - sizeof(params->keys.LoRaMacNwkSKey)); + if (mibSet->param.nwk_skey != NULL) { + memcpy(params->keys.nwk_skey, mibSet->param.nwk_skey, + sizeof(params->keys.nwk_skey)); } else { - status = LORAMAC_STATUS_PARAMETER_INVALID; + status = LORAWAN_STATUS_PARAMETER_INVALID; } break; } case MIB_APP_SKEY: { - if (mibSet->Param.AppSKey != NULL) { - memcpy(params->keys.LoRaMacAppSKey, mibSet->Param.AppSKey, - sizeof(params->keys.LoRaMacAppSKey)); + if (mibSet->param.app_skey != NULL) { + memcpy(params->keys.app_skey, mibSet->param.app_skey, + sizeof(params->keys.app_skey)); } else { - status = LORAMAC_STATUS_PARAMETER_INVALID; + status = LORAWAN_STATUS_PARAMETER_INVALID; } break; } case MIB_PUBLIC_NETWORK: { - params->PublicNetwork = mibSet->Param.EnablePublicNetwork; - _lora_phy->setup_public_network_mode(params->PublicNetwork); + params->is_nwk_public = mibSet->param.enable_public_nwk; + _lora_phy->setup_public_network_mode(params->is_nwk_public); break; } case MIB_REPEATER_SUPPORT: { - params->RepeaterSupport = mibSet->Param.EnableRepeaterSupport; + params->is_repeater_supported = mibSet->param.enable_repeater_support; break; } case MIB_RX2_CHANNEL: { - verify.DatarateParams.Datarate = mibSet->Param.Rx2Channel.Datarate; - verify.DatarateParams.DownlinkDwellTime = - params->sys_params.DownlinkDwellTime; + verify.DatarateParams.Datarate = mibSet->param.rx2_channel.datarate; + verify.DatarateParams.DownlinkDwellTime = params->sys_params.downlink_dwell_time; if (_lora_phy->verify(&verify, PHY_RX_DR) == true) { - params->sys_params.Rx2Channel = mibSet->Param.Rx2Channel; + params->sys_params.rx2_channel = mibSet->param.rx2_channel; - if ((params->LoRaMacDeviceClass == CLASS_C) - && (params->IsLoRaMacNetworkJoined == true)) { + if ((params->dev_class == CLASS_C) + && (params->is_nwk_joined == true)) { // We can only compute the RX window parameters directly, if we are already // in class c mode and joined. We cannot setup an RX window in case of any other // class type. @@ -142,214 +141,206 @@ LoRaMacStatus_t LoRaMacMib::set_request(MibRequestConfirm_t *mibSet, _lora_phy->put_radio_to_sleep(); // Compute Rx2 windows parameters _lora_phy->compute_rx_win_params( - params->sys_params.Rx2Channel.Datarate, - params->sys_params.MinRxSymbols, - params->sys_params.SystemMaxRxError, - ¶ms->RxWindow2Config); + params->sys_params.rx2_channel.datarate, + params->sys_params.min_rx_symb, + params->sys_params.max_sys_rx_error, + ¶ms->rx_window2_config); _lora_mac->OpenContinuousRx2Window(); } } else { - status = LORAMAC_STATUS_PARAMETER_INVALID; + status = LORAWAN_STATUS_PARAMETER_INVALID; } break; } case MIB_RX2_DEFAULT_CHANNEL: { - verify.DatarateParams.Datarate = mibSet->Param.Rx2Channel.Datarate; - verify.DatarateParams.DownlinkDwellTime = - params->sys_params.DownlinkDwellTime; + verify.DatarateParams.Datarate = mibSet->param.rx2_channel.datarate; + verify.DatarateParams.DownlinkDwellTime = params->sys_params.downlink_dwell_time; if (_lora_phy->verify(&verify, PHY_RX_DR) == true) { - params->def_sys_params.Rx2Channel = - mibSet->Param.Rx2DefaultChannel; + params->def_sys_params.rx2_channel = mibSet->param.default_rx2_channel; } else { - status = LORAMAC_STATUS_PARAMETER_INVALID; + status = LORAWAN_STATUS_PARAMETER_INVALID; } break; } case MIB_CHANNELS_DEFAULT_MASK: { - chanMaskSet.ChannelsMaskIn = mibSet->Param.ChannelsMask; + chanMaskSet.ChannelsMaskIn = mibSet->param.channel_mask; chanMaskSet.ChannelsMaskType = CHANNELS_DEFAULT_MASK; if (_lora_phy->set_channel_mask(&chanMaskSet) == false) { - status = LORAMAC_STATUS_PARAMETER_INVALID; + status = LORAWAN_STATUS_PARAMETER_INVALID; } break; } case MIB_CHANNELS_MASK: { - chanMaskSet.ChannelsMaskIn = mibSet->Param.ChannelsMask; + chanMaskSet.ChannelsMaskIn = mibSet->param.channel_mask; chanMaskSet.ChannelsMaskType = CHANNELS_MASK; if (_lora_phy->set_channel_mask(&chanMaskSet) == false) { - status = LORAMAC_STATUS_PARAMETER_INVALID; + status = LORAWAN_STATUS_PARAMETER_INVALID; } break; } case MIB_CHANNELS_NB_REP: { - if ((mibSet->Param.ChannelNbRep >= 1) - && (mibSet->Param.ChannelNbRep <= 15)) { - params->sys_params.ChannelsNbRep = mibSet->Param.ChannelNbRep; + if ((mibSet->param.channel_nb_rep >= 1) + && (mibSet->param.channel_nb_rep <= 15)) { + params->sys_params.retry_num = mibSet->param.channel_nb_rep; } else { - status = LORAMAC_STATUS_PARAMETER_INVALID; + status = LORAWAN_STATUS_PARAMETER_INVALID; } break; } case MIB_MAX_RX_WINDOW_DURATION: { - params->sys_params.MaxRxWindow = mibSet->Param.MaxRxWindow; + params->sys_params.max_rx_win_time = mibSet->param.max_rx_window; break; } case MIB_RECEIVE_DELAY_1: { - params->sys_params.ReceiveDelay1 = mibSet->Param.ReceiveDelay1; + params->sys_params.recv_delay1 = mibSet->param.recv_delay1; break; } case MIB_RECEIVE_DELAY_2: { - params->sys_params.ReceiveDelay2 = mibSet->Param.ReceiveDelay2; + params->sys_params.recv_delay2 = mibSet->param.recv_delay2; break; } case MIB_JOIN_ACCEPT_DELAY_1: { - params->sys_params.JoinAcceptDelay1 = - mibSet->Param.JoinAcceptDelay1; + params->sys_params.join_accept_delay1 = mibSet->param.join_accept_delay1; break; } case MIB_JOIN_ACCEPT_DELAY_2: { - params->sys_params.JoinAcceptDelay2 = - mibSet->Param.JoinAcceptDelay2; + params->sys_params.join_accept_delay2 = mibSet->param.join_accept_delay2; break; } case MIB_CHANNELS_DEFAULT_DATARATE: { - verify.DatarateParams.Datarate = - mibSet->Param.ChannelsDefaultDatarate; + verify.DatarateParams.Datarate = mibSet->param.default_channel_data_rate; if (_lora_phy->verify(&verify, PHY_DEF_TX_DR) == true) { - params->def_sys_params.ChannelsDatarate = - verify.DatarateParams.Datarate; + params->def_sys_params.channel_data_rate = verify.DatarateParams.Datarate; } else { - status = LORAMAC_STATUS_PARAMETER_INVALID; + status = LORAWAN_STATUS_PARAMETER_INVALID; } break; } case MIB_CHANNELS_DATARATE: { - verify.DatarateParams.Datarate = mibSet->Param.ChannelsDatarate; - verify.DatarateParams.UplinkDwellTime = - params->sys_params.UplinkDwellTime; + verify.DatarateParams.Datarate = mibSet->param.channel_data_rate; + verify.DatarateParams.UplinkDwellTime = params->sys_params.uplink_dwell_time; if (_lora_phy->verify(&verify, PHY_TX_DR) == true) { - params->sys_params.ChannelsDatarate = - verify.DatarateParams.Datarate; + params->sys_params.channel_data_rate = verify.DatarateParams.Datarate; } else { - status = LORAMAC_STATUS_PARAMETER_INVALID; + status = LORAWAN_STATUS_PARAMETER_INVALID; } break; } case MIB_CHANNELS_DEFAULT_TX_POWER: { - verify.TxPower = mibSet->Param.ChannelsDefaultTxPower; + verify.TxPower = mibSet->param.default_channel_tx_pwr; if (_lora_phy->verify(&verify, PHY_DEF_TX_POWER) == true) { - params->def_sys_params.ChannelsTxPower = verify.TxPower; + params->def_sys_params.channel_tx_power = verify.TxPower; } else { - status = LORAMAC_STATUS_PARAMETER_INVALID; + status = LORAWAN_STATUS_PARAMETER_INVALID; } break; } case MIB_CHANNELS_TX_POWER: { - verify.TxPower = mibSet->Param.ChannelsTxPower; + verify.TxPower = mibSet->param.channel_tx_pwr; if (_lora_phy->verify(&verify, PHY_TX_POWER) == true) { - params->sys_params.ChannelsTxPower = verify.TxPower; + params->sys_params.channel_tx_power = verify.TxPower; } else { - status = LORAMAC_STATUS_PARAMETER_INVALID; + status = LORAWAN_STATUS_PARAMETER_INVALID; } break; } case MIB_UPLINK_COUNTER: { - params->UpLinkCounter = mibSet->Param.UpLinkCounter; + params->ul_frame_counter = mibSet->param.ul_frame_counter; break; } case MIB_DOWNLINK_COUNTER: { - params->DownLinkCounter = mibSet->Param.DownLinkCounter; + params->dl_frame_counter = mibSet->param.dl_frame_counter; break; } case MIB_SYSTEM_MAX_RX_ERROR: { - params->sys_params.SystemMaxRxError = - params->def_sys_params.SystemMaxRxError = - mibSet->Param.SystemMaxRxError; + params->sys_params.max_sys_rx_error = + params->def_sys_params.max_sys_rx_error = + mibSet->param.max_rx_sys_error; break; } case MIB_MIN_RX_SYMBOLS: { - params->sys_params.MinRxSymbols = - params->def_sys_params.MinRxSymbols = - mibSet->Param.MinRxSymbols; + params->sys_params.min_rx_symb = + params->def_sys_params.min_rx_symb = + mibSet->param.min_rx_symb; break; } case MIB_ANTENNA_GAIN: { - params->sys_params.AntennaGain = mibSet->Param.AntennaGain; + params->sys_params.antenna_gain = mibSet->param.antenna_gain; break; } default: - status = LORAMAC_STATUS_SERVICE_UNKNOWN; + status = LORAWAN_STATUS_SERVICE_UNKNOWN; break; } return status; } -LoRaMacStatus_t LoRaMacMib::get_request(MibRequestConfirm_t *mibGet, - lora_mac_protocol_params *params) +lorawan_status_t LoRaMacMib::get_request(loramac_mib_req_confirm_t *mibGet, + loramac_protocol_params *params) { - LoRaMacStatus_t status = LORAMAC_STATUS_OK; + lorawan_status_t status = LORAWAN_STATUS_OK; GetPhyParams_t getPhy; PhyParam_t phyParam; if( mibGet == NULL ) { - return LORAMAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } - switch( mibGet->Type ) + switch( mibGet->type ) { case MIB_DEVICE_CLASS: { - mibGet->Param.Class = params->LoRaMacDeviceClass; + mibGet->param.dev_class = params->dev_class; break; } case MIB_NETWORK_JOINED: { - mibGet->Param.IsNetworkJoined = params->IsLoRaMacNetworkJoined; + mibGet->param.is_nwk_joined = params->is_nwk_joined; break; } case MIB_ADR: { - mibGet->Param.AdrEnable = params->sys_params.AdrCtrlOn; + mibGet->param.is_adr_enable = params->sys_params.adr_on; break; } case MIB_NET_ID: { - mibGet->Param.NetID = params->LoRaMacNetID; + mibGet->param.net_id = params->net_id; break; } case MIB_DEV_ADDR: { - mibGet->Param.DevAddr = params->LoRaMacDevAddr; + mibGet->param.dev_addr = params->dev_addr; break; } case MIB_NWK_SKEY: { - mibGet->Param.NwkSKey =params->keys.LoRaMacNwkSKey; + mibGet->param.nwk_skey =params->keys.nwk_skey; break; } case MIB_APP_SKEY: { - mibGet->Param.AppSKey = params->keys.LoRaMacAppSKey; + mibGet->param.app_skey = params->keys.app_skey; break; } case MIB_PUBLIC_NETWORK: { - mibGet->Param.EnablePublicNetwork = params->PublicNetwork; + mibGet->param.enable_public_nwk = params->is_nwk_public; break; } case MIB_REPEATER_SUPPORT: { - mibGet->Param.EnableRepeaterSupport = params->RepeaterSupport; + mibGet->param.enable_repeater_support = params->is_repeater_supported; break; } case MIB_CHANNELS: @@ -357,17 +348,17 @@ LoRaMacStatus_t LoRaMacMib::get_request(MibRequestConfirm_t *mibGet, getPhy.Attribute = PHY_CHANNELS; phyParam = _lora_phy->get_phy_params( &getPhy ); - mibGet->Param.ChannelList = phyParam.Channels; + mibGet->param.channel_list = phyParam.Channels; break; } case MIB_RX2_CHANNEL: { - mibGet->Param.Rx2Channel = params->sys_params.Rx2Channel; + mibGet->param.rx2_channel = params->sys_params.rx2_channel; break; } case MIB_RX2_DEFAULT_CHANNEL: { - mibGet->Param.Rx2Channel = params->def_sys_params.Rx2Channel; + mibGet->param.rx2_channel = params->def_sys_params.rx2_channel; break; } case MIB_CHANNELS_DEFAULT_MASK: @@ -375,7 +366,7 @@ LoRaMacStatus_t LoRaMacMib::get_request(MibRequestConfirm_t *mibGet, getPhy.Attribute = PHY_CHANNELS_DEFAULT_MASK; phyParam = _lora_phy->get_phy_params( &getPhy ); - mibGet->Param.ChannelsDefaultMask = phyParam.ChannelsMask; + mibGet->param.default_channel_mask = phyParam.ChannelsMask; break; } case MIB_CHANNELS_MASK: @@ -383,91 +374,91 @@ LoRaMacStatus_t LoRaMacMib::get_request(MibRequestConfirm_t *mibGet, getPhy.Attribute = PHY_CHANNELS_MASK; phyParam = _lora_phy->get_phy_params( &getPhy ); - mibGet->Param.ChannelsMask = phyParam.ChannelsMask; + mibGet->param.channel_mask = phyParam.ChannelsMask; break; } case MIB_CHANNELS_NB_REP: { - mibGet->Param.ChannelNbRep = params->sys_params.ChannelsNbRep; + mibGet->param.channel_nb_rep = params->sys_params.retry_num; break; } case MIB_MAX_RX_WINDOW_DURATION: { - mibGet->Param.MaxRxWindow = params->sys_params.MaxRxWindow; + mibGet->param.max_rx_window = params->sys_params.max_rx_win_time; break; } case MIB_RECEIVE_DELAY_1: { - mibGet->Param.ReceiveDelay1 = params->sys_params.ReceiveDelay1; + mibGet->param.recv_delay1 = params->sys_params.recv_delay1; break; } case MIB_RECEIVE_DELAY_2: { - mibGet->Param.ReceiveDelay2 = params->sys_params.ReceiveDelay2; + mibGet->param.recv_delay2 = params->sys_params.recv_delay2; break; } case MIB_JOIN_ACCEPT_DELAY_1: { - mibGet->Param.JoinAcceptDelay1 = params->sys_params.JoinAcceptDelay1; + mibGet->param.join_accept_delay1 = params->sys_params.join_accept_delay1; break; } case MIB_JOIN_ACCEPT_DELAY_2: { - mibGet->Param.JoinAcceptDelay2 = params->sys_params.JoinAcceptDelay2; + mibGet->param.join_accept_delay2 = params->sys_params.join_accept_delay2; break; } case MIB_CHANNELS_DEFAULT_DATARATE: { - mibGet->Param.ChannelsDefaultDatarate = params->def_sys_params.ChannelsDatarate; + mibGet->param.default_channel_data_rate = params->def_sys_params.channel_data_rate; break; } case MIB_CHANNELS_DATARATE: { - mibGet->Param.ChannelsDatarate = params->sys_params.ChannelsDatarate; + mibGet->param.channel_data_rate = params->sys_params.channel_data_rate; break; } case MIB_CHANNELS_DEFAULT_TX_POWER: { - mibGet->Param.ChannelsDefaultTxPower = params->def_sys_params.ChannelsTxPower; + mibGet->param.default_channel_tx_pwr = params->def_sys_params.channel_tx_power; break; } case MIB_CHANNELS_TX_POWER: { - mibGet->Param.ChannelsTxPower = params->sys_params.ChannelsTxPower; + mibGet->param.channel_tx_pwr = params->sys_params.channel_tx_power; break; } case MIB_UPLINK_COUNTER: { - mibGet->Param.UpLinkCounter = params->UpLinkCounter; + mibGet->param.ul_frame_counter = params->ul_frame_counter; break; } case MIB_DOWNLINK_COUNTER: { - mibGet->Param.DownLinkCounter = params->DownLinkCounter; + mibGet->param.dl_frame_counter = params->dl_frame_counter; break; } case MIB_MULTICAST_CHANNEL: { - mibGet->Param.MulticastList = params->MulticastChannels; + mibGet->param.multicast_list = params->multicast_channels; break; } case MIB_SYSTEM_MAX_RX_ERROR: { - mibGet->Param.SystemMaxRxError = params->sys_params.SystemMaxRxError; + mibGet->param.max_rx_sys_error = params->sys_params.max_sys_rx_error; break; } case MIB_MIN_RX_SYMBOLS: { - mibGet->Param.MinRxSymbols = params->sys_params.MinRxSymbols; + mibGet->param.min_rx_symb = params->sys_params.min_rx_symb; break; } case MIB_ANTENNA_GAIN: { - mibGet->Param.AntennaGain = params->sys_params.AntennaGain; + mibGet->param.antenna_gain = params->sys_params.antenna_gain; break; } default: - status = LORAMAC_STATUS_SERVICE_UNKNOWN; + status = LORAWAN_STATUS_SERVICE_UNKNOWN; break; } diff --git a/features/lorawan/lorastack/mac/LoRaMacMib.h b/features/lorawan/lorastack/mac/LoRaMacMib.h index 0cbf7f7ed9..70cbaecfeb 100644 --- a/features/lorawan/lorastack/mac/LoRaMacMib.h +++ b/features/lorawan/lorastack/mac/LoRaMacMib.h @@ -67,10 +67,11 @@ public: * @param mibSet [in] pointer to MIB request structure * @param params pointer to MAC protocol parameters which will be modified * - * @return LORA_MAC_STATUS_OK if everything goes well otherwise + * @return LORAWAN_STATUS_OK if everything goes well otherwise * a negative error code is returned. */ - LoRaMacStatus_t set_request(MibRequestConfirm_t *mibSet, lora_mac_protocol_params *params); + lorawan_status_t set_request(loramac_mib_req_confirm_t *mibSet, + loramac_protocol_params *params); /** Provides access to the given MIB parameter * @@ -80,10 +81,11 @@ public: * @param mibGet [out] pointer to MIB request structure which will be filled in * @param params pointer to MAC protocol parameters * - * @return LORA_MAC_STATUS_OK if everything goes well otherwise + * @return LORAWAN_STATUS_OK if everything goes well otherwise * a negative error code is returned. */ - LoRaMacStatus_t get_request(MibRequestConfirm_t *mibGet, lora_mac_protocol_params *params); + lorawan_status_t get_request(loramac_mib_req_confirm_t *mibGet, + loramac_protocol_params *params); private: diff --git a/features/lorawan/lorastack/mac/LoRaMacMlme.cpp b/features/lorawan/lorastack/mac/LoRaMacMlme.cpp index 00a6e5455f..8fd61544bd 100644 --- a/features/lorawan/lorastack/mac/LoRaMacMlme.cpp +++ b/features/lorawan/lorastack/mac/LoRaMacMlme.cpp @@ -43,111 +43,111 @@ void LoRaMacMlme::activate_mlme_subsystem(LoRaMac *mac, LoRaPHY *phy, _mac_cmd = cmd; } -LoRaMacStatus_t LoRaMacMlme::set_request(MlmeReq_t *mlmeRequest, - lora_mac_protocol_params *params) +lorawan_status_t LoRaMacMlme::set_request(loramac_mlme_req_t *mlmeRequest, + loramac_protocol_params *params) { if (mlmeRequest && params && _lora_mac && _lora_phy && _mac_cmd) { - LoRaMacStatus_t status = LORAMAC_STATUS_SERVICE_UNKNOWN; - LoRaMacHeader_t macHdr; + lorawan_status_t status = LORAWAN_STATUS_SERVICE_UNKNOWN; + loramac_mhdr_t macHdr; AlternateDrParams_t altDr; VerifyParams_t verify; GetPhyParams_t getPhy; PhyParam_t phyParam; - if (params->LoRaMacState != LORAMAC_IDLE) { - return LORAMAC_STATUS_BUSY; + 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; + confirmation.status = LORAMAC_EVENT_INFO_STATUS_ERROR; - switch (mlmeRequest->Type) { + switch (mlmeRequest->type) { case MLME_JOIN: { - if ((params->LoRaMacState & LORAMAC_TX_DELAYED) + if ((params->mac_state & LORAMAC_TX_DELAYED) == LORAMAC_TX_DELAYED) { - return LORAMAC_STATUS_BUSY; + return LORAWAN_STATUS_BUSY; } - if ((mlmeRequest->Req.Join.DevEui == NULL) - || (mlmeRequest->Req.Join.AppEui == NULL) - || (mlmeRequest->Req.Join.AppKey == NULL) - || (mlmeRequest->Req.Join.NbTrials == 0)) { - return LORAMAC_STATUS_PARAMETER_INVALID; + 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; } // Verify the parameter NbTrials for the join procedure - verify.NbJoinTrials = mlmeRequest->Req.Join.NbTrials; + verify.NbJoinTrials = mlmeRequest->req.join.nb_trials; if (_lora_phy->verify(&verify, PHY_NB_JOIN_TRIALS) == false) { // Value not supported, get default getPhy.Attribute = PHY_DEF_NB_JOIN_TRIALS; phyParam = _lora_phy->get_phy_params(&getPhy); - mlmeRequest->Req.Join.NbTrials = (uint8_t) phyParam.Value; + mlmeRequest->req.join.nb_trials = (uint8_t) phyParam.Value; } - params->LoRaMacFlags.Bits.MlmeReq = 1; - confirmation.MlmeRequest = mlmeRequest->Type; + params->flags.bits.mlme_req = 1; + confirmation.req_type = mlmeRequest->type; - params->keys.LoRaMacDevEui = mlmeRequest->Req.Join.DevEui; - params->keys.LoRaMacAppEui = mlmeRequest->Req.Join.AppEui; - params->keys.LoRaMacAppKey = mlmeRequest->Req.Join.AppKey; - params->MaxJoinRequestTrials = mlmeRequest->Req.Join.NbTrials; + 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; // Reset variable JoinRequestTrials - params->JoinRequestTrials = 0; + params->join_request_trial_counter = 0; // Setup header information - macHdr.Value = 0; - macHdr.Bits.MType = FRAME_TYPE_JOIN_REQ; + macHdr.value = 0; + macHdr.bits.mtype = FRAME_TYPE_JOIN_REQ; _lora_mac->ResetMacParameters(); - altDr.NbTrials = params->JoinRequestTrials + 1; + altDr.NbTrials = params->join_request_trial_counter + 1; - params->sys_params.ChannelsDatarate = + params->sys_params.channel_data_rate = _lora_phy->get_alternate_DR(&altDr); status = _lora_mac->Send(&macHdr, 0, NULL, 0); break; } case MLME_LINK_CHECK: { - params->LoRaMacFlags.Bits.MlmeReq = 1; + params->flags.bits.mlme_req = 1; // LoRaMac will send this command piggy-backed - confirmation.MlmeRequest = mlmeRequest->Type; + confirmation.req_type = mlmeRequest->type; status = _mac_cmd->AddMacCommand(MOTE_MAC_LINK_CHECK_REQ, 0, 0); break; } case MLME_TXCW: { - confirmation.MlmeRequest = mlmeRequest->Type; - params->LoRaMacFlags.Bits.MlmeReq = 1; - status = _lora_mac->SetTxContinuousWave(mlmeRequest->Req.TxCw.Timeout); + confirmation.req_type = mlmeRequest->type; + params->flags.bits.mlme_req = 1; + status = _lora_mac->SetTxContinuousWave(mlmeRequest->req.cw_tx_mode.timeout); break; } case MLME_TXCW_1: { - confirmation.MlmeRequest = mlmeRequest->Type; - params->LoRaMacFlags.Bits.MlmeReq = 1; - status = _lora_mac->SetTxContinuousWave1(mlmeRequest->Req.TxCw.Timeout, - mlmeRequest->Req.TxCw.Frequency, - mlmeRequest->Req.TxCw.Power); + confirmation.req_type = mlmeRequest->type; + params->flags.bits.mlme_req = 1; + status = _lora_mac->SetTxContinuousWave1(mlmeRequest->req.cw_tx_mode.timeout, + mlmeRequest->req.cw_tx_mode.frequency, + mlmeRequest->req.cw_tx_mode.power); break; } default: break; } - if (status != LORAMAC_STATUS_OK) { - params->NodeAckRequested = false; - params->LoRaMacFlags.Bits.MlmeReq = 0; + if (status != LORAWAN_STATUS_OK) { + params->is_node_ack_requested = false; + params->flags.bits.mlme_req = 0; } return status; } - return LORAMAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } diff --git a/features/lorawan/lorastack/mac/LoRaMacMlme.h b/features/lorawan/lorastack/mac/LoRaMacMlme.h index 6a80073201..deb73f75f2 100644 --- a/features/lorawan/lorastack/mac/LoRaMacMlme.h +++ b/features/lorawan/lorastack/mac/LoRaMacMlme.h @@ -69,16 +69,16 @@ public: * @param mlmeRequest pointer to MLME request structure * @param params pointer to MAC protocol parameters * - * @return LORA_MAC_STATUS_OK if everything goes well otherwise + * @return LORAWAN_STATUS_OK if everything goes well otherwise * a negative error code is returned. */ - LoRaMacStatus_t set_request(MlmeReq_t *mlmeRequest, lora_mac_protocol_params *params); + lorawan_status_t set_request(loramac_mlme_req_t *mlmeRequest, loramac_protocol_params *params); /** Grants access to MLME confirmation data * * @return a reference to MLME confirm data structure */ - inline MlmeConfirm_t& get_confirmation() + inline loramac_mlme_confirm_t& get_confirmation() { return confirmation; } @@ -87,7 +87,7 @@ public: * * @return a reference to MLME indication data structure */ - inline MlmeIndication_t& get_indication() + inline loramac_mlme_indication_t& get_indication() { return indication; } @@ -104,12 +104,12 @@ private: /** * Structure to hold MLME indication data. */ - MlmeIndication_t indication; + loramac_mlme_indication_t indication; /** * Structure to hold MLME confirm data. */ - MlmeConfirm_t confirmation; + loramac_mlme_confirm_t confirmation; }; #endif /* MBED_OS_LORAWAN_MAC_MLME_H_ */ diff --git a/features/lorawan/lorastack/phy/LoRaPHY.cpp b/features/lorawan/lorastack/phy/LoRaPHY.cpp index 80b20df2b0..3c4cc9b275 100644 --- a/features/lorawan/lorastack/phy/LoRaPHY.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHY.cpp @@ -128,7 +128,7 @@ int32_t LoRaPHY::get_random(int32_t min, int32_t max) return (int32_t) rand() % (max - min + 1) + min; } -uint16_t LoRaPHY::get_join_DC( TimerTime_t elapsedTime ) +uint16_t LoRaPHY::get_join_DC( lorawan_time_t elapsedTime ) { uint16_t dutyCycle = 0; @@ -147,7 +147,7 @@ uint16_t LoRaPHY::get_join_DC( TimerTime_t elapsedTime ) return dutyCycle; } -bool LoRaPHY::verify_channel_DR( uint8_t nbChannels, uint16_t* channelsMask, int8_t dr, int8_t minDr, int8_t maxDr, ChannelParams_t* channels ) +bool LoRaPHY::verify_channel_DR( uint8_t nbChannels, uint16_t* channelsMask, int8_t dr, int8_t minDr, int8_t maxDr, channel_params_t* channels ) { if( val_in_range( dr, minDr, maxDr ) == 0 ) { @@ -160,8 +160,8 @@ bool LoRaPHY::verify_channel_DR( uint8_t nbChannels, uint16_t* channelsMask, int { if( ( ( channelsMask[k] & ( 1 << j ) ) != 0 ) ) {// Check datarate validity for enabled channels - if( val_in_range( dr, ( channels[i + j].DrRange.Fields.Min & 0x0F ), - ( channels[i + j].DrRange.Fields.Max & 0x0F ) ) == 1 ) + if( val_in_range( dr, ( channels[i + j].dr_range.fields.min & 0x0F ), + ( channels[i + j].dr_range.fields.max & 0x0F ) ) == 1 ) { // At least 1 channel has been found we can return OK. return true; @@ -224,58 +224,58 @@ void LoRaPHY::copy_channel_mask( uint16_t* channelsMaskDest, uint16_t* channelsM } } -void LoRaPHY::set_last_tx_done( bool joined, Band_t* band, TimerTime_t lastTxDone ) +void LoRaPHY::set_last_tx_done( bool joined, band_t* band, lorawan_time_t lastTxDone ) { if( joined == true ) { - band->LastTxDoneTime = lastTxDone; + band->last_tx_time = lastTxDone; } else { - band->LastTxDoneTime = lastTxDone; - band->LastJoinTxDoneTime = lastTxDone; + band->last_tx_time = lastTxDone; + band->last_join_tx_time = lastTxDone; } } -TimerTime_t LoRaPHY::update_band_timeoff( bool joined, bool dutyCycle, Band_t* bands, uint8_t nbBands ) +lorawan_time_t LoRaPHY::update_band_timeoff( bool joined, bool dutyCycle, band_t* bands, uint8_t nbBands ) { - TimerTime_t nextTxDelay = ( TimerTime_t )( -1 ); + lorawan_time_t nextTxDelay = ( lorawan_time_t )( -1 ); // Update bands Time OFF for( uint8_t i = 0; i < nbBands; i++ ) { if( joined == false ) { - uint32_t txDoneTime = MAX( _lora_time.TimerGetElapsedTime( bands[i].LastJoinTxDoneTime ), - ( dutyCycle == true ) ? _lora_time.TimerGetElapsedTime( bands[i].LastTxDoneTime ) : 0 ); + uint32_t txDoneTime = MAX( _lora_time.TimerGetElapsedTime( bands[i].last_join_tx_time ), + ( dutyCycle == true ) ? _lora_time.TimerGetElapsedTime( bands[i].last_tx_time ) : 0 ); - if( bands[i].TimeOff <= txDoneTime ) + if( bands[i].off_time <= txDoneTime ) { - bands[i].TimeOff = 0; + bands[i].off_time = 0; } - if( bands[i].TimeOff != 0 ) + if( bands[i].off_time != 0 ) { - nextTxDelay = MIN( bands[i].TimeOff - txDoneTime, nextTxDelay ); + nextTxDelay = MIN( bands[i].off_time - txDoneTime, nextTxDelay ); } } else { if( dutyCycle == true ) { - if( bands[i].TimeOff <= _lora_time.TimerGetElapsedTime( bands[i].LastTxDoneTime ) ) + if( bands[i].off_time <= _lora_time.TimerGetElapsedTime( bands[i].last_tx_time ) ) { - bands[i].TimeOff = 0; + bands[i].off_time = 0; } - if( bands[i].TimeOff != 0 ) + if( bands[i].off_time != 0 ) { - nextTxDelay = MIN( bands[i].TimeOff - _lora_time.TimerGetElapsedTime( bands[i].LastTxDoneTime ), + nextTxDelay = MIN( bands[i].off_time - _lora_time.TimerGetElapsedTime( bands[i].last_tx_time ), nextTxDelay ); } } else { nextTxDelay = 0; - bands[i].TimeOff = 0; + bands[i].off_time = 0; } } } @@ -396,12 +396,12 @@ int8_t LoRaPHY::compute_tx_power( int8_t txPowerIndex, float maxEirp, float ante void LoRaPHY::get_DC_backoff( RegionCommonCalcBackOffParams_t* calcBackOffParams ) { - uint8_t bandIdx = calcBackOffParams->Channels[calcBackOffParams->Channel].Band; - uint16_t dutyCycle = calcBackOffParams->Bands[bandIdx].DCycle; + uint8_t bandIdx = calcBackOffParams->Channels[calcBackOffParams->Channel].band; + uint16_t dutyCycle = calcBackOffParams->Bands[bandIdx].duty_cycle; uint16_t joinDutyCycle = 0; // Reset time-off to initial value. - calcBackOffParams->Bands[bandIdx].TimeOff = 0; + calcBackOffParams->Bands[bandIdx].off_time = 0; if( calcBackOffParams->Joined == false ) { @@ -416,23 +416,23 @@ void LoRaPHY::get_DC_backoff( RegionCommonCalcBackOffParams_t* calcBackOffParams // This could happen in case of a rejoin, e.g. in compliance test mode. // In this special case we have to set the time off to 0, since the join duty cycle shall only // be applied after the first join request. - calcBackOffParams->Bands[bandIdx].TimeOff = 0; + calcBackOffParams->Bands[bandIdx].off_time = 0; } else { // Apply band time-off. - calcBackOffParams->Bands[bandIdx].TimeOff = calcBackOffParams->TxTimeOnAir * dutyCycle - calcBackOffParams->TxTimeOnAir; + calcBackOffParams->Bands[bandIdx].off_time = calcBackOffParams->TxTimeOnAir * dutyCycle - calcBackOffParams->TxTimeOnAir; } } else { if( calcBackOffParams->DutyCycleEnabled == true ) { - calcBackOffParams->Bands[bandIdx].TimeOff = calcBackOffParams->TxTimeOnAir * dutyCycle - calcBackOffParams->TxTimeOnAir; + calcBackOffParams->Bands[bandIdx].off_time = calcBackOffParams->TxTimeOnAir * dutyCycle - calcBackOffParams->TxTimeOnAir; } else { - calcBackOffParams->Bands[bandIdx].TimeOff = 0; + calcBackOffParams->Bands[bandIdx].off_time = 0; } } } diff --git a/features/lorawan/lorastack/phy/LoRaPHY.h b/features/lorawan/lorastack/phy/LoRaPHY.h index 057bcfbf7f..85cb4e9482 100644 --- a/features/lorawan/lorastack/phy/LoRaPHY.h +++ b/features/lorawan/lorastack/phy/LoRaPHY.h @@ -136,7 +136,7 @@ public: * * \retval True, if the configuration was applied successfully. */ - virtual bool rx_config(RxConfigParams_t* rxConfig, int8_t* datarate ) = 0; + virtual bool rx_config(rx_config_params_t* rxConfig, int8_t* datarate ) = 0; /* * RX window precise timing @@ -193,7 +193,7 @@ public: virtual void compute_rx_win_params(int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, - RxConfigParams_t *rxConfigParams) = 0; + rx_config_params_t *rxConfigParams) = 0; /*! * \brief TX configuration. * @@ -206,7 +206,7 @@ public: * \retval True, if the configuration was applied successfully. */ virtual bool tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - TimerTime_t* txTimeOnAir ) = 0; + lorawan_time_t* txTimeOnAir ) = 0; /*! * \brief The function processes a Link ADR Request. @@ -296,8 +296,8 @@ public: * \retval Function status [1: OK, 0: Unable to find a channel on the current datarate]. */ virtual bool set_next_channel(NextChanParams_t* nextChanParams, - uint8_t* channel, TimerTime_t* time, - TimerTime_t* aggregatedTimeOff ) = 0; + uint8_t* channel, lorawan_time_t* time, + lorawan_time_t* aggregatedTimeOff ) = 0; /*! * \brief Adds a channel. @@ -306,7 +306,7 @@ public: * * \retval The status of the operation. */ - virtual LoRaMacStatus_t add_channel(ChannelAddParams_t* channelAdd ) = 0; + virtual lorawan_status_t add_channel(ChannelAddParams_t* channelAdd ) = 0; /*! * \brief Removes a channel. @@ -418,7 +418,7 @@ protected: /*! * A pointer to the channels. */ - ChannelParams_t* Channels; + channel_params_t* Channels; /*! * The minimum possible TX power. */ @@ -434,11 +434,11 @@ protected: /*! * A pointer to region specific channels. */ - ChannelParams_t* Channels; + channel_params_t* Channels; /*! * A pointer to region specific bands. */ - Band_t* Bands; + band_t* Bands; /*! * Set to true, if the last uplink was a join request. */ @@ -458,11 +458,11 @@ protected: /*! * The elapsed time since initialization. */ - TimerTime_t ElapsedTime; + lorawan_time_t ElapsedTime; /*! * The time on air of the last TX frame. */ - TimerTime_t TxTimeOnAir; + lorawan_time_t TxTimeOnAir; }RegionCommonCalcBackOffParams_t; /*! @@ -473,7 +473,7 @@ protected: * * \retval Duty cycle restriction. */ - uint16_t get_join_DC( TimerTime_t elapsedTime ); + uint16_t get_join_DC( lorawan_time_t elapsedTime ); /*! * \brief Verifies, if a value is in a given range. @@ -508,7 +508,7 @@ protected: * \retval True if the datarate is supported, false if not. */ bool verify_channel_DR( uint8_t nbChannels, uint16_t* channelsMask, int8_t dr, - int8_t minDr, int8_t maxDr, ChannelParams_t* channels ); + int8_t minDr, int8_t maxDr, channel_params_t* channels ); /*! * \brief Disables a channel in a given channels mask. @@ -560,7 +560,7 @@ protected: * * \param [in] lastTxDone The time of the last TX done. */ - void set_last_tx_done( bool joined, Band_t* band, TimerTime_t lastTxDone ); + void set_last_tx_done( bool joined, band_t* band, lorawan_time_t lastTxDone ); /*! * \brief Updates the time-offs of the bands. @@ -576,7 +576,7 @@ protected: * * \retval The time which must be waited to perform the next uplink. */ - TimerTime_t update_band_timeoff( bool joined, bool dutyCycle, Band_t* bands, uint8_t nbBands ); + lorawan_time_t update_band_timeoff( bool joined, bool dutyCycle, band_t* bands, uint8_t nbBands ); /*! * \brief Parses the parameter of an LinkAdrRequest. diff --git a/features/lorawan/lorastack/phy/LoRaPHYAS923.cpp b/features/lorawan/lorastack/phy/LoRaPHYAS923.cpp index 17e3355775..c00119dcbd 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYAS923.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYAS923.cpp @@ -321,7 +321,7 @@ static bool VerifyTxFreq( uint32_t freq ) uint8_t LoRaPHYAS923::CountNbOfEnabledChannels(bool joined, uint8_t datarate, uint16_t* channelsMask, - ChannelParams_t* channels, Band_t* bands, + channel_params_t* channels, band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx) { uint8_t nbEnabledChannels = 0; @@ -333,7 +333,7 @@ uint8_t LoRaPHYAS923::CountNbOfEnabledChannels(bool joined, uint8_t datarate, { if( ( channelsMask[k] & ( 1 << j ) ) != 0 ) { - if( channels[i + j].Frequency == 0 ) + if( channels[i + j].frequency == 0 ) { // Check if the channel is enabled continue; } @@ -344,12 +344,12 @@ uint8_t LoRaPHYAS923::CountNbOfEnabledChannels(bool joined, uint8_t datarate, continue; } } - if( val_in_range( datarate, channels[i + j].DrRange.Fields.Min, - channels[i + j].DrRange.Fields.Max ) == 0 ) + if( val_in_range( datarate, channels[i + j].dr_range.fields.min, + channels[i + j].dr_range.fields.max ) == 0 ) { // Check if the current channel selection supports the given datarate continue; } - if( bands[channels[i + j].Band].TimeOff > 0 ) + if( bands[channels[i + j].band].off_time > 0 ) { // Check if the band is available for transmission delayTransmission++; continue; @@ -366,7 +366,7 @@ uint8_t LoRaPHYAS923::CountNbOfEnabledChannels(bool joined, uint8_t datarate, LoRaPHYAS923::LoRaPHYAS923(LoRaWANTimeHandler &lora_time) : LoRaPHY(lora_time) { - const Band_t band0 = AS923_BAND0; + const band_t band0 = AS923_BAND0; Bands[0] = band0; } @@ -562,7 +562,7 @@ PhyParam_t LoRaPHYAS923::get_phy_params(GetPhyParams_t* getPhy) void LoRaPHYAS923::set_band_tx_done(SetBandTxDoneParams_t* txDone) { - set_last_tx_done( txDone->Joined, &Bands[Channels[txDone->Channel].Band], txDone->LastTxDoneTime ); + set_last_tx_done( txDone->Joined, &Bands[Channels[txDone->Channel].band], txDone->LastTxDoneTime ); } void LoRaPHYAS923::load_defaults(InitType_t type) @@ -572,8 +572,8 @@ void LoRaPHYAS923::load_defaults(InitType_t type) case INIT_TYPE_INIT: { // Channels - const ChannelParams_t channel1 = AS923_LC1; - const ChannelParams_t channel2 = AS923_LC2; + const channel_params_t channel1 = AS923_LC1; + const channel_params_t channel2 = AS923_LC2; Channels[0] = channel1; Channels[1] = channel2; @@ -647,12 +647,12 @@ bool LoRaPHYAS923::verify(VerifyParams_t* verify, PhyAttribute_t phyAttribute) void LoRaPHYAS923::apply_cf_list(ApplyCFListParams_t* applyCFList) { - ChannelParams_t newChannel; + channel_params_t newChannel; ChannelAddParams_t channelAdd; ChannelRemoveParams_t channelRemove; // Setup default datarate range - newChannel.DrRange.Value = ( DR_5 << 4 ) | DR_0; + newChannel.dr_range.value = ( DR_5 << 4 ) | DR_0; // Size of the optional CF list if( applyCFList->Size != 16 ) @@ -666,22 +666,22 @@ void LoRaPHYAS923::apply_cf_list(ApplyCFListParams_t* applyCFList) if( chanIdx < ( AS923_NUMB_CHANNELS_CF_LIST + AS923_NUMB_DEFAULT_CHANNELS ) ) { // Channel frequency - newChannel.Frequency = (uint32_t) applyCFList->Payload[i]; - newChannel.Frequency |= ( (uint32_t) applyCFList->Payload[i + 1] << 8 ); - newChannel.Frequency |= ( (uint32_t) applyCFList->Payload[i + 2] << 16 ); - newChannel.Frequency *= 100; + newChannel.frequency = (uint32_t) applyCFList->Payload[i]; + newChannel.frequency |= ( (uint32_t) applyCFList->Payload[i + 1] << 8 ); + newChannel.frequency |= ( (uint32_t) applyCFList->Payload[i + 2] << 16 ); + newChannel.frequency *= 100; // Initialize alternative frequency to 0 - newChannel.Rx1Frequency = 0; + newChannel.rx1_frequency = 0; } else { - newChannel.Frequency = 0; - newChannel.DrRange.Value = 0; - newChannel.Rx1Frequency = 0; + newChannel.frequency = 0; + newChannel.dr_range.value = 0; + newChannel.rx1_frequency = 0; } - if( newChannel.Frequency != 0 ) + if( newChannel.frequency != 0 ) { channelAdd.NewChannel = &newChannel; channelAdd.ChannelId = chanIdx; @@ -791,47 +791,47 @@ bool LoRaPHYAS923::get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut, void LoRaPHYAS923::compute_rx_win_params(int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, - RxConfigParams_t *rxConfigParams) + rx_config_params_t *rxConfigParams) { double tSymbol = 0.0; // Get the datarate, perform a boundary check - rxConfigParams->Datarate = MIN( datarate, AS923_RX_MAX_DATARATE ); - rxConfigParams->Bandwidth = GetBandwidth( rxConfigParams->Datarate ); + rxConfigParams->datarate = MIN( datarate, AS923_RX_MAX_DATARATE ); + rxConfigParams->bandwidth = GetBandwidth( rxConfigParams->datarate ); - if( rxConfigParams->Datarate == DR_7 ) + if( rxConfigParams->datarate == DR_7 ) { // FSK - tSymbol = compute_symb_timeout_fsk( DataratesAS923[rxConfigParams->Datarate] ); + tSymbol = compute_symb_timeout_fsk( DataratesAS923[rxConfigParams->datarate] ); } else { // LoRa - tSymbol = compute_symb_timeout_lora( DataratesAS923[rxConfigParams->Datarate], BandwidthsAS923[rxConfigParams->Datarate] ); + tSymbol = compute_symb_timeout_lora( DataratesAS923[rxConfigParams->datarate], BandwidthsAS923[rxConfigParams->datarate] ); } - get_rx_window_params( tSymbol, minRxSymbols, rxError, RADIO_WAKEUP_TIME, &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); + get_rx_window_params( tSymbol, minRxSymbols, rxError, RADIO_WAKEUP_TIME, &rxConfigParams->window_timeout, &rxConfigParams->window_offset ); } -bool LoRaPHYAS923::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) +bool LoRaPHYAS923::rx_config(rx_config_params_t* rxConfig, int8_t* datarate) { radio_modems_t modem; - int8_t dr = rxConfig->Datarate; + int8_t dr = rxConfig->datarate; uint8_t maxPayload = 0; int8_t phyDr = 0; - uint32_t frequency = rxConfig->Frequency; + uint32_t frequency = rxConfig->frequency; if( _radio->get_status() != RF_IDLE ) { return false; } - if( rxConfig->RxSlot == RX_SLOT_WIN_1 ) + if( rxConfig->rx_slot == RX_SLOT_WIN_1 ) { // Apply window 1 frequency - frequency = Channels[rxConfig->Channel].Frequency; + frequency = Channels[rxConfig->channel].frequency; // Apply the alternative RX 1 window frequency, if it is available - if( Channels[rxConfig->Channel].Rx1Frequency != 0 ) + if( Channels[rxConfig->channel].rx1_frequency != 0 ) { - frequency = Channels[rxConfig->Channel].Rx1Frequency; + frequency = Channels[rxConfig->channel].rx1_frequency; } } @@ -845,19 +845,19 @@ bool LoRaPHYAS923::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) { modem = MODEM_FSK; _radio->set_rx_config(modem, 50000, phyDr * 1000, 0, 83333, 5, - rxConfig->WindowTimeout, false, 0, true, 0, - 0, false, rxConfig->RxContinuous); + rxConfig->window_timeout, false, 0, true, 0, + 0, false, rxConfig->is_rx_continuous); } else { modem = MODEM_LORA; - _radio->set_rx_config(modem, rxConfig->Bandwidth, phyDr, 1, 0, 8, - rxConfig->WindowTimeout, false, 0, false, 0, 0, - true, rxConfig->RxContinuous); + _radio->set_rx_config(modem, rxConfig->bandwidth, phyDr, 1, 0, 8, + rxConfig->window_timeout, false, 0, false, 0, 0, + true, rxConfig->is_rx_continuous); } // Check for repeater support - if( rxConfig->RepeaterSupport == true ) + if( rxConfig->is_repeater_supported == true ) { maxPayload = MaxPayloadOfDatarateRepeaterDwell0AS923[dr]; } @@ -873,11 +873,11 @@ bool LoRaPHYAS923::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) } bool LoRaPHYAS923::tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - TimerTime_t* txTimeOnAir) + lorawan_time_t* txTimeOnAir) { radio_modems_t modem; int8_t phyDr = DataratesAS923[txConfig->Datarate]; - int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, Bands[Channels[txConfig->Channel].Band].TxMaxPower, txConfig->Datarate, ChannelsMask ); + int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, Bands[Channels[txConfig->Channel].band].max_tx_pwr, txConfig->Datarate, ChannelsMask ); uint32_t bandwidth = GetBandwidth( txConfig->Datarate ); int8_t phyTxPower = 0; @@ -885,7 +885,7 @@ bool LoRaPHYAS923::tx_config(TxConfigParams_t* txConfig, int8_t* txPower, phyTxPower = compute_tx_power( txPowerLimited, txConfig->MaxEirp, txConfig->AntennaGain ); // Setup the radio frequency - _radio->set_channel(Channels[txConfig->Channel].Frequency); + _radio->set_channel(Channels[txConfig->Channel].frequency); if( txConfig->Datarate == DR_7 ) { // High Speed FSK channel @@ -956,7 +956,7 @@ uint8_t LoRaPHYAS923::link_ADR_request(LinkAdrReqParams_t* linkAdrReq, { if( linkAdrParams.ChMaskCtrl == 6 ) { - if( Channels[i].Frequency != 0 ) + if( Channels[i].frequency != 0 ) { chMask |= 1 << i; } @@ -964,7 +964,7 @@ uint8_t LoRaPHYAS923::link_ADR_request(LinkAdrReqParams_t* linkAdrReq, else { if( ( ( chMask & ( 1 << i ) ) != 0 ) && - ( Channels[i].Frequency == 0 ) ) + ( Channels[i].frequency == 0 ) ) {// Trying to enable an undefined channel status &= 0xFE; // Channel mask KO } @@ -1046,7 +1046,7 @@ uint8_t LoRaPHYAS923::request_new_channel(NewChannelReqParams_t* newChannelReq) ChannelAddParams_t channelAdd; ChannelRemoveParams_t channelRemove; - if( newChannelReq->NewChannel->Frequency == 0 ) + if( newChannelReq->NewChannel->frequency == 0 ) { channelRemove.ChannelId = newChannelReq->ChannelId; @@ -1063,21 +1063,21 @@ uint8_t LoRaPHYAS923::request_new_channel(NewChannelReqParams_t* newChannelReq) switch( add_channel (&channelAdd )) { - case LORAMAC_STATUS_OK: + case LORAWAN_STATUS_OK: { break; } - case LORAMAC_STATUS_FREQUENCY_INVALID: + case LORAWAN_STATUS_FREQUENCY_INVALID: { status &= 0xFE; break; } - case LORAMAC_STATUS_DATARATE_INVALID: + case LORAWAN_STATUS_DATARATE_INVALID: { status &= 0xFD; break; } - case LORAMAC_STATUS_FREQ_AND_DR_INVALID: + case LORAWAN_STATUS_FREQ_AND_DR_INVALID: { status &= 0xFC; break; @@ -1110,7 +1110,7 @@ uint8_t LoRaPHYAS923::dl_channel_request(DlChannelReqParams_t* dlChannelReq) } // Verify if an uplink frequency exists - if( Channels[dlChannelReq->ChannelId].Frequency == 0 ) + if( Channels[dlChannelReq->ChannelId].frequency == 0 ) { status &= 0xFD; } @@ -1118,7 +1118,7 @@ uint8_t LoRaPHYAS923::dl_channel_request(DlChannelReqParams_t* dlChannelReq) // Apply Rx1 frequency, if the status is OK if( status == 0x03 ) { - Channels[dlChannelReq->ChannelId].Rx1Frequency = dlChannelReq->Rx1Frequency; + Channels[dlChannelReq->ChannelId].rx1_frequency = dlChannelReq->Rx1Frequency; } return status; @@ -1147,14 +1147,14 @@ void LoRaPHYAS923::calculate_backoff(CalcBackOffParams_t* calcBackOff) } bool LoRaPHYAS923::set_next_channel(NextChanParams_t* nextChanParams, - uint8_t* channel, TimerTime_t* time, - TimerTime_t* aggregatedTimeOff) + uint8_t* channel, lorawan_time_t* time, + lorawan_time_t* aggregatedTimeOff) { uint8_t channelNext = 0; uint8_t nbEnabledChannels = 0; uint8_t delayTx = 0; uint8_t enabledChannels[AS923_MAX_NB_CHANNELS] = { 0 }; - TimerTime_t nextTxDelay = 0; + lorawan_time_t nextTxDelay = 0; if( num_active_channels( ChannelsMask, 0, 1 ) == 0 ) { // Reactivate default channels @@ -1190,7 +1190,7 @@ bool LoRaPHYAS923::set_next_channel(NextChanParams_t* nextChanParams, // Perform carrier sense for AS923_CARRIER_SENSE_TIME // If the channel is free, we can stop the LBT mechanism if( _radio->perform_carrier_sense(MODEM_LORA, - Channels[channelNext].Frequency, + Channels[channelNext].frequency, AS923_RSSI_FREE_TH, AS923_CARRIER_SENSE_TIME ) == true) { @@ -1217,7 +1217,7 @@ bool LoRaPHYAS923::set_next_channel(NextChanParams_t* nextChanParams, } } -LoRaMacStatus_t LoRaPHYAS923::add_channel(ChannelAddParams_t* channelAdd) +lorawan_status_t LoRaPHYAS923::add_channel(ChannelAddParams_t* channelAdd) { uint8_t band = 0; bool drInvalid = false; @@ -1226,19 +1226,19 @@ LoRaMacStatus_t LoRaPHYAS923::add_channel(ChannelAddParams_t* channelAdd) if( id >= AS923_MAX_NB_CHANNELS ) { - return LORAMAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } // Validate the datarate range - if( val_in_range( channelAdd->NewChannel->DrRange.Fields.Min, AS923_TX_MIN_DATARATE, AS923_TX_MAX_DATARATE ) == 0 ) + if( val_in_range( channelAdd->NewChannel->dr_range.fields.min, AS923_TX_MIN_DATARATE, AS923_TX_MAX_DATARATE ) == 0 ) { drInvalid = true; } - if( val_in_range( channelAdd->NewChannel->DrRange.Fields.Max, AS923_TX_MIN_DATARATE, AS923_TX_MAX_DATARATE ) == 0 ) + if( val_in_range( channelAdd->NewChannel->dr_range.fields.max, AS923_TX_MIN_DATARATE, AS923_TX_MAX_DATARATE ) == 0 ) { drInvalid = true; } - if( channelAdd->NewChannel->DrRange.Fields.Min > channelAdd->NewChannel->DrRange.Fields.Max ) + if( channelAdd->NewChannel->dr_range.fields.min > channelAdd->NewChannel->dr_range.fields.max ) { drInvalid = true; } @@ -1247,17 +1247,17 @@ LoRaMacStatus_t LoRaPHYAS923::add_channel(ChannelAddParams_t* channelAdd) if( id < AS923_NUMB_DEFAULT_CHANNELS ) { // Validate the datarate range for min: must be DR_0 - if( channelAdd->NewChannel->DrRange.Fields.Min > DR_0 ) + if( channelAdd->NewChannel->dr_range.fields.min > DR_0 ) { drInvalid = true; } // Validate the datarate range for max: must be DR_5 <= Max <= TX_MAX_DATARATE - if( val_in_range( channelAdd->NewChannel->DrRange.Fields.Max, DR_5, AS923_TX_MAX_DATARATE ) == 0 ) + if( val_in_range( channelAdd->NewChannel->dr_range.fields.max, DR_5, AS923_TX_MAX_DATARATE ) == 0 ) { drInvalid = true; } // We are not allowed to change the frequency - if( channelAdd->NewChannel->Frequency != Channels[id].Frequency ) + if( channelAdd->NewChannel->frequency != Channels[id].frequency ) { freqInvalid = true; } @@ -1266,7 +1266,7 @@ LoRaMacStatus_t LoRaPHYAS923::add_channel(ChannelAddParams_t* channelAdd) // Check frequency if( freqInvalid == false ) { - if( VerifyTxFreq( channelAdd->NewChannel->Frequency ) == false ) + if( VerifyTxFreq( channelAdd->NewChannel->frequency ) == false ) { freqInvalid = true; } @@ -1275,21 +1275,21 @@ LoRaMacStatus_t LoRaPHYAS923::add_channel(ChannelAddParams_t* channelAdd) // Check status if( ( drInvalid == true ) && ( freqInvalid == true ) ) { - return LORAMAC_STATUS_FREQ_AND_DR_INVALID; + return LORAWAN_STATUS_FREQ_AND_DR_INVALID; } if( drInvalid == true ) { - return LORAMAC_STATUS_DATARATE_INVALID; + return LORAWAN_STATUS_DATARATE_INVALID; } if( freqInvalid == true ) { - return LORAMAC_STATUS_FREQUENCY_INVALID; + return LORAWAN_STATUS_FREQUENCY_INVALID; } memcpy( &(Channels[id]), channelAdd->NewChannel, sizeof( Channels[id] ) ); - Channels[id].Band = band; + Channels[id].band = band; ChannelsMask[0] |= ( 1 << id ); - return LORAMAC_STATUS_OK; + return LORAWAN_STATUS_OK; } bool LoRaPHYAS923::remove_channel(ChannelRemoveParams_t* channelRemove) @@ -1302,7 +1302,7 @@ bool LoRaPHYAS923::remove_channel(ChannelRemoveParams_t* channelRemove) } // Remove the channel from the list of channels - const ChannelParams_t empty_channel = { 0, 0, { 0 }, 0 }; + const channel_params_t empty_channel = { 0, 0, { 0 }, 0 }; Channels[id] = empty_channel; return disable_channel( ChannelsMask, id, AS923_MAX_NB_CHANNELS ); @@ -1310,9 +1310,9 @@ bool LoRaPHYAS923::remove_channel(ChannelRemoveParams_t* channelRemove) void LoRaPHYAS923::set_tx_cont_mode(ContinuousWaveParams_t* continuousWave) { - int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, Bands[Channels[continuousWave->Channel].Band].TxMaxPower, continuousWave->Datarate, ChannelsMask ); + int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, Bands[Channels[continuousWave->Channel].band].max_tx_pwr, continuousWave->Datarate, ChannelsMask ); int8_t phyTxPower = 0; - uint32_t frequency = Channels[continuousWave->Channel].Frequency; + uint32_t frequency = Channels[continuousWave->Channel].frequency; // Calculate physical TX power phyTxPower = compute_tx_power( txPowerLimited, continuousWave->MaxEirp, continuousWave->AntennaGain ); diff --git a/features/lorawan/lorastack/phy/LoRaPHYAS923.h b/features/lorawan/lorastack/phy/LoRaPHYAS923.h index 34e022fb8b..aff0e55622 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYAS923.h +++ b/features/lorawan/lorastack/phy/LoRaPHYAS923.h @@ -131,7 +131,7 @@ public: * * \retval True, if the configuration was applied successfully. */ - virtual bool rx_config(RxConfigParams_t* rxConfig, int8_t* datarate ); + virtual bool rx_config(rx_config_params_t* rxConfig, int8_t* datarate ); /* * RX window precise timing. @@ -187,7 +187,7 @@ public: virtual void compute_rx_win_params(int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, - RxConfigParams_t *rxConfigParams); + rx_config_params_t *rxConfigParams); /*! * \brief TX configuration. @@ -201,7 +201,7 @@ public: * \retval True, if the configuration was applied successfully. */ virtual bool tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - TimerTime_t* txTimeOnAir ); + lorawan_time_t* txTimeOnAir ); /*! * \brief The function processes a Link ADR Request. @@ -291,8 +291,8 @@ public: * \retval Function status [1: OK, 0: Unable to find a channel on the current datarate]. */ virtual bool set_next_channel(NextChanParams_t* nextChanParams, - uint8_t* channel, TimerTime_t* time, - TimerTime_t* aggregatedTimeOff ); + uint8_t* channel, lorawan_time_t* time, + lorawan_time_t* aggregatedTimeOff ); /*! * \brief Adds a channel. @@ -301,7 +301,7 @@ public: * * \retval The status of the operation. */ - virtual LoRaMacStatus_t add_channel(ChannelAddParams_t* channelAdd ); + virtual lorawan_status_t add_channel(ChannelAddParams_t* channelAdd ); /*! * \brief Removes a channel. @@ -335,19 +335,19 @@ public: private: uint8_t CountNbOfEnabledChannels(bool joined, uint8_t datarate, uint16_t* channelsMask, - ChannelParams_t* channels, Band_t* bands, + channel_params_t* channels, band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx); // Global attributes /*! * LoRaMAC channels */ - ChannelParams_t Channels[AS923_MAX_NB_CHANNELS]; + channel_params_t Channels[AS923_MAX_NB_CHANNELS]; /*! * LoRaMac bands */ - Band_t Bands[AS923_MAX_NB_BANDS]; + band_t Bands[AS923_MAX_NB_BANDS]; /*! * LoRaMac channels mask diff --git a/features/lorawan/lorastack/phy/LoRaPHYAU915.cpp b/features/lorawan/lorastack/phy/LoRaPHYAU915.cpp index 407e7db78e..db4af8d0cd 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYAU915.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYAU915.cpp @@ -263,8 +263,8 @@ static int8_t LimitTxPower(int8_t txPower, int8_t maxBandTxPower, uint8_t LoRaPHYAU915::CountNbOfEnabledChannels(uint8_t datarate, uint16_t* channelsMask, - ChannelParams_t* channels, - Band_t* bands, uint8_t* enabledChannels, + channel_params_t* channels, + band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx) { uint8_t nbEnabledChannels = 0; @@ -273,14 +273,14 @@ uint8_t LoRaPHYAU915::CountNbOfEnabledChannels(uint8_t datarate, for (uint8_t i = 0, k = 0; i < AU915_MAX_NB_CHANNELS; i += 16, k++) { for (uint8_t j = 0; j < 16; j++) { if ((channelsMask[k] & (1 << j)) != 0) { - if (channels[i + j].Frequency == 0) { // Check if the channel is enabled + if (channels[i + j].frequency == 0) { // Check if the channel is enabled continue; } - if (val_in_range(datarate, channels[i + j].DrRange.Fields.Min, - channels[i + j].DrRange.Fields.Max) == 0) { // Check if the current channel selection supports the given datarate + if (val_in_range(datarate, channels[i + j].dr_range.fields.min, + channels[i + j].dr_range.fields.max) == 0) { // Check if the current channel selection supports the given datarate continue; } - if (bands[channels[i + j].Band].TimeOff > 0) { // Check if the band is available for transmission + if (bands[channels[i + j].band].off_time > 0) { // Check if the band is available for transmission delayTransmission++; continue; } @@ -296,7 +296,7 @@ uint8_t LoRaPHYAU915::CountNbOfEnabledChannels(uint8_t datarate, LoRaPHYAU915::LoRaPHYAU915(LoRaWANTimeHandler &lora_time) : LoRaPHY(lora_time) { - const Band_t band0 = AU915_BAND0; + const band_t band0 = AU915_BAND0; Bands[0] = band0; } @@ -430,7 +430,7 @@ PhyParam_t LoRaPHYAU915::get_phy_params(GetPhyParams_t* getPhy) void LoRaPHYAU915::set_band_tx_done(SetBandTxDoneParams_t* txDone) { - set_last_tx_done(txDone->Joined, &Bands[Channels[txDone->Channel].Band], + set_last_tx_done(txDone->Joined, &Bands[Channels[txDone->Channel].band], txDone->LastTxDoneTime); } @@ -441,17 +441,17 @@ void LoRaPHYAU915::load_defaults(InitType_t type) // Channels // 125 kHz channels for (uint8_t i = 0; i < AU915_MAX_NB_CHANNELS - 8; i++) { - Channels[i].Frequency = 915200000 + i * 200000; - Channels[i].DrRange.Value = ( DR_5 << 4) | DR_0; - Channels[i].Band = 0; + Channels[i].frequency = 915200000 + i * 200000; + Channels[i].dr_range.value = ( DR_5 << 4) | DR_0; + Channels[i].band = 0; } // 500 kHz channels for (uint8_t i = AU915_MAX_NB_CHANNELS - 8; i < AU915_MAX_NB_CHANNELS; i++) { - Channels[i].Frequency = 915900000 + Channels[i].frequency = 915900000 + (i - ( AU915_MAX_NB_CHANNELS - 8)) * 1600000; - Channels[i].DrRange.Value = ( DR_6 << 4) | DR_6; - Channels[i].Band = 0; + Channels[i].dr_range.value = ( DR_6 << 4) | DR_6; + Channels[i].band = 0; } // Initialize channels default mask @@ -611,38 +611,38 @@ bool LoRaPHYAU915::get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut, void LoRaPHYAU915::compute_rx_win_params(int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, - RxConfigParams_t *rxConfigParams) + rx_config_params_t *rxConfigParams) { double tSymbol = 0.0; // Get the datarate, perform a boundary check - rxConfigParams->Datarate = MIN(datarate, AU915_RX_MAX_DATARATE); - rxConfigParams->Bandwidth = GetBandwidth(rxConfigParams->Datarate); + rxConfigParams->datarate = MIN(datarate, AU915_RX_MAX_DATARATE); + rxConfigParams->bandwidth = GetBandwidth(rxConfigParams->datarate); tSymbol = compute_symb_timeout_lora( - DataratesAU915[rxConfigParams->Datarate], - BandwidthsAU915[rxConfigParams->Datarate]); + DataratesAU915[rxConfigParams->datarate], + BandwidthsAU915[rxConfigParams->datarate]); get_rx_window_params(tSymbol, minRxSymbols, rxError, RADIO_WAKEUP_TIME, - &rxConfigParams->WindowTimeout, - &rxConfigParams->WindowOffset); + &rxConfigParams->window_timeout, + &rxConfigParams->window_offset); } -bool LoRaPHYAU915::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) +bool LoRaPHYAU915::rx_config(rx_config_params_t* rxConfig, int8_t* datarate) { - int8_t dr = rxConfig->Datarate; + int8_t dr = rxConfig->datarate; uint8_t maxPayload = 0; int8_t phyDr = 0; - uint32_t frequency = rxConfig->Frequency; + uint32_t frequency = rxConfig->frequency; if (_radio->get_status() != RF_IDLE) { return false; } - if (rxConfig->RxSlot == RX_SLOT_WIN_1) { + if (rxConfig->rx_slot == RX_SLOT_WIN_1) { // Apply window 1 frequency frequency = AU915_FIRST_RX1_CHANNEL - + (rxConfig->Channel % 8) * AU915_STEPWIDTH_RX1_CHANNEL; + + (rxConfig->channel % 8) * AU915_STEPWIDTH_RX1_CHANNEL; } // Read the physical datarate from the datarates table @@ -651,11 +651,11 @@ bool LoRaPHYAU915::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) _radio->set_channel(frequency); // Radio configuration - _radio->set_rx_config(MODEM_LORA, rxConfig->Bandwidth, phyDr, 1, 0, 8, - rxConfig->WindowTimeout, false, 0, false, 0, 0, true, - rxConfig->RxContinuous); + _radio->set_rx_config(MODEM_LORA, rxConfig->bandwidth, phyDr, 1, 0, 8, + rxConfig->window_timeout, false, 0, false, 0, 0, true, + rxConfig->is_rx_continuous); - if (rxConfig->RepeaterSupport == true) { + if (rxConfig->is_repeater_supported == true) { maxPayload = MaxPayloadOfDatarateRepeaterAU915[dr]; } else { maxPayload = MaxPayloadOfDatarateAU915[dr]; @@ -668,12 +668,12 @@ bool LoRaPHYAU915::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) } bool LoRaPHYAU915::tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - TimerTime_t* txTimeOnAir) + lorawan_time_t* txTimeOnAir) { int8_t phyDr = DataratesAU915[txConfig->Datarate]; int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, - Bands[Channels[txConfig->Channel].Band].TxMaxPower, + Bands[Channels[txConfig->Channel].band].max_tx_pwr, txConfig->Datarate, ChannelsMask); uint32_t bandwidth = GetBandwidth(txConfig->Datarate); int8_t phyTxPower = 0; @@ -683,7 +683,7 @@ bool LoRaPHYAU915::tx_config(TxConfigParams_t* txConfig, int8_t* txPower, txConfig->AntennaGain); // Setup the radio frequency - _radio->set_channel(Channels[txConfig->Channel].Frequency); + _radio->set_channel(Channels[txConfig->Channel].frequency); _radio->set_tx_config(MODEM_LORA, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 3000); @@ -885,13 +885,13 @@ void LoRaPHYAU915::calculate_backoff(CalcBackOffParams_t* calcBackOff) } bool LoRaPHYAU915::set_next_channel(NextChanParams_t* nextChanParams, - uint8_t* channel, TimerTime_t* time, - TimerTime_t* aggregatedTimeOff) + uint8_t* channel, lorawan_time_t* time, + lorawan_time_t* aggregatedTimeOff) { uint8_t nbEnabledChannels = 0; uint8_t delayTx = 0; uint8_t enabledChannels[AU915_MAX_NB_CHANNELS] = { 0 }; - TimerTime_t nextTxDelay = 0; + lorawan_time_t nextTxDelay = 0; // Count 125kHz channels if (num_active_channels(ChannelsMaskRemaining, 0, 4) == 0) { // Reactivate default channels @@ -946,24 +946,24 @@ bool LoRaPHYAU915::set_next_channel(NextChanParams_t* nextChanParams, } } -LoRaMacStatus_t LoRaPHYAU915::add_channel(ChannelAddParams_t* channelAdd) +lorawan_status_t LoRaPHYAU915::add_channel(ChannelAddParams_t* channelAdd) { - return LORAMAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } bool LoRaPHYAU915::remove_channel(ChannelRemoveParams_t* channelRemove) { - return LORAMAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } void LoRaPHYAU915::set_tx_cont_mode(ContinuousWaveParams_t* continuousWave) { int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, - Bands[Channels[continuousWave->Channel].Band].TxMaxPower, + Bands[Channels[continuousWave->Channel].band].max_tx_pwr, continuousWave->Datarate, ChannelsMask); int8_t phyTxPower = 0; - uint32_t frequency = Channels[continuousWave->Channel].Frequency; + uint32_t frequency = Channels[continuousWave->Channel].frequency; // Calculate physical TX power phyTxPower = compute_tx_power(txPowerLimited, continuousWave->MaxEirp, diff --git a/features/lorawan/lorastack/phy/LoRaPHYAU915.h b/features/lorawan/lorastack/phy/LoRaPHYAU915.h index ae8ff3b39f..bc26d2ee10 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYAU915.h +++ b/features/lorawan/lorastack/phy/LoRaPHYAU915.h @@ -133,7 +133,7 @@ public: * * \retval True, if the configuration was applied successfully. */ - virtual bool rx_config(RxConfigParams_t* rxConfig, int8_t* datarate ); + virtual bool rx_config(rx_config_params_t* rxConfig, int8_t* datarate ); /* * RX window precise timing @@ -189,7 +189,7 @@ public: virtual void compute_rx_win_params(int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, - RxConfigParams_t *rxConfigParams); + rx_config_params_t *rxConfigParams); /*! * \brief TX configuration. @@ -203,7 +203,7 @@ public: * \retval True, if the configuration was applied successfully. */ virtual bool tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - TimerTime_t* txTimeOnAir ); + lorawan_time_t* txTimeOnAir ); /*! * \brief The function processes a Link ADR Request. @@ -294,8 +294,8 @@ public: * \retval The function status [1: OK, 0: Unable to find a channel on the current datarate]. */ virtual bool set_next_channel(NextChanParams_t* nextChanParams, - uint8_t* channel, TimerTime_t* time, - TimerTime_t* aggregatedTimeOff ); + uint8_t* channel, lorawan_time_t* time, + lorawan_time_t* aggregatedTimeOff ); /*! * \brief Adds a channel. @@ -304,7 +304,7 @@ public: * * \retval The status of the operation. */ - virtual LoRaMacStatus_t add_channel(ChannelAddParams_t* channelAdd ); + virtual lorawan_status_t add_channel(ChannelAddParams_t* channelAdd ); /*! * \brief Removes a channel. @@ -338,8 +338,8 @@ public: private: uint8_t CountNbOfEnabledChannels(uint8_t datarate, uint16_t* channelsMask, - ChannelParams_t* channels, - Band_t* bands, uint8_t* enabledChannels, + channel_params_t* channels, + band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx); @@ -347,12 +347,12 @@ private: /*! * LoRaMAC channels */ - ChannelParams_t Channels[AU915_MAX_NB_CHANNELS]; + channel_params_t Channels[AU915_MAX_NB_CHANNELS]; /*! * LoRaMac bands */ - Band_t Bands[AU915_MAX_NB_BANDS]; + band_t Bands[AU915_MAX_NB_BANDS]; /*! * LoRaMac channels mask diff --git a/features/lorawan/lorastack/phy/LoRaPHYCN470.cpp b/features/lorawan/lorastack/phy/LoRaPHYCN470.cpp index 55918d2957..4be2cf8562 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYCN470.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYCN470.cpp @@ -245,7 +245,7 @@ static int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower, int8_t datara return txPowerResult; } -uint8_t LoRaPHYCN470::CountNbOfEnabledChannels( uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ) +uint8_t LoRaPHYCN470::CountNbOfEnabledChannels( uint8_t datarate, uint16_t* channelsMask, channel_params_t* channels, band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ) { uint8_t nbEnabledChannels = 0; uint8_t delayTransmission = 0; @@ -256,16 +256,16 @@ uint8_t LoRaPHYCN470::CountNbOfEnabledChannels( uint8_t datarate, uint16_t* chan { if( ( channelsMask[k] & ( 1 << j ) ) != 0 ) { - if( channels[i + j].Frequency == 0 ) + if( channels[i + j].frequency == 0 ) { // Check if the channel is enabled continue; } - if( val_in_range( datarate, channels[i + j].DrRange.Fields.Min, - channels[i + j].DrRange.Fields.Max ) == 0 ) + if( val_in_range( datarate, channels[i + j].dr_range.fields.min, + channels[i + j].dr_range.fields.max ) == 0 ) { // Check if the current channel selection supports the given datarate continue; } - if( bands[channels[i + j].Band].TimeOff > 0 ) + if( bands[channels[i + j].band].off_time > 0 ) { // Check if the band is available for transmission delayTransmission++; continue; @@ -282,7 +282,7 @@ uint8_t LoRaPHYCN470::CountNbOfEnabledChannels( uint8_t datarate, uint16_t* chan LoRaPHYCN470::LoRaPHYCN470(LoRaWANTimeHandler &lora_time) : LoRaPHY(lora_time) { - const Band_t band0 = CN470_BAND0; + const band_t band0 = CN470_BAND0; Bands[0] = band0; } @@ -439,7 +439,7 @@ PhyParam_t LoRaPHYCN470::get_phy_params(GetPhyParams_t* getPhy) void LoRaPHYCN470::set_band_tx_done(SetBandTxDoneParams_t* txDone) { - set_last_tx_done( txDone->Joined, &Bands[Channels[txDone->Channel].Band], txDone->LastTxDoneTime ); + set_last_tx_done( txDone->Joined, &Bands[Channels[txDone->Channel].band], txDone->LastTxDoneTime ); } void LoRaPHYCN470::load_defaults(InitType_t type) @@ -452,9 +452,9 @@ void LoRaPHYCN470::load_defaults(InitType_t type) // 125 kHz channels for( uint8_t i = 0; i < CN470_MAX_NB_CHANNELS; i++ ) { - Channels[i].Frequency = 470300000 + i * 200000; - Channels[i].DrRange.Value = ( DR_5 << 4 ) | DR_0; - Channels[i].Band = 0; + Channels[i].frequency = 470300000 + i * 200000; + Channels[i].dr_range.value = ( DR_5 << 4 ) | DR_0; + Channels[i].band = 0; } // Initialize the channels default mask @@ -612,35 +612,35 @@ bool LoRaPHYCN470::get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut, void LoRaPHYCN470::compute_rx_win_params(int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, - RxConfigParams_t *rxConfigParams) + rx_config_params_t *rxConfigParams) { double tSymbol = 0.0; // Get the datarate, perform a boundary check - rxConfigParams->Datarate = MIN( datarate, CN470_RX_MAX_DATARATE ); - rxConfigParams->Bandwidth = GetBandwidth( rxConfigParams->Datarate ); + rxConfigParams->datarate = MIN( datarate, CN470_RX_MAX_DATARATE ); + rxConfigParams->bandwidth = GetBandwidth( rxConfigParams->datarate ); - tSymbol = compute_symb_timeout_lora( DataratesCN470[rxConfigParams->Datarate], BandwidthsCN470[rxConfigParams->Datarate] ); + tSymbol = compute_symb_timeout_lora( DataratesCN470[rxConfigParams->datarate], BandwidthsCN470[rxConfigParams->datarate] ); - get_rx_window_params( tSymbol, minRxSymbols, rxError, RADIO_WAKEUP_TIME, &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); + get_rx_window_params( tSymbol, minRxSymbols, rxError, RADIO_WAKEUP_TIME, &rxConfigParams->window_timeout, &rxConfigParams->window_offset ); } -bool LoRaPHYCN470::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) +bool LoRaPHYCN470::rx_config(rx_config_params_t* rxConfig, int8_t* datarate) { - int8_t dr = rxConfig->Datarate; + int8_t dr = rxConfig->datarate; uint8_t maxPayload = 0; int8_t phyDr = 0; - uint32_t frequency = rxConfig->Frequency; + uint32_t frequency = rxConfig->frequency; if(_radio->get_status() != RF_IDLE ) { return false; } - if( rxConfig->RxSlot == RX_SLOT_WIN_1 ) + if( rxConfig->rx_slot == RX_SLOT_WIN_1 ) { // Apply window 1 frequency - frequency = CN470_FIRST_RX1_CHANNEL + ( rxConfig->Channel % 48 ) * CN470_STEPWIDTH_RX1_CHANNEL; + frequency = CN470_FIRST_RX1_CHANNEL + ( rxConfig->channel % 48 ) * CN470_STEPWIDTH_RX1_CHANNEL; } // Read the physical datarate from the datarates table @@ -649,11 +649,11 @@ bool LoRaPHYCN470::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) _radio->set_channel(frequency); // Radio configuration - _radio->set_rx_config(MODEM_LORA, rxConfig->Bandwidth, phyDr, 1, 0, 8, - rxConfig->WindowTimeout, false, 0, false, 0, 0, true, - rxConfig->RxContinuous); + _radio->set_rx_config(MODEM_LORA, rxConfig->bandwidth, phyDr, 1, 0, 8, + rxConfig->window_timeout, false, 0, false, 0, 0, true, + rxConfig->is_rx_continuous); - if( rxConfig->RepeaterSupport == true ) + if( rxConfig->is_repeater_supported == true ) { maxPayload = MaxPayloadOfDatarateRepeaterCN470[dr]; } @@ -668,17 +668,17 @@ bool LoRaPHYCN470::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) } bool LoRaPHYCN470::tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - TimerTime_t* txTimeOnAir) + lorawan_time_t* txTimeOnAir) { int8_t phyDr = DataratesCN470[txConfig->Datarate]; - int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, Bands[Channels[txConfig->Channel].Band].TxMaxPower, txConfig->Datarate, ChannelsMask ); + int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, Bands[Channels[txConfig->Channel].band].max_tx_pwr, txConfig->Datarate, ChannelsMask ); int8_t phyTxPower = 0; // Calculate physical TX power phyTxPower = compute_tx_power( txPowerLimited, txConfig->MaxEirp, txConfig->AntennaGain ); // Setup the radio frequency - _radio->set_channel(Channels[txConfig->Channel].Frequency); + _radio->set_channel(Channels[txConfig->Channel].frequency); _radio->set_tx_config(MODEM_LORA, phyTxPower, 0, 0, phyDr, 1, 8, false, true, 0, 0, false, 3000); @@ -740,7 +740,7 @@ uint8_t LoRaPHYCN470::link_ADR_request(LinkAdrReqParams_t* linkAdrReq, for( uint8_t i = 0; i < 16; i++ ) { if( ( ( linkAdrParams.ChMask & ( 1 << i ) ) != 0 ) && - ( Channels[linkAdrParams.ChMaskCtrl * 16 + i].Frequency == 0 ) ) + ( Channels[linkAdrParams.ChMaskCtrl * 16 + i].frequency == 0 ) ) {// Trying to enable an undefined channel status &= 0xFE; // Channel mask KO } @@ -882,13 +882,13 @@ void LoRaPHYCN470::calculate_backoff(CalcBackOffParams_t* calcBackOff) } bool LoRaPHYCN470::set_next_channel(NextChanParams_t* nextChanParams, - uint8_t* channel, TimerTime_t* time, - TimerTime_t* aggregatedTimeOff) + uint8_t* channel, lorawan_time_t* time, + lorawan_time_t* aggregatedTimeOff) { uint8_t nbEnabledChannels = 0; uint8_t delayTx = 0; uint8_t enabledChannels[CN470_MAX_NB_CHANNELS] = { 0 }; - TimerTime_t nextTxDelay = 0; + lorawan_time_t nextTxDelay = 0; // Count 125kHz channels if( num_active_channels( ChannelsMask, 0, 6 ) == 0 ) @@ -942,21 +942,21 @@ bool LoRaPHYCN470::set_next_channel(NextChanParams_t* nextChanParams, } } -LoRaMacStatus_t LoRaPHYCN470::add_channel(ChannelAddParams_t* channelAdd) +lorawan_status_t LoRaPHYCN470::add_channel(ChannelAddParams_t* channelAdd) { - return LORAMAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } bool LoRaPHYCN470::remove_channel(ChannelRemoveParams_t* channelRemove) { - return LORAMAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } void LoRaPHYCN470::set_tx_cont_mode(ContinuousWaveParams_t* continuousWave) { - int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, Bands[Channels[continuousWave->Channel].Band].TxMaxPower, continuousWave->Datarate, ChannelsMask ); + int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, Bands[Channels[continuousWave->Channel].band].max_tx_pwr, continuousWave->Datarate, ChannelsMask ); int8_t phyTxPower = 0; - uint32_t frequency = Channels[continuousWave->Channel].Frequency; + uint32_t frequency = Channels[continuousWave->Channel].frequency; // Calculate physical TX power phyTxPower = compute_tx_power( txPowerLimited, continuousWave->MaxEirp, continuousWave->AntennaGain ); diff --git a/features/lorawan/lorastack/phy/LoRaPHYCN470.h b/features/lorawan/lorastack/phy/LoRaPHYCN470.h index 8f7f917f94..a7dfa574c6 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYCN470.h +++ b/features/lorawan/lorastack/phy/LoRaPHYCN470.h @@ -133,7 +133,7 @@ public: * * \retval True, if the configuration was applied successfully. */ - virtual bool rx_config(RxConfigParams_t* rxConfig, int8_t* datarate ); + virtual bool rx_config(rx_config_params_t* rxConfig, int8_t* datarate ); /* * RX window precise timing @@ -189,7 +189,7 @@ public: virtual void compute_rx_win_params(int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, - RxConfigParams_t *rxConfigParams); + rx_config_params_t *rxConfigParams); /*! * \brief TX configuration. @@ -203,7 +203,7 @@ public: * \retval True, if the configuration was applied successfully. */ virtual bool tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - TimerTime_t* txTimeOnAir ); + lorawan_time_t* txTimeOnAir ); /*! * \brief The function processes a Link ADR request. @@ -294,8 +294,8 @@ public: * \retval Function status [1: OK, 0: Unable to find a channel on the current datarate]. */ virtual bool set_next_channel(NextChanParams_t* nextChanParams, - uint8_t* channel, TimerTime_t* time, - TimerTime_t* aggregatedTimeOff ); + uint8_t* channel, lorawan_time_t* time, + lorawan_time_t* aggregatedTimeOff ); /*! * \brief Adds a channel. @@ -304,7 +304,7 @@ public: * * \retval The status of the operation. */ - virtual LoRaMacStatus_t add_channel(ChannelAddParams_t* channelAdd ); + virtual lorawan_status_t add_channel(ChannelAddParams_t* channelAdd ); /*! * \brief Removes a channel. @@ -336,7 +336,7 @@ public: virtual uint8_t apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ); private: - uint8_t CountNbOfEnabledChannels( uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ); + uint8_t CountNbOfEnabledChannels( uint8_t datarate, uint16_t* channelsMask, channel_params_t* channels, band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ); bool RegionCN470ChanMaskSet( ChanMaskSetParams_t* chanMaskSet ); @@ -344,12 +344,12 @@ private: /*! * LoRaMAC channels */ - ChannelParams_t Channels[CN470_MAX_NB_CHANNELS]; + channel_params_t Channels[CN470_MAX_NB_CHANNELS]; /*! * LoRaMac bands */ - Band_t Bands[CN470_MAX_NB_BANDS]; + band_t Bands[CN470_MAX_NB_BANDS]; /*! * LoRaMac channels mask diff --git a/features/lorawan/lorastack/phy/LoRaPHYCN779.cpp b/features/lorawan/lorastack/phy/LoRaPHYCN779.cpp index da754c4f84..ce693451b8 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYCN779.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYCN779.cpp @@ -285,7 +285,7 @@ static bool VerifyTxFreq( uint32_t freq, LoRaRadio *radio) return true; } -uint8_t LoRaPHYCN779::CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ) +uint8_t LoRaPHYCN779::CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, channel_params_t* channels, band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ) { uint8_t nbEnabledChannels = 0; uint8_t delayTransmission = 0; @@ -296,7 +296,7 @@ uint8_t LoRaPHYCN779::CountNbOfEnabledChannels( bool joined, uint8_t datarate, u { if( ( channelsMask[k] & ( 1 << j ) ) != 0 ) { - if( channels[i + j].Frequency == 0 ) + if( channels[i + j].frequency == 0 ) { // Check if the channel is enabled continue; } @@ -307,12 +307,12 @@ uint8_t LoRaPHYCN779::CountNbOfEnabledChannels( bool joined, uint8_t datarate, u continue; } } - if( val_in_range( datarate, channels[i + j].DrRange.Fields.Min, - channels[i + j].DrRange.Fields.Max ) == 0 ) + if( val_in_range( datarate, channels[i + j].dr_range.fields.min, + channels[i + j].dr_range.fields.max ) == 0 ) { // Check if the current channel selection supports the given datarate continue; } - if( bands[channels[i + j].Band].TimeOff > 0 ) + if( bands[channels[i + j].band].off_time > 0 ) { // Check if the band is available for transmission delayTransmission++; continue; @@ -329,7 +329,7 @@ uint8_t LoRaPHYCN779::CountNbOfEnabledChannels( bool joined, uint8_t datarate, u LoRaPHYCN779::LoRaPHYCN779(LoRaWANTimeHandler &lora_time) : LoRaPHY(lora_time) { - const Band_t band0 = CN779_BAND0; + const band_t band0 = CN779_BAND0; Bands[0] = band0; } @@ -486,7 +486,7 @@ PhyParam_t LoRaPHYCN779::get_phy_params(GetPhyParams_t* getPhy) void LoRaPHYCN779::set_band_tx_done(SetBandTxDoneParams_t* txDone) { - set_last_tx_done( txDone->Joined, &Bands[Channels[txDone->Channel].Band], txDone->LastTxDoneTime ); + set_last_tx_done( txDone->Joined, &Bands[Channels[txDone->Channel].band], txDone->LastTxDoneTime ); } void LoRaPHYCN779::load_defaults(InitType_t type) @@ -496,9 +496,9 @@ void LoRaPHYCN779::load_defaults(InitType_t type) case INIT_TYPE_INIT: { // Channels - const ChannelParams_t channel1 = CN779_LC1; - const ChannelParams_t channel2 = CN779_LC2; - const ChannelParams_t channel3 = CN779_LC3; + const channel_params_t channel1 = CN779_LC1; + const channel_params_t channel2 = CN779_LC2; + const channel_params_t channel3 = CN779_LC3; Channels[0] = channel1; Channels[1] = channel2; Channels[2] = channel3; @@ -564,12 +564,12 @@ bool LoRaPHYCN779::verify(VerifyParams_t* verify, PhyAttribute_t phyAttribute) void LoRaPHYCN779::apply_cf_list(ApplyCFListParams_t* applyCFList) { - ChannelParams_t newChannel; + channel_params_t newChannel; ChannelAddParams_t channelAdd; ChannelRemoveParams_t channelRemove; // Setup default datarate range - newChannel.DrRange.Value = ( DR_5 << 4 ) | DR_0; + newChannel.dr_range.value = ( DR_5 << 4 ) | DR_0; // Size of the optional CF list if( applyCFList->Size != 16 ) @@ -583,22 +583,22 @@ void LoRaPHYCN779::apply_cf_list(ApplyCFListParams_t* applyCFList) if( chanIdx < ( CN779_NUMB_CHANNELS_CF_LIST + CN779_NUMB_DEFAULT_CHANNELS ) ) { // Channel frequency - newChannel.Frequency = (uint32_t) applyCFList->Payload[i]; - newChannel.Frequency |= ( (uint32_t) applyCFList->Payload[i + 1] << 8 ); - newChannel.Frequency |= ( (uint32_t) applyCFList->Payload[i + 2] << 16 ); - newChannel.Frequency *= 100; + newChannel.frequency = (uint32_t) applyCFList->Payload[i]; + newChannel.frequency |= ( (uint32_t) applyCFList->Payload[i + 1] << 8 ); + newChannel.frequency |= ( (uint32_t) applyCFList->Payload[i + 2] << 16 ); + newChannel.frequency *= 100; // Initialize alternative frequency to 0 - newChannel.Rx1Frequency = 0; + newChannel.rx1_frequency = 0; } else { - newChannel.Frequency = 0; - newChannel.DrRange.Value = 0; - newChannel.Rx1Frequency = 0; + newChannel.frequency = 0; + newChannel.dr_range.value = 0; + newChannel.rx1_frequency = 0; } - if( newChannel.Frequency != 0 ) + if( newChannel.frequency != 0 ) { channelAdd.NewChannel = &newChannel; channelAdd.ChannelId = chanIdx; @@ -698,47 +698,47 @@ bool LoRaPHYCN779::get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut, void LoRaPHYCN779::compute_rx_win_params(int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, - RxConfigParams_t *rxConfigParams) + rx_config_params_t *rxConfigParams) { double tSymbol = 0.0; // Get the datarate, perform a boundary check - rxConfigParams->Datarate = MIN( datarate, CN779_RX_MAX_DATARATE ); - rxConfigParams->Bandwidth = GetBandwidth( rxConfigParams->Datarate ); + rxConfigParams->datarate = MIN( datarate, CN779_RX_MAX_DATARATE ); + rxConfigParams->bandwidth = GetBandwidth( rxConfigParams->datarate ); - if( rxConfigParams->Datarate == DR_7 ) + if( rxConfigParams->datarate == DR_7 ) { // FSK - tSymbol = compute_symb_timeout_fsk( DataratesCN779[rxConfigParams->Datarate] ); + tSymbol = compute_symb_timeout_fsk( DataratesCN779[rxConfigParams->datarate] ); } else { // LoRa - tSymbol = compute_symb_timeout_lora( DataratesCN779[rxConfigParams->Datarate], BandwidthsCN779[rxConfigParams->Datarate] ); + tSymbol = compute_symb_timeout_lora( DataratesCN779[rxConfigParams->datarate], BandwidthsCN779[rxConfigParams->datarate] ); } - get_rx_window_params( tSymbol, minRxSymbols, rxError, RADIO_WAKEUP_TIME, &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); + get_rx_window_params( tSymbol, minRxSymbols, rxError, RADIO_WAKEUP_TIME, &rxConfigParams->window_timeout, &rxConfigParams->window_offset ); } -bool LoRaPHYCN779::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) +bool LoRaPHYCN779::rx_config(rx_config_params_t* rxConfig, int8_t* datarate) { radio_modems_t modem; - int8_t dr = rxConfig->Datarate; + int8_t dr = rxConfig->datarate; uint8_t maxPayload = 0; int8_t phyDr = 0; - uint32_t frequency = rxConfig->Frequency; + uint32_t frequency = rxConfig->frequency; if(_radio->get_status() != RF_IDLE ) { return false; } - if( rxConfig->RxSlot == RX_SLOT_WIN_1) + if( rxConfig->rx_slot == RX_SLOT_WIN_1) { // Apply window 1 frequency - frequency = Channels[rxConfig->Channel].Frequency; + frequency = Channels[rxConfig->channel].frequency; // Apply the alternative RX 1 window frequency, if it is available - if( Channels[rxConfig->Channel].Rx1Frequency != 0 ) + if( Channels[rxConfig->channel].rx1_frequency != 0 ) { - frequency = Channels[rxConfig->Channel].Rx1Frequency; + frequency = Channels[rxConfig->channel].rx1_frequency; } } @@ -751,15 +751,15 @@ bool LoRaPHYCN779::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) if( dr == DR_7 ) { modem = MODEM_FSK; - _radio->set_rx_config(modem, 50000, phyDr * 1000, 0, 83333, 5, rxConfig->WindowTimeout, false, 0, true, 0, 0, false, rxConfig->RxContinuous); + _radio->set_rx_config(modem, 50000, phyDr * 1000, 0, 83333, 5, rxConfig->window_timeout, false, 0, true, 0, 0, false, rxConfig->is_rx_continuous); } else { modem = MODEM_LORA; - _radio->set_rx_config(modem, rxConfig->Bandwidth, phyDr, 1, 0, 8, rxConfig->WindowTimeout, false, 0, false, 0, 0, true, rxConfig->RxContinuous); + _radio->set_rx_config(modem, rxConfig->bandwidth, phyDr, 1, 0, 8, rxConfig->window_timeout, false, 0, false, 0, 0, true, rxConfig->is_rx_continuous); } - if( rxConfig->RepeaterSupport == true ) + if( rxConfig->is_repeater_supported == true ) { maxPayload = MaxPayloadOfDatarateRepeaterCN779[dr]; } @@ -774,11 +774,11 @@ bool LoRaPHYCN779::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) } bool LoRaPHYCN779::tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - TimerTime_t* txTimeOnAir) + lorawan_time_t* txTimeOnAir) { radio_modems_t modem; int8_t phyDr = DataratesCN779[txConfig->Datarate]; - int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, Bands[Channels[txConfig->Channel].Band].TxMaxPower, txConfig->Datarate, ChannelsMask ); + int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, Bands[Channels[txConfig->Channel].band].max_tx_pwr, txConfig->Datarate, ChannelsMask ); uint32_t bandwidth = GetBandwidth( txConfig->Datarate ); int8_t phyTxPower = 0; @@ -786,7 +786,7 @@ bool LoRaPHYCN779::tx_config(TxConfigParams_t* txConfig, int8_t* txPower, phyTxPower = compute_tx_power( txPowerLimited, txConfig->MaxEirp, txConfig->AntennaGain ); // Setup the radio frequency - _radio->set_channel(Channels[txConfig->Channel].Frequency); + _radio->set_channel(Channels[txConfig->Channel].frequency); if( txConfig->Datarate == DR_7 ) { // High Speed FSK channel @@ -855,7 +855,7 @@ uint8_t LoRaPHYCN779::link_ADR_request(LinkAdrReqParams_t* linkAdrReq, { if( linkAdrParams.ChMaskCtrl == 6 ) { - if( Channels[i].Frequency != 0 ) + if( Channels[i].frequency != 0 ) { chMask |= 1 << i; } @@ -863,7 +863,7 @@ uint8_t LoRaPHYCN779::link_ADR_request(LinkAdrReqParams_t* linkAdrReq, else { if( ( ( chMask & ( 1 << i ) ) != 0 ) && - ( Channels[i].Frequency == 0 ) ) + ( Channels[i].frequency == 0 ) ) {// Trying to enable an undefined channel status &= 0xFE; // Channel mask KO } @@ -945,7 +945,7 @@ uint8_t LoRaPHYCN779::request_new_channel(NewChannelReqParams_t* newChannelReq) ChannelAddParams_t channelAdd; ChannelRemoveParams_t channelRemove; - if( newChannelReq->NewChannel->Frequency == 0 ) + if( newChannelReq->NewChannel->frequency == 0 ) { channelRemove.ChannelId = newChannelReq->ChannelId; @@ -962,21 +962,21 @@ uint8_t LoRaPHYCN779::request_new_channel(NewChannelReqParams_t* newChannelReq) switch (add_channel(&channelAdd)) { - case LORAMAC_STATUS_OK: + case LORAWAN_STATUS_OK: { break; } - case LORAMAC_STATUS_FREQUENCY_INVALID: + case LORAWAN_STATUS_FREQUENCY_INVALID: { status &= 0xFE; break; } - case LORAMAC_STATUS_DATARATE_INVALID: + case LORAWAN_STATUS_DATARATE_INVALID: { status &= 0xFD; break; } - case LORAMAC_STATUS_FREQ_AND_DR_INVALID: + case LORAWAN_STATUS_FREQ_AND_DR_INVALID: { status &= 0xFC; break; @@ -1008,7 +1008,7 @@ uint8_t LoRaPHYCN779::dl_channel_request(DlChannelReqParams_t* dlChannelReq) } // Verify if an uplink frequency exists - if( Channels[dlChannelReq->ChannelId].Frequency == 0 ) + if( Channels[dlChannelReq->ChannelId].frequency == 0 ) { status &= 0xFD; } @@ -1016,7 +1016,7 @@ uint8_t LoRaPHYCN779::dl_channel_request(DlChannelReqParams_t* dlChannelReq) // Apply Rx1 frequency, if the status is OK if( status == 0x03 ) { - Channels[dlChannelReq->ChannelId].Rx1Frequency = dlChannelReq->Rx1Frequency; + Channels[dlChannelReq->ChannelId].rx1_frequency = dlChannelReq->Rx1Frequency; } return status; @@ -1070,13 +1070,13 @@ void LoRaPHYCN779::calculate_backoff(CalcBackOffParams_t* calcBackOff) } bool LoRaPHYCN779::set_next_channel(NextChanParams_t* nextChanParams, - uint8_t* channel, TimerTime_t* time, - TimerTime_t* aggregatedTimeOff) + uint8_t* channel, lorawan_time_t* time, + lorawan_time_t* aggregatedTimeOff) { uint8_t nbEnabledChannels = 0; uint8_t delayTx = 0; uint8_t enabledChannels[CN779_MAX_NB_CHANNELS] = { 0 }; - TimerTime_t nextTxDelay = 0; + lorawan_time_t nextTxDelay = 0; if( num_active_channels( ChannelsMask, 0, 1 ) == 0 ) { // Reactivate default channels @@ -1125,7 +1125,7 @@ bool LoRaPHYCN779::set_next_channel(NextChanParams_t* nextChanParams, } } -LoRaMacStatus_t LoRaPHYCN779::add_channel(ChannelAddParams_t* channelAdd) +lorawan_status_t LoRaPHYCN779::add_channel(ChannelAddParams_t* channelAdd) { uint8_t band = 0; bool drInvalid = false; @@ -1134,19 +1134,19 @@ LoRaMacStatus_t LoRaPHYCN779::add_channel(ChannelAddParams_t* channelAdd) if( id >= CN779_MAX_NB_CHANNELS ) { - return LORAMAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } // Validate the datarate range - if( val_in_range( channelAdd->NewChannel->DrRange.Fields.Min, CN779_TX_MIN_DATARATE, CN779_TX_MAX_DATARATE ) == 0 ) + if( val_in_range( channelAdd->NewChannel->dr_range.fields.min, CN779_TX_MIN_DATARATE, CN779_TX_MAX_DATARATE ) == 0 ) { drInvalid = true; } - if( val_in_range( channelAdd->NewChannel->DrRange.Fields.Max, CN779_TX_MIN_DATARATE, CN779_TX_MAX_DATARATE ) == 0 ) + if( val_in_range( channelAdd->NewChannel->dr_range.fields.max, CN779_TX_MIN_DATARATE, CN779_TX_MAX_DATARATE ) == 0 ) { drInvalid = true; } - if( channelAdd->NewChannel->DrRange.Fields.Min > channelAdd->NewChannel->DrRange.Fields.Max ) + if( channelAdd->NewChannel->dr_range.fields.min > channelAdd->NewChannel->dr_range.fields.max ) { drInvalid = true; } @@ -1155,17 +1155,17 @@ LoRaMacStatus_t LoRaPHYCN779::add_channel(ChannelAddParams_t* channelAdd) if( id < CN779_NUMB_DEFAULT_CHANNELS ) { // Validate the datarate range for min: must be DR_0 - if( channelAdd->NewChannel->DrRange.Fields.Min > DR_0 ) + if( channelAdd->NewChannel->dr_range.fields.min > DR_0 ) { drInvalid = true; } // Validate the datarate range for max: must be DR_5 <= Max <= TX_MAX_DATARATE - if( val_in_range( channelAdd->NewChannel->DrRange.Fields.Max, DR_5, CN779_TX_MAX_DATARATE ) == 0 ) + if( val_in_range( channelAdd->NewChannel->dr_range.fields.max, DR_5, CN779_TX_MAX_DATARATE ) == 0 ) { drInvalid = true; } // We are not allowed to change the frequency - if( channelAdd->NewChannel->Frequency != Channels[id].Frequency ) + if( channelAdd->NewChannel->frequency != Channels[id].frequency ) { freqInvalid = true; } @@ -1174,7 +1174,7 @@ LoRaMacStatus_t LoRaPHYCN779::add_channel(ChannelAddParams_t* channelAdd) // Check frequency if( freqInvalid == false ) { - if( VerifyTxFreq(channelAdd->NewChannel->Frequency, _radio) == false ) + if( VerifyTxFreq(channelAdd->NewChannel->frequency, _radio) == false ) { freqInvalid = true; } @@ -1183,21 +1183,21 @@ LoRaMacStatus_t LoRaPHYCN779::add_channel(ChannelAddParams_t* channelAdd) // Check status if( ( drInvalid == true ) && ( freqInvalid == true ) ) { - return LORAMAC_STATUS_FREQ_AND_DR_INVALID; + return LORAWAN_STATUS_FREQ_AND_DR_INVALID; } if( drInvalid == true ) { - return LORAMAC_STATUS_DATARATE_INVALID; + return LORAWAN_STATUS_DATARATE_INVALID; } if( freqInvalid == true ) { - return LORAMAC_STATUS_FREQUENCY_INVALID; + return LORAWAN_STATUS_FREQUENCY_INVALID; } memcpy( &(Channels[id]), channelAdd->NewChannel, sizeof( Channels[id] ) ); - Channels[id].Band = band; + Channels[id].band = band; ChannelsMask[0] |= ( 1 << id ); - return LORAMAC_STATUS_OK; + return LORAWAN_STATUS_OK; } bool LoRaPHYCN779::remove_channel(ChannelRemoveParams_t* channelRemove) @@ -1210,7 +1210,7 @@ bool LoRaPHYCN779::remove_channel(ChannelRemoveParams_t* channelRemove) } // Remove the channel from the list of channels - const ChannelParams_t empty_channel = { 0, 0, { 0 }, 0 }; + const channel_params_t empty_channel = { 0, 0, { 0 }, 0 }; Channels[id] = empty_channel; return disable_channel( ChannelsMask, id, CN779_MAX_NB_CHANNELS ); @@ -1218,9 +1218,9 @@ bool LoRaPHYCN779::remove_channel(ChannelRemoveParams_t* channelRemove) void LoRaPHYCN779::set_tx_cont_mode(ContinuousWaveParams_t* continuousWave) { - int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, Bands[Channels[continuousWave->Channel].Band].TxMaxPower, continuousWave->Datarate, ChannelsMask ); + int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, Bands[Channels[continuousWave->Channel].band].max_tx_pwr, continuousWave->Datarate, ChannelsMask ); int8_t phyTxPower = 0; - uint32_t frequency = Channels[continuousWave->Channel].Frequency; + uint32_t frequency = Channels[continuousWave->Channel].frequency; // Calculate physical TX power phyTxPower = compute_tx_power( txPowerLimited, continuousWave->MaxEirp, continuousWave->AntennaGain ); diff --git a/features/lorawan/lorastack/phy/LoRaPHYCN779.h b/features/lorawan/lorastack/phy/LoRaPHYCN779.h index 8d7640248c..e45f2a7c4f 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYCN779.h +++ b/features/lorawan/lorastack/phy/LoRaPHYCN779.h @@ -124,7 +124,7 @@ public: * * \retval True, if the configuration was applied successfully. */ - virtual bool rx_config(RxConfigParams_t* rxConfig, int8_t* datarate ); + virtual bool rx_config(rx_config_params_t* rxConfig, int8_t* datarate ); /* * RX window precise timing @@ -180,7 +180,7 @@ public: virtual void compute_rx_win_params(int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, - RxConfigParams_t *rxConfigParams); + rx_config_params_t *rxConfigParams); /*! * \brief TX configuration. @@ -194,7 +194,7 @@ public: * \retval True, if the configuration was applied successfully. */ virtual bool tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - TimerTime_t* txTimeOnAir ); + lorawan_time_t* txTimeOnAir ); /*! * \brief The function processes a Link ADR request. @@ -285,8 +285,8 @@ public: * \retval Function status [1: OK, 0: Unable to find a channel on the current datarate]. */ virtual bool set_next_channel(NextChanParams_t* nextChanParams, - uint8_t* channel, TimerTime_t* time, - TimerTime_t* aggregatedTimeOff ); + uint8_t* channel, lorawan_time_t* time, + lorawan_time_t* aggregatedTimeOff ); /*! * \brief Adds a channel. @@ -295,7 +295,7 @@ public: * * \retval The status of the operation. */ - virtual LoRaMacStatus_t add_channel(ChannelAddParams_t* channelAdd ); + virtual lorawan_status_t add_channel(ChannelAddParams_t* channelAdd ); /*! * \brief Removes a channel. @@ -327,18 +327,18 @@ public: virtual uint8_t apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ); private: - uint8_t CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ); + uint8_t CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, channel_params_t* channels, band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ); // Global attributes /*! * LoRaMAC channels */ - ChannelParams_t Channels[CN779_MAX_NB_CHANNELS]; + channel_params_t Channels[CN779_MAX_NB_CHANNELS]; /*! * LoRaMac bands */ - Band_t Bands[CN779_MAX_NB_BANDS]; + band_t Bands[CN779_MAX_NB_BANDS]; /*! * LoRaMac channels mask diff --git a/features/lorawan/lorastack/phy/LoRaPHYEU433.cpp b/features/lorawan/lorastack/phy/LoRaPHYEU433.cpp index dbdaa85e36..ccb0c8ff1a 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYEU433.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYEU433.cpp @@ -286,7 +286,7 @@ static bool VerifyTxFreq( uint32_t freq, LoRaRadio *radio ) return true; } -uint8_t LoRaPHYEU433::CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ) +uint8_t LoRaPHYEU433::CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, channel_params_t* channels, band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ) { uint8_t nbEnabledChannels = 0; uint8_t delayTransmission = 0; @@ -297,7 +297,7 @@ uint8_t LoRaPHYEU433::CountNbOfEnabledChannels( bool joined, uint8_t datarate, u { if( ( channelsMask[k] & ( 1 << j ) ) != 0 ) { - if( channels[i + j].Frequency == 0 ) + if( channels[i + j].frequency == 0 ) { // Check if the channel is enabled continue; } @@ -308,12 +308,12 @@ uint8_t LoRaPHYEU433::CountNbOfEnabledChannels( bool joined, uint8_t datarate, u continue; } } - if( val_in_range( datarate, channels[i + j].DrRange.Fields.Min, - channels[i + j].DrRange.Fields.Max ) == 0 ) + if( val_in_range( datarate, channels[i + j].dr_range.fields.min, + channels[i + j].dr_range.fields.max ) == 0 ) { // Check if the current channel selection supports the given datarate continue; } - if( bands[channels[i + j].Band].TimeOff > 0 ) + if( bands[channels[i + j].band].off_time > 0 ) { // Check if the band is available for transmission delayTransmission++; continue; @@ -330,7 +330,7 @@ uint8_t LoRaPHYEU433::CountNbOfEnabledChannels( bool joined, uint8_t datarate, u LoRaPHYEU433::LoRaPHYEU433(LoRaWANTimeHandler &lora_time) : LoRaPHY(lora_time) { - const Band_t band0 = EU433_BAND0; + const band_t band0 = EU433_BAND0; Bands[0] = band0; } @@ -487,7 +487,7 @@ PhyParam_t LoRaPHYEU433::get_phy_params(GetPhyParams_t* getPhy) void LoRaPHYEU433::set_band_tx_done(SetBandTxDoneParams_t* txDone) { - set_last_tx_done( txDone->Joined, &Bands[Channels[txDone->Channel].Band], txDone->LastTxDoneTime ); + set_last_tx_done( txDone->Joined, &Bands[Channels[txDone->Channel].band], txDone->LastTxDoneTime ); } void LoRaPHYEU433::load_defaults(InitType_t type) @@ -497,9 +497,9 @@ void LoRaPHYEU433::load_defaults(InitType_t type) case INIT_TYPE_INIT: { // Channels - const ChannelParams_t channel1 = EU433_LC1; - const ChannelParams_t channel2 = EU433_LC2; - const ChannelParams_t channel3 = EU433_LC3; + const channel_params_t channel1 = EU433_LC1; + const channel_params_t channel2 = EU433_LC2; + const channel_params_t channel3 = EU433_LC3; Channels[0] = channel1; Channels[1] = channel2; Channels[2] = channel3; @@ -565,12 +565,12 @@ bool LoRaPHYEU433::verify(VerifyParams_t* verify, PhyAttribute_t phyAttribute) void LoRaPHYEU433::apply_cf_list(ApplyCFListParams_t* applyCFList) { - ChannelParams_t newChannel; + channel_params_t newChannel; ChannelAddParams_t channelAdd; ChannelRemoveParams_t channelRemove; // Setup default datarate range - newChannel.DrRange.Value = ( DR_5 << 4 ) | DR_0; + newChannel.dr_range.value = ( DR_5 << 4 ) | DR_0; // Size of the optional CF list if( applyCFList->Size != 16 ) @@ -584,22 +584,22 @@ void LoRaPHYEU433::apply_cf_list(ApplyCFListParams_t* applyCFList) if( chanIdx < ( EU433_NUMB_CHANNELS_CF_LIST + EU433_NUMB_DEFAULT_CHANNELS ) ) { // Channel frequency - newChannel.Frequency = (uint32_t) applyCFList->Payload[i]; - newChannel.Frequency |= ( (uint32_t) applyCFList->Payload[i + 1] << 8 ); - newChannel.Frequency |= ( (uint32_t) applyCFList->Payload[i + 2] << 16 ); - newChannel.Frequency *= 100; + newChannel.frequency = (uint32_t) applyCFList->Payload[i]; + newChannel.frequency |= ( (uint32_t) applyCFList->Payload[i + 1] << 8 ); + newChannel.frequency |= ( (uint32_t) applyCFList->Payload[i + 2] << 16 ); + newChannel.frequency *= 100; // Initialize alternative frequency to 0 - newChannel.Rx1Frequency = 0; + newChannel.rx1_frequency = 0; } else { - newChannel.Frequency = 0; - newChannel.DrRange.Value = 0; - newChannel.Rx1Frequency = 0; + newChannel.frequency = 0; + newChannel.dr_range.value = 0; + newChannel.rx1_frequency = 0; } - if( newChannel.Frequency != 0 ) + if( newChannel.frequency != 0 ) { channelAdd.NewChannel = &newChannel; channelAdd.ChannelId = chanIdx; @@ -699,47 +699,47 @@ bool LoRaPHYEU433::get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut, void LoRaPHYEU433::compute_rx_win_params(int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, - RxConfigParams_t *rxConfigParams) + rx_config_params_t *rxConfigParams) { double tSymbol = 0.0; // Get the datarate, perform a boundary check - rxConfigParams->Datarate = MIN( datarate, EU433_RX_MAX_DATARATE ); - rxConfigParams->Bandwidth = GetBandwidth( rxConfigParams->Datarate ); + rxConfigParams->datarate = MIN( datarate, EU433_RX_MAX_DATARATE ); + rxConfigParams->bandwidth = GetBandwidth( rxConfigParams->datarate ); - if( rxConfigParams->Datarate == DR_7 ) + if( rxConfigParams->datarate == DR_7 ) { // FSK - tSymbol = compute_symb_timeout_fsk( DataratesEU433[rxConfigParams->Datarate] ); + tSymbol = compute_symb_timeout_fsk( DataratesEU433[rxConfigParams->datarate] ); } else { // LoRa - tSymbol = compute_symb_timeout_lora( DataratesEU433[rxConfigParams->Datarate], BandwidthsEU433[rxConfigParams->Datarate] ); + tSymbol = compute_symb_timeout_lora( DataratesEU433[rxConfigParams->datarate], BandwidthsEU433[rxConfigParams->datarate] ); } - get_rx_window_params( tSymbol, minRxSymbols, rxError, RADIO_WAKEUP_TIME, &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); + get_rx_window_params( tSymbol, minRxSymbols, rxError, RADIO_WAKEUP_TIME, &rxConfigParams->window_timeout, &rxConfigParams->window_offset ); } -bool LoRaPHYEU433::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) +bool LoRaPHYEU433::rx_config(rx_config_params_t* rxConfig, int8_t* datarate) { radio_modems_t modem; - int8_t dr = rxConfig->Datarate; + int8_t dr = rxConfig->datarate; uint8_t maxPayload = 0; int8_t phyDr = 0; - uint32_t frequency = rxConfig->Frequency; + uint32_t frequency = rxConfig->frequency; if( _radio->get_status() != RF_IDLE ) { return false; } - if( rxConfig->RxSlot == RX_SLOT_WIN_1 ) + if( rxConfig->rx_slot == RX_SLOT_WIN_1 ) { // Apply window 1 frequency - frequency = Channels[rxConfig->Channel].Frequency; + frequency = Channels[rxConfig->channel].frequency; // Apply the alternative RX 1 window frequency, if it is available - if( Channels[rxConfig->Channel].Rx1Frequency != 0 ) + if( Channels[rxConfig->channel].rx1_frequency != 0 ) { - frequency = Channels[rxConfig->Channel].Rx1Frequency; + frequency = Channels[rxConfig->channel].rx1_frequency; } } @@ -753,18 +753,18 @@ bool LoRaPHYEU433::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) { modem = MODEM_FSK; _radio->set_rx_config( modem, 50000, phyDr * 1000, 0, 83333, 5, - rxConfig->WindowTimeout, false, 0, true, 0, 0, - false, rxConfig->RxContinuous ); + rxConfig->window_timeout, false, 0, true, 0, 0, + false, rxConfig->is_rx_continuous ); } else { modem = MODEM_LORA; - _radio->set_rx_config( modem, rxConfig->Bandwidth, phyDr, 1, 0, 8, - rxConfig->WindowTimeout, false, 0, false, 0, 0, - true, rxConfig->RxContinuous ); + _radio->set_rx_config( modem, rxConfig->bandwidth, phyDr, 1, 0, 8, + rxConfig->window_timeout, false, 0, false, 0, 0, + true, rxConfig->is_rx_continuous ); } - if( rxConfig->RepeaterSupport == true ) + if( rxConfig->is_repeater_supported == true ) { maxPayload = MaxPayloadOfDatarateRepeaterEU433[dr]; } @@ -779,11 +779,11 @@ bool LoRaPHYEU433::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) } bool LoRaPHYEU433::tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - TimerTime_t* txTimeOnAir) + lorawan_time_t* txTimeOnAir) { radio_modems_t modem; int8_t phyDr = DataratesEU433[txConfig->Datarate]; - int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, Bands[Channels[txConfig->Channel].Band].TxMaxPower, txConfig->Datarate, ChannelsMask ); + int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, Bands[Channels[txConfig->Channel].band].max_tx_pwr, txConfig->Datarate, ChannelsMask ); uint32_t bandwidth = GetBandwidth( txConfig->Datarate ); int8_t phyTxPower = 0; @@ -791,7 +791,7 @@ bool LoRaPHYEU433::tx_config(TxConfigParams_t* txConfig, int8_t* txPower, phyTxPower = compute_tx_power( txPowerLimited, txConfig->MaxEirp, txConfig->AntennaGain ); // Setup the radio frequency - _radio->set_channel( Channels[txConfig->Channel].Frequency ); + _radio->set_channel( Channels[txConfig->Channel].frequency ); if( txConfig->Datarate == DR_7 ) { // High Speed FSK channel @@ -860,7 +860,7 @@ uint8_t LoRaPHYEU433::link_ADR_request(LinkAdrReqParams_t* linkAdrReq, { if( linkAdrParams.ChMaskCtrl == 6 ) { - if( Channels[i].Frequency != 0 ) + if( Channels[i].frequency != 0 ) { chMask |= 1 << i; } @@ -868,7 +868,7 @@ uint8_t LoRaPHYEU433::link_ADR_request(LinkAdrReqParams_t* linkAdrReq, else { if( ( ( chMask & ( 1 << i ) ) != 0 ) && - ( Channels[i].Frequency == 0 ) ) + ( Channels[i].frequency == 0 ) ) {// Trying to enable an undefined channel status &= 0xFE; // Channel mask KO } @@ -950,7 +950,7 @@ uint8_t LoRaPHYEU433::request_new_channel(NewChannelReqParams_t* newChannelReq) ChannelAddParams_t channelAdd; ChannelRemoveParams_t channelRemove; - if( newChannelReq->NewChannel->Frequency == 0 ) + if( newChannelReq->NewChannel->frequency == 0 ) { channelRemove.ChannelId = newChannelReq->ChannelId; @@ -967,21 +967,21 @@ uint8_t LoRaPHYEU433::request_new_channel(NewChannelReqParams_t* newChannelReq) switch( add_channel( &channelAdd ) ) { - case LORAMAC_STATUS_OK: + case LORAWAN_STATUS_OK: { break; } - case LORAMAC_STATUS_FREQUENCY_INVALID: + case LORAWAN_STATUS_FREQUENCY_INVALID: { status &= 0xFE; break; } - case LORAMAC_STATUS_DATARATE_INVALID: + case LORAWAN_STATUS_DATARATE_INVALID: { status &= 0xFD; break; } - case LORAMAC_STATUS_FREQ_AND_DR_INVALID: + case LORAWAN_STATUS_FREQ_AND_DR_INVALID: { status &= 0xFC; break; @@ -1013,7 +1013,7 @@ uint8_t LoRaPHYEU433::dl_channel_request(DlChannelReqParams_t* dlChannelReq) } // Verify if an uplink frequency exists - if( Channels[dlChannelReq->ChannelId].Frequency == 0 ) + if( Channels[dlChannelReq->ChannelId].frequency == 0 ) { status &= 0xFD; } @@ -1021,7 +1021,7 @@ uint8_t LoRaPHYEU433::dl_channel_request(DlChannelReqParams_t* dlChannelReq) // Apply Rx1 frequency, if the status is OK if( status == 0x03 ) { - Channels[dlChannelReq->ChannelId].Rx1Frequency = dlChannelReq->Rx1Frequency; + Channels[dlChannelReq->ChannelId].rx1_frequency = dlChannelReq->Rx1Frequency; } return status; @@ -1075,13 +1075,13 @@ void LoRaPHYEU433::calculate_backoff(CalcBackOffParams_t* calcBackOff) } bool LoRaPHYEU433::set_next_channel(NextChanParams_t* nextChanParams, - uint8_t* channel, TimerTime_t* time, - TimerTime_t* aggregatedTimeOff) + uint8_t* channel, lorawan_time_t* time, + lorawan_time_t* aggregatedTimeOff) { uint8_t nbEnabledChannels = 0; uint8_t delayTx = 0; uint8_t enabledChannels[EU433_MAX_NB_CHANNELS] = { 0 }; - TimerTime_t nextTxDelay = 0; + lorawan_time_t nextTxDelay = 0; if( num_active_channels( ChannelsMask, 0, 1 ) == 0 ) { // Reactivate default channels @@ -1130,7 +1130,7 @@ bool LoRaPHYEU433::set_next_channel(NextChanParams_t* nextChanParams, } } -LoRaMacStatus_t LoRaPHYEU433::add_channel(ChannelAddParams_t* channelAdd) +lorawan_status_t LoRaPHYEU433::add_channel(ChannelAddParams_t* channelAdd) { uint8_t band = 0; bool drInvalid = false; @@ -1139,19 +1139,19 @@ LoRaMacStatus_t LoRaPHYEU433::add_channel(ChannelAddParams_t* channelAdd) if( id >= EU433_MAX_NB_CHANNELS ) { - return LORAMAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } // Validate the datarate range - if( val_in_range( channelAdd->NewChannel->DrRange.Fields.Min, EU433_TX_MIN_DATARATE, EU433_TX_MAX_DATARATE ) == 0 ) + if( val_in_range( channelAdd->NewChannel->dr_range.fields.min, EU433_TX_MIN_DATARATE, EU433_TX_MAX_DATARATE ) == 0 ) { drInvalid = true; } - if( val_in_range( channelAdd->NewChannel->DrRange.Fields.Max, EU433_TX_MIN_DATARATE, EU433_TX_MAX_DATARATE ) == 0 ) + if( val_in_range( channelAdd->NewChannel->dr_range.fields.max, EU433_TX_MIN_DATARATE, EU433_TX_MAX_DATARATE ) == 0 ) { drInvalid = true; } - if( channelAdd->NewChannel->DrRange.Fields.Min > channelAdd->NewChannel->DrRange.Fields.Max ) + if( channelAdd->NewChannel->dr_range.fields.min > channelAdd->NewChannel->dr_range.fields.max ) { drInvalid = true; } @@ -1160,17 +1160,17 @@ LoRaMacStatus_t LoRaPHYEU433::add_channel(ChannelAddParams_t* channelAdd) if( id < EU433_NUMB_DEFAULT_CHANNELS ) { // Validate the datarate range for min: must be DR_0 - if( channelAdd->NewChannel->DrRange.Fields.Min > DR_0 ) + if( channelAdd->NewChannel->dr_range.fields.min > DR_0 ) { drInvalid = true; } // Validate the datarate range for max: must be DR_5 <= Max <= TX_MAX_DATARATE - if( val_in_range( channelAdd->NewChannel->DrRange.Fields.Max, DR_5, EU433_TX_MAX_DATARATE ) == 0 ) + if( val_in_range( channelAdd->NewChannel->dr_range.fields.max, DR_5, EU433_TX_MAX_DATARATE ) == 0 ) { drInvalid = true; } // We are not allowed to change the frequency - if( channelAdd->NewChannel->Frequency != Channels[id].Frequency ) + if( channelAdd->NewChannel->frequency != Channels[id].frequency ) { freqInvalid = true; } @@ -1179,7 +1179,7 @@ LoRaMacStatus_t LoRaPHYEU433::add_channel(ChannelAddParams_t* channelAdd) // Check frequency if( freqInvalid == false ) { - if( VerifyTxFreq( channelAdd->NewChannel->Frequency, _radio ) == false ) + if( VerifyTxFreq( channelAdd->NewChannel->frequency, _radio ) == false ) { freqInvalid = true; } @@ -1188,21 +1188,21 @@ LoRaMacStatus_t LoRaPHYEU433::add_channel(ChannelAddParams_t* channelAdd) // Check status if( ( drInvalid == true ) && ( freqInvalid == true ) ) { - return LORAMAC_STATUS_FREQ_AND_DR_INVALID; + return LORAWAN_STATUS_FREQ_AND_DR_INVALID; } if( drInvalid == true ) { - return LORAMAC_STATUS_DATARATE_INVALID; + return LORAWAN_STATUS_DATARATE_INVALID; } if( freqInvalid == true ) { - return LORAMAC_STATUS_FREQUENCY_INVALID; + return LORAWAN_STATUS_FREQUENCY_INVALID; } memcpy( &(Channels[id]), channelAdd->NewChannel, sizeof( Channels[id] ) ); - Channels[id].Band = band; + Channels[id].band = band; ChannelsMask[0] |= ( 1 << id ); - return LORAMAC_STATUS_OK; + return LORAWAN_STATUS_OK; } bool LoRaPHYEU433::remove_channel(ChannelRemoveParams_t* channelRemove) @@ -1215,7 +1215,7 @@ bool LoRaPHYEU433::remove_channel(ChannelRemoveParams_t* channelRemove) } // Remove the channel from the list of channels - const ChannelParams_t empty_channel = { 0, 0, { 0 }, 0 }; + const channel_params_t empty_channel = { 0, 0, { 0 }, 0 }; Channels[id] = empty_channel; return disable_channel( ChannelsMask, id, EU433_MAX_NB_CHANNELS ); @@ -1223,9 +1223,9 @@ bool LoRaPHYEU433::remove_channel(ChannelRemoveParams_t* channelRemove) void LoRaPHYEU433::set_tx_cont_mode(ContinuousWaveParams_t* continuousWave) { - int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, Bands[Channels[continuousWave->Channel].Band].TxMaxPower, continuousWave->Datarate, ChannelsMask ); + int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, Bands[Channels[continuousWave->Channel].band].max_tx_pwr, continuousWave->Datarate, ChannelsMask ); int8_t phyTxPower = 0; - uint32_t frequency = Channels[continuousWave->Channel].Frequency; + uint32_t frequency = Channels[continuousWave->Channel].frequency; // Calculate physical TX power phyTxPower = compute_tx_power( txPowerLimited, continuousWave->MaxEirp, continuousWave->AntennaGain ); diff --git a/features/lorawan/lorastack/phy/LoRaPHYEU433.h b/features/lorawan/lorastack/phy/LoRaPHYEU433.h index 27e5735821..6b5868ee77 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYEU433.h +++ b/features/lorawan/lorastack/phy/LoRaPHYEU433.h @@ -130,7 +130,7 @@ public: * * \retval True, if the configuration was applied successfully. */ - virtual bool rx_config(RxConfigParams_t* rxConfig, int8_t* datarate ); + virtual bool rx_config(rx_config_params_t* rxConfig, int8_t* datarate ); /* * RX window precise timing @@ -186,7 +186,7 @@ public: virtual void compute_rx_win_params(int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, - RxConfigParams_t *rxConfigParams); + rx_config_params_t *rxConfigParams); /*! * \brief TX configuration. @@ -200,7 +200,7 @@ public: * \retval True, if the configuration was applied successfully. */ virtual bool tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - TimerTime_t* txTimeOnAir ); + lorawan_time_t* txTimeOnAir ); /*! * \brief The function processes a Link ADR request. @@ -291,8 +291,8 @@ public: * \retval Function status [1: OK, 0: Unable to find a channel on the current datarate]. */ virtual bool set_next_channel(NextChanParams_t* nextChanParams, - uint8_t* channel, TimerTime_t* time, - TimerTime_t* aggregatedTimeOff ); + uint8_t* channel, lorawan_time_t* time, + lorawan_time_t* aggregatedTimeOff ); /*! * \brief Adds a channel. @@ -301,7 +301,7 @@ public: * * \retval The status of the operation. */ - virtual LoRaMacStatus_t add_channel(ChannelAddParams_t* channelAdd ); + virtual lorawan_status_t add_channel(ChannelAddParams_t* channelAdd ); /*! * \brief Removes a channel. @@ -333,18 +333,18 @@ public: virtual uint8_t apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ); private: - uint8_t CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ); + uint8_t CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, channel_params_t* channels, band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ); // Global attributes /*! * LoRaMAC channels */ - ChannelParams_t Channels[EU433_MAX_NB_CHANNELS]; + channel_params_t Channels[EU433_MAX_NB_CHANNELS]; /*! * LoRaMac bands */ - Band_t Bands[EU433_MAX_NB_BANDS]; + band_t Bands[EU433_MAX_NB_BANDS]; /*! * LoRaMac channels mask diff --git a/features/lorawan/lorastack/phy/LoRaPHYEU868.cpp b/features/lorawan/lorastack/phy/LoRaPHYEU868.cpp index 812f7abc8f..5ee3585270 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYEU868.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYEU868.cpp @@ -331,7 +331,7 @@ static bool VerifyTxFreq( uint32_t freq, uint8_t *band, LoRaRadio *radio ) return true; } -uint8_t LoRaPHYEU868::CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ) +uint8_t LoRaPHYEU868::CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, channel_params_t* channels, band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ) { uint8_t nbEnabledChannels = 0; uint8_t delayTransmission = 0; @@ -342,7 +342,7 @@ uint8_t LoRaPHYEU868::CountNbOfEnabledChannels( bool joined, uint8_t datarate, u { if( ( channelsMask[k] & ( 1 << j ) ) != 0 ) { - if( channels[i + j].Frequency == 0 ) + if( channels[i + j].frequency == 0 ) { // Check if the channel is enabled continue; } @@ -353,12 +353,12 @@ uint8_t LoRaPHYEU868::CountNbOfEnabledChannels( bool joined, uint8_t datarate, u continue; } } - if( val_in_range( datarate, channels[i + j].DrRange.Fields.Min, - channels[i + j].DrRange.Fields.Max ) == 0 ) + if( val_in_range( datarate, channels[i + j].dr_range.fields.min, + channels[i + j].dr_range.fields.max ) == 0 ) { // Check if the current channel selection supports the given datarate continue; } - if( bands[channels[i + j].Band].TimeOff > 0 ) + if( bands[channels[i + j].band].off_time > 0 ) { // Check if the band is available for transmission delayTransmission++; continue; @@ -375,11 +375,11 @@ uint8_t LoRaPHYEU868::CountNbOfEnabledChannels( bool joined, uint8_t datarate, u LoRaPHYEU868::LoRaPHYEU868(LoRaWANTimeHandler &lora_time) : LoRaPHY(lora_time) { - const Band_t band0 = EU868_BAND0; - const Band_t band1 = EU868_BAND1; - const Band_t band2 = EU868_BAND2; - const Band_t band3 = EU868_BAND3; - const Band_t band4 = EU868_BAND4; + const band_t band0 = EU868_BAND0; + const band_t band1 = EU868_BAND1; + const band_t band2 = EU868_BAND2; + const band_t band3 = EU868_BAND3; + const band_t band4 = EU868_BAND4; Bands[0] = band0; Bands[1] = band1; @@ -541,7 +541,7 @@ PhyParam_t LoRaPHYEU868::get_phy_params(GetPhyParams_t* getPhy) void LoRaPHYEU868::set_band_tx_done(SetBandTxDoneParams_t* txDone) { - set_last_tx_done( txDone->Joined, &Bands[Channels[txDone->Channel].Band], txDone->LastTxDoneTime ); + set_last_tx_done( txDone->Joined, &Bands[Channels[txDone->Channel].band], txDone->LastTxDoneTime ); } void LoRaPHYEU868::load_defaults(InitType_t type) @@ -551,9 +551,9 @@ void LoRaPHYEU868::load_defaults(InitType_t type) case INIT_TYPE_INIT: { // Channels - const ChannelParams_t channel1 = EU868_LC1; - const ChannelParams_t channel2 = EU868_LC2; - const ChannelParams_t channel3 = EU868_LC3; + const channel_params_t channel1 = EU868_LC1; + const channel_params_t channel2 = EU868_LC2; + const channel_params_t channel3 = EU868_LC3; Channels[0] = channel1; Channels[1] = channel2; Channels[2] = channel3; @@ -619,12 +619,12 @@ bool LoRaPHYEU868::verify(VerifyParams_t* verify, PhyAttribute_t phyAttribute) void LoRaPHYEU868::apply_cf_list(ApplyCFListParams_t* applyCFList) { - ChannelParams_t newChannel; + channel_params_t newChannel; ChannelAddParams_t channelAdd; ChannelRemoveParams_t channelRemove; // Setup default datarate range - newChannel.DrRange.Value = ( DR_5 << 4 ) | DR_0; + newChannel.dr_range.value = ( DR_5 << 4 ) | DR_0; // Size of the optional CF list if( applyCFList->Size != 16 ) @@ -638,22 +638,22 @@ void LoRaPHYEU868::apply_cf_list(ApplyCFListParams_t* applyCFList) if( chanIdx < ( EU868_NUMB_CHANNELS_CF_LIST + EU868_NUMB_DEFAULT_CHANNELS ) ) { // Channel frequency - newChannel.Frequency = (uint32_t) applyCFList->Payload[i]; - newChannel.Frequency |= ( (uint32_t) applyCFList->Payload[i + 1] << 8 ); - newChannel.Frequency |= ( (uint32_t) applyCFList->Payload[i + 2] << 16 ); - newChannel.Frequency *= 100; + newChannel.frequency = (uint32_t) applyCFList->Payload[i]; + newChannel.frequency |= ( (uint32_t) applyCFList->Payload[i + 1] << 8 ); + newChannel.frequency |= ( (uint32_t) applyCFList->Payload[i + 2] << 16 ); + newChannel.frequency *= 100; // Initialize alternative frequency to 0 - newChannel.Rx1Frequency = 0; + newChannel.rx1_frequency = 0; } else { - newChannel.Frequency = 0; - newChannel.DrRange.Value = 0; - newChannel.Rx1Frequency = 0; + newChannel.frequency = 0; + newChannel.dr_range.value = 0; + newChannel.rx1_frequency = 0; } - if( newChannel.Frequency != 0 ) + if( newChannel.frequency != 0 ) { channelAdd.NewChannel = &newChannel; channelAdd.ChannelId = chanIdx; @@ -753,47 +753,47 @@ bool LoRaPHYEU868::get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut, void LoRaPHYEU868::compute_rx_win_params(int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, - RxConfigParams_t *rxConfigParams) + rx_config_params_t *rxConfigParams) { double tSymbol = 0.0; // Get the datarate, perform a boundary check - rxConfigParams->Datarate = MIN( datarate, EU868_RX_MAX_DATARATE ); - rxConfigParams->Bandwidth = GetBandwidth( rxConfigParams->Datarate ); + rxConfigParams->datarate = MIN( datarate, EU868_RX_MAX_DATARATE ); + rxConfigParams->bandwidth = GetBandwidth( rxConfigParams->datarate ); - if( rxConfigParams->Datarate == DR_7 ) + if( rxConfigParams->datarate == DR_7 ) { // FSK - tSymbol = compute_symb_timeout_fsk( DataratesEU868[rxConfigParams->Datarate] ); + tSymbol = compute_symb_timeout_fsk( DataratesEU868[rxConfigParams->datarate] ); } else { // LoRa - tSymbol = compute_symb_timeout_lora( DataratesEU868[rxConfigParams->Datarate], BandwidthsEU868[rxConfigParams->Datarate] ); + tSymbol = compute_symb_timeout_lora( DataratesEU868[rxConfigParams->datarate], BandwidthsEU868[rxConfigParams->datarate] ); } - get_rx_window_params( tSymbol, minRxSymbols, rxError, RADIO_WAKEUP_TIME, &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); + get_rx_window_params( tSymbol, minRxSymbols, rxError, RADIO_WAKEUP_TIME, &rxConfigParams->window_timeout, &rxConfigParams->window_offset ); } -bool LoRaPHYEU868::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) +bool LoRaPHYEU868::rx_config(rx_config_params_t* rxConfig, int8_t* datarate) { radio_modems_t modem; - int8_t dr = rxConfig->Datarate; + int8_t dr = rxConfig->datarate; uint8_t maxPayload = 0; int8_t phyDr = 0; - uint32_t frequency = rxConfig->Frequency; + uint32_t frequency = rxConfig->frequency; if( _radio->get_status() != RF_IDLE ) { return false; } - if( rxConfig->RxSlot == RX_SLOT_WIN_1 ) + if( rxConfig->rx_slot == RX_SLOT_WIN_1 ) { // Apply window 1 frequency - frequency = Channels[rxConfig->Channel].Frequency; + frequency = Channels[rxConfig->channel].frequency; // Apply the alternative RX 1 window frequency, if it is available - if( Channels[rxConfig->Channel].Rx1Frequency != 0 ) + if( Channels[rxConfig->channel].rx1_frequency != 0 ) { - frequency = Channels[rxConfig->Channel].Rx1Frequency; + frequency = Channels[rxConfig->channel].rx1_frequency; } } @@ -806,15 +806,15 @@ bool LoRaPHYEU868::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) if( dr == DR_7 ) { modem = MODEM_FSK; - _radio->set_rx_config( modem, 50000, phyDr * 1000, 0, 83333, 5, rxConfig->WindowTimeout, false, 0, true, 0, 0, false, rxConfig->RxContinuous ); + _radio->set_rx_config( modem, 50000, phyDr * 1000, 0, 83333, 5, rxConfig->window_timeout, false, 0, true, 0, 0, false, rxConfig->is_rx_continuous ); } else { modem = MODEM_LORA; - _radio->set_rx_config( modem, rxConfig->Bandwidth, phyDr, 1, 0, 8, rxConfig->WindowTimeout, false, 0, false, 0, 0, true, rxConfig->RxContinuous ); + _radio->set_rx_config( modem, rxConfig->bandwidth, phyDr, 1, 0, 8, rxConfig->window_timeout, false, 0, false, 0, 0, true, rxConfig->is_rx_continuous ); } - if( rxConfig->RepeaterSupport == true ) + if( rxConfig->is_repeater_supported == true ) { maxPayload = MaxPayloadOfDatarateRepeaterEU868[dr]; } @@ -830,11 +830,11 @@ bool LoRaPHYEU868::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) } bool LoRaPHYEU868::tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - TimerTime_t* txTimeOnAir) + lorawan_time_t* txTimeOnAir) { radio_modems_t modem; int8_t phyDr = DataratesEU868[txConfig->Datarate]; - int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, Bands[Channels[txConfig->Channel].Band].TxMaxPower, txConfig->Datarate, ChannelsMask ); + int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, Bands[Channels[txConfig->Channel].band].max_tx_pwr, txConfig->Datarate, ChannelsMask ); uint32_t bandwidth = GetBandwidth( txConfig->Datarate ); int8_t phyTxPower = 0; @@ -842,7 +842,7 @@ bool LoRaPHYEU868::tx_config(TxConfigParams_t* txConfig, int8_t* txPower, phyTxPower = compute_tx_power( txPowerLimited, txConfig->MaxEirp, txConfig->AntennaGain ); // Setup the radio frequency - _radio->set_channel( Channels[txConfig->Channel].Frequency ); + _radio->set_channel( Channels[txConfig->Channel].frequency ); if( txConfig->Datarate == DR_7 ) { // High Speed FSK channel @@ -911,7 +911,7 @@ uint8_t LoRaPHYEU868::link_ADR_request(LinkAdrReqParams_t* linkAdrReq, { if( linkAdrParams.ChMaskCtrl == 6 ) { - if( Channels[i].Frequency != 0 ) + if( Channels[i].frequency != 0 ) { chMask |= 1 << i; } @@ -919,7 +919,7 @@ uint8_t LoRaPHYEU868::link_ADR_request(LinkAdrReqParams_t* linkAdrReq, else { if( ( ( chMask & ( 1 << i ) ) != 0 ) && - ( Channels[i].Frequency == 0 ) ) + ( Channels[i].frequency == 0 ) ) {// Trying to enable an undefined channel status &= 0xFE; // Channel mask KO } @@ -1001,7 +1001,7 @@ uint8_t LoRaPHYEU868::request_new_channel(NewChannelReqParams_t* newChannelReq) ChannelAddParams_t channelAdd; ChannelRemoveParams_t channelRemove; - if( newChannelReq->NewChannel->Frequency == 0 ) + if( newChannelReq->NewChannel->frequency == 0 ) { channelRemove.ChannelId = newChannelReq->ChannelId; @@ -1018,21 +1018,21 @@ uint8_t LoRaPHYEU868::request_new_channel(NewChannelReqParams_t* newChannelReq) switch( add_channel( &channelAdd ) ) { - case LORAMAC_STATUS_OK: + case LORAWAN_STATUS_OK: { break; } - case LORAMAC_STATUS_FREQUENCY_INVALID: + case LORAWAN_STATUS_FREQUENCY_INVALID: { status &= 0xFE; break; } - case LORAMAC_STATUS_DATARATE_INVALID: + case LORAWAN_STATUS_DATARATE_INVALID: { status &= 0xFD; break; } - case LORAMAC_STATUS_FREQ_AND_DR_INVALID: + case LORAWAN_STATUS_FREQ_AND_DR_INVALID: { status &= 0xFC; break; @@ -1065,7 +1065,7 @@ uint8_t LoRaPHYEU868::dl_channel_request(DlChannelReqParams_t* dlChannelReq) } // Verify if an uplink frequency exists - if( Channels[dlChannelReq->ChannelId].Frequency == 0 ) + if( Channels[dlChannelReq->ChannelId].frequency == 0 ) { status &= 0xFD; } @@ -1073,7 +1073,7 @@ uint8_t LoRaPHYEU868::dl_channel_request(DlChannelReqParams_t* dlChannelReq) // Apply Rx1 frequency, if the status is OK if( status == 0x03 ) { - Channels[dlChannelReq->ChannelId].Rx1Frequency = dlChannelReq->Rx1Frequency; + Channels[dlChannelReq->ChannelId].rx1_frequency = dlChannelReq->Rx1Frequency; } return status; @@ -1127,13 +1127,13 @@ void LoRaPHYEU868::calculate_backoff(CalcBackOffParams_t* calcBackOff) } bool LoRaPHYEU868::set_next_channel(NextChanParams_t* nextChanParams, - uint8_t* channel, TimerTime_t* time, - TimerTime_t* aggregatedTimeOff) + uint8_t* channel, lorawan_time_t* time, + lorawan_time_t* aggregatedTimeOff) { uint8_t nbEnabledChannels = 0; uint8_t delayTx = 0; uint8_t enabledChannels[EU868_MAX_NB_CHANNELS] = { 0 }; - TimerTime_t nextTxDelay = 0; + lorawan_time_t nextTxDelay = 0; if( num_active_channels( ChannelsMask, 0, 1 ) == 0 ) { // Reactivate default channels @@ -1182,7 +1182,7 @@ bool LoRaPHYEU868::set_next_channel(NextChanParams_t* nextChanParams, } } -LoRaMacStatus_t LoRaPHYEU868::add_channel(ChannelAddParams_t* channelAdd) +lorawan_status_t LoRaPHYEU868::add_channel(ChannelAddParams_t* channelAdd) { uint8_t band = 0; bool drInvalid = false; @@ -1191,19 +1191,19 @@ LoRaMacStatus_t LoRaPHYEU868::add_channel(ChannelAddParams_t* channelAdd) if( id >= EU868_MAX_NB_CHANNELS ) { - return LORAMAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } // Validate the datarate range - if( val_in_range( channelAdd->NewChannel->DrRange.Fields.Min, EU868_TX_MIN_DATARATE, EU868_TX_MAX_DATARATE ) == 0 ) + if( val_in_range( channelAdd->NewChannel->dr_range.fields.min, EU868_TX_MIN_DATARATE, EU868_TX_MAX_DATARATE ) == 0 ) { drInvalid = true; } - if( val_in_range( channelAdd->NewChannel->DrRange.Fields.Max, EU868_TX_MIN_DATARATE, EU868_TX_MAX_DATARATE ) == 0 ) + if( val_in_range( channelAdd->NewChannel->dr_range.fields.max, EU868_TX_MIN_DATARATE, EU868_TX_MAX_DATARATE ) == 0 ) { drInvalid = true; } - if( channelAdd->NewChannel->DrRange.Fields.Min > channelAdd->NewChannel->DrRange.Fields.Max ) + if( channelAdd->NewChannel->dr_range.fields.min > channelAdd->NewChannel->dr_range.fields.max ) { drInvalid = true; } @@ -1212,17 +1212,17 @@ LoRaMacStatus_t LoRaPHYEU868::add_channel(ChannelAddParams_t* channelAdd) if( id < EU868_NUMB_DEFAULT_CHANNELS ) { // Validate the datarate range for min: must be DR_0 - if( channelAdd->NewChannel->DrRange.Fields.Min > DR_0 ) + if( channelAdd->NewChannel->dr_range.fields.min > DR_0 ) { drInvalid = true; } // Validate the datarate range for max: must be DR_5 <= Max <= TX_MAX_DATARATE - if( val_in_range( channelAdd->NewChannel->DrRange.Fields.Max, DR_5, EU868_TX_MAX_DATARATE ) == 0 ) + if( val_in_range( channelAdd->NewChannel->dr_range.fields.max, DR_5, EU868_TX_MAX_DATARATE ) == 0 ) { drInvalid = true; } // We are not allowed to change the frequency - if( channelAdd->NewChannel->Frequency != Channels[id].Frequency ) + if( channelAdd->NewChannel->frequency != Channels[id].frequency ) { freqInvalid = true; } @@ -1231,7 +1231,7 @@ LoRaMacStatus_t LoRaPHYEU868::add_channel(ChannelAddParams_t* channelAdd) // Check frequency if( freqInvalid == false ) { - if( VerifyTxFreq( channelAdd->NewChannel->Frequency, &band, _radio ) == false ) + if( VerifyTxFreq( channelAdd->NewChannel->frequency, &band, _radio ) == false ) { freqInvalid = true; } @@ -1240,21 +1240,21 @@ LoRaMacStatus_t LoRaPHYEU868::add_channel(ChannelAddParams_t* channelAdd) // Check status if( ( drInvalid == true ) && ( freqInvalid == true ) ) { - return LORAMAC_STATUS_FREQ_AND_DR_INVALID; + return LORAWAN_STATUS_FREQ_AND_DR_INVALID; } if( drInvalid == true ) { - return LORAMAC_STATUS_DATARATE_INVALID; + return LORAWAN_STATUS_DATARATE_INVALID; } if( freqInvalid == true ) { - return LORAMAC_STATUS_FREQUENCY_INVALID; + return LORAWAN_STATUS_FREQUENCY_INVALID; } memcpy( &(Channels[id]), channelAdd->NewChannel, sizeof( Channels[id] ) ); - Channels[id].Band = band; + Channels[id].band = band; ChannelsMask[0] |= ( 1 << id ); - return LORAMAC_STATUS_OK; + return LORAWAN_STATUS_OK; } bool LoRaPHYEU868::remove_channel(ChannelRemoveParams_t* channelRemove) @@ -1267,7 +1267,7 @@ bool LoRaPHYEU868::remove_channel(ChannelRemoveParams_t* channelRemove) } // Remove the channel from the list of channels - const ChannelParams_t empty_channel = { 0, 0, { 0 }, 0 }; + const channel_params_t empty_channel = { 0, 0, { 0 }, 0 }; Channels[id] = empty_channel; return disable_channel( ChannelsMask, id, EU868_MAX_NB_CHANNELS ); @@ -1275,9 +1275,9 @@ bool LoRaPHYEU868::remove_channel(ChannelRemoveParams_t* channelRemove) void LoRaPHYEU868::set_tx_cont_mode(ContinuousWaveParams_t* continuousWave) { - int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, Bands[Channels[continuousWave->Channel].Band].TxMaxPower, continuousWave->Datarate, ChannelsMask ); + int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, Bands[Channels[continuousWave->Channel].band].max_tx_pwr, continuousWave->Datarate, ChannelsMask ); int8_t phyTxPower = 0; - uint32_t frequency = Channels[continuousWave->Channel].Frequency; + uint32_t frequency = Channels[continuousWave->Channel].frequency; // Calculate physical TX power phyTxPower = compute_tx_power( txPowerLimited, continuousWave->MaxEirp, continuousWave->AntennaGain ); diff --git a/features/lorawan/lorastack/phy/LoRaPHYEU868.h b/features/lorawan/lorastack/phy/LoRaPHYEU868.h index 42144a781a..beaffb777e 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYEU868.h +++ b/features/lorawan/lorastack/phy/LoRaPHYEU868.h @@ -129,7 +129,7 @@ public: * * \retval True, if the configuration was applied successfully. */ - virtual bool rx_config(RxConfigParams_t* rxConfig, int8_t* datarate ); + virtual bool rx_config(rx_config_params_t* rxConfig, int8_t* datarate ); /* * RX window precise timing @@ -185,7 +185,7 @@ public: virtual void compute_rx_win_params(int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, - RxConfigParams_t *rxConfigParams); + rx_config_params_t *rxConfigParams); /*! * \brief TX configuration. @@ -199,7 +199,7 @@ public: * \retval True, if the configuration was applied successfully. */ virtual bool tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - TimerTime_t* txTimeOnAir ); + lorawan_time_t* txTimeOnAir ); /*! * \brief The function processes a Link ADR request. @@ -289,8 +289,8 @@ public: * \retval The function status [1: OK, 0: Unable to find a channel on the current datarate]. */ virtual bool set_next_channel(NextChanParams_t* nextChanParams, - uint8_t* channel, TimerTime_t* time, - TimerTime_t* aggregatedTimeOff ); + uint8_t* channel, lorawan_time_t* time, + lorawan_time_t* aggregatedTimeOff ); /*! * \brief Adds a channel. @@ -299,7 +299,7 @@ public: * * \retval The status of the operation. */ - virtual LoRaMacStatus_t add_channel(ChannelAddParams_t* channelAdd ); + virtual lorawan_status_t add_channel(ChannelAddParams_t* channelAdd ); /*! * \brief Removes a channel. @@ -331,18 +331,18 @@ public: virtual uint8_t apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ); private: - uint8_t CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ); + uint8_t CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, channel_params_t* channels, band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ); // Global attributes /*! * LoRaMAC channels */ - ChannelParams_t Channels[EU868_MAX_NB_CHANNELS]; + channel_params_t Channels[EU868_MAX_NB_CHANNELS]; /*! * LoRaMac bands */ - Band_t Bands[EU868_MAX_NB_BANDS]; + band_t Bands[EU868_MAX_NB_BANDS]; /*! * LoRaMac channels mask diff --git a/features/lorawan/lorastack/phy/LoRaPHYIN865.cpp b/features/lorawan/lorastack/phy/LoRaPHYIN865.cpp index 0f124138d1..651868fce8 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYIN865.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYIN865.cpp @@ -293,7 +293,7 @@ static bool VerifyTxFreq( uint32_t freq, uint8_t *band, LoRaRadio *radio ) return true; } -uint8_t LoRaPHYIN865::CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ) +uint8_t LoRaPHYIN865::CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, channel_params_t* channels, band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ) { uint8_t nbEnabledChannels = 0; uint8_t delayTransmission = 0; @@ -304,7 +304,7 @@ uint8_t LoRaPHYIN865::CountNbOfEnabledChannels( bool joined, uint8_t datarate, u { if( ( channelsMask[k] & ( 1 << j ) ) != 0 ) { - if( channels[i + j].Frequency == 0 ) + if( channels[i + j].frequency == 0 ) { // Check if the channel is enabled continue; } @@ -315,12 +315,12 @@ uint8_t LoRaPHYIN865::CountNbOfEnabledChannels( bool joined, uint8_t datarate, u continue; } } - if( val_in_range( datarate, channels[i + j].DrRange.Fields.Min, - channels[i + j].DrRange.Fields.Max ) == 0 ) + if( val_in_range( datarate, channels[i + j].dr_range.fields.min, + channels[i + j].dr_range.fields.max ) == 0 ) { // Check if the current channel selection supports the given datarate continue; } - if( bands[channels[i + j].Band].TimeOff > 0 ) + if( bands[channels[i + j].band].off_time > 0 ) { // Check if the band is available for transmission delayTransmission++; continue; @@ -337,7 +337,7 @@ uint8_t LoRaPHYIN865::CountNbOfEnabledChannels( bool joined, uint8_t datarate, u LoRaPHYIN865::LoRaPHYIN865(LoRaWANTimeHandler &lora_time) : LoRaPHY(lora_time) { - const Band_t band0 = IN865_BAND0; + const band_t band0 = IN865_BAND0; Bands[0] = band0; } @@ -494,7 +494,7 @@ PhyParam_t LoRaPHYIN865::get_phy_params(GetPhyParams_t* getPhy) void LoRaPHYIN865::set_band_tx_done(SetBandTxDoneParams_t* txDone) { - set_last_tx_done( txDone->Joined, &Bands[Channels[txDone->Channel].Band], txDone->LastTxDoneTime ); + set_last_tx_done( txDone->Joined, &Bands[Channels[txDone->Channel].band], txDone->LastTxDoneTime ); } void LoRaPHYIN865::load_defaults(InitType_t type) @@ -504,9 +504,9 @@ void LoRaPHYIN865::load_defaults(InitType_t type) case INIT_TYPE_INIT: { // Channels - const ChannelParams_t channel1 = IN865_LC1; - const ChannelParams_t channel2 = IN865_LC2; - const ChannelParams_t channel3 = IN865_LC3; + const channel_params_t channel1 = IN865_LC1; + const channel_params_t channel2 = IN865_LC2; + const channel_params_t channel3 = IN865_LC3; Channels[0] = channel1; Channels[1] = channel2; Channels[2] = channel3; @@ -572,12 +572,12 @@ bool LoRaPHYIN865::verify(VerifyParams_t* verify, PhyAttribute_t phyAttribute) void LoRaPHYIN865::apply_cf_list(ApplyCFListParams_t* applyCFList) { - ChannelParams_t newChannel; + channel_params_t newChannel; ChannelAddParams_t channelAdd; ChannelRemoveParams_t channelRemove; // Setup default datarate range - newChannel.DrRange.Value = ( DR_5 << 4 ) | DR_0; + newChannel.dr_range.value = ( DR_5 << 4 ) | DR_0; // Size of the optional CF list if( applyCFList->Size != 16 ) @@ -591,22 +591,22 @@ void LoRaPHYIN865::apply_cf_list(ApplyCFListParams_t* applyCFList) if( chanIdx < ( IN865_NUMB_CHANNELS_CF_LIST + IN865_NUMB_DEFAULT_CHANNELS ) ) { // Channel frequency - newChannel.Frequency = (uint32_t) applyCFList->Payload[i]; - newChannel.Frequency |= ( (uint32_t) applyCFList->Payload[i + 1] << 8 ); - newChannel.Frequency |= ( (uint32_t) applyCFList->Payload[i + 2] << 16 ); - newChannel.Frequency *= 100; + newChannel.frequency = (uint32_t) applyCFList->Payload[i]; + newChannel.frequency |= ( (uint32_t) applyCFList->Payload[i + 1] << 8 ); + newChannel.frequency |= ( (uint32_t) applyCFList->Payload[i + 2] << 16 ); + newChannel.frequency *= 100; // Initialize alternative frequency to 0 - newChannel.Rx1Frequency = 0; + newChannel.rx1_frequency = 0; } else { - newChannel.Frequency = 0; - newChannel.DrRange.Value = 0; - newChannel.Rx1Frequency = 0; + newChannel.frequency = 0; + newChannel.dr_range.value = 0; + newChannel.rx1_frequency = 0; } - if( newChannel.Frequency != 0 ) + if( newChannel.frequency != 0 ) { channelAdd.NewChannel = &newChannel; channelAdd.ChannelId = chanIdx; @@ -706,47 +706,47 @@ bool LoRaPHYIN865::get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut, void LoRaPHYIN865::compute_rx_win_params(int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, - RxConfigParams_t *rxConfigParams) + rx_config_params_t *rxConfigParams) { double tSymbol = 0.0; // Get the datarate, perform a boundary check - rxConfigParams->Datarate = MIN( datarate, IN865_RX_MAX_DATARATE ); - rxConfigParams->Bandwidth = GetBandwidth( rxConfigParams->Datarate ); + rxConfigParams->datarate = MIN( datarate, IN865_RX_MAX_DATARATE ); + rxConfigParams->bandwidth = GetBandwidth( rxConfigParams->datarate ); - if( rxConfigParams->Datarate == DR_7 ) + if( rxConfigParams->datarate == DR_7 ) { // FSK - tSymbol = compute_symb_timeout_fsk( DataratesIN865[rxConfigParams->Datarate] ); + tSymbol = compute_symb_timeout_fsk( DataratesIN865[rxConfigParams->datarate] ); } else { // LoRa - tSymbol = compute_symb_timeout_lora( DataratesIN865[rxConfigParams->Datarate], BandwidthsIN865[rxConfigParams->Datarate] ); + tSymbol = compute_symb_timeout_lora( DataratesIN865[rxConfigParams->datarate], BandwidthsIN865[rxConfigParams->datarate] ); } - get_rx_window_params( tSymbol, minRxSymbols, rxError, RADIO_WAKEUP_TIME, &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); + get_rx_window_params( tSymbol, minRxSymbols, rxError, RADIO_WAKEUP_TIME, &rxConfigParams->window_timeout, &rxConfigParams->window_offset ); } -bool LoRaPHYIN865::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) +bool LoRaPHYIN865::rx_config(rx_config_params_t* rxConfig, int8_t* datarate) { radio_modems_t modem; - int8_t dr = rxConfig->Datarate; + int8_t dr = rxConfig->datarate; uint8_t maxPayload = 0; int8_t phyDr = 0; - uint32_t frequency = rxConfig->Frequency; + uint32_t frequency = rxConfig->frequency; if( _radio->get_status() != RF_IDLE ) { return false; } - if( rxConfig->RxSlot == RX_SLOT_WIN_1 ) + if( rxConfig->rx_slot == RX_SLOT_WIN_1 ) { // Apply window 1 frequency - frequency = Channels[rxConfig->Channel].Frequency; + frequency = Channels[rxConfig->channel].frequency; // Apply the alternative RX 1 window frequency, if it is available - if( Channels[rxConfig->Channel].Rx1Frequency != 0 ) + if( Channels[rxConfig->channel].rx1_frequency != 0 ) { - frequency = Channels[rxConfig->Channel].Rx1Frequency; + frequency = Channels[rxConfig->channel].rx1_frequency; } } @@ -759,15 +759,15 @@ bool LoRaPHYIN865::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) if( dr == DR_7 ) { modem = MODEM_FSK; - _radio->set_rx_config( modem, 50000, phyDr * 1000, 0, 83333, 5, rxConfig->WindowTimeout, false, 0, true, 0, 0, false, rxConfig->RxContinuous ); + _radio->set_rx_config( modem, 50000, phyDr * 1000, 0, 83333, 5, rxConfig->window_timeout, false, 0, true, 0, 0, false, rxConfig->is_rx_continuous ); } else { modem = MODEM_LORA; - _radio->set_rx_config( modem, rxConfig->Bandwidth, phyDr, 1, 0, 8, rxConfig->WindowTimeout, false, 0, false, 0, 0, true, rxConfig->RxContinuous ); + _radio->set_rx_config( modem, rxConfig->bandwidth, phyDr, 1, 0, 8, rxConfig->window_timeout, false, 0, false, 0, 0, true, rxConfig->is_rx_continuous ); } - if( rxConfig->RepeaterSupport == true ) + if( rxConfig->is_repeater_supported == true ) { maxPayload = MaxPayloadOfDatarateRepeaterIN865[dr]; } @@ -781,11 +781,11 @@ bool LoRaPHYIN865::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) return true; } -bool LoRaPHYIN865::tx_config(TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir) +bool LoRaPHYIN865::tx_config(TxConfigParams_t* txConfig, int8_t* txPower, lorawan_time_t* txTimeOnAir) { radio_modems_t modem; int8_t phyDr = DataratesIN865[txConfig->Datarate]; - int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, Bands[Channels[txConfig->Channel].Band].TxMaxPower, txConfig->Datarate, ChannelsMask ); + int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, Bands[Channels[txConfig->Channel].band].max_tx_pwr, txConfig->Datarate, ChannelsMask ); uint32_t bandwidth = GetBandwidth( txConfig->Datarate ); int8_t phyTxPower = 0; @@ -793,7 +793,7 @@ bool LoRaPHYIN865::tx_config(TxConfigParams_t* txConfig, int8_t* txPower, TimerT phyTxPower = compute_tx_power( txPowerLimited, txConfig->MaxEirp, txConfig->AntennaGain ); // Setup the radio frequency - _radio->set_channel( Channels[txConfig->Channel].Frequency ); + _radio->set_channel( Channels[txConfig->Channel].frequency ); if( txConfig->Datarate == DR_7 ) { // High Speed FSK channel @@ -862,7 +862,7 @@ uint8_t LoRaPHYIN865::link_ADR_request(LinkAdrReqParams_t* linkAdrReq, { if( linkAdrParams.ChMaskCtrl == 6 ) { - if( Channels[i].Frequency != 0 ) + if( Channels[i].frequency != 0 ) { chMask |= 1 << i; } @@ -870,7 +870,7 @@ uint8_t LoRaPHYIN865::link_ADR_request(LinkAdrReqParams_t* linkAdrReq, else { if( ( ( chMask & ( 1 << i ) ) != 0 ) && - ( Channels[i].Frequency == 0 ) ) + ( Channels[i].frequency == 0 ) ) {// Trying to enable an undefined channel status &= 0xFE; // Channel mask KO } @@ -952,7 +952,7 @@ uint8_t LoRaPHYIN865::request_new_channel(NewChannelReqParams_t* newChannelReq) ChannelAddParams_t channelAdd; ChannelRemoveParams_t channelRemove; - if( newChannelReq->NewChannel->Frequency == 0 ) + if( newChannelReq->NewChannel->frequency == 0 ) { channelRemove.ChannelId = newChannelReq->ChannelId; @@ -969,21 +969,21 @@ uint8_t LoRaPHYIN865::request_new_channel(NewChannelReqParams_t* newChannelReq) switch( add_channel( &channelAdd ) ) { - case LORAMAC_STATUS_OK: + case LORAWAN_STATUS_OK: { break; } - case LORAMAC_STATUS_FREQUENCY_INVALID: + case LORAWAN_STATUS_FREQUENCY_INVALID: { status &= 0xFE; break; } - case LORAMAC_STATUS_DATARATE_INVALID: + case LORAWAN_STATUS_DATARATE_INVALID: { status &= 0xFD; break; } - case LORAMAC_STATUS_FREQ_AND_DR_INVALID: + case LORAWAN_STATUS_FREQ_AND_DR_INVALID: { status &= 0xFC; break; @@ -1016,7 +1016,7 @@ uint8_t LoRaPHYIN865::dl_channel_request(DlChannelReqParams_t* dlChannelReq) } // Verify if an uplink frequency exists - if( Channels[dlChannelReq->ChannelId].Frequency == 0 ) + if( Channels[dlChannelReq->ChannelId].frequency == 0 ) { status &= 0xFD; } @@ -1024,7 +1024,7 @@ uint8_t LoRaPHYIN865::dl_channel_request(DlChannelReqParams_t* dlChannelReq) // Apply Rx1 frequency, if the status is OK if( status == 0x03 ) { - Channels[dlChannelReq->ChannelId].Rx1Frequency = dlChannelReq->Rx1Frequency; + Channels[dlChannelReq->ChannelId].rx1_frequency = dlChannelReq->Rx1Frequency; } return status; @@ -1078,13 +1078,13 @@ void LoRaPHYIN865::calculate_backoff(CalcBackOffParams_t* calcBackOff) } bool LoRaPHYIN865::set_next_channel(NextChanParams_t* nextChanParams, - uint8_t* channel, TimerTime_t* time, - TimerTime_t* aggregatedTimeOff) + uint8_t* channel, lorawan_time_t* time, + lorawan_time_t* aggregatedTimeOff) { uint8_t nbEnabledChannels = 0; uint8_t delayTx = 0; uint8_t enabledChannels[IN865_MAX_NB_CHANNELS] = { 0 }; - TimerTime_t nextTxDelay = 0; + lorawan_time_t nextTxDelay = 0; if( num_active_channels( ChannelsMask, 0, 1 ) == 0 ) { // Reactivate default channels @@ -1133,7 +1133,7 @@ bool LoRaPHYIN865::set_next_channel(NextChanParams_t* nextChanParams, } } -LoRaMacStatus_t LoRaPHYIN865::add_channel(ChannelAddParams_t* channelAdd) +lorawan_status_t LoRaPHYIN865::add_channel(ChannelAddParams_t* channelAdd) { uint8_t band = 0; bool drInvalid = false; @@ -1142,19 +1142,19 @@ LoRaMacStatus_t LoRaPHYIN865::add_channel(ChannelAddParams_t* channelAdd) if( id >= IN865_MAX_NB_CHANNELS ) { - return LORAMAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } // Validate the datarate range - if( val_in_range( channelAdd->NewChannel->DrRange.Fields.Min, IN865_TX_MIN_DATARATE, IN865_TX_MAX_DATARATE ) == 0 ) + if( val_in_range( channelAdd->NewChannel->dr_range.fields.min, IN865_TX_MIN_DATARATE, IN865_TX_MAX_DATARATE ) == 0 ) { drInvalid = true; } - if( val_in_range( channelAdd->NewChannel->DrRange.Fields.Max, IN865_TX_MIN_DATARATE, IN865_TX_MAX_DATARATE ) == 0 ) + if( val_in_range( channelAdd->NewChannel->dr_range.fields.max, IN865_TX_MIN_DATARATE, IN865_TX_MAX_DATARATE ) == 0 ) { drInvalid = true; } - if( channelAdd->NewChannel->DrRange.Fields.Min > channelAdd->NewChannel->DrRange.Fields.Max ) + if( channelAdd->NewChannel->dr_range.fields.min > channelAdd->NewChannel->dr_range.fields.max ) { drInvalid = true; } @@ -1163,17 +1163,17 @@ LoRaMacStatus_t LoRaPHYIN865::add_channel(ChannelAddParams_t* channelAdd) if( id < IN865_NUMB_DEFAULT_CHANNELS ) { // Validate the datarate range for min: must be DR_0 - if( channelAdd->NewChannel->DrRange.Fields.Min > DR_0 ) + if( channelAdd->NewChannel->dr_range.fields.min > DR_0 ) { drInvalid = true; } // Validate the datarate range for max: must be DR_5 <= Max <= TX_MAX_DATARATE - if( val_in_range( channelAdd->NewChannel->DrRange.Fields.Max, DR_5, IN865_TX_MAX_DATARATE ) == 0 ) + if( val_in_range( channelAdd->NewChannel->dr_range.fields.max, DR_5, IN865_TX_MAX_DATARATE ) == 0 ) { drInvalid = true; } // We are not allowed to change the frequency - if( channelAdd->NewChannel->Frequency != Channels[id].Frequency ) + if( channelAdd->NewChannel->frequency != Channels[id].frequency ) { freqInvalid = true; } @@ -1182,7 +1182,7 @@ LoRaMacStatus_t LoRaPHYIN865::add_channel(ChannelAddParams_t* channelAdd) // Check frequency if( freqInvalid == false ) { - if( VerifyTxFreq( channelAdd->NewChannel->Frequency, &band, _radio ) == false ) + if( VerifyTxFreq( channelAdd->NewChannel->frequency, &band, _radio ) == false ) { freqInvalid = true; } @@ -1191,21 +1191,21 @@ LoRaMacStatus_t LoRaPHYIN865::add_channel(ChannelAddParams_t* channelAdd) // Check status if( ( drInvalid == true ) && ( freqInvalid == true ) ) { - return LORAMAC_STATUS_FREQ_AND_DR_INVALID; + return LORAWAN_STATUS_FREQ_AND_DR_INVALID; } if( drInvalid == true ) { - return LORAMAC_STATUS_DATARATE_INVALID; + return LORAWAN_STATUS_DATARATE_INVALID; } if( freqInvalid == true ) { - return LORAMAC_STATUS_FREQUENCY_INVALID; + return LORAWAN_STATUS_FREQUENCY_INVALID; } memcpy( &(Channels[id]), channelAdd->NewChannel, sizeof( Channels[id] ) ); - Channels[id].Band = band; + Channels[id].band = band; ChannelsMask[0] |= ( 1 << id ); - return LORAMAC_STATUS_OK; + return LORAWAN_STATUS_OK; } bool LoRaPHYIN865::remove_channel(ChannelRemoveParams_t* channelRemove) @@ -1218,7 +1218,7 @@ bool LoRaPHYIN865::remove_channel(ChannelRemoveParams_t* channelRemove) } // Remove the channel from the list of channels - const ChannelParams_t empty_channel = { 0, 0, { 0 }, 0 }; + const channel_params_t empty_channel = { 0, 0, { 0 }, 0 }; Channels[id] = empty_channel; return disable_channel( ChannelsMask, id, IN865_MAX_NB_CHANNELS ); @@ -1226,9 +1226,9 @@ bool LoRaPHYIN865::remove_channel(ChannelRemoveParams_t* channelRemove) void LoRaPHYIN865::set_tx_cont_mode(ContinuousWaveParams_t* continuousWave) { - int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, Bands[Channels[continuousWave->Channel].Band].TxMaxPower, continuousWave->Datarate, ChannelsMask ); + int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, Bands[Channels[continuousWave->Channel].band].max_tx_pwr, continuousWave->Datarate, ChannelsMask ); int8_t phyTxPower = 0; - uint32_t frequency = Channels[continuousWave->Channel].Frequency; + uint32_t frequency = Channels[continuousWave->Channel].frequency; // Calculate physical TX power phyTxPower = compute_tx_power( txPowerLimited, continuousWave->MaxEirp, continuousWave->AntennaGain ); diff --git a/features/lorawan/lorastack/phy/LoRaPHYIN865.h b/features/lorawan/lorastack/phy/LoRaPHYIN865.h index 5745239869..a4b870095e 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYIN865.h +++ b/features/lorawan/lorastack/phy/LoRaPHYIN865.h @@ -132,7 +132,7 @@ public: * * \retval True, if the configuration was applied successfully. */ - virtual bool rx_config(RxConfigParams_t* rxConfig, int8_t* datarate ); + virtual bool rx_config(rx_config_params_t* rxConfig, int8_t* datarate ); /* * RX window precise timing @@ -188,7 +188,7 @@ public: virtual void compute_rx_win_params(int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, - RxConfigParams_t *rxConfigParams); + rx_config_params_t *rxConfigParams); /*! * \brief TX configuration. @@ -202,7 +202,7 @@ public: * \retval True, if the configuration was applied successfully. */ virtual bool tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - TimerTime_t* txTimeOnAir ); + lorawan_time_t* txTimeOnAir ); /*! * \brief The function processes a Link ADR request. @@ -292,8 +292,8 @@ public: * \retval The function status [1: OK, 0: Unable to find a channel on the current datarate]. */ virtual bool set_next_channel(NextChanParams_t* nextChanParams, - uint8_t* channel, TimerTime_t* time, - TimerTime_t* aggregatedTimeOff ); + uint8_t* channel, lorawan_time_t* time, + lorawan_time_t* aggregatedTimeOff ); /*! * \brief Adds a channel. @@ -302,7 +302,7 @@ public: * * \retval The status of the operation. */ - virtual LoRaMacStatus_t add_channel(ChannelAddParams_t* channelAdd ); + virtual lorawan_status_t add_channel(ChannelAddParams_t* channelAdd ); /*! * \brief Removes a channel. @@ -334,18 +334,18 @@ public: virtual uint8_t apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ); private: - uint8_t CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ); + uint8_t CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, channel_params_t* channels, band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ); // Global attributes /*! * LoRaMAC channels */ - ChannelParams_t Channels[IN865_MAX_NB_CHANNELS]; + channel_params_t Channels[IN865_MAX_NB_CHANNELS]; /*! * LoRaMac bands */ - Band_t Bands[IN865_MAX_NB_BANDS]; + band_t Bands[IN865_MAX_NB_BANDS]; /*! * LoRaMac channels mask diff --git a/features/lorawan/lorastack/phy/LoRaPHYKR920.cpp b/features/lorawan/lorastack/phy/LoRaPHYKR920.cpp index 9524a28fbd..e2a96046b0 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYKR920.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYKR920.cpp @@ -318,7 +318,7 @@ static bool VerifyTxFreq( uint32_t freq, LoRaRadio *radio ) return false; } -uint8_t LoRaPHYKR920::CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ) +uint8_t LoRaPHYKR920::CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, channel_params_t* channels, band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ) { uint8_t nbEnabledChannels = 0; uint8_t delayTransmission = 0; @@ -329,7 +329,7 @@ uint8_t LoRaPHYKR920::CountNbOfEnabledChannels( bool joined, uint8_t datarate, u { if( ( channelsMask[k] & ( 1 << j ) ) != 0 ) { - if( channels[i + j].Frequency == 0 ) + if( channels[i + j].frequency == 0 ) { // Check if the channel is enabled continue; } @@ -340,12 +340,12 @@ uint8_t LoRaPHYKR920::CountNbOfEnabledChannels( bool joined, uint8_t datarate, u continue; } } - if( val_in_range( datarate, channels[i + j].DrRange.Fields.Min, - channels[i + j].DrRange.Fields.Max ) == 0 ) + if( val_in_range( datarate, channels[i + j].dr_range.fields.min, + channels[i + j].dr_range.fields.max ) == 0 ) { // Check if the current channel selection supports the given datarate continue; } - if( bands[channels[i + j].Band].TimeOff > 0 ) + if( bands[channels[i + j].band].off_time > 0 ) { // Check if the band is available for transmission delayTransmission++; continue; @@ -362,7 +362,7 @@ uint8_t LoRaPHYKR920::CountNbOfEnabledChannels( bool joined, uint8_t datarate, u LoRaPHYKR920::LoRaPHYKR920(LoRaWANTimeHandler &lora_time) : LoRaPHY(lora_time) { - const Band_t band0 = KR920_BAND0; + const band_t band0 = KR920_BAND0; Bands[0] = band0; } @@ -523,7 +523,7 @@ PhyParam_t LoRaPHYKR920::get_phy_params(GetPhyParams_t* getPhy) void LoRaPHYKR920::set_band_tx_done(SetBandTxDoneParams_t* txDone) { - set_last_tx_done( txDone->Joined, &Bands[Channels[txDone->Channel].Band], txDone->LastTxDoneTime ); + set_last_tx_done( txDone->Joined, &Bands[Channels[txDone->Channel].band], txDone->LastTxDoneTime ); } void LoRaPHYKR920::load_defaults(InitType_t type) @@ -533,9 +533,9 @@ void LoRaPHYKR920::load_defaults(InitType_t type) case INIT_TYPE_INIT: { // Channels - const ChannelParams_t channel1 = KR920_LC1; - const ChannelParams_t channel2 = KR920_LC2; - const ChannelParams_t channel3 = KR920_LC3; + const channel_params_t channel1 = KR920_LC1; + const channel_params_t channel2 = KR920_LC2; + const channel_params_t channel3 = KR920_LC3; Channels[0] = channel1; Channels[1] = channel2; Channels[2] = channel3; @@ -601,12 +601,12 @@ bool LoRaPHYKR920::verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) void LoRaPHYKR920::apply_cf_list(ApplyCFListParams_t* applyCFList) { - ChannelParams_t newChannel; + channel_params_t newChannel; ChannelAddParams_t channelAdd; ChannelRemoveParams_t channelRemove; // Setup default datarate range - newChannel.DrRange.Value = ( DR_5 << 4 ) | DR_0; + newChannel.dr_range.value = ( DR_5 << 4 ) | DR_0; // Size of the optional CF list if( applyCFList->Size != 16 ) @@ -620,22 +620,22 @@ void LoRaPHYKR920::apply_cf_list(ApplyCFListParams_t* applyCFList) if( chanIdx < ( KR920_NUMB_CHANNELS_CF_LIST + KR920_NUMB_DEFAULT_CHANNELS ) ) { // Channel frequency - newChannel.Frequency = (uint32_t) applyCFList->Payload[i]; - newChannel.Frequency |= ( (uint32_t) applyCFList->Payload[i + 1] << 8 ); - newChannel.Frequency |= ( (uint32_t) applyCFList->Payload[i + 2] << 16 ); - newChannel.Frequency *= 100; + newChannel.frequency = (uint32_t) applyCFList->Payload[i]; + newChannel.frequency |= ( (uint32_t) applyCFList->Payload[i + 1] << 8 ); + newChannel.frequency |= ( (uint32_t) applyCFList->Payload[i + 2] << 16 ); + newChannel.frequency *= 100; // Initialize alternative frequency to 0 - newChannel.Rx1Frequency = 0; + newChannel.rx1_frequency = 0; } else { - newChannel.Frequency = 0; - newChannel.DrRange.Value = 0; - newChannel.Rx1Frequency = 0; + newChannel.frequency = 0; + newChannel.dr_range.value = 0; + newChannel.rx1_frequency = 0; } - if( newChannel.Frequency != 0 ) + if( newChannel.frequency != 0 ) { channelAdd.NewChannel = &newChannel; channelAdd.ChannelId = chanIdx; @@ -735,39 +735,39 @@ bool LoRaPHYKR920::get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut, void LoRaPHYKR920::compute_rx_win_params(int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, - RxConfigParams_t *rxConfigParams) + rx_config_params_t *rxConfigParams) { double tSymbol = 0.0; // Get the datarate, perform a boundary check - rxConfigParams->Datarate = MIN( datarate, KR920_RX_MAX_DATARATE ); - rxConfigParams->Bandwidth = GetBandwidth( rxConfigParams->Datarate ); + rxConfigParams->datarate = MIN( datarate, KR920_RX_MAX_DATARATE ); + rxConfigParams->bandwidth = GetBandwidth( rxConfigParams->datarate ); - tSymbol = compute_symb_timeout_lora( DataratesKR920[rxConfigParams->Datarate], BandwidthsKR920[rxConfigParams->Datarate] ); + tSymbol = compute_symb_timeout_lora( DataratesKR920[rxConfigParams->datarate], BandwidthsKR920[rxConfigParams->datarate] ); - get_rx_window_params( tSymbol, minRxSymbols, rxError, RADIO_WAKEUP_TIME, &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); + get_rx_window_params( tSymbol, minRxSymbols, rxError, RADIO_WAKEUP_TIME, &rxConfigParams->window_timeout, &rxConfigParams->window_offset ); } -bool LoRaPHYKR920::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) +bool LoRaPHYKR920::rx_config(rx_config_params_t* rxConfig, int8_t* datarate) { - int8_t dr = rxConfig->Datarate; + int8_t dr = rxConfig->datarate; uint8_t maxPayload = 0; int8_t phyDr = 0; - uint32_t frequency = rxConfig->Frequency; + uint32_t frequency = rxConfig->frequency; if( _radio->get_status() != RF_IDLE ) { return false; } - if( rxConfig->RxSlot == RX_SLOT_WIN_1 ) + if( rxConfig->rx_slot == RX_SLOT_WIN_1 ) { // Apply window 1 frequency - frequency = Channels[rxConfig->Channel].Frequency; + frequency = Channels[rxConfig->channel].frequency; // Apply the alternative RX 1 window frequency, if it is available - if( Channels[rxConfig->Channel].Rx1Frequency != 0 ) + if( Channels[rxConfig->channel].rx1_frequency != 0 ) { - frequency = Channels[rxConfig->Channel].Rx1Frequency; + frequency = Channels[rxConfig->channel].rx1_frequency; } } @@ -777,9 +777,9 @@ bool LoRaPHYKR920::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) _radio->set_channel( frequency ); // Radio configuration - _radio->set_rx_config( MODEM_LORA, rxConfig->Bandwidth, phyDr, 1, 0, 8, - rxConfig->WindowTimeout, false, 0, false, 0, 0, true, - rxConfig->RxContinuous ); + _radio->set_rx_config( MODEM_LORA, rxConfig->bandwidth, phyDr, 1, 0, 8, + rxConfig->window_timeout, false, 0, false, 0, 0, true, + rxConfig->is_rx_continuous ); maxPayload = MaxPayloadOfDatarateKR920[dr]; _radio->set_max_payload_length( MODEM_LORA, maxPayload + LORA_MAC_FRMPAYLOAD_OVERHEAD ); @@ -787,12 +787,12 @@ bool LoRaPHYKR920::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) return true; } -bool LoRaPHYKR920::tx_config(TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir) +bool LoRaPHYKR920::tx_config(TxConfigParams_t* txConfig, int8_t* txPower, lorawan_time_t* txTimeOnAir) { int8_t phyDr = DataratesKR920[txConfig->Datarate]; - int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, Bands[Channels[txConfig->Channel].Band].TxMaxPower, txConfig->Datarate, ChannelsMask ); + int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, Bands[Channels[txConfig->Channel].band].max_tx_pwr, txConfig->Datarate, ChannelsMask ); uint32_t bandwidth = GetBandwidth( txConfig->Datarate ); - float maxEIRP = GetMaxEIRP( Channels[txConfig->Channel].Frequency ); + float maxEIRP = GetMaxEIRP( Channels[txConfig->Channel].frequency ); int8_t phyTxPower = 0; // Take the minimum between the maxEIRP and txConfig->MaxEirp. @@ -803,7 +803,7 @@ bool LoRaPHYKR920::tx_config(TxConfigParams_t* txConfig, int8_t* txPower, TimerT phyTxPower = compute_tx_power( txPowerLimited, maxEIRP, txConfig->AntennaGain ); // Setup the radio frequency - _radio->set_channel( Channels[txConfig->Channel].Frequency ); + _radio->set_channel( Channels[txConfig->Channel].frequency ); _radio->set_tx_config( MODEM_LORA, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 3000 ); @@ -863,7 +863,7 @@ uint8_t LoRaPHYKR920::link_ADR_request(LinkAdrReqParams_t* linkAdrReq, { if( linkAdrParams.ChMaskCtrl == 6 ) { - if( Channels[i].Frequency != 0 ) + if( Channels[i].frequency != 0 ) { chMask |= 1 << i; } @@ -871,7 +871,7 @@ uint8_t LoRaPHYKR920::link_ADR_request(LinkAdrReqParams_t* linkAdrReq, else { if( ( ( chMask & ( 1 << i ) ) != 0 ) && - ( Channels[i].Frequency == 0 ) ) + ( Channels[i].frequency == 0 ) ) {// Trying to enable an undefined channel status &= 0xFE; // Channel mask KO } @@ -953,7 +953,7 @@ uint8_t LoRaPHYKR920::request_new_channel(NewChannelReqParams_t* newChannelReq) ChannelAddParams_t channelAdd; ChannelRemoveParams_t channelRemove; - if( newChannelReq->NewChannel->Frequency == 0 ) + if( newChannelReq->NewChannel->frequency == 0 ) { channelRemove.ChannelId = newChannelReq->ChannelId; @@ -970,21 +970,21 @@ uint8_t LoRaPHYKR920::request_new_channel(NewChannelReqParams_t* newChannelReq) switch( add_channel( &channelAdd ) ) { - case LORAMAC_STATUS_OK: + case LORAWAN_STATUS_OK: { break; } - case LORAMAC_STATUS_FREQUENCY_INVALID: + case LORAWAN_STATUS_FREQUENCY_INVALID: { status &= 0xFE; break; } - case LORAMAC_STATUS_DATARATE_INVALID: + case LORAWAN_STATUS_DATARATE_INVALID: { status &= 0xFD; break; } - case LORAMAC_STATUS_FREQ_AND_DR_INVALID: + case LORAWAN_STATUS_FREQ_AND_DR_INVALID: { status &= 0xFC; break; @@ -1016,7 +1016,7 @@ uint8_t LoRaPHYKR920::dl_channel_request(DlChannelReqParams_t* dlChannelReq) } // Verify if an uplink frequency exists - if( Channels[dlChannelReq->ChannelId].Frequency == 0 ) + if( Channels[dlChannelReq->ChannelId].frequency == 0 ) { status &= 0xFD; } @@ -1024,7 +1024,7 @@ uint8_t LoRaPHYKR920::dl_channel_request(DlChannelReqParams_t* dlChannelReq) // Apply Rx1 frequency, if the status is OK if( status == 0x03 ) { - Channels[dlChannelReq->ChannelId].Rx1Frequency = dlChannelReq->Rx1Frequency; + Channels[dlChannelReq->ChannelId].rx1_frequency = dlChannelReq->Rx1Frequency; } return status; @@ -1078,14 +1078,14 @@ void LoRaPHYKR920::calculate_backoff(CalcBackOffParams_t* calcBackOff) } bool LoRaPHYKR920::set_next_channel(NextChanParams_t* nextChanParams, - uint8_t* channel, TimerTime_t* time, - TimerTime_t* aggregatedTimeOff) + uint8_t* channel, lorawan_time_t* time, + lorawan_time_t* aggregatedTimeOff) { uint8_t channelNext = 0; uint8_t nbEnabledChannels = 0; uint8_t delayTx = 0; uint8_t enabledChannels[KR920_MAX_NB_CHANNELS] = { 0 }; - TimerTime_t nextTxDelay = 0; + lorawan_time_t nextTxDelay = 0; if( num_active_channels( ChannelsMask, 0, 1 ) == 0 ) { // Reactivate default channels @@ -1121,7 +1121,7 @@ bool LoRaPHYKR920::set_next_channel(NextChanParams_t* nextChanParams, // Perform carrier sense for KR920_CARRIER_SENSE_TIME // If the channel is free, we can stop the LBT mechanism if( _radio->perform_carrier_sense( MODEM_LORA, - Channels[channelNext].Frequency, + Channels[channelNext].frequency, KR920_RSSI_FREE_TH, KR920_CARRIER_SENSE_TIME ) == true ) { @@ -1148,7 +1148,7 @@ bool LoRaPHYKR920::set_next_channel(NextChanParams_t* nextChanParams, } } -LoRaMacStatus_t LoRaPHYKR920::add_channel(ChannelAddParams_t* channelAdd) +lorawan_status_t LoRaPHYKR920::add_channel(ChannelAddParams_t* channelAdd) { uint8_t band = 0; bool drInvalid = false; @@ -1157,19 +1157,19 @@ LoRaMacStatus_t LoRaPHYKR920::add_channel(ChannelAddParams_t* channelAdd) if( id >= KR920_MAX_NB_CHANNELS ) { - return LORAMAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } // Validate the datarate range - if( val_in_range( channelAdd->NewChannel->DrRange.Fields.Min, KR920_TX_MIN_DATARATE, KR920_TX_MAX_DATARATE ) == 0 ) + if( val_in_range( channelAdd->NewChannel->dr_range.fields.min, KR920_TX_MIN_DATARATE, KR920_TX_MAX_DATARATE ) == 0 ) { drInvalid = true; } - if( val_in_range( channelAdd->NewChannel->DrRange.Fields.Max, KR920_TX_MIN_DATARATE, KR920_TX_MAX_DATARATE ) == 0 ) + if( val_in_range( channelAdd->NewChannel->dr_range.fields.max, KR920_TX_MIN_DATARATE, KR920_TX_MAX_DATARATE ) == 0 ) { drInvalid = true; } - if( channelAdd->NewChannel->DrRange.Fields.Min > channelAdd->NewChannel->DrRange.Fields.Max ) + if( channelAdd->NewChannel->dr_range.fields.min > channelAdd->NewChannel->dr_range.fields.max ) { drInvalid = true; } @@ -1179,7 +1179,7 @@ LoRaMacStatus_t LoRaPHYKR920::add_channel(ChannelAddParams_t* channelAdd) { // All datarates are supported // We are not allowed to change the frequency - if( channelAdd->NewChannel->Frequency != Channels[id].Frequency ) + if( channelAdd->NewChannel->frequency != Channels[id].frequency ) { freqInvalid = true; } @@ -1188,7 +1188,7 @@ LoRaMacStatus_t LoRaPHYKR920::add_channel(ChannelAddParams_t* channelAdd) // Check frequency if( freqInvalid == false ) { - if( VerifyTxFreq( channelAdd->NewChannel->Frequency, _radio ) == false ) + if( VerifyTxFreq( channelAdd->NewChannel->frequency, _radio ) == false ) { freqInvalid = true; } @@ -1197,21 +1197,21 @@ LoRaMacStatus_t LoRaPHYKR920::add_channel(ChannelAddParams_t* channelAdd) // Check status if( ( drInvalid == true ) && ( freqInvalid == true ) ) { - return LORAMAC_STATUS_FREQ_AND_DR_INVALID; + return LORAWAN_STATUS_FREQ_AND_DR_INVALID; } if( drInvalid == true ) { - return LORAMAC_STATUS_DATARATE_INVALID; + return LORAWAN_STATUS_DATARATE_INVALID; } if( freqInvalid == true ) { - return LORAMAC_STATUS_FREQUENCY_INVALID; + return LORAWAN_STATUS_FREQUENCY_INVALID; } memcpy( &(Channels[id]), channelAdd->NewChannel, sizeof( Channels[id] ) ); - Channels[id].Band = band; + Channels[id].band = band; ChannelsMask[0] |= ( 1 << id ); - return LORAMAC_STATUS_OK; + return LORAWAN_STATUS_OK; } bool LoRaPHYKR920::remove_channel(ChannelRemoveParams_t* channelRemove) @@ -1224,7 +1224,7 @@ bool LoRaPHYKR920::remove_channel(ChannelRemoveParams_t* channelRemove) } // Remove the channel from the list of channels - const ChannelParams_t empty_channel = { 0, 0, { 0 }, 0 }; + const channel_params_t empty_channel = { 0, 0, { 0 }, 0 }; Channels[id] = empty_channel; return disable_channel( ChannelsMask, id, KR920_MAX_NB_CHANNELS ); @@ -1232,10 +1232,10 @@ bool LoRaPHYKR920::remove_channel(ChannelRemoveParams_t* channelRemove) void LoRaPHYKR920::set_tx_cont_mode(ContinuousWaveParams_t* continuousWave) { - int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, Bands[Channels[continuousWave->Channel].Band].TxMaxPower, continuousWave->Datarate, ChannelsMask ); - float maxEIRP = GetMaxEIRP( Channels[continuousWave->Channel].Frequency ); + int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, Bands[Channels[continuousWave->Channel].band].max_tx_pwr, continuousWave->Datarate, ChannelsMask ); + float maxEIRP = GetMaxEIRP( Channels[continuousWave->Channel].frequency ); int8_t phyTxPower = 0; - uint32_t frequency = Channels[continuousWave->Channel].Frequency; + uint32_t frequency = Channels[continuousWave->Channel].frequency; // Take the minimum between the maxEIRP and continuousWave->MaxEirp. // The value of continuousWave->MaxEirp could have changed during runtime, e.g. due to a MAC command. diff --git a/features/lorawan/lorastack/phy/LoRaPHYKR920.h b/features/lorawan/lorastack/phy/LoRaPHYKR920.h index 0d0c893f84..428df3989a 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYKR920.h +++ b/features/lorawan/lorastack/phy/LoRaPHYKR920.h @@ -130,7 +130,7 @@ public: * * \retval True, if the configuration was applied successfully. */ - virtual bool rx_config(RxConfigParams_t* rxConfig, int8_t* datarate ); + virtual bool rx_config(rx_config_params_t* rxConfig, int8_t* datarate ); /* * RX window precise timing @@ -186,7 +186,7 @@ public: virtual void compute_rx_win_params(int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, - RxConfigParams_t *rxConfigParams); + rx_config_params_t *rxConfigParams); /*! * \brief TX configuration. @@ -200,7 +200,7 @@ public: * \retval True, if the configuration was applied successfully. */ virtual bool tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - TimerTime_t* txTimeOnAir ); + lorawan_time_t* txTimeOnAir ); /*! * \brief The function processes a Link ADR request. @@ -290,8 +290,8 @@ public: * \retval The function status [1: OK, 0: Unable to find a channel on the current datarate]. */ virtual bool set_next_channel(NextChanParams_t* nextChanParams, - uint8_t* channel, TimerTime_t* time, - TimerTime_t* aggregatedTimeOff ); + uint8_t* channel, lorawan_time_t* time, + lorawan_time_t* aggregatedTimeOff ); /*! * \brief Adds a channel. @@ -300,7 +300,7 @@ public: * * \retval The status of the operation. */ - virtual LoRaMacStatus_t add_channel(ChannelAddParams_t* channelAdd ); + virtual lorawan_status_t add_channel(ChannelAddParams_t* channelAdd ); /*! * \brief Removes a channel. @@ -331,18 +331,18 @@ public: */ virtual uint8_t apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ); - uint8_t CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ); + uint8_t CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, channel_params_t* channels, band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ); // Global attributes /*! * LoRaMAC channels */ - ChannelParams_t Channels[KR920_MAX_NB_CHANNELS]; + channel_params_t Channels[KR920_MAX_NB_CHANNELS]; /*! * LoRaMac bands */ - Band_t Bands[KR920_MAX_NB_BANDS]; + band_t Bands[KR920_MAX_NB_BANDS]; /*! * LoRaMac channels mask diff --git a/features/lorawan/lorastack/phy/LoRaPHYUS915.cpp b/features/lorawan/lorastack/phy/LoRaPHYUS915.cpp index 057bdf5c11..af4859ff99 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYUS915.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYUS915.cpp @@ -264,7 +264,7 @@ int8_t LoRaPHYUS915::LimitTxPower( int8_t txPower, int8_t maxBandTxPower, int8_t return txPowerResult; } -uint8_t LoRaPHYUS915::CountNbOfEnabledChannels( uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ) +uint8_t LoRaPHYUS915::CountNbOfEnabledChannels( uint8_t datarate, uint16_t* channelsMask, channel_params_t* channels, band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ) { uint8_t nbEnabledChannels = 0; uint8_t delayTransmission = 0; @@ -275,16 +275,16 @@ uint8_t LoRaPHYUS915::CountNbOfEnabledChannels( uint8_t datarate, uint16_t* chan { if( ( channelsMask[k] & ( 1 << j ) ) != 0 ) { - if( channels[i + j].Frequency == 0 ) + if( channels[i + j].frequency == 0 ) { // Check if the channel is enabled continue; } - if( val_in_range( datarate, channels[i + j].DrRange.Fields.Min, - channels[i + j].DrRange.Fields.Max ) == 0 ) + if( val_in_range( datarate, channels[i + j].dr_range.fields.min, + channels[i + j].dr_range.fields.max ) == 0 ) { // Check if the current channel selection supports the given datarate continue; } - if( bands[channels[i + j].Band].TimeOff > 0 ) + if( bands[channels[i + j].band].off_time > 0 ) { // Check if the band is available for transmission delayTransmission++; continue; @@ -301,7 +301,7 @@ uint8_t LoRaPHYUS915::CountNbOfEnabledChannels( uint8_t datarate, uint16_t* chan LoRaPHYUS915::LoRaPHYUS915(LoRaWANTimeHandler &lora_time) : LoRaPHY(lora_time) { - const Band_t band0 = US915_BAND0; + const band_t band0 = US915_BAND0; Bands[0] = band0; } @@ -454,7 +454,7 @@ PhyParam_t LoRaPHYUS915::get_phy_params(GetPhyParams_t* getPhy) void LoRaPHYUS915::set_band_tx_done(SetBandTxDoneParams_t* txDone) { - set_last_tx_done( txDone->Joined, &Bands[Channels[txDone->Channel].Band], txDone->LastTxDoneTime ); + set_last_tx_done( txDone->Joined, &Bands[Channels[txDone->Channel].band], txDone->LastTxDoneTime ); } void LoRaPHYUS915::load_defaults(InitType_t type) @@ -467,16 +467,16 @@ void LoRaPHYUS915::load_defaults(InitType_t type) // 125 kHz channels for( uint8_t i = 0; i < US915_MAX_NB_CHANNELS - 8; i++ ) { - Channels[i].Frequency = 902300000 + i * 200000; - Channels[i].DrRange.Value = ( DR_3 << 4 ) | DR_0; - Channels[i].Band = 0; + Channels[i].frequency = 902300000 + i * 200000; + Channels[i].dr_range.value = ( DR_3 << 4 ) | DR_0; + Channels[i].band = 0; } // 500 kHz channels for( uint8_t i = US915_MAX_NB_CHANNELS - 8; i < US915_MAX_NB_CHANNELS; i++ ) { - Channels[i].Frequency = 903000000 + ( i - ( US915_MAX_NB_CHANNELS - 8 ) ) * 1600000; - Channels[i].DrRange.Value = ( DR_4 << 4 ) | DR_4; - Channels[i].Band = 0; + Channels[i].frequency = 903000000 + ( i - ( US915_MAX_NB_CHANNELS - 8 ) ) * 1600000; + Channels[i].dr_range.value = ( DR_4 << 4 ) | DR_4; + Channels[i].band = 0; } // ChannelsMask @@ -659,35 +659,35 @@ bool LoRaPHYUS915::get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut, void LoRaPHYUS915::compute_rx_win_params(int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, - RxConfigParams_t *rxConfigParams) + rx_config_params_t *rxConfigParams) { double tSymbol = 0.0; // Get the datarate, perform a boundary check - rxConfigParams->Datarate = MIN( datarate, US915_RX_MAX_DATARATE ); - rxConfigParams->Bandwidth = GetBandwidth( rxConfigParams->Datarate ); + rxConfigParams->datarate = MIN( datarate, US915_RX_MAX_DATARATE ); + rxConfigParams->bandwidth = GetBandwidth( rxConfigParams->datarate ); - tSymbol = compute_symb_timeout_lora( DataratesUS915[rxConfigParams->Datarate], BandwidthsUS915[rxConfigParams->Datarate] ); + tSymbol = compute_symb_timeout_lora( DataratesUS915[rxConfigParams->datarate], BandwidthsUS915[rxConfigParams->datarate] ); - get_rx_window_params( tSymbol, minRxSymbols, rxError, RADIO_WAKEUP_TIME, &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); + get_rx_window_params( tSymbol, minRxSymbols, rxError, RADIO_WAKEUP_TIME, &rxConfigParams->window_timeout, &rxConfigParams->window_offset ); } -bool LoRaPHYUS915::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) +bool LoRaPHYUS915::rx_config(rx_config_params_t* rxConfig, int8_t* datarate) { - int8_t dr = rxConfig->Datarate; + int8_t dr = rxConfig->datarate; uint8_t maxPayload = 0; int8_t phyDr = 0; - uint32_t frequency = rxConfig->Frequency; + uint32_t frequency = rxConfig->frequency; if(_radio->get_status() != RF_IDLE ) { return false; } - if( rxConfig->RxSlot == RX_SLOT_WIN_1 ) + if( rxConfig->rx_slot == RX_SLOT_WIN_1 ) { // Apply window 1 frequency - frequency = US915_FIRST_RX1_CHANNEL + ( rxConfig->Channel % 8 ) * US915_STEPWIDTH_RX1_CHANNEL; + frequency = US915_FIRST_RX1_CHANNEL + ( rxConfig->channel % 8 ) * US915_STEPWIDTH_RX1_CHANNEL; } // Read the physical datarate from the datarates table @@ -696,11 +696,11 @@ bool LoRaPHYUS915::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) _radio->set_channel( frequency ); // Radio configuration - _radio->set_rx_config( MODEM_LORA, rxConfig->Bandwidth, phyDr, 1, 0, 8, - rxConfig->WindowTimeout, false, 0, false, 0, 0, true, - rxConfig->RxContinuous ); + _radio->set_rx_config( MODEM_LORA, rxConfig->bandwidth, phyDr, 1, 0, 8, + rxConfig->window_timeout, false, 0, false, 0, 0, true, + rxConfig->is_rx_continuous ); - if( rxConfig->RepeaterSupport == true ) + if( rxConfig->is_repeater_supported == true ) { maxPayload = MaxPayloadOfDatarateRepeaterUS915[dr]; } @@ -715,10 +715,10 @@ bool LoRaPHYUS915::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) } bool LoRaPHYUS915::tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - TimerTime_t* txTimeOnAir) + lorawan_time_t* txTimeOnAir) { int8_t phyDr = DataratesUS915[txConfig->Datarate]; - int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, Bands[Channels[txConfig->Channel].Band].TxMaxPower, txConfig->Datarate, ChannelsMask ); + int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, Bands[Channels[txConfig->Channel].band].max_tx_pwr, txConfig->Datarate, ChannelsMask ); uint32_t bandwidth = GetBandwidth( txConfig->Datarate ); int8_t phyTxPower = 0; @@ -726,7 +726,7 @@ bool LoRaPHYUS915::tx_config(TxConfigParams_t* txConfig, int8_t* txPower, phyTxPower = compute_tx_power( txPowerLimited, US915_DEFAULT_MAX_ERP, 0 ); // Setup the radio frequency - _radio->set_channel( Channels[txConfig->Channel].Frequency ); + _radio->set_channel( Channels[txConfig->Channel].frequency ); _radio->set_tx_config( MODEM_LORA, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 3000 ); @@ -938,13 +938,13 @@ void LoRaPHYUS915::calculate_backoff(CalcBackOffParams_t* calcBackOff) } bool LoRaPHYUS915::set_next_channel(NextChanParams_t* nextChanParams, - uint8_t* channel, TimerTime_t* time, - TimerTime_t* aggregatedTimeOff) + uint8_t* channel, lorawan_time_t* time, + lorawan_time_t* aggregatedTimeOff) { uint8_t nbEnabledChannels = 0; uint8_t delayTx = 0; uint8_t enabledChannels[US915_MAX_NB_CHANNELS] = { 0 }; - TimerTime_t nextTxDelay = 0; + lorawan_time_t nextTxDelay = 0; // Count 125kHz channels if( num_active_channels( ChannelsMaskRemaining, 0, 4 ) == 0 ) @@ -1003,21 +1003,21 @@ bool LoRaPHYUS915::set_next_channel(NextChanParams_t* nextChanParams, } } -LoRaMacStatus_t LoRaPHYUS915::add_channel(ChannelAddParams_t* channelAdd) +lorawan_status_t LoRaPHYUS915::add_channel(ChannelAddParams_t* channelAdd) { - return LORAMAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } bool LoRaPHYUS915::remove_channel(ChannelRemoveParams_t* channelRemove) { - return LORAMAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } void LoRaPHYUS915::set_tx_cont_mode(ContinuousWaveParams_t* continuousWave) { - int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, Bands[Channels[continuousWave->Channel].Band].TxMaxPower, continuousWave->Datarate, ChannelsMask ); + int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, Bands[Channels[continuousWave->Channel].band].max_tx_pwr, continuousWave->Datarate, ChannelsMask ); int8_t phyTxPower = 0; - uint32_t frequency = Channels[continuousWave->Channel].Frequency; + uint32_t frequency = Channels[continuousWave->Channel].frequency; // Calculate physical TX power phyTxPower = compute_tx_power( txPowerLimited, US915_DEFAULT_MAX_ERP, 0 ); diff --git a/features/lorawan/lorastack/phy/LoRaPHYUS915.h b/features/lorawan/lorastack/phy/LoRaPHYUS915.h index 22ca4ef322..88ab2ce391 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYUS915.h +++ b/features/lorawan/lorastack/phy/LoRaPHYUS915.h @@ -130,7 +130,7 @@ public: * * \retval True, if the configuration was applied successfully. */ - virtual bool rx_config(RxConfigParams_t* rxConfig, int8_t* datarate ); + virtual bool rx_config(rx_config_params_t* rxConfig, int8_t* datarate ); /* * RX window precise timing @@ -186,7 +186,7 @@ public: virtual void compute_rx_win_params(int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, - RxConfigParams_t *rxConfigParams); + rx_config_params_t *rxConfigParams); /*! * \brief TX configuration. @@ -200,7 +200,7 @@ public: * \retval True, if the configuration was applied successfully. */ virtual bool tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - TimerTime_t* txTimeOnAir ); + lorawan_time_t* txTimeOnAir ); /*! * \brief The function processes a Link ADR request. @@ -290,8 +290,8 @@ public: * \retval The function status [1: OK, 0: Unable to find a channel on the current datarate]. */ virtual bool set_next_channel(NextChanParams_t* nextChanParams, - uint8_t* channel, TimerTime_t* time, - TimerTime_t* aggregatedTimeOff ); + uint8_t* channel, lorawan_time_t* time, + lorawan_time_t* aggregatedTimeOff ); /*! * \brief Adds a channel. @@ -300,7 +300,7 @@ public: * * \retval The status of the operation. */ - virtual LoRaMacStatus_t add_channel(ChannelAddParams_t* channelAdd ); + virtual lorawan_status_t add_channel(ChannelAddParams_t* channelAdd ); /*! * \brief Removes a channel. @@ -333,18 +333,18 @@ public: private: int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower, int8_t datarate, uint16_t* channelsMask ); - uint8_t CountNbOfEnabledChannels( uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ); + uint8_t CountNbOfEnabledChannels( uint8_t datarate, uint16_t* channelsMask, channel_params_t* channels, band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ); // Global attributes /*! * LoRaMAC channels */ - ChannelParams_t Channels[US915_MAX_NB_CHANNELS]; + channel_params_t Channels[US915_MAX_NB_CHANNELS]; /*! * LoRaMac bands */ - Band_t Bands[US915_MAX_NB_BANDS]; + band_t Bands[US915_MAX_NB_BANDS]; /*! * LoRaMac channels mask diff --git a/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.cpp b/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.cpp index 393327f094..60aa4ac810 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.cpp @@ -354,7 +354,7 @@ static bool ValidateChannelsMask( uint16_t* channelsMask ) return chanMaskState; } -uint8_t LoRaPHYUS915Hybrid::CountNbOfEnabledChannels( uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ) +uint8_t LoRaPHYUS915Hybrid::CountNbOfEnabledChannels( uint8_t datarate, uint16_t* channelsMask, channel_params_t* channels, band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ) { uint8_t nbEnabledChannels = 0; uint8_t delayTransmission = 0; @@ -365,16 +365,16 @@ uint8_t LoRaPHYUS915Hybrid::CountNbOfEnabledChannels( uint8_t datarate, uint16_t { if( ( channelsMask[k] & ( 1 << j ) ) != 0 ) { - if( channels[i + j].Frequency == 0 ) + if( channels[i + j].frequency == 0 ) { // Check if the channel is enabled continue; } - if( val_in_range( datarate, channels[i + j].DrRange.Fields.Min, - channels[i + j].DrRange.Fields.Max ) == 0 ) + if( val_in_range( datarate, channels[i + j].dr_range.fields.min, + channels[i + j].dr_range.fields.max ) == 0 ) { // Check if the current channel selection supports the given datarate continue; } - if( bands[channels[i + j].Band].TimeOff > 0 ) + if( bands[channels[i + j].band].off_time > 0 ) { // Check if the band is available for transmission delayTransmission++; continue; @@ -391,7 +391,7 @@ uint8_t LoRaPHYUS915Hybrid::CountNbOfEnabledChannels( uint8_t datarate, uint16_t LoRaPHYUS915Hybrid::LoRaPHYUS915Hybrid(LoRaWANTimeHandler &lora_time) : LoRaPHY(lora_time) { - const Band_t band0 = US915_HYBRID_BAND0; + const band_t band0 = US915_HYBRID_BAND0; Bands[0] = band0; } @@ -544,7 +544,7 @@ PhyParam_t LoRaPHYUS915Hybrid::get_phy_params(GetPhyParams_t* getPhy) void LoRaPHYUS915Hybrid::set_band_tx_done(SetBandTxDoneParams_t* txDone) { - set_last_tx_done( txDone->Joined, &Bands[Channels[txDone->Channel].Band], txDone->LastTxDoneTime ); + set_last_tx_done( txDone->Joined, &Bands[Channels[txDone->Channel].band], txDone->LastTxDoneTime ); } void LoRaPHYUS915Hybrid::load_defaults(InitType_t type) @@ -557,16 +557,16 @@ void LoRaPHYUS915Hybrid::load_defaults(InitType_t type) // 125 kHz channels for( uint8_t i = 0; i < US915_HYBRID_MAX_NB_CHANNELS - 8; i++ ) { - Channels[i].Frequency = 902300000 + i * 200000; - Channels[i].DrRange.Value = ( DR_3 << 4 ) | DR_0; - Channels[i].Band = 0; + Channels[i].frequency = 902300000 + i * 200000; + Channels[i].dr_range.value = ( DR_3 << 4 ) | DR_0; + Channels[i].band = 0; } // 500 kHz channels for( uint8_t i = US915_HYBRID_MAX_NB_CHANNELS - 8; i < US915_HYBRID_MAX_NB_CHANNELS; i++ ) { - Channels[i].Frequency = 903000000 + ( i - ( US915_HYBRID_MAX_NB_CHANNELS - 8 ) ) * 1600000; - Channels[i].DrRange.Value = ( DR_4 << 4 ) | DR_4; - Channels[i].Band = 0; + Channels[i].frequency = 903000000 + ( i - ( US915_HYBRID_MAX_NB_CHANNELS - 8 ) ) * 1600000; + Channels[i].dr_range.value = ( DR_4 << 4 ) | DR_4; + Channels[i].band = 0; } // ChannelsMask @@ -747,35 +747,35 @@ bool LoRaPHYUS915Hybrid::get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut, } void LoRaPHYUS915Hybrid::compute_rx_win_params(int8_t datarate, uint8_t minRxSymbols, - uint32_t rxError, RxConfigParams_t *rxConfigParams) + uint32_t rxError, rx_config_params_t *rxConfigParams) { double tSymbol = 0.0; // Get the datarate, perform a boundary check - rxConfigParams->Datarate = MIN( datarate, US915_HYBRID_RX_MAX_DATARATE ); - rxConfigParams->Bandwidth = GetBandwidth( rxConfigParams->Datarate ); + rxConfigParams->datarate = MIN( datarate, US915_HYBRID_RX_MAX_DATARATE ); + rxConfigParams->bandwidth = GetBandwidth( rxConfigParams->datarate ); - tSymbol = compute_symb_timeout_lora( DataratesUS915_HYBRID[rxConfigParams->Datarate], BandwidthsUS915_HYBRID[rxConfigParams->Datarate] ); + tSymbol = compute_symb_timeout_lora( DataratesUS915_HYBRID[rxConfigParams->datarate], BandwidthsUS915_HYBRID[rxConfigParams->datarate] ); - get_rx_window_params( tSymbol, minRxSymbols, rxError, RADIO_WAKEUP_TIME, &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset ); + get_rx_window_params( tSymbol, minRxSymbols, rxError, RADIO_WAKEUP_TIME, &rxConfigParams->window_timeout, &rxConfigParams->window_offset ); } -bool LoRaPHYUS915Hybrid::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) +bool LoRaPHYUS915Hybrid::rx_config(rx_config_params_t* rxConfig, int8_t* datarate) { - int8_t dr = rxConfig->Datarate; + int8_t dr = rxConfig->datarate; uint8_t maxPayload = 0; int8_t phyDr = 0; - uint32_t frequency = rxConfig->Frequency; + uint32_t frequency = rxConfig->frequency; if( _radio->get_status() != RF_IDLE ) { return false; } - if( rxConfig->RxSlot == RX_SLOT_WIN_1 ) + if( rxConfig->rx_slot == RX_SLOT_WIN_1 ) { // Apply window 1 frequency - frequency = US915_HYBRID_FIRST_RX1_CHANNEL + ( rxConfig->Channel % 8 ) * US915_HYBRID_STEPWIDTH_RX1_CHANNEL; + frequency = US915_HYBRID_FIRST_RX1_CHANNEL + ( rxConfig->channel % 8 ) * US915_HYBRID_STEPWIDTH_RX1_CHANNEL; } // Read the physical datarate from the datarates table @@ -784,9 +784,9 @@ bool LoRaPHYUS915Hybrid::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) _radio->set_channel( frequency ); // Radio configuration - _radio->set_rx_config( MODEM_LORA, rxConfig->Bandwidth, phyDr, 1, 0, 8, rxConfig->WindowTimeout, false, 0, false, 0, 0, true, rxConfig->RxContinuous ); + _radio->set_rx_config( MODEM_LORA, rxConfig->bandwidth, phyDr, 1, 0, 8, rxConfig->window_timeout, false, 0, false, 0, 0, true, rxConfig->is_rx_continuous ); - if( rxConfig->RepeaterSupport == true ) + if( rxConfig->is_repeater_supported == true ) { maxPayload = MaxPayloadOfDatarateRepeaterUS915_HYBRID[dr]; } @@ -801,10 +801,10 @@ bool LoRaPHYUS915Hybrid::rx_config(RxConfigParams_t* rxConfig, int8_t* datarate) } bool LoRaPHYUS915Hybrid::tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - TimerTime_t* txTimeOnAir) + lorawan_time_t* txTimeOnAir) { int8_t phyDr = DataratesUS915_HYBRID[txConfig->Datarate]; - int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, Bands[Channels[txConfig->Channel].Band].TxMaxPower, txConfig->Datarate, ChannelsMask ); + int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, Bands[Channels[txConfig->Channel].band].max_tx_pwr, txConfig->Datarate, ChannelsMask ); uint32_t bandwidth = GetBandwidth( txConfig->Datarate ); int8_t phyTxPower = 0; @@ -812,7 +812,7 @@ bool LoRaPHYUS915Hybrid::tx_config(TxConfigParams_t* txConfig, int8_t* txPower, phyTxPower = compute_tx_power( txPowerLimited, US915_HYBRID_DEFAULT_MAX_ERP, 0 ); // Setup the radio frequency - _radio->set_channel( Channels[txConfig->Channel].Frequency ); + _radio->set_channel( Channels[txConfig->Channel].frequency ); _radio->set_tx_config( MODEM_LORA, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 3000 ); @@ -1029,13 +1029,13 @@ void LoRaPHYUS915Hybrid::calculate_backoff(CalcBackOffParams_t* calcBackOff) } bool LoRaPHYUS915Hybrid::set_next_channel(NextChanParams_t* nextChanParams, - uint8_t* channel, TimerTime_t* time, - TimerTime_t* aggregatedTimeOff) + uint8_t* channel, lorawan_time_t* time, + lorawan_time_t* aggregatedTimeOff) { uint8_t nbEnabledChannels = 0; uint8_t delayTx = 0; uint8_t enabledChannels[US915_HYBRID_MAX_NB_CHANNELS] = { 0 }; - TimerTime_t nextTxDelay = 0; + lorawan_time_t nextTxDelay = 0; // Count 125kHz channels if( num_active_channels( ChannelsMaskRemaining, 0, 4 ) == 0 ) @@ -1094,21 +1094,21 @@ bool LoRaPHYUS915Hybrid::set_next_channel(NextChanParams_t* nextChanParams, } } -LoRaMacStatus_t LoRaPHYUS915Hybrid::add_channel(ChannelAddParams_t* channelAdd) +lorawan_status_t LoRaPHYUS915Hybrid::add_channel(ChannelAddParams_t* channelAdd) { - return LORAMAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } bool LoRaPHYUS915Hybrid::remove_channel(ChannelRemoveParams_t* channelRemove) { - return LORAMAC_STATUS_PARAMETER_INVALID; + return LORAWAN_STATUS_PARAMETER_INVALID; } void LoRaPHYUS915Hybrid::set_tx_cont_mode(ContinuousWaveParams_t* continuousWave) { - int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, Bands[Channels[continuousWave->Channel].Band].TxMaxPower, continuousWave->Datarate, ChannelsMask ); + int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, Bands[Channels[continuousWave->Channel].band].max_tx_pwr, continuousWave->Datarate, ChannelsMask ); int8_t phyTxPower = 0; - uint32_t frequency = Channels[continuousWave->Channel].Frequency; + uint32_t frequency = Channels[continuousWave->Channel].frequency; // Calculate physical TX power phyTxPower = compute_tx_power( txPowerLimited, US915_HYBRID_DEFAULT_MAX_ERP, 0 ); diff --git a/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.h b/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.h index ae3dfb8f99..b894492665 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.h +++ b/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.h @@ -131,7 +131,7 @@ public: * * \retval True, if the configuration was applied successfully. */ - virtual bool rx_config(RxConfigParams_t* rxConfig, int8_t* datarate ); + virtual bool rx_config(rx_config_params_t* rxConfig, int8_t* datarate ); /* * RX window precise timing @@ -187,7 +187,7 @@ public: virtual void compute_rx_win_params(int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, - RxConfigParams_t *rxConfigParams); + rx_config_params_t *rxConfigParams); /*! * \brief TX configuration. @@ -201,7 +201,7 @@ public: * \retval True, if the configuration was applied successfully. */ virtual bool tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - TimerTime_t* txTimeOnAir ); + lorawan_time_t* txTimeOnAir ); /*! * \brief The function processes a Link ADR request. @@ -291,8 +291,8 @@ public: * \retval The function status [1: OK, 0: Unable to find a channel on the current datarate]. */ virtual bool set_next_channel(NextChanParams_t* nextChanParams, - uint8_t* channel, TimerTime_t* time, - TimerTime_t* aggregatedTimeOff ); + uint8_t* channel, lorawan_time_t* time, + lorawan_time_t* aggregatedTimeOff ); /*! * \brief Adds a channel. @@ -301,7 +301,7 @@ public: * * \retval The status of the operation. */ - virtual LoRaMacStatus_t add_channel(ChannelAddParams_t* channelAdd ); + virtual lorawan_status_t add_channel(ChannelAddParams_t* channelAdd ); /*! * \brief Removes a channel. @@ -334,18 +334,18 @@ public: private: int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower, int8_t datarate, uint16_t* channelsMask ); - uint8_t CountNbOfEnabledChannels( uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ); + uint8_t CountNbOfEnabledChannels( uint8_t datarate, uint16_t* channelsMask, channel_params_t* channels, band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ); // Global attributes /*! * LoRaMAC channels */ - ChannelParams_t Channels[US915_HYBRID_MAX_NB_CHANNELS]; + channel_params_t Channels[US915_HYBRID_MAX_NB_CHANNELS]; /*! * LoRaMac bands */ - Band_t Bands[US915_HYBRID_MAX_NB_BANDS]; + band_t Bands[US915_HYBRID_MAX_NB_BANDS]; /*! * LoRaMac channels mask diff --git a/features/lorawan/lorastack/phy/lora_phy_ds.h b/features/lorawan/lorastack/phy/lora_phy_ds.h index 3a9c10d9c7..b4d6351e3e 100644 --- a/features/lorawan/lorastack/phy/lora_phy_ds.h +++ b/features/lorawan/lorastack/phy/lora_phy_ds.h @@ -713,7 +713,7 @@ typedef union uPhyParam /*! * A pointer to the channels. */ - ChannelParams_t* Channels; + channel_params_t* Channels; }PhyParam_t; /*! @@ -761,7 +761,7 @@ typedef struct sSetBandTxDoneParams /*! * The last TX done time. */ - TimerTime_t LastTxDoneTime; + lorawan_time_t LastTxDoneTime; }SetBandTxDoneParams_t; /*! @@ -955,7 +955,7 @@ typedef struct sNewChannelReqParams /*! * A pointer to the new channels. */ - ChannelParams_t* NewChannel; + channel_params_t* NewChannel; /*! * The channel ID. */ @@ -1031,11 +1031,11 @@ typedef struct sCalcBackOffParams /*! * Elapsed time since the start of the node. */ - TimerTime_t ElapsedTime; + lorawan_time_t ElapsedTime; /*! * Time-on-air of the last transmission. */ - TimerTime_t TxTimeOnAir; + lorawan_time_t TxTimeOnAir; }CalcBackOffParams_t; /*! @@ -1046,11 +1046,11 @@ typedef struct sNextChanParams /*! * The aggregated time-off time. */ - TimerTime_t AggrTimeOff; + lorawan_time_t AggrTimeOff; /*! * The time of the last aggregated TX. */ - TimerTime_t LastAggrTx; + lorawan_time_t LastAggrTx; /*! * The current datarate. */ @@ -1073,7 +1073,7 @@ typedef struct sChannelAddParams /*! * A pointer to the new channel to add. */ - ChannelParams_t* NewChannel; + channel_params_t* NewChannel; /*! * The channel ID to add. */ diff --git a/features/lorawan/system/LoRaWANTimer.cpp b/features/lorawan/system/LoRaWANTimer.cpp index eaa80b2e44..ca5a8ce598 100644 --- a/features/lorawan/system/LoRaWANTimer.cpp +++ b/features/lorawan/system/LoRaWANTimer.cpp @@ -34,34 +34,34 @@ void LoRaWANTimeHandler::TimerTimeCounterInit(events::EventQueue *queue) _queue = queue; } -TimerTime_t LoRaWANTimeHandler::TimerGetCurrentTime( void ) +lorawan_time_t LoRaWANTimeHandler::TimerGetCurrentTime( void ) { const uint32_t current_time = _queue->tick(); - return (TimerTime_t)current_time; + return (lorawan_time_t)current_time; } -TimerTime_t LoRaWANTimeHandler::TimerGetElapsedTime( TimerTime_t savedTime ) +lorawan_time_t LoRaWANTimeHandler::TimerGetElapsedTime( lorawan_time_t savedTime ) { return TimerGetCurrentTime() - savedTime; } -void LoRaWANTimeHandler::TimerInit( TimerEvent_t *obj, mbed::Callback callback) +void LoRaWANTimeHandler::TimerInit( timer_event_t *obj, mbed::Callback callback) { obj->value = 0; - obj->Callback = callback; + obj->callback = callback; } -void LoRaWANTimeHandler::TimerStart( TimerEvent_t *obj ) +void LoRaWANTimeHandler::TimerStart( timer_event_t *obj ) { - obj->Timer.get()->attach_us( mbed::callback( obj->Callback ), obj->value * 1000 ); + obj->timer.get()->attach_us(obj->callback, obj->value * 1000 ); } -void LoRaWANTimeHandler::TimerStop( TimerEvent_t *obj ) +void LoRaWANTimeHandler::TimerStop( timer_event_t *obj ) { - obj->Timer.get()->detach( ); + obj->timer.get()->detach( ); } -void LoRaWANTimeHandler::TimerSetValue( TimerEvent_t *obj, uint32_t value ) +void LoRaWANTimeHandler::TimerSetValue( timer_event_t *obj, uint32_t value ) { obj->value = value; } diff --git a/features/lorawan/system/LoRaWANTimer.h b/features/lorawan/system/LoRaWANTimer.h index 90263110bb..797c29493c 100644 --- a/features/lorawan/system/LoRaWANTimer.h +++ b/features/lorawan/system/LoRaWANTimer.h @@ -49,14 +49,14 @@ public: * \param [in] obj The structure containing the timer object parameters. * \param [in] callback The function callback called at the end of the timeout. */ - void TimerInit( TimerEvent_t *obj, mbed::Callback callback); + void TimerInit( timer_event_t *obj, mbed::Callback callback); /*! * \brief Read the current time. * * \retval time The current time. */ - TimerTime_t TimerGetCurrentTime( void ); + lorawan_time_t TimerGetCurrentTime( void ); /*! * \brief Return the time elapsed since a fixed moment in time. @@ -64,7 +64,7 @@ public: * \param [in] savedTime The fixed moment in time. * \retval time The elapsed time. */ - TimerTime_t TimerGetElapsedTime( TimerTime_t savedTime ); + lorawan_time_t TimerGetElapsedTime( lorawan_time_t savedTime ); @@ -73,14 +73,14 @@ public: * * \param [in] obj The structure containing the timer object parameters. */ - void TimerStart( TimerEvent_t *obj ); + void TimerStart( timer_event_t *obj ); /*! * \brief Stops and removes the timer object from the list of timer events. * * \param [in] obj The structure containing the timer object parameters. */ - void TimerStop( TimerEvent_t *obj ); + void TimerStop( timer_event_t *obj ); /*! * \brief Set a new timeout value. @@ -88,7 +88,7 @@ public: * \param [in] obj The structure containing the timer object parameters. * \param [in] value The new timeout value. */ - void TimerSetValue( TimerEvent_t *obj, uint32_t value ); + void TimerSetValue( timer_event_t *obj, uint32_t value ); private: events::EventQueue *_queue; diff --git a/features/lorawan/system/lorawan_data_structures.h b/features/lorawan/system/lorawan_data_structures.h index b1d48845e3..dd97e07cee 100644 --- a/features/lorawan/system/lorawan_data_structures.h +++ b/features/lorawan/system/lorawan_data_structures.h @@ -31,8 +31,8 @@ /*! * \brief Timer time variable definition */ -#ifndef TimerTime_t -typedef uint32_t TimerTime_t; +#ifndef lorawan_time_t +typedef uint32_t lorawan_time_t; #endif // Radio wake-up time from sleep - unit ms. @@ -93,7 +93,7 @@ typedef uint32_t TimerTime_t; /** * Maximum PHY layer payload size for reception. */ -#define LORAMAC_PHY_MAXPAYLOAD 255 +#define LORAMAC_PHY_MAXPAYLOAD 255 /** * @@ -102,6 +102,7 @@ typedef uint32_t TimerTime_t; // reject if user tries to set more than MTU #if MBED_CONF_LORA_TX_MAX_SIZE > 255 #warning "Cannot set TX Max size more than MTU=255" + #define MBED_CONF_LORA_TX_MAX_SIZE 255 #endif /*! @@ -109,8 +110,7 @@ typedef uint32_t TimerTime_t; * * LoRaWAN Specification V1.0.2, chapter 2.1. */ -typedef enum eDeviceClass -{ +typedef enum { /*! * LoRaWAN device class A. * @@ -129,17 +129,16 @@ typedef enum eDeviceClass * LoRaWAN Specification V1.0.2, chapter 17. */ CLASS_C, -}DeviceClass_t; +} device_class_t; /*! * LoRaMAC channel parameters definition. */ -typedef union uDrRange -{ +typedef union { /*! * Byte-access to the bits. */ - int8_t Value; + int8_t value; /*! * The structure to store the minimum and the maximum datarate. */ @@ -152,7 +151,7 @@ typedef union uDrRange * * The allowed ranges are region-specific. Please refer to \ref DR_0 to \ref DR_15 for details. */ - int8_t Min : 4; + int8_t min : 4; /*! * The maximum data rate. * @@ -160,70 +159,66 @@ typedef union uDrRange * * The allowed ranges are region-specific. Please refer to \ref DR_0 to \ref DR_15 for details. */ - int8_t Max : 4; - }Fields; -}DrRange_t; + int8_t max : 4; + } fields; +} dr_range_t; /*! * LoRaMAC channel definition. */ -typedef struct sChannelParams -{ +typedef struct { /*! * The frequency in Hz. */ - uint32_t Frequency; + uint32_t frequency; /*! * The alternative frequency for RX window 1. */ - uint32_t Rx1Frequency; + uint32_t rx1_frequency; /*! * The data rate definition. */ - DrRange_t DrRange; + dr_range_t dr_range; /*! * The band index. */ - uint8_t Band; -}ChannelParams_t; + uint8_t band; +} channel_params_t; /*! * LoRaMAC band parameters definition. */ -typedef struct sBand -{ +typedef struct { /*! * The duty cycle. */ - uint16_t DCycle; + uint16_t duty_cycle; /*! * The maximum TX power. */ - int8_t TxMaxPower; + int8_t max_tx_pwr; /*! - * The timestamp of the last JoinReq TX frame. + * The timestamp of the last Join Request TX frame. */ - TimerTime_t LastJoinTxDoneTime; + lorawan_time_t last_join_tx_time; /*! * The timestamp of the last TX frame. */ - TimerTime_t LastTxDoneTime; + lorawan_time_t last_tx_time; /*! * The device off time. */ - TimerTime_t TimeOff; -}Band_t; - + lorawan_time_t off_time; +} band_t; /*! * LoRaMAC receive window 2 channel parameters. */ -typedef struct sRx2ChannelParams -{ +typedef struct { /*! * The frequency in Hz. */ - uint32_t Frequency; + uint32_t frequency; /*! * The data rate. * @@ -231,14 +226,13 @@ typedef struct sRx2ChannelParams * * The allowed ranges are region-specific. Please refer to \ref DR_0 to \ref DR_15 for details. */ - uint8_t Datarate; -}Rx2ChannelParams_t; + uint8_t datarate; +} rx2_channel_params; /*! * LoRaMAC receive window enumeration */ -typedef enum eLoRaMacRxSlot -{ +typedef enum { /*! * LoRaMAC receive window 1 */ @@ -255,131 +249,128 @@ typedef enum eLoRaMacRxSlot * LoRaMAC class b ping slot window */ RX_SLOT_WIN_PING_SLOT -}LoRaMacRxSlot_t; +} rx_slot_t; /*! * The global MAC layer parameters. */ -typedef struct sLoRaMacParams -{ +typedef struct { /*! * The TX power in channels. */ - int8_t ChannelsTxPower; + int8_t channel_tx_power; /*! * The data rate in channels. */ - int8_t ChannelsDatarate; + int8_t channel_data_rate; /*! * The system overall timing error in milliseconds. * [-SystemMaxRxError : +SystemMaxRxError] * Default: +/-10 ms */ - uint32_t SystemMaxRxError; + uint32_t max_sys_rx_error; /*! * The minimum number of symbols required to detect an RX frame. * Default: 6 symbols */ - uint8_t MinRxSymbols; + uint8_t min_rx_symb; /*! * LoRaMac maximum time a reception window stays open. */ - uint32_t MaxRxWindow; + uint32_t max_rx_win_time; /*! * Receive delay 1. */ - uint32_t ReceiveDelay1; + uint32_t recv_delay1; /*! * Receive delay 2. */ - uint32_t ReceiveDelay2; + uint32_t recv_delay2; /*! * Join accept delay 1. */ - uint32_t JoinAcceptDelay1; + uint32_t join_accept_delay1; /*! * Join accept delay 1. */ - uint32_t JoinAcceptDelay2; + uint32_t join_accept_delay2; /*! - * The number of uplink messages repetitions [1:15] (unconfirmed messages only). + * The number of uplink messages repetitions (confirmed messages only). */ - uint8_t ChannelsNbRep; + uint8_t retry_num; /*! * The datarate offset between uplink and downlink on first window. */ - uint8_t Rx1DrOffset; + uint8_t rx1_dr_offset; /*! * LoRaMAC 2nd reception window settings. */ - Rx2ChannelParams_t Rx2Channel; + rx2_channel_params rx2_channel; /*! * The uplink dwell time configuration. 0: No limit, 1: 400ms */ - uint8_t UplinkDwellTime; + uint8_t uplink_dwell_time; /*! * The downlink dwell time configuration. 0: No limit, 1: 400ms */ - uint8_t DownlinkDwellTime; + uint8_t downlink_dwell_time; /*! * The maximum possible EIRP. */ - float MaxEirp; + float max_eirp; /*! * The antenna gain of the node. */ - float AntennaGain; + float antenna_gain; /*! * Maximum duty cycle * \remark Possibility to shutdown the device. */ - uint8_t MaxDCycle; + uint8_t max_duty_cycle; /*! * Aggregated duty cycle management */ - uint16_t AggregatedDCycle; + uint16_t aggregated_duty_cycle; /*! * LoRaMac ADR control status */ - bool AdrCtrlOn; + bool adr_on; } lora_mac_system_params_t; /*! * LoRaMAC multicast channel parameter. */ -typedef struct sMulticastParams -{ +typedef struct multicast_params_s { /*! * Address. */ - uint32_t Address; + uint32_t address; /*! * Network session key. */ - uint8_t NwkSKey[16]; + uint8_t nwk_skey[16]; /*! * Application session key. */ - uint8_t AppSKey[16]; + uint8_t app_skey[16]; /*! * Downlink counter. */ - uint32_t DownLinkCounter; + uint32_t dl_frame_counter; /*! * A reference pointer to the next multicast channel parameters in the list. */ - struct sMulticastParams *Next; -}MulticastParams_t; + struct multicast_params_s *Next; +} multicast_params_t; /*! * LoRaMAC frame types. * * LoRaWAN Specification V1.0.2, chapter 4.2.1, table 1. */ -typedef enum eLoRaMacFrameType -{ +typedef enum { /*! * LoRaMAC join request frame. */ @@ -412,15 +403,14 @@ typedef enum eLoRaMacFrameType * LoRaMAC proprietary frame. */ FRAME_TYPE_PROPRIETARY = 0x07, -}LoRaMacFrameType_t; +} mac_frame_type_t; /*! * LoRaMAC mote MAC commands. * * LoRaWAN Specification V1.0.2, chapter 5, table 4. */ -typedef enum eLoRaMacMoteCmd -{ +typedef enum { /*! * LinkCheckReq */ @@ -457,15 +447,14 @@ typedef enum eLoRaMacMoteCmd * DlChannelAns */ MOTE_MAC_DL_CHANNEL_ANS = 0x0A -}LoRaMacMoteCmd_t; +} mote_mac_cmds_t; /*! * LoRaMAC server MAC commands. * * LoRaWAN Specification V1.0.2 chapter 5, table 4. */ -typedef enum eLoRaMacSrvCmd -{ +typedef enum { /*! * LinkCheckAns */ @@ -502,13 +491,12 @@ typedef enum eLoRaMacSrvCmd * DlChannelReq */ SRV_MAC_DL_CHANNEL_REQ = 0x0A, -}LoRaMacSrvCmd_t; +} server_mac_cmds_t; /*! * LoRaMAC battery level indicator. */ -typedef enum eLoRaMacBatteryLevel -{ +typedef enum { /*! * An external power source. */ @@ -525,28 +513,27 @@ typedef enum eLoRaMacBatteryLevel * Battery level - no measurement available. */ BAT_LEVEL_NO_MEASURE = 0xFF, -}LoRaMacBatteryLevel_t; +} device_battery_level_t; /*! * LoRaMAC header field definition (MHDR field). * * LoRaWAN Specification V1.0.2, chapter 4.2. */ -typedef union uLoRaMacHeader -{ +typedef union { /*! * Byte-access to the bits. */ - uint8_t Value; + uint8_t value; /*! * The structure containing single access to header bits. */ - struct sHdrBits + struct hdr_bits_s { /*! * Major version. */ - uint8_t Major : 2; + uint8_t major : 2; /*! * RFU */ @@ -554,54 +541,52 @@ typedef union uLoRaMacHeader /*! * Message type */ - uint8_t MType : 3; - }Bits; -}LoRaMacHeader_t; + uint8_t mtype : 3; + } bits; +} loramac_mhdr_t; /*! * LoRaMAC frame control field definition (FCtrl). * * LoRaWAN Specification V1.0.2, chapter 4.3.1. */ -typedef union uLoRaMacFrameCtrl -{ +typedef union { /*! * Byte-access to the bits. */ - uint8_t Value; + uint8_t value; /*! * The structure containing single access to bits. */ - struct sCtrlBits + struct ctrl_bits_s { /*! * Frame options length. */ - uint8_t FOptsLen : 4; + uint8_t fopts_len : 4; /*! * Frame pending bit. */ - uint8_t FPending : 1; + uint8_t fpending : 1; /*! * Message acknowledge bit. */ - uint8_t Ack : 1; + uint8_t ack : 1; /*! * ADR acknowledgment request bit. */ - uint8_t AdrAckReq : 1; + uint8_t adr_ack_req : 1; /*! * ADR control in the frame header. */ - uint8_t Adr : 1; - }Bits; -}LoRaMacFrameCtrl_t; + uint8_t adr : 1; + } bits; +} loramac_frame_ctrl_t; /*! * The enumeration containing the status of the operation of a MAC service. */ -typedef enum eLoRaMacEventInfoStatus -{ +typedef enum { /*! * Service performed successfully. */ @@ -661,48 +646,47 @@ typedef enum eLoRaMacEventInfoStatus * Crypto methods failure */ LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL, -}LoRaMacEventInfoStatus_t; +} loramac_event_info_status_t; /*! - * LoRaMac TX/RX operation state. + * LoRaMac service state flags. */ -typedef union eLoRaMacFlags_t -{ +typedef union { /*! * Byte-access to the bits. */ - uint8_t Value; + uint8_t value; /*! * The structure containing single access to bits. */ - struct sMacFlagBits + struct mac_flag_bits_s { /*! * MCPS-Req pending */ - uint8_t McpsReq : 1; + uint8_t mcps_req : 1; /*! * MCPS-Ind pending */ - uint8_t McpsInd : 1; + uint8_t mcps_ind : 1; /*! * MCPS-Ind pending. Skip indication to the application layer. */ - uint8_t McpsIndSkip : 1; + uint8_t mcps_ind_skip : 1; /*! * MLME-Req pending */ - uint8_t MlmeReq : 1; + uint8_t mlme_req : 1; /*! * MLME-Ind pending */ - uint8_t MlmeInd : 1; + uint8_t mlme_ind : 1; /*! * MAC cycle done */ - uint8_t MacDone : 1; - }Bits; -}LoRaMacFlags_t; + uint8_t mac_done : 1; + } bits; +} loramac_flags_t; /*! * @@ -727,8 +711,7 @@ typedef union eLoRaMacFlags_t * MCPS-Confirm | MacMcpsConfirm in \ref LoRaMacPrimitives_t * MCPS-Indication | MacMcpsIndication in \ref LoRaMacPrimitives_t */ -typedef enum eMcps -{ +typedef enum { /*! * Unconfirmed LoRaMAC frame. */ @@ -745,58 +728,42 @@ typedef enum eMcps * Proprietary frame. */ MCPS_PROPRIETARY, -}Mcps_t; +} mcps_type_t; /*! * LoRaMAC MCPS-Request for an unconfirmed frame. */ -typedef struct sMcpsReqUnconfirmed -{ +typedef struct { /*! * Frame port field. Must be set if the payload is not empty. Use the * application-specific frame port values: [1...223]. * * LoRaWAN Specification V1.0.2, chapter 4.3.2. */ - uint8_t fPort; - /*! - * A pointer to the buffer of the frame payload. - */ - void *fBuffer; - /*! - * The size of the frame payload. - */ - uint16_t fBufferSize; + uint8_t fport; + /*! * Uplink datarate, if ADR is off. */ - int8_t Datarate; -}McpsReqUnconfirmed_t; + int8_t data_rate; +} mcps_req_unconfirmed_t; /*! * LoRaMAC MCPS-Request for a confirmed frame. */ -typedef struct sMcpsReqConfirmed -{ +typedef struct { /*! * Frame port field. Must be set if the payload is not empty. Use the * application-specific frame port values: [1...223]. * * LoRaWAN Specification V1.0.2, chapter 4.3.2. */ - uint8_t fPort; - /*! - * A pointer to the buffer of the frame payload. - */ - void *fBuffer; - /*! - * The size of the frame payload. - */ - uint16_t fBufferSize; + uint8_t fport; + /*! * Uplink datarate, if ADR is off. */ - int8_t Datarate; + int8_t data_rate; /*! * The number of trials to transmit the frame, if the LoRaMAC layer did not * receive an acknowledgment. The MAC performs a datarate adaptation @@ -814,168 +781,169 @@ typedef struct sMcpsReqConfirmed * 7 | max(DR-3,0) * 8 | max(DR-3,0) * - * Note that if NbTrials is set to 1 or 2, the MAC will not decrease + * Note that if nb_trials is set to 1 or 2, the MAC will not decrease * the datarate, if the LoRaMAC layer did not receive an acknowledgment. */ - uint8_t NbTrials; -}McpsReqConfirmed_t; + uint8_t nb_trials; +} mcps_req_confirmed_t; /*! * LoRaMAC MCPS-Request for a proprietary frame. */ -typedef struct sMcpsReqProprietary -{ - /*! - * A pointer to the buffer of the frame payload. - */ - void *fBuffer; - /*! - * The size of the frame payload. - */ - uint16_t fBufferSize; +typedef struct { /*! * Uplink datarate, if ADR is off. */ - int8_t Datarate; -}McpsReqProprietary_t; + int8_t data_rate; +} mcps_req_proprietary_t; /*! * LoRaMAC MCPS-Request structure. */ -typedef struct sMcpsReq -{ +typedef struct { /*! * MCPS-Request type. */ - Mcps_t Type; + mcps_type_t type; /*! * MCPS-Request parameters. */ - union uMcpsParam + union { /*! * MCPS-Request parameters for an unconfirmed frame. */ - McpsReqUnconfirmed_t Unconfirmed; + mcps_req_unconfirmed_t unconfirmed; /*! * MCPS-Request parameters for a confirmed frame. */ - McpsReqConfirmed_t Confirmed; + mcps_req_confirmed_t confirmed; /*! * MCPS-Request parameters for a proprietary frame. */ - McpsReqProprietary_t Proprietary; - }Req; -}McpsReq_t; + mcps_req_proprietary_t proprietary; + } req; + + /** Payload data + * + * A pointer to the buffer of the frame payload. + */ + void *f_buffer; + /** Payload size + * + * The size of the frame payload. + */ + uint16_t f_buffer_size; + +} loramac_mcps_req_t; /*! * LoRaMAC MCPS-Confirm. */ -typedef struct sMcpsConfirm -{ +typedef struct { /*! - * Holds the previously performed MCPS-Request. + * Holds the previously performed MCPS-Request type. i.e., the type of + * the MCPS request for which this confirmation is being generated */ - Mcps_t McpsRequest; + mcps_type_t req_type; /*! * The status of the operation. */ - LoRaMacEventInfoStatus_t Status; + loramac_event_info_status_t status; /*! * The uplink datarate. */ - uint8_t Datarate; + uint8_t data_rate; /*! * The transmission power. */ - int8_t TxPower; + int8_t tx_power; /*! * Set if an acknowledgement was received. */ - bool AckReceived; + bool ack_received; /*! * Provides the number of retransmissions. */ - uint8_t NbRetries; + uint8_t nb_retries; /*! * The transmission time on air of the frame. */ - TimerTime_t TxTimeOnAir; + lorawan_time_t tx_toa; /*! * The uplink counter value related to the frame. */ - uint32_t UpLinkCounter; + uint32_t ul_frame_counter; /*! * The uplink frequency related to the frame. */ - uint32_t UpLinkFrequency; -}McpsConfirm_t; + uint32_t ul_frequency; +} loramac_mcps_confirm_t; /*! * LoRaMAC MCPS-Indication primitive. */ -typedef struct sMcpsIndication -{ +typedef struct { /*! * MCPS-Indication type. */ - Mcps_t McpsIndication; + mcps_type_t type; /*! * The status of the operation. */ - LoRaMacEventInfoStatus_t Status; + loramac_event_info_status_t status; /*! * Multicast. */ - uint8_t Multicast; + uint8_t multicast; /*! * The application port. */ - uint8_t Port; + uint8_t port; /*! * The downlink datarate. */ - uint8_t RxDatarate; + uint8_t rx_datarate; /*! * Frame pending status. */ - uint8_t FramePending; + uint8_t fpending_status; /*! * A pointer to the received data stream. */ - uint8_t *Buffer; + uint8_t *buffer; /*! * The size of the received data stream. */ - uint8_t BufferSize; + uint16_t buffer_size; /*! * Indicates, if data is available. */ - bool RxData; + bool is_data_recvd; /*! * The RSSI of the received packet. */ - int16_t Rssi; + int16_t rssi; /*! * The SNR of the received packet. */ - uint8_t Snr; + uint8_t snr; /*! * The receive window. * * [0: Rx window 1, 1: Rx window 2] */ - LoRaMacRxSlot_t RxSlot; + rx_slot_t rx_slot; /*! * Set if an acknowledgement was received. */ - bool AckReceived; + bool is_ack_recvd; /*! * The downlink counter value for the received frame. */ - uint32_t DownLinkCounter; -}McpsIndication_t; + uint32_t dl_frame_counter; +} loramac_mcps_indication_t; /*! * \brief LoRaMAC management services. @@ -999,8 +967,7 @@ typedef struct sMcpsIndication * MLME-Confirm | MacMlmeConfirm in \ref LoRaMacPrimitives_t * MLME-Indication | MacMlmeIndication in \ref LoRaMacPrimitives_t */ -typedef enum eMlme -{ +typedef enum { /*! * Initiates the Over-the-Air activation. * @@ -1030,124 +997,119 @@ typedef enum eMlme * soon as possible. */ MLME_SCHEDULE_UPLINK -}Mlme_t; +} mlme_type_t; /*! * LoRaMAC MLME-Request for the join service. */ -typedef struct sMlmeReqJoin -{ +typedef struct { /*! * A globally unique end-device identifier. * * LoRaWAN Specification V1.0.2, chapter 6.2.1. */ - uint8_t *DevEui; + uint8_t *dev_eui; /*! * An application identifier. * * LoRaWAN Specification V1.0.2, chapter 6.1.2 */ - uint8_t *AppEui; + uint8_t *app_eui; /*! * AES-128 application key. * * LoRaWAN Specification V1.0.2, chapter 6.2.2. */ - uint8_t *AppKey; + uint8_t *app_key; /*! * The number of trials for the join request. */ - uint8_t NbTrials; -}MlmeReqJoin_t; + uint8_t nb_trials; +} mlme_join_req_t; /*! * LoRaMAC MLME-Request for TX continuous wave mode. */ -typedef struct sMlmeReqTxCw -{ +typedef struct { /*! * The time while the radio is kept in continuous wave mode, in seconds. */ - uint16_t Timeout; + uint16_t timeout; /*! * The RF frequency to set (only used with the new way). */ - uint32_t Frequency; + uint32_t frequency; /*! * The RF output power to set (only used with the new way). */ - uint8_t Power; -}MlmeReqTxCw_t; + uint8_t power; +} mlme_cw_tx_mode_t; /*! * LoRaMAC MLME-Request structure. */ -typedef struct sMlmeReq -{ +typedef struct { /*! * MLME-Request type. */ - Mlme_t Type; + mlme_type_t type; /*! * MLME-Request parameters. */ - union uMlmeParam - { + union { /*! * MLME-Request parameters for a join request. */ - MlmeReqJoin_t Join; + mlme_join_req_t join; /*! * MLME-Request parameters for TX continuous mode request. */ - MlmeReqTxCw_t TxCw; - }Req; -}MlmeReq_t; + mlme_cw_tx_mode_t cw_tx_mode; + } req; +} loramac_mlme_req_t; /*! * LoRaMAC MLME-Confirm primitive. */ -typedef struct sMlmeConfirm -{ +typedef struct { /*! - * The previously performed MLME-Request. + * The previously performed MLME-Request. i.e., the request type + * for which the confirmation is being generated */ - Mlme_t MlmeRequest; + mlme_type_t req_type; /*! * The status of the operation. */ - LoRaMacEventInfoStatus_t Status; + loramac_event_info_status_t status; /*! * The transmission time on air of the frame. */ - TimerTime_t TxTimeOnAir; + lorawan_time_t tx_toa; /*! * The demodulation margin. Contains the link margin [dB] of the last LinkCheckReq * successfully received. */ - uint8_t DemodMargin; + uint8_t demod_margin; /*! * The number of gateways which received the last LinkCheckReq. */ - uint8_t NbGateways; + uint8_t nb_gateways; /*! * The number of retransmissions. */ - uint8_t NbRetries; -}MlmeConfirm_t; + uint8_t nb_retries; +} loramac_mlme_confirm_t; /*! * LoRaMAC MLME-Indication primitive */ -typedef struct sMlmeIndication -{ +typedef struct { /*! * MLME-Indication type */ - Mlme_t MlmeIndication; -}MlmeIndication_t; + mlme_type_t indication_type; +} loramac_mlme_indication_t; /*! * LoRa MAC Information Base (MIB). @@ -1194,8 +1156,7 @@ typedef struct sMlmeIndication * MIB-Set | \ref LoRaMacMibSetRequestConfirm * MIB-Get | \ref LoRaMacMibGetRequestConfirm */ -typedef enum eMib -{ +typedef enum { /*! * LoRaWAN device class. * @@ -1392,333 +1353,283 @@ typedef enum eMib * radioTxPower = ( int8_t )floor( maxEirp - antennaGain ) */ MIB_ANTENNA_GAIN -}Mib_t; +} mib_type_t; /*! * LoRaMAC MIB parameters. */ -typedef union uMibParam -{ +typedef union { /*! * LoRaWAN device class. * * Related MIB type: \ref MIB_DEVICE_CLASS */ - DeviceClass_t Class; + device_class_t dev_class; /*! * LoRaWAN network joined attribute * * Related MIB type: \ref MIB_NETWORK_JOINED */ - bool IsNetworkJoined; + bool is_nwk_joined; /*! * Activation state of ADR * * Related MIB type: \ref MIB_ADR */ - bool AdrEnable; + bool is_adr_enable; /*! * Network identifier * * Related MIB type: \ref MIB_NET_ID */ - uint32_t NetID; + uint32_t net_id; /*! * End-device address * * Related MIB type: \ref MIB_DEV_ADDR */ - uint32_t DevAddr; + uint32_t dev_addr; /*! * Network session key * * Related MIB type: \ref MIB_NWK_SKEY */ - uint8_t *NwkSKey; + uint8_t *nwk_skey; /*! * Application session key * * Related MIB type: \ref MIB_APP_SKEY */ - uint8_t *AppSKey; + uint8_t *app_skey; /*! * Enable or disable a public network * * Related MIB type: \ref MIB_PUBLIC_NETWORK */ - bool EnablePublicNetwork; + bool enable_public_nwk; /*! * Enable or disable repeater support * * Related MIB type: \ref MIB_REPEATER_SUPPORT */ - bool EnableRepeaterSupport; + bool enable_repeater_support; /*! * LoRaWAN channel * * Related MIB type: \ref MIB_CHANNELS */ - ChannelParams_t* ChannelList; + channel_params_t* channel_list; /*! * Channel for the receive window 2 * * Related MIB type: \ref MIB_RX2_CHANNEL */ - Rx2ChannelParams_t Rx2Channel; + rx2_channel_params rx2_channel; /*! * Channel for the receive window 2 * * Related MIB type: \ref MIB_RX2_DEFAULT_CHANNEL */ - Rx2ChannelParams_t Rx2DefaultChannel; + rx2_channel_params default_rx2_channel; /*! * Channel mask * * Related MIB type: \ref MIB_CHANNELS_MASK */ - uint16_t* ChannelsMask; + uint16_t* channel_mask; /*! * Default channel mask * * Related MIB type: \ref MIB_CHANNELS_DEFAULT_MASK */ - uint16_t* ChannelsDefaultMask; + uint16_t* default_channel_mask; /*! * Number of frame repetitions * * Related MIB type: \ref MIB_CHANNELS_NB_REP */ - uint8_t ChannelNbRep; + uint8_t channel_nb_rep; /*! * Maximum receive window duration * * Related MIB type: \ref MIB_MAX_RX_WINDOW_DURATION */ - uint32_t MaxRxWindow; + uint32_t max_rx_window; /*! * Receive delay 1 * * Related MIB type: \ref MIB_RECEIVE_DELAY_1 */ - uint32_t ReceiveDelay1; + uint32_t recv_delay1; /*! * Receive delay 2 * * Related MIB type: \ref MIB_RECEIVE_DELAY_2 */ - uint32_t ReceiveDelay2; + uint32_t recv_delay2; /*! * Join accept delay 1 * * Related MIB type: \ref MIB_JOIN_ACCEPT_DELAY_1 */ - uint32_t JoinAcceptDelay1; + uint32_t join_accept_delay1; /*! * Join accept delay 2 * * Related MIB type: \ref MIB_JOIN_ACCEPT_DELAY_2 */ - uint32_t JoinAcceptDelay2; + uint32_t join_accept_delay2; /*! * Channels data rate * * Related MIB type: \ref MIB_CHANNELS_DEFAULT_DATARATE */ - int8_t ChannelsDefaultDatarate; + int8_t default_channel_data_rate; /*! * Channels data rate * * Related MIB type: \ref MIB_CHANNELS_DATARATE */ - int8_t ChannelsDatarate; + int8_t channel_data_rate; /*! * Channels TX power * * Related MIB type: \ref MIB_CHANNELS_DEFAULT_TX_POWER */ - int8_t ChannelsDefaultTxPower; + int8_t default_channel_tx_pwr; /*! * Channels TX power * * Related MIB type: \ref MIB_CHANNELS_TX_POWER */ - int8_t ChannelsTxPower; + int8_t channel_tx_pwr; /*! * LoRaWAN uplink counter * * Related MIB type: \ref MIB_UPLINK_COUNTER */ - uint32_t UpLinkCounter; + uint32_t ul_frame_counter; /*! * LoRaWAN downlink counter * * Related MIB type: \ref MIB_DOWNLINK_COUNTER */ - uint32_t DownLinkCounter; + uint32_t dl_frame_counter; /*! * Multicast channel * * Related MIB type: \ref MIB_MULTICAST_CHANNEL */ - MulticastParams_t* MulticastList; + multicast_params_t* multicast_list; /*! * System overall timing error in milliseconds * * Related MIB type: \ref MIB_SYSTEM_MAX_RX_ERROR */ - uint32_t SystemMaxRxError; + uint32_t max_rx_sys_error; /*! * Minimum required number of symbols to detect an RX frame * * Related MIB type: \ref MIB_MIN_RX_SYMBOLS */ - uint8_t MinRxSymbols; + uint8_t min_rx_symb; /*! * Antenna gain * * Related MIB type: \ref MIB_ANTENNA_GAIN */ - float AntennaGain; -}MibParam_t; + float antenna_gain; +} mib_params_t; /*! * LoRaMAC MIB-RequestConfirm structure */ -typedef struct eMibRequestConfirm -{ +typedef struct { /*! * MIB-Request type */ - Mib_t Type; + mib_type_t type; /*! * MLME-RequestConfirm parameters */ - MibParam_t Param; -}MibRequestConfirm_t; + mib_params_t param; +}loramac_mib_req_confirm_t; /*! * LoRaMAC TX information */ -typedef struct sLoRaMacTxInfo -{ +typedef struct { /*! * Defines the size of the applicable payload that can be processed. */ - uint8_t MaxPossiblePayload; + uint8_t max_possible_payload_size; /*! * The current payload size, dependent on the current datarate. */ - uint8_t CurrentPayloadSize; -}LoRaMacTxInfo_t; + uint8_t current_payload_size; +} loramac_tx_info_t; -/*! - * LoRaMAC status. +/** LoRaMAC status. + * */ -typedef enum eLoRaMacStatus -{ - /*! - * Service started successfully. - */ - LORAMAC_STATUS_OK, - /*! - * Service not started - LoRaMAC is busy. - */ - LORAMAC_STATUS_BUSY, - /*! - * Service unknown. - */ - LORAMAC_STATUS_SERVICE_UNKNOWN, - /*! - * Service not started - invalid parameter. - */ - LORAMAC_STATUS_PARAMETER_INVALID, - /*! - * Service not started - invalid frequency. - */ - LORAMAC_STATUS_FREQUENCY_INVALID, - /*! - * Service not started - invalid datarate. - */ - LORAMAC_STATUS_DATARATE_INVALID, - /*! - * Service not started - invalid frequency and datarate. - */ - LORAMAC_STATUS_FREQ_AND_DR_INVALID, - /*! - * Service not started - the device is not in a LoRaWAN. - */ - LORAMAC_STATUS_NO_NETWORK_JOINED, - /*! - * Service not started - payload length error. - */ - LORAMAC_STATUS_LENGTH_ERROR, - /*! - * Service not started - the device is switched off. - */ - LORAMAC_STATUS_DEVICE_OFF, - /*! - * Service not started - the specified region is not supported - * or not activated with preprocessor definitions. - */ - LORAMAC_STATUS_REGION_NOT_SUPPORTED, - /*! - * Crypto methods failure. - */ - LORAMAC_STATUS_CRYPTO_FAIL, -}LoRaMacStatus_t; +typedef enum lorawan_status { + LORAWAN_STATUS_OK = 0, /**< Service started successfully */ + LORAWAN_STATUS_BUSY = -1000, /**< Service not started - LoRaMAC is busy */ + LORAWAN_STATUS_WOULD_BLOCK = -1001, /**< LoRaMAC cannot send at the moment or have nothing to read */ + LORAWAN_STATUS_SERVICE_UNKNOWN = -1002, /**< Service unknown */ + LORAWAN_STATUS_PARAMETER_INVALID = -1003, /**< Service not started - invalid parameter */ + LORAWAN_STATUS_FREQUENCY_INVALID = -1004, /**< Service not started - invalid frequency */ + LORAWAN_STATUS_DATARATE_INVALID = -1005, /**< Service not started - invalid datarate */ + LORAWAN_STATUS_FREQ_AND_DR_INVALID = -1006, /**< Service not started - invalid frequency and datarate */ + LORAWAN_STATUS_NO_NETWORK_JOINED = -1009, /**< Service not started - the device is not in a LoRaWAN */ + LORAWAN_STATUS_LENGTH_ERROR = -1010, /**< Service not started - payload lenght error */ + LORAWAN_STATUS_DEVICE_OFF = -1011, /**< Service not started - the device is switched off */ + LORAWAN_STATUS_NOT_INITIALIZED = -1012, /**< Service not started - stack not initialized */ + LORAWAN_STATUS_UNSUPPORTED = -1013, /**< Service not supported */ + LORAWAN_STATUS_CRYPTO_FAIL = -1014, /**< Service not started - crypto failure */ + LORAWAN_STATUS_PORT_INVALID = -1015, /**< Invalid port */ + LORAWAN_STATUS_CONNECT_IN_PROGRESS = -1016, /**< Services started - Connection in progress */ + LORAWAN_STATUS_NO_ACTIVE_SESSIONS = -1017, /**< Services not started - No active session */ + LORAWAN_STATUS_IDLE = -1018, /**< Services started - Idle at the moment */ +#if defined(LORAWAN_COMPLIANCE_TEST) + LORAWAN_STATUS_COMPLIANCE_TEST_ON = -1019, /**< Compliance test - is on-going */ +#endif +} lorawan_status_t; /*! * LoRaMAC events structure. * Used to notify upper layers of MAC events. */ -typedef struct sLoRaMacPrimitives -{ +typedef struct { /*! * \brief MCPS-Confirm primitive. * * \param [OUT] MCPS-Confirm parameters. */ - mbed::Callback MacMcpsConfirm; + mbed::Callback mcps_confirm; /*! * \brief MCPS-Indication primitive. * * \param [OUT] MCPS-Indication parameters. */ - mbed::Callback MacMcpsIndication; + mbed::Callback mcps_indication; /*! * \brief MLME-Confirm primitive. * * \param [OUT] MLME-Confirm parameters. */ - mbed::Callback MacMlmeConfirm; + mbed::Callback mlme_confirm; /*! * \brief MLME-Indication primitive * * \param [OUT] MLME-Indication parameters */ - mbed::Callback MacMlmeIndication; -}LoRaMacPrimitives_t; - -/*! - * LoRaMAC callback structure. - */ -typedef struct sLoRaMacCallback -{ - /*! - * \brief Measures the battery level. - * - * \retval The battery level [0: node is connected to an external - * power source, 1..254: battery level, where 1 is the minimum - * and 254 is the maximum value, 255: the node was not able - * to measure the battery level]. - */ - uint8_t ( *GetBatteryLevel )( void ); - -}LoRaMacCallback_t; + mbed::Callback mlme_indication; +}loramac_primitives_t; /** End-device states. * @@ -1751,7 +1662,7 @@ typedef enum lorawan_connect_type { * A structure representing the LoRaWAN Over The Air Activation * parameters. */ -typedef struct lorawan_connect_otaa { +typedef struct { /** End-device identifier * * LoRaWAN Specification V1.0.2, chapter 6.2.1 @@ -1779,7 +1690,7 @@ typedef struct lorawan_connect_otaa { * A structure representing the LoRaWAN Activation By Personalization * parameters. */ -typedef struct lorawan_connect_abp { +typedef struct { /** Network identifier * * LoRaWAN Specification V1.0.2, chapter 6.1.1 @@ -1802,104 +1713,10 @@ typedef struct lorawan_connect_abp { uint8_t *app_skey; } lorawan_connect_abp_t; -/** LoRaMAC data services - * +/** + * Stack level TX message structure */ -typedef enum lora_mac_mcps { - LORA_MCPS_UNCONFIRMED = 0, /**< Unconfirmed LoRaMAC frame */ - LORA_MCPS_CONFIRMED, /**< Confirmed LoRaMAC frame */ - LORA_MCPS_MULTICAST, /**< Multicast LoRaMAC frame */ - LORA_MCPS_PROPRIETARY, /**< Proprietary frame */ -} lora_mac_mcps_t; - -/** LoRaMAC management services - * - */ -typedef enum lora_mac_mlme { - LORA_MLME_JOIN, /**< Initiates the Over-the-Air activation */ - LORA_MLME_LINK_CHECK, /**< LinkCheckReq - Connectivity validation */ - LORA_MLME_TXCW, /**< Sets Tx continuous wave mode */ - LORA_MLME_TXCW_1, /**< Sets Tx continuous wave mode (new LoRa-Alliance CC definition) */ -} lora_mac_mlme_t; - -/** Unconfirmed message. - * - * A message for an unconfirmed frame. - */ -typedef struct lora_mac_unconfirmed { - /** Frame port field. - * - * Must be set if the payload is not empty. Use the - * application-specific frame port values: [1...223] - * - * LoRaWAN Specification V1.0.2, chapter 4.3.2 - */ - uint8_t f_port; - /** Uplink datarate - * - * Used if ADR is off - */ - int8_t datarate; -} lora_mac_unconfirmed_t; - -/** Confirmed message. - * - * A message for a confirmed frame. - */ -typedef struct lora_mac_confirmed { - /** Frame port field. - * - * Must be set if the payload is not empty. Use the - * application-specific frame port values: [1...223] - * - * LoRaWAN Specification V1.0.2, chapter 4.3.2 - */ - uint8_t f_port; - /** Uplink datarate. - * - * Used if ADR is off. - */ - int8_t datarate; - /** Number of trials. - * - * The number of trials to transmit the frame, if the LoRaMAC layer did not - * receive an acknowledgment. The MAC performs a datarate adaptation - * according to the LoRaWAN Specification V1.0.2, chapter 18.4, as in - * the following table: - * - * Transmission nb | Data Rate - * ----------------|----------- - * 1 (first) | DR - * 2 | DR - * 3 | max(DR-1,0) - * 4 | max(DR-1,0) - * 5 | max(DR-2,0) - * 6 | max(DR-2,0) - * 7 | max(DR-3,0) - * 8 | max(DR-3,0) - * - * Note that if NbTrials is set to 1 or 2, the MAC does not decrease - * the datarate, if the LoRaMAC layer did not receive an acknowledgment. - */ - uint8_t nb_trials; -} lora_mac_confirmed_t; - -/** A proprietary message. - * - * A message for a proprietary frame. - */ -typedef struct lora_mac_proprietary { - /** Uplink datarate. - * - * Used if ADR is off. - */ - int8_t datarate; -} lora_mac_proprietary_t; - -/** LoRaMAC message structure. - * - */ -typedef struct lora_mac_tx_message { +typedef struct { /** * TX Ongoing flag @@ -1914,7 +1731,7 @@ typedef struct lora_mac_tx_message { /** * Message type */ - lora_mac_mcps_t type; + mcps_type_t type; /** Message parameters. * */ @@ -1923,17 +1740,17 @@ typedef struct lora_mac_tx_message { * * The message parameters for an unconfirmed frame. */ - lora_mac_unconfirmed_t unconfirmed; + mcps_req_unconfirmed_t unconfirmed; /** A confirmed frame. * * The message parameters for a confirmed frame. */ - lora_mac_confirmed_t confirmed; + mcps_req_confirmed_t confirmed; /** A proprietary frame. * * The message parameters for a proprietary frame. */ - lora_mac_proprietary_t proprietary; + mcps_req_proprietary_t proprietary; } message_u; /** Payload data @@ -1953,476 +1770,48 @@ typedef struct lora_mac_tx_message { */ uint16_t pending_size; -} lora_mac_tx_message_t; - -/** LoRaMAC status. - * - */ -typedef enum lora_mac_status { - LORA_MAC_STATUS_OK = 0, /**< Service started successfully */ - LORA_MAC_STATUS_BUSY = -1000, /**< Service not started - LoRaMAC is busy */ - LORA_MAC_STATUS_WOULD_BLOCK = -1001, /**< LoRaMAC cannot send at the moment or have nothing to read */ - LORA_MAC_STATUS_SERVICE_UNKNOWN = -1002, /**< Service unknown */ - LORA_MAC_STATUS_PARAMETER_INVALID = -1003, /**< Service not started - invalid parameter */ - LORA_MAC_STATUS_FREQUENCY_INVALID = -1004, /**< Service not started - invalid frequency */ - LORA_MAC_STATUS_DATARATE_INVALID = -1005, /**< Service not started - invalid datarate */ - LORA_MAC_STATUS_FREQ_AND_DR_INVALID = -1006, /**< Service not started - invalid frequency and datarate */ - LORA_MAC_STATUS_NO_NETWORK_JOINED = -1009, /**< Service not started - the device is not in a LoRaWAN */ - LORA_MAC_STATUS_LENGTH_ERROR = -1010, /**< Service not started - payload lenght error */ - LORA_MAC_STATUS_DEVICE_OFF = -1011, /**< Service not started - the device is switched off */ - LORA_MAC_STATUS_NOT_INITIALIZED = -1012, /**< Service not started - stack not initialized */ - LORA_MAC_STATUS_UNSUPPORTED = -1013, /**< Service not supported */ - LORA_MAC_STATUS_CRYPTO_FAIL = -1014, /**< Service not started - crypto failure */ - LORA_MAC_STATUS_PORT_INVALID = -1015, /**< Invalid port */ - LORA_MAC_STATUS_CONNECT_IN_PROGRESS = -1016, /**< Services started - Connection in progress */ - LORA_MAC_STATUS_NO_ACTIVE_SESSIONS = -1017, /**< Services not started - No active session */ - LORA_MAC_STATUS_IDLE = -1018, /**< Services started - Idle at the moment */ -#if defined(LORAWAN_COMPLIANCE_TEST) - LORA_MAC_STATUS_COMPLIANCE_TEST_ON = -1019, /**< Compliance test - is on-going */ -#endif -} lora_mac_status_t; - -/** - * - * Enumeration containing the status of the operation of a MAC service - */ -typedef enum lora_mac_event_info_status { - LORA_EVENT_INFO_STATUS_OK = 0, /**< Service performed successfully */ - LORA_EVENT_INFO_STATUS_ERROR, /**< An error occurred during the execution of the service */ - LORA_EVENT_INFO_STATUS_TX_TIMEOUT, /**< A TX timeout occurred */ - LORA_EVENT_INFO_STATUS_RX1_TIMEOUT, /**< An RX timeout occurred on receive window 1 */ - LORA_EVENT_INFO_STATUS_RX2_TIMEOUT, /**< An RX timeout occurred on receive window 2 */ - LORA_EVENT_INFO_STATUS_RX1_ERROR, /**< An RX error occurred on receive window 1 */ - LORA_EVENT_INFO_STATUS_RX2_ERROR, /**< An RX error occurred on receive window 2 */ - LORA_EVENT_INFO_STATUS_JOIN_FAIL, /**< An error occurred in the join procedure */ - LORA_EVENT_INFO_STATUS_DOWNLINK_REPEATED, /**< A frame with an invalid downlink counter */ - LORA_EVENT_INFO_STATUS_TX_DR_PAYLOAD_SIZE_ERROR, /**< Payload size is not applicable for the datarate */ - LORA_EVENT_INFO_STATUS_DOWNLINK_TOO_MANY_FRAMES_LOSS, /**< The node has lost MAX_FCNT_GAP or more frames. */ - LORA_EVENT_INFO_STATUS_ADDRESS_FAIL, /**< An address error occurred */ - LORA_EVENT_INFO_STATUS_MIC_FAIL, /**< Message integrity check failure */ - LORA_EVENT_INFO_STATUS_CRYPTO_FAIL /**< Crypto error*/ -} lora_mac_event_info_status_t; - -/** - * LoRaMAC MLME-Request for TX continuous wave mode. - */ -typedef struct mlme_req_tx_cw { - /** - * The time while the radio is kept in continuous wave mode, in seconds. - */ - uint16_t timeout; - /** - * RF frequency to set (only used with the new way). - */ - uint32_t frequency; - /** - * RF output power to set (only used with the new way). - */ - uint8_t power; -} mlme_req_tx_cw_t; - -/** - * LoRaMAC MLME-Request structure - */ -typedef struct lora_mac_mlme_req { - /** - * MLME-Request type - */ - lora_mac_mlme_t type; - - /** - * MLME-Request parameters - */ - union mlme_param { - /** - * MLME-Request parameters for a join request - */ - lorawan_connect_otaa_t join; - /** - * MLME-Request parameters for TX continuous mode request - */ - mlme_req_tx_cw_t tx_cw; - } req; -} lora_mac_mlme_req_t; - -/** - * LoRaMAC MCPS-Request structure - */ -typedef struct lora_mac_mcps_req { - /** - * MCPS-Request type - */ - lora_mac_mcps_t type; - - /** - * MCPS-Request parameters - */ - union mcps_param - { - /** - * MCPS-Request parameters for an unconfirmed frame. - */ - lora_mac_unconfirmed_t unconfirmed; - /** - * MCPS-Request parameters for a confirmed frame. - */ - lora_mac_confirmed_t confirmed; - /** - * MCPS-Request parameters for a proprietary frame. - */ - lora_mac_proprietary_t proprietary; - } req; - /** Payload data - * - * A pointer to the buffer of the frame payload. - */ - void *f_buffer; - /** Payload size - * - * The size of the frame payload. - */ - uint16_t f_buffer_size; -} lora_mac_mcps_req_t; - -/** LoRaMAC MLME-Confirm - * - */ -typedef struct lora_mac_mlme_confirm { - /** The previous MLME-Request. - * - * The previously performed MLME-Request. - */ - lora_mac_mlme_t mlme_request; - /** The status of the operation. - * - * The current status of the MAC service operation. - */ - lora_mac_event_info_status_t status; - /** Time on air. - * - * The transmission time on air of the frame. - */ - TimerTime_t tx_time_on_air; - /** Demodulation margin. - * - * The link margin [dB] of the last LinkCheckReq successfully received. - */ - uint8_t demod_margin; - /** The number of gateways. - * - * The number of gateways that received the last LinkCheckReq. - */ - uint8_t nb_gateways; - /** The retransmission counter. - * - * The number of retransmissions. - */ - uint8_t nb_retries; -} lora_mac_mlme_confirm_t; - -/** LoRaMAC MCPS-Confirm - * - */ -typedef struct lora_mac_mcps_confirm { - /** MCPS-request - * - * Holds the previously performed MCPS-Request. - */ - lora_mac_mcps_t mcps_request; - /** The status of the operation. - * - * The current status of MAC service operation. - */ - lora_mac_event_info_status_t status; - /** Uplink datarate - * - */ - uint8_t datarate; - /** Transmission power - * - */ - int8_t tx_power; - /** ACK-received - * - * Set if an acknowledgement was received. - */ - bool ack_received; - /** Retransmission counter - * - * Provides the number of retransmissions. - */ - uint8_t nb_retries; - /** Time on air - * - * The transmission time on air of the frame. - */ - TimerTime_t tx_time_on_air; - /** Uplink counter - * - * The uplink counter value related to the frame. - */ - uint32_t uplink_counter; - /** Uplink frequency - * - * The uplink frequency related to the frame. - */ - uint32_t uplink_frequency; -} lora_mac_mcps_confirm_t; - -/** LoRaMAC MCPS-Indication - * - */ -typedef struct lora_mac_mcps_indication { - /** MCPS-Indication type - * - */ - lora_mac_mcps_t mcps_indication; - /** The status of the operation - * - * The current status of MAC service operation. - */ - lora_mac_event_info_status_t status; - /** Multicast - * - * This is a multicast message. - */ - uint8_t multicast; - /** Application port - * - */ - uint8_t port; - /** Downlink datarate - * - */ - uint8_t rx_datarate; - /** Frame pending - * - * The frame is pending. - */ - uint8_t frame_pending; - /** Payload data - * - * A pointer to the received data stream. - */ - uint8_t buffer[LORAMAC_PHY_MAXPAYLOAD]; - /** Payload size - * - * The size of the received data stream. - */ - uint16_t buffer_size; - /** RX-data indication - * - * Indicates, if data is available. - */ - bool rx_data; - /** Packet RSSI - * - * The RSSI of the received packet. - */ - int16_t rssi; - /** Packet SNR - * - * The SNR of the received packet. - */ - uint8_t snr; - /** Receive window - * - * [0: Rx window 1, 1: Rx window 2] - */ - uint8_t rx_slot; - /** ACK-received - * - * Set if an acknowledgement was received. - */ - bool ack_received; - /** Downlink counter - * - * The downlink counter value for the received frame. - */ - uint32_t downlink_counter; -} lora_mac_mcps_indication_t; +} loramac_tx_message_t; /** lora_mac_rx_message_type_t * * An enum representing a structure for RX messages. */ -typedef enum lora_mac_rx_message_type { +typedef enum { LORAMAC_RX_MLME_CONFIRM = 0, /**< lora_mac_mlme_confirm_t */ LORAMAC_RX_MCPS_CONFIRM, /**< lora_mac_mcps_confirm_t */ LORAMAC_RX_MCPS_INDICATION /**< lora_mac_mcps_indication_t */ -} lora_mac_rx_message_type_t; +} rx_msg_type; /** lora_mac_rx_message_by_type_t union * * A union representing a structure for RX messages. */ -typedef union lora_mac_rx_message_by_type_t { - lora_mac_mlme_confirm_t mlme_confirm; - lora_mac_mcps_confirm_t mcps_confirm; - lora_mac_mcps_indication_t mcps_indication; -} lora_mac_rx_message_by_type_t; +typedef union { + loramac_mlme_confirm_t mlme_confirm; + loramac_mcps_confirm_t mcps_confirm; + loramac_mcps_indication_t mcps_indication; +} rx_message_u; -/** lora_mac_rx_message_t +/** loramac_rx_message_t * * A structure representing a structure for an RX message. */ -typedef struct lora_mac_rx_message { +typedef struct { bool receive_ready; - lora_mac_rx_message_type_t type; - lora_mac_rx_message_by_type_t rx_message; + rx_msg_type type; + rx_message_u msg; uint16_t pending_size; uint16_t prev_read_size; -} lora_mac_rx_message_t; - -/** lora_mac_dr_range_t union - * - * A union representing a structure for the minimum and maximum data rate. - */ -typedef union lora_mac_dr_range { - /** Byte-access - * - * Byte-access to the bits. - */ - int8_t value; - /** lora_mac_fields_s - * - * A structure to store the minimum and maximum data rate. - */ - struct lora_mac_fields { - /** Minimum data rate - * - * EU868 - [DR_0, DR_1, DR_2, DR_3, DR_4, DR_5, DR_6, DR_7] - * - * US915 - [DR_0, DR_1, DR_2, DR_3, DR_4] - */ - int8_t min :4; - /** Maximum data rate - * - * EU868 - [DR_0, DR_1, DR_2, DR_3, DR_4, DR_5, DR_6, DR_7] - * - * US915 - [DR_0, DR_1, DR_2, DR_3, DR_4] - */ - int8_t max :4; - } lora_mac_fields_s; -} lora_mac_dr_range_t; - -/** LoRaWAN device class definition - * - */ -typedef enum lora_mac_device_class { - LORA_CLASS_A, /**< LoRaWAN device class A */ - LORA_CLASS_B, /**< LoRaWAN device class B */ - LORA_CLASS_C, /**< LoRaWAN device class C */ -} lora_mac_device_class_t; - -/** LoRaMAC channel definition - * - */ -typedef struct lora_mac_channel_params { - /** Frequency in Hz - * - */ - uint32_t frequency; - /** Alternative frequency for RX window 1 - * - */ - uint32_t rx1_frequency; - /** Data rate definition - * - */ - lora_mac_dr_range_t dr_range; - /** Band index - * - */ - uint8_t band; -} lora_mac_channel_params_t; +} loramac_rx_message_t; /** * Structure to hold A list of LoRa Channels */ typedef struct lora_channels_s { uint8_t id; - lora_mac_channel_params_t ch_param; -} lora_channels_t; + channel_params_t ch_param; +} loramac_channel_t; -/** LoRaMAC receive window 2 channel parameters - * - */ -typedef struct lora_mac_rx2_channel_params { - /** Frequency in Hz - * - */ - uint32_t frequency; - /** Data rate - * - * EU868 - [DR_0, DR_1, DR_2, DR_3, DR_4, DR_5, DR_6, DR_7] - * - * US915 - [DR_8, DR_9, DR_10, DR_11, DR_12, DR_13] - */ - uint8_t datarate; -} lora_mac_rx2_channel_params_t; - -/** LoRaMAC multicast channel parameter - * - */ -typedef struct lora_mac_multicast_params { - /** Address - * - */ - uint32_t address; - /** Network session key - * - */ - uint8_t nwk_skey[16]; - /** Application session key - * - */ - uint8_t app_skey[16]; - /** Downlink counter - * - */ - uint32_t downlink_counter; - /** Next multicast - * - * A reference pointer to the next multicast channel parameters in the list - */ - struct lora_mac_multicast_params *next; -} lora_mac_multicast_params_t; - -/** Enum lora_mac_mib_t - * - */ -typedef enum lora_mac_mib { - LORA_MIB_DEVICE_CLASS, /**< LoRaWAN device class */ - LORA_MIB_NETWORK_JOINED, /**< LoRaWAN network joined attribute */ - LORA_MIB_ADR, /**< Adaptive data rate */ - LORA_MIB_NET_ID, /**< Network identifier */ - LORA_MIB_DEV_ADDR, /**< End-device address */ - LORA_MIB_NWK_SKEY, /**< Network session key */ - LORA_MIB_APP_SKEY, /**< Application session key */ - LORA_MIB_PUBLIC_NETWORK, /**< Set the network type to public or private */ - LORA_MIB_REPEATER_SUPPORT, /**< Support the operation with repeaters */ - LORA_MIB_CHANNELS, /**< Communication channels */ - LORA_MIB_RX2_CHANNEL, /**< Set receive window 2 channel */ - LORA_MIB_RX2_DEFAULT_CHANNEL, /**< Set receive window 2 channel */ - LORA_MIB_CHANNELS_MASK, /**< LoRaWAN channels mask */ - LORA_MIB_CHANNELS_DEFAULT_MASK, /**< LoRaWAN default channels mask */ - LORA_MIB_CHANNELS_NB_REP, /**< Set the number of repetitions on a channel */ - LORA_MIB_MAX_RX_WINDOW_DURATION, /**< Maximum receive window duration in [ms] */ - LORA_MIB_RECEIVE_DELAY_1, /**< Receive delay 1 in [ms] */ - LORA_MIB_RECEIVE_DELAY_2, /**< Receive delay 2 in [ms] */ - LORA_MIB_JOIN_ACCEPT_DELAY_1, /**< Join accept delay 1 in [ms] */ - LORA_MIB_JOIN_ACCEPT_DELAY_2, /**< Join accept delay 2 in [ms] */ - LORA_MIB_CHANNELS_DEFAULT_DATARATE, /**< Default data rate of a channel */ - LORA_MIB_CHANNELS_DATARATE, /**< Data rate of a channel */ - LORA_MIB_CHANNELS_TX_POWER, /**< Transmission power of a channel */ - LORA_MIB_CHANNELS_DEFAULT_TX_POWER, /**< Transmission power of a channel */ - LORA_MIB_UPLINK_COUNTER, /**< LoRaWAN uplink counter */ - LORA_MIB_DOWNLINK_COUNTER, /**< LoRaWAN downlink counter */ - LORA_MIB_MULTICAST_CHANNEL, /**< Multicast channels */ - LORA_MIB_SYSTEM_MAX_RX_ERROR, /**< System overall timing error in milliseconds. */ - LORA_MIB_MIN_RX_SYMBOLS, /**< Minimum number of symbols required to detect an RX frame */ -} lora_mac_mib_t; /** lorawan_connect_t structure * @@ -2477,7 +1866,7 @@ typedef struct lorawan_session { * * A structure for data in commission. */ -typedef struct lora_dev_commission { +typedef struct { /** Connection information * * Saves information for etc. keys @@ -2495,179 +1884,7 @@ typedef struct lora_dev_commission { * Related MIB type: LORA_MIB_DOWNLINK_COUNTER */ uint32_t downlink_counter; -} lora_dev_commission_t; - -/** LoRaMAC MIB parameters - * - */ -typedef union lora_mac_mib_param { - /** LoRaWAN device class - * - * Related MIB type: \ref MIB_DEVICE_CLASS - */ - lora_mac_device_class_t lora_class; - /** LoRaWAN network joined attribute - * - * Related MIB type: \ref MIB_NETWORK_JOINED - */ - bool is_network_joined; - /** Activation state of ADR - * - * Related MIB type: \ref MIB_ADR - */ - bool adr_enable; - /** Network identifier - * - * Related MIB type: \ref MIB_NET_ID - */ - uint32_t net_id; - /** End-device address - * - * Related MIB type: \ref MIB_DEV_ADDR - */ - uint32_t dev_addr; - /** Network session key - * - * Related MIB type: \ref MIB_NWK_SKEY - */ - uint8_t *nwk_skey; - /** Application session key - * - * Related MIB type: \ref MIB_APP_SKEY - */ - uint8_t *app_skey; - /** Enable public network - * - * Enable or disable a public network - * Related MIB type: \ref MIB_PUBLIC_NETWORK - */ - bool enable_public_network; - /** Enable repeater support - * - * Enable or disable repeater support - * Related MIB type: \ref MIB_REPEATER_SUPPORT - */ - bool enable_repeater_support; - /** LoRaWAN Channel - * - * Related MIB type: \ref MIB_CHANNELS - */ - lora_mac_channel_params_t *channel_list; - /** Channel rx 2 - * - * Channel for the receive window 2 - * Related MIB type: \ref MIB_RX2_CHANNEL - */ - lora_mac_rx2_channel_params_t rx2_channel; - /** Default channel rx 2 - * - * Channel for the receive window 2 - * Related MIB type: \ref MIB_RX2_DEFAULT_CHANNEL - */ - lora_mac_rx2_channel_params_t rx2_default_channel; - /** Channel mask - * - * Related MIB type: \ref MIB_CHANNELS_MASK - */ - uint16_t *channels_mask; - /** Default channel mask - * - * Related MIB type: \ref MIB_CHANNELS_DEFAULT_MASK - */ - uint16_t *channels_default_mask; - /** Frame repetition number - * - * Number of frame repetitions - * Related MIB type: \ref MIB_CHANNELS_NB_REP - */ - uint8_t channel_nb_rep; - /** Maximum receive window duration - * - * Related MIB type: \ref MIB_MAX_RX_WINDOW_DURATION - */ - uint32_t max_rx_window; - /** Receive delay 1 - * - * Related MIB type: \ref MIB_RECEIVE_DELAY_1 - */ - uint32_t receive_delay1; - /** Receive delay 2 - * - * Related MIB type: \ref MIB_RECEIVE_DELAY_2 - */ - uint32_t receive_delay2; - /** Join accept delay 1 - * - * Related MIB type: \ref MIB_JOIN_ACCEPT_DELAY_1 - */ - uint32_t join_accept_delay1; - /** Join accept delay 2 - * - * Related MIB type: \ref MIB_JOIN_ACCEPT_DELAY_2 - */ - uint32_t join_accept_delay2; - /** Channels default data rate - * - * Related MIB type: \ref MIB_CHANNELS_DEFAULT_DATARATE - */ - int8_t channels_default_datarate; - /** Channels data rate - * - * Related MIB type: \ref MIB_CHANNELS_DATARATE - */ - int8_t channels_datarate; - /** Channels default TX power - * - * Related MIB type: \ref MIB_CHANNELS_DEFAULT_TX_POWER - */ - int8_t channels_default_tx_power; - /** Channels TX power - * - * Related MIB type: \ref MIB_CHANNELS_TX_POWER - */ - int8_t channels_tx_power; - /** LoRaWAN uplink counter - * - * Related MIB type: \ref MIB_UPLINK_COUNTER - */ - uint32_t uplink_counter; - /** LoRaWAN downlink counter - * - * Related MIB type: \ref MIB_DOWNLINK_COUNTER - */ - uint32_t downlink_counter; - /** Multicast channel - * - * Related MIB type: \ref MIB_MULTICAST_CHANNEL - */ - lora_mac_multicast_params_t *multicast_list; - /** Maximum RX error timing - * - * System overall timing error in milliseconds. - * Related MIB type: \ref MIB_SYSTEM_MAX_RX_ERROR - */ - uint32_t system_max_rx_error; - /** Minimum RX symbols - * - * Minimum required number of symbols to detect an RX frame - * Related MIB type: \ref MIB_MIN_RX_SYMBOLS - */ - uint8_t min_rx_symbols; -} lora_mac_mib_param_t; - -/** LoRaMAC MIB-RequestConfirm structure - * - */ -typedef struct lora_mac_mib_request_confirm { - /** MIB-Request type - * - */ - lora_mac_mib_t type; - /** MIB-RequestConfirm parameters - * - */ - lora_mac_mib_param_t param; -} lora_mac_mib_request_confirm_t; +} lorawan_dev_commission_t; #if defined(LORAWAN_COMPLIANCE_TEST) /** LoRaWAN compliance tests support data @@ -2720,7 +1937,7 @@ typedef struct compliance_test { /** Structure containing the uplink status * */ -typedef struct loramac_uplink_status { +typedef struct { /** Is acked * */ @@ -2750,7 +1967,7 @@ typedef struct loramac_uplink_status { /** A structure containing the downlink status * */ -typedef struct loramac_downlink_status { +typedef struct { /** RSSI of downlink * */ @@ -2782,71 +1999,68 @@ typedef struct loramac_downlink_status { } loramac_downlink_status_t; /*! - * The parameter structure for the function RegionRxConfig. + * The parameter structure for the function for regional rx configuration. */ -typedef struct sRxConfigParams -{ +typedef struct { /*! * The RX channel. */ - uint8_t Channel; + uint8_t channel; /*! * The RX datarate. */ - int8_t Datarate; + int8_t datarate; /*! * The RX bandwidth. */ - uint8_t Bandwidth; + uint8_t bandwidth; /*! * The RX datarate offset. */ - int8_t DrOffset; + int8_t dr_offset; /*! * The RX frequency. */ - uint32_t Frequency; + uint32_t frequency; /*! * The RX window timeout */ - uint32_t WindowTimeout; + uint32_t window_timeout; /*! * The RX window offset */ - int32_t WindowOffset; + int32_t window_offset; /*! * The downlink dwell time. */ - uint8_t DownlinkDwellTime; + uint8_t dl_dwell_time; /*! * Set to true, if a repeater is supported. */ - bool RepeaterSupport; + bool is_repeater_supported; /*! * Set to true, if RX should be continuous. */ - bool RxContinuous; + bool is_rx_continuous; /*! * Sets the RX window. */ - LoRaMacRxSlot_t RxSlot; -}RxConfigParams_t; + rx_slot_t rx_slot; +} rx_config_params_t; /*! * \brief Timer object description */ -typedef struct TimerEvent_s -{ +typedef struct { uint32_t value; - mbed::Callback Callback; - SingletonPtr Timer; -} TimerEvent_t; + mbed::Callback callback; + SingletonPtr timer; +} timer_event_t; /*! * LoRaMac internal states */ -enum eLoRaMacState -{ +typedef enum { LORAMAC_IDLE = 0x00000000, LORAMAC_TX_RUNNING = 0x00000001, LORAMAC_RX = 0x00000002, @@ -2855,259 +2069,259 @@ enum eLoRaMacState LORAMAC_TX_DELAYED = 0x00000010, LORAMAC_TX_CONFIG = 0x00000020, LORAMAC_RX_ABORT = 0x00000040, -}; +} loramac_internal_state; typedef struct { /*! * Device IEEE EUI */ - uint8_t *LoRaMacDevEui; + uint8_t *dev_eui; /*! * Application IEEE EUI */ - uint8_t *LoRaMacAppEui; + uint8_t *app_eui; /*! * AES encryption/decryption cipher application key */ - uint8_t *LoRaMacAppKey; + uint8_t *app_key; /*! * AES encryption/decryption cipher network session key */ - uint8_t LoRaMacNwkSKey[16]; + uint8_t nwk_skey[16]; /*! * AES encryption/decryption cipher application session key */ - uint8_t LoRaMacAppSKey[16]; + uint8_t app_skey[16]; -} lora_mac_keys; +} loramac_keys; typedef struct { /*! * Aggregated duty cycle management */ - TimerTime_t AggregatedLastTxDoneTime; - TimerTime_t AggregatedTimeOff; + lorawan_time_t aggregated_last_tx_time; + lorawan_time_t aggregated_timeoff; /*! * Stores the time at LoRaMac initialization. * * \remark Used for the BACKOFF_DC computation. */ - TimerTime_t LoRaMacInitializationTime; + lorawan_time_t mac_init_time; /*! * Last transmission time on air */ - TimerTime_t TxTimeOnAir; + lorawan_time_t tx_toa; /*! * LoRaMac timer used to check the LoRaMacState (runs every second) */ - TimerEvent_t MacStateCheckTimer; + timer_event_t mac_state_check_timer; /*! * LoRaMac duty cycle delayed Tx timer */ - TimerEvent_t TxDelayedTimer; + timer_event_t tx_delayed_timer; /*! * LoRaMac reception windows timers */ - TimerEvent_t RxWindowTimer1; - TimerEvent_t RxWindowTimer2; + timer_event_t rx_window1_timer; + timer_event_t rx_window2_timer; /*! * Acknowledge timeout timer. Used for packet retransmissions. */ - TimerEvent_t AckTimeoutTimer; + timer_event_t ack_timeout_timer; - } lora_mac_timers; +} lorawan_timers; typedef struct { /*! * Actual device class */ - DeviceClass_t LoRaMacDeviceClass; + device_class_t dev_class; /*! * Holds the type of current Receive window slot */ - LoRaMacRxSlot_t RxSlot; + rx_slot_t rx_slot; /*! * Indicates if the node is connected to a private or public network */ - bool PublicNetwork; + bool is_nwk_public; /*! * Indicates if the node supports repeaters */ - bool RepeaterSupport; + bool is_repeater_supported; /*! * IsPacketCounterFixed enables the MIC field tests by fixing the - * UpLinkCounter value + * ul_frame_counter value */ - bool IsUpLinkCounterFixed; + bool is_ul_frame_counter_fixed; /*! * Used for test purposes. Disables the opening of the reception windows. */ - bool IsRxWindowsEnabled; + bool is_rx_window_enabled; /*! * Indicates if the MAC layer has already joined a network. */ - bool IsLoRaMacNetworkJoined; + bool is_nwk_joined; /*! * If the node has sent a FRAME_TYPE_DATA_CONFIRMED_UP this variable indicates * if the nodes needs to manage the server acknowledgement. */ - bool NodeAckRequested; + bool is_node_ack_requested; /*! * If the server has sent a FRAME_TYPE_DATA_CONFIRMED_DOWN this variable indicates * if the ACK bit must be set for the next transmission */ - bool SrvAckRequested; + bool is_srv_ack_requested; /*! * Enables/Disables duty cycle management (Test only) */ - bool DutyCycleOn; + bool is_dutycycle_on; /*! * Set to true, if the last uplink was a join request */ - bool LastTxIsJoinRequest; + bool is_last_tx_join_request; /*! * Indicates if the AckTimeout timer has expired or not */ - bool AckTimeoutRetry; + bool is_ack_retry_timeout_expired; /*! * Current channel index */ - uint8_t Channel; + uint8_t channel; /*! * Current channel index */ - uint8_t LastTxChannel; + uint8_t last_channel_idx; /*! * Uplink messages repetitions counter */ - uint8_t ChannelsNbRepCounter; + uint8_t ul_nb_rep_counter; /*! * Buffer containing the data to be sent or received. */ - uint8_t LoRaMacBuffer[LORAMAC_PHY_MAXPAYLOAD]; - - /*! - * Length of the payload in LoRaMacBuffer - */ - uint8_t LoRaMacTxPayloadLen; - - /*! - * Buffer containing the upper layer data. - */ - uint8_t LoRaMacRxPayload[LORAMAC_PHY_MAXPAYLOAD]; - - /*! - * Number of trials to get a frame acknowledged - */ - uint8_t AckTimeoutRetries; - - /*! - * Number of trials to get a frame acknowledged - */ - uint8_t AckTimeoutRetriesCounter; - - /*! - * Number of trials for the Join Request - */ - uint8_t JoinRequestTrials; - - /*! - * Maximum number of trials for the Join Request - */ - uint8_t MaxJoinRequestTrials; - - /*! - * Mac keys - */ - lora_mac_keys keys; - - /*! - * LoRaMac tx/rx operation state - */ - LoRaMacFlags_t LoRaMacFlags; + uint8_t buffer[LORAMAC_PHY_MAXPAYLOAD]; /*! * Length of packet in LoRaMacBuffer */ - uint16_t LoRaMacBufferPktLen; + uint16_t buffer_pkt_len; + + /*! + * Buffer containing the upper layer data. + */ + uint8_t payload[LORAMAC_PHY_MAXPAYLOAD]; + + /*! + * Length of the payload in LoRaMacBuffer + */ + uint8_t payload_length; + + /*! + * Number of trials to get a frame acknowledged + */ + uint8_t max_ack_timeout_retries; + + /*! + * Number of trials to get a frame acknowledged + */ + uint8_t ack_timeout_retry_counter; + + /*! + * Maximum number of trials for the Join Request + */ + uint8_t max_join_request_trials; + + /*! + * Number of trials for the Join Request + */ + uint8_t join_request_trial_counter; + + /*! + * Mac keys + */ + loramac_keys keys; + + /*! + * LoRaMac tx/rx operation state + */ + loramac_flags_t flags; /*! * Device nonce is a random value extracted by issuing a sequence of RSSI * measurements */ - uint16_t LoRaMacDevNonce; + uint16_t dev_nonce; /*! * Network ID ( 3 bytes ) */ - uint32_t LoRaMacNetID; + uint32_t net_id; /*! * Mote Address */ - uint32_t LoRaMacDevAddr; + uint32_t dev_addr; /*! * LoRaMAC frame counter. Each time a packet is sent the counter is incremented. * Only the 16 LSB bits are sent */ - uint32_t UpLinkCounter; + uint32_t ul_frame_counter; /*! * LoRaMAC frame counter. Each time a packet is received the counter is incremented. * Only the 16 LSB bits are received */ - uint32_t DownLinkCounter; + uint32_t dl_frame_counter; /*! * Counts the number of missed ADR acknowledgements */ - uint32_t AdrAckCounter; + uint32_t adr_ack_counter; /*! * LoRaMac internal state */ - uint32_t LoRaMacState; + uint32_t mac_state; /*! * LoRaMac reception windows delay * \remark normal frame: RxWindowXDelay = ReceiveDelayX - RADIO_WAKEUP_TIME * join frame : RxWindowXDelay = JoinAcceptDelayX - RADIO_WAKEUP_TIME */ - uint32_t RxWindow1Delay; - uint32_t RxWindow2Delay; + uint32_t rx_window1_delay; + uint32_t rx_window2_delay; /*! * Timer objects and stored values */ - lora_mac_timers timers; + lorawan_timers timers; /*! * LoRaMac parameters @@ -3122,15 +2336,15 @@ typedef struct { /*! * Receive Window configurations for PHY layer */ - RxConfigParams_t RxWindow1Config; - RxConfigParams_t RxWindow2Config; + rx_config_params_t rx_window1_config; + rx_config_params_t rx_window2_config; /*! * Multicast channels linked list */ - MulticastParams_t *MulticastChannels; + multicast_params_t *multicast_channels; -} lora_mac_protocol_params; +} loramac_protocol_params; /** LoRaWAN callback functions * @@ -3147,11 +2361,11 @@ typedef enum lora_events { RX_TIMEOUT, RX_ERROR, JOIN_FAILURE, -} lora_events_t; +} lorawan_events_t; typedef struct { // Mandatory. Event Callback must be provided - mbed::Callback events; + mbed::Callback events; // Rest are optional // If the user do not assign these callbacks, these callbacks would return @@ -3159,11 +2373,16 @@ typedef struct { // link_check_resp callback and other such callbacks will be maped in // future releases of Mbed-OS mbed::Callback link_check_resp; - }lorawan_app_callbacks_t; + + // Battery level callback goes in the down direction, i.e., it informs + // the stack about the battery level by calling a function provided + // by the upper layers + mbed::Callback battery_level; + } lorawan_app_callbacks_t; typedef struct lora_channelplan { uint8_t nb_channels; // number of channels - lora_channels_t *channels; -} lora_channelplan_t; + loramac_channel_t *channels; +} lorawan_channelplan_t; #endif /* LORAWAN_SYSTEM_LORAWAN_DATA_STRUCTURES_H_ */ diff --git a/features/netsocket/LoRaWANBase.h b/features/netsocket/LoRaWANBase.h index 98a29f5004..4796424f08 100644 --- a/features/netsocket/LoRaWANBase.h +++ b/features/netsocket/LoRaWANBase.h @@ -31,20 +31,20 @@ public: * * @param queue A pointer to EventQueue provided by the application. * - * @return LORA_MAC_STATUS_OK on success, a negative error code on + * @return LORAWAN_STATUS_OK on success, a negative error code on * failure. */ - virtual lora_mac_status_t initialize(events::EventQueue *queue) = 0; + virtual lorawan_status_t initialize(events::EventQueue *queue) = 0; /** Connect OTAA or ABP by setup. * * Connect by Over The Air Activation or Activation By Personalization. * The connection type is selected at the setup. * - * @return LORA_MAC_STATUS_OK on success, a negative error code on + * @return LORAWAN_STATUS_OK on success, a negative error code on * failure. */ - virtual lora_mac_status_t connect() = 0; + virtual lorawan_status_t connect() = 0; /** Connect OTAA or ABP by parameters * @@ -53,16 +53,16 @@ public: * You need to define the parameters in the main application. * * @param connect Options how end-device will connect to gateway - * @return LORA_MAC_STATUS_OK on success, negative error code + * @return LORAWAN_STATUS_OK on success, negative error code * on failure */ - virtual lora_mac_status_t connect(const lorawan_connect_t &connect) = 0; + virtual lorawan_status_t connect(const lorawan_connect_t &connect) = 0; /** Disconnects the current session. * - * @return LORA_MAC_STATUS_OK on success, a negative error code on failure. + * @return LORAWAN_STATUS_OK on success, a negative error code on failure. */ - virtual lora_mac_status_t disconnect() = 0; + virtual lorawan_status_t disconnect() = 0; /** Validate the connectivity with the network. * @@ -74,7 +74,7 @@ public: * * This API is usable only when the link check response is callback set by * the application. See add_lora_app_callbacks API. If the above mentioned - * callback is not set, a LORA_MAC_STATUS_PARAMETER_INVALID error is thrown. + * callback is not set, a LORAWAN_STATUS_PARAMETER_INVALID error is thrown. * * First parameter to callback function is the demodulation margin and * the second parameter is the number of gateways that successfully received @@ -85,11 +85,11 @@ public: * remove_link_check_request() API. * * @param cb A callback function to receive link check response - * @return LORA_MAC_STATUS_OK on successfully queuing a request, or + * @return LORAWAN_STATUS_OK on successfully queuing a request, or * a negative error code on failure. * */ - virtual lora_mac_status_t add_link_check_request() = 0; + virtual lorawan_status_t add_link_check_request() = 0; /** Detaches Link Request MAC command. * @@ -102,30 +102,30 @@ public: * @param data_rate Intended data rate e.g., DR_0, DR_1 etc. * Caution is advised as the macro DR_* can mean different * things while being in a different region. - * @return LORA_MAC_STATUS_OK if everything goes well, otherwise + * @return LORAWAN_STATUS_OK if everything goes well, otherwise * a negative error code. */ - virtual lora_mac_status_t set_datarate(uint8_t data_rate) = 0; + virtual lorawan_status_t set_datarate(uint8_t data_rate) = 0; /** Enables adaptive data rate (ADR) * * Underlying LoRaPHY and LoRaMac layers handle the data rate automatically * for the user based upon radio conditions (network congestion). * - * @return LORA_MAC_STATUS_OK on success, negative error code + * @return LORAWAN_STATUS_OK on success, negative error code * on failure. */ - virtual lora_mac_status_t enable_adaptive_datarate() = 0; + virtual lorawan_status_t enable_adaptive_datarate() = 0; /** Disables adaptive data rate * * When adaptive data rate (ADR) is disabled, user can either set a certain * data rate or the Mac layer will choose a default value. * - * @return LORA_MAC_STATUS_OK on success, negative error code + * @return LORAWAN_STATUS_OK on success, negative error code * on failure. */ - virtual lora_mac_status_t disable_adaptive_datarate() = 0; + virtual lorawan_status_t disable_adaptive_datarate() = 0; /** Sets up retry counter for confirmed messages * @@ -141,25 +141,25 @@ public: * * @param count number of retries for confirmed messages * - * @return LORA_MAC_STATUS_OK or a negative error code + * @return LORAWAN_STATUS_OK or a negative error code */ - virtual lora_mac_status_t set_confirmed_msg_retries(uint8_t count) = 0; + virtual lorawan_status_t set_confirmed_msg_retries(uint8_t count) = 0; /** Sets channel plan * * @param channel_plan The defined channel plans to be set. * @return 0 on success, a negative error code on failure. */ - virtual lora_mac_status_t set_channel_plan(const lora_channelplan_t &channel_plan) = 0; + virtual lorawan_status_t set_channel_plan(const lorawan_channelplan_t &channel_plan) = 0; /** Gets the current channel plan. * * @param channel_plan The current channel information. * - * @return LORA_MAC_STATUS_OK on success, a negative error + * @return LORAWAN_STATUS_OK on success, a negative error * code on failure. */ - virtual lora_mac_status_t get_channel_plan(lora_channelplan_t &channel_plan) = 0; + virtual lorawan_status_t get_channel_plan(lorawan_channelplan_t &channel_plan) = 0; /** Removes currently active channel plan * @@ -167,10 +167,10 @@ public: * allowed to be removed. So when a plan is abolished, only non-default * channels are removed. * - * @return LORA_MAC_STATUS_OK on success, negative error + * @return LORAWAN_STATUS_OK on success, negative error * code on failure */ - virtual lora_mac_status_t remove_channel_plan() = 0; + virtual lorawan_status_t remove_channel_plan() = 0; /** Removes a given single channel * @@ -179,10 +179,10 @@ public: * * @param index The channel index * - * @return LORA_MAC_STATUS_OK on success, negative error + * @return LORAWAN_STATUS_OK on success, negative error * code on failure */ - virtual lora_mac_status_t remove_channel(uint8_t index) = 0; + virtual lorawan_status_t remove_channel(uint8_t index) = 0; /** Send message to gateway * @@ -215,7 +215,7 @@ public: * * * @return The number of bytes sent, or - * LORA_MAC_STATUS_WOULD_BLOCK if another TX is + * LORAWAN_STATUS_WOULD_BLOCK if another TX is * ongoing, or a negative error code on failure. */ virtual int16_t send(uint8_t port, const uint8_t* data, @@ -256,7 +256,7 @@ public: * @return It could be one of these: * i) 0 if there is nothing else to read. * ii) Number of bytes written to user buffer. - * iii) LORA_MAC_STATUS_WOULD_BLOCK if there is + * iii) LORAWAN_STATUS_WOULD_BLOCK if there is * nothing available to read at the moment. * iv) A negative error code on failure. */ @@ -331,7 +331,7 @@ public: * @param callbacks A pointer to the structure containing application * callbacks. */ - virtual lora_mac_status_t add_app_callbacks(lorawan_app_callbacks_t *callbacks) = 0; + virtual lorawan_status_t add_app_callbacks(lorawan_app_callbacks_t *callbacks) = 0; }; #endif /* LORAWAN_BASE_H_ */ From 7369cbd649170b79c34eb6df7f933bf47d666346 Mon Sep 17 00:00:00 2001 From: Hasnain Virk Date: Mon, 15 Jan 2018 14:30:46 +0200 Subject: [PATCH 13/23] [IOTCELL-346] Removing default value storage We now save roughly 500 bytes by removing storage of default parameters in the loramac_params_t data structure. We use Mib to get default values from PHY whenever needed instead. loramac_sys_arams_t now contains only the runtime values set during operation whenever defaults are needed we directly query the PHY layer or via Mib as the need maybe. --- features/lorawan/LoRaWANStack.cpp | 4 +- features/lorawan/lorastack/mac/LoRaMac.cpp | 95 +++++++++++-------- features/lorawan/lorastack/mac/LoRaMacMib.cpp | 33 ++++--- .../lorawan/system/lorawan_data_structures.h | 5 - 4 files changed, 81 insertions(+), 56 deletions(-) diff --git a/features/lorawan/LoRaWANStack.cpp b/features/lorawan/LoRaWANStack.cpp index 6cfaba80e6..17cffa5fc1 100644 --- a/features/lorawan/LoRaWANStack.cpp +++ b/features/lorawan/LoRaWANStack.cpp @@ -244,7 +244,7 @@ lorawan_status_t LoRaWANStack::send_compliance_test_frame_to_mac() mcps_req.f_buffer_size = _tx_msg.f_buffer_size; mcps_req.req.unconfirmed.data_rate = default_datarate.Value; - tr_info("Transmit unconfirmed compliance test frame %d bytes.", mcps_req.req.unconfirmed.fbuffer_size); + tr_info("Transmit unconfirmed compliance test frame %d bytes.", mcps_req.f_buffer_size); for (uint8_t i = 0; i < mcps_req.f_buffer_size; ++i) { tr_info("Byte %d, data is 0x%x", i+1, ((uint8_t*)mcps_req.f_buffer)[i]); @@ -257,7 +257,7 @@ lorawan_status_t LoRaWANStack::send_compliance_test_frame_to_mac() mcps_req.req.confirmed.nb_trials = _num_retry; mcps_req.req.confirmed.data_rate = default_datarate.Value; - tr_info("Transmit confirmed compliance test frame %d bytes.", mcps_req.req.confirmed.fbuffer_size); + tr_info("Transmit confirmed compliance test frame %d bytes.", mcps_req.f_buffer_size); for (uint8_t i = 0; i < mcps_req.f_buffer_size; ++i) { tr_info("Byte %d, data is 0x%x", i+1, ((uint8_t*)mcps_req.f_buffer)[i]); diff --git a/features/lorawan/lorastack/mac/LoRaMac.cpp b/features/lorawan/lorastack/mac/LoRaMac.cpp index 434da73dce..06615eec44 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.cpp +++ b/features/lorawan/lorastack/mac/LoRaMac.cpp @@ -1225,6 +1225,8 @@ lorawan_status_t LoRaMac::ScheduleTx( void ) { lorawan_time_t dutyCycleTimeOff = 0; NextChanParams_t nextChan; + GetPhyParams_t getPhy; + PhyParam_t phyParam; // Check if the device is off if( _params.sys_params.max_duty_cycle == 255 ) @@ -1251,7 +1253,9 @@ lorawan_status_t LoRaMac::ScheduleTx( void ) &_params.timers.aggregated_timeoff ) == false ) { // Set the default datarate - _params.sys_params.channel_data_rate = _params.def_sys_params.channel_data_rate; + getPhy.Attribute = PHY_DEF_TX_DR; + phyParam = lora_phy->get_phy_params( &getPhy ); + _params.sys_params.channel_data_rate = phyParam.Value; // Update datarate in the function parameters nextChan.Datarate = _params.sys_params.channel_data_rate; } @@ -1330,6 +1334,9 @@ void LoRaMac::CalculateBackOff( uint8_t channel ) void LoRaMac::ResetMacParameters( void ) { + GetPhyParams_t getPhy; + PhyParam_t phyParam; + _params.is_nwk_joined = false; // Counters @@ -1352,14 +1359,37 @@ void LoRaMac::ResetMacParameters( void ) _params.is_rx_window_enabled = true; - _params.sys_params.channel_tx_power = _params.def_sys_params.channel_tx_power; - _params.sys_params.channel_data_rate = _params.def_sys_params.channel_data_rate; - _params.sys_params.rx1_dr_offset = _params.def_sys_params.rx1_dr_offset; - _params.sys_params.rx2_channel = _params.def_sys_params.rx2_channel; - _params.sys_params.uplink_dwell_time = _params.def_sys_params.uplink_dwell_time; - _params.sys_params.downlink_dwell_time = _params.def_sys_params.downlink_dwell_time; - _params.sys_params.max_eirp = _params.def_sys_params.max_eirp; - _params.sys_params.antenna_gain = _params.def_sys_params.antenna_gain; + getPhy.Attribute = PHY_DEF_TX_POWER; + phyParam = lora_phy->get_phy_params( &getPhy ); + + _params.sys_params.channel_tx_power = phyParam.Value; + + getPhy.Attribute = PHY_DEF_TX_DR; + phyParam = lora_phy->get_phy_params( &getPhy ); + _params.sys_params.channel_data_rate = phyParam.Value; + + getPhy.Attribute = PHY_DEF_DR1_OFFSET; + phyParam = lora_phy->get_phy_params( &getPhy ); + _params.sys_params.rx1_dr_offset = phyParam.Value; + + getPhy.Attribute = PHY_DEF_RX2_FREQUENCY; + phyParam = lora_phy->get_phy_params( &getPhy ); + _params.sys_params.rx2_channel.frequency = phyParam.Value; + getPhy.Attribute = PHY_DEF_RX2_DR; + phyParam = lora_phy->get_phy_params( &getPhy ); + _params.sys_params.rx2_channel.datarate = phyParam.Value; + + getPhy.Attribute = PHY_DEF_UPLINK_DWELL_TIME; + phyParam = lora_phy->get_phy_params( &getPhy ); + _params.sys_params.uplink_dwell_time = phyParam.Value; + + getPhy.Attribute = PHY_DEF_MAX_EIRP; + phyParam = lora_phy->get_phy_params( &getPhy ); + _params.sys_params.max_eirp = phyParam.Value; + + getPhy.Attribute = PHY_DEF_ANTENNA_GAIN; + phyParam = lora_phy->get_phy_params( &getPhy ); + _params.sys_params.antenna_gain = phyParam.Value; _params.is_node_ack_requested = false; _params.is_srv_ack_requested = false; @@ -1727,75 +1757,66 @@ lorawan_status_t LoRaMac::LoRaMacInitialization(loramac_primitives_t *primitives getPhy.Attribute = PHY_DEF_TX_POWER; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.def_sys_params.channel_tx_power = phyParam.Value; + _params.sys_params.channel_tx_power = phyParam.Value; getPhy.Attribute = PHY_DEF_TX_DR; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.def_sys_params.channel_data_rate = phyParam.Value; + _params.sys_params.channel_data_rate = phyParam.Value; getPhy.Attribute = PHY_MAX_RX_WINDOW; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.def_sys_params.max_rx_win_time = phyParam.Value; + _params.sys_params.max_rx_win_time = phyParam.Value; getPhy.Attribute = PHY_RECEIVE_DELAY1; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.def_sys_params.recv_delay1 = phyParam.Value; + _params.sys_params.recv_delay1 = phyParam.Value; getPhy.Attribute = PHY_RECEIVE_DELAY2; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.def_sys_params.recv_delay2 = phyParam.Value; + _params.sys_params.recv_delay2 = phyParam.Value; getPhy.Attribute = PHY_JOIN_ACCEPT_DELAY1; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.def_sys_params.join_accept_delay1 = phyParam.Value; + _params.sys_params.join_accept_delay1 = phyParam.Value; getPhy.Attribute = PHY_JOIN_ACCEPT_DELAY2; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.def_sys_params.join_accept_delay2 = phyParam.Value; + _params.sys_params.join_accept_delay2 = phyParam.Value; getPhy.Attribute = PHY_DEF_DR1_OFFSET; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.def_sys_params.rx1_dr_offset = phyParam.Value; + _params.sys_params.rx1_dr_offset = phyParam.Value; getPhy.Attribute = PHY_DEF_RX2_FREQUENCY; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.def_sys_params.rx2_channel.frequency = phyParam.Value; + _params.sys_params.rx2_channel.frequency = phyParam.Value; getPhy.Attribute = PHY_DEF_RX2_DR; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.def_sys_params.rx2_channel.datarate = phyParam.Value; + _params.sys_params.rx2_channel.datarate = phyParam.Value; getPhy.Attribute = PHY_DEF_UPLINK_DWELL_TIME; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.def_sys_params.uplink_dwell_time = phyParam.Value; + _params.sys_params.uplink_dwell_time = phyParam.Value; getPhy.Attribute = PHY_DEF_DOWNLINK_DWELL_TIME; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.def_sys_params.downlink_dwell_time = phyParam.Value; + _params.sys_params.downlink_dwell_time = phyParam.Value; getPhy.Attribute = PHY_DEF_MAX_EIRP; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.def_sys_params.max_eirp = phyParam.fValue; + _params.sys_params.max_eirp = phyParam.fValue; getPhy.Attribute = PHY_DEF_ANTENNA_GAIN; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.def_sys_params.antenna_gain = phyParam.fValue; + _params.sys_params.antenna_gain = phyParam.fValue; lora_phy->load_defaults(INIT_TYPE_INIT); // Init parameters which are not set in function ResetMacParameters - _params.def_sys_params.retry_num = 1; - _params.def_sys_params.max_sys_rx_error = 10; - _params.def_sys_params.min_rx_symb = 6; - - _params.sys_params.max_sys_rx_error = _params.def_sys_params.max_sys_rx_error; - _params.sys_params.min_rx_symb = _params.def_sys_params.min_rx_symb; - _params.sys_params.max_rx_win_time = _params.def_sys_params.max_rx_win_time; - _params.sys_params.recv_delay1 = _params.def_sys_params.recv_delay1; - _params.sys_params.recv_delay2 = _params.def_sys_params.recv_delay2; - _params.sys_params.join_accept_delay1 = _params.def_sys_params.join_accept_delay1; - _params.sys_params.join_accept_delay2 = _params.def_sys_params.join_accept_delay2; - _params.sys_params.retry_num = _params.def_sys_params.retry_num; + _params.sys_params.max_sys_rx_error = 10; + _params.sys_params.min_rx_symb = 6; + _params.sys_params.retry_num = 1; ResetMacParameters( ); @@ -1831,8 +1852,8 @@ lorawan_status_t LoRaMac::LoRaMacQueryTxPossible( uint8_t size, loramac_tx_info_ AdrNextParams_t adrNext; GetPhyParams_t getPhy; PhyParam_t phyParam; - int8_t datarate = _params.def_sys_params.channel_data_rate; - int8_t txPower = _params.def_sys_params.channel_tx_power; + int8_t datarate = _params.sys_params.channel_data_rate; + int8_t txPower = _params.sys_params.channel_tx_power; uint8_t fOptLen = mac_commands.GetLength() + mac_commands.GetRepeatLength(); if( txInfo == NULL ) diff --git a/features/lorawan/lorastack/mac/LoRaMacMib.cpp b/features/lorawan/lorastack/mac/LoRaMacMib.cpp index 9cd3745dc0..7e567cedbe 100644 --- a/features/lorawan/lorastack/mac/LoRaMacMib.cpp +++ b/features/lorawan/lorastack/mac/LoRaMacMib.cpp @@ -158,7 +158,7 @@ lorawan_status_t LoRaMacMib::set_request(loramac_mib_req_confirm_t *mibSet, verify.DatarateParams.DownlinkDwellTime = params->sys_params.downlink_dwell_time; if (_lora_phy->verify(&verify, PHY_RX_DR) == true) { - params->def_sys_params.rx2_channel = mibSet->param.default_rx2_channel; + params->sys_params.rx2_channel = mibSet->param.default_rx2_channel; } else { status = LORAWAN_STATUS_PARAMETER_INVALID; } @@ -215,7 +215,7 @@ lorawan_status_t LoRaMacMib::set_request(loramac_mib_req_confirm_t *mibSet, verify.DatarateParams.Datarate = mibSet->param.default_channel_data_rate; if (_lora_phy->verify(&verify, PHY_DEF_TX_DR) == true) { - params->def_sys_params.channel_data_rate = verify.DatarateParams.Datarate; + params->sys_params.channel_data_rate = verify.DatarateParams.Datarate; } else { status = LORAWAN_STATUS_PARAMETER_INVALID; } @@ -236,7 +236,7 @@ lorawan_status_t LoRaMacMib::set_request(loramac_mib_req_confirm_t *mibSet, verify.TxPower = mibSet->param.default_channel_tx_pwr; if (_lora_phy->verify(&verify, PHY_DEF_TX_POWER) == true) { - params->def_sys_params.channel_tx_power = verify.TxPower; + params->sys_params.channel_tx_power = verify.TxPower; } else { status = LORAWAN_STATUS_PARAMETER_INVALID; } @@ -261,15 +261,11 @@ lorawan_status_t LoRaMacMib::set_request(loramac_mib_req_confirm_t *mibSet, break; } case MIB_SYSTEM_MAX_RX_ERROR: { - params->sys_params.max_sys_rx_error = - params->def_sys_params.max_sys_rx_error = - mibSet->param.max_rx_sys_error; + params->sys_params.max_sys_rx_error = mibSet->param.max_rx_sys_error; break; } case MIB_MIN_RX_SYMBOLS: { - params->sys_params.min_rx_symb = - params->def_sys_params.min_rx_symb = - mibSet->param.min_rx_symb; + params->sys_params.min_rx_symb = mibSet->param.min_rx_symb; break; } case MIB_ANTENNA_GAIN: { @@ -290,6 +286,7 @@ lorawan_status_t LoRaMacMib::get_request(loramac_mib_req_confirm_t *mibGet, lorawan_status_t status = LORAWAN_STATUS_OK; GetPhyParams_t getPhy; PhyParam_t phyParam; + rx2_channel_params rx2_channel; if( mibGet == NULL ) { @@ -358,7 +355,15 @@ lorawan_status_t LoRaMacMib::get_request(loramac_mib_req_confirm_t *mibGet, } case MIB_RX2_DEFAULT_CHANNEL: { - mibGet->param.rx2_channel = params->def_sys_params.rx2_channel; + getPhy.Attribute = PHY_DEF_RX2_DR; + phyParam = _lora_phy->get_phy_params( &getPhy ); + rx2_channel.datarate = phyParam.Value; + + getPhy.Attribute = PHY_DEF_RX2_FREQUENCY; + phyParam = _lora_phy->get_phy_params( &getPhy ); + rx2_channel.frequency = phyParam.Value; + + mibGet->param.rx2_channel = rx2_channel; break; } case MIB_CHANNELS_DEFAULT_MASK: @@ -409,7 +414,9 @@ lorawan_status_t LoRaMacMib::get_request(loramac_mib_req_confirm_t *mibGet, } case MIB_CHANNELS_DEFAULT_DATARATE: { - mibGet->param.default_channel_data_rate = params->def_sys_params.channel_data_rate; + getPhy.Attribute = PHY_DEF_TX_DR; + phyParam = _lora_phy->get_phy_params( &getPhy ); + mibGet->param.default_channel_data_rate = phyParam.Value; break; } case MIB_CHANNELS_DATARATE: @@ -419,7 +426,9 @@ lorawan_status_t LoRaMacMib::get_request(loramac_mib_req_confirm_t *mibGet, } case MIB_CHANNELS_DEFAULT_TX_POWER: { - mibGet->param.default_channel_tx_pwr = params->def_sys_params.channel_tx_power; + getPhy.Attribute = PHY_DEF_TX_POWER; + phyParam = _lora_phy->get_phy_params( &getPhy ); + mibGet->param.default_channel_tx_pwr = phyParam.Value; break; } case MIB_CHANNELS_TX_POWER: diff --git a/features/lorawan/system/lorawan_data_structures.h b/features/lorawan/system/lorawan_data_structures.h index dd97e07cee..844853d0bd 100644 --- a/features/lorawan/system/lorawan_data_structures.h +++ b/features/lorawan/system/lorawan_data_structures.h @@ -2328,11 +2328,6 @@ typedef struct { */ lora_mac_system_params_t sys_params; - /*! - * LoRaMac default parameters - */ - lora_mac_system_params_t def_sys_params; - /*! * Receive Window configurations for PHY layer */ From f2bdef8543a3ce03ac94940dd0561e2ade5e16d5 Mon Sep 17 00:00:00 2001 From: Kimmo Vaisanen Date: Wed, 24 Jan 2018 14:28:25 +0200 Subject: [PATCH 14/23] Add includes for used data types --- features/netsocket/LoRaRadio.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/features/netsocket/LoRaRadio.h b/features/netsocket/LoRaRadio.h index e63db1da84..983c1dbf17 100644 --- a/features/netsocket/LoRaRadio.h +++ b/features/netsocket/LoRaRadio.h @@ -18,6 +18,10 @@ #ifndef LORARADIO_H_ #define LORARADIO_H_ +#include +#include "PinNames.h" +#include "Callback.h" + /** * Structure to hold RF controls for LoRa Radio. * SX1276 have an extra control for the crystal (used in DOSCO-L072CZ) From 44bca596c5fe9980e9d42e41345fc4abd2cb66b0 Mon Sep 17 00:00:00 2001 From: Kimmo Vaisanen Date: Wed, 24 Jan 2018 14:30:22 +0200 Subject: [PATCH 15/23] Use EventQueue for timers Instead of initiating own timer objects we can use EventQueue::call_in() method as we already have handle to EventQueue object. Also setting timeout and starting timer has been combined to TimerStart method. --- features/lorawan/lorastack/mac/LoRaMac.cpp | 70 +++++++------------ features/lorawan/system/LoRaWANTimer.cpp | 21 +++--- features/lorawan/system/LoRaWANTimer.h | 35 ++++------ .../lorawan/system/lorawan_data_structures.h | 5 +- 4 files changed, 50 insertions(+), 81 deletions(-) diff --git a/features/lorawan/lorastack/mac/LoRaMac.cpp b/features/lorawan/lorastack/mac/LoRaMac.cpp index 06615eec44..6f120dcf83 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.cpp +++ b/features/lorawan/lorastack/mac/LoRaMac.cpp @@ -214,19 +214,16 @@ void LoRaMac::OnRadioTxDone( void ) // Setup timers if( _params.is_rx_window_enabled == true ) { - _lora_time.TimerSetValue( &_params.timers.rx_window1_timer, _params.rx_window1_delay ); - _lora_time.TimerStart( &_params.timers.rx_window1_timer ); + _lora_time.TimerStart( _params.timers.rx_window1_timer, _params.rx_window1_delay ); if( _params.dev_class != CLASS_C ) { - _lora_time.TimerSetValue( &_params.timers.rx_window2_timer, _params.rx_window2_delay ); - _lora_time.TimerStart( &_params.timers.rx_window2_timer ); + _lora_time.TimerStart( _params.timers.rx_window2_timer, _params.rx_window2_delay ); } if( ( _params.dev_class == CLASS_C ) || ( _params.is_node_ack_requested == true ) ) { getPhy.Attribute = PHY_ACK_TIMEOUT; phyParam = lora_phy->get_phy_params(&getPhy); - _lora_time.TimerSetValue( &_params.timers.ack_timeout_timer, _params.rx_window2_delay + phyParam.Value ); - _lora_time.TimerStart( &_params.timers.ack_timeout_timer ); + _lora_time.TimerStart( _params.timers.ack_timeout_timer, _params.rx_window2_delay + phyParam.Value ); } } else @@ -281,8 +278,7 @@ void LoRaMac::PrepareRxDoneAbort( void ) _params.flags.bits.mac_done = 1; // Trig OnMacCheckTimerEvent call as soon as possible - _lora_time.TimerSetValue( &_params.timers.mac_state_check_timer, 1 ); - _lora_time.TimerStart( &_params.timers.mac_state_check_timer ); + _lora_time.TimerStart( _params.timers.mac_state_check_timer, 1 ); } void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) @@ -331,7 +327,7 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 lora_phy->put_radio_to_sleep(); - _lora_time.TimerStop( &_params.timers.rx_window2_timer ); + _lora_time.TimerStop( _params.timers.rx_window2_timer ); macHdr.value = payload[pktHeaderLen++]; @@ -679,7 +675,7 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 // Stop the AckTimeout timer as no more retransmissions // are needed. - _lora_time.TimerStop( &_params.timers.ack_timeout_timer ); + _lora_time.TimerStop( _params.timers.ack_timeout_timer ); } else { @@ -689,7 +685,7 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 { // Stop the AckTimeout timer as no more retransmissions // are needed. - _lora_time.TimerStop( &_params.timers.ack_timeout_timer ); + _lora_time.TimerStop( _params.timers.ack_timeout_timer ); } } } @@ -727,8 +723,7 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 _params.flags.bits.mac_done = 1; // Trig OnMacCheckTimerEvent call as soon as possible - _lora_time.TimerSetValue( &_params.timers.mac_state_check_timer, 1 ); - _lora_time.TimerStart( &_params.timers.mac_state_check_timer ); + _lora_time.TimerStart( _params.timers.mac_state_check_timer, 1 ); } void LoRaMac::OnRadioTxTimeout( void ) @@ -771,7 +766,7 @@ void LoRaMac::OnRadioRxError( void ) if( _lora_time.TimerGetElapsedTime( _params.timers.aggregated_last_tx_time ) >= _params.rx_window2_delay ) { - _lora_time.TimerStop( &_params.timers.rx_window2_timer ); + _lora_time.TimerStop( _params.timers.rx_window2_timer ); _params.flags.bits.mac_done = 1; } } @@ -809,7 +804,7 @@ void LoRaMac::OnRadioRxTimeout( void ) if( _lora_time.TimerGetElapsedTime( _params.timers.aggregated_last_tx_time ) >= _params.rx_window2_delay ) { - _lora_time.TimerStop( &_params.timers.rx_window2_timer ); + _lora_time.TimerStop( _params.timers.rx_window2_timer ); _params.flags.bits.mac_done = 1; } } @@ -838,7 +833,7 @@ void LoRaMac::OnMacStateCheckTimerEvent( void ) PhyParam_t phyParam; bool txTimeout = false; - _lora_time.TimerStop( &_params.timers.mac_state_check_timer ); + _lora_time.TimerStop( _params.timers.mac_state_check_timer ); if( _params.flags.bits.mac_done == 1 ) { @@ -1024,9 +1019,7 @@ void LoRaMac::OnMacStateCheckTimerEvent( void ) else { // Operation not finished restart timer - _lora_time.TimerSetValue( &_params.timers.mac_state_check_timer, - MAC_STATE_CHECK_TIMEOUT ); - _lora_time.TimerStart( &_params.timers.mac_state_check_timer ); + _lora_time.TimerStart( _params.timers.mac_state_check_timer, MAC_STATE_CHECK_TIMEOUT ); } // Handle MCPS indication @@ -1058,7 +1051,7 @@ void LoRaMac::OnTxDelayedTimerEvent( void ) loramac_frame_ctrl_t fCtrl; AlternateDrParams_t altDr; - _lora_time.TimerStop( &_params.timers.tx_delayed_timer ); + _lora_time.TimerStop( _params.timers.tx_delayed_timer ); _params.mac_state &= ~LORAMAC_TX_DELAYED; if( ( _params.flags.bits.mlme_req == 1 ) && ( mlme.get_confirmation().req_type == MLME_JOIN ) ) @@ -1085,7 +1078,7 @@ void LoRaMac::OnTxDelayedTimerEvent( void ) void LoRaMac::OnRxWindow1TimerEvent( void ) { - _lora_time.TimerStop( &_params.timers.rx_window1_timer ); + _lora_time.TimerStop( _params.timers.rx_window1_timer ); _params.rx_slot= RX_SLOT_WIN_1; _params.rx_window1_config.channel = _params.channel; @@ -1106,7 +1099,7 @@ void LoRaMac::OnRxWindow1TimerEvent( void ) void LoRaMac::OnRxWindow2TimerEvent( void ) { - _lora_time.TimerStop( &_params.timers.rx_window2_timer ); + _lora_time.TimerStop( _params.timers.rx_window2_timer ); _params.rx_window2_config.channel = _params.channel; _params.rx_window2_config.frequency = _params.sys_params.rx2_channel.frequency; @@ -1133,7 +1126,7 @@ void LoRaMac::OnRxWindow2TimerEvent( void ) void LoRaMac::OnAckTimeoutTimerEvent( void ) { - _lora_time.TimerStop( &_params.timers.ack_timeout_timer ); + _lora_time.TimerStop( _params.timers.ack_timeout_timer ); if( _params.is_node_ack_requested == true ) { @@ -1305,8 +1298,7 @@ lorawan_status_t LoRaMac::ScheduleTx( void ) _params.mac_state |= LORAMAC_TX_DELAYED; tr_debug("Next Transmission in %lu ms", dutyCycleTimeOff); - _lora_time.TimerSetValue( &_params.timers.tx_delayed_timer, dutyCycleTimeOff ); - _lora_time.TimerStart( &_params.timers.tx_delayed_timer ); + _lora_time.TimerStart( _params.timers.tx_delayed_timer, dutyCycleTimeOff ); return LORAWAN_STATUS_OK; } @@ -1654,8 +1646,7 @@ lorawan_status_t LoRaMac::SendFrameOnChannel( uint8_t channel ) mlme.get_confirmation().tx_toa = _params.timers.tx_toa; // Starts the MAC layer status check timer - _lora_time.TimerSetValue( &_params.timers.mac_state_check_timer, MAC_STATE_CHECK_TIMEOUT ); - _lora_time.TimerStart( &_params.timers.mac_state_check_timer ); + _lora_time.TimerStart( _params.timers.mac_state_check_timer, MAC_STATE_CHECK_TIMEOUT ); if( _params.is_nwk_joined == false ) { @@ -1684,8 +1675,7 @@ lorawan_status_t LoRaMac::SetTxContinuousWave( uint16_t timeout ) lora_phy->set_tx_cont_mode(&continuousWave); // Starts the MAC layer status check timer - _lora_time.TimerSetValue( &_params.timers.mac_state_check_timer, MAC_STATE_CHECK_TIMEOUT ); - _lora_time.TimerStart( &_params.timers.mac_state_check_timer ); + _lora_time.TimerStart( _params.timers.mac_state_check_timer, MAC_STATE_CHECK_TIMEOUT ); _params.mac_state |= LORAMAC_TX_RUNNING; @@ -1697,8 +1687,7 @@ lorawan_status_t LoRaMac::SetTxContinuousWave1( uint16_t timeout, uint32_t frequ lora_phy->setup_tx_cont_wave_mode(frequency, power, timeout); // Starts the MAC layer status check timer - _lora_time.TimerSetValue( &_params.timers.mac_state_check_timer, MAC_STATE_CHECK_TIMEOUT ); - _lora_time.TimerStart( &_params.timers.mac_state_check_timer ); + _lora_time.TimerStart( _params.timers.mac_state_check_timer, MAC_STATE_CHECK_TIMEOUT ); _params.mac_state |= LORAMAC_TX_RUNNING; @@ -1828,17 +1817,15 @@ lorawan_status_t LoRaMac::LoRaMacInitialization(loramac_primitives_t *primitives lora_phy->put_radio_to_sleep(); // Initialize timers - _lora_time.TimerInit(&_params.timers.mac_state_check_timer, + _lora_time.TimerInit(_params.timers.mac_state_check_timer, mbed::callback(this, &LoRaMac::handle_mac_state_check_timer_event)); - _lora_time.TimerSetValue(&_params.timers.mac_state_check_timer, MAC_STATE_CHECK_TIMEOUT); - - _lora_time.TimerInit(&_params.timers.tx_delayed_timer, + _lora_time.TimerInit(_params.timers.tx_delayed_timer, mbed::callback(this, &LoRaMac::handle_delayed_tx_timer_event)); - _lora_time.TimerInit(&_params.timers.rx_window1_timer, + _lora_time.TimerInit(_params.timers.rx_window1_timer, mbed::callback(this, &LoRaMac::handle_rx1_timer_event)); - _lora_time.TimerInit(&_params.timers.rx_window2_timer, + _lora_time.TimerInit(_params.timers.rx_window2_timer, mbed::callback(this, &LoRaMac::handle_rx2_timer_event)); - _lora_time.TimerInit(&_params.timers.ack_timeout_timer, + _lora_time.TimerInit(_params.timers.ack_timeout_timer, mbed::callback(this, &LoRaMac::handle_ack_timeout)); // Store the current initialization time @@ -2071,16 +2058,13 @@ radio_events_t *LoRaMac::GetPhyEventHandlers() lorawan_status_t LoRaMac::LoRaMacSetTxTimer( uint32_t TxDutyCycleTime ) { - _lora_time.TimerSetValue(&tx_next_packet_timer, TxDutyCycleTime); - _lora_time.TimerStart(&tx_next_packet_timer); - + _lora_time.TimerStart(tx_next_packet_timer, TxDutyCycleTime); return LORAWAN_STATUS_OK; } lorawan_status_t LoRaMac::LoRaMacStopTxTimer( ) { - _lora_time.TimerStop(&tx_next_packet_timer); - + _lora_time.TimerStop(tx_next_packet_timer); return LORAWAN_STATUS_OK; } diff --git a/features/lorawan/system/LoRaWANTimer.cpp b/features/lorawan/system/LoRaWANTimer.cpp index ca5a8ce598..3c25db431e 100644 --- a/features/lorawan/system/LoRaWANTimer.cpp +++ b/features/lorawan/system/LoRaWANTimer.cpp @@ -45,23 +45,20 @@ lorawan_time_t LoRaWANTimeHandler::TimerGetElapsedTime( lorawan_time_t savedTime return TimerGetCurrentTime() - savedTime; } -void LoRaWANTimeHandler::TimerInit( timer_event_t *obj, mbed::Callback callback) +void LoRaWANTimeHandler::TimerInit( timer_event_t &obj, mbed::Callback callback) { - obj->value = 0; - obj->callback = callback; + obj.callback = callback; + obj.timer_id = 0; } -void LoRaWANTimeHandler::TimerStart( timer_event_t *obj ) +void LoRaWANTimeHandler::TimerStart( timer_event_t &obj, const uint32_t timeout ) { - obj->timer.get()->attach_us(obj->callback, obj->value * 1000 ); + obj.timer_id = _queue->call_in(timeout, obj.callback); + MBED_ASSERT(obj.timer_id != 0); } -void LoRaWANTimeHandler::TimerStop( timer_event_t *obj ) +void LoRaWANTimeHandler::TimerStop( timer_event_t &obj ) { - obj->timer.get()->detach( ); -} - -void LoRaWANTimeHandler::TimerSetValue( timer_event_t *obj, uint32_t value ) -{ - obj->value = value; + _queue->cancel(obj.timer_id); + obj.timer_id = 0; } diff --git a/features/lorawan/system/LoRaWANTimer.h b/features/lorawan/system/LoRaWANTimer.h index 797c29493c..f909489d55 100644 --- a/features/lorawan/system/LoRaWANTimer.h +++ b/features/lorawan/system/LoRaWANTimer.h @@ -40,17 +40,6 @@ public: */ void TimerTimeCounterInit(events::EventQueue *queue); - /*! - * \brief Initializes the timer object. - * - * \remark The TimerSetValue function must be called before starting the timer. - * This function initializes the timestamp and reloads the value at 0. - * - * \param [in] obj The structure containing the timer object parameters. - * \param [in] callback The function callback called at the end of the timeout. - */ - void TimerInit( timer_event_t *obj, mbed::Callback callback); - /*! * \brief Read the current time. * @@ -66,29 +55,31 @@ public: */ lorawan_time_t TimerGetElapsedTime( lorawan_time_t savedTime ); - + /*! + * \brief Initializes the timer object. + * + * \remark The TimerSetValue function must be called before starting the timer. + * This function initializes the timestamp and reloads the value at 0. + * + * \param [in] obj The structure containing the timer object parameters. + * \param [in] callback The function callback called at the end of the timeout. + */ + void TimerInit( timer_event_t &obj, mbed::Callback callback); /*! * \brief Starts and adds the timer object to the list of timer events. * * \param [in] obj The structure containing the timer object parameters. + * \param [in] value The new timeout value. */ - void TimerStart( timer_event_t *obj ); + void TimerStart( timer_event_t &obj, const uint32_t timeout ); /*! * \brief Stops and removes the timer object from the list of timer events. * * \param [in] obj The structure containing the timer object parameters. */ - void TimerStop( timer_event_t *obj ); - - /*! - * \brief Set a new timeout value. - * - * \param [in] obj The structure containing the timer object parameters. - * \param [in] value The new timeout value. - */ - void TimerSetValue( timer_event_t *obj, uint32_t value ); + void TimerStop( timer_event_t &obj ); private: events::EventQueue *_queue; diff --git a/features/lorawan/system/lorawan_data_structures.h b/features/lorawan/system/lorawan_data_structures.h index 844853d0bd..e6d4f9e907 100644 --- a/features/lorawan/system/lorawan_data_structures.h +++ b/features/lorawan/system/lorawan_data_structures.h @@ -24,9 +24,7 @@ #define LORAWAN_SYSTEM_LORAWAN_DATA_STRUCTURES_H_ #include -#include "drivers/Ticker.h" #include "platform/Callback.h" -#include "platform/SingletonPtr.h" /*! * \brief Timer time variable definition @@ -2052,9 +2050,8 @@ typedef struct { * \brief Timer object description */ typedef struct { - uint32_t value; mbed::Callback callback; - SingletonPtr timer; + int timer_id; } timer_event_t; /*! From 35045f19cc466df9f1d3f4b2f2e4b9ac01c3a923 Mon Sep 17 00:00:00 2001 From: Kimmo Vaisanen Date: Fri, 26 Jan 2018 14:33:26 +0200 Subject: [PATCH 16/23] Implement LoRaMac::disconnect In order to reset LoRaMac's state in disconnect, we need to implement an API which can be used to cancel all outstanding requests and reset LoRaMac's internal state to idle. This commit introduces LoRaMac::disconnect() which can be used for this purpose. --- features/lorawan/LoRaWANStack.cpp | 3 +++ features/lorawan/lorastack/mac/LoRaMac.cpp | 30 ++++++++++++++++++++++ features/lorawan/lorastack/mac/LoRaMac.h | 8 ++++++ 3 files changed, 41 insertions(+) diff --git a/features/lorawan/LoRaWANStack.cpp b/features/lorawan/LoRaWANStack.cpp index 17cffa5fc1..9846079ec7 100644 --- a/features/lorawan/LoRaWANStack.cpp +++ b/features/lorawan/LoRaWANStack.cpp @@ -1193,6 +1193,9 @@ lorawan_status_t LoRaWANStack::lora_state_machine() */ drop_channel_list(); + // Shutdown LoRaMac + _loramac.disconnect(); + // Stop sending messages and set joined status to false. #if defined(LORAWAN_COMPLIANCE_TEST) _loramac.LoRaMacStopTxTimer(); diff --git a/features/lorawan/lorastack/mac/LoRaMac.cpp b/features/lorawan/lorastack/mac/LoRaMac.cpp index 6f120dcf83..346387c36c 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.cpp +++ b/features/lorawan/lorastack/mac/LoRaMac.cpp @@ -1834,6 +1834,36 @@ lorawan_status_t LoRaMac::LoRaMacInitialization(loramac_primitives_t *primitives return LORAWAN_STATUS_OK; } +void LoRaMac::disconnect() +{ + // Cancel all timers + _lora_time.TimerStop(_params.timers.mac_state_check_timer); + _lora_time.TimerStop(_params.timers.tx_delayed_timer); + _lora_time.TimerStop(_params.timers.rx_window1_timer); + _lora_time.TimerStop(_params.timers.rx_window2_timer); + _lora_time.TimerStop(_params.timers.ack_timeout_timer); + + // Put radio to sleep + lora_phy->put_radio_to_sleep(); + + // Reset internal state + _params.is_nwk_joined = false; + _params.is_ack_retry_timeout_expired = false; + _params.is_rx_window_enabled = true; + _params.is_node_ack_requested = false; + _params.is_srv_ack_requested = false; + _params.flags.value = 0; + _params.mac_state = 0; + + // Clear MAC commands + mac_commands.ClearCommandBuffer(); + mac_commands.ClearRepeatBuffer(); + mac_commands.ClearMacCommandsInNextTx(); + + // Set internal state to idle. + _params.mac_state = LORAMAC_IDLE; +} + lorawan_status_t LoRaMac::LoRaMacQueryTxPossible( uint8_t size, loramac_tx_info_t* txInfo ) { AdrNextParams_t adrNext; diff --git a/features/lorawan/lorastack/mac/LoRaMac.h b/features/lorawan/lorastack/mac/LoRaMac.h index 668381d3f2..ee31fc36e5 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.h +++ b/features/lorawan/lorastack/mac/LoRaMac.h @@ -91,6 +91,14 @@ public: LoRaPHY *phy, events::EventQueue *queue); + /*! + * \brief Disconnect LoRaMac layer + * + * \details Cancels all outstanding requests and sets LoRaMac's + * internal state to idle. + */ + void disconnect(void); + /*! * \brief Queries the LoRaMAC whether it is possible to send the next frame with * a given payload size. The LoRaMAC takes the scheduled MAC commands into From 5d98839092e068948ca6a1540d8d87513502a295 Mon Sep 17 00:00:00 2001 From: Kimmo Vaisanen Date: Fri, 9 Feb 2018 09:59:15 +0200 Subject: [PATCH 17/23] Improve error handling & robustness This commit also introduces API change for disconnect(). disconnect() will now return LORAWAN_STATUS_DEVICE_OFF for successfull disconnect. * LoRaWANStack::handle_tx() can be called with NULL buffer when length is 0. This commit fixes the case where user has provided NULL buffer and length is > max_possible_size. handle_tx() now always returns LORAWAN_STATUS_PARAMETER_INVALID if given buffer is NULL pointer and length > 0. General error checking is added and some asserts are added for events. --- features/lorawan/LoRaWANInterface.cpp | 3 +- features/lorawan/LoRaWANInterface.h | 3 +- features/lorawan/LoRaWANStack.cpp | 113 +++++++++++------- features/lorawan/LoRaWANStack.h | 6 +- features/lorawan/lorastack/mac/LoRaMac.cpp | 94 ++++++++++----- features/lorawan/lorastack/mac/LoRaMac.h | 60 +++++----- .../lorastack/mac/LoRaMacChannelPlan.h | 2 + .../lorawan/lorastack/mac/LoRaMacCommand.cpp | 38 +++--- .../lorawan/lorastack/mac/LoRaMacCommand.h | 14 ++- .../lorawan/lorastack/mac/LoRaMacMcps.cpp | 2 +- features/lorawan/system/LoRaWANTimer.h | 2 +- .../lorawan/system/lorawan_data_structures.h | 16 +-- features/netsocket/LoRaWANBase.h | 1 - 13 files changed, 208 insertions(+), 146 deletions(-) diff --git a/features/lorawan/LoRaWANInterface.cpp b/features/lorawan/LoRaWANInterface.cpp index b11759744c..8d45b0dee3 100644 --- a/features/lorawan/LoRaWANInterface.cpp +++ b/features/lorawan/LoRaWANInterface.cpp @@ -113,8 +113,7 @@ lorawan_status_t LoRaWANInterface::connect(const lorawan_connect_t &connect) lorawan_status_t LoRaWANInterface::disconnect() { - stk_obj().shutdown(); - return LORAWAN_STATUS_OK; + return stk_obj().shutdown(); } lorawan_status_t LoRaWANInterface::add_link_check_request() diff --git a/features/lorawan/LoRaWANInterface.h b/features/lorawan/LoRaWANInterface.h index f64fe1609b..3889526ebf 100644 --- a/features/lorawan/LoRaWANInterface.h +++ b/features/lorawan/LoRaWANInterface.h @@ -125,8 +125,7 @@ public: /** Disconnect the current session. * - * @return LORAWAN_STATUS_OK on success, a negative error code on - * failure. + * @return LORAWAN_STATUS_DEVICE_OFF on successfully shutdown. */ virtual lorawan_status_t disconnect(); diff --git a/features/lorawan/LoRaWANStack.cpp b/features/lorawan/LoRaWANStack.cpp index 9846079ec7..f913b7499c 100644 --- a/features/lorawan/LoRaWANStack.cpp +++ b/features/lorawan/LoRaWANStack.cpp @@ -107,11 +107,15 @@ LoRaWANStack::LoRaWANStack() memset(&_lw_session, 0, sizeof(_lw_session)); memset(&_tx_msg, 0, sizeof(_tx_msg)); memset(&_rx_msg, 0, sizeof(_rx_msg)); + + LoRaMacPrimitives.mcps_confirm = callback(this, &LoRaWANStack::mcps_confirm_handler); + LoRaMacPrimitives.mcps_indication = callback(this, &LoRaWANStack::mcps_indication_handler); + LoRaMacPrimitives.mlme_confirm = callback(this, &LoRaWANStack::mlme_confirm_handler); + LoRaMacPrimitives.mlme_indication = callback(this, &LoRaWANStack::mlme_indication_handler); } LoRaWANStack::~LoRaWANStack() { - } /***************************************************************************** @@ -131,6 +135,7 @@ radio_events_t *LoRaWANStack::bind_radio_driver(LoRaRadio& radio) _lora_phy.set_radio_instance(radio); return _mac_handlers; } + lorawan_status_t LoRaWANStack::initialize_mac_layer(EventQueue *queue) { if (DEVICE_STATE_NOT_INITIALIZED != _device_current_state) @@ -139,31 +144,20 @@ lorawan_status_t LoRaWANStack::initialize_mac_layer(EventQueue *queue) return LORAWAN_STATUS_OK; } - static loramac_primitives_t LoRaMacPrimitives; - static loramac_mib_req_confirm_t mib_req; - -#if defined(LORAWAN_COMPLIANCE_TEST) - static uint8_t compliance_test_buffer[MBED_CONF_LORA_TX_MAX_SIZE]; -#endif - tr_debug("Initializing MAC layer"); //store a pointer to Event Queue _queue = queue; #if defined(LORAWAN_COMPLIANCE_TEST) - // Allocate memory for compliance test _compliance_test.app_data_buffer = compliance_test_buffer; #endif _lora_time.TimerTimeCounterInit(queue); - - LoRaMacPrimitives.mcps_confirm = callback(this, &LoRaWANStack::mcps_confirm_handler); - LoRaMacPrimitives.mcps_indication = callback(this, &LoRaWANStack::mcps_indication_handler); - LoRaMacPrimitives.mlme_confirm = callback(this, &LoRaWANStack::mlme_confirm_handler); - LoRaMacPrimitives.mlme_indication = callback(this, &LoRaWANStack::mlme_indication_handler); _loramac.LoRaMacInitialization(&LoRaMacPrimitives, &_lora_phy, queue); + loramac_mib_req_confirm_t mib_req; + mib_req.type = MIB_ADR; mib_req.param.is_adr_enable = MBED_CONF_LORA_ADR_ON; mib_set_request(&mib_req); @@ -385,7 +379,6 @@ void LoRaWANStack::mlme_indication_handler(loramac_mlme_indication_t *mlmeIndica } } - void LoRaWANStack::set_lora_callbacks(lorawan_app_callbacks_t *cbs) { if (cbs) { @@ -597,6 +590,10 @@ int16_t LoRaWANStack::handle_tx(uint8_t port, const uint8_t* data, return LORAWAN_STATUS_WOULD_BLOCK; } + if (!data && length > 0) { + return LORAWAN_STATUS_PARAMETER_INVALID; + } + #if defined(LORAWAN_COMPLIANCE_TEST) if (_compliance_test.running) { return LORAWAN_STATUS_COMPLIANCE_TEST_ON; @@ -653,7 +650,7 @@ int16_t LoRaWANStack::handle_tx(uint8_t port, const uint8_t* data, _tx_msg.f_buffer_size = length; _tx_msg.pending_size = 0; // copy user buffer upto the max_possible_size - if (data && length > 0) { + if (length > 0) { memcpy(_tx_msg.f_buffer, data, length); } } @@ -679,11 +676,11 @@ int16_t LoRaWANStack::handle_tx(uint8_t port, const uint8_t* data, tr_info("RTS = %u bytes, PEND = %u", _tx_msg.f_buffer_size, _tx_msg.pending_size); set_device_state(DEVICE_STATE_SEND); - lora_state_machine(); + status = lora_state_machine(); // send user the length of data which is scheduled now. // user should take care of the pending data. - return _tx_msg.f_buffer_size; + return (status == LORAWAN_STATUS_OK) ? _tx_msg.f_buffer_size : status; } int16_t LoRaWANStack::handle_rx(const uint8_t port, uint8_t* data, @@ -785,6 +782,8 @@ lorawan_status_t LoRaWANStack::mlme_request_handler(loramac_mlme_req_t *mlme_req void LoRaWANStack::mlme_confirm_handler(loramac_mlme_confirm_t *mlme_confirm) { if (NULL == mlme_confirm) { + tr_error("mlme_confirm: struct [in] is null!"); + MBED_ASSERT(0); return; } @@ -793,14 +792,20 @@ void LoRaWANStack::mlme_confirm_handler(loramac_mlme_confirm_t *mlme_confirm) if (mlme_confirm->status == LORAMAC_EVENT_INFO_STATUS_OK) { // Status is OK, node has joined the network set_device_state(DEVICE_STATE_JOINED); - lora_state_machine(); + if (lora_state_machine() != LORAWAN_STATUS_OK) { + tr_error("Lora state machine did not return LORAWAN_STATUS_OK"); + } } else { // Join attempt failed. set_device_state(DEVICE_STATE_IDLE); - lora_state_machine(); + if (lora_state_machine() != LORAWAN_STATUS_IDLE) { + tr_error("Lora state machine did not return DEVICE_STATE_IDLE !"); + } if (_callbacks.events) { - _queue->call(_callbacks.events, JOIN_FAILURE); + const int ret = _queue->call(_callbacks.events, JOIN_FAILURE); + MBED_ASSERT(ret != 0); + (void)ret; } } break; @@ -818,15 +823,16 @@ void LoRaWANStack::mlme_confirm_handler(loramac_mlme_confirm_t *mlme_confirm) { // normal operation as oppose to compliance testing if (_callbacks.link_check_resp) { - _queue->call(_callbacks.link_check_resp, - mlme_confirm->demod_margin, - mlme_confirm->nb_gateways); + const int ret = _queue->call(_callbacks.link_check_resp, + mlme_confirm->demod_margin, + mlme_confirm->nb_gateways); + MBED_ASSERT(ret != 0); + (void)ret; } } } break; default: - return; break; } } @@ -848,7 +854,8 @@ lorawan_status_t LoRaWANStack::mcps_request_handler(loramac_mcps_req_t *mcps_req void LoRaWANStack::mcps_confirm_handler(loramac_mcps_confirm_t *mcps_confirm) { if (mcps_confirm == NULL) { - tr_error("mcps_confirm: struct [in] is null."); + tr_error("mcps_confirm: struct [in] is null!"); + MBED_ASSERT(0); return; } @@ -865,7 +872,9 @@ void LoRaWANStack::mcps_confirm_handler(loramac_mcps_confirm_t *mcps_confirm) // If sending timed out, we have a special event for that if (mcps_confirm->status == LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT) { if (_callbacks.events) { - _queue->call(_callbacks.events, TX_TIMEOUT); + const int ret = _queue->call(_callbacks.events, TX_TIMEOUT); + MBED_ASSERT(ret != 0); + (void)ret; } return; } if (mcps_confirm->status == LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT) { @@ -874,7 +883,9 @@ void LoRaWANStack::mcps_confirm_handler(loramac_mcps_confirm_t *mcps_confirm) // Otherwise send a general TX_ERROR event if (_callbacks.events) { - _queue->call(_callbacks.events, TX_ERROR); + const int ret = _queue->call(_callbacks.events, TX_ERROR); + MBED_ASSERT(ret != 0); + (void)ret; } return; } @@ -896,7 +907,9 @@ void LoRaWANStack::mcps_confirm_handler(loramac_mcps_confirm_t *mcps_confirm) _lw_session.uplink_counter = mcps_confirm->ul_frame_counter; _tx_msg.tx_ongoing = false; if (_callbacks.events) { - _queue->call(_callbacks.events, TX_DONE); + const int ret = _queue->call(_callbacks.events, TX_DONE); + MBED_ASSERT(ret != 0); + (void)ret; } } @@ -914,7 +927,9 @@ void LoRaWANStack::mcps_indication_handler(loramac_mcps_indication_t *mcps_indic if (mcps_indication->status != LORAMAC_EVENT_INFO_STATUS_OK) { if (_callbacks.events) { - _queue->call(_callbacks.events, RX_ERROR); + const int ret = _queue->call(_callbacks.events, RX_ERROR); + MBED_ASSERT(ret != 0); + (void)ret; } return; } @@ -971,7 +986,9 @@ void LoRaWANStack::mcps_indication_handler(loramac_mcps_indication_t *mcps_indic // to the size 255 bytes tr_debug("Cannot receive more than buffer capacity!"); if (_callbacks.events) { - _queue->call(_callbacks.events, RX_ERROR); + const int ret = _queue->call(_callbacks.events, RX_ERROR); + MBED_ASSERT(ret != 0); + (void)ret; } return; } else { @@ -987,7 +1004,9 @@ void LoRaWANStack::mcps_indication_handler(loramac_mcps_indication_t *mcps_indic tr_debug("Received %d bytes", _rx_msg.msg.mcps_indication.buffer_size); _rx_msg.receive_ready = true; if (_callbacks.events) { - _queue->call(_callbacks.events, RX_DONE); + const int ret = _queue->call(_callbacks.events, RX_DONE); + MBED_ASSERT(ret != 0); + (void)ret; } // If fPending bit is set we try to generate an empty packet @@ -1146,7 +1165,6 @@ lorawan_status_t LoRaWANStack::mib_set_request(loramac_mib_req_confirm_t *mib_se if (NULL == mib_set_params) { return LORAWAN_STATUS_PARAMETER_INVALID; } - return _loramac.LoRaMacMibSetRequestConfirm(mib_set_params); } @@ -1155,10 +1173,7 @@ lorawan_status_t LoRaWANStack::mib_get_request(loramac_mib_req_confirm_t *mib_ge if(NULL == mib_get_params) { return LORAWAN_STATUS_PARAMETER_INVALID; } - return _loramac.LoRaMacMibGetRequestConfirm(mib_get_params); - - } lorawan_status_t LoRaWANStack::set_link_check_request() @@ -1174,10 +1189,10 @@ lorawan_status_t LoRaWANStack::set_link_check_request() return mlme_request_handler(&mlme_req); } -void LoRaWANStack::shutdown() +lorawan_status_t LoRaWANStack::shutdown() { set_device_state(DEVICE_STATE_SHUTDOWN); - lora_state_machine(); + return lora_state_machine(); } lorawan_status_t LoRaWANStack::lora_state_machine() @@ -1219,7 +1234,9 @@ lorawan_status_t LoRaWANStack::lora_state_machine() tr_debug("LoRaWAN protocol has been shut down."); if (_callbacks.events) { - _queue->call(_callbacks.events, DISCONNECTED); + const int ret = _queue->call(_callbacks.events, DISCONNECTED); + MBED_ASSERT(ret != 0); + (void)ret; } status = LORAWAN_STATUS_DEVICE_OFF; break; @@ -1254,7 +1271,6 @@ lorawan_status_t LoRaWANStack::lora_state_machine() return LORAWAN_STATUS_CONNECT_IN_PROGRESS; } else { status = LORAWAN_STATUS_PARAMETER_INVALID; - break; } break; case DEVICE_STATE_JOINED: @@ -1263,8 +1279,11 @@ lorawan_status_t LoRaWANStack::lora_state_machine() _lw_session.active = true; // Tell the application that we are connected if (_callbacks.events) { - _queue->call(_callbacks.events, CONNECTED); + const int ret = _queue->call(_callbacks.events, CONNECTED); + MBED_ASSERT(ret != 0); + (void)ret; } + status = LORAWAN_STATUS_OK; break; case DEVICE_STATE_ABP_CONNECTING: /* @@ -1297,7 +1316,9 @@ lorawan_status_t LoRaWANStack::lora_state_machine() // Session is now active _lw_session.active = true; if (_callbacks.events) { - _queue->call(_callbacks.events, CONNECTED); + const int ret = _queue->call(_callbacks.events, CONNECTED); + MBED_ASSERT(ret != 0); + (void)ret; } break; case DEVICE_STATE_SEND: @@ -1315,13 +1336,17 @@ lorawan_status_t LoRaWANStack::lora_state_machine() case LORAWAN_STATUS_CRYPTO_FAIL: tr_error("Crypto failed. Clearing TX buffers"); if (_callbacks.events) { - _queue->call(_callbacks.events, TX_CRYPTO_ERROR); + const int ret = _queue->call(_callbacks.events, TX_CRYPTO_ERROR); + MBED_ASSERT(ret != 0); + (void)ret; } break; default: tr_error("Failure to schedule TX!"); if (_callbacks.events) { - _queue->call(_callbacks.events, TX_SCHEDULING_ERROR); + const int ret = _queue->call(_callbacks.events, TX_SCHEDULING_ERROR); + MBED_ASSERT(ret != 0); + (void)ret; } break; } diff --git a/features/lorawan/LoRaWANStack.h b/features/lorawan/LoRaWANStack.h index 27ae1744a3..08daf98ca9 100644 --- a/features/lorawan/LoRaWANStack.h +++ b/features/lorawan/LoRaWANStack.h @@ -322,8 +322,10 @@ public: /** Shuts down the LoRaWAN protocol. * * In response to the user call for disconnection, the stack shuts down itself. + * + * @return LORAWAN_STATUS_DEVICE_OFF on successfully shutdown. */ - void shutdown(); + lorawan_status_t shutdown(); private: LoRaWANStack(); @@ -442,8 +444,10 @@ private: LoRaWANTimeHandler _lora_time; LoRaMac _loramac; LoRaPHY_region _lora_phy; + loramac_primitives_t LoRaMacPrimitives; #if defined(LORAWAN_COMPLIANCE_TEST) + uint8_t compliance_test_buffer[MBED_CONF_LORA_TX_MAX_SIZE]; compliance_test_t _compliance_test; #endif diff --git a/features/lorawan/lorastack/mac/LoRaMac.cpp b/features/lorawan/lorastack/mac/LoRaMac.cpp index 346387c36c..211c5b53da 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.cpp +++ b/features/lorawan/lorastack/mac/LoRaMac.cpp @@ -36,10 +36,6 @@ SPDX-License-Identifier: BSD-3-Clause using namespace events; -/** - * EventQueue object storage - */ -static EventQueue *ev_queue; /*! * Maximum length of the fOpts field @@ -119,6 +115,8 @@ LoRaMac::LoRaMac(LoRaWANTimeHandler &lora_time) _params.sys_params.adr_on = false; _params.sys_params.max_duty_cycle = 0; + + LoRaMacPrimitives = NULL; } LoRaMac::~LoRaMac() @@ -131,64 +129,88 @@ LoRaMac::~LoRaMac() **************************************************************************/ void LoRaMac::handle_tx_done(void) { - ev_queue->call(this, &LoRaMac::OnRadioTxDone); + const int ret = ev_queue->call(this, &LoRaMac::OnRadioTxDone); + MBED_ASSERT(ret != 0); + (void)ret; } void LoRaMac::handle_rx_done(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr) { - ev_queue->call(this, &LoRaMac::OnRadioRxDone, payload, size, rssi, snr); + const int ret = ev_queue->call(this, &LoRaMac::OnRadioRxDone, payload, size, rssi, snr); + MBED_ASSERT(ret != 0); + (void)ret; } void LoRaMac::handle_rx_error(void) { - ev_queue->call(this, &LoRaMac::OnRadioRxError); + const int ret = ev_queue->call(this, &LoRaMac::OnRadioRxError); + MBED_ASSERT(ret != 0); + (void)ret; } void LoRaMac::handle_rx_timeout(void) { - ev_queue->call(this, &LoRaMac::OnRadioRxTimeout); + const int ret = ev_queue->call(this, &LoRaMac::OnRadioRxTimeout); + MBED_ASSERT(ret != 0); + (void)ret; } void LoRaMac::handle_tx_timeout(void) { - ev_queue->call(this, &LoRaMac::OnRadioTxTimeout); + const int ret = ev_queue->call(this, &LoRaMac::OnRadioTxTimeout); + MBED_ASSERT(ret != 0); + (void)ret; } void LoRaMac::handle_cad_done(bool cad) { //TODO Not implemented yet - //ev_queue->call(this, &LoRaMac::OnRadioCadDone, cad); + //const int ret = ev_queue->call(this, &LoRaMac::OnRadioCadDone, cad); + //MBED_ASSERT(ret != 0); + //(void)ret; } void LoRaMac::handle_fhss_change_channel(uint8_t cur_channel) { // TODO Not implemented yet - //ev_queue->call(this, &LoRaMac::OnRadioFHSSChangeChannel, cur_channel); + //const int ret = ev_queue->call(this, &LoRaMac::OnRadioFHSSChangeChannel, cur_channel); + //MBED_ASSERT(ret != 0); + //(void)ret; } void LoRaMac::handle_mac_state_check_timer_event(void) { - ev_queue->call(this, &LoRaMac::OnMacStateCheckTimerEvent); + const int ret = ev_queue->call(this, &LoRaMac::OnMacStateCheckTimerEvent); + MBED_ASSERT(ret != 0); + (void)ret; } void LoRaMac::handle_delayed_tx_timer_event(void) { - ev_queue->call(this, &LoRaMac::OnTxDelayedTimerEvent); + const int ret = ev_queue->call(this, &LoRaMac::OnTxDelayedTimerEvent); + MBED_ASSERT(ret != 0); + (void)ret; } void LoRaMac::handle_ack_timeout() { - ev_queue->call(this, &LoRaMac::OnAckTimeoutTimerEvent); + const int ret = ev_queue->call(this, &LoRaMac::OnAckTimeoutTimerEvent); + MBED_ASSERT(ret != 0); + (void)ret; } void LoRaMac::handle_rx1_timer_event(void) { - ev_queue->call(this, &LoRaMac::OnRxWindow1TimerEvent); + const int ret = ev_queue->call(this, &LoRaMac::OnRxWindow1TimerEvent); + MBED_ASSERT(ret != 0); + (void)ret; } void LoRaMac::handle_rx2_timer_event(void) { - ev_queue->call(this, &LoRaMac::OnRxWindow2TimerEvent); + const int ret = ev_queue->call(this, &LoRaMac::OnRxWindow2TimerEvent); + MBED_ASSERT(ret != 0); + (void)ret; } /*************************************************************************** @@ -293,7 +315,6 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 uint8_t pktHeaderLen = 0; uint32_t address = 0; uint8_t appPayloadStartIndex = 0; - uint8_t port = 0xFF; uint8_t frameLen = 0; uint32_t mic = 0; uint32_t micRx = 0; @@ -596,7 +617,7 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 // Process payload and MAC commands if( ( ( size - 4 ) - appPayloadStartIndex ) > 0 ) { - port = payload[appPayloadStartIndex++]; + uint8_t port = payload[appPayloadStartIndex++]; frameLen = ( size - 4 ) - appPayloadStartIndex; mcps.get_indication().port = port; @@ -617,9 +638,11 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 } // Decode frame payload MAC commands - mac_commands.ProcessMacCommands( _params.payload, 0, frameLen, snr, - mlme.get_confirmation(), - _params.sys_params, *lora_phy ); + if (mac_commands.ProcessMacCommands( _params.payload, 0, frameLen, snr, + mlme.get_confirmation(), + _params.sys_params, *lora_phy ) != LORAWAN_STATUS_OK ) { + mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_ERROR; + } } else { @@ -631,9 +654,11 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 if( fCtrl.bits.fopts_len > 0 ) { // Decode Options field MAC commands. Omit the fPort. - mac_commands.ProcessMacCommands( payload, 8, appPayloadStartIndex - 1, snr, - mlme.get_confirmation(), - _params.sys_params, *lora_phy ); + if (mac_commands.ProcessMacCommands( payload, 8, appPayloadStartIndex - 1, snr, + mlme.get_confirmation(), + _params.sys_params, *lora_phy ) != LORAWAN_STATUS_OK ) { + mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_ERROR; + } } if (0 != LoRaMacPayloadDecrypt( payload + appPayloadStartIndex, @@ -659,9 +684,11 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 if( fCtrl.bits.fopts_len > 0 ) { // Decode Options field MAC commands - mac_commands.ProcessMacCommands( payload, 8, appPayloadStartIndex, snr, - mlme.get_confirmation(), - _params.sys_params, *lora_phy ); + if (mac_commands.ProcessMacCommands( payload, 8, appPayloadStartIndex, snr, + mlme.get_confirmation(), + _params.sys_params, *lora_phy ) != LORAWAN_STATUS_OK ) { + mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_ERROR; + } } } @@ -1051,6 +1078,8 @@ void LoRaMac::OnTxDelayedTimerEvent( void ) loramac_frame_ctrl_t fCtrl; AlternateDrParams_t altDr; + lorawan_status_t status = LORAWAN_STATUS_OK; + _lora_time.TimerStop( _params.timers.tx_delayed_timer ); _params.mac_state &= ~LORAMAC_TX_DELAYED; @@ -1070,10 +1099,14 @@ void LoRaMac::OnTxDelayedTimerEvent( void ) /* In case of join request retransmissions, the stack must prepare * the frame again, because the network server keeps track of the random * LoRaMacDevNonce values to prevent reply attacks. */ - PrepareFrame( &macHdr, &fCtrl, 0, NULL, 0 ); + status = PrepareFrame( &macHdr, &fCtrl, 0, NULL, 0 ); } - ScheduleTx( ); + if (status == LORAWAN_STATUS_OK) { + ScheduleTx( ); + } else { + tr_error("Delayed TX: PrepareFrame returned error %d", status); + } } void LoRaMac::OnRxWindow1TimerEvent( void ) @@ -1186,7 +1219,6 @@ void LoRaMac::SetMlmeScheduleUplinkIndication( void ) lorawan_status_t LoRaMac::Send( loramac_mhdr_t *macHdr, uint8_t fPort, void *fBuffer, uint16_t fBufferSize ) { loramac_frame_ctrl_t fCtrl; - lorawan_status_t status = LORAWAN_STATUS_PARAMETER_INVALID; fCtrl.value = 0; fCtrl.bits.fopts_len = 0; @@ -1196,7 +1228,7 @@ lorawan_status_t LoRaMac::Send( loramac_mhdr_t *macHdr, uint8_t fPort, void *fBu fCtrl.bits.adr = _params.sys_params.adr_on; // Prepare the frame - status = PrepareFrame( macHdr, &fCtrl, fPort, fBuffer, fBufferSize ); + lorawan_status_t status = PrepareFrame( macHdr, &fCtrl, fPort, fBuffer, fBufferSize ); // Validate status if( status != LORAWAN_STATUS_OK ) diff --git a/features/lorawan/lorastack/mac/LoRaMac.h b/features/lorawan/lorastack/mac/LoRaMac.h index ee31fc36e5..00f4f44e28 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.h +++ b/features/lorawan/lorastack/mac/LoRaMac.h @@ -69,14 +69,11 @@ public: * * \details In addition to the initialization of the LoRaMAC layer, this * function initializes the callback primitives of the MCPS and - * MLME services. Every data field of \ref LoRaMacPrimitives_t must be + * MLME services. Every data field of \ref loramac_primitives_t must be * set to a valid callback function. * * \param primitives [in] - A pointer to the structure defining the LoRaMAC - * event functions. Refer to \ref LoRaMacPrimitives_t. - * - * \param callbacks [in] - A pointer to the structure defining the LoRaMAC - * callback functions. Refer to \ref LoRaMacCallback_t. + * event functions. Refer to \ref loramac_primitives_t. * * \param phy [in]- A pointer to the selected PHY layer. * @@ -85,7 +82,6 @@ public: * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: * \ref LORAWAN_STATUS_OK * \ref LORAWAN_STATUS_PARAMETER_INVALID - * \ref LORAWAN_STATUS_REGION_NOT_SUPPORTED. */ lorawan_status_t LoRaMacInitialization(loramac_primitives_t *primitives, LoRaPHY *phy, @@ -105,7 +101,7 @@ public: * account and reports when the frame can be sent. * * \param size [in]- The size of the applicable payload to be sent next. - * \param txInfo [out] - The structure \ref LoRaMacTxInfo_t contains + * \param txInfo [out] - The structure \ref loramac_tx_info_t contains * information on the actual maximum payload possible * (according to the configured datarate or the next * datarate according to ADR), and the maximum frame @@ -231,7 +227,7 @@ public: * } * \endcode * - * \param [in] mibGet - The MIB-GET request to perform. Refer to \ref MibRequestConfirm_t. + * \param [in] mibGet - The MIB-GET request to perform. Refer to \ref loramac_mib_req_confirm_t. * * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: * \ref LORAWAN_STATUS_OK @@ -260,7 +256,7 @@ public: * } * \endcode * - * \param [in] mibSet - The MIB-SET request to perform. Refer to \ref MibRequestConfirm_t. + * \param [in] mibSet - The MIB-SET request to perform. Refer to \ref loramac_mib_req_confirm_t. * * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: * \ref LORAWAN_STATUS_OK @@ -304,7 +300,7 @@ public: * } * \endcode * - * \param [in] mlmeRequest - The MLME request to perform. Refer to \ref MlmeReq_t. + * \param [in] mlmeRequest - The MLME request to perform. Refer to \ref loramac_mlme_req_t. * * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: * \ref LORAWAN_STATUS_OK @@ -339,7 +335,7 @@ public: * } * \endcode * - * \param [in] mcpsRequest - The MCPS request to perform. Refer to \ref McpsReq_t. + * \param [in] mcpsRequest - The MCPS request to perform. Refer to \ref loramac_mcps_req_t. * * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: * \ref LORAWAN_STATUS_OK @@ -369,10 +365,10 @@ public: /*! * \brief LoRaMAC layer generic send frame * - * \param [IN] macHdr MAC header field - * \param [IN] fPort MAC payload port - * \param [IN] fBuffer MAC data buffer to be sent - * \param [IN] fBufferSize MAC data buffer size + * \param [in] macHdr MAC header field + * \param [in] fPort MAC payload port + * \param [in] fBuffer MAC data buffer to be sent + * \param [in] fBufferSize MAC data buffer size * \retval status Status of the operation. */ lorawan_status_t Send( loramac_mhdr_t *macHdr, uint8_t fPort, void *fBuffer, uint16_t fBufferSize ); @@ -382,7 +378,7 @@ public: * * \remark Uses the radio parameters set on the previous transmission. * - * \param [IN] timeout Time in seconds while the radio is kept in continuous wave mode + * \param [in] timeout Time in seconds while the radio is kept in continuous wave mode * \retval status Status of the operation. */ lorawan_status_t SetTxContinuousWave( uint16_t timeout ); @@ -392,9 +388,9 @@ public: * * \remark Uses the radio parameters set on the previous transmission. * - * \param [IN] timeout Time in seconds while the radio is kept in continuous wave mode - * \param [IN] frequency RF frequency to be set. - * \param [IN] power RF output power to be set. + * \param [in] timeout Time in seconds while the radio is kept in continuous wave mode + * \param [in] frequency RF frequency to be set. + * \param [in] power RF output power to be set. * \retval status Status of the operation. */ lorawan_status_t SetTxContinuousWave1( uint16_t timeout, uint32_t frequency, uint8_t power ); @@ -549,8 +545,8 @@ private: /*! * \brief Initializes and opens the reception window * - * \param [IN] rxContinuous Set to true, if the RX is in continuous mode - * \param [IN] maxRxWindow Maximum RX window timeout + * \param [in] rxContinuous Set to true, if the RX is in continuous mode + * \param [in] maxRxWindow Maximum RX window timeout */ void RxWindowSetup( bool rxContinuous, uint32_t maxRxWindow ); @@ -575,12 +571,11 @@ private: /*! * \brief LoRaMAC layer frame buffer initialization * - * \param [IN] macHdr MAC header field - * \param [IN] fCtrl MAC frame control field - * \param [IN] fOpts MAC commands buffer - * \param [IN] fPort MAC payload port - * \param [IN] fBuffer MAC data buffer to be sent - * \param [IN] fBufferSize MAC data buffer size + * \param [in] macHdr MAC header field + * \param [in] fCtrl MAC frame control field + * \param [in] fPort MAC payload port + * \param [in] fBuffer MAC data buffer to be sent + * \param [in] fBufferSize MAC data buffer size * \retval status Status of the operation. */ lorawan_status_t PrepareFrame( loramac_mhdr_t *macHdr, loramac_frame_ctrl_t *fCtrl, uint8_t fPort, void *fBuffer, uint16_t fBufferSize ); @@ -595,7 +590,7 @@ private: /* * \brief Calculates the back-off time for the band of a channel. * - * \param [IN] channel The last Tx channel index + * \param [in] channel The last Tx channel index */ void CalculateBackOff( uint8_t channel ); @@ -605,7 +600,7 @@ private: * \remark PrepareFrame must be called at least once before calling this * function. * - * \param [IN] channel Channel to transmit on + * \param [in] channel Channel to transmit on * \retval status Status of the operation. */ lorawan_status_t SendFrameOnChannel( uint8_t channel ); @@ -613,7 +608,7 @@ private: /*! * \brief Resets MAC specific parameters to default * - * \param [IN] fPort The fPort + * \param [in] fPort The fPort * * \retval [false: fPort not allowed, true: fPort allowed] */ @@ -687,6 +682,11 @@ private: * LoRaMac upper layer event functions */ loramac_primitives_t *LoRaMacPrimitives; + + /** + * EventQueue object storage + */ + events::EventQueue *ev_queue; }; #endif // __LORAMAC_H__ diff --git a/features/lorawan/lorastack/mac/LoRaMacChannelPlan.h b/features/lorawan/lorastack/mac/LoRaMacChannelPlan.h index facce4abde..adf880de64 100644 --- a/features/lorawan/lorastack/mac/LoRaMacChannelPlan.h +++ b/features/lorawan/lorastack/mac/LoRaMacChannelPlan.h @@ -1,4 +1,5 @@ /** + \code / _____) _ | | ( (____ _____ ____ _| |_ _____ ____| |__ \____ \| ___ | (_ _) ___ |/ ___) _ \ @@ -10,6 +11,7 @@ \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| embedded.connectivity.solutions=============== +\endcode Description: LoRaWAN stack layer that controls both MAC and PHY underneath diff --git a/features/lorawan/lorastack/mac/LoRaMacCommand.cpp b/features/lorawan/lorastack/mac/LoRaMacCommand.cpp index 14c0fc7c57..18a19890b4 100644 --- a/features/lorawan/lorastack/mac/LoRaMacCommand.cpp +++ b/features/lorawan/lorastack/mac/LoRaMacCommand.cpp @@ -45,8 +45,9 @@ LoRaMacCommand::LoRaMacCommand(LoRaMac& lora_mac) MacCommandsInNextTx = false; MacCommandsBufferIndex = 0; MacCommandsBufferToRepeatIndex = 0; - //uint8_t MacCommandsBuffer[LORA_MAC_COMMAND_MAX_LENGTH]; - //uint8_t MacCommandsBufferToRepeat[LORA_MAC_COMMAND_MAX_LENGTH]; + + memset(MacCommandsBuffer, 0, sizeof(MacCommandsBuffer)); + memset(MacCommandsBufferToRepeat, 0, sizeof(MacCommandsBufferToRepeat)); } LoRaMacCommand::~LoRaMacCommand() @@ -251,13 +252,14 @@ bool LoRaMacCommand::IsMacCommandsInNextTx() const return MacCommandsInNextTx; } -void LoRaMacCommand::ProcessMacCommands(uint8_t *payload, uint8_t macIndex, - uint8_t commandsSize, uint8_t snr, - loramac_mlme_confirm_t& MlmeConfirm, - lora_mac_system_params_t &LoRaMacParams, - LoRaPHY &lora_phy) +lorawan_status_t LoRaMacCommand::ProcessMacCommands(uint8_t *payload, uint8_t macIndex, + uint8_t commandsSize, uint8_t snr, + loramac_mlme_confirm_t& MlmeConfirm, + lora_mac_system_params_t &LoRaMacParams, + LoRaPHY &lora_phy) { uint8_t status = 0; + lorawan_status_t ret_value = LORAWAN_STATUS_OK; while( macIndex < commandsSize ) { @@ -301,7 +303,7 @@ void LoRaMacCommand::ProcessMacCommands(uint8_t *payload, uint8_t macIndex, // Add the answers to the buffer for( uint8_t i = 0; i < ( linkAdrNbBytesParsed / 5 ); i++ ) { - AddMacCommand( MOTE_MAC_LINK_ADR_ANS, status, 0 ); + ret_value = AddMacCommand( MOTE_MAC_LINK_ADR_ANS, status, 0 ); } // Update MAC index macIndex += linkAdrNbBytesParsed - 1; @@ -310,12 +312,11 @@ void LoRaMacCommand::ProcessMacCommands(uint8_t *payload, uint8_t macIndex, case SRV_MAC_DUTY_CYCLE_REQ: LoRaMacParams.max_duty_cycle = payload[macIndex++]; LoRaMacParams.aggregated_duty_cycle = 1 << LoRaMacParams.max_duty_cycle; - AddMacCommand( MOTE_MAC_DUTY_CYCLE_ANS, 0, 0 ); + ret_value = AddMacCommand( MOTE_MAC_DUTY_CYCLE_ANS, 0, 0 ); break; case SRV_MAC_RX_PARAM_SETUP_REQ: { RxParamSetupReqParams_t rxParamSetupReq; - status = 0x07; rxParamSetupReq.DrOffset = ( payload[macIndex] >> 4 ) & 0x07; rxParamSetupReq.Datarate = payload[macIndex] & 0x0F; @@ -335,7 +336,7 @@ void LoRaMacCommand::ProcessMacCommands(uint8_t *payload, uint8_t macIndex, LoRaMacParams.rx2_channel.frequency = rxParamSetupReq.Frequency; LoRaMacParams.rx1_dr_offset = rxParamSetupReq.DrOffset; } - AddMacCommand( MOTE_MAC_RX_PARAM_SETUP_ANS, status, 0 ); + ret_value = AddMacCommand( MOTE_MAC_RX_PARAM_SETUP_ANS, status, 0 ); } break; case SRV_MAC_DEV_STATUS_REQ: @@ -343,14 +344,13 @@ void LoRaMacCommand::ProcessMacCommands(uint8_t *payload, uint8_t macIndex, uint8_t batteryLevel = BAT_LEVEL_NO_MEASURE; // we don't have a mechanism at the moment to measure // battery levels - AddMacCommand( MOTE_MAC_DEV_STATUS_ANS, batteryLevel, snr ); + ret_value = AddMacCommand( MOTE_MAC_DEV_STATUS_ANS, batteryLevel, snr ); break; } case SRV_MAC_NEW_CHANNEL_REQ: { NewChannelReqParams_t newChannelReq; channel_params_t chParam; - status = 0x03; newChannelReq.ChannelId = payload[macIndex++]; newChannelReq.NewChannel = &chParam; @@ -364,7 +364,7 @@ void LoRaMacCommand::ProcessMacCommands(uint8_t *payload, uint8_t macIndex, status = lora_phy.request_new_channel(&newChannelReq); - AddMacCommand( MOTE_MAC_NEW_CHANNEL_ANS, status, 0 ); + ret_value = AddMacCommand( MOTE_MAC_NEW_CHANNEL_ANS, status, 0 ); } break; case SRV_MAC_RX_TIMING_SETUP_REQ: @@ -377,7 +377,7 @@ void LoRaMacCommand::ProcessMacCommands(uint8_t *payload, uint8_t macIndex, } LoRaMacParams.recv_delay1 = delay * 1000; LoRaMacParams.recv_delay2 = LoRaMacParams.recv_delay1 + 1000; - AddMacCommand( MOTE_MAC_RX_TIMING_SETUP_ANS, 0, 0 ); + ret_value = AddMacCommand( MOTE_MAC_RX_TIMING_SETUP_ANS, 0, 0 ); } break; case SRV_MAC_TX_PARAM_SETUP_REQ: @@ -406,14 +406,13 @@ void LoRaMacCommand::ProcessMacCommands(uint8_t *payload, uint8_t macIndex, LoRaMacParams.downlink_dwell_time = txParamSetupReq.DownlinkDwellTime; LoRaMacParams.max_eirp = LoRaMacMaxEirpTable[txParamSetupReq.MaxEirp]; // Add command response - AddMacCommand( MOTE_MAC_TX_PARAM_SETUP_ANS, 0, 0 ); + ret_value = AddMacCommand( MOTE_MAC_TX_PARAM_SETUP_ANS, 0, 0 ); } } break; case SRV_MAC_DL_CHANNEL_REQ: { DlChannelReqParams_t dlChannelReq; - status = 0x03; dlChannelReq.ChannelId = payload[macIndex++]; dlChannelReq.Rx1Frequency = ( uint32_t )payload[macIndex++]; @@ -423,14 +422,15 @@ void LoRaMacCommand::ProcessMacCommands(uint8_t *payload, uint8_t macIndex, status = lora_phy.dl_channel_request(&dlChannelReq); - AddMacCommand( MOTE_MAC_DL_CHANNEL_ANS, status, 0 ); + ret_value = AddMacCommand( MOTE_MAC_DL_CHANNEL_ANS, status, 0 ); } break; default: // Unknown command. ABORT MAC commands processing - return; + ret_value = LORAWAN_STATUS_UNSUPPORTED; } } + return ret_value; } bool LoRaMacCommand::IsStickyMacCommandPending() diff --git a/features/lorawan/lorastack/mac/LoRaMacCommand.h b/features/lorawan/lorastack/mac/LoRaMacCommand.h index a6796e61a3..787df24e74 100644 --- a/features/lorawan/lorastack/mac/LoRaMacCommand.h +++ b/features/lorawan/lorastack/mac/LoRaMacCommand.h @@ -60,7 +60,7 @@ public: /*! * \brief Adds a new MAC command to be sent. * - * \Remark MAC layer internal function + * \remark MAC layer internal function * * \param [in] cmd MAC command to be added * [MOTE_MAC_LINK_CHECK_REQ, @@ -131,12 +131,14 @@ public: /*! * \brief Decodes MAC commands in the fOpts field and in the payload + + * \retval status Function status. LORAWAN_STATUS_OK if command successful. */ - void ProcessMacCommands(uint8_t *payload, uint8_t macIndex, - uint8_t commandsSize, uint8_t snr, - loramac_mlme_confirm_t& MlmeConfirm, - lora_mac_system_params_t& LoRaMacParams, - LoRaPHY& lora_phy); + lorawan_status_t ProcessMacCommands(uint8_t *payload, uint8_t macIndex, + uint8_t commandsSize, uint8_t snr, + loramac_mlme_confirm_t& MlmeConfirm, + lora_mac_system_params_t& LoRaMacParams, + LoRaPHY& lora_phy); /*! * \brief Verifies if sticky MAC commands are pending. diff --git a/features/lorawan/lorastack/mac/LoRaMacMcps.cpp b/features/lorawan/lorastack/mac/LoRaMacMcps.cpp index ab538df94d..96ee43ac15 100644 --- a/features/lorawan/lorastack/mac/LoRaMacMcps.cpp +++ b/features/lorawan/lorastack/mac/LoRaMacMcps.cpp @@ -121,7 +121,7 @@ lorawan_status_t LoRaMacMcps::set_request(loramac_mcps_req_t *mcpsRequest, // Apply the minimum possible datarate. // Some regions have limitations for the minimum datarate. - datarate = MAX(datarate, phyParam.Value); + datarate = MAX(datarate, (int8_t)phyParam.Value); if (readyToSend == true) { if (params->sys_params.adr_on == false) { diff --git a/features/lorawan/system/LoRaWANTimer.h b/features/lorawan/system/LoRaWANTimer.h index f909489d55..fef22e153b 100644 --- a/features/lorawan/system/LoRaWANTimer.h +++ b/features/lorawan/system/LoRaWANTimer.h @@ -70,7 +70,7 @@ public: * \brief Starts and adds the timer object to the list of timer events. * * \param [in] obj The structure containing the timer object parameters. - * \param [in] value The new timeout value. + * \param [in] timeout The new timeout value. */ void TimerStart( timer_event_t &obj, const uint32_t timeout ); diff --git a/features/lorawan/system/lorawan_data_structures.h b/features/lorawan/system/lorawan_data_structures.h index e6d4f9e907..01dee24dc6 100644 --- a/features/lorawan/system/lorawan_data_structures.h +++ b/features/lorawan/system/lorawan_data_structures.h @@ -705,9 +705,9 @@ typedef union { * * Primitive | Function * ---------------- | :---------------------: - * MCPS-Request | \ref LoRaMacMlmeRequest - * MCPS-Confirm | MacMcpsConfirm in \ref LoRaMacPrimitives_t - * MCPS-Indication | MacMcpsIndication in \ref LoRaMacPrimitives_t + * MCPS-Request | LoRaMacMlmeRequest + * MCPS-Confirm | MacMcpsConfirm in \ref loramac_primitives_t + * MCPS-Indication | MacMcpsIndication in \ref loramac_primitives_t */ typedef enum { /*! @@ -961,9 +961,9 @@ typedef struct { * * Primitive | Function * ---------------- | :---------------------: - * MLME-Request | \ref LoRaMacMlmeRequest - * MLME-Confirm | MacMlmeConfirm in \ref LoRaMacPrimitives_t - * MLME-Indication | MacMlmeIndication in \ref LoRaMacPrimitives_t + * MLME-Request | LoRaMacMlmeRequest + * MLME-Confirm | MacMlmeConfirm in \ref loramac_primitives_t + * MLME-Indication | MacMlmeIndication in \ref loramac_primitives_t */ typedef enum { /*! @@ -1151,8 +1151,8 @@ typedef struct { * * Primitive | Function * ---------------- | :---------------------: - * MIB-Set | \ref LoRaMacMibSetRequestConfirm - * MIB-Get | \ref LoRaMacMibGetRequestConfirm + * MIB-Set | LoRaMacMibSetRequestConfirm + * MIB-Get | LoRaMacMibGetRequestConfirm */ typedef enum { /*! diff --git a/features/netsocket/LoRaWANBase.h b/features/netsocket/LoRaWANBase.h index 4796424f08..f4b3354f5b 100644 --- a/features/netsocket/LoRaWANBase.h +++ b/features/netsocket/LoRaWANBase.h @@ -84,7 +84,6 @@ public: * transmission, until/unless application explicitly turns it off using * remove_link_check_request() API. * - * @param cb A callback function to receive link check response * @return LORAWAN_STATUS_OK on successfully queuing a request, or * a negative error code on failure. * From 4432ad9ae7a1b1d5516d72a56db54e615ce7b53f Mon Sep 17 00:00:00 2001 From: Hasnain Virk Date: Tue, 16 Jan 2018 16:58:18 +0200 Subject: [PATCH 18/23] Major PHY layer modifications The PHY layer had a lot of duplicated code in various geographic regions. In this commit we have tried to concentrate all common functionaliy into one single class which LoRaPHY that provides three kind of methods: i) Non virtual base methods which are there for upper layer use, e.g., providing access to driver or generic PHY layer functionality which needs to be exposed to upper layers. ii) Virtual methods (no hard limit on implementation) that can be overriden in derived classes. Some PHY implementations will need that as they may come with very peculiar channel schemes, e.g., dynamic channel schemes in US bands. iii) Protected methods which are only available for the derived PHYs We have adopted a mechanism for the dervied PHYs to announce their differenmtiating parameters in their constructors by filling up a data structure known as lora_phy_params_t which exists at base level. Access modifier for this data structure is protected so it can only be used by the base or derived classes, i.e., no exposure to upper layers. For extra functionality and differentiating controls, a derived PHY can override any virual method as necessary. In addition to that we have adopted the Mbed-OS style guide and have changed data structures and code to reflect that. Some data structures are removed. * Algorithm to get alternate DR is modified. Current scheme, works as multiples of 6 as EU and EU like PHYs provide 6 datarates. We make sure that we try a datarate at least once. If nuber of join retries is a multiple of 6, we may try multiple times on each data rate. * Most of the PHYs with dynamic channel plans, always override the above mentioned algorithm as the rules governing this algorithm do not hild in their case. * band_t data structure is enhanced with lower band frequency and higher band frequency. That enables us to validate frequency based upon the band and hence we can have a single function for all PHYs to validate frequency. * In some PHYs, there were some extra channel masks were defined which were not being used. Hence removed. * EIRP table corrected in some PHYs based upon spec. * PHY functions in response to Mac commands are renamed to reflect what they exactly do. for example accept_rx_param_setup_req() because that's what they do. they can either accept the mac command or reject it.# Please enter the commit message for your changes. --- features/lorawan/LoRaWANStack.cpp | 49 +- features/lorawan/lorastack/mac/LoRaMac.cpp | 316 ++-- features/lorawan/lorastack/mac/LoRaMac.h | 1 - .../lorastack/mac/LoRaMacChannelPlan.cpp | 74 +- .../lorawan/lorastack/mac/LoRaMacCommand.cpp | 76 +- .../lorawan/lorastack/mac/LoRaMacMcps.cpp | 20 +- features/lorawan/lorastack/mac/LoRaMacMib.cpp | 93 +- .../lorawan/lorastack/mac/LoRaMacMlme.cpp | 20 +- features/lorawan/lorastack/phy/LoRaPHY.cpp | 1390 ++++++++++++++--- features/lorawan/lorastack/phy/LoRaPHY.h | 724 ++++----- .../lorawan/lorastack/phy/LoRaPHYAS923.cpp | 1200 ++------------ features/lorawan/lorastack/phy/LoRaPHYAS923.h | 306 +--- .../lorawan/lorastack/phy/LoRaPHYAU915.cpp | 863 +++------- features/lorawan/lorastack/phy/LoRaPHYAU915.h | 300 +--- .../lorawan/lorastack/phy/LoRaPHYCN470.cpp | 910 +++-------- features/lorawan/lorastack/phy/LoRaPHYCN470.h | 294 +--- .../lorawan/lorastack/phy/LoRaPHYCN779.cpp | 1101 ++----------- features/lorawan/lorastack/phy/LoRaPHYCN779.h | 289 +--- .../lorawan/lorastack/phy/LoRaPHYEU433.cpp | 1106 ++----------- features/lorawan/lorastack/phy/LoRaPHYEU433.h | 289 +--- .../lorawan/lorastack/phy/LoRaPHYEU868.cpp | 1159 ++------------ features/lorawan/lorastack/phy/LoRaPHYEU868.h | 296 +--- .../lorawan/lorastack/phy/LoRaPHYIN865.cpp | 1100 ++----------- features/lorawan/lorastack/phy/LoRaPHYIN865.h | 288 +--- .../lorawan/lorastack/phy/LoRaPHYKR920.cpp | 1130 +++----------- features/lorawan/lorastack/phy/LoRaPHYKR920.h | 299 +--- .../lorawan/lorastack/phy/LoRaPHYUS915.cpp | 982 ++++-------- features/lorawan/lorastack/phy/LoRaPHYUS915.h | 301 +--- .../lorastack/phy/LoRaPHYUS915Hybrid.cpp | 1159 +++++--------- .../lorastack/phy/LoRaPHYUS915Hybrid.h | 303 +--- features/lorawan/lorastack/phy/lora_phy_ds.h | 591 +++---- features/lorawan/mbed_lib.json | 4 +- .../lorawan/system/lorawan_data_structures.h | 10 +- 33 files changed, 4116 insertions(+), 12927 deletions(-) diff --git a/features/lorawan/LoRaWANStack.cpp b/features/lorawan/LoRaWANStack.cpp index f913b7499c..4ced8af0c3 100644 --- a/features/lorawan/LoRaWANStack.cpp +++ b/features/lorawan/LoRaWANStack.cpp @@ -224,9 +224,9 @@ lorawan_status_t LoRaWANStack::send_compliance_test_frame_to_mac() { loramac_mcps_req_t mcps_req; - GetPhyParams_t phy_params; - PhyParam_t default_datarate; - phy_params.Attribute = PHY_DEF_TX_DR; + get_phy_params_t phy_params; + phy_param_t default_datarate; + phy_params.attribute = PHY_DEF_TX_DR; default_datarate = _lora_phy.get_phy_params(&phy_params); prepare_special_tx_frame(_compliance_test.app_port); @@ -236,7 +236,7 @@ lorawan_status_t LoRaWANStack::send_compliance_test_frame_to_mac() mcps_req.req.unconfirmed.fport = _compliance_test.app_port; mcps_req.f_buffer = _tx_msg.f_buffer; mcps_req.f_buffer_size = _tx_msg.f_buffer_size; - mcps_req.req.unconfirmed.data_rate = default_datarate.Value; + mcps_req.req.unconfirmed.data_rate = default_datarate.value; tr_info("Transmit unconfirmed compliance test frame %d bytes.", mcps_req.f_buffer_size); @@ -249,7 +249,7 @@ lorawan_status_t LoRaWANStack::send_compliance_test_frame_to_mac() mcps_req.f_buffer = _tx_msg.f_buffer; mcps_req.f_buffer_size = _tx_msg.f_buffer_size; mcps_req.req.confirmed.nb_trials = _num_retry; - mcps_req.req.confirmed.data_rate = default_datarate.Value; + mcps_req.req.confirmed.data_rate = default_datarate.value; tr_info("Transmit confirmed compliance test frame %d bytes.", mcps_req.f_buffer_size); @@ -286,9 +286,9 @@ lorawan_status_t LoRaWANStack::send_frame_to_mac() lorawan_status_t status; loramac_mib_req_confirm_t mib_get_params; - GetPhyParams_t phy_params; - PhyParam_t default_datarate; - phy_params.Attribute = PHY_DEF_TX_DR; + get_phy_params_t phy_params; + phy_param_t default_datarate; + phy_params.attribute = PHY_DEF_TX_DR; default_datarate = _lora_phy.get_phy_params(&phy_params); mcps_req.type = _tx_msg.type; @@ -302,7 +302,7 @@ lorawan_status_t LoRaWANStack::send_frame_to_mac() mib_get_params.type = MIB_CHANNELS_DATARATE; if(mib_get_request(&mib_get_params) != LORAWAN_STATUS_OK) { tr_debug("Couldn't get MIB parameters: Using default data rate"); - mcps_req.req.unconfirmed.data_rate = default_datarate.Value; + mcps_req.req.unconfirmed.data_rate = default_datarate.value; } else { mcps_req.req.unconfirmed.data_rate = mib_get_params.param.channel_data_rate; } @@ -316,7 +316,7 @@ lorawan_status_t LoRaWANStack::send_frame_to_mac() mib_get_params.type = MIB_CHANNELS_DATARATE; if(mib_get_request(&mib_get_params) != LORAWAN_STATUS_OK) { tr_debug("Couldn't get MIB parameters: Using default data rate"); - mcps_req.req.confirmed.data_rate = default_datarate.Value; + mcps_req.req.confirmed.data_rate = default_datarate.value; } else { mcps_req.req.confirmed.data_rate = mib_get_params.param.channel_data_rate; } @@ -328,7 +328,7 @@ lorawan_status_t LoRaWANStack::send_frame_to_mac() mib_get_params.type = MIB_CHANNELS_DATARATE; if(mib_get_request(&mib_get_params) != LORAWAN_STATUS_OK) { tr_debug("Couldn't get MIB parameters: Using default data rate"); - mcps_req.req.proprietary.data_rate = default_datarate.Value; + mcps_req.req.proprietary.data_rate = default_datarate.value; } else { mcps_req.req.proprietary.data_rate = mib_get_params.param.channel_data_rate; } @@ -977,32 +977,21 @@ void LoRaWANStack::mcps_indication_handler(loramac_mcps_indication_t *mcps_indic break; default: if (is_port_valid(mcps_indication->port) == true || - mcps_indication->type == MCPS_PROPRIETARY) { + mcps_indication->type == MCPS_PROPRIETARY) { // Valid message arrived. - // Save message to buffer with session information. - if (_rx_msg.msg.mcps_indication.buffer_size > LORAMAC_PHY_MAXPAYLOAD) { - // This may never happen as both radio and MAC are limited - // to the size 255 bytes - tr_debug("Cannot receive more than buffer capacity!"); - if (_callbacks.events) { - const int ret = _queue->call(_callbacks.events, RX_ERROR); - MBED_ASSERT(ret != 0); - (void)ret; - } - return; - } else { - _rx_msg.type = LORAMAC_RX_MCPS_INDICATION; - _rx_msg.msg.mcps_indication.buffer_size = mcps_indication->buffer_size; - _rx_msg.msg.mcps_indication.port = mcps_indication->port; + _rx_msg.type = LORAMAC_RX_MCPS_INDICATION; + _rx_msg.msg.mcps_indication.buffer_size = mcps_indication->buffer_size; + _rx_msg.msg.mcps_indication.port = mcps_indication->port; - // no copy, just set the pointer for the user - _rx_msg.msg.mcps_indication.buffer = mcps_indication->buffer; - } + // no copy, just set the pointer for the user + _rx_msg.msg.mcps_indication.buffer = + mcps_indication->buffer; // Notify application about received frame.. tr_debug("Received %d bytes", _rx_msg.msg.mcps_indication.buffer_size); _rx_msg.receive_ready = true; + if (_callbacks.events) { const int ret = _queue->call(_callbacks.events, RX_DONE); MBED_ASSERT(ret != 0); diff --git a/features/lorawan/lorastack/mac/LoRaMac.cpp b/features/lorawan/lorastack/mac/LoRaMac.cpp index 211c5b53da..6c3fca6217 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.cpp +++ b/features/lorawan/lorastack/mac/LoRaMac.cpp @@ -117,6 +117,7 @@ LoRaMac::LoRaMac(LoRaWANTimeHandler &lora_time) _params.sys_params.max_duty_cycle = 0; LoRaMacPrimitives = NULL; + ev_queue = NULL; } LoRaMac::~LoRaMac() @@ -218,9 +219,9 @@ void LoRaMac::handle_rx2_timer_event(void) **************************************************************************/ void LoRaMac::OnRadioTxDone( void ) { - GetPhyParams_t getPhy; - PhyParam_t phyParam; - SetBandTxDoneParams_t txDone; + get_phy_params_t getPhy; + phy_param_t phyParam; + set_band_txdone_params_t txDone; lorawan_time_t curTime = _lora_time.TimerGetCurrentTime( ); loramac_mlme_confirm_t mlme_confirm = mlme.get_confirmation(); @@ -243,9 +244,9 @@ void LoRaMac::OnRadioTxDone( void ) } if( ( _params.dev_class == CLASS_C ) || ( _params.is_node_ack_requested == true ) ) { - getPhy.Attribute = PHY_ACK_TIMEOUT; + getPhy.attribute = PHY_ACK_TIMEOUT; phyParam = lora_phy->get_phy_params(&getPhy); - _lora_time.TimerStart( _params.timers.ack_timeout_timer, _params.rx_window2_delay + phyParam.Value ); + _lora_time.TimerStart( _params.timers.ack_timeout_timer, _params.rx_window2_delay + phyParam.value ); } } else @@ -273,10 +274,10 @@ void LoRaMac::OnRadioTxDone( void ) // Store last Tx channel _params.last_channel_idx = _params.channel; // Update last tx done time for the current channel - txDone.Channel = _params.channel; - txDone.Joined = _params.is_nwk_joined; - txDone.LastTxDoneTime = curTime; - lora_phy->set_band_tx_done(&txDone); + txDone.channel = _params.channel; + txDone.joined = _params.is_nwk_joined; + txDone.last_tx_done_time = curTime; + lora_phy->set_last_tx_done(&txDone); // Update Aggregated last tx done time _params.timers.aggregated_last_tx_time = curTime; @@ -307,9 +308,9 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 { loramac_mhdr_t macHdr; loramac_frame_ctrl_t fCtrl; - ApplyCFListParams_t applyCFList; - GetPhyParams_t getPhy; - PhyParam_t phyParam; + cflist_params_t applyCFList; + get_phy_params_t getPhy; + phy_param_t phyParam; bool skipIndication = false; uint8_t pktHeaderLen = 0; @@ -416,9 +417,9 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 _params.sys_params.recv_delay2 = _params.sys_params.recv_delay1 + 1000; // Apply CF list - applyCFList.Payload = &_params.payload[13]; + applyCFList.payload = &_params.payload[13]; // Size of the regular payload is 12. Plus 1 byte MHDR and 4 bytes MIC - applyCFList.Size = size - 17; + applyCFList.size = size - 17; lora_phy->apply_cf_list(&applyCFList); @@ -434,17 +435,16 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 case FRAME_TYPE_DATA_UNCONFIRMED_DOWN: { // Check if the received payload size is valid - getPhy.UplinkDwellTime = _params.sys_params.downlink_dwell_time; - getPhy.Datarate = mcps.get_indication().rx_datarate; - getPhy.Attribute = PHY_MAX_PAYLOAD; + getPhy.datarate = mcps.get_indication().rx_datarate; + getPhy.attribute = PHY_MAX_PAYLOAD; // Get the maximum payload length if( _params.is_repeater_supported == true ) { - getPhy.Attribute = PHY_MAX_PAYLOAD_REPEATER; + getPhy.attribute = PHY_MAX_PAYLOAD_REPEATER; } phyParam = lora_phy->get_phy_params(&getPhy); - if( MAX( 0, ( int16_t )( ( int16_t )size - ( int16_t )LORA_MAC_FRMPAYLOAD_OVERHEAD ) ) > (int32_t)phyParam.Value ) + if( MAX( 0, ( int16_t )( ( int16_t )size - ( int16_t )LORA_MAC_FRMPAYLOAD_OVERHEAD ) ) > (int32_t)phyParam.value ) { mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_ERROR; PrepareRxDoneAbort( ); @@ -524,9 +524,9 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 } // Check for a the maximum allowed counter difference - getPhy.Attribute = PHY_MAX_FCNT_GAP; + getPhy.attribute = PHY_MAX_FCNT_GAP; phyParam = lora_phy->get_phy_params( &getPhy ); - if( sequenceCounterDiff >= phyParam.Value ) + if( sequenceCounterDiff >= phyParam.value ) { mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_TOO_MANY_FRAMES_LOSS; mcps.get_indication().dl_frame_counter = downLinkCounter; @@ -856,8 +856,8 @@ void LoRaMac::OnRadioRxTimeout( void ) **************************************************************************/ void LoRaMac::OnMacStateCheckTimerEvent( void ) { - GetPhyParams_t getPhy; - PhyParam_t phyParam; + get_phy_params_t getPhy; + phy_param_t phyParam; bool txTimeout = false; _lora_time.TimerStop( _params.timers.mac_state_check_timer ); @@ -970,11 +970,10 @@ void LoRaMac::OnMacStateCheckTimerEvent( void ) if( ( _params.ack_timeout_retry_counter % 2 ) == 1 ) { - getPhy.Attribute = PHY_NEXT_LOWER_TX_DR; - getPhy.UplinkDwellTime = _params.sys_params.uplink_dwell_time; - getPhy.Datarate = _params.sys_params.channel_data_rate; + getPhy.attribute = PHY_NEXT_LOWER_TX_DR; + getPhy.datarate = _params.sys_params.channel_data_rate; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.channel_data_rate = phyParam.Value; + _params.sys_params.channel_data_rate = phyParam.value; } // Try to send the frame again if( ScheduleTx( ) == LORAWAN_STATUS_OK ) @@ -1000,7 +999,7 @@ void LoRaMac::OnMacStateCheckTimerEvent( void ) } else { - lora_phy->load_defaults(INIT_TYPE_RESTORE); + lora_phy->restore_default_channels(); _params.mac_state &= ~LORAMAC_TX_RUNNING; @@ -1076,7 +1075,6 @@ void LoRaMac::OnTxDelayedTimerEvent( void ) { loramac_mhdr_t macHdr; loramac_frame_ctrl_t fCtrl; - AlternateDrParams_t altDr; lorawan_status_t status = LORAWAN_STATUS_OK; @@ -1087,8 +1085,7 @@ void LoRaMac::OnTxDelayedTimerEvent( void ) { ResetMacParameters( ); - altDr.NbTrials = _params.join_request_trial_counter + 1; - _params.sys_params.channel_data_rate = lora_phy->get_alternate_DR(&altDr); + _params.sys_params.channel_data_rate = lora_phy->get_alternate_DR(_params.join_request_trial_counter + 1); macHdr.value = 0; macHdr.bits.mtype = FRAME_TYPE_JOIN_REQ; @@ -1179,23 +1176,22 @@ void LoRaMac::RxWindowSetup( bool rxContinuous, uint32_t maxRxWindow ) bool LoRaMac::ValidatePayloadLength( uint8_t lenN, int8_t datarate, uint8_t fOptsLen ) { - GetPhyParams_t getPhy; - PhyParam_t phyParam; + get_phy_params_t getPhy; + phy_param_t phyParam; uint16_t maxN = 0; uint16_t payloadSize = 0; // Setup PHY request - getPhy.UplinkDwellTime = _params.sys_params.uplink_dwell_time; - getPhy.Datarate = datarate; - getPhy.Attribute = PHY_MAX_PAYLOAD; + getPhy.datarate = datarate; + getPhy.attribute = PHY_MAX_PAYLOAD; // Get the maximum payload length if( _params.is_repeater_supported == true ) { - getPhy.Attribute = PHY_MAX_PAYLOAD_REPEATER; + getPhy.attribute = PHY_MAX_PAYLOAD_REPEATER; } phyParam = lora_phy->get_phy_params(&getPhy); - maxN = phyParam.Value; + maxN = phyParam.value; // Calculate the resulting payload size payloadSize = ( lenN + fOptsLen ); @@ -1249,9 +1245,9 @@ lorawan_status_t LoRaMac::Send( loramac_mhdr_t *macHdr, uint8_t fPort, void *fBu lorawan_status_t LoRaMac::ScheduleTx( void ) { lorawan_time_t dutyCycleTimeOff = 0; - NextChanParams_t nextChan; - GetPhyParams_t getPhy; - PhyParam_t phyParam; + channel_selection_params_t nextChan; + get_phy_params_t getPhy; + phy_param_t phyParam; // Check if the device is off if( _params.sys_params.max_duty_cycle == 255 ) @@ -1266,31 +1262,30 @@ lorawan_status_t LoRaMac::ScheduleTx( void ) // Update Backoff CalculateBackOff( _params.last_channel_idx ); - nextChan.AggrTimeOff = _params.timers.aggregated_timeoff; - nextChan.Datarate = _params.sys_params.channel_data_rate; + nextChan.aggregate_timeoff = _params.timers.aggregated_timeoff; + nextChan.current_datarate = _params.sys_params.channel_data_rate; _params.is_dutycycle_on = MBED_CONF_LORA_DUTY_CYCLE_ON; - nextChan.DutyCycleEnabled = _params.is_dutycycle_on; - nextChan.Joined = _params.is_nwk_joined; - nextChan.LastAggrTx = _params.timers.aggregated_last_tx_time; + nextChan.dc_enabled = _params.is_dutycycle_on; + nextChan.joined = _params.is_nwk_joined; + nextChan.last_aggregate_tx_time = _params.timers.aggregated_last_tx_time; // Select channel while( lora_phy->set_next_channel(&nextChan, &_params.channel, &dutyCycleTimeOff, &_params.timers.aggregated_timeoff ) == false ) { // Set the default datarate - getPhy.Attribute = PHY_DEF_TX_DR; + getPhy.attribute = PHY_DEF_TX_DR; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.channel_data_rate = phyParam.Value; + _params.sys_params.channel_data_rate = phyParam.value; // Update datarate in the function parameters - nextChan.Datarate = _params.sys_params.channel_data_rate; + nextChan.current_datarate = _params.sys_params.channel_data_rate; } - tr_debug("Next Channel Idx=%d, DR=%d", _params.channel, nextChan.Datarate); + tr_debug("Next Channel Idx=%d, DR=%d", _params.channel, nextChan.current_datarate); // Compute Rx1 windows parameters - uint8_t dr_offset = lora_phy->apply_DR_offset(_params.sys_params.downlink_dwell_time, - _params.sys_params.channel_data_rate, - _params.sys_params.rx1_dr_offset); + uint8_t dr_offset = lora_phy->apply_DR_offset(_params.sys_params.channel_data_rate, + _params.sys_params.rx1_dr_offset); lora_phy->compute_rx_win_params(dr_offset, _params.sys_params.min_rx_symb, _params.sys_params.max_sys_rx_error, @@ -1338,15 +1333,15 @@ lorawan_status_t LoRaMac::ScheduleTx( void ) void LoRaMac::CalculateBackOff( uint8_t channel ) { - CalcBackOffParams_t calcBackOff; + backoff_params_t calcBackOff; - calcBackOff.Joined = _params.is_nwk_joined; + calcBackOff.joined = _params.is_nwk_joined; _params.is_dutycycle_on = MBED_CONF_LORA_DUTY_CYCLE_ON; - calcBackOff.DutyCycleEnabled = _params.is_dutycycle_on; - calcBackOff.Channel = channel; - calcBackOff.ElapsedTime = _lora_time.TimerGetElapsedTime( _params.timers.mac_init_time ); - calcBackOff.TxTimeOnAir = _params.timers.tx_toa; - calcBackOff.LastTxIsJoinRequest = _params.is_last_tx_join_request; + calcBackOff.dc_enabled = _params.is_dutycycle_on; + calcBackOff.channel = channel; + calcBackOff.elapsed_time = _lora_time.TimerGetElapsedTime( _params.timers.mac_init_time ); + calcBackOff.tx_toa = _params.timers.tx_toa; + calcBackOff.last_tx_was_join_req = _params.is_last_tx_join_request; // Update regional back-off lora_phy->calculate_backoff(&calcBackOff); @@ -1358,8 +1353,8 @@ void LoRaMac::CalculateBackOff( uint8_t channel ) void LoRaMac::ResetMacParameters( void ) { - GetPhyParams_t getPhy; - PhyParam_t phyParam; + get_phy_params_t getPhy; + phy_param_t phyParam; _params.is_nwk_joined = false; @@ -1383,37 +1378,37 @@ void LoRaMac::ResetMacParameters( void ) _params.is_rx_window_enabled = true; - getPhy.Attribute = PHY_DEF_TX_POWER; + getPhy.attribute = PHY_DEF_TX_POWER; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.channel_tx_power = phyParam.Value; + _params.sys_params.channel_tx_power = phyParam.value; - getPhy.Attribute = PHY_DEF_TX_DR; + getPhy.attribute = PHY_DEF_TX_DR; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.channel_data_rate = phyParam.Value; + _params.sys_params.channel_data_rate = phyParam.value; - getPhy.Attribute = PHY_DEF_DR1_OFFSET; + getPhy.attribute = PHY_DEF_DR1_OFFSET; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.rx1_dr_offset = phyParam.Value; + _params.sys_params.rx1_dr_offset = phyParam.value; - getPhy.Attribute = PHY_DEF_RX2_FREQUENCY; + getPhy.attribute = PHY_DEF_RX2_FREQUENCY; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.rx2_channel.frequency = phyParam.Value; - getPhy.Attribute = PHY_DEF_RX2_DR; + _params.sys_params.rx2_channel.frequency = phyParam.value; + getPhy.attribute = PHY_DEF_RX2_DR; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.rx2_channel.datarate = phyParam.Value; + _params.sys_params.rx2_channel.datarate = phyParam.value; - getPhy.Attribute = PHY_DEF_UPLINK_DWELL_TIME; + getPhy.attribute = PHY_DEF_UPLINK_DWELL_TIME; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.uplink_dwell_time = phyParam.Value; + _params.sys_params.uplink_dwell_time = phyParam.value; - getPhy.Attribute = PHY_DEF_MAX_EIRP; + getPhy.attribute = PHY_DEF_MAX_EIRP; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.max_eirp = phyParam.Value; + _params.sys_params.max_eirp = phyParam.value; - getPhy.Attribute = PHY_DEF_ANTENNA_GAIN; + getPhy.attribute = PHY_DEF_ANTENNA_GAIN; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.antenna_gain = phyParam.Value; + _params.sys_params.antenna_gain = phyParam.value; _params.is_node_ack_requested = false; _params.is_srv_ack_requested = false; @@ -1457,7 +1452,6 @@ static void memcpy_convert_endianess( uint8_t *dst, const uint8_t *src, uint16_t lorawan_status_t LoRaMac::PrepareFrame( loramac_mhdr_t *macHdr, loramac_frame_ctrl_t *fCtrl, uint8_t fPort, void *fBuffer, uint16_t fBufferSize ) { - AdrNextParams_t adrNext; uint16_t i; uint8_t pktHeaderLen = 0; uint32_t mic = 0; @@ -1517,18 +1511,14 @@ lorawan_status_t LoRaMac::PrepareFrame( loramac_mhdr_t *macHdr, loramac_frame_ct return LORAWAN_STATUS_NO_NETWORK_JOINED; // No network has been joined yet } - // Adr next request - adrNext.UpdateChanMask = true; - adrNext.AdrEnabled = fCtrl->bits.adr; - adrNext.AdrAckCounter = _params.adr_ack_counter; - adrNext.Datarate = _params.sys_params.channel_data_rate; - adrNext.TxPower = _params.sys_params.channel_tx_power; - adrNext.UplinkDwellTime = _params.sys_params.uplink_dwell_time; - - fCtrl->bits.adr_ack_req = lora_phy->get_next_ADR(&adrNext, - &_params.sys_params.channel_data_rate, - &_params.sys_params.channel_tx_power, - &_params.adr_ack_counter); + if (_params.sys_params.adr_on) { + if (lora_phy->get_next_ADR(true, + _params.sys_params.channel_data_rate, + _params.sys_params.channel_tx_power, + _params.adr_ack_counter)) { + fCtrl->bits.adr_ack_req = 1; + } + } if( _params.is_srv_ack_requested == true ) { @@ -1655,17 +1645,17 @@ lorawan_status_t LoRaMac::PrepareFrame( loramac_mhdr_t *macHdr, loramac_frame_ct lorawan_status_t LoRaMac::SendFrameOnChannel( uint8_t channel ) { - TxConfigParams_t txConfig; + tx_config_params_t tx_config; int8_t txPower = 0; - txConfig.Channel = channel; - txConfig.Datarate = _params.sys_params.channel_data_rate; - txConfig.TxPower = _params.sys_params.channel_tx_power; - txConfig.MaxEirp = _params.sys_params.max_eirp; - txConfig.AntennaGain = _params.sys_params.antenna_gain; - txConfig.PktLen = _params.buffer_pkt_len; + tx_config.channel = channel; + tx_config.datarate = _params.sys_params.channel_data_rate; + tx_config.tx_power = _params.sys_params.channel_tx_power; + tx_config.max_eirp = _params.sys_params.max_eirp; + tx_config.antenna_gain = _params.sys_params.antenna_gain; + tx_config.pkt_len = _params.buffer_pkt_len; - lora_phy->tx_config(&txConfig, &txPower, &_params.timers.tx_toa); + lora_phy->tx_config(&tx_config, &txPower, &_params.timers.tx_toa); mlme.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_ERROR; @@ -1695,14 +1685,14 @@ lorawan_status_t LoRaMac::SendFrameOnChannel( uint8_t channel ) lorawan_status_t LoRaMac::SetTxContinuousWave( uint16_t timeout ) { - ContinuousWaveParams_t continuousWave; + cw_mode_params_t continuousWave; - continuousWave.Channel = _params.channel; - continuousWave.Datarate = _params.sys_params.channel_data_rate; - continuousWave.TxPower = _params.sys_params.channel_tx_power; - continuousWave.MaxEirp = _params.sys_params.max_eirp; - continuousWave.AntennaGain = _params.sys_params.antenna_gain; - continuousWave.Timeout = timeout; + continuousWave.channel = _params.channel; + continuousWave.datarate = _params.sys_params.channel_data_rate; + continuousWave.tx_power = _params.sys_params.channel_tx_power; + continuousWave.max_eirp = _params.sys_params.max_eirp; + continuousWave.antenna_gain = _params.sys_params.antenna_gain; + continuousWave.timeout = timeout; lora_phy->set_tx_cont_mode(&continuousWave); @@ -1716,7 +1706,16 @@ lorawan_status_t LoRaMac::SetTxContinuousWave( uint16_t timeout ) lorawan_status_t LoRaMac::SetTxContinuousWave1( uint16_t timeout, uint32_t frequency, uint8_t power ) { - lora_phy->setup_tx_cont_wave_mode(frequency, power, timeout); + cw_mode_params_t continuousWave; + + continuousWave.channel = 0; + continuousWave.datarate = 0; + continuousWave.tx_power = power; + continuousWave.max_eirp = 0; + continuousWave.antenna_gain = 0; + continuousWave.timeout = timeout; + + lora_phy->set_tx_cont_mode(&continuousWave); // Starts the MAC layer status check timer _lora_time.TimerStart( _params.timers.mac_state_check_timer, MAC_STATE_CHECK_TIMEOUT ); @@ -1730,8 +1729,8 @@ lorawan_status_t LoRaMac::LoRaMacInitialization(loramac_primitives_t *primitives LoRaPHY *phy, EventQueue *queue) { - GetPhyParams_t getPhy; - PhyParam_t phyParam; + get_phy_params_t getPhy; + phy_param_t phyParam; //store event queue pointer ev_queue = queue; @@ -1771,68 +1770,66 @@ lorawan_status_t LoRaMac::LoRaMacInitialization(loramac_primitives_t *primitives _params.timers.aggregated_timeoff = 0; // Reset to defaults - getPhy.Attribute = PHY_DUTY_CYCLE; + getPhy.attribute = PHY_DUTY_CYCLE; phyParam = lora_phy->get_phy_params(&getPhy); // load default at this moment. Later can be changed using json - _params.is_dutycycle_on = ( bool ) phyParam.Value; + _params.is_dutycycle_on = ( bool ) phyParam.value; - getPhy.Attribute = PHY_DEF_TX_POWER; + getPhy.attribute = PHY_DEF_TX_POWER; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.channel_tx_power = phyParam.Value; + _params.sys_params.channel_tx_power = phyParam.value; - getPhy.Attribute = PHY_DEF_TX_DR; + getPhy.attribute = PHY_DEF_TX_DR; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.channel_data_rate = phyParam.Value; + _params.sys_params.channel_data_rate = phyParam.value; - getPhy.Attribute = PHY_MAX_RX_WINDOW; + getPhy.attribute = PHY_MAX_RX_WINDOW; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.max_rx_win_time = phyParam.Value; + _params.sys_params.max_rx_win_time = phyParam.value; - getPhy.Attribute = PHY_RECEIVE_DELAY1; + getPhy.attribute = PHY_RECEIVE_DELAY1; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.recv_delay1 = phyParam.Value; + _params.sys_params.recv_delay1 = phyParam.value; - getPhy.Attribute = PHY_RECEIVE_DELAY2; + getPhy.attribute = PHY_RECEIVE_DELAY2; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.recv_delay2 = phyParam.Value; + _params.sys_params.recv_delay2 = phyParam.value; - getPhy.Attribute = PHY_JOIN_ACCEPT_DELAY1; + getPhy.attribute = PHY_JOIN_ACCEPT_DELAY1; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.join_accept_delay1 = phyParam.Value; + _params.sys_params.join_accept_delay1 = phyParam.value; - getPhy.Attribute = PHY_JOIN_ACCEPT_DELAY2; + getPhy.attribute = PHY_JOIN_ACCEPT_DELAY2; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.join_accept_delay2 = phyParam.Value; + _params.sys_params.join_accept_delay2 = phyParam.value; - getPhy.Attribute = PHY_DEF_DR1_OFFSET; + getPhy.attribute = PHY_DEF_DR1_OFFSET; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.rx1_dr_offset = phyParam.Value; + _params.sys_params.rx1_dr_offset = phyParam.value; - getPhy.Attribute = PHY_DEF_RX2_FREQUENCY; + getPhy.attribute = PHY_DEF_RX2_FREQUENCY; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.rx2_channel.frequency = phyParam.Value; + _params.sys_params.rx2_channel.frequency = phyParam.value; - getPhy.Attribute = PHY_DEF_RX2_DR; + getPhy.attribute = PHY_DEF_RX2_DR; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.rx2_channel.datarate = phyParam.Value; + _params.sys_params.rx2_channel.datarate = phyParam.value; - getPhy.Attribute = PHY_DEF_UPLINK_DWELL_TIME; + getPhy.attribute = PHY_DEF_UPLINK_DWELL_TIME; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.uplink_dwell_time = phyParam.Value; + _params.sys_params.uplink_dwell_time = phyParam.value; - getPhy.Attribute = PHY_DEF_DOWNLINK_DWELL_TIME; + getPhy.attribute = PHY_DEF_DOWNLINK_DWELL_TIME; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.downlink_dwell_time = phyParam.Value; + _params.sys_params.downlink_dwell_time = phyParam.value; - getPhy.Attribute = PHY_DEF_MAX_EIRP; + getPhy.attribute = PHY_DEF_MAX_EIRP; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.max_eirp = phyParam.fValue; + _params.sys_params.max_eirp = phyParam.f_value; - getPhy.Attribute = PHY_DEF_ANTENNA_GAIN; + getPhy.attribute = PHY_DEF_ANTENNA_GAIN; phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.antenna_gain = phyParam.fValue; - - lora_phy->load_defaults(INIT_TYPE_INIT); + _params.sys_params.antenna_gain = phyParam.f_value; // Init parameters which are not set in function ResetMacParameters _params.sys_params.max_sys_rx_error = 10; @@ -1898,11 +1895,9 @@ void LoRaMac::disconnect() lorawan_status_t LoRaMac::LoRaMacQueryTxPossible( uint8_t size, loramac_tx_info_t* txInfo ) { - AdrNextParams_t adrNext; - GetPhyParams_t getPhy; - PhyParam_t phyParam; - int8_t datarate = _params.sys_params.channel_data_rate; - int8_t txPower = _params.sys_params.channel_tx_power; + get_phy_params_t getPhy; + phy_param_t phyParam; + uint8_t fOptLen = mac_commands.GetLength() + mac_commands.GetRepeatLength(); if( txInfo == NULL ) @@ -1910,30 +1905,24 @@ lorawan_status_t LoRaMac::LoRaMacQueryTxPossible( uint8_t size, loramac_tx_info_ return LORAWAN_STATUS_PARAMETER_INVALID; } - // Setup ADR request - adrNext.UpdateChanMask = false; - adrNext.AdrEnabled = _params.sys_params.adr_on; - adrNext.AdrAckCounter = _params.adr_ack_counter; - adrNext.Datarate = _params.sys_params.channel_data_rate; - adrNext.TxPower = _params.sys_params.channel_tx_power; - adrNext.UplinkDwellTime = _params.sys_params.uplink_dwell_time; - - // We call the function for information purposes only. We don't want to - // apply the datarate, the tx power and the ADR ack counter. - lora_phy->get_next_ADR(&adrNext, &datarate, &txPower, &_params.adr_ack_counter); + // if applicaion has turned on ADR, we want to opt it out + if (_params.sys_params.adr_on) { + lora_phy->get_next_ADR(false, _params.sys_params.channel_data_rate, + _params.sys_params.channel_tx_power, + _params.adr_ack_counter); + } // Setup PHY request - getPhy.UplinkDwellTime = _params.sys_params.uplink_dwell_time; - getPhy.Datarate = datarate; - getPhy.Attribute = PHY_MAX_PAYLOAD; + getPhy.datarate = _params.sys_params.channel_data_rate; + getPhy.attribute = PHY_MAX_PAYLOAD; // Change request in case repeater is supported if( _params.is_repeater_supported == true ) { - getPhy.Attribute = PHY_MAX_PAYLOAD_REPEATER; + getPhy.attribute = PHY_MAX_PAYLOAD_REPEATER; } phyParam = lora_phy->get_phy_params( &getPhy ); - txInfo->current_payload_size = phyParam.Value; + txInfo->current_payload_size = phyParam.value; // Verify if the fOpts fit into the maximum payload if( txInfo->current_payload_size >= fOptLen ) @@ -1951,7 +1940,8 @@ lorawan_status_t LoRaMac::LoRaMacQueryTxPossible( uint8_t size, loramac_tx_info_ } // Verify if the fOpts and the payload fit into the maximum payload - if( ValidatePayloadLength( size, datarate, fOptLen ) == false ) + if( ValidatePayloadLength( size, _params.sys_params.channel_data_rate, + fOptLen ) == false ) { return LORAWAN_STATUS_LENGTH_ERROR; } diff --git a/features/lorawan/lorastack/mac/LoRaMac.h b/features/lorawan/lorastack/mac/LoRaMac.h index 00f4f44e28..030f6f3e4a 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.h +++ b/features/lorawan/lorastack/mac/LoRaMac.h @@ -41,7 +41,6 @@ #define __LORAMAC_H__ #include "lorawan/system/LoRaWANTimer.h" -#include "netsocket/LoRaRadio.h" #include "lorastack/phy/LoRaPHY.h" #include "lorawan/system/lorawan_data_structures.h" #include "lorastack/mac/LoRaMacCommand.h" diff --git a/features/lorawan/lorastack/mac/LoRaMacChannelPlan.cpp b/features/lorawan/lorastack/mac/LoRaMacChannelPlan.cpp index b84c8ca1f3..aa36de1388 100644 --- a/features/lorawan/lorastack/mac/LoRaMacChannelPlan.cpp +++ b/features/lorawan/lorastack/mac/LoRaMacChannelPlan.cpp @@ -41,18 +41,17 @@ void LoRaMacChannelPlan::activate_channelplan_subsystem(LoRaPHY *phy, LoRaMacMib lorawan_status_t LoRaMacChannelPlan::set_plan(const lorawan_channelplan_t& plan) { - ChannelAddParams_t channelAdd; channel_params_t mac_layer_ch_params; lorawan_status_t status; - GetPhyParams_t get_phy; - PhyParam_t phy_param; + get_phy_params_t get_phy; + phy_param_t phy_param; uint8_t max_num_channels; // Check first how many channels the selected PHY layer supports - get_phy.Attribute = PHY_MAX_NB_CHANNELS; + get_phy.attribute = PHY_MAX_NB_CHANNELS; phy_param = _lora_phy->get_phy_params(&get_phy); - max_num_channels = (uint8_t) phy_param.Value; + max_num_channels = (uint8_t) phy_param.value; // check if user is setting more channels than supported if (plan.nb_channels > max_num_channels) { @@ -60,22 +59,16 @@ lorawan_status_t LoRaMacChannelPlan::set_plan(const lorawan_channelplan_t& plan) } for (uint8_t i = 0; i < plan.nb_channels; i++) { + mac_layer_ch_params.band = plan.channels[i].ch_param.band; - mac_layer_ch_params.dr_range.fields.max = - plan.channels[i].ch_param.dr_range.fields.max; - mac_layer_ch_params.dr_range.fields.min = - plan.channels[i].ch_param.dr_range.fields.min; - mac_layer_ch_params.dr_range.value = - plan.channels[i].ch_param.dr_range.value; - mac_layer_ch_params.frequency = - plan.channels[i].ch_param.frequency; - mac_layer_ch_params.rx1_frequency = - plan.channels[i].ch_param.rx1_frequency; - channelAdd.ChannelId = plan.channels[i].id; - channelAdd.NewChannel = &mac_layer_ch_params; + mac_layer_ch_params.dr_range.fields.max = plan.channels[i].ch_param.dr_range.fields.max; + mac_layer_ch_params.dr_range.fields.min = plan.channels[i].ch_param.dr_range.fields.min; + mac_layer_ch_params.dr_range.value = plan.channels[i].ch_param.dr_range.value; + mac_layer_ch_params.frequency = plan.channels[i].ch_param.frequency; + mac_layer_ch_params.rx1_frequency = plan.channels[i].ch_param.rx1_frequency; - status = _lora_phy->add_channel(&channelAdd); + status = _lora_phy->add_channel(&mac_layer_ch_params, plan.channels[i].id); if (status != LORAWAN_STATUS_OK) { return status; @@ -95,21 +88,21 @@ lorawan_status_t LoRaMacChannelPlan::get_plan(lorawan_channelplan_t& plan, loramac_mib_req_confirm_t mib_confirm; lorawan_status_t status; - GetPhyParams_t get_phy; - PhyParam_t phy_param; + get_phy_params_t get_phy; + phy_param_t phy_param; uint8_t max_num_channels; uint16_t *channel_masks; uint8_t count = 0; // Check first how many channels the selected PHY layer supports - get_phy.Attribute = PHY_MAX_NB_CHANNELS; + get_phy.attribute = PHY_MAX_NB_CHANNELS; phy_param = _lora_phy->get_phy_params(&get_phy); - max_num_channels = (uint8_t) phy_param.Value; + max_num_channels = (uint8_t) phy_param.value; // Now check the Default channel mask - get_phy.Attribute = PHY_CHANNELS_MASK; + get_phy.attribute = PHY_CHANNELS_MASK; phy_param = _lora_phy->get_phy_params(&get_phy); - channel_masks = phy_param.ChannelsMask; + channel_masks = phy_param.channel_mask; // Request Mib to get channels memset(&mib_confirm, 0, sizeof(mib_confirm)); @@ -147,26 +140,26 @@ lorawan_status_t LoRaMacChannelPlan::remove_plan() { lorawan_status_t status = LORAWAN_STATUS_OK; - GetPhyParams_t get_phy; - PhyParam_t phy_param; + get_phy_params_t get_phy; + phy_param_t phy_param; uint8_t max_num_channels; uint16_t *channel_masks; uint16_t *default_channel_masks; // Check first how many channels the selected PHY layer supports - get_phy.Attribute = PHY_MAX_NB_CHANNELS; + get_phy.attribute = PHY_MAX_NB_CHANNELS; phy_param = _lora_phy->get_phy_params(&get_phy); - max_num_channels = (uint8_t) phy_param.Value; + max_num_channels = (uint8_t) phy_param.value; // Now check the channel mask for enabled channels - get_phy.Attribute = PHY_CHANNELS_MASK; + get_phy.attribute = PHY_CHANNELS_MASK; phy_param = _lora_phy->get_phy_params(&get_phy); - channel_masks = phy_param.ChannelsMask; + channel_masks = phy_param.channel_mask; // Now check the channel mask for default channels - get_phy.Attribute = PHY_CHANNELS_DEFAULT_MASK; + get_phy.attribute = PHY_CHANNELS_DEFAULT_MASK; phy_param = _lora_phy->get_phy_params(&get_phy); - default_channel_masks = phy_param.ChannelsMask; + default_channel_masks = phy_param.channel_mask; for (uint8_t i = 0; i < max_num_channels; i++) { // skip any default channels @@ -191,16 +184,15 @@ lorawan_status_t LoRaMacChannelPlan::remove_plan() lorawan_status_t LoRaMacChannelPlan::remove_single_channel(uint8_t channel_id) { - GetPhyParams_t get_phy; - PhyParam_t phy_param; + get_phy_params_t get_phy; + phy_param_t phy_param; uint8_t max_num_channels; uint16_t *channel_masks; - ChannelRemoveParams_t channelRemove; // Check first how many channels the selected PHY layer supports - get_phy.Attribute = PHY_MAX_NB_CHANNELS; + get_phy.attribute = PHY_MAX_NB_CHANNELS; phy_param = _lora_phy->get_phy_params(&get_phy); - max_num_channels = (uint8_t) phy_param.Value; + max_num_channels = (uint8_t) phy_param.value; // According to specification channel IDs start from 0 and last valid // channel ID is N-1 where N=MAX_NUM_CHANNELS. @@ -210,9 +202,9 @@ lorawan_status_t LoRaMacChannelPlan::remove_single_channel(uint8_t channel_id) } // Now check the Default channel mask - get_phy.Attribute = PHY_CHANNELS_DEFAULT_MASK; + get_phy.attribute = PHY_CHANNELS_DEFAULT_MASK; phy_param = _lora_phy->get_phy_params(&get_phy); - channel_masks = phy_param.ChannelsMask; + channel_masks = phy_param.channel_mask; // check if the channel ID give belongs to a default channel // Mostly the default channels are in the first mask if the region @@ -222,9 +214,7 @@ lorawan_status_t LoRaMacChannelPlan::remove_single_channel(uint8_t channel_id) return LORAWAN_STATUS_PARAMETER_INVALID; } - channelRemove.ChannelId = channel_id; - - if(_lora_phy->remove_channel(&channelRemove) == false) + if(_lora_phy->remove_channel(channel_id) == false) { return LORAWAN_STATUS_PARAMETER_INVALID; } diff --git a/features/lorawan/lorastack/mac/LoRaMacCommand.cpp b/features/lorawan/lorastack/mac/LoRaMacCommand.cpp index 18a19890b4..7d834216cd 100644 --- a/features/lorawan/lorastack/mac/LoRaMacCommand.cpp +++ b/features/lorawan/lorastack/mac/LoRaMacCommand.cpp @@ -273,20 +273,20 @@ lorawan_status_t LoRaMacCommand::ProcessMacCommands(uint8_t *payload, uint8_t ma break; case SRV_MAC_LINK_ADR_REQ: { - LinkAdrReqParams_t linkAdrReq; + adr_req_params_t linkAdrReq; int8_t linkAdrDatarate = DR_0; int8_t linkAdrTxPower = TX_POWER_0; uint8_t linkAdrNbRep = 0; uint8_t linkAdrNbBytesParsed = 0; // Fill parameter structure - linkAdrReq.Payload = &payload[macIndex - 1]; - linkAdrReq.PayloadSize = commandsSize - ( macIndex - 1 ); - linkAdrReq.AdrEnabled = LoRaMacParams.adr_on; - linkAdrReq.UplinkDwellTime = LoRaMacParams.uplink_dwell_time; - linkAdrReq.CurrentDatarate = LoRaMacParams.channel_data_rate; - linkAdrReq.CurrentTxPower = LoRaMacParams.channel_tx_power; - linkAdrReq.CurrentNbRep = LoRaMacParams.retry_num; + linkAdrReq.payload = &payload[macIndex - 1]; + linkAdrReq.payload_size = commandsSize - ( macIndex - 1 ); + linkAdrReq.adr_enabled = LoRaMacParams.adr_on; + linkAdrReq.ul_dwell_time = LoRaMacParams.uplink_dwell_time; + linkAdrReq.current_datarate = LoRaMacParams.channel_data_rate; + linkAdrReq.current_tx_power = LoRaMacParams.channel_tx_power; + linkAdrReq.current_nb_rep = LoRaMacParams.retry_num; // Process the ADR requests status = lora_phy.link_ADR_request(&linkAdrReq, &linkAdrDatarate, @@ -316,25 +316,25 @@ lorawan_status_t LoRaMacCommand::ProcessMacCommands(uint8_t *payload, uint8_t ma break; case SRV_MAC_RX_PARAM_SETUP_REQ: { - RxParamSetupReqParams_t rxParamSetupReq; + rx_param_setup_req_t rxParamSetupReq; - rxParamSetupReq.DrOffset = ( payload[macIndex] >> 4 ) & 0x07; - rxParamSetupReq.Datarate = payload[macIndex] & 0x0F; + rxParamSetupReq.dr_offset = ( payload[macIndex] >> 4 ) & 0x07; + rxParamSetupReq.datarate = payload[macIndex] & 0x0F; macIndex++; - rxParamSetupReq.Frequency = ( uint32_t )payload[macIndex++]; - rxParamSetupReq.Frequency |= ( uint32_t )payload[macIndex++] << 8; - rxParamSetupReq.Frequency |= ( uint32_t )payload[macIndex++] << 16; - rxParamSetupReq.Frequency *= 100; + rxParamSetupReq.frequency = ( uint32_t )payload[macIndex++]; + rxParamSetupReq.frequency |= ( uint32_t )payload[macIndex++] << 8; + rxParamSetupReq.frequency |= ( uint32_t )payload[macIndex++] << 16; + rxParamSetupReq.frequency *= 100; // Perform request on region - status = lora_phy.setup_rx_params(&rxParamSetupReq); + status = lora_phy.accept_rx_param_setup_req(&rxParamSetupReq); if( ( status & 0x07 ) == 0x07 ) { - LoRaMacParams.rx2_channel.datarate = rxParamSetupReq.Datarate; - LoRaMacParams.rx2_channel.frequency = rxParamSetupReq.Frequency; - LoRaMacParams.rx1_dr_offset = rxParamSetupReq.DrOffset; + LoRaMacParams.rx2_channel.datarate = rxParamSetupReq.datarate; + LoRaMacParams.rx2_channel.frequency = rxParamSetupReq.frequency; + LoRaMacParams.rx1_dr_offset = rxParamSetupReq.dr_offset; } ret_value = AddMacCommand( MOTE_MAC_RX_PARAM_SETUP_ANS, status, 0 ); } @@ -349,11 +349,11 @@ lorawan_status_t LoRaMacCommand::ProcessMacCommands(uint8_t *payload, uint8_t ma } case SRV_MAC_NEW_CHANNEL_REQ: { - NewChannelReqParams_t newChannelReq; + new_channel_req_params_t newChannelReq; channel_params_t chParam; - newChannelReq.ChannelId = payload[macIndex++]; - newChannelReq.NewChannel = &chParam; + newChannelReq.channel_id = payload[macIndex++]; + newChannelReq.new_channel = &chParam; chParam.frequency = ( uint32_t )payload[macIndex++]; chParam.frequency |= ( uint32_t )payload[macIndex++] << 8; @@ -382,29 +382,29 @@ lorawan_status_t LoRaMacCommand::ProcessMacCommands(uint8_t *payload, uint8_t ma break; case SRV_MAC_TX_PARAM_SETUP_REQ: { - TxParamSetupReqParams_t txParamSetupReq; + tx_param_setup_req_t txParamSetupReq; uint8_t eirpDwellTime = payload[macIndex++]; - txParamSetupReq.UplinkDwellTime = 0; - txParamSetupReq.DownlinkDwellTime = 0; + txParamSetupReq.ul_dwell_time = 0; + txParamSetupReq.dl_dwell_time = 0; if( ( eirpDwellTime & 0x20 ) == 0x20 ) { - txParamSetupReq.DownlinkDwellTime = 1; + txParamSetupReq.dl_dwell_time = 1; } if( ( eirpDwellTime & 0x10 ) == 0x10 ) { - txParamSetupReq.UplinkDwellTime = 1; + txParamSetupReq.ul_dwell_time = 1; } - txParamSetupReq.MaxEirp = eirpDwellTime & 0x0F; + txParamSetupReq.max_eirp = eirpDwellTime & 0x0F; // Check the status for correctness - if( lora_phy.setup_tx_params(&txParamSetupReq ) != -1 ) + if(lora_phy.accept_tx_param_setup_req(&txParamSetupReq)) { // Accept command - LoRaMacParams.uplink_dwell_time = txParamSetupReq.UplinkDwellTime; - LoRaMacParams.downlink_dwell_time = txParamSetupReq.DownlinkDwellTime; - LoRaMacParams.max_eirp = LoRaMacMaxEirpTable[txParamSetupReq.MaxEirp]; + LoRaMacParams.uplink_dwell_time = txParamSetupReq.ul_dwell_time; + LoRaMacParams.downlink_dwell_time = txParamSetupReq.dl_dwell_time; + LoRaMacParams.max_eirp = LoRaMacMaxEirpTable[txParamSetupReq.max_eirp]; // Add command response ret_value = AddMacCommand( MOTE_MAC_TX_PARAM_SETUP_ANS, 0, 0 ); } @@ -412,13 +412,13 @@ lorawan_status_t LoRaMacCommand::ProcessMacCommands(uint8_t *payload, uint8_t ma break; case SRV_MAC_DL_CHANNEL_REQ: { - DlChannelReqParams_t dlChannelReq; + dl_channel_req_params_t dlChannelReq; - dlChannelReq.ChannelId = payload[macIndex++]; - dlChannelReq.Rx1Frequency = ( uint32_t )payload[macIndex++]; - dlChannelReq.Rx1Frequency |= ( uint32_t )payload[macIndex++] << 8; - dlChannelReq.Rx1Frequency |= ( uint32_t )payload[macIndex++] << 16; - dlChannelReq.Rx1Frequency *= 100; + dlChannelReq.channel_id = payload[macIndex++]; + dlChannelReq.rx1_frequency = ( uint32_t )payload[macIndex++]; + dlChannelReq.rx1_frequency |= ( uint32_t )payload[macIndex++] << 8; + dlChannelReq.rx1_frequency |= ( uint32_t )payload[macIndex++] << 16; + dlChannelReq.rx1_frequency *= 100; status = lora_phy.dl_channel_request(&dlChannelReq); diff --git a/features/lorawan/lorastack/mac/LoRaMacMcps.cpp b/features/lorawan/lorastack/mac/LoRaMacMcps.cpp index 96ee43ac15..17aa3194ee 100644 --- a/features/lorawan/lorastack/mac/LoRaMacMcps.cpp +++ b/features/lorawan/lorastack/mac/LoRaMacMcps.cpp @@ -49,11 +49,11 @@ lorawan_status_t LoRaMacMcps::set_request(loramac_mcps_req_t *mcpsRequest, return LORAWAN_STATUS_PARAMETER_INVALID; } - GetPhyParams_t getPhy; - PhyParam_t phyParam; + get_phy_params_t get_phy; + phy_param_t phyParam; lorawan_status_t status = LORAWAN_STATUS_SERVICE_UNKNOWN; loramac_mhdr_t macHdr; - VerifyParams_t verify; + verification_params_t verify; uint8_t fPort = 0; void *fBuffer; uint16_t fBufferSize; @@ -115,23 +115,19 @@ lorawan_status_t LoRaMacMcps::set_request(loramac_mcps_req_t *mcpsRequest, // } // Get the minimum possible datarate - getPhy.Attribute = PHY_MIN_TX_DR; - getPhy.UplinkDwellTime = params->sys_params.uplink_dwell_time; - phyParam = _lora_phy->get_phy_params(&getPhy); + get_phy.attribute = PHY_MIN_TX_DR; + phyParam = _lora_phy->get_phy_params(&get_phy); // Apply the minimum possible datarate. // Some regions have limitations for the minimum datarate. - datarate = MAX(datarate, (int8_t)phyParam.Value); + datarate = MAX(datarate, (int8_t)phyParam.value); if (readyToSend == true) { if (params->sys_params.adr_on == false) { - verify.DatarateParams.Datarate = datarate; - verify.DatarateParams.UplinkDwellTime = - params->sys_params.uplink_dwell_time; + verify.datarate = datarate; if (_lora_phy->verify(&verify, PHY_TX_DR) == true) { - params->sys_params.channel_data_rate = - verify.DatarateParams.Datarate; + params->sys_params.channel_data_rate = verify.datarate; } else { return LORAWAN_STATUS_PARAMETER_INVALID; } diff --git a/features/lorawan/lorastack/mac/LoRaMacMib.cpp b/features/lorawan/lorastack/mac/LoRaMacMib.cpp index 7e567cedbe..2849469494 100644 --- a/features/lorawan/lorastack/mac/LoRaMacMib.cpp +++ b/features/lorawan/lorastack/mac/LoRaMacMib.cpp @@ -49,8 +49,7 @@ lorawan_status_t LoRaMacMib::set_request(loramac_mib_req_confirm_t *mibSet, } lorawan_status_t status = LORAWAN_STATUS_OK; - ChanMaskSetParams_t chanMaskSet; - VerifyParams_t verify; + verification_params_t verify; switch (mibSet->type) { @@ -126,8 +125,7 @@ lorawan_status_t LoRaMacMib::set_request(loramac_mib_req_confirm_t *mibSet, break; } case MIB_RX2_CHANNEL: { - verify.DatarateParams.Datarate = mibSet->param.rx2_channel.datarate; - verify.DatarateParams.DownlinkDwellTime = params->sys_params.downlink_dwell_time; + verify.datarate = mibSet->param.rx2_channel.datarate; if (_lora_phy->verify(&verify, PHY_RX_DR) == true) { params->sys_params.rx2_channel = mibSet->param.rx2_channel; @@ -154,8 +152,7 @@ lorawan_status_t LoRaMacMib::set_request(loramac_mib_req_confirm_t *mibSet, break; } case MIB_RX2_DEFAULT_CHANNEL: { - verify.DatarateParams.Datarate = mibSet->param.rx2_channel.datarate; - verify.DatarateParams.DownlinkDwellTime = params->sys_params.downlink_dwell_time; + verify.datarate = mibSet->param.rx2_channel.datarate; if (_lora_phy->verify(&verify, PHY_RX_DR) == true) { params->sys_params.rx2_channel = mibSet->param.default_rx2_channel; @@ -164,22 +161,13 @@ lorawan_status_t LoRaMacMib::set_request(loramac_mib_req_confirm_t *mibSet, } break; } - case MIB_CHANNELS_DEFAULT_MASK: { - chanMaskSet.ChannelsMaskIn = mibSet->param.channel_mask; - chanMaskSet.ChannelsMaskType = CHANNELS_DEFAULT_MASK; - - if (_lora_phy->set_channel_mask(&chanMaskSet) == false) { - status = LORAWAN_STATUS_PARAMETER_INVALID; - } - break; - } + case MIB_CHANNELS_DEFAULT_MASK: case MIB_CHANNELS_MASK: { - chanMaskSet.ChannelsMaskIn = mibSet->param.channel_mask; - chanMaskSet.ChannelsMaskType = CHANNELS_MASK; - - if (_lora_phy->set_channel_mask(&chanMaskSet) == false) { - status = LORAWAN_STATUS_PARAMETER_INVALID; - } + // channel masks must not be tempered with. + // They should be manipulated only on request with certain + // APIs like add_channel() and remove_channel() + // You should be able to get these MIB parameters, not set + status = LORAWAN_STATUS_SERVICE_UNKNOWN; break; } case MIB_CHANNELS_NB_REP: { @@ -212,41 +200,40 @@ lorawan_status_t LoRaMacMib::set_request(loramac_mib_req_confirm_t *mibSet, break; } case MIB_CHANNELS_DEFAULT_DATARATE: { - verify.DatarateParams.Datarate = mibSet->param.default_channel_data_rate; + verify.datarate = mibSet->param.default_channel_data_rate; if (_lora_phy->verify(&verify, PHY_DEF_TX_DR) == true) { - params->sys_params.channel_data_rate = verify.DatarateParams.Datarate; + params->sys_params.channel_data_rate = verify.datarate; } else { status = LORAWAN_STATUS_PARAMETER_INVALID; } break; } case MIB_CHANNELS_DATARATE: { - verify.DatarateParams.Datarate = mibSet->param.channel_data_rate; - verify.DatarateParams.UplinkDwellTime = params->sys_params.uplink_dwell_time; + verify.datarate = mibSet->param.channel_data_rate; if (_lora_phy->verify(&verify, PHY_TX_DR) == true) { - params->sys_params.channel_data_rate = verify.DatarateParams.Datarate; + params->sys_params.channel_data_rate = verify.datarate; } else { status = LORAWAN_STATUS_PARAMETER_INVALID; } break; } case MIB_CHANNELS_DEFAULT_TX_POWER: { - verify.TxPower = mibSet->param.default_channel_tx_pwr; + verify.tx_power = mibSet->param.default_channel_tx_pwr; if (_lora_phy->verify(&verify, PHY_DEF_TX_POWER) == true) { - params->sys_params.channel_tx_power = verify.TxPower; + params->sys_params.channel_tx_power = verify.tx_power; } else { status = LORAWAN_STATUS_PARAMETER_INVALID; } break; } case MIB_CHANNELS_TX_POWER: { - verify.TxPower = mibSet->param.channel_tx_pwr; + verify.tx_power = mibSet->param.channel_tx_pwr; if (_lora_phy->verify(&verify, PHY_TX_POWER) == true) { - params->sys_params.channel_tx_power = verify.TxPower; + params->sys_params.channel_tx_power = verify.tx_power; } else { status = LORAWAN_STATUS_PARAMETER_INVALID; } @@ -284,8 +271,8 @@ lorawan_status_t LoRaMacMib::get_request(loramac_mib_req_confirm_t *mibGet, loramac_protocol_params *params) { lorawan_status_t status = LORAWAN_STATUS_OK; - GetPhyParams_t getPhy; - PhyParam_t phyParam; + get_phy_params_t get_phy; + phy_param_t phyParam; rx2_channel_params rx2_channel; if( mibGet == NULL ) @@ -342,10 +329,10 @@ lorawan_status_t LoRaMacMib::get_request(loramac_mib_req_confirm_t *mibGet, } case MIB_CHANNELS: { - getPhy.Attribute = PHY_CHANNELS; - phyParam = _lora_phy->get_phy_params( &getPhy ); + get_phy.attribute = PHY_CHANNELS; + phyParam = _lora_phy->get_phy_params( &get_phy ); - mibGet->param.channel_list = phyParam.Channels; + mibGet->param.channel_list = phyParam.channel_params; break; } case MIB_RX2_CHANNEL: @@ -355,31 +342,31 @@ lorawan_status_t LoRaMacMib::get_request(loramac_mib_req_confirm_t *mibGet, } case MIB_RX2_DEFAULT_CHANNEL: { - getPhy.Attribute = PHY_DEF_RX2_DR; - phyParam = _lora_phy->get_phy_params( &getPhy ); - rx2_channel.datarate = phyParam.Value; + get_phy.attribute = PHY_DEF_RX2_DR; + phyParam = _lora_phy->get_phy_params( &get_phy ); + rx2_channel.datarate = phyParam.value; - getPhy.Attribute = PHY_DEF_RX2_FREQUENCY; - phyParam = _lora_phy->get_phy_params( &getPhy ); - rx2_channel.frequency = phyParam.Value; + get_phy.attribute = PHY_DEF_RX2_FREQUENCY; + phyParam = _lora_phy->get_phy_params( &get_phy ); + rx2_channel.frequency = phyParam.value; mibGet->param.rx2_channel = rx2_channel; break; } case MIB_CHANNELS_DEFAULT_MASK: { - getPhy.Attribute = PHY_CHANNELS_DEFAULT_MASK; - phyParam = _lora_phy->get_phy_params( &getPhy ); + get_phy.attribute = PHY_CHANNELS_DEFAULT_MASK; + phyParam = _lora_phy->get_phy_params( &get_phy ); - mibGet->param.default_channel_mask = phyParam.ChannelsMask; + mibGet->param.default_channel_mask = phyParam.channel_mask; break; } case MIB_CHANNELS_MASK: { - getPhy.Attribute = PHY_CHANNELS_MASK; - phyParam = _lora_phy->get_phy_params( &getPhy ); + get_phy.attribute = PHY_CHANNELS_MASK; + phyParam = _lora_phy->get_phy_params( &get_phy ); - mibGet->param.channel_mask = phyParam.ChannelsMask; + mibGet->param.channel_mask = phyParam.channel_mask; break; } case MIB_CHANNELS_NB_REP: @@ -414,9 +401,9 @@ lorawan_status_t LoRaMacMib::get_request(loramac_mib_req_confirm_t *mibGet, } case MIB_CHANNELS_DEFAULT_DATARATE: { - getPhy.Attribute = PHY_DEF_TX_DR; - phyParam = _lora_phy->get_phy_params( &getPhy ); - mibGet->param.default_channel_data_rate = phyParam.Value; + get_phy.attribute = PHY_DEF_TX_DR; + phyParam = _lora_phy->get_phy_params( &get_phy ); + mibGet->param.default_channel_data_rate = phyParam.value; break; } case MIB_CHANNELS_DATARATE: @@ -426,9 +413,9 @@ lorawan_status_t LoRaMacMib::get_request(loramac_mib_req_confirm_t *mibGet, } case MIB_CHANNELS_DEFAULT_TX_POWER: { - getPhy.Attribute = PHY_DEF_TX_POWER; - phyParam = _lora_phy->get_phy_params( &getPhy ); - mibGet->param.default_channel_tx_pwr = phyParam.Value; + get_phy.attribute = PHY_DEF_TX_POWER; + phyParam = _lora_phy->get_phy_params( &get_phy ); + mibGet->param.default_channel_tx_pwr = phyParam.value; break; } case MIB_CHANNELS_TX_POWER: diff --git a/features/lorawan/lorastack/mac/LoRaMacMlme.cpp b/features/lorawan/lorastack/mac/LoRaMacMlme.cpp index 8fd61544bd..9f2eb6f668 100644 --- a/features/lorawan/lorastack/mac/LoRaMacMlme.cpp +++ b/features/lorawan/lorastack/mac/LoRaMacMlme.cpp @@ -50,10 +50,10 @@ lorawan_status_t LoRaMacMlme::set_request(loramac_mlme_req_t *mlmeRequest, lorawan_status_t status = LORAWAN_STATUS_SERVICE_UNKNOWN; loramac_mhdr_t macHdr; - AlternateDrParams_t altDr; - VerifyParams_t verify; - GetPhyParams_t getPhy; - PhyParam_t phyParam; + + verification_params_t verify; + get_phy_params_t get_phy; + phy_param_t phyParam; if (params->mac_state != LORAMAC_IDLE) { @@ -81,13 +81,13 @@ lorawan_status_t LoRaMacMlme::set_request(loramac_mlme_req_t *mlmeRequest, } // Verify the parameter NbTrials for the join procedure - verify.NbJoinTrials = mlmeRequest->req.join.nb_trials; + verify.nb_join_trials = mlmeRequest->req.join.nb_trials; if (_lora_phy->verify(&verify, PHY_NB_JOIN_TRIALS) == false) { // Value not supported, get default - getPhy.Attribute = PHY_DEF_NB_JOIN_TRIALS; - phyParam = _lora_phy->get_phy_params(&getPhy); - mlmeRequest->req.join.nb_trials = (uint8_t) phyParam.Value; + get_phy.attribute = PHY_DEF_NB_JOIN_TRIALS; + phyParam = _lora_phy->get_phy_params(&get_phy); + mlmeRequest->req.join.nb_trials = (uint8_t) phyParam.value; } params->flags.bits.mlme_req = 1; @@ -107,10 +107,8 @@ lorawan_status_t LoRaMacMlme::set_request(loramac_mlme_req_t *mlmeRequest, _lora_mac->ResetMacParameters(); - altDr.NbTrials = params->join_request_trial_counter + 1; - params->sys_params.channel_data_rate = - _lora_phy->get_alternate_DR(&altDr); + _lora_phy->get_alternate_DR(params->join_request_trial_counter + 1); status = _lora_mac->Send(&macHdr, 0, NULL, 0); break; diff --git a/features/lorawan/lorastack/phy/LoRaPHY.cpp b/features/lorawan/lorastack/phy/LoRaPHY.cpp index 3c4cc9b275..72234139c1 100644 --- a/features/lorawan/lorastack/phy/LoRaPHY.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHY.cpp @@ -28,28 +28,17 @@ SPDX-License-Identifier: BSD-3-Clause #include #include "lorawan/lorastack/phy/LoRaPHY.h" - #define BACKOFF_DC_1_HOUR 100 #define BACKOFF_DC_10_HOURS 1000 #define BACKOFF_DC_24_HOURS 10000 -static uint8_t CountChannels( uint16_t mask, uint8_t nbBits ) -{ - uint8_t nbActiveBits = 0; - - for( uint8_t j = 0; j < nbBits; j++ ) - { - if( ( mask & ( 1 << j ) ) == ( 1 << j ) ) - { - nbActiveBits++; - } - } - return nbActiveBits; -} +#define CHANNELS_IN_MASK 16 LoRaPHY::LoRaPHY(LoRaWANTimeHandler &lora_time) - : _lora_time(lora_time) + : _radio(NULL), + _lora_time(lora_time) { + memset(&phy_params, 0, sizeof(phy_params)); } LoRaPHY::~LoRaPHY() @@ -74,14 +63,6 @@ void LoRaPHY::put_radio_to_standby() { _radio->unlock(); } -void LoRaPHY::setup_tx_cont_wave_mode(uint16_t timeout, uint32_t frequency, - uint8_t power) -{ - _radio->lock(); - _radio->set_tx_continuous_wave(frequency, power, timeout); - _radio->unlock(); -} - void LoRaPHY::setup_public_network_mode(bool set) { _radio->lock(); @@ -92,15 +73,11 @@ void LoRaPHY::setup_public_network_mode(bool set) void LoRaPHY::setup_rx_window(bool rx_continuous, uint32_t max_rx_window) { _radio->lock(); - if (!rx_continuous) { _radio->receive(max_rx_window); - _radio->unlock(); - return; + } else { + _radio->receive(0); // Continuous mode } - - _radio->receive(0); // Continuous mode - _radio->unlock(); } @@ -123,316 +100,1319 @@ void LoRaPHY::handle_send(uint8_t *buf, uint8_t size) _radio->unlock(); } +uint8_t LoRaPHY::request_new_channel(new_channel_req_params_t* params) +{ + if (!phy_params.custom_channelplans_supported) { + return 0; + } + + uint8_t status = 0x03; + + if (params->new_channel->frequency == 0) { + // Remove + if (remove_channel(params->channel_id) == false) { + status &= 0xFC; + } + } else { + + switch (add_channel(params->new_channel, params->channel_id)) { + case LORAWAN_STATUS_OK: + { + break; + } + case LORAWAN_STATUS_FREQUENCY_INVALID: + { + status &= 0xFE; + break; + } + case LORAWAN_STATUS_DATARATE_INVALID: + { + status &= 0xFD; + break; + } + case LORAWAN_STATUS_FREQ_AND_DR_INVALID: + { + status &= 0xFC; + break; + } + default: + { + status &= 0xFC; + break; + } + } + } + + return status; +} + int32_t LoRaPHY::get_random(int32_t min, int32_t max) { return (int32_t) rand() % (max - min + 1) + min; } -uint16_t LoRaPHY::get_join_DC( lorawan_time_t elapsedTime ) +bool LoRaPHY::verify_channel_DR(uint8_t nbChannels, uint16_t* channelsMask, + int8_t dr, int8_t minDr, int8_t maxDr, + channel_params_t* channels) { - uint16_t dutyCycle = 0; - - if( elapsedTime < 3600000 ) - { - dutyCycle = BACKOFF_DC_1_HOUR; - } - else if( elapsedTime < ( 3600000 + 36000000 ) ) - { - dutyCycle = BACKOFF_DC_10_HOURS; - } - else - { - dutyCycle = BACKOFF_DC_24_HOURS; - } - return dutyCycle; -} - -bool LoRaPHY::verify_channel_DR( uint8_t nbChannels, uint16_t* channelsMask, int8_t dr, int8_t minDr, int8_t maxDr, channel_params_t* channels ) -{ - if( val_in_range( dr, minDr, maxDr ) == 0 ) - { + if (val_in_range(dr, minDr, maxDr) == 0) { return false; } - for( uint8_t i = 0, k = 0; i < nbChannels; i += 16, k++ ) - { - for( uint8_t j = 0; j < 16; j++ ) - { - if( ( ( channelsMask[k] & ( 1 << j ) ) != 0 ) ) - {// Check datarate validity for enabled channels - if( val_in_range( dr, ( channels[i + j].dr_range.fields.min & 0x0F ), - ( channels[i + j].dr_range.fields.max & 0x0F ) ) == 1 ) - { + for (uint8_t i = 0, k = 0; i < nbChannels; i += 16, k++) { + for( uint8_t j = 0; j < 16; j++ ) { + if( ((channelsMask[k] & (1 << j)) != 0)) { + // Check datarate validity for enabled channels + if (val_in_range(dr, (channels[i + j].dr_range.fields.min & 0x0F), + (channels[i + j].dr_range.fields.max & 0x0F)) == 1 ) { // At least 1 channel has been found we can return OK. return true; } } } } + return false; } uint8_t LoRaPHY::val_in_range( int8_t value, int8_t min, int8_t max ) { - if( ( value >= min ) && ( value <= max ) ) - { + if ((value >= min) && (value <= max)) { return 1; } + return 0; } -bool LoRaPHY::disable_channel( uint16_t* channelsMask, uint8_t id, uint8_t maxChannels ) +bool LoRaPHY::disable_channel(uint16_t* channelsMask, uint8_t id, + uint8_t maxChannels) { uint8_t index = id / 16; - if( ( index > ( maxChannels / 16 ) ) || ( id >= maxChannels ) ) - { + if ((index > phy_params.channels.mask_list_size) || (id >= maxChannels)) { return false; } // Deactivate channel - channelsMask[index] &= ~( 1 << ( id % 16 ) ); + channelsMask[index] &= ~(1 << (id % 16)); return true; } +uint8_t LoRaPHY::count_bits(uint16_t mask, uint8_t nbBits) +{ + uint8_t nbActiveBits = 0; + + for(uint8_t j = 0; j < nbBits; j++) { + if ((mask & (1 << j)) == (1 << j)) { + nbActiveBits++; + } + } + + return nbActiveBits; +} + uint8_t LoRaPHY::num_active_channels( uint16_t* channelsMask, uint8_t startIdx, uint8_t stopIdx ) { uint8_t nbChannels = 0; - if( channelsMask == NULL ) - { + if (channelsMask == NULL) { return 0; } - for( uint8_t i = startIdx; i < stopIdx; i++ ) - { - nbChannels += CountChannels( channelsMask[i], 16 ); + for (uint8_t i = startIdx; i < stopIdx; i++) { + nbChannels += count_bits(channelsMask[i], 16); } return nbChannels; } -void LoRaPHY::copy_channel_mask( uint16_t* channelsMaskDest, uint16_t* channelsMaskSrc, uint8_t len ) +void LoRaPHY::copy_channel_mask(uint16_t* channelsMaskDest, uint16_t* channelsMaskSrc, uint8_t len) { - if( ( channelsMaskDest != NULL ) && ( channelsMaskSrc != NULL ) ) - { - for( uint8_t i = 0; i < len; i++ ) - { + if ((channelsMaskDest != NULL) && (channelsMaskSrc != NULL)) { + for( uint8_t i = 0; i < len; i++ ) { channelsMaskDest[i] = channelsMaskSrc[i]; } } } -void LoRaPHY::set_last_tx_done( bool joined, band_t* band, lorawan_time_t lastTxDone ) +void LoRaPHY::set_last_tx_done(set_band_txdone_params_t* last_tx_params) { - if( joined == true ) - { - band->last_tx_time = lastTxDone; + if (!last_tx_params) { + return; } - else - { - band->last_tx_time = lastTxDone; - band->last_join_tx_time = lastTxDone; + + band_t *band_table = (band_t *) phy_params.bands.table; + channel_params_t *channel_list = phy_params.channels.channel_list; + + if (last_tx_params->joined == true) { + band_table[channel_list[last_tx_params->channel].band].last_tx_time = last_tx_params->last_tx_done_time; + return; } + + band_table[channel_list[last_tx_params->channel].band].last_tx_time = last_tx_params->last_tx_done_time; + band_table[channel_list[last_tx_params->channel].band].last_join_tx_time = last_tx_params->last_tx_done_time; + } -lorawan_time_t LoRaPHY::update_band_timeoff( bool joined, bool dutyCycle, band_t* bands, uint8_t nbBands ) +lorawan_time_t LoRaPHY::update_band_timeoff(bool joined, bool duty_cycle, + band_t* bands, uint8_t nb_bands) { - lorawan_time_t nextTxDelay = ( lorawan_time_t )( -1 ); + lorawan_time_t next_tx_delay = (lorawan_time_t) (-1); // Update bands Time OFF - for( uint8_t i = 0; i < nbBands; i++ ) - { - if( joined == false ) - { - uint32_t txDoneTime = MAX( _lora_time.TimerGetElapsedTime( bands[i].last_join_tx_time ), - ( dutyCycle == true ) ? _lora_time.TimerGetElapsedTime( bands[i].last_tx_time ) : 0 ); + for (uint8_t i = 0; i < nb_bands; i++) { - if( bands[i].off_time <= txDoneTime ) - { + if (joined == false) { + uint32_t txDoneTime = MAX(_lora_time.TimerGetElapsedTime(bands[i].last_join_tx_time), + (duty_cycle == true) ? + _lora_time.TimerGetElapsedTime(bands[i].last_tx_time) : 0); + + if (bands[i].off_time <= txDoneTime) { bands[i].off_time = 0; } - if( bands[i].off_time != 0 ) - { - nextTxDelay = MIN( bands[i].off_time - txDoneTime, nextTxDelay ); + + if (bands[i].off_time != 0) { + next_tx_delay = MIN( bands[i].off_time - txDoneTime, next_tx_delay ); } - } - else - { - if( dutyCycle == true ) - { - if( bands[i].off_time <= _lora_time.TimerGetElapsedTime( bands[i].last_tx_time ) ) - { + + } else { + // if network has been joined + if (duty_cycle == true) { + + if( bands[i].off_time <= _lora_time.TimerGetElapsedTime(bands[i].last_tx_time)) { bands[i].off_time = 0; } - if( bands[i].off_time != 0 ) - { - nextTxDelay = MIN( bands[i].off_time - _lora_time.TimerGetElapsedTime( bands[i].last_tx_time ), - nextTxDelay ); + + if(bands[i].off_time != 0 ) { + next_tx_delay = MIN(bands[i].off_time - _lora_time.TimerGetElapsedTime(bands[i].last_tx_time), + next_tx_delay); } - } - else - { - nextTxDelay = 0; + } else { + // if duty cycle is not on + next_tx_delay = 0; bands[i].off_time = 0; } } } - return nextTxDelay; + + return next_tx_delay; } -uint8_t LoRaPHY::parse_link_ADR_req( uint8_t* payload, RegionCommonLinkAdrParams_t* linkAdrParams ) +uint8_t LoRaPHY::parse_link_ADR_req(uint8_t* payload, link_adr_params_t* params) { - uint8_t retIndex = 0; + uint8_t ret_index = 0; + + if (payload[0] == SRV_MAC_LINK_ADR_REQ) { - if( payload[0] == SRV_MAC_LINK_ADR_REQ ) - { // Parse datarate and tx power - linkAdrParams->Datarate = payload[1]; - linkAdrParams->TxPower = linkAdrParams->Datarate & 0x0F; - linkAdrParams->Datarate = ( linkAdrParams->Datarate >> 4 ) & 0x0F; + params->datarate = payload[1]; + params->tx_power = params->datarate & 0x0F; + params->datarate = (params->datarate >> 4) & 0x0F; + // Parse ChMask - linkAdrParams->ChMask = ( uint16_t )payload[2]; - linkAdrParams->ChMask |= ( uint16_t )payload[3] << 8; + params->channel_mask = (uint16_t) payload[2]; + params->channel_mask |= (uint16_t) payload[3] << 8; + // Parse ChMaskCtrl and nbRep - linkAdrParams->NbRep = payload[4]; - linkAdrParams->ChMaskCtrl = ( linkAdrParams->NbRep >> 4 ) & 0x07; - linkAdrParams->NbRep &= 0x0F; + params->nb_rep = payload[4]; + params->ch_mask_ctrl = ( params->nb_rep >> 4 ) & 0x07; + params->nb_rep &= 0x0F; // LinkAdrReq has 4 bytes length + 1 byte CMD - retIndex = 5; + ret_index = 5; } - return retIndex; + + return ret_index; } -uint8_t LoRaPHY::verify_link_ADR_req( RegionCommonLinkAdrReqVerifyParams_t* verifyParams, int8_t* dr, int8_t* txPow, uint8_t* nbRep ) +uint8_t LoRaPHY::verify_link_ADR_req(verify_adr_params_t* verify_params, + int8_t* dr, int8_t* tx_pow, uint8_t* nb_rep) { - uint8_t status = verifyParams->Status; - int8_t datarate = verifyParams->Datarate; - int8_t txPower = verifyParams->TxPower; - int8_t nbRepetitions = verifyParams->NbRep; + uint8_t status = verify_params->status; + int8_t datarate = verify_params->datarate; + int8_t tx_power = verify_params->tx_power; + int8_t nb_repetitions = verify_params->nb_rep; // Handle the case when ADR is off. - if( verifyParams->AdrEnabled == false ) - { + if (verify_params->adr_enabled == false) { // When ADR is off, we are allowed to change the channels mask and the NbRep, // if the datarate and the TX power of the LinkAdrReq are set to 0x0F. - if( ( verifyParams->Datarate != 0x0F ) || ( verifyParams->TxPower != 0x0F ) ) - { + if ((verify_params->datarate != 0x0F) || (verify_params->tx_power != 0x0F)) { status = 0; - nbRepetitions = verifyParams->CurrentNbRep; + nb_repetitions = verify_params->current_nb_rep; } + // Get the current datarate and tx power - datarate = verifyParams->CurrentDatarate; - txPower = verifyParams->CurrentTxPower; + datarate = verify_params->current_datarate; + tx_power = verify_params->current_tx_power; } - if( status != 0 ) - { - // Verify datarate. The variable phyParam. Value contains the minimum allowed datarate. - if( verify_channel_DR( verifyParams->NbChannels, verifyParams->ChannelsMask, datarate, - verifyParams->MinDatarate, verifyParams->MaxDatarate, verifyParams->Channels ) == false ) - { + if (status != 0) { + // Verify channel datarate + if (verify_channel_DR(phy_params.max_channel_cnt, verify_params->channel_mask, + datarate, phy_params.min_tx_datarate, + phy_params.max_tx_datarate, phy_params.channels.channel_list) + == false) { status &= 0xFD; // Datarate KO } // Verify tx power - if( val_in_range( txPower, verifyParams->MaxTxPower, verifyParams->MinTxPower ) == 0 ) - { + if (val_in_range(tx_power, phy_params.max_tx_power, + phy_params.min_tx_power) == 0) { // Verify if the maximum TX power is exceeded - if( verifyParams->MaxTxPower > txPower ) - { // Apply maximum TX power. Accept TX power. - txPower = verifyParams->MaxTxPower; - } - else - { + if (phy_params.max_tx_power > tx_power) { + // Apply maximum TX power. Accept TX power. + tx_power = phy_params.max_tx_power; + } else { status &= 0xFB; // TxPower KO } } } // If the status is ok, verify the NbRep - if( status == 0x07 ) - { - if( nbRepetitions == 0 ) - { // Restore the default value according to the LoRaWAN specification - nbRepetitions = 1; - } + if (status == 0x07 && nb_repetitions == 0) { + // Restore the default value according to the LoRaWAN specification + nb_repetitions = 1; } // Apply changes *dr = datarate; - *txPow = txPower; - *nbRep = nbRepetitions; + *tx_pow = tx_power; + *nb_rep = nb_repetitions; return status; } -double LoRaPHY::compute_symb_timeout_lora( uint8_t phyDr, uint32_t bandwidth ) +double LoRaPHY::compute_symb_timeout_lora(uint8_t phy_dr, uint32_t bandwidth) { - return ( ( double )( 1 << phyDr ) / ( double )bandwidth ) * 1000; + return ((double)(1 << phy_dr) / (double) bandwidth) * 1000; } -double LoRaPHY::compute_symb_timeout_fsk( uint8_t phyDr ) +double LoRaPHY::compute_symb_timeout_fsk(uint8_t phy_dr) { - return ( 8.0 / ( double )phyDr ); // 1 symbol equals 1 byte + return (8.0 / (double) phy_dr); // 1 symbol equals 1 byte } -void LoRaPHY::get_rx_window_params( double tSymbol, uint8_t minRxSymbols, uint32_t rxError, uint32_t wakeUpTime, uint32_t* windowTimeout, int32_t* windowOffset ) +void LoRaPHY::get_rx_window_params(double t_symb, uint8_t min_rx_symb, + uint32_t rx_error, uint32_t wakeup_time, + uint32_t* window_timeout, int32_t* window_offset) { - *windowTimeout = MAX( ( uint32_t )ceil( ( ( 2 * minRxSymbols - 8 ) * tSymbol + 2 * rxError ) / tSymbol ), minRxSymbols ); // Computed number of symbols - *windowOffset = ( int32_t )ceil( ( 4.0 * tSymbol ) - ( ( *windowTimeout * tSymbol ) / 2.0 ) - wakeUpTime ); + // Computed number of symbols + *window_timeout = MAX ((uint32_t) ceil(((2 * min_rx_symb - 8) * t_symb + 2 * rx_error) / t_symb), min_rx_symb ); + *window_offset = (int32_t) ceil((4.0 * t_symb) - ((*window_timeout * t_symb) / 2.0 ) - wakeup_time); } -int8_t LoRaPHY::compute_tx_power( int8_t txPowerIndex, float maxEirp, float antennaGain ) +int8_t LoRaPHY::compute_tx_power(int8_t tx_power_idx, float max_eirp, + float antenna_gain) { - int8_t phyTxPower = 0; + int8_t phy_tx_power = 0; - phyTxPower = ( int8_t )floor( ( maxEirp - ( txPowerIndex * 2U ) ) - antennaGain ); + phy_tx_power = (int8_t) floor((max_eirp - (tx_power_idx * 2U)) - antenna_gain); - return phyTxPower; + return phy_tx_power; } -void LoRaPHY::get_DC_backoff( RegionCommonCalcBackOffParams_t* calcBackOffParams ) + +int8_t LoRaPHY::get_next_lower_dr(int8_t dr, int8_t min_dr) { - uint8_t bandIdx = calcBackOffParams->Channels[calcBackOffParams->Channel].band; - uint16_t dutyCycle = calcBackOffParams->Bands[bandIdx].duty_cycle; - uint16_t joinDutyCycle = 0; + uint8_t next_lower_dr = 0; + + if (dr == min_dr) { + next_lower_dr = min_dr; + } else { + next_lower_dr = dr - 1; + } + + return next_lower_dr; +} + +uint8_t LoRaPHY::get_bandwidth(uint8_t dr) +{ + uint32_t *bandwidths = (uint32_t *) phy_params.bandwidths.table; + + switch(bandwidths[dr]) { + default: + case 125000: + return 0; + case 250000: + return 1; + case 500000: + return 2; + } +} + +uint8_t LoRaPHY::enabled_channel_count(bool joined, uint8_t datarate, + uint16_t *mask_list, + uint8_t mask_list_size, + uint8_t *channel_indices, + uint8_t *delayTx) +{ + uint8_t count = 0; + uint8_t delay_transmission = 0; + + for (uint8_t i = 0, k = 0; i < phy_params.max_channel_cnt && k < mask_list_size; + i += CHANNELS_IN_MASK, k++) { + + for (uint8_t j = 0; j < CHANNELS_IN_MASK; j++) { + + if ((mask_list[k] & (1 << j)) != 0) { + if (val_in_range(datarate, phy_params.channels.channel_list[i + j].dr_range.fields.min, + phy_params.channels.channel_list[i + j].dr_range.fields.max ) == 0) { + // data rate range invalid for this channel + continue; + } + + band_t *band_table = (band_t *) phy_params.bands.table; + if (band_table[phy_params.channels.channel_list[i + j].band].off_time > 0) { + // Check if the band is available for transmission + delay_transmission++; + continue; + } + + // otherwise count the channel as enabled + channel_indices[count++] = i + j; + } + } + } + + *delayTx = delay_transmission; + + return count; +} + +phy_param_t LoRaPHY::get_phy_params(get_phy_params_t* getPhy) +{ + phy_param_t phyParam = { 0 }; + + switch (getPhy->attribute) { + case PHY_MIN_RX_DR: { + if (phy_params.dl_dwell_time_setting == 0) { + phyParam.value = phy_params.min_rx_datarate; + } else { + phyParam.value = phy_params.dwell_limit_datarate; + } + break; + } + case PHY_MIN_TX_DR: { + if (phy_params.ul_dwell_time_setting == 0) { + phyParam.value = phy_params.min_tx_datarate; + } else { + phyParam.value = phy_params.dwell_limit_datarate; + } + break; + } + case PHY_DEF_TX_DR: { + phyParam.value = phy_params.default_datarate; + break; + } + case PHY_NEXT_LOWER_TX_DR: { + if (phy_params.ul_dwell_time_setting == 0) { + phyParam.value = get_next_lower_dr(getPhy->datarate, + phy_params.min_tx_datarate); + } else { + phyParam.value = get_next_lower_dr( + getPhy->datarate, phy_params.dwell_limit_datarate); + } + break; + } + case PHY_DEF_TX_POWER: { + phyParam.value = phy_params.default_tx_power; + break; + } + case PHY_MAX_PAYLOAD: { + uint8_t *payload_table = (uint8_t *) phy_params.payloads.table; + phyParam.value = payload_table[getPhy->datarate]; + break; + } + case PHY_MAX_PAYLOAD_REPEATER: { + uint8_t *payload_table = + (uint8_t *) phy_params.payloads_with_repeater.table; + phyParam.value = payload_table[getPhy->datarate]; + break; + } + case PHY_DUTY_CYCLE: { + phyParam.value = phy_params.duty_cycle_enabled; + break; + } + case PHY_MAX_RX_WINDOW: { + phyParam.value = phy_params.max_rx_window; + break; + } + case PHY_RECEIVE_DELAY1: { + phyParam.value = phy_params.recv_delay1; + break; + } + case PHY_RECEIVE_DELAY2: { + phyParam.value = phy_params.recv_delay2; + break; + } + case PHY_JOIN_ACCEPT_DELAY1: { + phyParam.value = phy_params.join_accept_delay1; + break; + } + case PHY_JOIN_ACCEPT_DELAY2: { + phyParam.value = phy_params.join_accept_delay2; + break; + } + case PHY_MAX_FCNT_GAP: { + phyParam.value = phy_params.max_fcnt_gap; + break; + } + case PHY_ACK_TIMEOUT: { + uint16_t ack_timeout = phy_params.ack_timeout; + uint16_t ack_timeout_rnd = phy_params.ack_timeout_rnd; + phyParam.value = (ack_timeout + + get_random(-ack_timeout_rnd, ack_timeout_rnd)); + break; + } + case PHY_DEF_DR1_OFFSET: { + phyParam.value = phy_params.default_rx1_dr_offset; + break; + } + case PHY_DEF_RX2_FREQUENCY: { + phyParam.value = phy_params.rx_window2_frequency; + break; + } + case PHY_DEF_RX2_DR: { + phyParam.value = phy_params.rx_window2_datarate; + break; + } + case PHY_CHANNELS_MASK: { + phyParam.channel_mask = phy_params.channels.mask_list; + break; + } + case PHY_CHANNELS_DEFAULT_MASK: { + phyParam.channel_mask = phy_params.channels.default_mask_list; + break; + } + case PHY_MAX_NB_CHANNELS: { + phyParam.value = phy_params.max_channel_cnt; + break; + } + case PHY_CHANNELS: { + phyParam.channel_params = phy_params.channels.channel_list; + break; + } + case PHY_DEF_UPLINK_DWELL_TIME: { + phyParam.value = phy_params.ul_dwell_time_setting; + break; + } + case PHY_DEF_DOWNLINK_DWELL_TIME: { + phyParam.value = phy_params.dl_dwell_time_setting; + break; + } + case PHY_DEF_MAX_EIRP: { + phyParam.f_value = phy_params.default_max_eirp; + break; + } + case PHY_DEF_ANTENNA_GAIN: { + phyParam.f_value = phy_params.default_antenna_gain; + break; + } + case PHY_NB_JOIN_TRIALS: + case PHY_DEF_NB_JOIN_TRIALS: { + phyParam.value = MBED_CONF_LORA_NB_TRIALS; + break; + } + default: { + break; + } + } + + return phyParam; +} + +void LoRaPHY::restore_default_channels() +{ + // Restore channels default mask + for (uint8_t i=0; i < phy_params.channels.mask_list_size; i++) { + phy_params.channels.mask_list[i] |= phy_params.channels.default_mask_list[i]; + } +} + +bool LoRaPHY::verify(verification_params_t* verify, phy_attributes_t phy_attribute) +{ + switch(phy_attribute) { + case PHY_TX_DR: + { + if (phy_params.ul_dwell_time_setting == 0) { + return val_in_range(verify->datarate, + phy_params.min_tx_datarate, + phy_params.max_tx_datarate); + } else { + return val_in_range(verify->datarate, + phy_params.dwell_limit_datarate, + phy_params.max_tx_datarate); + } + + } + case PHY_DEF_TX_DR: + { + return val_in_range(verify->datarate, + phy_params.default_datarate, + phy_params.default_max_datarate); + } + case PHY_RX_DR: + { + if (phy_params.dl_dwell_time_setting == 0) { + return val_in_range(verify->datarate, + phy_params.min_rx_datarate, + phy_params.min_rx_datarate); + } else { + return val_in_range(verify->datarate, + phy_params.dwell_limit_datarate, + phy_params.min_rx_datarate ); + } + } + case PHY_DEF_TX_POWER: + case PHY_TX_POWER: + { + // Remark: switched min and max! + return val_in_range(verify->tx_power, phy_params.max_tx_power, + phy_params.min_tx_power); + } + case PHY_DUTY_CYCLE: + { + if (verify->duty_cycle == phy_params.duty_cycle_enabled) { + return true; + } + + return false; + } + case PHY_NB_JOIN_TRIALS: + { + if (verify->nb_join_trials < MBED_CONF_LORA_NB_TRIALS) { + return false; + } + break; + } + default: + return false; + } + + return true; +} + +void LoRaPHY::apply_cf_list(cflist_params_t* cf_list) +{ + // if the underlying PHY doesn't support CF-List, ignore the request + if (!phy_params.cflist_supported) { + return; + } + + channel_params_t new_channel; + + // Setup default datarate range + new_channel.dr_range.value = (phy_params.default_max_datarate << 4) + | phy_params.default_datarate; + + // Size of the optional CF list + if (cf_list->size != 16) { + return; + } + + // Last byte is RFU, don't take it into account + // NOTE: Currently the PHY layers supported by LoRaWAN who accept a CF-List + // define first 2 or 3 channels as default channels. this function is + // written keeping that in mind. If there would be a PHY in the future that + // accepts CF-list but have haphazard allocation of default channels, we + // should override this function in the implementation of that particular + // PHY. + for (uint8_t i = 0, channel_id = phy_params.default_channel_cnt; + channel_id < phy_params.max_channel_cnt; i+=phy_params.default_channel_cnt, channel_id++) { + if (channel_id < (phy_params.cflist_channel_cnt + phy_params.default_channel_cnt)) { + // Channel frequency + new_channel.frequency = (uint32_t) cf_list->payload[i]; + new_channel.frequency |= ((uint32_t) cf_list->payload[i + 1] << 8); + new_channel.frequency |= ((uint32_t) cf_list->payload[i + 2] << 16); + new_channel.frequency *= 100; + + // Initialize alternative frequency to 0 + new_channel.rx1_frequency = 0; + } else { + new_channel.frequency = 0; + new_channel.dr_range.value = 0; + new_channel.rx1_frequency = 0; + } + + if (new_channel.frequency != 0) { + // Try to add channel + add_channel(&new_channel, channel_id); + } else { + remove_channel(channel_id); + } + } +} + + +bool LoRaPHY::get_next_ADR(bool restore_channel_mask, int8_t& dr_out, + int8_t& tx_power_out, uint32_t& adr_ack_cnt) +{ + bool set_adr_ack_bit = false; + + get_phy_params_t get_phy; + phy_param_t phy_param; + uint16_t ack_limit_plus_delay = phy_params.adr_ack_limit + phy_params.adr_ack_delay; + + if (dr_out == phy_params.min_tx_datarate) { + adr_ack_cnt = 0; + return set_adr_ack_bit; + } + + if (adr_ack_cnt < phy_params.adr_ack_limit) { + return set_adr_ack_bit; + } + + // ADR ack counter is larger than ADR-ACK-LIMIT + set_adr_ack_bit = true; + tx_power_out = phy_params.max_tx_power; + + + if (adr_ack_cnt >= ack_limit_plus_delay) { + if ((adr_ack_cnt % phy_params.adr_ack_delay) == 1) { + // Decrease the datarate + get_phy.attribute = PHY_NEXT_LOWER_TX_DR; + get_phy.datarate = dr_out; + phy_param = get_phy_params(&get_phy); + dr_out = phy_param.value; + + if (dr_out == phy_params.min_tx_datarate) { + // We must set adrAckReq to false as soon as we reach the lowest datarate + set_adr_ack_bit = false; + if (restore_channel_mask) { + // Re-enable default channels + restore_default_channels(); + } + } + } + } + + return set_adr_ack_bit; +} + +void LoRaPHY::compute_rx_win_params(int8_t datarate, uint8_t min_rx_symbols, + uint32_t rx_error, + rx_config_params_t *rx_conf_params) +{ + double t_symbol = 0.0; + + // Get the datarate, perform a boundary check + rx_conf_params->datarate = MIN( datarate, phy_params.max_rx_datarate); + + rx_conf_params->bandwidth = get_bandwidth(rx_conf_params->datarate); + + if (phy_params.fsk_supported && rx_conf_params->datarate == phy_params.max_rx_datarate) { + // FSK + t_symbol = compute_symb_timeout_fsk(((uint8_t *)phy_params.datarates.table)[rx_conf_params->datarate]); + } else { + // LoRa + t_symbol = compute_symb_timeout_lora(((uint8_t *)phy_params.datarates.table)[rx_conf_params->datarate], + ((uint32_t *)phy_params.bandwidths.table)[rx_conf_params->datarate]); + } + + get_rx_window_params(t_symbol, min_rx_symbols, rx_error, RADIO_WAKEUP_TIME, + &rx_conf_params->window_timeout, &rx_conf_params->window_offset); +} + +bool LoRaPHY::rx_config(rx_config_params_t* rx_conf, int8_t* datarate) +{ + 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; + + _radio->lock(); + + if (_radio->get_status() != RF_IDLE) { + _radio->unlock(); + return false; + } + + _radio->unlock(); + + 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; + uint8_t *payload_table = (uint8_t *) phy_params.payloads.table; + uint8_t *payload_with_repeater_table = (uint8_t *) phy_params.payloads_with_repeater.table; + + phy_dr = datarate_table[dr]; + + _radio->lock(); + + _radio->set_channel(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, 5, + 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, 8, + rx_conf->window_timeout, false, 0, false, 0, 0, + true, rx_conf->is_rx_continuous); + } + + if (rx_conf->is_repeater_supported) { + max_payload = payload_with_repeater_table[dr]; + } else { + max_payload = payload_table[dr]; + } + + _radio->set_max_payload_length(modem, max_payload + LORA_MAC_FRMPAYLOAD_OVERHEAD); + + _radio->unlock(); + + *datarate = phy_dr; + + return true; +} + +bool LoRaPHY::tx_config(tx_config_params_t* tx_conf, int8_t* tx_power, + lorawan_time_t* tx_toa) +{ + radio_modems_t modem; + int8_t phy_dr = ((uint8_t *)phy_params.datarates.table)[tx_conf->datarate]; + channel_params_t *list = phy_params.channels.channel_list; + uint8_t band_idx = list[tx_conf->channel].band; + band_t *bands = (band_t *)phy_params.bands.table; + + // limit TX power if set to too much + if (tx_conf->tx_power > bands[band_idx].max_tx_pwr) { + tx_conf->tx_power = bands[band_idx].max_tx_pwr; + } + + uint8_t bandwidth = get_bandwidth(tx_conf->datarate); + int8_t phy_tx_power = 0; + + // Calculate physical TX power + phy_tx_power = compute_tx_power(tx_conf->tx_power, tx_conf->max_eirp, + tx_conf->antenna_gain); + + _radio->lock(); + + // Setup the radio frequency + _radio->set_channel(list[tx_conf->channel].frequency); + + if( tx_conf->datarate == phy_params.max_tx_datarate ) { + // High Speed FSK channel + modem = MODEM_FSK; + _radio->set_tx_config(modem, phy_tx_power, 25000, bandwidth, + phy_dr * 1000, 0, 5, false, true, 0, 0, false, + 3000); + } else { + modem = MODEM_LORA; + _radio->set_tx_config(modem, phy_tx_power, 0, bandwidth, phy_dr, 1, 8, + false, true, 0, 0, false, 3000 ); + } + + // Setup maximum payload lenght of the radio driver + _radio->set_max_payload_length( modem, tx_conf->pkt_len); + // Get the time-on-air of the next tx frame + *tx_toa = _radio->time_on_air(modem, tx_conf->pkt_len); + + _radio->unlock(); + + *tx_power = tx_conf->tx_power; + + return true; +} + +uint8_t LoRaPHY::link_ADR_request(adr_req_params_t* link_adr_req, + int8_t* dr_out, int8_t* tx_power_out, + uint8_t* nb_rep_out, uint8_t* nb_bytes_processed) +{ + uint8_t status = 0x07; + link_adr_params_t adr_settings; + uint8_t next_index = 0; + uint8_t bytes_processed = 0; + + // rather than dynamically allocating memory, we choose to set + // a channel mask list size of unity here as we know that all + // the PHY layer implementations who have more than 16 channels, i.e., + // have channel mask list size more than unity, override this method. + uint16_t temp_channel_masks[1] = {0}; + + verify_adr_params_t verify_params; + + while (bytes_processed < link_adr_req->payload_size) { + // Get ADR request parameters + next_index = parse_link_ADR_req(&(link_adr_req->payload[bytes_processed]), + &adr_settings); + + if (next_index == 0) { + break; // break loop, since no more request has been found + } + + // Update bytes processed + bytes_processed += next_index; + + // Revert status, as we only check the last ADR request for the channel mask KO + status = 0x07; + + // Setup temporary channels mask + temp_channel_masks[0] = adr_settings.channel_mask; + + // Verify channels mask + if (adr_settings.ch_mask_ctrl == 0 && temp_channel_masks[0] == 0) { + status &= 0xFE; // Channel mask KO + } + + // channel mask applies to first 16 channels + if (adr_settings.ch_mask_ctrl == 0 || + adr_settings.ch_mask_ctrl == 6) { + + for (uint8_t i = 0; i < phy_params.max_channel_cnt; i++) { + + // turn on all channels if channel mask control is 6 + if (adr_settings.ch_mask_ctrl == 6) { + if (phy_params.channels.channel_list[i].frequency != 0) { + temp_channel_masks[0] |= 1 << i; + } + + continue; + } + + // if channel mask control is 0, we test the bits and + // frequencies and change the status if we find a discrepancy + if (((temp_channel_masks[0] & (1 << i)) != 0) + && (phy_params.channels.channel_list[i].frequency == 0)) { + // Trying to enable an undefined channel + status &= 0xFE; // Channel mask KO + } + } + } else { + // Channel mask control applies to RFUs + status &= 0xFE; // Channel mask KO + } + } + + verify_params.status = status; + + verify_params.adr_enabled = link_adr_req->adr_enabled; + verify_params.current_datarate = link_adr_req->current_datarate; + verify_params.current_tx_power = link_adr_req->current_tx_power; + verify_params.current_nb_rep = link_adr_req->current_nb_rep; + + verify_params.datarate = adr_settings.datarate; + verify_params.tx_power = adr_settings.tx_power; + verify_params.nb_rep = adr_settings.nb_rep; + + + verify_params.channel_mask = temp_channel_masks; + + // Verify the parameters and update, if necessary + status = verify_link_ADR_req(&verify_params, &adr_settings.datarate, + &adr_settings.tx_power, &adr_settings.nb_rep); + + // Update channelsMask if everything is correct + if (status == 0x07) { + // Set the channels mask to a default value + memset(phy_params.channels.mask_list, 0, + sizeof(uint16_t)*phy_params.channels.mask_list_size); + + // Update the channels mask + copy_channel_mask(phy_params.channels.mask_list, temp_channel_masks, + phy_params.channels.mask_list_size); + } + + // Update status variables + *dr_out = adr_settings.datarate; + *tx_power_out = adr_settings.tx_power; + *nb_rep_out = adr_settings.nb_rep; + *nb_bytes_processed = bytes_processed; + + return status; +} + +uint8_t LoRaPHY::accept_rx_param_setup_req(rx_param_setup_req_t* params) +{ + uint8_t status = 0x07; + + // Verify radio frequency + if (_radio->check_rf_frequency(params->frequency) == false) { + status &= 0xFE; // Channel frequency KO + } + + // Verify datarate + if (val_in_range(params->datarate, phy_params.min_rx_datarate, + phy_params.max_rx_datarate) == 0) { + status &= 0xFD; // Datarate KO + } + + // Verify datarate offset + if (val_in_range(params->dr_offset, phy_params.min_rx1_dr_offset, + phy_params.max_rx1_dr_offset) == 0) { + status &= 0xFB; // Rx1DrOffset range KO + } + + return status; +} + +bool LoRaPHY::accept_tx_param_setup_req(tx_param_setup_req_t *params) +{ + if (phy_params.accept_tx_param_setup_req) { + phy_params.ul_dwell_time_setting = params->ul_dwell_time; + phy_params.dl_dwell_time_setting = params->dl_dwell_time; + } + + return phy_params.accept_tx_param_setup_req; +} + +bool LoRaPHY::verify_frequency(uint32_t freq) +{ + band_t *bands_table = (band_t *)phy_params.bands.table; + + // check all sub bands (if there are sub-bands) to check if the given + // frequency falls into any of the frequency ranges + + for (uint8_t i=0; i= bands_table[i].lower_band_freq) { + return true; + } + } + + return false; +} + +uint8_t LoRaPHY::dl_channel_request(dl_channel_req_params_t* params) +{ + if (!phy_params.dl_channel_req_supported) { + return 0; + } + + uint8_t status = 0x03; + + // Verify if the frequency is supported + if (verify_frequency(params->rx1_frequency) == false) { + status &= 0xFE; + } + + // Verify if an uplink frequency exists + if (phy_params.channels.channel_list[params->channel_id].frequency == 0) { + status &= 0xFD; + } + + // Apply Rx1 frequency, if the status is OK + if (status == 0x03) { + phy_params.channels.channel_list[params->channel_id].rx1_frequency + = params->rx1_frequency; + } + + return status; +} + +/** + * Alternate datarate algorithm for join requests. + * - We check from the PHY and take note of total + * number of data rates available upto the default data rate for + * default channels. + * + * - Application sets a total number of re-trials for a Join Request, i.e., + * MBED_CONF_LORA_NB_TRIALS. So MAC layer will send us a counter + * nb_trials < MBED_CONF_LORA_NB_TRIALS which is the current number of trial. + * + * - We roll over total available datarates and pick one according to the + * number of trial sequentially. + * + * - We always start from the Default Data rate and and set the next lower + * data rate for every iteration. + * + * - MAC layer will stop when maximum number of re-trials, i.e., + * MBED_CONF_LORA_NB_TRIALS is achieved. + * + * So essentially MBED_CONF_LORA_NB_TRIALS should be a multiple of range of + * data rates available. For example, in EU868 band, default max. data rate is + * DR_5 and min. data rate is DR_0, so total data rates available are 6. + * + * Hence MBED_CONF_LORA_NB_TRIALS should be a multiple of 6. Setting, + * MBED_CONF_LORA_NB_TRIALS = 6 would mean that every data rate will be tried + * exactly once starting from the largest and finishing at the smallest. + * + * PHY layers which do not have datarates scheme similar to EU band will ofcourse + * override this method. + */ +int8_t LoRaPHY::get_alternate_DR(uint8_t nb_trials) +{ + int8_t datarate = 0; + uint8_t total_nb_datrates = (phy_params.default_max_datarate - phy_params.min_tx_datarate) + 1; + + uint8_t res = nb_trials % total_nb_datrates; + + if (res == 0) { + datarate = phy_params.min_tx_datarate; + } else if (res == 1) { + datarate = phy_params.default_max_datarate; + } else { + datarate = (phy_params.default_max_datarate - res) + 1; + } + + return datarate; +} + +void LoRaPHY::calculate_backoff(backoff_params_t* calc_backoff) +{ + band_t *band_table = (band_t *) phy_params.bands.table; + channel_params_t *channel_list = phy_params.channels.channel_list; + + uint8_t band_idx = channel_list[calc_backoff->channel].band; + uint16_t duty_cycle = band_table[band_idx].duty_cycle; + uint16_t join_duty_cycle = 0; // Reset time-off to initial value. - calcBackOffParams->Bands[bandIdx].off_time = 0; + band_table[band_idx].off_time = 0; - if( calcBackOffParams->Joined == false ) - { + if (calc_backoff->joined == false) { // Get the join duty cycle - joinDutyCycle = get_join_DC( calcBackOffParams->ElapsedTime ); + if (calc_backoff->elapsed_time < 3600000) { + join_duty_cycle = BACKOFF_DC_1_HOUR; + } else if (calc_backoff->elapsed_time < (3600000 + 36000000)) { + join_duty_cycle = BACKOFF_DC_10_HOURS; + } else { + join_duty_cycle = BACKOFF_DC_24_HOURS; + } + // Apply the most restricting duty cycle - dutyCycle = MAX( dutyCycle, joinDutyCycle ); - // Reset the timeoff if the last frame was not a join request and when the duty cycle is not enabled - if( ( calcBackOffParams->DutyCycleEnabled == false ) && ( calcBackOffParams->LastTxIsJoinRequest == false ) ) - { - // This is the case when the duty cycle is off and the last uplink frame was not a join. - // This could happen in case of a rejoin, e.g. in compliance test mode. - // In this special case we have to set the time off to 0, since the join duty cycle shall only - // be applied after the first join request. - calcBackOffParams->Bands[bandIdx].off_time = 0; - } - else - { - // Apply band time-off. - calcBackOffParams->Bands[bandIdx].off_time = calcBackOffParams->TxTimeOnAir * dutyCycle - calcBackOffParams->TxTimeOnAir; - } + duty_cycle = MAX(duty_cycle, join_duty_cycle); } - else - { - if( calcBackOffParams->DutyCycleEnabled == true ) - { - calcBackOffParams->Bands[bandIdx].off_time = calcBackOffParams->TxTimeOnAir * dutyCycle - calcBackOffParams->TxTimeOnAir; - } - else - { - calcBackOffParams->Bands[bandIdx].off_time = 0; - } + + // No back-off if the last frame was not a join request and when the + // duty cycle is not enabled + if (calc_backoff->dc_enabled == false && + calc_backoff->last_tx_was_join_req == false) { + band_table[band_idx].off_time = 0; + } else { + // Apply band time-off. + band_table[band_idx].off_time = calc_backoff->tx_toa * duty_cycle + - calc_backoff->tx_toa; } } + +bool LoRaPHY::set_next_channel(channel_selection_params_t* params, + uint8_t* channel, lorawan_time_t* time, + lorawan_time_t* aggregate_timeoff) +{ + uint8_t channel_count = 0; + uint8_t delay_tx = 0; + + // Note here that the PHY layer implementations which have more than + // 16 channels at their disposal, override this function. That's why + // it is safe to assume that we are dealing with a block of 16 channels + // i.e., EU like implementations. So rather than dynamically allocating + // memory we chose to use a magic number of 16 + uint8_t enabled_channels[16]; + + memset(enabled_channels, 0xFF, sizeof(uint8_t)*16); + + lorawan_time_t next_tx_delay = 0; + band_t *band_table = (band_t *) phy_params.bands.table; + + if (num_active_channels(phy_params.channels.mask_list, 0, + phy_params.channels.mask_list_size) == 0) { + + // Reactivate default channels + copy_channel_mask(phy_params.channels.mask_list, + phy_params.channels.default_mask_list, + phy_params.channels.mask_list_size); + } + + if (params->aggregate_timeoff + <= _lora_time.TimerGetElapsedTime(params->last_aggregate_tx_time)) { + // Reset Aggregated time off + *aggregate_timeoff = 0; + + // Update bands Time OFF + next_tx_delay = update_band_timeoff(params->joined, + params->dc_enabled, + band_table, phy_params.bands.size); + + // Search how many channels are enabled + channel_count = enabled_channel_count(params->joined, params->current_datarate, + phy_params.channels.mask_list, + phy_params.channels.mask_list_size, + enabled_channels, &delay_tx); + } else { + delay_tx++; + next_tx_delay = params->aggregate_timeoff + - _lora_time.TimerGetElapsedTime(params->last_aggregate_tx_time); + } + + if (channel_count > 0) { + // We found a valid channel + *channel = enabled_channels[get_random(0, channel_count - 1)]; + *time = 0; + return true; + } + + if (delay_tx > 0) { + // Delay transmission due to AggregatedTimeOff or to a band time off + *time = next_tx_delay; + return true; + } + + // Datarate not supported by any channel, restore defaults + copy_channel_mask(phy_params.channels.mask_list, + phy_params.channels.default_mask_list, + phy_params.channels.mask_list_size); + *time = 0; + return false; +} + +lorawan_status_t LoRaPHY::add_channel(channel_params_t* new_channel, uint8_t id) +{ + bool dr_invalid = false; + bool freq_invalid = false; + + if (!phy_params.custom_channelplans_supported + || id >= phy_params.max_channel_cnt) { + + return LORAWAN_STATUS_PARAMETER_INVALID; + } + + // Validate the datarate range + if (val_in_range(new_channel->dr_range.fields.min, + phy_params.min_tx_datarate, + phy_params.max_tx_datarate) == 0) { + dr_invalid = true; + } + + if (val_in_range(new_channel->dr_range.fields.max, phy_params.min_tx_datarate, + phy_params.max_tx_datarate) == 0) { + dr_invalid = true; + } + + if (new_channel->dr_range.fields.min > new_channel->dr_range.fields.max) { + dr_invalid = true; + } + + // Default channels don't accept all values + if (id < phy_params.default_channel_cnt) { + // Validate the datarate range for min: must be DR_0 + if (new_channel->dr_range.fields.min > phy_params.min_tx_datarate) { + dr_invalid = true; + } + + // Validate the datarate range for max: must be DR_5 <= Max <= TX_MAX_DATARATE + if (val_in_range(new_channel->dr_range.fields.max, + phy_params.default_max_datarate, + phy_params.max_tx_datarate) == 0) { + dr_invalid = true; + } + + // We are not allowed to change the frequency + if (new_channel->frequency != phy_params.channels.channel_list[id].frequency) { + freq_invalid = true; + } + } + + // Check frequency + if (!freq_invalid) { + if (verify_frequency(new_channel->frequency) == false) { + freq_invalid = true; + } + } + + // Check status + if (dr_invalid && freq_invalid) { + return LORAWAN_STATUS_FREQ_AND_DR_INVALID; + } + + if (dr_invalid) { + return LORAWAN_STATUS_DATARATE_INVALID; + } + + if (freq_invalid) { + return LORAWAN_STATUS_FREQUENCY_INVALID; + } + + memcpy(&(phy_params.channels.channel_list[id]), new_channel, + sizeof(phy_params.channels.channel_list[id])); + + phy_params.channels.channel_list[id].band = new_channel->band; + + // if there are multiple channel masks, i.e., there are more than 16 channels + // defined by the PHY layer, we search the channel index in all masks and + // set the appropriate bit in the appropriate mask + for (uint8_t i = 0; i < phy_params.max_channel_cnt; i ++) { + if (i == id) { + phy_params.channels.mask_list[i/16] |= (1 << (i%16)); + } + } + + return LORAWAN_STATUS_OK; +} + +bool LoRaPHY::remove_channel(uint8_t channel_id) +{ + if (!phy_params.custom_channelplans_supported) { + return false; + } + + if (channel_id < phy_params.default_channel_cnt) { + return false; + } + + // Remove the channel from the list of channels + const channel_params_t empty_channel = { 0, 0, { 0 }, 0 }; + phy_params.channels.channel_list[channel_id] = empty_channel; + + return disable_channel(phy_params.channels.mask_list, channel_id, + phy_params.max_channel_cnt); +} + +void LoRaPHY::set_tx_cont_mode(cw_mode_params_t* params, uint32_t given_frequency) +{ + band_t *bands_table = (band_t *) phy_params.bands.table; + channel_params_t *channels = phy_params.channels.channel_list; + + if (params->tx_power > bands_table[channels[params->channel].band].max_tx_pwr) { + params->tx_power = bands_table[channels[params->channel].band].max_tx_pwr; + } + + int8_t phy_tx_power = 0; + uint32_t frequency = 0; + + if (given_frequency == 0) { + frequency = channels[params->channel].frequency; + } else { + frequency = given_frequency; + } + + // Calculate physical TX power + if (params->max_eirp > 0 && params->antenna_gain > 0) { + phy_tx_power = compute_tx_power(params->tx_power, params->max_eirp, + params->antenna_gain ); + } else { + phy_tx_power = params->tx_power; + } + + _radio->lock(); + _radio->set_tx_continuous_wave(frequency, phy_tx_power, params->timeout); + _radio->unlock(); +} + +uint8_t LoRaPHY::apply_DR_offset(int8_t dr, int8_t dr_offset) +{ + int8_t datarate = dr - dr_offset; + + if (datarate < 0) { + datarate = phy_params.min_tx_datarate; + } + + return datarate; +} + + diff --git a/features/lorawan/lorastack/phy/LoRaPHY.h b/features/lorawan/lorastack/phy/LoRaPHY.h index 85cb4e9482..cf433665e1 100644 --- a/features/lorawan/lorastack/phy/LoRaPHY.h +++ b/features/lorawan/lorastack/phy/LoRaPHY.h @@ -37,109 +37,168 @@ #include "lorawan/system/LoRaWANTimer.h" #include "lorawan/lorastack/phy/lora_phy_ds.h" #include "netsocket/LoRaRadio.h" +#include "platform/NonCopyable.h" -class LoRaPHY { +class LoRaPHY : private mbed::NonCopyable { public: - LoRaPHY(LoRaWANTimeHandler &lora_time); virtual ~LoRaPHY(); + /** Stores a reference to Radio object. + * + * Application is responsible for constructing a 'LoRaRadio' object + * which is passed down to the PHY layer. + * + * @param radio a reference to radio driver object + */ void set_radio_instance(LoRaRadio& radio); + /** Puts radio in sleep mode. + * + * Requests the radio driver to enter sleep mode. + */ void put_radio_to_sleep(void); + /** Puts radio in standby mode. + * + * Requests the radio driver to enter standby mode. + */ void put_radio_to_standby(void); + /** Puts radio in receive mode. + * + * Requests the radio driver to enter receive mode for a given time or to + * enter continuous reception mode. + * + * @param is_rx_continuous if true, sets the radio to enter continuous + * reception mode. + * + * @param max_rx_window duration of receive window + */ void setup_rx_window(bool is_rx_continuous, uint32_t max_rx_window); - void setup_tx_cont_wave_mode(uint16_t timeout, uint32_t frequency, - uint8_t power); - + /** Delegates MAC layer request to transmit packet. + * + * @param buf a pointer to the data which needs to be transmitted + * + * @param size size of the data in bytes + */ void handle_send(uint8_t *buf, uint8_t size); + /** Enables/Disables public network mode. + * + * Public and private LoRaWAN network constitute different preambles and + * Net IDs. This API isused to tell the radio which network mode is in use. + * + * @param set true or false + */ void setup_public_network_mode(bool set); + /** Provides a random number from radio. + * + * Returns a 32-bit random unsigned integer value based upon RSSI + * measurements. + * + * @return a 32-bit long random number + * + */ uint32_t get_radio_rng(); - /*! - * \brief The function gets a value of a specific PHY attribute. + /** Calculates and applies duty cycle back-off time. * - * \param [in] getPhy A pointer to the function parameters. + * Explicitly updates the band time-off. * - * \retval A structure containing the PHY parameter. + * @param [in] backoff_params A pointer to backoff parameters. */ - virtual PhyParam_t get_phy_params(GetPhyParams_t* getPhy ) = 0; + void calculate_backoff(backoff_params_t* backoff_params); - /*! - * \brief Updates the last TX done parameters of the current channel. + /** Entertain a new channel request MAC command. * - * \param [in] txDone A pointer to the function parameters. + * MAC command subsystem processes the new channel request coming form + * the network server and then MAC layer asks the PHY layer to entertain + * the request. + * + * @param [in] new_channel_req A pointer to the new_channel_req_params_t. + * + * @return bit mask, according to the LoRaWAN spec 1.0.2. */ - virtual void set_band_tx_done(SetBandTxDoneParams_t* txDone ) = 0; + virtual uint8_t request_new_channel(new_channel_req_params_t* new_channel_req); - /*! - * \brief Initializes the channels masks and the channels. + /** Grants access to PHY layer parameters. * - * \param [in] type Sets the initialization type. + * This is essentially a PHY layer parameter retrieval system. + * A request is made for a certain parameter by setting an appropriate + * attribute. + * + * @param [in] get_phy A pointer to get_phy_params_t + * + * @return A structure containing the requested PHY parameter value. */ - virtual void load_defaults(InitType_t type ) = 0; + virtual phy_param_t get_phy_params(get_phy_params_t* get_phy); - /*! - * \brief Verifies a parameter. + /** Process PHY layer state after a successful transmission. * - * \param [in] verify A pointer to the function parameters. + * Updates times of the last transmission for the particular channel and + * band upon which last transmission took place. * - * \param [in] phyAttribute The attribute for which the verification is needed. - * - * \retval True, if the parameter is valid. + * @param [in] tx_done A pointer to set_band_txdone_params_t */ - virtual bool verify(VerifyParams_t* verify, PhyAttribute_t phyAttribute ) = 0; + virtual void set_last_tx_done(set_band_txdone_params_t* tx_done); - /*! - * \brief The function parses the input buffer and sets up the channels of the CF list. + /** Enables default channels only. * - * \param [in] applyCFList A pointer to the function parameters. + * Falls back to a channel mask where only default channels are enabled, all + * other channels are disabled. */ - virtual void apply_cf_list(ApplyCFListParams_t* applyCFList ) = 0; + virtual void restore_default_channels(); - /*! - * \brief Sets a channels mask. + /** Verify if a parameter is eligible. * - * \param [in] chanMaskSet A pointer to the function parameters. + * @param verify A pointer to the verification_params_t that contains + * parameters which we need to check for validity. * - * \retval True, if the channels mask could be set. + * @param phy_attr The attribute for which the verification is needed. + * + * @return True, if the parameter is valid. */ - virtual bool set_channel_mask(ChanMaskSetParams_t* chanMaskSet ) = 0; + virtual bool verify(verification_params_t* verify, phy_attributes_t phy_attr); - /*! - * \brief Calculates the next datarate to set, when ADR is on or off. + /** Processes the incoming CF-list. * - * \param [in] adrNext A pointer to the function parameters. + * Handles the payload containing CF-list and enables channels defined + * therein. * - * \param [out] drOut The calculated datarate for the next TX. - * - * \param [out] txPowOut The TX power for the next TX. - * - * \param [out] adrAckCounter The calculated ADR acknowledgement counter. - * - * \retval True, if an ADR request should be performed. + * @param cflist_params A pointer to cflist_params_t. */ - virtual bool get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut, - int8_t* txPowOut, uint32_t* adrAckCounter ) = 0; + virtual void apply_cf_list(cflist_params_t* cflist_params); - /*! - * \brief Configuration of the RX windows. + /** Calculates the next datarate to set, when ADR is on or off. * - * \param [in] rxConfig A pointer to the function parameters. + * @param restore_channel_mask A boolean set restore channel mask in case + * of failure. * - * \param [out] datarate The datarate index set. + * @param dr_out The calculated datarate for the next TX. * - * \retval True, if the configuration was applied successfully. + * @param tx_power_out The TX power for the next TX. + * + * @param adr_ack_counter The calculated ADR acknowledgement counter. + * + * @return True, if an ADR request should be performed. */ - virtual bool rx_config(rx_config_params_t* rxConfig, int8_t* datarate ) = 0; + bool get_next_ADR(bool restore_channel_mask, int8_t& dr_out, + int8_t& tx_power_out, uint32_t& adr_ack_counter); - /* - * RX window precise timing + /** Configure radio reception. + * + * @param [in] config A pointer to the RX configuration. + * + * @param [out] datarate The datarate index set. + * + * @return True, if the configuration was applied successfully. + */ + virtual bool rx_config(rx_config_params_t* config, int8_t* datarate); + + /** Computing Receive Windows * * For more details please consult the following document, chapter 3.1.2. * http://www.semtech.com/images/datasheet/SX1272_settings_for_LoRaWAN_v2.0.pdf @@ -179,500 +238,257 @@ public: /*! * Computes the RX window timeout and offset. * - * \param [in] datarate The RX window datarate index to be used. + * @param [in] datarate The RX window datarate index to be used. * - * \param [in] minRxSymbols The minimum number of symbols required to detect an RX frame. + * @param [in] min_rx_symbols The minimum number of symbols required to + * detect an RX frame. * - * \param [in] rxError The maximum timing error of the receiver in milliseconds. - * The receiver will turn on in a [-rxError : +rxError] ms - * interval around RxOffset. + * @param [in] rx_error The maximum timing error of the receiver + * in milliseconds. The receiver will turn on + * in a [-rxError : +rxError] ms interval around + * RxOffset. * - * \param [out] rxConfigParams Returns the updated WindowTimeout and WindowOffset fields. + * @param [out] rx_conf_params Pointer to the structure that needs to be + * filled with receive window parameters. * */ - virtual void compute_rx_win_params(int8_t datarate, - uint8_t minRxSymbols, - uint32_t rxError, - rx_config_params_t *rxConfigParams) = 0; - /*! - * \brief TX configuration. - * - * \param [in] txConfig A pointer to the function parameters. - * - * \param [out] txPower The TX power index set. - * - * \param [out] txTimeOnAir The time-on-air of the frame. - * - * \retval True, if the configuration was applied successfully. - */ - virtual bool tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - lorawan_time_t* txTimeOnAir ) = 0; + virtual void compute_rx_win_params(int8_t datarate, uint8_t min_rx_symbols, + uint32_t rx_error, + rx_config_params_t *rx_conf_params); - /*! - * \brief The function processes a Link ADR Request. + /** Configure radio transmission. * - * \param [in] linkAdrReq A pointer to the function parameters. + * @param [in] tx_config Structure containing tx parameters. * - * \param [out] drOut The datarate applied. + * @param [out] tx_power The TX power which will be set. * - * \param [out] txPowOut The TX power applied. + * @param [out] tx_toa The time-on-air of the frame. * - * \param [out] nbRepOut The number of repetitions to apply. - * - * \param [out] nbBytesParsed The number of bytes parsed. - * - * \retval The status of the operation, according to the LoRaMAC specification. + * @return True, if the configuration was applied successfully. */ - virtual uint8_t link_ADR_request(LinkAdrReqParams_t* linkAdrReq, - int8_t* drOut, int8_t* txPowOut, - uint8_t* nbRepOut, - uint8_t* nbBytesParsed ) = 0; + virtual bool tx_config(tx_config_params_t* tx_config, int8_t* tx_power, + lorawan_time_t* tx_toa); - /*! - * \brief The function processes a RX Parameter Setup Request. + /** Processes a Link ADR Request. * - * \param [in] rxParamSetupReq A pointer to the function parameters. + * @param [in] params A pointer ADR request parameters. * - * \retval The status of the operation, according to the LoRaMAC specification. + * @param [out] dr_out The datarate applied. + * + * @param [out] tx_power_out The TX power applied. + * + * @param [out] nb_rep_out The number of repetitions to apply. + * + * @param [out] nb_bytes_parsed The number of bytes parsed. + * + * @return The status of the operation, according to the LoRaMAC specification. */ - virtual uint8_t setup_rx_params(RxParamSetupReqParams_t* rxParamSetupReq ) = 0; + virtual uint8_t link_ADR_request(adr_req_params_t* params, + int8_t* dr_out, int8_t* tx_power_out, + uint8_t* nb_rep_out, + uint8_t* nb_bytes_parsed); - /*! - * \brief The function processes a New Channel Request. + /** Accept or rejects RxParamSetupReq MAC command * - * \param [in] newChannelReq A pointer to the function parameters. + * The function processes a RX parameter setup request in response to + * server MAC command for RX setup. * - * \retval The status of the operation, according to the LoRaMAC specification. + * @param [in] params A pointer to rx parameter setup request. + * + * @return The status of the operation, according to the LoRaWAN specification. */ - virtual uint8_t request_new_channel(NewChannelReqParams_t* newChannelReq ) = 0; + virtual uint8_t accept_rx_param_setup_req(rx_param_setup_req_t* params); - /*! - * \brief The function processes a TX ParamSetup Request. + /** Makes decision whether to accept or reject TxParamSetupReq MAC command * - * \param [in] txParamSetupReq A pointer to the function parameters. + * @param [in] params A pointer to tx parameter setup request. * - * \retval The status of the operation, according to the LoRaMAC specification. - * Returns -1, if the functionality is not implemented. In this case, the end node - * shall ignore the command. + * @return True to let the MAC know that the request is + * accepted and MAC can apply TX parameters received + * form Network Server. Otherwise false is returned. */ - virtual int8_t setup_tx_params(TxParamSetupReqParams_t* txParamSetupReq ) = 0; + virtual bool accept_tx_param_setup_req(tx_param_setup_req_t* params); - /*! - * \brief The function processes a DlChannel Request. + /** Processes a DlChannelReq MAC command. * - * \param [in] dlChannelReq A pointer to the function parameters. + * @param [in] params A pointer to downlink channel request. * - * \retval The status of the operation, according to the LoRaMAC specification. + * @return The status of the operation, according to the LoRaWAN specification. */ - virtual uint8_t dl_channel_request(DlChannelReqParams_t* dlChannelReq ) = 0; + virtual uint8_t dl_channel_request(dl_channel_req_params_t* params); - /*! - * \brief Alternates the datarate of the channel for the join request. + /** Alternates the datarate of the channel for the join request. * - * \param [in] alternateDr A pointer to the function parameters. + * @param nb_trials Number of trials to be made on one given data rate. * - * \retval The datarate to apply. + * @return The datarate to apply . */ - virtual int8_t get_alternate_DR(AlternateDrParams_t* alternateDr ) = 0; + virtual int8_t get_alternate_DR(uint8_t nb_trials); - /*! - * \brief Calculates the back-off time. + /** Searches and sets the next available channel. * - * \param [in] calcBackOff A pointer to the function parameters. + * If there are multiple channels found available, one of them is selected + * randomly. + * + * @param [in] nextChanParams Parameters for the next channel. + * + * @param [out] channel The next channel to use for TX. + * + * @param [out] time The time to wait for the next transmission according to the duty cycle. + * + * @param [out] aggregatedTimeOff Updates the aggregated time off. + * + * @return Function status [1: OK, 0: Unable to find a channel on the current datarate]. */ - virtual void calculate_backoff(CalcBackOffParams_t* calcBackOff ) = 0; - - /*! - * \brief Searches and sets the next random available channel. - * - * \param [in] nextChanParams Parameters for the next channel. - * - * \param [out] channel The next channel to use for TX. - * - * \param [out] time The time to wait for the next transmission according to the duty cycle. - * - * \param [out] aggregatedTimeOff Updates the aggregated time off. - * - * \retval Function status [1: OK, 0: Unable to find a channel on the current datarate]. - */ - virtual bool set_next_channel(NextChanParams_t* nextChanParams, + virtual bool set_next_channel(channel_selection_params_t* nextChanParams, uint8_t* channel, lorawan_time_t* time, - lorawan_time_t* aggregatedTimeOff ) = 0; + lorawan_time_t* aggregatedTimeOff); - /*! - * \brief Adds a channel. + /** Adds a channel to the channel list. * - * \param [in] channelAdd A pointer to the function parameters. + * Verifies the channel parameters and if everything is found legitimate, + * adds that particular channel to the channel list and updates the channel + * mask. * - * \retval The status of the operation. + * @param [in] new_channel A pointer to the parameters for the new channel. + * @param [in] id Channel ID + * + * @return LORAWAN_STATUS_OK if everything goes fine, negative error code + * otherwise. */ - virtual lorawan_status_t add_channel(ChannelAddParams_t* channelAdd ) = 0; + virtual lorawan_status_t add_channel(channel_params_t* new_channel, uint8_t id); - /*! - * \brief Removes a channel. + /** Removes a channel from the channel list. * - * \param [in] channelRemove A pointer to the function parameters. + * @param [in] channel_id Index of the channel to be removed * - * \retval True, if the channel was removed successfully. + * @return True, if the channel was removed successfully. */ - virtual bool remove_channel(ChannelRemoveParams_t* channelRemove ) = 0; + virtual bool remove_channel(uint8_t channel_id); - /*! - * \brief Sets the radio into continuous wave mode. + /** Puts the radio into continuous wave mode. * - * \param [in] continuousWave A pointer to the function parameters. + * @param [in] continuous_wave A pointer to the function parameters. + * + * @param [in] frequency Frequency to transmit at */ - virtual void set_tx_cont_mode(ContinuousWaveParams_t* continuousWave ) = 0; + virtual void set_tx_cont_mode(cw_mode_params_t* continuous_wave, + uint32_t frequency = 0); - /*! - * \brief Computes new datarate according to the given offset + /** Computes new data rate according to the given offset * - * \param [in] downlinkDwellTime The downlink dwell time configuration. 0: No limit, 1: 400ms + * @param [in] dr The current datarate. * - * \param [in] dr The current datarate. + * @param [in] dr_offset The offset to be applied. * - * \param [in] drOffset The offset to be applied. - * - * \retval newDr The computed datarate. + * @return The computed datarate. */ - virtual uint8_t apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ) = 0; + virtual uint8_t apply_DR_offset(int8_t dr, int8_t dr_offset); protected: LoRaRadio *_radio; LoRaWANTimeHandler &_lora_time; + loraphy_params_t phy_params; - typedef struct sRegionCommonLinkAdrParams - { - /*! - * The number of repetitions. - */ - uint8_t NbRep; - /*! - * Datarate. - */ - int8_t Datarate; - /*! - * TX power. - */ - int8_t TxPower; - /*! - * Channels mask control field. - */ - uint8_t ChMaskCtrl; - /*! - * Channels mask field. - */ - uint16_t ChMask; - }RegionCommonLinkAdrParams_t; + LoRaPHY(LoRaWANTimeHandler &lora_time); - typedef struct sRegionCommonLinkAdrReqVerifyParams - { - /*! - * The current status of the AdrLinkRequest. - */ - uint8_t Status; - /*! - * Set to true, if ADR is enabled. - */ - bool AdrEnabled; - /*! - * The datarate the AdrLinkRequest wants to set. - */ - int8_t Datarate; - /*! - * The TX power the AdrLinkRequest wants to set. - */ - int8_t TxPower; - /*! - * The number of repetitions the AdrLinkRequest wants to set. - */ - uint8_t NbRep; - /*! - * The current datarate the node is using. - */ - int8_t CurrentDatarate; - /*! - * The current TX power the node is using. - */ - int8_t CurrentTxPower; - /*! - * The current number of repetitions the node is using. - */ - int8_t CurrentNbRep; - /*! - * The number of channels. - */ - uint8_t NbChannels; - /*! - * A pointer to the first element of the channels mask. - */ - uint16_t* ChannelsMask; - /*! - * The minimum possible datarate. - */ - int8_t MinDatarate; - /*! - * The maximum possible datarate. - */ - int8_t MaxDatarate; - /*! - * A pointer to the channels. - */ - channel_params_t* Channels; - /*! - * The minimum possible TX power. - */ - int8_t MinTxPower; - /*! - * The maximum possible TX power. - */ - int8_t MaxTxPower; - }RegionCommonLinkAdrReqVerifyParams_t; - - typedef struct sRegionCommonCalcBackOffParams - { - /*! - * A pointer to region specific channels. - */ - channel_params_t* Channels; - /*! - * A pointer to region specific bands. - */ - band_t* Bands; - /*! - * Set to true, if the last uplink was a join request. - */ - bool LastTxIsJoinRequest; - /*! - * Set to true, if the node is joined. - */ - bool Joined; - /*! - * Set to true, if the duty cycle is enabled. - */ - bool DutyCycleEnabled; - /*! - * The current channel. - */ - uint8_t Channel; - /*! - * The elapsed time since initialization. - */ - lorawan_time_t ElapsedTime; - /*! - * The time on air of the last TX frame. - */ - lorawan_time_t TxTimeOnAir; - }RegionCommonCalcBackOffParams_t; - - /*! - * \brief Calculates the join duty cycle. - * This is a generic function and valid for all regions. - * - * \param [in] elapsedTime The time elapsed since starting the device. - * - * \retval Duty cycle restriction. + /** + * Verifies the given frequency. */ - uint16_t get_join_DC( lorawan_time_t elapsedTime ); + virtual bool verify_frequency(uint32_t freq); - /*! - * \brief Verifies, if a value is in a given range. - * This is a generic function and valid for all regions. - * - * \param [in] value The value to verify, if it is in range. - * - * \param [in] min The minimum possible value. - * - * \param [in] max The maximum possible value. - * - * \retval 1 if the value is in range, otherwise 0. + + /** + * Verifies, if a value is in a given range. */ - uint8_t val_in_range( int8_t value, int8_t min, int8_t max ); + uint8_t val_in_range(int8_t value, int8_t min, int8_t max); - /*! - * \brief Verifies, if a datarate is available on an active channel. - * This is a generic function and valid for all regions. - * - * \param [in] nbChannels The number of channels. - * - * \param [in] channelsMask The channels mask of the region. - * - * \param [in] dr The datarate to verify. - * - * \param [in] minDr The minimum datarate. - * - * \param [in] maxDr The maximum datarate. - * - * \param [in] channels The channels of the region. - * - * \retval True if the datarate is supported, false if not. + /** + * Verifies, if a datarate is available on an active channel. */ - bool verify_channel_DR( uint8_t nbChannels, uint16_t* channelsMask, int8_t dr, - int8_t minDr, int8_t maxDr, channel_params_t* channels ); + bool verify_channel_DR(uint8_t nbChannels, uint16_t* channelsMask, int8_t dr, + int8_t minDr, int8_t maxDr, channel_params_t* channels ); - /*! - * \brief Disables a channel in a given channels mask. - * This is a generic function and valid for all regions. - * - * \param [in] channelsMask The channels mask of the region. - * - * \param [in] id The ID of the channels mask to disable. - * - * \param [in] maxChannels The maximum number of channels. - * - * \retval True if the channel could be disabled, false if not. + /** + * Disables a channel in a given channels mask. */ bool disable_channel( uint16_t* channelsMask, uint8_t id, uint8_t maxChannels ); - /*! - * \brief Counts the number of active channels in a given channels mask. - * This is a generic function and valid for all regions. - * - * \param [in] channelsMask The channels mask of the region. - * - * \param [in] startIdx The start index. - * - * \param [in] stopIdx The stop index (the channels of this index will not be counted). - * - * \retval The number of active channels. + /** + * Counts number of bits on in a given mask */ - uint8_t num_active_channels( uint16_t* channelsMask, uint8_t startIdx, uint8_t stopIdx ); + uint8_t count_bits(uint16_t mask, uint8_t nbBits); - /*! - * \brief Copy a channels mask. - * This is a generic function and valid for all regions. - * - * \param [in] channelsMaskDest The destination channels mask. - * - * \param [in] channelsMaskSrc The source channels mask. - * - * \param [in] len The index length to copy. + /** + * Counts the number of active channels in a given channels mask. */ - void copy_channel_mask( uint16_t* channelsMaskDest, uint16_t* channelsMaskSrc, uint8_t len ); + uint8_t num_active_channels(uint16_t* channelsMask, uint8_t startIdx, + uint8_t stopIdx); - /*! - * \brief Sets the last TX done property. - * This is a generic function and valid for all regions. - * - * \param [in] joined Set to true, if the node has joined the network - * - * \param [in] band The band to be updated. - * - * \param [in] lastTxDone The time of the last TX done. + /** + * Copy channel masks. */ - void set_last_tx_done( bool joined, band_t* band, lorawan_time_t lastTxDone ); + void copy_channel_mask(uint16_t* channelsMaskDest, uint16_t* channelsMaskSrc, + uint8_t len ); - /*! - * \brief Updates the time-offs of the bands. - * This is a generic function and valid for all regions. - * - * \param [in] joined Set to true, if the node has joined the network - * - * \param [in] dutyCycle Set to true, if the duty cycle is enabled. - * - * \param [in] bands A pointer to the bands. - * - * \param [in] nbBands The number of bands available. - * - * \retval The time which must be waited to perform the next uplink. + /** + * Updates the time-offs of the bands. */ - lorawan_time_t update_band_timeoff( bool joined, bool dutyCycle, band_t* bands, uint8_t nbBands ); + lorawan_time_t update_band_timeoff(bool joined, bool dutyCycle, band_t* bands, + uint8_t nbBands); - /*! - * \brief Parses the parameter of an LinkAdrRequest. - * This is a generic function and valid for all regions. - * - * \param [in] payload A pointer to the payload containing the MAC commands. The payload - * must contain the CMD identifier, followed by the parameters. - * - * \param [out] parseLinkAdr The function fills the structure with the ADR parameters. - * - * \retval The length of the ADR request, if a request was found. Otherwise, the - * function returns 0. + /** + * Parses the parameter of an LinkAdrRequest. */ - uint8_t parse_link_ADR_req( uint8_t* payload, RegionCommonLinkAdrParams_t* parseLinkAdr ); + uint8_t parse_link_ADR_req(uint8_t* payload, link_adr_params_t* parseLinkAdr ); - /*! - * \brief Verifies and updates the datarate, the TX power and the number of repetitions - * of a LinkAdrRequest. This also depends on the ADR configuration. - * - * \param [in] verifyParams A pointer to a structure containing the input parameters. - * - * \param [out] dr The updated datarate. - * - * \param [out] txPow The updated TX power. - * - * \param [out] nbRep The updated number of repetitions. - * - * \retval The status according to the LinkAdrRequest definition. + /** + * Verifies and updates the datarate, the TX power and the number of repetitions + * of a LinkAdrRequest. */ - uint8_t verify_link_ADR_req( RegionCommonLinkAdrReqVerifyParams_t* verifyParams, int8_t* dr, int8_t* txPow, uint8_t* nbRep ); + uint8_t verify_link_ADR_req( verify_adr_params_t* verifyParams, int8_t* dr, int8_t* txPow, uint8_t* nbRep ); - /*! - * \brief Computes the symbol time for LoRa modulation. - * - * \param [in] phyDr The physical datarate to use. - * - * \param [in] bandwidth The bandwidth to use. - * - * \retval The symbol time. + /** + * Computes the symbol time for LoRa modulation. */ double compute_symb_timeout_lora( uint8_t phyDr, uint32_t bandwidth ); - /*! - * \brief Computes the symbol time for FSK modulation. - * - * \param [in] phyDr The physical datarate to use. - * - * \retval The symbol time. + /** + * Computes the symbol time for FSK modulation. */ double compute_symb_timeout_fsk( uint8_t phyDr ); - /*! - * \brief Computes the RX window timeout and the RX window offset. - * - * \param [in] tSymbol The symbol timeout. - * - * \param [in] minRxSymbols The minimum required number of symbols to detect an RX frame. - * - * \param [in] rxError The system maximum timing error of the receiver in milliseconds - * The receiver will turn on in a [-rxError : +rxError] ms interval around RxOffset. - * - * \param [in] wakeUpTime The wakeup time of the system. - * - * \param [out] windowTimeout The RX window timeout. - * - * \param [out] windowOffset The RX window time offset to be applied to the RX delay. + /** + * Computes the RX window timeout and the RX window offset. */ void get_rx_window_params( double tSymbol, uint8_t minRxSymbols, uint32_t rxError, uint32_t wakeUpTime, uint32_t* windowTimeout, int32_t* windowOffset ); - /*! - * \brief Computes the txPower, based on the max EIRP and the antenna gain. - * - * \param [in] txPowerIndex The TX power index. - * - * \param [in] maxEirp The maximum EIRP. - * - * \param [in] antennaGain The antenna gain. - * - * \retval The physical TX power. + /** + * Computes the txPower, based on the max EIRP and the antenna gain. */ int8_t compute_tx_power( int8_t txPowerIndex, float maxEirp, float antennaGain ); - /*! - * \brief Provides a random number in the range provided. - * - * \param [in] min lower boundary - * \param [in] max upper boundary + /** + * Provides a random number in the range provided. */ int32_t get_random(int32_t min, int32_t max); - /*! - * \brief Calculates the duty cycle for the current band. - * - * \param [in] calcBackOffParams A pointer to the input parameters. + /** + * Get next lower data rate */ - void get_DC_backoff( RegionCommonCalcBackOffParams_t* calcBackOffParams ); + int8_t get_next_lower_dr(int8_t dr, int8_t min_dr); + + /** + * Get channel bandwidth depending upon data rate table index + */ + uint8_t get_bandwidth(uint8_t dr_index); + + uint8_t enabled_channel_count(bool joined, uint8_t datarate, + uint16_t *mask_list, uint8_t mask_list_size, + uint8_t* enabledChannels, + uint8_t* delayTx); }; + + #endif /* MBED_OS_LORAPHY_BASE_ */ diff --git a/features/lorawan/lorastack/phy/LoRaPHYAS923.cpp b/features/lorawan/lorastack/phy/LoRaPHYAS923.cpp index c00119dcbd..f871b1ebcd 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYAS923.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYAS923.cpp @@ -31,8 +31,6 @@ #include "LoRaPHYAS923.h" #include "lora_phy_ds.h" -#include "LoRaRadio.h" - /*! * Number of default channels @@ -69,6 +67,8 @@ */ #define AS923_DEFAULT_DATARATE DR_2 +#define AS923_DEFAULT_MAX_DATARATE DR_7 + /*! * The minimum datarate which is used when the * dwell time is limited. @@ -105,16 +105,6 @@ */ #define AS923_DEFAULT_TX_POWER TX_POWER_0 -/*! - * Default uplink dwell time configuration - */ -#define AS923_DEFAULT_UPLINK_DWELL_TIME 1 - -/*! - * Default downlink dwell time configuration - */ -#define AS923_DEFAULT_DOWNLINK_DWELL_TIME 1 - /*! * Default Max EIRP */ @@ -198,19 +188,19 @@ * Band 0 definition * { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff } */ -#define AS923_BAND0 { 100, AS923_MAX_TX_POWER, 0, 0, 0 } // 1.0 % +static const band_t AS923_BAND0 = {100, AS923_MAX_TX_POWER, 0, 0, 0, 923000000, 928000000}; // 1.0 % /*! * LoRaMac default channel 1 * Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } */ -#define AS923_LC1 { 923200000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } +static const channel_params_t AS923_LC1 = { 923200000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }; /*! * LoRaMac default channel 2 * Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } */ -#define AS923_LC2 { 923400000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } +static const channel_params_t AS923_LC2 = { 923400000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }; /*! * LoRaMac channels which are allowed for the join procedure @@ -230,1110 +220,206 @@ /*! * Data rates table definition */ -static const uint8_t DataratesAS923[] = { 12, 11, 10, 9, 8, 7, 7, 50 }; +static const uint8_t datarates_AS923[] = {12, 11, 10, 9, 8, 7, 7, 50}; /*! * Bandwidths table definition in Hz */ -static const uint32_t BandwidthsAS923[] = { 125000, 125000, 125000, 125000, 125000, 125000, 250000, 0 }; +static const uint32_t bandwidths_AS923[] = {125000, 125000, 125000, 125000, 125000, 125000, 250000, 0}; -/*! - * Maximum payload with respect to the datarate index. Cannot operate with repeater. - * The table is valid for the dwell time configuration of 0 for uplinks and downlinks. - */ -static const uint8_t MaxPayloadOfDatarateDwell0AS923[] = { 51, 51, 51, 115, 242, 242, 242, 242 }; - -/*! - * Maximum payload with respect to the datarate index. Can operate with repeater. - * The table is valid for the dwell time configuration of 0 for uplinks and downlinks. The table provides - * repeater support. - */ -static const uint8_t MaxPayloadOfDatarateRepeaterDwell0AS923[] = { 51, 51, 51, 115, 222, 222, 222, 222 }; - -/*! - * Maximum payload with respect to the datarate index. Can operate with and without repeater. - * The table proides repeater support. The table is only valid for uplinks. - */ -static const uint8_t MaxPayloadOfDatarateDwell1UpAS923[] = { 0, 0, 11, 53, 125, 242, 242, 242 }; - -/*! - * Maximum payload with respect to the datarate index. Can operate with and without repeater. - * The table proides repeater support. The table is only valid for downlinks. - */ -static const uint8_t MaxPayloadOfDatarateDwell1DownAS923[] = { 0, 0, 11, 53, 126, 242, 242, 242 }; +#if (MBED_CONF_LORA_DWELL_TIME == 0) + static const uint8_t max_payload_table[] = {51, 51, 51, 115, 242, 242, 242, 242}; + static const uint8_t max_payload_table_with_repeater[] = {51, 51, 51, 115, 222, 222, 222, 222}; +#else + // this is the default, i.e., + static const uint8_t max_payload_table[] = {0, 0, 11, 53, 125, 242, 242, 242}; + static const uint8_t max_payload_table_with_repeater[] = {0, 0, 11, 53, 125, 242, 242, 242}; +#endif /*! * Effective datarate offsets for receive window 1. */ -static const int8_t EffectiveRx1DrOffsetAS923[] = { 0, 1, 2, 3, 4, 5, -1, -2 }; - - -// Static functions -static int8_t GetNextLowerTxDr( int8_t dr, int8_t minDr ) -{ - uint8_t nextLowerDr = 0; - - if( dr == minDr ) - { - nextLowerDr = minDr; - } - else - { - nextLowerDr = dr - 1; - } - return nextLowerDr; -} - -static uint32_t GetBandwidth( uint32_t drIndex ) -{ - switch( BandwidthsAS923[drIndex] ) - { - default: - case 125000: - return 0; - case 250000: - return 1; - case 500000: - return 2; - } -} - -static int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower, int8_t datarate, uint16_t* channelsMask ) -{ - int8_t txPowerResult = txPower; - - // Limit tx power to the band max - txPowerResult = MAX( txPower, maxBandTxPower ); - - return txPowerResult; -} - -static bool VerifyTxFreq( uint32_t freq ) -{ - // Not checking the radio drivers here as all radio drivers - // always return true. Just check for Asia-Pacific band here - if( ( freq < 915000000 ) || ( freq > 928000000 ) ) - { - return false; - } - return true; -} - -uint8_t LoRaPHYAS923::CountNbOfEnabledChannels(bool joined, uint8_t datarate, - uint16_t* channelsMask, - channel_params_t* channels, band_t* bands, - uint8_t* enabledChannels, uint8_t* delayTx) -{ - uint8_t nbEnabledChannels = 0; - uint8_t delayTransmission = 0; - - for( uint8_t i = 0, k = 0; i < AS923_MAX_NB_CHANNELS; i += 16, k++ ) - { - for( uint8_t j = 0; j < 16; j++ ) - { - if( ( channelsMask[k] & ( 1 << j ) ) != 0 ) - { - if( channels[i + j].frequency == 0 ) - { // Check if the channel is enabled - continue; - } - if( joined == false ) - { - if( ( AS923_JOIN_CHANNELS & ( 1 << j ) ) == 0 ) - { - continue; - } - } - if( val_in_range( datarate, channels[i + j].dr_range.fields.min, - channels[i + j].dr_range.fields.max ) == 0 ) - { // Check if the current channel selection supports the given datarate - continue; - } - if( bands[channels[i + j].band].off_time > 0 ) - { // Check if the band is available for transmission - delayTransmission++; - continue; - } - enabledChannels[nbEnabledChannels++] = i + j; - } - } - } - - *delayTx = delayTransmission; - return nbEnabledChannels; -} +static const int8_t rx1_dr_offset_AS923[] = {0, 1, 2, 3, 4, 5, -1, -2}; LoRaPHYAS923::LoRaPHYAS923(LoRaWANTimeHandler &lora_time) : LoRaPHY(lora_time) { - const band_t band0 = AS923_BAND0; - Bands[0] = band0; + bands[0] = AS923_BAND0; + + // Default Channels are always enabled in the channel list, + // rest will be added later + channels[0] = AS923_LC1; + channels[1] = AS923_LC2; + + // Initialize the default channel mask + default_channel_masks[0] = LC(1) + LC(2); + + // Update the channel mask list + copy_channel_mask(channel_masks, default_channel_masks, AS923_CHANNELS_MASK_SIZE); + + // set default channels + phy_params.channels.channel_list = channels; + phy_params.channels.channel_list_size = AS923_MAX_NB_CHANNELS; + phy_params.channels.mask_list = channel_masks; + phy_params.channels.default_mask_list = default_channel_masks; + phy_params.channels.mask_list_size = AS923_CHANNELS_MASK_SIZE; + + // set bands for AS923 spectrum + phy_params.bands.table = (void *) bands; + phy_params.bands.size = AS923_MAX_NB_BANDS; + + // set bandwidths available in AS923 spectrum + phy_params.bandwidths.table = (void *) bandwidths_AS923; + phy_params.bandwidths.size = 8; + + // set data rates available in AS923 spectrum + phy_params.datarates.table = (void *) datarates_AS923; + phy_params.datarates.size = 8; + + // set payload sizes with respect to data rates + phy_params.payloads.table = (void *) max_payload_table; + phy_params.payloads.size = 8; + phy_params.payloads_with_repeater.table = (void *) max_payload_table_with_repeater; + phy_params.payloads.size = 8; + + // dwell time setting, 400 ms + phy_params.ul_dwell_time_setting = 1; + phy_params.dl_dwell_time_setting = 1; + phy_params.dwell_limit_datarate = AS923_DWELL_LIMIT_DATARATE; + + phy_params.duty_cycle_enabled = AS923_DUTY_CYCLE_ENABLED; + phy_params.accept_tx_param_setup_req = true; + phy_params.fsk_supported = true; + phy_params.cflist_supported = true; + + phy_params.default_channel_cnt = AS923_NUMB_DEFAULT_CHANNELS; + phy_params.max_channel_cnt = AS923_MAX_NB_CHANNELS; + phy_params.cflist_channel_cnt = AS923_NUMB_CHANNELS_CF_LIST; + phy_params.min_tx_datarate = AS923_TX_MIN_DATARATE; + phy_params.max_tx_datarate = AS923_TX_MAX_DATARATE; + phy_params.min_rx_datarate = AS923_RX_MIN_DATARATE; + phy_params.max_rx_datarate = AS923_RX_MAX_DATARATE; + phy_params.default_datarate = AS923_DEFAULT_DATARATE; + phy_params.default_max_datarate = AS923_DEFAULT_MAX_DATARATE; + phy_params.min_rx1_dr_offset = AS923_MIN_RX1_DR_OFFSET; + phy_params.max_rx1_dr_offset = AS923_MAX_RX1_DR_OFFSET; + phy_params.default_rx1_dr_offset = AS923_DEFAULT_RX1_DR_OFFSET; + phy_params.min_tx_power = AS923_MIN_TX_POWER; + phy_params.max_tx_power = AS923_MAX_TX_POWER; + phy_params.default_tx_power = AS923_DEFAULT_TX_POWER; + phy_params.default_max_eirp = AS923_DEFAULT_MAX_EIRP; + phy_params.default_antenna_gain = AS923_DEFAULT_ANTENNA_GAIN; + phy_params.adr_ack_limit = AS923_ADR_ACK_LIMIT; + phy_params.adr_ack_delay = AS923_ADR_ACK_DELAY; + phy_params.max_rx_window = AS923_MAX_RX_WINDOW; + phy_params.recv_delay1 = AS923_RECEIVE_DELAY1; + phy_params.recv_delay2 = AS923_RECEIVE_DELAY2; + phy_params.join_channel_mask = AS923_JOIN_CHANNELS; + phy_params.join_accept_delay1 = AS923_JOIN_ACCEPT_DELAY1; + phy_params.join_accept_delay2 = AS923_JOIN_ACCEPT_DELAY2; + phy_params.max_fcnt_gap = AS923_MAX_FCNT_GAP; + phy_params.ack_timeout = AS923_ACKTIMEOUT; + phy_params.ack_timeout_rnd = AS923_ACK_TIMEOUT_RND; + phy_params.rx_window2_datarate = AS923_RX_WND_2_DR; + phy_params.rx_window2_frequency = AS923_RX_WND_2_FREQ; } LoRaPHYAS923::~LoRaPHYAS923() { } -PhyParam_t LoRaPHYAS923::get_phy_params(GetPhyParams_t* getPhy) -{ - PhyParam_t phyParam = { 0 }; - - switch( getPhy->Attribute ) - { - case PHY_MIN_RX_DR: - { - if( getPhy->DownlinkDwellTime == 0 ) - { - phyParam.Value = AS923_RX_MIN_DATARATE; - } - else - { - phyParam.Value = AS923_DWELL_LIMIT_DATARATE; - } - break; - } - case PHY_MIN_TX_DR: - { - if( getPhy->UplinkDwellTime == 0 ) - { - phyParam.Value = AS923_TX_MIN_DATARATE; - } - else - { - phyParam.Value = AS923_DWELL_LIMIT_DATARATE; - } - break; - } - case PHY_DEF_TX_DR: - { - phyParam.Value = AS923_DEFAULT_DATARATE; - break; - } - case PHY_NEXT_LOWER_TX_DR: - { - if( getPhy->UplinkDwellTime == 0 ) - { - phyParam.Value = GetNextLowerTxDr( getPhy->Datarate, AS923_TX_MIN_DATARATE ); - } - else - { - phyParam.Value = GetNextLowerTxDr( getPhy->Datarate, AS923_DWELL_LIMIT_DATARATE ); - } - break; - } - case PHY_DEF_TX_POWER: - { - phyParam.Value = AS923_DEFAULT_TX_POWER; - break; - } - case PHY_MAX_PAYLOAD: - { - if( getPhy->UplinkDwellTime == 0 ) - { - phyParam.Value = MaxPayloadOfDatarateDwell0AS923[getPhy->Datarate]; - } - else - { - phyParam.Value = MaxPayloadOfDatarateDwell1UpAS923[getPhy->Datarate]; - } - break; - } - case PHY_MAX_PAYLOAD_REPEATER: - { - if( getPhy->UplinkDwellTime == 0 ) - { - phyParam.Value = MaxPayloadOfDatarateRepeaterDwell0AS923[getPhy->Datarate]; - } - else - { - phyParam.Value = MaxPayloadOfDatarateDwell1UpAS923[getPhy->Datarate]; - } - break; - } - case PHY_DUTY_CYCLE: - { - phyParam.Value = AS923_DUTY_CYCLE_ENABLED; - break; - } - case PHY_MAX_RX_WINDOW: - { - phyParam.Value = AS923_MAX_RX_WINDOW; - break; - } - case PHY_RECEIVE_DELAY1: - { - phyParam.Value = AS923_RECEIVE_DELAY1; - break; - } - case PHY_RECEIVE_DELAY2: - { - phyParam.Value = AS923_RECEIVE_DELAY2; - break; - } - case PHY_JOIN_ACCEPT_DELAY1: - { - phyParam.Value = AS923_JOIN_ACCEPT_DELAY1; - break; - } - case PHY_JOIN_ACCEPT_DELAY2: - { - phyParam.Value = AS923_JOIN_ACCEPT_DELAY2; - break; - } - case PHY_MAX_FCNT_GAP: - { - phyParam.Value = AS923_MAX_FCNT_GAP; - break; - } - case PHY_ACK_TIMEOUT: - { - phyParam.Value = ( AS923_ACKTIMEOUT + get_random( -AS923_ACK_TIMEOUT_RND, AS923_ACK_TIMEOUT_RND ) ); - break; - } - case PHY_DEF_DR1_OFFSET: - { - phyParam.Value = AS923_DEFAULT_RX1_DR_OFFSET; - break; - } - case PHY_DEF_RX2_FREQUENCY: - { - phyParam.Value = AS923_RX_WND_2_FREQ; - break; - } - case PHY_DEF_RX2_DR: - { - phyParam.Value = AS923_RX_WND_2_DR; - break; - } - case PHY_CHANNELS_MASK: - { - phyParam.ChannelsMask = ChannelsMask; - break; - } - case PHY_CHANNELS_DEFAULT_MASK: - { - phyParam.ChannelsMask = ChannelsDefaultMask; - break; - } - case PHY_MAX_NB_CHANNELS: - { - phyParam.Value = AS923_MAX_NB_CHANNELS; - break; - } - case PHY_CHANNELS: - { - phyParam.Channels = Channels; - break; - } - case PHY_DEF_UPLINK_DWELL_TIME: - { - phyParam.Value = AS923_DEFAULT_UPLINK_DWELL_TIME; - break; - } - case PHY_DEF_DOWNLINK_DWELL_TIME: - { - phyParam.Value = AS923_DEFAULT_DOWNLINK_DWELL_TIME; - break; - } - case PHY_DEF_MAX_EIRP: - { - phyParam.fValue = AS923_DEFAULT_MAX_EIRP; - break; - } - case PHY_DEF_ANTENNA_GAIN: - { - phyParam.fValue = AS923_DEFAULT_ANTENNA_GAIN; - break; - } - case PHY_NB_JOIN_TRIALS: - case PHY_DEF_NB_JOIN_TRIALS: - { - phyParam.Value = 1; - break; - } - default: - { - break; - } - } - - return phyParam; -} - -void LoRaPHYAS923::set_band_tx_done(SetBandTxDoneParams_t* txDone) -{ - set_last_tx_done( txDone->Joined, &Bands[Channels[txDone->Channel].band], txDone->LastTxDoneTime ); -} - -void LoRaPHYAS923::load_defaults(InitType_t type) -{ - switch( type ) - { - case INIT_TYPE_INIT: - { - // Channels - const channel_params_t channel1 = AS923_LC1; - const channel_params_t channel2 = AS923_LC2; - Channels[0] = channel1; - Channels[1] = channel2; - - // Initialize the channels default mask - ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ); - // Update the channels mask - copy_channel_mask( ChannelsMask, ChannelsDefaultMask, 1 ); - break; - } - case INIT_TYPE_RESTORE: - { - // Restore channels default mask - ChannelsMask[0] |= ChannelsDefaultMask[0]; - break; - } - default: - { - break; - } - } -} - -bool LoRaPHYAS923::verify(VerifyParams_t* verify, PhyAttribute_t phyAttribute) -{ - switch( phyAttribute ) - { - case PHY_TX_DR: - { - if( verify->DatarateParams.UplinkDwellTime == 0 ) - { - return val_in_range( verify->DatarateParams.Datarate, AS923_TX_MIN_DATARATE, AS923_TX_MAX_DATARATE ); - } - else - { - return val_in_range( verify->DatarateParams.Datarate, AS923_DWELL_LIMIT_DATARATE, AS923_TX_MAX_DATARATE ); - } - } - case PHY_DEF_TX_DR: - { - return val_in_range( verify->DatarateParams.Datarate, DR_0, DR_5 ); - } - case PHY_RX_DR: - { - if( verify->DatarateParams.DownlinkDwellTime == 0 ) - { - return val_in_range( verify->DatarateParams.Datarate, AS923_RX_MIN_DATARATE, AS923_RX_MAX_DATARATE ); - } - else - { - return val_in_range( verify->DatarateParams.Datarate, AS923_DWELL_LIMIT_DATARATE, AS923_RX_MAX_DATARATE ); - } - } - case PHY_DEF_TX_POWER: - case PHY_TX_POWER: - { - // Remark: switched min and max! - return val_in_range( verify->TxPower, AS923_MAX_TX_POWER, AS923_MIN_TX_POWER ); - } - case PHY_DUTY_CYCLE: - { - return AS923_DUTY_CYCLE_ENABLED; - } - case PHY_NB_JOIN_TRIALS: - { - return true; - } - default: - return false; - } -} - -void LoRaPHYAS923::apply_cf_list(ApplyCFListParams_t* applyCFList) -{ - channel_params_t newChannel; - ChannelAddParams_t channelAdd; - ChannelRemoveParams_t channelRemove; - - // Setup default datarate range - newChannel.dr_range.value = ( DR_5 << 4 ) | DR_0; - - // Size of the optional CF list - if( applyCFList->Size != 16 ) - { - return; - } - - // Last byte is RFU, don't take it into account - for( uint8_t i = 0, chanIdx = AS923_NUMB_DEFAULT_CHANNELS; chanIdx < AS923_MAX_NB_CHANNELS; i+=3, chanIdx++ ) - { - if( chanIdx < ( AS923_NUMB_CHANNELS_CF_LIST + AS923_NUMB_DEFAULT_CHANNELS ) ) - { - // Channel frequency - newChannel.frequency = (uint32_t) applyCFList->Payload[i]; - newChannel.frequency |= ( (uint32_t) applyCFList->Payload[i + 1] << 8 ); - newChannel.frequency |= ( (uint32_t) applyCFList->Payload[i + 2] << 16 ); - newChannel.frequency *= 100; - - // Initialize alternative frequency to 0 - newChannel.rx1_frequency = 0; - } - else - { - newChannel.frequency = 0; - newChannel.dr_range.value = 0; - newChannel.rx1_frequency = 0; - } - - if( newChannel.frequency != 0 ) - { - channelAdd.NewChannel = &newChannel; - channelAdd.ChannelId = chanIdx; - - // Try to add all channels - add_channel(&channelAdd); - } - else - { - channelRemove.ChannelId = chanIdx; - - remove_channel(&channelRemove); - } - } -} - -bool LoRaPHYAS923::set_channel_mask(ChanMaskSetParams_t* chanMaskSet) -{ - switch( chanMaskSet->ChannelsMaskType ) - { - case CHANNELS_MASK: - { - copy_channel_mask( ChannelsMask, chanMaskSet->ChannelsMaskIn, 1 ); - break; - } - case CHANNELS_DEFAULT_MASK: - { - copy_channel_mask( ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 1 ); - break; - } - default: - return false; - } - return true; -} - -bool LoRaPHYAS923::get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut, - int8_t* txPowOut, uint32_t* adrAckCounter) -{ - bool adrAckReq = false; - int8_t datarate = adrNext->Datarate; - int8_t minTxDatarate = 0; - int8_t txPower = adrNext->TxPower; - GetPhyParams_t getPhy; - PhyParam_t phyParam; - - // Get the minimum possible datarate - getPhy.Attribute = PHY_MIN_TX_DR; - getPhy.UplinkDwellTime = adrNext->UplinkDwellTime; - phyParam = get_phy_params(&getPhy); - minTxDatarate = phyParam.Value; - - // Report back the adr ack counter - *adrAckCounter = adrNext->AdrAckCounter; - - // Apply the minimum possible datarate. - datarate = MAX( datarate, minTxDatarate ); - - if( adrNext->AdrEnabled == true ) - { - if( datarate == minTxDatarate ) - { - *adrAckCounter = 0; - adrAckReq = false; - } - else - { - if( adrNext->AdrAckCounter >= AS923_ADR_ACK_LIMIT ) - { - adrAckReq = true; - txPower = AS923_MAX_TX_POWER; - } - else - { - adrAckReq = false; - } - if( adrNext->AdrAckCounter >= ( AS923_ADR_ACK_LIMIT + AS923_ADR_ACK_DELAY ) ) - { - if( ( adrNext->AdrAckCounter % AS923_ADR_ACK_DELAY ) == 1 ) - { - // Decrease the datarate - getPhy.Attribute = PHY_NEXT_LOWER_TX_DR; - getPhy.Datarate = datarate; - getPhy.UplinkDwellTime = adrNext->UplinkDwellTime; - phyParam = get_phy_params(&getPhy); - datarate = phyParam.Value; - - if( datarate == minTxDatarate ) - { - // We must set adrAckReq to false as soon as we reach the lowest datarate - adrAckReq = false; - if( adrNext->UpdateChanMask == true ) - { - // Re-enable default channels - ChannelsMask[0] |= LC( 1 ) + LC( 2 ); - } - } - } - } - } - } - - *drOut = datarate; - *txPowOut = txPower; - return adrAckReq; -} - -void LoRaPHYAS923::compute_rx_win_params(int8_t datarate, uint8_t minRxSymbols, - uint32_t rxError, - rx_config_params_t *rxConfigParams) -{ - double tSymbol = 0.0; - - // Get the datarate, perform a boundary check - rxConfigParams->datarate = MIN( datarate, AS923_RX_MAX_DATARATE ); - rxConfigParams->bandwidth = GetBandwidth( rxConfigParams->datarate ); - - if( rxConfigParams->datarate == DR_7 ) - { // FSK - tSymbol = compute_symb_timeout_fsk( DataratesAS923[rxConfigParams->datarate] ); - } - else - { // LoRa - tSymbol = compute_symb_timeout_lora( DataratesAS923[rxConfigParams->datarate], BandwidthsAS923[rxConfigParams->datarate] ); - } - - get_rx_window_params( tSymbol, minRxSymbols, rxError, RADIO_WAKEUP_TIME, &rxConfigParams->window_timeout, &rxConfigParams->window_offset ); -} - -bool LoRaPHYAS923::rx_config(rx_config_params_t* rxConfig, int8_t* datarate) -{ - radio_modems_t modem; - int8_t dr = rxConfig->datarate; - uint8_t maxPayload = 0; - int8_t phyDr = 0; - uint32_t frequency = rxConfig->frequency; - - if( _radio->get_status() != RF_IDLE ) - { - return false; - } - - if( rxConfig->rx_slot == RX_SLOT_WIN_1 ) - { - // Apply window 1 frequency - frequency = Channels[rxConfig->channel].frequency; - // Apply the alternative RX 1 window frequency, if it is available - if( Channels[rxConfig->channel].rx1_frequency != 0 ) - { - frequency = Channels[rxConfig->channel].rx1_frequency; - } - } - - // Read the physical datarate from the datarates table - phyDr = DataratesAS923[dr]; - - _radio->set_channel(frequency); - - // Radio configuration - if( dr == DR_7 ) - { - modem = MODEM_FSK; - _radio->set_rx_config(modem, 50000, phyDr * 1000, 0, 83333, 5, - rxConfig->window_timeout, false, 0, true, 0, - 0, false, rxConfig->is_rx_continuous); - } - else - { - modem = MODEM_LORA; - _radio->set_rx_config(modem, rxConfig->bandwidth, phyDr, 1, 0, 8, - rxConfig->window_timeout, false, 0, false, 0, 0, - true, rxConfig->is_rx_continuous); - } - - // Check for repeater support - if( rxConfig->is_repeater_supported == true ) - { - maxPayload = MaxPayloadOfDatarateRepeaterDwell0AS923[dr]; - } - else - { - maxPayload = MaxPayloadOfDatarateDwell0AS923[dr]; - } - - _radio->set_max_payload_length(modem, maxPayload + LORA_MAC_FRMPAYLOAD_OVERHEAD); - - *datarate = (uint8_t) dr; - return true; -} - -bool LoRaPHYAS923::tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - lorawan_time_t* txTimeOnAir) -{ - radio_modems_t modem; - int8_t phyDr = DataratesAS923[txConfig->Datarate]; - int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, Bands[Channels[txConfig->Channel].band].max_tx_pwr, txConfig->Datarate, ChannelsMask ); - uint32_t bandwidth = GetBandwidth( txConfig->Datarate ); - int8_t phyTxPower = 0; - - // Calculate physical TX power - phyTxPower = compute_tx_power( txPowerLimited, txConfig->MaxEirp, txConfig->AntennaGain ); - - // Setup the radio frequency - _radio->set_channel(Channels[txConfig->Channel].frequency); - - if( txConfig->Datarate == DR_7 ) - { // High Speed FSK channel - modem = MODEM_FSK; - _radio->set_tx_config(modem, phyTxPower, 25000, bandwidth, phyDr * 1000, - 0, 5, false, true, 0, 0, false, 3000 ); - } - else - { - modem = MODEM_LORA; - _radio->set_tx_config(modem, phyTxPower, 0, bandwidth, phyDr, 1, 8, - false, true, 0, 0, false, 3000); - } - - // Setup maximum payload lenght of the radio driver - _radio->set_max_payload_length(modem, txConfig->PktLen); - // Get the time-on-air of the next tx frame - *txTimeOnAir = _radio->time_on_air(modem, txConfig->PktLen); - - *txPower = txPowerLimited; - return true; -} - -uint8_t LoRaPHYAS923::link_ADR_request(LinkAdrReqParams_t* linkAdrReq, - int8_t* drOut, int8_t* txPowOut, - uint8_t* nbRepOut, uint8_t* nbBytesParsed) -{ - uint8_t status = 0x07; - RegionCommonLinkAdrParams_t linkAdrParams; - uint8_t nextIndex = 0; - uint8_t bytesProcessed = 0; - uint16_t chMask = 0; - GetPhyParams_t getPhy; - PhyParam_t phyParam; - RegionCommonLinkAdrReqVerifyParams_t linkAdrVerifyParams; - - while( bytesProcessed < linkAdrReq->PayloadSize ) - { - // Get ADR request parameters - nextIndex = parse_link_ADR_req( &( linkAdrReq->Payload[bytesProcessed] ), &linkAdrParams ); - - if( nextIndex == 0 ) - break; // break loop, since no more request has been found - - // Update bytes processed - bytesProcessed += nextIndex; - - // Revert status, as we only check the last ADR request for the channel mask KO - status = 0x07; - - // Setup temporary channels mask - chMask = linkAdrParams.ChMask; - - // Verify channels mask - if( ( linkAdrParams.ChMaskCtrl == 0 ) && ( chMask == 0 ) ) - { - status &= 0xFE; // Channel mask KO - } - else if( ( ( linkAdrParams.ChMaskCtrl >= 1 ) && ( linkAdrParams.ChMaskCtrl <= 5 )) || - ( linkAdrParams.ChMaskCtrl >= 7 ) ) - { - // RFU - status &= 0xFE; // Channel mask KO - } - else - { - for( uint8_t i = 0; i < AS923_MAX_NB_CHANNELS; i++ ) - { - if( linkAdrParams.ChMaskCtrl == 6 ) - { - if( Channels[i].frequency != 0 ) - { - chMask |= 1 << i; - } - } - else - { - if( ( ( chMask & ( 1 << i ) ) != 0 ) && - ( Channels[i].frequency == 0 ) ) - {// Trying to enable an undefined channel - status &= 0xFE; // Channel mask KO - } - } - } - } - } - - // Get the minimum possible datarate - getPhy.Attribute = PHY_MIN_TX_DR; - getPhy.UplinkDwellTime = linkAdrReq->UplinkDwellTime; - phyParam = get_phy_params(&getPhy); - - linkAdrVerifyParams.Status = status; - linkAdrVerifyParams.AdrEnabled = linkAdrReq->AdrEnabled; - linkAdrVerifyParams.Datarate = linkAdrParams.Datarate; - linkAdrVerifyParams.TxPower = linkAdrParams.TxPower; - linkAdrVerifyParams.NbRep = linkAdrParams.NbRep; - linkAdrVerifyParams.CurrentDatarate = linkAdrReq->CurrentDatarate; - linkAdrVerifyParams.CurrentTxPower = linkAdrReq->CurrentTxPower; - linkAdrVerifyParams.CurrentNbRep = linkAdrReq->CurrentNbRep; - linkAdrVerifyParams.NbChannels = AS923_MAX_NB_CHANNELS; - linkAdrVerifyParams.ChannelsMask = &chMask; - linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value; - linkAdrVerifyParams.MaxDatarate = AS923_TX_MAX_DATARATE; - linkAdrVerifyParams.Channels = Channels; - linkAdrVerifyParams.MinTxPower = AS923_MIN_TX_POWER; - linkAdrVerifyParams.MaxTxPower = AS923_MAX_TX_POWER; - - // Verify the parameters and update, if necessary - status = verify_link_ADR_req( &linkAdrVerifyParams, &linkAdrParams.Datarate, &linkAdrParams.TxPower, &linkAdrParams.NbRep ); - - // Update channelsMask if everything is correct - if( status == 0x07 ) - { - // Set the channels mask to a default value - memset( ChannelsMask, 0, sizeof( ChannelsMask ) ); - // Update the channels mask - ChannelsMask[0] = chMask; - } - - // Update status variables - *drOut = linkAdrParams.Datarate; - *txPowOut = linkAdrParams.TxPower; - *nbRepOut = linkAdrParams.NbRep; - *nbBytesParsed = bytesProcessed; - - return status; -} - -uint8_t LoRaPHYAS923::setup_rx_params(RxParamSetupReqParams_t* rxParamSetupReq) -{ - uint8_t status = 0x07; - - // Verify radio frequency - if(_radio->check_rf_frequency(rxParamSetupReq->Frequency) == false ) - { - status &= 0xFE; // Channel frequency KO - } - - // Verify datarate - if( val_in_range( rxParamSetupReq->Datarate, AS923_RX_MIN_DATARATE, AS923_RX_MAX_DATARATE ) == 0 ) - { - status &= 0xFD; // Datarate KO - } - - // Verify datarate offset - if( val_in_range( rxParamSetupReq->DrOffset, AS923_MIN_RX1_DR_OFFSET, AS923_MAX_RX1_DR_OFFSET ) == 0 ) - { - status &= 0xFB; // Rx1DrOffset range KO - } - - return status; -} - -uint8_t LoRaPHYAS923::request_new_channel(NewChannelReqParams_t* newChannelReq) -{ - uint8_t status = 0x03; - ChannelAddParams_t channelAdd; - ChannelRemoveParams_t channelRemove; - - if( newChannelReq->NewChannel->frequency == 0 ) - { - channelRemove.ChannelId = newChannelReq->ChannelId; - - // Remove - if( remove_channel(&channelRemove) == false ) - { - status &= 0xFC; - } - } - else - { - channelAdd.NewChannel = newChannelReq->NewChannel; - channelAdd.ChannelId = newChannelReq->ChannelId; - - switch( add_channel (&channelAdd )) - { - case LORAWAN_STATUS_OK: - { - break; - } - case LORAWAN_STATUS_FREQUENCY_INVALID: - { - status &= 0xFE; - break; - } - case LORAWAN_STATUS_DATARATE_INVALID: - { - status &= 0xFD; - break; - } - case LORAWAN_STATUS_FREQ_AND_DR_INVALID: - { - status &= 0xFC; - break; - } - default: - { - status &= 0xFC; - break; - } - } - } - - return status; -} - -int8_t LoRaPHYAS923::setup_tx_params(TxParamSetupReqParams_t* txParamSetupReq) -{ - // Accept the request - return 0; -} - -uint8_t LoRaPHYAS923::dl_channel_request(DlChannelReqParams_t* dlChannelReq) -{ - uint8_t status = 0x03; - - // Verify if the frequency is supported - if( VerifyTxFreq( dlChannelReq->Rx1Frequency ) == false ) - { - status &= 0xFE; - } - - // Verify if an uplink frequency exists - if( Channels[dlChannelReq->ChannelId].frequency == 0 ) - { - status &= 0xFD; - } - - // Apply Rx1 frequency, if the status is OK - if( status == 0x03 ) - { - Channels[dlChannelReq->ChannelId].rx1_frequency = dlChannelReq->Rx1Frequency; - } - - return status; -} - -int8_t LoRaPHYAS923::get_alternate_DR(AlternateDrParams_t* alternateDr) +int8_t LoRaPHYAS923::get_alternate_DR(uint8_t nb_trials) { // Only AS923_DWELL_LIMIT_DATARATE is supported return AS923_DWELL_LIMIT_DATARATE; } -void LoRaPHYAS923::calculate_backoff(CalcBackOffParams_t* calcBackOff) -{ - RegionCommonCalcBackOffParams_t calcBackOffParams; - - calcBackOffParams.Channels = Channels; - calcBackOffParams.Bands = Bands; - calcBackOffParams.LastTxIsJoinRequest = calcBackOff->LastTxIsJoinRequest; - calcBackOffParams.Joined = calcBackOff->Joined; - calcBackOffParams.DutyCycleEnabled = calcBackOff->DutyCycleEnabled; - calcBackOffParams.Channel = calcBackOff->Channel; - calcBackOffParams.ElapsedTime = calcBackOff->ElapsedTime; - calcBackOffParams.TxTimeOnAir = calcBackOff->TxTimeOnAir; - - get_DC_backoff( &calcBackOffParams ); -} - -bool LoRaPHYAS923::set_next_channel(NextChanParams_t* nextChanParams, +bool LoRaPHYAS923::set_next_channel(channel_selection_params_t* next_channel_prams, uint8_t* channel, lorawan_time_t* time, - lorawan_time_t* aggregatedTimeOff) + lorawan_time_t* aggregate_timeoff) { - uint8_t channelNext = 0; - uint8_t nbEnabledChannels = 0; - uint8_t delayTx = 0; - uint8_t enabledChannels[AS923_MAX_NB_CHANNELS] = { 0 }; - lorawan_time_t nextTxDelay = 0; + uint8_t next_channel_idx = 0; + uint8_t nb_enabled_channels = 0; + uint8_t delay_tx = 0; + uint8_t enabled_channels[AS923_MAX_NB_CHANNELS] = { 0 }; + lorawan_time_t next_tx_delay = 0; - if( num_active_channels( ChannelsMask, 0, 1 ) == 0 ) - { // Reactivate default channels - ChannelsMask[0] |= LC( 1 ) + LC( 2 ); + if (num_active_channels(channel_masks, 0, 1) == 0) { + // Reactivate default channels + channel_masks[0] |= LC(1) + LC(2); } - if( nextChanParams->AggrTimeOff <= _lora_time.TimerGetElapsedTime( nextChanParams->LastAggrTx ) ) - { + if (next_channel_prams->aggregate_timeoff <= _lora_time.TimerGetElapsedTime(next_channel_prams->last_aggregate_tx_time)) { // Reset Aggregated time off - *aggregatedTimeOff = 0; + *aggregate_timeoff = 0; // Update bands Time OFF - nextTxDelay = update_band_timeoff( nextChanParams->Joined, nextChanParams->DutyCycleEnabled, Bands, AS923_MAX_NB_BANDS ); + next_tx_delay = update_band_timeoff(next_channel_prams->joined, + next_channel_prams->dc_enabled, + bands, AS923_MAX_NB_BANDS); // Search how many channels are enabled - nbEnabledChannels = CountNbOfEnabledChannels( nextChanParams->Joined, nextChanParams->Datarate, - ChannelsMask, Channels, - Bands, enabledChannels, &delayTx ); - } - else - { - delayTx++; - nextTxDelay = nextChanParams->AggrTimeOff - _lora_time.TimerGetElapsedTime( nextChanParams->LastAggrTx ); + nb_enabled_channels = enabled_channel_count(next_channel_prams->joined, + next_channel_prams->current_datarate, + channel_masks, + AS923_CHANNELS_MASK_SIZE, + enabled_channels, &delay_tx); + } else { + delay_tx++; + next_tx_delay = next_channel_prams->aggregate_timeoff - _lora_time.TimerGetElapsedTime(next_channel_prams->last_aggregate_tx_time); } - if( nbEnabledChannels > 0 ) - { - for( uint8_t i = 0, j = get_random( 0, nbEnabledChannels - 1 ); i < AS923_MAX_NB_CHANNELS; i++ ) - { - channelNext = enabledChannels[j]; - j = ( j + 1 ) % nbEnabledChannels; + if (nb_enabled_channels > 0) { + + _radio->lock(); + + for (uint8_t i = 0, j = get_random(0, nb_enabled_channels - 1); i < AS923_MAX_NB_CHANNELS; i++) { + next_channel_idx = enabled_channels[j]; + j = ( j + 1 ) % nb_enabled_channels; // Perform carrier sense for AS923_CARRIER_SENSE_TIME // If the channel is free, we can stop the LBT mechanism - if( _radio->perform_carrier_sense(MODEM_LORA, - Channels[channelNext].frequency, + + if (_radio->perform_carrier_sense(MODEM_LORA, + channels[next_channel_idx].frequency, AS923_RSSI_FREE_TH, - AS923_CARRIER_SENSE_TIME ) == true) - { + AS923_CARRIER_SENSE_TIME) == true) { // Free channel found - *channel = channelNext; + _radio->unlock(); + *channel = next_channel_idx; *time = 0; return true; } } + _radio->unlock(); return false; - } - else - { - if( delayTx > 0 ) - { + } else { + + if (delay_tx > 0) { // Delay transmission due to AggregatedTimeOff or to a band time off - *time = nextTxDelay; + *time = next_tx_delay; return true; } + // Datarate not supported by any channel, restore defaults - ChannelsMask[0] |= LC( 1 ) + LC( 2 ); + channel_masks[0] |= LC( 1 ) + LC( 2 ); *time = 0; return false; } } -lorawan_status_t LoRaPHYAS923::add_channel(ChannelAddParams_t* channelAdd) -{ - uint8_t band = 0; - bool drInvalid = false; - bool freqInvalid = false; - uint8_t id = channelAdd->ChannelId; - - if( id >= AS923_MAX_NB_CHANNELS ) - { - return LORAWAN_STATUS_PARAMETER_INVALID; - } - - // Validate the datarate range - if( val_in_range( channelAdd->NewChannel->dr_range.fields.min, AS923_TX_MIN_DATARATE, AS923_TX_MAX_DATARATE ) == 0 ) - { - drInvalid = true; - } - if( val_in_range( channelAdd->NewChannel->dr_range.fields.max, AS923_TX_MIN_DATARATE, AS923_TX_MAX_DATARATE ) == 0 ) - { - drInvalid = true; - } - if( channelAdd->NewChannel->dr_range.fields.min > channelAdd->NewChannel->dr_range.fields.max ) - { - drInvalid = true; - } - - // Default channels don't accept all values - if( id < AS923_NUMB_DEFAULT_CHANNELS ) - { - // Validate the datarate range for min: must be DR_0 - if( channelAdd->NewChannel->dr_range.fields.min > DR_0 ) - { - drInvalid = true; - } - // Validate the datarate range for max: must be DR_5 <= Max <= TX_MAX_DATARATE - if( val_in_range( channelAdd->NewChannel->dr_range.fields.max, DR_5, AS923_TX_MAX_DATARATE ) == 0 ) - { - drInvalid = true; - } - // We are not allowed to change the frequency - if( channelAdd->NewChannel->frequency != Channels[id].frequency ) - { - freqInvalid = true; - } - } - - // Check frequency - if( freqInvalid == false ) - { - if( VerifyTxFreq( channelAdd->NewChannel->frequency ) == false ) - { - freqInvalid = true; - } - } - - // Check status - if( ( drInvalid == true ) && ( freqInvalid == true ) ) - { - return LORAWAN_STATUS_FREQ_AND_DR_INVALID; - } - if( drInvalid == true ) - { - return LORAWAN_STATUS_DATARATE_INVALID; - } - if( freqInvalid == true ) - { - return LORAWAN_STATUS_FREQUENCY_INVALID; - } - - memcpy( &(Channels[id]), channelAdd->NewChannel, sizeof( Channels[id] ) ); - Channels[id].band = band; - ChannelsMask[0] |= ( 1 << id ); - return LORAWAN_STATUS_OK; -} - -bool LoRaPHYAS923::remove_channel(ChannelRemoveParams_t* channelRemove) -{ - uint8_t id = channelRemove->ChannelId; - - if( id < AS923_NUMB_DEFAULT_CHANNELS ) - { - return false; - } - - // Remove the channel from the list of channels - const channel_params_t empty_channel = { 0, 0, { 0 }, 0 }; - Channels[id] = empty_channel; - - return disable_channel( ChannelsMask, id, AS923_MAX_NB_CHANNELS ); -} - -void LoRaPHYAS923::set_tx_cont_mode(ContinuousWaveParams_t* continuousWave) -{ - int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, Bands[Channels[continuousWave->Channel].band].max_tx_pwr, continuousWave->Datarate, ChannelsMask ); - int8_t phyTxPower = 0; - uint32_t frequency = Channels[continuousWave->Channel].frequency; - - // Calculate physical TX power - phyTxPower = compute_tx_power( txPowerLimited, continuousWave->MaxEirp, continuousWave->AntennaGain ); - - _radio->set_tx_continuous_wave(frequency, phyTxPower, continuousWave->Timeout); -} - -uint8_t LoRaPHYAS923::apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, - int8_t drOffset) +uint8_t LoRaPHYAS923::apply_DR_offset(int8_t dr, int8_t dr_offset) { // Initialize minDr for a downlink dwell time configuration of 0 - int8_t minDr = DR_0; + int8_t min_dr = DR_0; // Update the minDR for a downlink dwell time configuration of 1 - if( downlinkDwellTime == 1 ) - { - minDr = AS923_DWELL_LIMIT_DATARATE; + if (phy_params.dl_dwell_time_setting == 1) { + min_dr = AS923_DWELL_LIMIT_DATARATE; } // Apply offset formula - return MIN( DR_5, MAX( minDr, dr - EffectiveRx1DrOffsetAS923[drOffset] ) ); + return MIN(DR_5, MAX(min_dr, dr - rx1_dr_offset_AS923[dr_offset])); } diff --git a/features/lorawan/lorastack/phy/LoRaPHYAS923.h b/features/lorawan/lorastack/phy/LoRaPHYAS923.h index aff0e55622..c4be485950 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYAS923.h +++ b/features/lorawan/lorastack/phy/LoRaPHYAS923.h @@ -33,7 +33,6 @@ #define MBED_OS_LORAPHY_AS923_H_ #include "LoRaPHY.h" -#include "netsocket/LoRaRadio.h" /*! * LoRaMac maximum number of channels @@ -51,313 +50,22 @@ class LoRaPHYAS923 : public LoRaPHY { public: - LoRaPHYAS923(LoRaWANTimeHandler &lora_time); virtual ~LoRaPHYAS923(); - /*! - * \brief The function gets a value of a specific PHY attribute. - * - * \param [in] getPhy A pointer to the function parameters. - * - * \retval A structure containing the PHY parameter. - */ - virtual PhyParam_t get_phy_params(GetPhyParams_t* getPhy ); + virtual int8_t get_alternate_DR(uint8_t nb_trials); - /*! - * \brief Updates the last TX done parameters of the current channel. - * - * \param [in] txDone A pointer to the function parameters. - */ - virtual void set_band_tx_done(SetBandTxDoneParams_t* txDone ); - - /*! - * \brief Initializes the channels masks and the channels. - * - * \param [in] type Sets the initialization type. - */ - virtual void load_defaults(InitType_t type ); - - /*! - * \brief Verifies a parameter. - * - * \param [in] verify A pointer to the function parameters. - * - * \param [in] phyAttribute The attribute to be verified. - * - * \retval True, if the parameter is valid. - */ - virtual bool verify(VerifyParams_t* verify, PhyAttribute_t phyAttribute ); - - /*! - * \brief The function parses the input buffer and sets up the channels of the - * CF list. - * - * \param [in] applyCFList A pointer to the function parameters. - */ - virtual void apply_cf_list(ApplyCFListParams_t* applyCFList ); - - /*! - * \brief Sets a channels mask. - * - * \param [in] chanMaskSet A pointer to the function parameters. - * - * \retval True, if the channels mask could be set. - */ - virtual bool set_channel_mask(ChanMaskSetParams_t* chanMaskSet ); - - /*! - * \brief Calculates the next datarate to set, when ADR is on or off. - * - * \param [in] adrNext A pointer to the function parameters. - * - * \param [out] drOut The calculated datarate for the next TX. - * - * \param [out] txPowOut The TX power for the next TX. - * - * \param [out] adrAckCounter The calculated ADR acknowledgement counter. - * - * \retval True, if an ADR request should be performed. - */ - virtual bool get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut, - int8_t* txPowOut, uint32_t* adrAckCounter ); - - /*! - * \brief Configuration of the RX windows. - * - * \param [in] rxConfig A pointer to the function parameters. - * - * \param [out] datarate The datarate index set. - * - * \retval True, if the configuration was applied successfully. - */ - virtual bool rx_config(rx_config_params_t* rxConfig, int8_t* datarate ); - - /* - * RX window precise timing. - * - * For more details please consult the following document, chapter 3.1.2. - * http://www.semtech.com/images/datasheet/SX1272_settings_for_LoRaWAN_v2.0.pdf - * or - * http://www.semtech.com/images/datasheet/SX1276_settings_for_LoRaWAN_v2.0.pdf - * - * Downlink start: T = Tx + 1s (+/- 20 us) - * | - * TRxEarly | TRxLate - * | | | - * | | +---+---+---+---+---+---+---+---+ - * | | | Latest Rx window | - * | | +---+---+---+---+---+---+---+---+ - * | | | - * +---+---+---+---+---+---+---+---+ - * | Earliest Rx window | - * +---+---+---+---+---+---+---+---+ - * | - * +---+---+---+---+---+---+---+---+ - *Downlink preamble 8 symbols | | | | | | | | | - * +---+---+---+---+---+---+---+---+ - * - * Worst case Rx window timings - * - * TRxLate = DEFAULT_MIN_RX_SYMBOLS * tSymbol - RADIO_WAKEUP_TIME - * TRxEarly = 8 - DEFAULT_MIN_RX_SYMBOLS * tSymbol - RxWindowTimeout - RADIO_WAKEUP_TIME - * - * TRxLate - TRxEarly = 2 * DEFAULT_SYSTEM_MAX_RX_ERROR - * - * RxOffset = ( TRxLate + TRxEarly ) / 2 - * - * RxWindowTimeout = ( 2 * DEFAULT_MIN_RX_SYMBOLS - 8 ) * tSymbol + 2 * DEFAULT_SYSTEM_MAX_RX_ERROR - * RxOffset = 4 * tSymbol - RxWindowTimeout / 2 - RADIO_WAKE_UP_TIME - * - * The minimum value of RxWindowTimeout must be 5 symbols which implies that the system always tolerates at least an error of 1.5 * tSymbol - */ - /*! - * Computes the RX window timeout and offset. - * - * \param [in] datarate The RX window datarate index to be used. - * - * \param [in] minRxSymbols The minimum required number of symbols to detect an RX frame. - * - * \param [in] rxError The system maximum timing error of the receiver in milliseconds. - * The receiver will turn on in a [-rxError : +rxError] ms - * interval around RxOffset. - * - * \param [out] rxConfigParams The updated WindowTimeout and WindowOffset fields. - */ - virtual void compute_rx_win_params(int8_t datarate, - uint8_t minRxSymbols, - uint32_t rxError, - rx_config_params_t *rxConfigParams); - - /*! - * \brief TX configuration. - * - * \param [in] txConfig A pointer to the function parameters. - * - * \param [out] txPower The TX power index set. - * - * \param [out] txTimeOnAir The time-on-air of the frame. - * - * \retval True, if the configuration was applied successfully. - */ - virtual bool tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - lorawan_time_t* txTimeOnAir ); - - /*! - * \brief The function processes a Link ADR Request. - * - * \param [in] linkAdrReq A pointer to the function parameters. - * - * \param [out] drOut The datarate applied. - * - * \param [out] txPowOut The TX power applied. - * - * \param [out] nbRepOut The number of repetitions to apply. - * - * \param [out] nbBytesParsed The number of bytes parsed. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t link_ADR_request(LinkAdrReqParams_t* linkAdrReq, - int8_t* drOut, int8_t* txPowOut, - uint8_t* nbRepOut, - uint8_t* nbBytesParsed ); - - /*! - * \brief The function processes a RX parameter setup request. - * - * \param [in] rxParamSetupReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t setup_rx_params(RxParamSetupReqParams_t* rxParamSetupReq ); - - /*! - * \brief The function processes a new channel request. - * - * \param [in] newChannelReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t request_new_channel(NewChannelReqParams_t* newChannelReq ); - - /*! - * \brief The function processes a TX ParamSetup request. - * - * \param [in] txParamSetupReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - * Returns -1, if the functionality is not implemented. In this case, the end node - * shall ignore the command. - */ - virtual int8_t setup_tx_params(TxParamSetupReqParams_t* txParamSetupReq ); - - /*! - * \brief The function processes a DlChannel request. - * - * \param [in] dlChannelReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t dl_channel_request(DlChannelReqParams_t* dlChannelReq ); - - /*! - * \brief Alternates the datarate of the channel for the join request. - * - * \param [in] alternateDr A pointer to the function parameters. - * - * \retval The datarate to apply. - */ - virtual int8_t get_alternate_DR(AlternateDrParams_t* alternateDr ); - - /*! - * \brief Calculates the back-off time. - * - * \param [in] calcBackOff A pointer to the function parameters. - */ - virtual void calculate_backoff(CalcBackOffParams_t* calcBackOff ); - - /*! - * \brief Searches and sets the next random available channel. - * - * \param [in] nextChanParams The parameters for the next channel - * - * \param [out] channel The next channel to use for TX. - * - * \param [out] time The time to wait for the next transmission according to the duty cycle. - * - * \param [out] aggregatedTimeOff Updates the aggregated time off. - * - * \retval Function status [1: OK, 0: Unable to find a channel on the current datarate]. - */ - virtual bool set_next_channel(NextChanParams_t* nextChanParams, + virtual bool set_next_channel(channel_selection_params_t* nextChanParams, uint8_t* channel, lorawan_time_t* time, lorawan_time_t* aggregatedTimeOff ); - /*! - * \brief Adds a channel. - * - * \param [in] channelAdd A pointer to the function parameters. - * - * \retval The status of the operation. - */ - virtual lorawan_status_t add_channel(ChannelAddParams_t* channelAdd ); - - /*! - * \brief Removes a channel. - * - * \param [in] channelRemove A pointer to the function parameters. - * - * \retval True, if the channel was removed successfully. - */ - virtual bool remove_channel(ChannelRemoveParams_t* channelRemove ); - - /*! - * \brief Sets the radio into continuous wave mode. - * - * \param [in] continuousWave A pointer to the function parameters. - */ - virtual void set_tx_cont_mode(ContinuousWaveParams_t* continuousWave ); - - /*! - * \brief Computes a new datarate according to the given offset. - * - * \param [in] downlinkDwellTime The downlink dwell time configuration. 0: No limit, 1: 400ms - * - * \param [in] dr The current datarate. - * - * \param [in] drOffset The offset to be applied. - * - * \retval newDr The computed datarate. - */ - virtual uint8_t apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ); + virtual uint8_t apply_DR_offset(int8_t dr, int8_t drOffset ); private: - uint8_t CountNbOfEnabledChannels(bool joined, uint8_t datarate, - uint16_t* channelsMask, - channel_params_t* channels, band_t* bands, - uint8_t* enabledChannels, uint8_t* delayTx); - - // Global attributes - /*! - * LoRaMAC channels - */ - channel_params_t Channels[AS923_MAX_NB_CHANNELS]; - - /*! - * LoRaMac bands - */ - band_t Bands[AS923_MAX_NB_BANDS]; - - /*! - * LoRaMac channels mask - */ - uint16_t ChannelsMask[AS923_CHANNELS_MASK_SIZE]; - - /*! - * LoRaMac channels default mask - */ - uint16_t ChannelsDefaultMask[AS923_CHANNELS_MASK_SIZE]; + channel_params_t channels[AS923_MAX_NB_CHANNELS]; + band_t bands[AS923_MAX_NB_BANDS]; + uint16_t channel_masks[AS923_CHANNELS_MASK_SIZE]; + uint16_t default_channel_masks[AS923_CHANNELS_MASK_SIZE]; }; #endif /* MBED_OS_LORAPHY_AS923_H_ */ diff --git a/features/lorawan/lorastack/phy/LoRaPHYAU915.cpp b/features/lorawan/lorastack/phy/LoRaPHYAU915.cpp index db4af8d0cd..992fc7295f 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYAU915.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYAU915.cpp @@ -31,7 +31,6 @@ #include "LoRaPHYAU915.h" #include "lora_phy_ds.h" -#include "LoRaRadio.h" /*! * Minimal datarate that can be used by the node @@ -163,46 +162,44 @@ */ #define AU915_RX_WND_2_DR DR_8 - /*! * Band 0 definition * { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff } */ -#define AU915_BAND0 { 1, AU915_MAX_TX_POWER, 0, 0, 0 } // 100.0 % +static const band_t AU915_BAND0 = {1, AU915_MAX_TX_POWER, 0, 0, 0, 915200000, 927800000}; // 100.0 % /*! * Defines the first channel for RX window 1 for US band */ -#define AU915_FIRST_RX1_CHANNEL ( (uint32_t) 923300000 ) +#define AU915_FIRST_RX1_CHANNEL ((uint32_t) 923300000) /*! * Defines the last channel for RX window 1 for US band */ -#define AU915_LAST_RX1_CHANNEL ( (uint32_t) 927500000 ) +#define AU915_LAST_RX1_CHANNEL ((uint32_t) 927500000) /*! * Defines the step width of the channels for RX window 1 */ -#define AU915_STEPWIDTH_RX1_CHANNEL ( (uint32_t) 600000 ) +#define AU915_STEPWIDTH_RX1_CHANNEL ((uint32_t) 600000) /*! * Data rates table definition */ -static const uint8_t DataratesAU915[] = { 12, 11, 10, 9, 8, 7, 8, 0, 12, 11, 10, - 9, 8, 7, 0, 0 }; +static const uint8_t datarates_AU915[] = {12, 11, 10, 9, 8, 7, 8, 0, 12, 11, 10, 9, 8, 7, 0, 0}; /*! * Bandwidths table definition in Hz */ -static const uint32_t BandwidthsAU915[] = { 125000, 125000, 125000, 125000, +static const uint32_t bandwidths_AU915[] = { 125000, 125000, 125000, 125000, 125000, 125000, 500000, 0, 500000, 500000, 500000, 500000, 500000, 500000, 0, 0 }; /*! * Up/Down link data rates offset definition */ -static const int8_t DatarateOffsetsAU915[7][6] = { { DR_8, DR_8, DR_8, DR_8, - DR_8, DR_8 }, // DR_0 +static const int8_t datarate_offsets_AU915[7][6] = { { DR_8, DR_8, DR_8, DR_8, +DR_8, DR_8 }, // DR_0 { DR_9, DR_8, DR_8, DR_8, DR_8, DR_8 }, // DR_1 { DR_10, DR_9, DR_8, DR_8, DR_8, DR_8 }, // DR_2 { DR_11, DR_10, DR_9, DR_8, DR_8, DR_8 }, // DR_3 @@ -214,602 +211,307 @@ static const int8_t DatarateOffsetsAU915[7][6] = { { DR_8, DR_8, DR_8, DR_8, /*! * Maximum payload with respect to the datarate index. Cannot operate with repeater. */ -static const uint8_t MaxPayloadOfDatarateAU915[] = { 51, 51, 51, 115, 242, 242, +static const uint8_t max_payload_AU915[] = { 51, 51, 51, 115, 242, 242, 242, 0, 53, 129, 242, 242, 242, 242, 0, 0 }; /*! * Maximum payload with respect to the datarate index. Can operate with repeater. */ -static const uint8_t MaxPayloadOfDatarateRepeaterAU915[] = { 51, 51, 51, 115, +static const uint8_t max_payload_with_repeater_AU915[] = { 51, 51, 51, 115, 222, 222, 222, 0, 33, 109, 222, 222, 222, 222, 0, 0 }; -// Static functions -static int8_t GetNextLowerTxDr(int8_t dr, int8_t minDr) -{ - uint8_t nextLowerDr = 0; - - if (dr == minDr) { - nextLowerDr = minDr; - } else { - nextLowerDr = dr - 1; - } - return nextLowerDr; -} - -static uint32_t GetBandwidth(uint32_t drIndex) -{ - switch (BandwidthsAU915[drIndex]) { - default: - case 125000: - return 0; - case 250000: - return 1; - case 500000: - return 2; - } -} - -static int8_t LimitTxPower(int8_t txPower, int8_t maxBandTxPower, - int8_t datarate, uint16_t* channelsMask) -{ - int8_t txPowerResult = txPower; - - // Limit tx power to the band max - txPowerResult = MAX(txPower, maxBandTxPower); - - return txPowerResult; -} - -uint8_t LoRaPHYAU915::CountNbOfEnabledChannels(uint8_t datarate, - uint16_t* channelsMask, - channel_params_t* channels, - band_t* bands, uint8_t* enabledChannels, - uint8_t* delayTx) -{ - uint8_t nbEnabledChannels = 0; - uint8_t delayTransmission = 0; - - for (uint8_t i = 0, k = 0; i < AU915_MAX_NB_CHANNELS; i += 16, k++) { - for (uint8_t j = 0; j < 16; j++) { - if ((channelsMask[k] & (1 << j)) != 0) { - if (channels[i + j].frequency == 0) { // Check if the channel is enabled - continue; - } - if (val_in_range(datarate, channels[i + j].dr_range.fields.min, - channels[i + j].dr_range.fields.max) == 0) { // Check if the current channel selection supports the given datarate - continue; - } - if (bands[channels[i + j].band].off_time > 0) { // Check if the band is available for transmission - delayTransmission++; - continue; - } - enabledChannels[nbEnabledChannels++] = i + j; - } - } - } - - *delayTx = delayTransmission; - return nbEnabledChannels; -} - LoRaPHYAU915::LoRaPHYAU915(LoRaWANTimeHandler &lora_time) - : LoRaPHY(lora_time) + : LoRaPHY(lora_time) { - const band_t band0 = AU915_BAND0; - Bands[0] = band0; + bands[0] = AU915_BAND0; + + // Activate Channels + // 125 kHz channels Upstream only + for (uint8_t i = 0; i < AU915_MAX_NB_CHANNELS - 8; i++) { + channels[i].frequency = 915200000 + i * 200000; + channels[i].dr_range.value = ( DR_5 << 4) | DR_0; + channels[i].band = 0; + } + // 500 kHz channels + // Upstream and downstream both + for (uint8_t i = AU915_MAX_NB_CHANNELS - 8; i < AU915_MAX_NB_CHANNELS; i++) { + channels[i].frequency = 915900000 + (i - ( AU915_MAX_NB_CHANNELS - 8)) * 1600000; + channels[i].dr_range.value = ( DR_6 << 4) | DR_6; + channels[i].band = 0; + } + + // Initialize channels default mask + // All channels are default channels here + // Join request needs to alternate between 125 KHz and 500 KHz channels + // randomly. + default_channel_masks[0] = 0xFFFF; + default_channel_masks[1] = 0xFFFF; + default_channel_masks[2] = 0xFFFF; + default_channel_masks[3] = 0xFFFF; + default_channel_masks[4] = 0x00FF; + + memset(channel_masks, 0, sizeof(channel_masks)); + memset(current_channel_masks, 0, sizeof(current_channel_masks)); + + // Copy channels default mask + copy_channel_mask(channel_masks, default_channel_masks, AU915_CHANNELS_MASK_SIZE); + + // Copy into current channels mask + // This mask is used to keep track of the channels which were used in + // previous transmissions as the AU915 band doesn't allow concurrent + // transmission on the same channel + copy_channel_mask(current_channel_masks, channel_masks, AU915_CHANNELS_MASK_SIZE); + + // set bands for EU868 spectrum + phy_params.bands.table = (void *) bands; + phy_params.bands.size = AU915_MAX_NB_BANDS; + + // set bandwidths available in EU868 spectrum + phy_params.bandwidths.table = (void *) bandwidths_AU915; + phy_params.bandwidths.size = 16; + + // set data rates available in EU868 spectrum + phy_params.datarates.table = (void *) datarates_AU915; + phy_params.datarates.size = 16; + + // set payload sizes with respect to data rates + phy_params.payloads.table = (void *) max_payload_AU915; + phy_params.payloads.size = 16; + phy_params.payloads_with_repeater.table = (void *) max_payload_with_repeater_AU915; + phy_params.payloads.size = 16; + + // dwell time setting + phy_params.ul_dwell_time_setting = 0; + phy_params.dl_dwell_time_setting = 0; + phy_params.dwell_limit_datarate = AU915_DEFAULT_DATARATE; + + phy_params.duty_cycle_enabled = AU915_DUTY_CYCLE_ENABLED; + phy_params.accept_tx_param_setup_req = false; + phy_params.custom_channelplans_supported = false; + phy_params.cflist_supported = false; + phy_params.fsk_supported = false; + + phy_params.default_channel_cnt = AU915_MAX_NB_CHANNELS; + phy_params.max_channel_cnt = AU915_MAX_NB_CHANNELS; + phy_params.cflist_channel_cnt = 0; + phy_params.min_tx_datarate = AU915_TX_MIN_DATARATE; + phy_params.max_tx_datarate = AU915_TX_MAX_DATARATE; + phy_params.min_rx_datarate = AU915_RX_MIN_DATARATE; + phy_params.max_rx_datarate = AU915_RX_MAX_DATARATE; + phy_params.default_datarate = AU915_DEFAULT_DATARATE; + phy_params.default_max_datarate = AU915_TX_MAX_DATARATE; + phy_params.min_rx1_dr_offset = AU915_MIN_RX1_DR_OFFSET; + phy_params.max_rx1_dr_offset = AU915_MAX_RX1_DR_OFFSET; + phy_params.default_rx1_dr_offset = AU915_DEFAULT_RX1_DR_OFFSET; + phy_params.min_tx_power = AU915_MIN_TX_POWER; + phy_params.max_tx_power = AU915_MAX_TX_POWER; + phy_params.default_tx_power = AU915_DEFAULT_TX_POWER; + phy_params.default_max_eirp = AU915_DEFAULT_MAX_EIRP; + phy_params.default_antenna_gain = AU915_DEFAULT_ANTENNA_GAIN; + phy_params.adr_ack_limit = AU915_ADR_ACK_LIMIT; + phy_params.adr_ack_delay = AU915_ADR_ACK_DELAY; + phy_params.max_rx_window = AU915_MAX_RX_WINDOW; + phy_params.recv_delay1 = AU915_RECEIVE_DELAY1; + phy_params.recv_delay2 = AU915_RECEIVE_DELAY2; + + phy_params.join_accept_delay1 = AU915_JOIN_ACCEPT_DELAY1; + phy_params.join_accept_delay2 = AU915_JOIN_ACCEPT_DELAY2; + phy_params.max_fcnt_gap = AU915_MAX_FCNT_GAP; + phy_params.ack_timeout = AU915_ACKTIMEOUT; + phy_params.ack_timeout_rnd = AU915_ACK_TIMEOUT_RND; + phy_params.rx_window2_datarate = AU915_RX_WND_2_DR; + phy_params.rx_window2_frequency = AU915_RX_WND_2_FREQ; } LoRaPHYAU915::~LoRaPHYAU915() { } -PhyParam_t LoRaPHYAU915::get_phy_params(GetPhyParams_t* getPhy) +bool LoRaPHYAU915::rx_config(rx_config_params_t* params, int8_t* datarate) { - PhyParam_t phyParam = { 0 }; - - switch (getPhy->Attribute) { - case PHY_MIN_RX_DR: { - phyParam.Value = AU915_RX_MIN_DATARATE; - break; - } - case PHY_MIN_TX_DR: { - phyParam.Value = AU915_TX_MIN_DATARATE; - break; - } - case PHY_DEF_TX_DR: { - phyParam.Value = AU915_DEFAULT_DATARATE; - break; - } - case PHY_NEXT_LOWER_TX_DR: { - phyParam.Value = GetNextLowerTxDr(getPhy->Datarate, - AU915_TX_MIN_DATARATE); - break; - } - case PHY_DEF_TX_POWER: { - phyParam.Value = AU915_DEFAULT_TX_POWER; - break; - } - case PHY_MAX_PAYLOAD: { - phyParam.Value = MaxPayloadOfDatarateAU915[getPhy->Datarate]; - break; - } - case PHY_MAX_PAYLOAD_REPEATER: { - phyParam.Value = - MaxPayloadOfDatarateRepeaterAU915[getPhy->Datarate]; - break; - } - case PHY_DUTY_CYCLE: { - phyParam.Value = AU915_DUTY_CYCLE_ENABLED; - break; - } - case PHY_MAX_RX_WINDOW: { - phyParam.Value = AU915_MAX_RX_WINDOW; - break; - } - case PHY_RECEIVE_DELAY1: { - phyParam.Value = AU915_RECEIVE_DELAY1; - break; - } - case PHY_RECEIVE_DELAY2: { - phyParam.Value = AU915_RECEIVE_DELAY2; - break; - } - case PHY_JOIN_ACCEPT_DELAY1: { - phyParam.Value = AU915_JOIN_ACCEPT_DELAY1; - break; - } - case PHY_JOIN_ACCEPT_DELAY2: { - phyParam.Value = AU915_JOIN_ACCEPT_DELAY2; - break; - } - case PHY_MAX_FCNT_GAP: { - phyParam.Value = AU915_MAX_FCNT_GAP; - break; - } - case PHY_ACK_TIMEOUT: { - phyParam.Value = - ( AU915_ACKTIMEOUT - + get_random(-AU915_ACK_TIMEOUT_RND, - AU915_ACK_TIMEOUT_RND)); - break; - } - case PHY_DEF_DR1_OFFSET: { - phyParam.Value = AU915_DEFAULT_RX1_DR_OFFSET; - break; - } - case PHY_DEF_RX2_FREQUENCY: { - phyParam.Value = AU915_RX_WND_2_FREQ; - break; - } - case PHY_DEF_RX2_DR: { - phyParam.Value = AU915_RX_WND_2_DR; - break; - } - case PHY_CHANNELS_MASK: { - phyParam.ChannelsMask = ChannelsMask; - break; - } - case PHY_CHANNELS_DEFAULT_MASK: { - phyParam.ChannelsMask = ChannelsDefaultMask; - break; - } - case PHY_MAX_NB_CHANNELS: { - phyParam.Value = AU915_MAX_NB_CHANNELS; - break; - } - case PHY_CHANNELS: { - phyParam.Channels = Channels; - break; - } - case PHY_DEF_UPLINK_DWELL_TIME: - case PHY_DEF_DOWNLINK_DWELL_TIME: { - phyParam.Value = 0; - break; - } - case PHY_DEF_MAX_EIRP: { - phyParam.fValue = AU915_DEFAULT_MAX_EIRP; - break; - } - case PHY_DEF_ANTENNA_GAIN: { - phyParam.fValue = AU915_DEFAULT_ANTENNA_GAIN; - break; - } - case PHY_NB_JOIN_TRIALS: - case PHY_DEF_NB_JOIN_TRIALS: { - phyParam.Value = 2; - break; - } - default: { - break; - } - } - - return phyParam; -} - -void LoRaPHYAU915::set_band_tx_done(SetBandTxDoneParams_t* txDone) -{ - set_last_tx_done(txDone->Joined, &Bands[Channels[txDone->Channel].band], - txDone->LastTxDoneTime); -} - -void LoRaPHYAU915::load_defaults(InitType_t type) -{ - switch (type) { - case INIT_TYPE_INIT: { - // Channels - // 125 kHz channels - for (uint8_t i = 0; i < AU915_MAX_NB_CHANNELS - 8; i++) { - Channels[i].frequency = 915200000 + i * 200000; - Channels[i].dr_range.value = ( DR_5 << 4) | DR_0; - Channels[i].band = 0; - } - // 500 kHz channels - for (uint8_t i = AU915_MAX_NB_CHANNELS - 8; - i < AU915_MAX_NB_CHANNELS; i++) { - Channels[i].frequency = 915900000 - + (i - ( AU915_MAX_NB_CHANNELS - 8)) * 1600000; - Channels[i].dr_range.value = ( DR_6 << 4) | DR_6; - Channels[i].band = 0; - } - - // Initialize channels default mask - ChannelsDefaultMask[0] = 0xFFFF; - ChannelsDefaultMask[1] = 0xFFFF; - ChannelsDefaultMask[2] = 0xFFFF; - ChannelsDefaultMask[3] = 0xFFFF; - ChannelsDefaultMask[4] = 0x00FF; - ChannelsDefaultMask[5] = 0x0000; - - // Copy channels default mask - copy_channel_mask(ChannelsMask, ChannelsDefaultMask, 6); - - // Copy into channels mask remaining - copy_channel_mask(ChannelsMaskRemaining, ChannelsMask, 6); - break; - } - case INIT_TYPE_RESTORE: { - // Copy channels default mask - copy_channel_mask(ChannelsMask, ChannelsDefaultMask, 6); - - for (uint8_t i = 0; i < 6; i++) { // Copy-And the channels mask - ChannelsMaskRemaining[i] &= ChannelsMask[i]; - } - break; - } - default: { - break; - } - } -} - -bool LoRaPHYAU915::verify(VerifyParams_t* verify, PhyAttribute_t phyAttribute) -{ - switch (phyAttribute) { - case PHY_TX_DR: - case PHY_DEF_TX_DR: { - return val_in_range(verify->DatarateParams.Datarate, - AU915_TX_MIN_DATARATE, AU915_TX_MAX_DATARATE); - } - case PHY_RX_DR: { - return val_in_range(verify->DatarateParams.Datarate, - AU915_RX_MIN_DATARATE, AU915_RX_MAX_DATARATE); - } - case PHY_DEF_TX_POWER: - case PHY_TX_POWER: { - // Remark: switched min and max! - return val_in_range(verify->TxPower, AU915_MAX_TX_POWER, - AU915_MIN_TX_POWER); - } - case PHY_DUTY_CYCLE: { - return AU915_DUTY_CYCLE_ENABLED; - } - case PHY_NB_JOIN_TRIALS: { - if (verify->NbJoinTrials < 2) { - return false; - } - break; - } - default: - return false; - } - return true; -} - -void LoRaPHYAU915::apply_cf_list(ApplyCFListParams_t* applyCFList) -{ - return; -} - -bool LoRaPHYAU915::set_channel_mask(ChanMaskSetParams_t* chanMaskSet) -{ - uint8_t nbChannels = num_active_channels(chanMaskSet->ChannelsMaskIn, 0, 4); - - // Check the number of active channels - // According to ACMA regulation, we require at least 20 125KHz channels, if - // the node shall utilize 125KHz channels. - if ((nbChannels < 20) && (nbChannels > 0)) { - return false; - } - - switch (chanMaskSet->ChannelsMaskType) { - case CHANNELS_MASK: { - copy_channel_mask(ChannelsMask, chanMaskSet->ChannelsMaskIn, 6); - - for (uint8_t i = 0; i < 6; i++) { // Copy-And the channels mask - ChannelsMaskRemaining[i] &= ChannelsMask[i]; - } - break; - } - case CHANNELS_DEFAULT_MASK: { - copy_channel_mask(ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, - 6); - break; - } - default: - return false; - } - return true; -} - -bool LoRaPHYAU915::get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut, - int8_t* txPowOut, uint32_t* adrAckCounter) -{ - bool adrAckReq = false; - int8_t datarate = adrNext->Datarate; - int8_t txPower = adrNext->TxPower; - GetPhyParams_t getPhy; - PhyParam_t phyParam; - - // Report back the adr ack counter - *adrAckCounter = adrNext->AdrAckCounter; - - if (adrNext->AdrEnabled == true) { - if (datarate == AU915_TX_MIN_DATARATE) { - *adrAckCounter = 0; - adrAckReq = false; - } else { - if (adrNext->AdrAckCounter >= AU915_ADR_ACK_LIMIT) { - adrAckReq = true; - txPower = AU915_MAX_TX_POWER; - } else { - adrAckReq = false; - } - if (adrNext->AdrAckCounter - >= ( AU915_ADR_ACK_LIMIT + AU915_ADR_ACK_DELAY)) { - if ((adrNext->AdrAckCounter % AU915_ADR_ACK_DELAY) == 1) { - // Decrease the datarate - getPhy.Attribute = PHY_NEXT_LOWER_TX_DR; - getPhy.Datarate = datarate; - getPhy.UplinkDwellTime = adrNext->UplinkDwellTime; - phyParam = get_phy_params(&getPhy); - datarate = phyParam.Value; - - if (datarate == AU915_TX_MIN_DATARATE) { - // We must set adrAckReq to false as soon as we reach the lowest datarate - adrAckReq = false; - if (adrNext->UpdateChanMask == true) { - // Re-enable default channels - ChannelsMask[0] = 0xFFFF; - ChannelsMask[1] = 0xFFFF; - ChannelsMask[2] = 0xFFFF; - ChannelsMask[3] = 0xFFFF; - ChannelsMask[4] = 0x00FF; - ChannelsMask[5] = 0x0000; - } - } - } - } - } - } - - *drOut = datarate; - *txPowOut = txPower; - return adrAckReq; -} - -void LoRaPHYAU915::compute_rx_win_params(int8_t datarate, uint8_t minRxSymbols, - uint32_t rxError, - rx_config_params_t *rxConfigParams) -{ - double tSymbol = 0.0; - - // Get the datarate, perform a boundary check - rxConfigParams->datarate = MIN(datarate, AU915_RX_MAX_DATARATE); - rxConfigParams->bandwidth = GetBandwidth(rxConfigParams->datarate); - - tSymbol = compute_symb_timeout_lora( - DataratesAU915[rxConfigParams->datarate], - BandwidthsAU915[rxConfigParams->datarate]); - - get_rx_window_params(tSymbol, minRxSymbols, rxError, RADIO_WAKEUP_TIME, - &rxConfigParams->window_timeout, - &rxConfigParams->window_offset); -} - -bool LoRaPHYAU915::rx_config(rx_config_params_t* rxConfig, int8_t* datarate) -{ - int8_t dr = rxConfig->datarate; - uint8_t maxPayload = 0; - int8_t phyDr = 0; - uint32_t frequency = rxConfig->frequency; + int8_t dr = params->datarate; + uint8_t max_payload = 0; + int8_t phy_dr = 0; + uint32_t frequency = params->frequency; if (_radio->get_status() != RF_IDLE) { return false; } - if (rxConfig->rx_slot == RX_SLOT_WIN_1) { + if (params->rx_slot == RX_SLOT_WIN_1) { // Apply window 1 frequency frequency = AU915_FIRST_RX1_CHANNEL - + (rxConfig->channel % 8) * AU915_STEPWIDTH_RX1_CHANNEL; + + (params->channel % 8) * AU915_STEPWIDTH_RX1_CHANNEL; } // Read the physical datarate from the datarates table - phyDr = DataratesAU915[dr]; + phy_dr = datarates_AU915[dr]; + + _radio->lock(); _radio->set_channel(frequency); // Radio configuration - _radio->set_rx_config(MODEM_LORA, rxConfig->bandwidth, phyDr, 1, 0, 8, - rxConfig->window_timeout, false, 0, false, 0, 0, true, - rxConfig->is_rx_continuous); + _radio->set_rx_config(MODEM_LORA, params->bandwidth, phy_dr, 1, 0, 8, + params->window_timeout, false, 0, false, 0, 0, true, + params->is_rx_continuous); - if (rxConfig->is_repeater_supported == true) { - maxPayload = MaxPayloadOfDatarateRepeaterAU915[dr]; + if (params->is_repeater_supported == true) { + max_payload = max_payload_with_repeater_AU915[dr]; } else { - maxPayload = MaxPayloadOfDatarateAU915[dr]; + max_payload = max_payload_AU915[dr]; } _radio->set_max_payload_length(MODEM_LORA, - maxPayload + LORA_MAC_FRMPAYLOAD_OVERHEAD); + max_payload + LORA_MAC_FRMPAYLOAD_OVERHEAD); + + _radio->unlock(); *datarate = (uint8_t) dr; return true; } -bool LoRaPHYAU915::tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - lorawan_time_t* txTimeOnAir) +bool LoRaPHYAU915::tx_config(tx_config_params_t* params, int8_t* tx_power, + lorawan_time_t* tx_toa) { - int8_t phyDr = DataratesAU915[txConfig->Datarate]; - int8_t txPowerLimited = LimitTxPower( - txConfig->TxPower, - Bands[Channels[txConfig->Channel].band].max_tx_pwr, - txConfig->Datarate, ChannelsMask); - uint32_t bandwidth = GetBandwidth(txConfig->Datarate); - int8_t phyTxPower = 0; + int8_t phy_dr = datarates_AU915[params->datarate]; + + if (params->tx_power > bands[channels[params->channel].band].max_tx_pwr) { + params->tx_power = bands[channels[params->channel].band].max_tx_pwr; + } + + uint32_t bandwidth = get_bandwidth(params->datarate); + int8_t phy_tx_power = 0; // Calculate physical TX power - phyTxPower = compute_tx_power(txPowerLimited, txConfig->MaxEirp, - txConfig->AntennaGain); + phy_tx_power = compute_tx_power(params->tx_power, params->max_eirp, + params->antenna_gain); - // Setup the radio frequency - _radio->set_channel(Channels[txConfig->Channel].frequency); + // setting up radio tx configurations - _radio->set_tx_config(MODEM_LORA, phyTxPower, 0, bandwidth, phyDr, 1, 8, + _radio->lock(); + + _radio->set_channel(channels[params->channel].frequency); + + _radio->set_tx_config(MODEM_LORA, phy_tx_power, 0, bandwidth, phy_dr, 1, 8, false, true, 0, 0, false, 3000); // Setup maximum payload lenght of the radio driver - _radio->set_max_payload_length(MODEM_LORA, txConfig->PktLen); + _radio->set_max_payload_length(MODEM_LORA, params->pkt_len); - *txTimeOnAir = _radio->time_on_air(MODEM_LORA, txConfig->PktLen); - *txPower = txPowerLimited; + *tx_toa = _radio->time_on_air(MODEM_LORA, params->pkt_len); + + _radio->unlock(); + + *tx_power = params->tx_power; return true; } -uint8_t LoRaPHYAU915::link_ADR_request(LinkAdrReqParams_t* linkAdrReq, - int8_t* drOut, int8_t* txPowOut, - uint8_t* nbRepOut, - uint8_t* nbBytesParsed) +uint8_t LoRaPHYAU915::link_ADR_request(adr_req_params_t* params, + int8_t* dr_out, int8_t* tx_power_out, + uint8_t* nb_rep_out, + uint8_t* nb_bytes_parsed) { uint8_t status = 0x07; - RegionCommonLinkAdrParams_t linkAdrParams; - uint8_t nextIndex = 0; - uint8_t bytesProcessed = 0; - uint16_t channelsMask[6] = { 0, 0, 0, 0, 0, 0 }; - GetPhyParams_t getPhy; - PhyParam_t phyParam; - RegionCommonLinkAdrReqVerifyParams_t linkAdrVerifyParams; + link_adr_params_t adr_settings; + uint8_t next_index = 0; + uint8_t bytes_processed = 0; + uint16_t temp_channel_masks[AU915_CHANNELS_MASK_SIZE] = { 0, 0, 0, 0, 0}; + + verify_adr_params_t verify_params; // Initialize local copy of channels mask - copy_channel_mask(channelsMask, ChannelsMask, 6); + copy_channel_mask(temp_channel_masks, channel_masks, AU915_CHANNELS_MASK_SIZE); - while (bytesProcessed < linkAdrReq->PayloadSize) { - nextIndex = parse_link_ADR_req(&(linkAdrReq->Payload[bytesProcessed]), - &linkAdrParams); + while (bytes_processed < params->payload_size) { + next_index = parse_link_ADR_req(&(params->payload[bytes_processed]), + &adr_settings); - if (nextIndex == 0) + if (next_index == 0) { break; // break loop, since no more request has been found + } // Update bytes processed - bytesProcessed += nextIndex; + bytes_processed += next_index; // Revert status, as we only check the last ADR request for the channel mask KO status = 0x07; - if (linkAdrParams.ChMaskCtrl == 6) { + if (adr_settings.ch_mask_ctrl == 6) { // Enable all 125 kHz channels - channelsMask[0] = 0xFFFF; - channelsMask[1] = 0xFFFF; - channelsMask[2] = 0xFFFF; - channelsMask[3] = 0xFFFF; + temp_channel_masks[0] = 0xFFFF; + temp_channel_masks[1] = 0xFFFF; + temp_channel_masks[2] = 0xFFFF; + temp_channel_masks[3] = 0xFFFF; // Apply chMask to channels 64 to 71 - channelsMask[4] = linkAdrParams.ChMask; - } else if (linkAdrParams.ChMaskCtrl == 7) { + temp_channel_masks[4] = adr_settings.channel_mask; + } else if (adr_settings.ch_mask_ctrl == 7) { // Disable all 125 kHz channels - channelsMask[0] = 0x0000; - channelsMask[1] = 0x0000; - channelsMask[2] = 0x0000; - channelsMask[3] = 0x0000; + temp_channel_masks[0] = 0x0000; + temp_channel_masks[1] = 0x0000; + temp_channel_masks[2] = 0x0000; + temp_channel_masks[3] = 0x0000; // Apply chMask to channels 64 to 71 - channelsMask[4] = linkAdrParams.ChMask; - } else if (linkAdrParams.ChMaskCtrl == 5) { + temp_channel_masks[4] = adr_settings.channel_mask; + } else if (adr_settings.ch_mask_ctrl == 5) { // RFU status &= 0xFE; // Channel mask KO } else { - channelsMask[linkAdrParams.ChMaskCtrl] = linkAdrParams.ChMask; + temp_channel_masks[adr_settings.ch_mask_ctrl] = adr_settings.channel_mask; } } // FCC 15.247 paragraph F mandates to hop on at least 2 125 kHz channels - if ((linkAdrParams.Datarate < DR_6) - && (num_active_channels(channelsMask, 0, 4) < 2)) { + if ((adr_settings.datarate < DR_6) + && (num_active_channels(temp_channel_masks, 0, 4) < 2)) { status &= 0xFE; // Channel mask KO } - // Get the minimum possible datarate - getPhy.Attribute = PHY_MIN_TX_DR; - getPhy.UplinkDwellTime = linkAdrReq->UplinkDwellTime; - phyParam = get_phy_params(&getPhy); + verify_params.status = status; + verify_params.adr_enabled = params->adr_enabled; + verify_params.datarate = adr_settings.datarate; + verify_params.tx_power = adr_settings.tx_power; + verify_params.nb_rep = adr_settings.nb_rep; + verify_params.current_datarate = params->current_datarate; + verify_params.current_tx_power = params->current_tx_power; + verify_params.current_nb_rep = params->current_nb_rep; + verify_params.channel_mask = temp_channel_masks; - linkAdrVerifyParams.Status = status; - linkAdrVerifyParams.AdrEnabled = linkAdrReq->AdrEnabled; - linkAdrVerifyParams.Datarate = linkAdrParams.Datarate; - linkAdrVerifyParams.TxPower = linkAdrParams.TxPower; - linkAdrVerifyParams.NbRep = linkAdrParams.NbRep; - linkAdrVerifyParams.CurrentDatarate = linkAdrReq->CurrentDatarate; - linkAdrVerifyParams.CurrentTxPower = linkAdrReq->CurrentTxPower; - linkAdrVerifyParams.CurrentNbRep = linkAdrReq->CurrentNbRep; - linkAdrVerifyParams.NbChannels = AU915_MAX_NB_CHANNELS; - linkAdrVerifyParams.ChannelsMask = channelsMask; - linkAdrVerifyParams.MinDatarate = (int8_t) phyParam.Value; - linkAdrVerifyParams.MaxDatarate = AU915_TX_MAX_DATARATE; - linkAdrVerifyParams.Channels = Channels; - linkAdrVerifyParams.MinTxPower = AU915_MIN_TX_POWER; - linkAdrVerifyParams.MaxTxPower = AU915_MAX_TX_POWER; // Verify the parameters and update, if necessary - status = verify_link_ADR_req(&linkAdrVerifyParams, &linkAdrParams.Datarate, - &linkAdrParams.TxPower, &linkAdrParams.NbRep); + status = verify_link_ADR_req(&verify_params, &adr_settings.datarate, + &adr_settings.tx_power, &adr_settings.nb_rep); // Update channelsMask if everything is correct if (status == 0x07) { // Copy Mask - copy_channel_mask(ChannelsMask, channelsMask, 6); + copy_channel_mask(channel_masks, temp_channel_masks, AU915_CHANNELS_MASK_SIZE); - ChannelsMaskRemaining[0] &= ChannelsMask[0]; - ChannelsMaskRemaining[1] &= ChannelsMask[1]; - ChannelsMaskRemaining[2] &= ChannelsMask[2]; - ChannelsMaskRemaining[3] &= ChannelsMask[3]; - ChannelsMaskRemaining[4] = ChannelsMask[4]; - ChannelsMaskRemaining[5] = ChannelsMask[5]; + current_channel_masks[0] &= channel_masks[0]; + current_channel_masks[1] &= channel_masks[1]; + current_channel_masks[2] &= channel_masks[2]; + current_channel_masks[3] &= channel_masks[3]; + current_channel_masks[4] = channel_masks[4]; } // Update status variables - *drOut = linkAdrParams.Datarate; - *txPowOut = linkAdrParams.TxPower; - *nbRepOut = linkAdrParams.NbRep; - *nbBytesParsed = bytesProcessed; + *dr_out = adr_settings.datarate; + *tx_power_out = adr_settings.tx_power; + *nb_rep_out = adr_settings.nb_rep; + *nb_bytes_parsed = bytes_processed; return status; } -uint8_t LoRaPHYAU915::setup_rx_params(RxParamSetupReqParams_t* rxParamSetupReq) +uint8_t LoRaPHYAU915::accept_rx_param_setup_req(rx_param_setup_req_t* params) { uint8_t status = 0x07; - uint32_t freq = rxParamSetupReq->Frequency; + uint32_t freq = params->frequency; // Verify radio frequency + _radio->lock(); + if ((_radio->check_rf_frequency(freq) == false) || (freq < AU915_FIRST_RX1_CHANNEL) || (freq > AU915_LAST_RX1_CHANNEL) @@ -818,126 +520,97 @@ uint8_t LoRaPHYAU915::setup_rx_params(RxParamSetupReqParams_t* rxParamSetupReq) status &= 0xFE; // Channel frequency KO } + _radio->unlock(); + // Verify datarate - if (val_in_range(rxParamSetupReq->Datarate, AU915_RX_MIN_DATARATE, - AU915_RX_MAX_DATARATE) == 0) { + if (val_in_range(params->datarate, AU915_RX_MIN_DATARATE, AU915_RX_MAX_DATARATE) == 0) { status &= 0xFD; // Datarate KO } - if ((rxParamSetupReq->Datarate == DR_7) - || (rxParamSetupReq->Datarate > DR_13)) { + + if ((params->datarate == DR_7) || (params->datarate > DR_13)) { status &= 0xFD; // Datarate KO } // Verify datarate offset - if (val_in_range(rxParamSetupReq->DrOffset, AU915_MIN_RX1_DR_OFFSET, - AU915_MAX_RX1_DR_OFFSET) == 0) { + if (val_in_range(params->dr_offset, AU915_MIN_RX1_DR_OFFSET, AU915_MAX_RX1_DR_OFFSET) == 0) { status &= 0xFB; // Rx1DrOffset range KO } return status; } -uint8_t LoRaPHYAU915::request_new_channel(NewChannelReqParams_t* newChannelReq) -{ - // Datarate and frequency KO - return 0; -} - -int8_t LoRaPHYAU915::setup_tx_params(TxParamSetupReqParams_t* txParamSetupReq) -{ - return -1; -} - -uint8_t LoRaPHYAU915::dl_channel_request(DlChannelReqParams_t* dlChannelReq) -{ - return 0; -} - -int8_t LoRaPHYAU915::get_alternate_DR(AlternateDrParams_t* alternateDr) +int8_t LoRaPHYAU915::get_alternate_DR(uint8_t nb_trials) { int8_t datarate = 0; // Re-enable 500 kHz default channels - ChannelsMask[4] = 0x00FF; + channel_masks[4] = 0x00FF; - if ((alternateDr->NbTrials & 0x01) == 0x01) { + if ((nb_trials & 0x01) == 0x01) { datarate = DR_6; } else { datarate = DR_0; } + return datarate; } -void LoRaPHYAU915::calculate_backoff(CalcBackOffParams_t* calcBackOff) -{ - RegionCommonCalcBackOffParams_t calcBackOffParams; - - calcBackOffParams.Channels = Channels; - calcBackOffParams.Bands = Bands; - calcBackOffParams.LastTxIsJoinRequest = calcBackOff->LastTxIsJoinRequest; - calcBackOffParams.Joined = calcBackOff->Joined; - calcBackOffParams.DutyCycleEnabled = calcBackOff->DutyCycleEnabled; - calcBackOffParams.Channel = calcBackOff->Channel; - calcBackOffParams.ElapsedTime = calcBackOff->ElapsedTime; - calcBackOffParams.TxTimeOnAir = calcBackOff->TxTimeOnAir; - - get_DC_backoff(&calcBackOffParams); -} - -bool LoRaPHYAU915::set_next_channel(NextChanParams_t* nextChanParams, +bool LoRaPHYAU915::set_next_channel(channel_selection_params_t* next_chan_params, uint8_t* channel, lorawan_time_t* time, - lorawan_time_t* aggregatedTimeOff) + lorawan_time_t* aggregated_timeOff) { - uint8_t nbEnabledChannels = 0; - uint8_t delayTx = 0; - uint8_t enabledChannels[AU915_MAX_NB_CHANNELS] = { 0 }; - lorawan_time_t nextTxDelay = 0; + uint8_t nb_enabled_channels = 0; + uint8_t delay_tx = 0; + uint8_t enabled_channels[AU915_MAX_NB_CHANNELS] = { 0 }; + lorawan_time_t next_tx_delay = 0; // Count 125kHz channels - if (num_active_channels(ChannelsMaskRemaining, 0, 4) == 0) { // Reactivate default channels - copy_channel_mask(ChannelsMaskRemaining, ChannelsMask, 4); + if (num_active_channels(current_channel_masks, 0, 4) == 0) { + // Reactivate 125 kHz default channels + copy_channel_mask(current_channel_masks, channel_masks, 4); } + // Check other channels - if (nextChanParams->Datarate >= DR_6) { - if ((ChannelsMaskRemaining[4] & 0x00FF) == 0) { - ChannelsMaskRemaining[4] = ChannelsMask[4]; + if (next_chan_params->current_datarate >= DR_6) { + if ((current_channel_masks[4] & 0x00FF) == 0) { + // fall back to 500 kHz default channels + current_channel_masks[4] = channel_masks[4]; } } - if (nextChanParams->AggrTimeOff - <= _lora_time.TimerGetElapsedTime(nextChanParams->LastAggrTx)) { + if (next_chan_params->aggregate_timeoff <= _lora_time.TimerGetElapsedTime(next_chan_params->last_aggregate_tx_time)) { // Reset Aggregated time off - *aggregatedTimeOff = 0; + *aggregated_timeOff = 0; // Update bands Time OFF - nextTxDelay = update_band_timeoff(nextChanParams->Joined, - nextChanParams->DutyCycleEnabled, - Bands, AU915_MAX_NB_BANDS); + next_tx_delay = update_band_timeoff(next_chan_params->joined, + next_chan_params->dc_enabled, + bands, AU915_MAX_NB_BANDS); // Search how many channels are enabled - nbEnabledChannels = CountNbOfEnabledChannels(nextChanParams->Datarate, - ChannelsMaskRemaining, - Channels, Bands, - enabledChannels, &delayTx); + nb_enabled_channels = enabled_channel_count(next_chan_params->joined, + next_chan_params->current_datarate, + current_channel_masks, + AU915_CHANNELS_MASK_SIZE, + enabled_channels, &delay_tx); } else { - delayTx++; - nextTxDelay = nextChanParams->AggrTimeOff - - _lora_time.TimerGetElapsedTime(nextChanParams->LastAggrTx); + delay_tx++; + next_tx_delay = next_chan_params->aggregate_timeoff - _lora_time.TimerGetElapsedTime(next_chan_params->last_aggregate_tx_time); } - if (nbEnabledChannels > 0) { + if (nb_enabled_channels > 0) { // We found a valid channel - *channel = enabledChannels[get_random(0, nbEnabledChannels - 1)]; + *channel = enabled_channels[get_random(0, nb_enabled_channels - 1)]; // Disable the channel in the mask - disable_channel(ChannelsMaskRemaining, *channel, - AU915_MAX_NB_CHANNELS - 8); + disable_channel(current_channel_masks, *channel, + AU915_MAX_NB_CHANNELS - 8); *time = 0; return true; } else { - if (delayTx > 0) { + if (delay_tx > 0) { // Delay transmission due to AggregatedTimeOff or to a band time off - *time = nextTxDelay; + *time = next_tx_delay; return true; } // Datarate not supported by any channel @@ -946,37 +619,9 @@ bool LoRaPHYAU915::set_next_channel(NextChanParams_t* nextChanParams, } } -lorawan_status_t LoRaPHYAU915::add_channel(ChannelAddParams_t* channelAdd) +uint8_t LoRaPHYAU915::apply_DR_offset(int8_t dr, int8_t dr_offset) { - return LORAWAN_STATUS_PARAMETER_INVALID; -} - -bool LoRaPHYAU915::remove_channel(ChannelRemoveParams_t* channelRemove) -{ - return LORAWAN_STATUS_PARAMETER_INVALID; -} - -void LoRaPHYAU915::set_tx_cont_mode(ContinuousWaveParams_t* continuousWave) -{ - int8_t txPowerLimited = LimitTxPower( - continuousWave->TxPower, - Bands[Channels[continuousWave->Channel].band].max_tx_pwr, - continuousWave->Datarate, ChannelsMask); - int8_t phyTxPower = 0; - uint32_t frequency = Channels[continuousWave->Channel].frequency; - - // Calculate physical TX power - phyTxPower = compute_tx_power(txPowerLimited, continuousWave->MaxEirp, - continuousWave->AntennaGain); - - _radio->set_tx_continuous_wave(frequency, phyTxPower, - continuousWave->Timeout); -} - -uint8_t LoRaPHYAU915::apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, - int8_t drOffset) -{ - int8_t datarate = DatarateOffsetsAU915[dr][drOffset]; + int8_t datarate = datarate_offsets_AU915[dr][dr_offset]; if (datarate < 0) { datarate = DR_0; diff --git a/features/lorawan/lorastack/phy/LoRaPHYAU915.h b/features/lorawan/lorastack/phy/LoRaPHYAU915.h index bc26d2ee10..7d30e39d30 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYAU915.h +++ b/features/lorawan/lorastack/phy/LoRaPHYAU915.h @@ -34,7 +34,6 @@ #define MBED_OS_LORAPHY_AU915_H_ #include "LoRaPHY.h" -#include "netsocket/LoRaRadio.h" // Definitions /*! @@ -47,7 +46,7 @@ */ #define AU915_MAX_NB_BANDS 1 -#define AU915_CHANNELS_MASK_SIZE 6 +#define AU915_CHANNELS_MASK_SIZE 5 class LoRaPHYAU915 : public LoRaPHY{ @@ -57,317 +56,52 @@ public: LoRaPHYAU915(LoRaWANTimeHandler &lora_time); virtual ~LoRaPHYAU915(); - /*! - * \brief The function gets a value of a specific PHY attribute. - * - * \param [in] getPhy A pointer to the function parameters. - * - * \retval A structure containing the PHY parameter. - */ - virtual PhyParam_t get_phy_params(GetPhyParams_t* getPhy ); + virtual bool rx_config(rx_config_params_t* config, int8_t* datarate); - /*! - * \brief Updates the last TX done parameters of the current channel. - * - * \param [in] txDone A pointer to the function parameters. - */ - virtual void set_band_tx_done(SetBandTxDoneParams_t* txDone ); + virtual bool tx_config(tx_config_params_t* config, int8_t* txPower, + lorawan_time_t* txTimeOnAir); - /*! - * \brief Initializes the channels masks and the channels. - * - * \param [in] type Sets the initialization type. - */ - virtual void load_defaults(InitType_t type ); - - /*! - * \brief Verifies a parameter. - * - * \param [in] verify A pointer to the function parameters. - * - * \param [in] phyAttribute The attribute to be verified. - * - * \retval True, if the parameter is valid. - */ - virtual bool verify(VerifyParams_t* verify, PhyAttribute_t phyAttribute ); - - /*! - * \brief The function parses the input buffer and sets up the channels of the - * CF list. - * - * \param [in] applyCFList A pointer to the function parameters. - */ - virtual void apply_cf_list(ApplyCFListParams_t* applyCFList ); - - /*! - * \brief Sets a channels mask. - * - * \param [in] chanMaskSet A pointer to the function parameters. - * - * \retval True, if the channels mask could be set. - */ - virtual bool set_channel_mask(ChanMaskSetParams_t* chanMaskSet ); - - /*! - * \brief Calculates the next datarate to set, when ADR is on or off. - * - * \param [in] adrNext A pointer to the function parameters. - * - * \param [out] drOut The calculated datarate for the next TX. - * - * \param [out] txPowOut The TX power for the next TX. - * - * \param [out] adrAckCounter The calculated ADR acknowledgement counter. - * - * \retval True, if an ADR request should be performed. - */ - virtual bool get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut, - int8_t* txPowOut, uint32_t* adrAckCounter ); - - /*! - * \brief Configuration of the RX windows. - * - * \param [in] rxConfig A pointer to the function parameters. - * - * \param [out] datarate The datarate index set. - * - * \retval True, if the configuration was applied successfully. - */ - virtual bool rx_config(rx_config_params_t* rxConfig, int8_t* datarate ); - - /* - * RX window precise timing - * - * For more details please consult the following document, chapter 3.1.2. - * http://www.semtech.com/images/datasheet/SX1272_settings_for_LoRaWAN_v2.0.pdf - * or - * http://www.semtech.com/images/datasheet/SX1276_settings_for_LoRaWAN_v2.0.pdf - * - * Downlink start: T = Tx + 1s (+/- 20 us) - * | - * TRxEarly | TRxLate - * | | | - * | | +---+---+---+---+---+---+---+---+ - * | | | Latest Rx window | - * | | +---+---+---+---+---+---+---+---+ - * | | | - * +---+---+---+---+---+---+---+---+ - * | Earliest Rx window | - * +---+---+---+---+---+---+---+---+ - * | - * +---+---+---+---+---+---+---+---+ - *Downlink preamble 8 symbols | | | | | | | | | - * +---+---+---+---+---+---+---+---+ - * - * Worst case Rx window timings - * - * TRxLate = DEFAULT_MIN_RX_SYMBOLS * tSymbol - RADIO_WAKEUP_TIME - * TRxEarly = 8 - DEFAULT_MIN_RX_SYMBOLS * tSymbol - RxWindowTimeout - RADIO_WAKEUP_TIME - * - * TRxLate - TRxEarly = 2 * DEFAULT_SYSTEM_MAX_RX_ERROR - * - * RxOffset = ( TRxLate + TRxEarly ) / 2 - * - * RxWindowTimeout = ( 2 * DEFAULT_MIN_RX_SYMBOLS - 8 ) * tSymbol + 2 * DEFAULT_SYSTEM_MAX_RX_ERROR - * RxOffset = 4 * tSymbol - RxWindowTimeout / 2 - RADIO_WAKE_UP_TIME - * - * The minimum value of RxWindowTimeout must be 5 symbols which implies that the system always tolerates at least an error of 1.5 * tSymbol - */ - /*! - * Computes the Rx window timeout and offset. - * - * \param [in] datarate The RX window datarate index to be used. - * - * \param [in] minRxSymbols The minimum number of symbols required to detect an RX frame. - * - * \param [in] rxError The system maximum timing error of the receiver in milliseconds. - * The receiver will turn on in a [-rxError : +rxError] ms - * interval around RxOffset. - * - * \param [out] rxConfigParams The updated WindowTimeout and WindowOffset fields. - */ - virtual void compute_rx_win_params(int8_t datarate, - uint8_t minRxSymbols, - uint32_t rxError, - rx_config_params_t *rxConfigParams); - - /*! - * \brief TX configuration. - * - * \param [in] txConfig A pointer to the function parameters. - * - * \param [out] txPower The TX power index set. - * - * \param [out] txTimeOnAir The time-on-air of the frame. - * - * \retval True, if the configuration was applied successfully. - */ - virtual bool tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - lorawan_time_t* txTimeOnAir ); - - /*! - * \brief The function processes a Link ADR Request. - * - * \param [in] linkAdrReq A pointer to the function parameters. - * - * \param [out] drOut The datarate applied. - * - * \param [out] txPowOut The TX power applied. - * - * \param [out] nbRepOut The number of repetitions to apply. - * - * \param [out] nbBytesParsed The number bytes parsed. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t link_ADR_request(LinkAdrReqParams_t* linkAdrReq, + virtual uint8_t link_ADR_request(adr_req_params_t* params, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, - uint8_t* nbBytesParsed ); + uint8_t* nbBytesParsed); - /*! - * \brief The function processes a RX parameter setup request. - * - * \param [in] rxParamSetupReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t setup_rx_params(RxParamSetupReqParams_t* rxParamSetupReq ); + virtual uint8_t accept_rx_param_setup_req(rx_param_setup_req_t* params); - /*! - * \brief The function processes a new channel request. - * - * \param [in] newChannelReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t request_new_channel(NewChannelReqParams_t* newChannelReq ); + virtual int8_t get_alternate_DR(uint8_t nb_trials); - /*! - * \brief The function processes a TX ParamSetup request. - * - * \param [in] txParamSetupReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - * Returns -1, if the functionality is not implemented. In this case, the end node - * shall ignore the command. - */ - virtual int8_t setup_tx_params(TxParamSetupReqParams_t* txParamSetupReq ); + virtual bool set_next_channel(channel_selection_params_t* next_chan_params, + uint8_t* channel, lorawan_time_t* time, + lorawan_time_t* aggregate_timeoff); - /*! - * \brief The function processes a DlChannel request. - * - * \param [in] dlChannelReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t dl_channel_request(DlChannelReqParams_t* dlChannelReq ); - - /*! - * \brief Alternates the datarate of the channel for the join request. - * - * \param [in] alternateDr A pointer to the function parameters. - * - * \retval The datarate to apply. - */ - virtual int8_t get_alternate_DR(AlternateDrParams_t* alternateDr ); - - /*! - * \brief Calculates the back-off time. - * - * \param [in] calcBackOff A pointer to the function parameters. - */ - virtual void calculate_backoff(CalcBackOffParams_t* calcBackOff ); - - /*! - * \brief Searches and sets the next random available channel. - * - * \param [in] nextChanParams The parameters for the next channel. - * - * \param [out] channel The next channel to use for TX. - * - * \param [out] time The time to wait for the next transmission according to the duty - * cycle. - * - * \param [out] aggregatedTimeOff Updates the aggregated time off. - * - * \retval The function status [1: OK, 0: Unable to find a channel on the current datarate]. - */ - virtual bool set_next_channel(NextChanParams_t* nextChanParams, - uint8_t* channel, lorawan_time_t* time, - lorawan_time_t* aggregatedTimeOff ); - - /*! - * \brief Adds a channel. - * - * \param [in] channelAdd A pointer to the function parameters. - * - * \retval The status of the operation. - */ - virtual lorawan_status_t add_channel(ChannelAddParams_t* channelAdd ); - - /*! - * \brief Removes a channel. - * - * \param [in] channelRemove A pointer to the function parameters. - * - * \retval True, if the channel was removed successfully. - */ - virtual bool remove_channel(ChannelRemoveParams_t* channelRemove ); - - /*! - * \brief Sets the radio into continuous wave mode. - * - * \param [in] continuousWave A pointer to the function parameters. - */ - virtual void set_tx_cont_mode(ContinuousWaveParams_t* continuousWave ); - - /*! - * \brief Computes a new datarate according to the given offset. - * - * \param [in] downlinkDwellTime The downlink dwell time configuration. 0: No limit, 1: 400ms - * - * \param [in] dr The current datarate. - * - * \param [in] drOffset The offset to be applied. - * - * \retval newDr The computed datarate. - */ - virtual uint8_t apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ); + virtual uint8_t apply_DR_offset(int8_t dr, int8_t dr_offset); private: - uint8_t CountNbOfEnabledChannels(uint8_t datarate, - uint16_t* channelsMask, - channel_params_t* channels, - band_t* bands, uint8_t* enabledChannels, - uint8_t* delayTx); - - // Global attributes /*! * LoRaMAC channels */ - channel_params_t Channels[AU915_MAX_NB_CHANNELS]; + channel_params_t channels[AU915_MAX_NB_CHANNELS]; /*! * LoRaMac bands */ - band_t Bands[AU915_MAX_NB_BANDS]; + band_t bands[AU915_MAX_NB_BANDS]; /*! * LoRaMac channels mask */ - uint16_t ChannelsMask[AU915_CHANNELS_MASK_SIZE]; + uint16_t channel_masks[AU915_CHANNELS_MASK_SIZE]; /*! * LoRaMac channels remaining */ - uint16_t ChannelsMaskRemaining[AU915_CHANNELS_MASK_SIZE]; + uint16_t current_channel_masks[AU915_CHANNELS_MASK_SIZE]; /*! * LoRaMac channels default mask */ - uint16_t ChannelsDefaultMask[AU915_CHANNELS_MASK_SIZE]; + uint16_t default_channel_masks[AU915_CHANNELS_MASK_SIZE]; }; #endif /* MBED_OS_LORAPHY_AU915_H_ */ diff --git a/features/lorawan/lorastack/phy/LoRaPHYCN470.cpp b/features/lorawan/lorastack/phy/LoRaPHYCN470.cpp index 4be2cf8562..eb5d0512b6 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYCN470.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYCN470.cpp @@ -30,9 +30,7 @@ */ #include "LoRaPHYCN470.h" - #include "lora_phy_ds.h" -#include "LoRaRadio.h" /*! * Minimal datarate that can be used by the node @@ -168,813 +166,347 @@ * Band 0 definition * { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff } */ -#define CN470_BAND0 { 1, CN470_MAX_TX_POWER, 0, 0, 0 } // 100.0 % +static const band_t CN470_BAND0 = {1, CN470_MAX_TX_POWER, 0, 0, 0}; // 100.0 % /*! * Defines the first channel for RX window 1 for CN470 band */ -#define CN470_FIRST_RX1_CHANNEL ( (uint32_t) 500300000 ) +#define CN470_FIRST_RX1_CHANNEL ((uint32_t) 500300000) /*! * Defines the last channel for RX window 1 for CN470 band */ -#define CN470_LAST_RX1_CHANNEL ( (uint32_t) 509700000 ) +#define CN470_LAST_RX1_CHANNEL ((uint32_t) 509700000) /*! * Defines the step width of the channels for RX window 1 */ -#define CN470_STEPWIDTH_RX1_CHANNEL ( (uint32_t) 200000 ) +#define CN470_STEPWIDTH_RX1_CHANNEL ((uint32_t) 200000) /*! * Data rates table definition */ -static const uint8_t DataratesCN470[] = { 12, 11, 10, 9, 8, 7 }; +static const uint8_t datarates_CN470[] = {12, 11, 10, 9, 8, 7}; /*! * Bandwidths table definition in Hz */ -static const uint32_t BandwidthsCN470[] = { 125000, 125000, 125000, 125000, 125000, 125000 }; +static const uint32_t bandwidths_CN470[] = {125000, 125000, 125000, 125000, 125000, 125000}; /*! * Maximum payload with respect to the datarate index. Cannot operate with repeater. */ -static const uint8_t MaxPayloadOfDatarateCN470[] = { 51, 51, 51, 115, 222, 222 }; +static const uint8_t max_payloads_CN470[] = {51, 51, 51, 115, 222, 222}; /*! * Maximum payload with respect to the datarate index. Can operate with repeater. */ -static const uint8_t MaxPayloadOfDatarateRepeaterCN470[] = { 51, 51, 51, 115, 222, 222 }; +static const uint8_t max_payloads_with_repeater_CN470[] = {51, 51, 51, 115, 222, 222}; -// Static functions -static int8_t GetNextLowerTxDr( int8_t dr, int8_t minDr ) -{ - uint8_t nextLowerDr = 0; - - if( dr == minDr ) - { - nextLowerDr = minDr; - } - else - { - nextLowerDr = dr - 1; - } - return nextLowerDr; -} - -static uint32_t GetBandwidth( uint32_t drIndex ) -{ - switch( BandwidthsCN470[drIndex] ) - { - default: - case 125000: - return 0; - case 250000: - return 1; - case 500000: - return 2; - } -} - -static int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower, int8_t datarate, uint16_t* channelsMask ) -{ - int8_t txPowerResult = txPower; - - // Limit tx power to the band max - txPowerResult = MAX( txPower, maxBandTxPower ); - - return txPowerResult; -} - -uint8_t LoRaPHYCN470::CountNbOfEnabledChannels( uint8_t datarate, uint16_t* channelsMask, channel_params_t* channels, band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ) -{ - uint8_t nbEnabledChannels = 0; - uint8_t delayTransmission = 0; - - for( uint8_t i = 0, k = 0; i < CN470_MAX_NB_CHANNELS; i += 16, k++ ) - { - for( uint8_t j = 0; j < 16; j++ ) - { - if( ( channelsMask[k] & ( 1 << j ) ) != 0 ) - { - if( channels[i + j].frequency == 0 ) - { // Check if the channel is enabled - continue; - } - if( val_in_range( datarate, channels[i + j].dr_range.fields.min, - channels[i + j].dr_range.fields.max ) == 0 ) - { // Check if the current channel selection supports the given datarate - continue; - } - if( bands[channels[i + j].band].off_time > 0 ) - { // Check if the band is available for transmission - delayTransmission++; - continue; - } - enabledChannels[nbEnabledChannels++] = i + j; - } - } - } - - *delayTx = delayTransmission; - return nbEnabledChannels; -} LoRaPHYCN470::LoRaPHYCN470(LoRaWANTimeHandler &lora_time) - : LoRaPHY(lora_time) + : LoRaPHY(lora_time) { - const band_t band0 = CN470_BAND0; - Bands[0] = band0; + bands[0] = CN470_BAND0; + + // Channels + // 125 kHz channels + for( uint8_t i = 0; i < CN470_MAX_NB_CHANNELS; i++ ) + { + channels[i].frequency = 470300000 + i * 200000; + channels[i].dr_range.value = ( DR_5 << 4 ) | DR_0; + channels[i].band = 0; + } + + // Initialize the channels default mask + default_channel_masks[0] = 0xFFFF; + default_channel_masks[1] = 0xFFFF; + default_channel_masks[2] = 0xFFFF; + default_channel_masks[3] = 0xFFFF; + default_channel_masks[4] = 0xFFFF; + default_channel_masks[5] = 0xFFFF; + + // Update the channels mask + copy_channel_mask(channel_masks, default_channel_masks, CN470_CHANNELS_MASK_SIZE); + + // set default channels + phy_params.channels.channel_list = channels; + phy_params.channels.channel_list_size = CN470_MAX_NB_CHANNELS; + phy_params.channels.mask_list = channel_masks; + phy_params.channels.default_mask_list = default_channel_masks; + phy_params.channels.mask_list_size = CN470_CHANNELS_MASK_SIZE; + + // set bands for CN470 spectrum + phy_params.bands.table = (void *) bands; + phy_params.bands.size = CN470_MAX_NB_BANDS; + + // set bandwidths available in CN470 spectrum + phy_params.bandwidths.table = (void *) bandwidths_CN470; + phy_params.bandwidths.size = 6; + + // set data rates available in CN470 spectrum + phy_params.datarates.table = (void *) datarates_CN470; + phy_params.datarates.size = 6; + + // set payload sizes with respect to data rates + phy_params.payloads.table = (void *) max_payloads_CN470; + phy_params.payloads.size = 6; + phy_params.payloads_with_repeater.table = (void *)max_payloads_with_repeater_CN470; + phy_params.payloads.size = 6; + + // dwell time setting + phy_params.ul_dwell_time_setting = 0; + phy_params.dl_dwell_time_setting = 0; + + // set initial and default parameters + phy_params.duty_cycle_enabled = CN470_DUTY_CYCLE_ENABLED; + + phy_params.accept_tx_param_setup_req = false; + phy_params.fsk_supported = false; + phy_params.cflist_supported = false; + phy_params.dl_channel_req_supported = false; + phy_params.custom_channelplans_supported = false; + + phy_params.default_channel_cnt = CN470_MAX_NB_CHANNELS; + phy_params.max_channel_cnt = CN470_MAX_NB_CHANNELS; + phy_params.cflist_channel_cnt = 0; + phy_params.min_tx_datarate = CN470_TX_MIN_DATARATE; + phy_params.max_tx_datarate = CN470_TX_MAX_DATARATE; + phy_params.min_rx_datarate = CN470_RX_MIN_DATARATE; + phy_params.max_rx_datarate = CN470_RX_MAX_DATARATE; + phy_params.default_datarate = CN470_DEFAULT_DATARATE; + phy_params.default_max_datarate = CN470_TX_MAX_DATARATE; + phy_params.min_rx1_dr_offset = CN470_MIN_RX1_DR_OFFSET; + phy_params.max_rx1_dr_offset = CN470_MAX_RX1_DR_OFFSET; + phy_params.default_rx1_dr_offset = CN470_DEFAULT_RX1_DR_OFFSET; + phy_params.min_tx_power = CN470_MIN_TX_POWER; + phy_params.max_tx_power = CN470_MAX_TX_POWER; + phy_params.default_tx_power = CN470_DEFAULT_TX_POWER; + phy_params.default_max_eirp = CN470_DEFAULT_MAX_EIRP; + phy_params.default_antenna_gain = CN470_DEFAULT_ANTENNA_GAIN; + phy_params.adr_ack_limit = CN470_ADR_ACK_LIMIT; + phy_params.adr_ack_delay = CN470_ADR_ACK_DELAY; + phy_params.max_rx_window = CN470_MAX_RX_WINDOW; + phy_params.recv_delay1 = CN470_RECEIVE_DELAY1; + phy_params.recv_delay2 = CN470_RECEIVE_DELAY2; + + phy_params.join_accept_delay1 = CN470_JOIN_ACCEPT_DELAY1; + phy_params.join_accept_delay2 = CN470_JOIN_ACCEPT_DELAY2; + phy_params.max_fcnt_gap = CN470_MAX_FCNT_GAP; + phy_params.ack_timeout = CN470_ACKTIMEOUT; + phy_params.ack_timeout_rnd = CN470_ACK_TIMEOUT_RND; + phy_params.rx_window2_datarate = CN470_RX_WND_2_DR; + phy_params.rx_window2_frequency = CN470_RX_WND_2_FREQ; } LoRaPHYCN470::~LoRaPHYCN470() { } -PhyParam_t LoRaPHYCN470::get_phy_params(GetPhyParams_t* getPhy) +bool LoRaPHYCN470::rx_config(rx_config_params_t* config, int8_t* datarate) { - PhyParam_t phyParam = { 0 }; + int8_t dr = config->datarate; + uint8_t max_payload = 0; + int8_t phy_dr = 0; + uint32_t frequency = config->frequency; - switch( getPhy->Attribute ) - { - case PHY_MIN_RX_DR: - { - phyParam.Value = CN470_RX_MIN_DATARATE; - break; - } - case PHY_MIN_TX_DR: - { - phyParam.Value = CN470_TX_MIN_DATARATE; - break; - } - case PHY_DEF_TX_DR: - { - phyParam.Value = CN470_DEFAULT_DATARATE; - break; - } - case PHY_NEXT_LOWER_TX_DR: - { - phyParam.Value = GetNextLowerTxDr( getPhy->Datarate, CN470_TX_MIN_DATARATE ); - break; - } - case PHY_DEF_TX_POWER: - { - phyParam.Value = CN470_DEFAULT_TX_POWER; - break; - } - case PHY_MAX_PAYLOAD: - { - phyParam.Value = MaxPayloadOfDatarateCN470[getPhy->Datarate]; - break; - } - case PHY_MAX_PAYLOAD_REPEATER: - { - phyParam.Value = MaxPayloadOfDatarateRepeaterCN470[getPhy->Datarate]; - break; - } - case PHY_DUTY_CYCLE: - { - phyParam.Value = CN470_DUTY_CYCLE_ENABLED; - break; - } - case PHY_MAX_RX_WINDOW: - { - phyParam.Value = CN470_MAX_RX_WINDOW; - break; - } - case PHY_RECEIVE_DELAY1: - { - phyParam.Value = CN470_RECEIVE_DELAY1; - break; - } - case PHY_RECEIVE_DELAY2: - { - phyParam.Value = CN470_RECEIVE_DELAY2; - break; - } - case PHY_JOIN_ACCEPT_DELAY1: - { - phyParam.Value = CN470_JOIN_ACCEPT_DELAY1; - break; - } - case PHY_JOIN_ACCEPT_DELAY2: - { - phyParam.Value = CN470_JOIN_ACCEPT_DELAY2; - break; - } - case PHY_MAX_FCNT_GAP: - { - phyParam.Value = CN470_MAX_FCNT_GAP; - break; - } - case PHY_ACK_TIMEOUT: - { - phyParam.Value = ( CN470_ACKTIMEOUT + get_random( -CN470_ACK_TIMEOUT_RND, CN470_ACK_TIMEOUT_RND ) ); - break; - } - case PHY_DEF_DR1_OFFSET: - { - phyParam.Value = CN470_DEFAULT_RX1_DR_OFFSET; - break; - } - case PHY_DEF_RX2_FREQUENCY: - { - phyParam.Value = CN470_RX_WND_2_FREQ; - break; - } - case PHY_DEF_RX2_DR: - { - phyParam.Value = CN470_RX_WND_2_DR; - break; - } - case PHY_CHANNELS_MASK: - { - phyParam.ChannelsMask = ChannelsMask; - break; - } - case PHY_CHANNELS_DEFAULT_MASK: - { - phyParam.ChannelsMask = ChannelsDefaultMask; - break; - } - case PHY_MAX_NB_CHANNELS: - { - phyParam.Value = CN470_MAX_NB_CHANNELS; - break; - } - case PHY_CHANNELS: - { - phyParam.Channels = Channels; - break; - } - case PHY_DEF_UPLINK_DWELL_TIME: - case PHY_DEF_DOWNLINK_DWELL_TIME: - { - phyParam.Value = 0; - break; - } - case PHY_DEF_MAX_EIRP: - { - phyParam.fValue = CN470_DEFAULT_MAX_EIRP; - break; - } - case PHY_DEF_ANTENNA_GAIN: - { - phyParam.fValue = CN470_DEFAULT_ANTENNA_GAIN; - break; - } - case PHY_NB_JOIN_TRIALS: - case PHY_DEF_NB_JOIN_TRIALS: - { - phyParam.Value = 48; - break; - } - default: - { - break; - } - } + _radio->lock(); - return phyParam; -} - -void LoRaPHYCN470::set_band_tx_done(SetBandTxDoneParams_t* txDone) -{ - set_last_tx_done( txDone->Joined, &Bands[Channels[txDone->Channel].band], txDone->LastTxDoneTime ); -} - -void LoRaPHYCN470::load_defaults(InitType_t type) -{ - switch( type ) - { - case INIT_TYPE_INIT: - { - // Channels - // 125 kHz channels - for( uint8_t i = 0; i < CN470_MAX_NB_CHANNELS; i++ ) - { - Channels[i].frequency = 470300000 + i * 200000; - Channels[i].dr_range.value = ( DR_5 << 4 ) | DR_0; - Channels[i].band = 0; - } - - // Initialize the channels default mask - ChannelsDefaultMask[0] = 0xFFFF; - ChannelsDefaultMask[1] = 0xFFFF; - ChannelsDefaultMask[2] = 0xFFFF; - ChannelsDefaultMask[3] = 0xFFFF; - ChannelsDefaultMask[4] = 0xFFFF; - ChannelsDefaultMask[5] = 0xFFFF; - - // Update the channels mask - copy_channel_mask( ChannelsMask, ChannelsDefaultMask, 6 ); - break; - } - case INIT_TYPE_RESTORE: - { - // Restore channels default mask - copy_channel_mask( ChannelsMask, ChannelsDefaultMask, 6 ); - break; - } - default: - { - break; - } - } -} - -bool LoRaPHYCN470::verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) -{ - switch( phyAttribute ) - { - case PHY_TX_DR: - case PHY_DEF_TX_DR: - { - return val_in_range( verify->DatarateParams.Datarate, CN470_TX_MIN_DATARATE, CN470_TX_MAX_DATARATE ); - } - case PHY_RX_DR: - { - return val_in_range( verify->DatarateParams.Datarate, CN470_RX_MIN_DATARATE, CN470_RX_MAX_DATARATE ); - } - case PHY_DEF_TX_POWER: - case PHY_TX_POWER: - { - // Remark: switched min and max! - return val_in_range( verify->TxPower, CN470_MAX_TX_POWER, CN470_MIN_TX_POWER ); - } - case PHY_DUTY_CYCLE: - { - return CN470_DUTY_CYCLE_ENABLED; - } - case PHY_NB_JOIN_TRIALS: - { - if( verify->NbJoinTrials < 48 ) - { - return false; - } - break; - } - default: - return false; - } - return true; -} - -void LoRaPHYCN470::apply_cf_list(ApplyCFListParams_t* applyCFList) -{ - return; -} - -bool LoRaPHYCN470::set_channel_mask( ChanMaskSetParams_t* chanMaskSet ) -{ - switch( chanMaskSet->ChannelsMaskType ) - { - case CHANNELS_MASK: - { - copy_channel_mask( ChannelsMask, chanMaskSet->ChannelsMaskIn, 6 ); - break; - } - case CHANNELS_DEFAULT_MASK: - { - copy_channel_mask( ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 6 ); - break; - } - default: - return false; - } - return true; -} - -bool LoRaPHYCN470::get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut, - int8_t* txPowOut, uint32_t* adrAckCounter) -{ - bool adrAckReq = false; - int8_t datarate = adrNext->Datarate; - int8_t txPower = adrNext->TxPower; - GetPhyParams_t getPhy; - PhyParam_t phyParam; - - // Report back the adr ack counter - *adrAckCounter = adrNext->AdrAckCounter; - - if( adrNext->AdrEnabled == true ) - { - if( datarate == CN470_TX_MIN_DATARATE ) - { - *adrAckCounter = 0; - adrAckReq = false; - } - else - { - if( adrNext->AdrAckCounter >= CN470_ADR_ACK_LIMIT ) - { - adrAckReq = true; - txPower = CN470_MAX_TX_POWER; - } - else - { - adrAckReq = false; - } - if( adrNext->AdrAckCounter >= ( CN470_ADR_ACK_LIMIT + CN470_ADR_ACK_DELAY ) ) - { - if( ( adrNext->AdrAckCounter % CN470_ADR_ACK_DELAY ) == 1 ) - { - // Decrease the datarate - getPhy.Attribute = PHY_NEXT_LOWER_TX_DR; - getPhy.Datarate = datarate; - getPhy.UplinkDwellTime = adrNext->UplinkDwellTime; - phyParam = get_phy_params(&getPhy); - datarate = phyParam.Value; - - if( datarate == CN470_TX_MIN_DATARATE ) - { - // We must set adrAckReq to false as soon as we reach the lowest datarate - adrAckReq = false; - if( adrNext->UpdateChanMask == true ) - { - // Re-enable default channels - ChannelsMask[0] = 0xFFFF; - ChannelsMask[1] = 0xFFFF; - ChannelsMask[2] = 0xFFFF; - ChannelsMask[3] = 0xFFFF; - ChannelsMask[4] = 0xFFFF; - ChannelsMask[5] = 0xFFFF; - } - } - } - } - } - } - - *drOut = datarate; - *txPowOut = txPower; - return adrAckReq; -} - -void LoRaPHYCN470::compute_rx_win_params(int8_t datarate, uint8_t minRxSymbols, - uint32_t rxError, - rx_config_params_t *rxConfigParams) -{ - double tSymbol = 0.0; - - // Get the datarate, perform a boundary check - rxConfigParams->datarate = MIN( datarate, CN470_RX_MAX_DATARATE ); - rxConfigParams->bandwidth = GetBandwidth( rxConfigParams->datarate ); - - tSymbol = compute_symb_timeout_lora( DataratesCN470[rxConfigParams->datarate], BandwidthsCN470[rxConfigParams->datarate] ); - - get_rx_window_params( tSymbol, minRxSymbols, rxError, RADIO_WAKEUP_TIME, &rxConfigParams->window_timeout, &rxConfigParams->window_offset ); -} - -bool LoRaPHYCN470::rx_config(rx_config_params_t* rxConfig, int8_t* datarate) -{ - int8_t dr = rxConfig->datarate; - uint8_t maxPayload = 0; - int8_t phyDr = 0; - uint32_t frequency = rxConfig->frequency; - - if(_radio->get_status() != RF_IDLE ) - { + if (_radio->get_status() != RF_IDLE) { + _radio->unlock(); return false; } - if( rxConfig->rx_slot == RX_SLOT_WIN_1 ) + _radio->unlock(); + + if( config->rx_slot == RX_SLOT_WIN_1 ) { // Apply window 1 frequency - frequency = CN470_FIRST_RX1_CHANNEL + ( rxConfig->channel % 48 ) * CN470_STEPWIDTH_RX1_CHANNEL; + frequency = CN470_FIRST_RX1_CHANNEL + (config->channel % 48) * CN470_STEPWIDTH_RX1_CHANNEL; } // Read the physical datarate from the datarates table - phyDr = DataratesCN470[dr]; + phy_dr = datarates_CN470[dr]; + + _radio->lock(); _radio->set_channel(frequency); // Radio configuration - _radio->set_rx_config(MODEM_LORA, rxConfig->bandwidth, phyDr, 1, 0, 8, - rxConfig->window_timeout, false, 0, false, 0, 0, true, - rxConfig->is_rx_continuous); + _radio->set_rx_config(MODEM_LORA, config->bandwidth, phy_dr, 1, 0, 8, + config->window_timeout, false, 0, false, 0, 0, true, + config->is_rx_continuous); - if( rxConfig->is_repeater_supported == true ) - { - maxPayload = MaxPayloadOfDatarateRepeaterCN470[dr]; + _radio->unlock(); + + if (config->is_repeater_supported == true) { + max_payload = max_payloads_with_repeater_CN470[dr]; + } else { + max_payload = max_payloads_CN470[dr]; } - else - { - maxPayload = MaxPayloadOfDatarateCN470[dr]; - } - _radio->set_max_payload_length(MODEM_LORA, maxPayload + LORA_MAC_FRMPAYLOAD_OVERHEAD); + + _radio->lock(); + _radio->set_max_payload_length(MODEM_LORA, max_payload + LORA_MAC_FRMPAYLOAD_OVERHEAD); + _radio->unlock(); *datarate = (uint8_t) dr; return true; } -bool LoRaPHYCN470::tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - lorawan_time_t* txTimeOnAir) +bool LoRaPHYCN470::tx_config(tx_config_params_t* config, int8_t* tx_power, + lorawan_time_t* tx_toa) { - int8_t phyDr = DataratesCN470[txConfig->Datarate]; - int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, Bands[Channels[txConfig->Channel].band].max_tx_pwr, txConfig->Datarate, ChannelsMask ); - int8_t phyTxPower = 0; + int8_t phy_dr = datarates_CN470[config->datarate]; + + if (config->tx_power > bands[channels[config->channel].band].max_tx_pwr) { + config->tx_power = bands[channels[config->channel].band].max_tx_pwr; + } + + int8_t phy_tx_power = 0; // Calculate physical TX power - phyTxPower = compute_tx_power( txPowerLimited, txConfig->MaxEirp, txConfig->AntennaGain ); + phy_tx_power = compute_tx_power(config->tx_power, config->max_eirp, + config->antenna_gain); - // Setup the radio frequency - _radio->set_channel(Channels[txConfig->Channel].frequency); + // acquire lock to radio + _radio->lock(); - _radio->set_tx_config(MODEM_LORA, phyTxPower, 0, 0, phyDr, 1, 8, false, true, + _radio->set_channel(channels[config->channel].frequency); + + _radio->set_tx_config(MODEM_LORA, phy_tx_power, 0, 0, phy_dr, 1, 8, false, true, 0, 0, false, 3000); // Setup maximum payload lenght of the radio driver - _radio->set_max_payload_length(MODEM_LORA, txConfig->PktLen); + _radio->set_max_payload_length(MODEM_LORA, config->pkt_len); + // Get the time-on-air of the next tx frame - *txTimeOnAir = _radio->time_on_air(MODEM_LORA, txConfig->PktLen); - *txPower = txPowerLimited; + *tx_toa = _radio->time_on_air(MODEM_LORA, config->pkt_len); + + // release lock to radio + _radio->unlock(); + + *tx_power = config->tx_power; return true; } -uint8_t LoRaPHYCN470::link_ADR_request(LinkAdrReqParams_t* linkAdrReq, - int8_t* drOut, int8_t* txPowOut, - uint8_t* nbRepOut, uint8_t* nbBytesParsed) +uint8_t LoRaPHYCN470::link_ADR_request(adr_req_params_t* params, + int8_t* dr_out, int8_t* tx_power_out, + uint8_t* nb_rep_out, + uint8_t* nb_bytes_parsed) { uint8_t status = 0x07; - RegionCommonLinkAdrParams_t linkAdrParams; - uint8_t nextIndex = 0; - uint8_t bytesProcessed = 0; - uint16_t channelsMask[6] = { 0, 0, 0, 0, 0, 0 }; - GetPhyParams_t getPhy; - PhyParam_t phyParam; - RegionCommonLinkAdrReqVerifyParams_t linkAdrVerifyParams; + link_adr_params_t adr_settings; + uint8_t next_index = 0; + uint8_t bytes_processed = 0; + uint16_t temp_channel_masks[CN470_CHANNELS_MASK_SIZE] = {0, 0, 0, 0, 0, 0}; + + verify_adr_params_t verify_params; // Initialize local copy of channels mask - copy_channel_mask( channelsMask, ChannelsMask, 6 ); + copy_channel_mask(temp_channel_masks, channel_masks, CN470_CHANNELS_MASK_SIZE); + + while(bytes_processed < params->payload_size) { - while( bytesProcessed < linkAdrReq->PayloadSize ) - { // Get ADR request parameters - nextIndex = parse_link_ADR_req( &( linkAdrReq->Payload[bytesProcessed] ), &linkAdrParams ); + next_index = parse_link_ADR_req(&(params->payload[bytes_processed]), &adr_settings); - if( nextIndex == 0 ) + if (next_index == 0) { break; // break loop, since no more request has been found + } // Update bytes processed - bytesProcessed += nextIndex; + bytes_processed += next_index; // Revert status, as we only check the last ADR request for the channel mask KO status = 0x07; - if( linkAdrParams.ChMaskCtrl == 6 ) - { + if (adr_settings.ch_mask_ctrl == 6) { + // Enable all 125 kHz channels - channelsMask[0] = 0xFFFF; - channelsMask[1] = 0xFFFF; - channelsMask[2] = 0xFFFF; - channelsMask[3] = 0xFFFF; - channelsMask[4] = 0xFFFF; - channelsMask[5] = 0xFFFF; - } - else if( linkAdrParams.ChMaskCtrl == 7 ) - { + temp_channel_masks[0] = 0xFFFF; + temp_channel_masks[1] = 0xFFFF; + temp_channel_masks[2] = 0xFFFF; + temp_channel_masks[3] = 0xFFFF; + temp_channel_masks[4] = 0xFFFF; + temp_channel_masks[5] = 0xFFFF; + + } else if( adr_settings.ch_mask_ctrl == 7 ) { + status &= 0xFE; // Channel mask KO - } - else - { - for( uint8_t i = 0; i < 16; i++ ) - { - if( ( ( linkAdrParams.ChMask & ( 1 << i ) ) != 0 ) && - ( Channels[linkAdrParams.ChMaskCtrl * 16 + i].frequency == 0 ) ) - {// Trying to enable an undefined channel + + } else { + + for (uint8_t i = 0; i < 16; i++) { + + if (((adr_settings.channel_mask & (1 << i)) != 0 ) && + (channels[adr_settings.ch_mask_ctrl * 16 + i].frequency == 0)) { + // Trying to enable an undefined channel status &= 0xFE; // Channel mask KO } } - channelsMask[linkAdrParams.ChMaskCtrl] = linkAdrParams.ChMask; + + temp_channel_masks[adr_settings.ch_mask_ctrl] = adr_settings.channel_mask; } } - // Get the minimum possible datarate - getPhy.Attribute = PHY_MIN_TX_DR; - getPhy.UplinkDwellTime = linkAdrReq->UplinkDwellTime; - phyParam = get_phy_params(&getPhy); + verify_params.status = status; + verify_params.adr_enabled = params->adr_enabled; + verify_params.datarate = adr_settings.datarate; + verify_params.tx_power = adr_settings.tx_power; + verify_params.nb_rep = adr_settings.nb_rep; + verify_params.current_datarate = params->current_datarate; + verify_params.current_tx_power = params->current_tx_power; + verify_params.current_nb_rep = params->current_nb_rep; + verify_params.channel_mask = temp_channel_masks; - linkAdrVerifyParams.Status = status; - linkAdrVerifyParams.AdrEnabled = linkAdrReq->AdrEnabled; - linkAdrVerifyParams.Datarate = linkAdrParams.Datarate; - linkAdrVerifyParams.TxPower = linkAdrParams.TxPower; - linkAdrVerifyParams.NbRep = linkAdrParams.NbRep; - linkAdrVerifyParams.CurrentDatarate = linkAdrReq->CurrentDatarate; - linkAdrVerifyParams.CurrentTxPower = linkAdrReq->CurrentTxPower; - linkAdrVerifyParams.CurrentNbRep = linkAdrReq->CurrentNbRep; - linkAdrVerifyParams.NbChannels = CN470_MAX_NB_CHANNELS; - linkAdrVerifyParams.ChannelsMask = channelsMask; - linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value; - linkAdrVerifyParams.MaxDatarate = CN470_TX_MAX_DATARATE; - linkAdrVerifyParams.Channels = Channels; - linkAdrVerifyParams.MinTxPower = CN470_MIN_TX_POWER; - linkAdrVerifyParams.MaxTxPower = CN470_MAX_TX_POWER; // Verify the parameters and update, if necessary - status = verify_link_ADR_req( &linkAdrVerifyParams, &linkAdrParams.Datarate, &linkAdrParams.TxPower, &linkAdrParams.NbRep ); + status = verify_link_ADR_req(&verify_params, &adr_settings.datarate, + &adr_settings.tx_power, &adr_settings.nb_rep); // Update channelsMask if everything is correct - if( status == 0x07 ) - { + if (status == 0x07) { // Copy Mask - copy_channel_mask( ChannelsMask, channelsMask, 6 ); + copy_channel_mask(channel_masks, temp_channel_masks, CN470_CHANNELS_MASK_SIZE); } // Update status variables - *drOut = linkAdrParams.Datarate; - *txPowOut = linkAdrParams.TxPower; - *nbRepOut = linkAdrParams.NbRep; - *nbBytesParsed = bytesProcessed; + *dr_out = adr_settings.datarate; + *tx_power_out = adr_settings.tx_power; + *nb_rep_out = adr_settings.nb_rep; + *nb_bytes_parsed = bytes_processed; return status; } -uint8_t LoRaPHYCN470::setup_rx_params( RxParamSetupReqParams_t* rxParamSetupReq) +uint8_t LoRaPHYCN470::accept_rx_param_setup_req(rx_param_setup_req_t* params) { uint8_t status = 0x07; - uint32_t freq = rxParamSetupReq->Frequency; + uint32_t freq = params->frequency; + + // acquire radio lock + _radio->lock(); + + if ((_radio->check_rf_frequency(freq) == false) + || (freq < CN470_FIRST_RX1_CHANNEL) + || (freq > CN470_LAST_RX1_CHANNEL) + || (((freq - (uint32_t) CN470_FIRST_RX1_CHANNEL) % (uint32_t) CN470_STEPWIDTH_RX1_CHANNEL) != 0)) { - // Verify radio frequency - if( (_radio->check_rf_frequency(freq) == false ) || - ( freq < CN470_FIRST_RX1_CHANNEL ) || - ( freq > CN470_LAST_RX1_CHANNEL ) || - ( ( ( freq - ( uint32_t ) CN470_FIRST_RX1_CHANNEL ) % ( uint32_t ) CN470_STEPWIDTH_RX1_CHANNEL ) != 0 ) ) - { status &= 0xFE; // Channel frequency KO } + // release radio lock + _radio->unlock(); + // Verify datarate - if( val_in_range( rxParamSetupReq->Datarate, CN470_RX_MIN_DATARATE, CN470_RX_MAX_DATARATE ) == 0 ) - { + if (val_in_range(params->datarate, CN470_RX_MIN_DATARATE, CN470_RX_MAX_DATARATE) == 0) { status &= 0xFD; // Datarate KO } // Verify datarate offset - if( val_in_range( rxParamSetupReq->DrOffset, CN470_MIN_RX1_DR_OFFSET, CN470_MAX_RX1_DR_OFFSET ) == 0 ) - { + if (val_in_range(params->dr_offset, CN470_MIN_RX1_DR_OFFSET, CN470_MAX_RX1_DR_OFFSET) == 0) { status &= 0xFB; // Rx1DrOffset range KO } return status; } - -uint8_t LoRaPHYCN470::request_new_channel(NewChannelReqParams_t* newChannelReq) -{ - // Datarate and frequency KO - return 0; -} - -int8_t LoRaPHYCN470::setup_tx_params(TxParamSetupReqParams_t* txParamSetupReq) -{ - return -1; -} - -uint8_t LoRaPHYCN470::dl_channel_request(DlChannelReqParams_t* dlChannelReq) -{ - return 0; -} - -int8_t LoRaPHYCN470::get_alternate_DR(AlternateDrParams_t* alternateDr) -{ - int8_t datarate = 0; - - if( ( alternateDr->NbTrials % 48 ) == 0 ) - { - datarate = DR_0; - } - else if( ( alternateDr->NbTrials % 32 ) == 0 ) - { - datarate = DR_1; - } - else if( ( alternateDr->NbTrials % 24 ) == 0 ) - { - datarate = DR_2; - } - else if( ( alternateDr->NbTrials % 16 ) == 0 ) - { - datarate = DR_3; - } - else if( ( alternateDr->NbTrials % 8 ) == 0 ) - { - datarate = DR_4; - } - else - { - datarate = DR_5; - } - return datarate; -} - -void LoRaPHYCN470::calculate_backoff(CalcBackOffParams_t* calcBackOff) -{ - RegionCommonCalcBackOffParams_t calcBackOffParams; - - calcBackOffParams.Channels = Channels; - calcBackOffParams.Bands = Bands; - calcBackOffParams.LastTxIsJoinRequest = calcBackOff->LastTxIsJoinRequest; - calcBackOffParams.Joined = calcBackOff->Joined; - calcBackOffParams.DutyCycleEnabled = calcBackOff->DutyCycleEnabled; - calcBackOffParams.Channel = calcBackOff->Channel; - calcBackOffParams.ElapsedTime = calcBackOff->ElapsedTime; - calcBackOffParams.TxTimeOnAir = calcBackOff->TxTimeOnAir; - - get_DC_backoff( &calcBackOffParams ); -} - -bool LoRaPHYCN470::set_next_channel(NextChanParams_t* nextChanParams, - uint8_t* channel, lorawan_time_t* time, - lorawan_time_t* aggregatedTimeOff) -{ - uint8_t nbEnabledChannels = 0; - uint8_t delayTx = 0; - uint8_t enabledChannels[CN470_MAX_NB_CHANNELS] = { 0 }; - lorawan_time_t nextTxDelay = 0; - - // Count 125kHz channels - if( num_active_channels( ChannelsMask, 0, 6 ) == 0 ) - { // Reactivate default channels - ChannelsMask[0] = 0xFFFF; - ChannelsMask[1] = 0xFFFF; - ChannelsMask[2] = 0xFFFF; - ChannelsMask[3] = 0xFFFF; - ChannelsMask[4] = 0xFFFF; - ChannelsMask[5] = 0xFFFF; - } - - if( nextChanParams->AggrTimeOff <= _lora_time.TimerGetElapsedTime( nextChanParams->LastAggrTx ) ) - { - // Reset Aggregated time off - *aggregatedTimeOff = 0; - - // Update bands Time OFF - nextTxDelay = update_band_timeoff( nextChanParams->Joined, nextChanParams->DutyCycleEnabled, Bands, CN470_MAX_NB_BANDS ); - - // Search how many channels are enabled - nbEnabledChannels = CountNbOfEnabledChannels( nextChanParams->Datarate, - ChannelsMask, Channels, - Bands, enabledChannels, &delayTx ); - } - else - { - delayTx++; - nextTxDelay = nextChanParams->AggrTimeOff - _lora_time.TimerGetElapsedTime( nextChanParams->LastAggrTx ); - } - - if( nbEnabledChannels > 0 ) - { - // We found a valid channel - *channel = enabledChannels[get_random( 0, nbEnabledChannels - 1 )]; - - *time = 0; - return true; - } - else - { - if( delayTx > 0 ) - { - // Delay transmission due to AggregatedTimeOff or to a band time off - *time = nextTxDelay; - return true; - } - // Datarate not supported by any channel - *time = 0; - return false; - } -} - -lorawan_status_t LoRaPHYCN470::add_channel(ChannelAddParams_t* channelAdd) -{ - return LORAWAN_STATUS_PARAMETER_INVALID; -} - -bool LoRaPHYCN470::remove_channel(ChannelRemoveParams_t* channelRemove) -{ - return LORAWAN_STATUS_PARAMETER_INVALID; -} - -void LoRaPHYCN470::set_tx_cont_mode(ContinuousWaveParams_t* continuousWave) -{ - int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, Bands[Channels[continuousWave->Channel].band].max_tx_pwr, continuousWave->Datarate, ChannelsMask ); - int8_t phyTxPower = 0; - uint32_t frequency = Channels[continuousWave->Channel].frequency; - - // Calculate physical TX power - phyTxPower = compute_tx_power( txPowerLimited, continuousWave->MaxEirp, continuousWave->AntennaGain ); - - _radio->set_tx_continuous_wave(frequency, phyTxPower, continuousWave->Timeout); -} - -uint8_t LoRaPHYCN470::apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, - int8_t drOffset) -{ - int8_t datarate = dr - drOffset; - - if( datarate < 0 ) - { - datarate = DR_0; - } - return datarate; -} - - - diff --git a/features/lorawan/lorastack/phy/LoRaPHYCN470.h b/features/lorawan/lorastack/phy/LoRaPHYCN470.h index a7dfa574c6..2ededa893c 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYCN470.h +++ b/features/lorawan/lorastack/phy/LoRaPHYCN470.h @@ -33,7 +33,6 @@ #define MBED_OS_LORAPHY_CN470_H_ #include "LoRaPHY.h" -#include "netsocket/LoRaRadio.h" // Definitions /*! @@ -57,309 +56,38 @@ public: LoRaPHYCN470(LoRaWANTimeHandler &lora_time); virtual ~LoRaPHYCN470(); - /*! - * \brief The function gets a value of a specific PHY attribute. - * - * \param [in] getPhy A pointer to the function parameters. - * - * \retval A structure containing the PHY parameter. - */ - virtual PhyParam_t get_phy_params(GetPhyParams_t* getPhy ); + virtual bool rx_config(rx_config_params_t* config, int8_t* datarate ); - /*! - * \brief Updates the last TX done parameters of the current channel. - * - * \param [in] txDone A pointer to the function parameters. - */ - virtual void set_band_tx_done(SetBandTxDoneParams_t* txDone ); + virtual bool tx_config(tx_config_params_t* config, int8_t* tx_power, + lorawan_time_t* tx_toa); - /*! - * \brief Initializes the channels masks and the channels. - * - * \param [in] type Sets the initialization type. - */ - virtual void load_defaults(InitType_t type ); + virtual uint8_t link_ADR_request(adr_req_params_t* params, int8_t* dr_out, + int8_t* tx_power_out, uint8_t* nb_rep_out, + uint8_t* nb_bytes_parsed); - /*! - * \brief Verifies a parameter. - * - * \param [in] verify A pointer to the function parameters. - * - * \param [in] phyAttribute The attribute to be verified. - * - * \retval True, if the parameter is valid. - */ - virtual bool verify(VerifyParams_t* verify, PhyAttribute_t phyAttribute ); - - /*! - * \brief The function parses the input buffer and sets up the channels of the - * CF list. - * - * \param [in] applyCFList A pointer to the function parameters. - */ - virtual void apply_cf_list(ApplyCFListParams_t* applyCFList ); - - /*! - * \brief Sets a channels mask. - * - * \param [in] chanMaskSet A pointer to the function parameters. - * - * \retval True, if the channels mask could be set. - */ - virtual bool set_channel_mask(ChanMaskSetParams_t* chanMaskSet ); - - /*! - * \brief Calculates the next datarate to set, when ADR is on or off. - * - * \param [in] adrNext A pointer to the function parameters. - * - * \param [out] drOut The calculated datarate for the next TX. - * - * \param [out] txPowOut The TX power for the next TX. - * - * \param [out] adrAckCounter The calculated ADR acknowledgement counter. - * - * \retval True, if an ADR request should be performed. - */ - virtual bool get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut, - int8_t* txPowOut, uint32_t* adrAckCounter ); - - /*! - * \brief Configuration of the RX windows. - * - * \param [in] rxConfig A pointer to the function parameters. - * - * \param [out] datarate The datarate index set. - * - * \retval True, if the configuration was applied successfully. - */ - virtual bool rx_config(rx_config_params_t* rxConfig, int8_t* datarate ); - - /* - * RX window precise timing - * - * For more details please consult the following document, chapter 3.1.2. - * http://www.semtech.com/images/datasheet/SX1272_settings_for_LoRaWAN_v2.0.pdf - * or - * http://www.semtech.com/images/datasheet/SX1276_settings_for_LoRaWAN_v2.0.pdf - * - * Downlink start: T = Tx + 1s (+/- 20 us) - * | - * TRxEarly | TRxLate - * | | | - * | | +---+---+---+---+---+---+---+---+ - * | | | Latest Rx window | - * | | +---+---+---+---+---+---+---+---+ - * | | | - * +---+---+---+---+---+---+---+---+ - * | Earliest Rx window | - * +---+---+---+---+---+---+---+---+ - * | - * +---+---+---+---+---+---+---+---+ - *Downlink preamble 8 symbols | | | | | | | | | - * +---+---+---+---+---+---+---+---+ - * - * Worst case Rx window timings - * - * TRxLate = DEFAULT_MIN_RX_SYMBOLS * tSymbol - RADIO_WAKEUP_TIME - * TRxEarly = 8 - DEFAULT_MIN_RX_SYMBOLS * tSymbol - RxWindowTimeout - RADIO_WAKEUP_TIME - * - * TRxLate - TRxEarly = 2 * DEFAULT_SYSTEM_MAX_RX_ERROR - * - * RxOffset = ( TRxLate + TRxEarly ) / 2 - * - * RxWindowTimeout = ( 2 * DEFAULT_MIN_RX_SYMBOLS - 8 ) * tSymbol + 2 * DEFAULT_SYSTEM_MAX_RX_ERROR - * RxOffset = 4 * tSymbol - RxWindowTimeout / 2 - RADIO_WAKE_UP_TIME - * - * The minimum value of RxWindowTimeout must be 5 symbols which implies that the system always tolerates at least an error of 1.5 * tSymbol - */ - /*! - * Computes the RX window timeout and offset. - * - * \param [in] datarate The RX window datarate index to be used. - * - * \param [in] minRxSymbols The minimum number of symbols required to detect an RX frame. - * - * \param [in] rxError The system maximum timing error of the receiver in milliseconds. - * The receiver will turn on in a [-rxError : +rxError] ms - * interval around RxOffset. - * - * \param [out] rxConfigParams The updated WindowTimeout and WindowOffset fields. - */ - virtual void compute_rx_win_params(int8_t datarate, - uint8_t minRxSymbols, - uint32_t rxError, - rx_config_params_t *rxConfigParams); - - /*! - * \brief TX configuration. - * - * \param [in] txConfig A pointer to the function parameters. - * - * \param [out] txPower The TX power index set. - * - * \param [out] txTimeOnAir The time-on-air of the frame. - * - * \retval True, if the configuration was applied successfully. - */ - virtual bool tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - lorawan_time_t* txTimeOnAir ); - - /*! - * \brief The function processes a Link ADR request. - * - * \param [in] linkAdrReq A pointer to the function parameters. - * - * \param [out] drOut The datarate applied. - * - * \param [out] txPowOut The TX power applied. - * - * \param [out] nbRepOut The number of repetitions to apply. - * - * \param [out] nbBytesParsed The number of bytes parsed. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t link_ADR_request(LinkAdrReqParams_t* linkAdrReq, - int8_t* drOut, int8_t* txPowOut, - uint8_t* nbRepOut, - uint8_t* nbBytesParsed ); - - /*! - * \brief The function processes a RX parameter setup request. - * - * \param [in] rxParamSetupReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t setup_rx_params(RxParamSetupReqParams_t* rxParamSetupReq ); - - /*! - * \brief The function processes a new channel request. - * - * \param [in] newChannelReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t request_new_channel(NewChannelReqParams_t* newChannelReq ); - - /*! - * \brief The function processes a TX ParamSetup request. - * - * \param [in] txParamSetupReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - * Returns -1, if the functionality is not implemented. In this case, the end node - * shall ignore the command. - */ - virtual int8_t setup_tx_params(TxParamSetupReqParams_t* txParamSetupReq ); - - /*! - * \brief The function processes a DlChannel request. - * - * \param [in] dlChannelReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t dl_channel_request(DlChannelReqParams_t* dlChannelReq ); - - /*! - * \brief Alternates the datarate of the channel for the join request. - * - * \param [in] alternateDr A pointer to the function parameters. - * - * \retval The datarate to apply. - */ - virtual int8_t get_alternate_DR(AlternateDrParams_t* alternateDr ); - - /*! - * \brief Calculates the back-off time. - * - * \param [in] calcBackOff A pointer to the function parameters. - */ - virtual void calculate_backoff(CalcBackOffParams_t* calcBackOff ); - - /*! - * \brief Searches and sets the next random available channel. - * - * \param [in] nextChanParams The parameters for the next channel - * - * \param [out] channel The next channel to use for TX. - * - * \param [out] time The time to wait for the next transmission according to the duty - * cycle. - * - * \param [out] aggregatedTimeOff Updates the aggregated time off. - * - * \retval Function status [1: OK, 0: Unable to find a channel on the current datarate]. - */ - virtual bool set_next_channel(NextChanParams_t* nextChanParams, - uint8_t* channel, lorawan_time_t* time, - lorawan_time_t* aggregatedTimeOff ); - - /*! - * \brief Adds a channel. - * - * \param [in] channelAdd A pointer to the function parameters. - * - * \retval The status of the operation. - */ - virtual lorawan_status_t add_channel(ChannelAddParams_t* channelAdd ); - - /*! - * \brief Removes a channel. - * - * \param [in] channelRemove A pointer to the function parameters. - * - * \retval True, if the channel was removed successfully. - */ - virtual bool remove_channel(ChannelRemoveParams_t* channelRemove ); - - /*! - * \brief Sets the radio into continuous wave mode. - * - * \param [in] continuousWave A pointer to the function parameters. - */ - virtual void set_tx_cont_mode(ContinuousWaveParams_t* continuousWave ); - - /*! - * \brief Computes a new datarate according to the given offset. - * - * \param [in] downlinkDwellTime The downlink dwell time configuration. 0: No limit, 1: 400ms - * - * \param [in] dr The current datarate. - * - * \param [in] drOffset The offset to be applied. - * - * \retval newDr The computed datarate. - */ - virtual uint8_t apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ); + virtual uint8_t accept_rx_param_setup_req(rx_param_setup_req_t* params); private: - uint8_t CountNbOfEnabledChannels( uint8_t datarate, uint16_t* channelsMask, channel_params_t* channels, band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ); - bool RegionCN470ChanMaskSet( ChanMaskSetParams_t* chanMaskSet ); - - // Global attributes /*! * LoRaMAC channels */ - channel_params_t Channels[CN470_MAX_NB_CHANNELS]; + channel_params_t channels[CN470_MAX_NB_CHANNELS]; /*! * LoRaMac bands */ - band_t Bands[CN470_MAX_NB_BANDS]; + band_t bands[CN470_MAX_NB_BANDS]; /*! * LoRaMac channels mask */ - uint16_t ChannelsMask[CN470_CHANNELS_MASK_SIZE]; + uint16_t channel_masks[CN470_CHANNELS_MASK_SIZE]; /*! * LoRaMac channels default mask */ - uint16_t ChannelsDefaultMask[CN470_CHANNELS_MASK_SIZE]; + uint16_t default_channel_masks[CN470_CHANNELS_MASK_SIZE]; }; #endif /* MBED_OS_LORAPHY_CN470_H_ */ diff --git a/features/lorawan/lorastack/phy/LoRaPHYCN779.cpp b/features/lorawan/lorastack/phy/LoRaPHYCN779.cpp index ce693451b8..c85e6ac541 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYCN779.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYCN779.cpp @@ -30,10 +30,7 @@ */ #include "LoRaPHYCN779.h" - #include "lora_phy_ds.h" -#include "LoRaRadio.h" - /*! * Number of default channels @@ -65,6 +62,8 @@ */ #define CN779_RX_MAX_DATARATE DR_7 +#define CN779_DEFAULT_MAX_DATARATE DR_5 + /*! * Default datarate used by the node */ @@ -186,1055 +185,135 @@ * Band 0 definition * { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff } */ -#define CN779_BAND0 { 100, CN779_MAX_TX_POWER, 0, 0, 0 } // 1.0 % +static const band_t CN779_BAND0 = {100, CN779_MAX_TX_POWER, 0, 0, 0, 779500000, 786500000}; // 1.0 % /*! * LoRaMac default channel 1 * Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } */ -#define CN779_LC1 { 779500000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } +static const channel_params_t CN779_LC1 = {779500000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0}; /*! * LoRaMac default channel 2 * Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } */ -#define CN779_LC2 { 779700000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } +static const channel_params_t CN779_LC2 = {779700000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0}; /*! * LoRaMac default channel 3 * Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } */ -#define CN779_LC3 { 779900000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } +static const channel_params_t CN779_LC3 = {779900000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0}; /*! * LoRaMac channels which are allowed for the join procedure */ -#define CN779_JOIN_CHANNELS ( uint16_t )( LC( 1 ) | LC( 2 ) | LC( 3 ) ) +#define CN779_JOIN_CHANNELS (uint16_t) (LC(1) | LC(2) | LC(3)) /*! * Data rates table definition */ -static const uint8_t DataratesCN779[] = { 12, 11, 10, 9, 8, 7, 7, 50 }; +static const uint8_t datarates_CN779[] = {12, 11, 10, 9, 8, 7, 7, 50}; /*! * Bandwidths table definition in Hz */ -static const uint32_t BandwidthsCN779[] = { 125000, 125000, 125000, 125000, 125000, 125000, 250000, 0 }; +static const uint32_t bandwidths_CN779[] = {125000, 125000, 125000, 125000, 125000, 125000, 250000, 0}; /*! * Maximum payload with respect to the datarate index. Cannot operate with repeater. */ -static const uint8_t MaxPayloadOfDatarateCN779[] = { 51, 51, 51, 115, 242, 242, 242, 242 }; +static const uint8_t max_payloads_CN779[] = {51, 51, 51, 115, 242, 242, 242, 242}; /*! * Maximum payload with respect to the datarate index. Can operate with repeater. */ -static const uint8_t MaxPayloadOfDatarateRepeaterCN779[] = { 51, 51, 51, 115, 222, 222, 222, 222 }; +static const uint8_t max_payloads_with_repeater_CN779[] = {51, 51, 51, 115, 222, 222, 222, 222}; -// Static functions -static int8_t GetNextLowerTxDr( int8_t dr, int8_t minDr ) -{ - uint8_t nextLowerDr = 0; - - if( dr == minDr ) - { - nextLowerDr = minDr; - } - else - { - nextLowerDr = dr - 1; - } - return nextLowerDr; -} - -static uint32_t GetBandwidth( uint32_t drIndex ) -{ - switch( BandwidthsCN779[drIndex] ) - { - default: - case 125000: - return 0; - case 250000: - return 1; - case 500000: - return 2; - } -} - -static int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower, int8_t datarate, uint16_t* channelsMask ) -{ - int8_t txPowerResult = txPower; - - // Limit tx power to the band max - txPowerResult = MAX( txPower, maxBandTxPower ); - - return txPowerResult; -} - -static bool VerifyTxFreq( uint32_t freq, LoRaRadio *radio) -{ - // Check radio driver support - if(radio->check_rf_frequency(freq) == false) - { - return false; - } - - if( ( freq < 779500000 ) || ( freq > 786500000 ) ) - { - return false; - } - return true; -} - -uint8_t LoRaPHYCN779::CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, channel_params_t* channels, band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ) -{ - uint8_t nbEnabledChannels = 0; - uint8_t delayTransmission = 0; - - for( uint8_t i = 0, k = 0; i < CN779_MAX_NB_CHANNELS; i += 16, k++ ) - { - for( uint8_t j = 0; j < 16; j++ ) - { - if( ( channelsMask[k] & ( 1 << j ) ) != 0 ) - { - if( channels[i + j].frequency == 0 ) - { // Check if the channel is enabled - continue; - } - if( joined == false ) - { - if( ( CN779_JOIN_CHANNELS & ( 1 << j ) ) == 0 ) - { - continue; - } - } - if( val_in_range( datarate, channels[i + j].dr_range.fields.min, - channels[i + j].dr_range.fields.max ) == 0 ) - { // Check if the current channel selection supports the given datarate - continue; - } - if( bands[channels[i + j].band].off_time > 0 ) - { // Check if the band is available for transmission - delayTransmission++; - continue; - } - enabledChannels[nbEnabledChannels++] = i + j; - } - } - } - - *delayTx = delayTransmission; - return nbEnabledChannels; -} LoRaPHYCN779::LoRaPHYCN779(LoRaWANTimeHandler &lora_time) - : LoRaPHY(lora_time) + : LoRaPHY(lora_time) { - const band_t band0 = CN779_BAND0; - Bands[0] = band0; + bands[0] = CN779_BAND0; + + // Channels + channels[0] = CN779_LC1; + channels[1] = CN779_LC2; + channels[2] = CN779_LC3; + + // Initialize the channels default mask + default_channel_masks[0] = LC(1) + LC(2) + LC(3); + // Update the channels mask + copy_channel_mask(channel_masks, default_channel_masks, CN779_CHANNELS_MASK_SIZE); + + // set default channels + phy_params.channels.channel_list = channels; + phy_params.channels.channel_list_size = CN779_MAX_NB_CHANNELS; + phy_params.channels.mask_list = channel_masks; + phy_params.channels.default_mask_list = default_channel_masks; + phy_params.channels.mask_list_size = CN779_CHANNELS_MASK_SIZE; + + // set bands for CN779 spectrum + phy_params.bands.table = bands; + phy_params.bands.size = CN779_MAX_NB_BANDS; + + // set bandwidths available in CN779 spectrum + phy_params.bandwidths.table = (void *) bandwidths_CN779; + phy_params.bandwidths.size = 8; + + // set data rates available in CN779 spectrum + phy_params.datarates.table = (void *) datarates_CN779; + phy_params.datarates.size = 8; + + // set payload sizes with respect to data rates + phy_params.payloads.table = (void *) max_payloads_CN779; + phy_params.payloads.size = 8; + phy_params.payloads_with_repeater.table = (void *) max_payloads_with_repeater_CN779; + phy_params.payloads.size = 8; + + // dwell time setting + phy_params.ul_dwell_time_setting = 0; + phy_params.dl_dwell_time_setting = 0; + + // set initial and default parameters + phy_params.duty_cycle_enabled = CN779_DUTY_CYCLE_ENABLED; + phy_params.accept_tx_param_setup_req = false; + phy_params.fsk_supported = true; + phy_params.cflist_supported = true; + phy_params.dl_channel_req_supported = true; + phy_params.custom_channelplans_supported = true; + phy_params.default_channel_cnt = CN779_NUMB_DEFAULT_CHANNELS; + phy_params.max_channel_cnt = CN779_MAX_NB_CHANNELS; + phy_params.cflist_channel_cnt = CN779_NUMB_CHANNELS_CF_LIST; + phy_params.min_tx_datarate = CN779_TX_MIN_DATARATE; + phy_params.max_tx_datarate = CN779_TX_MAX_DATARATE; + phy_params.min_rx_datarate = CN779_RX_MIN_DATARATE; + phy_params.max_rx_datarate = CN779_RX_MAX_DATARATE; + phy_params.default_datarate = CN779_DEFAULT_DATARATE; + phy_params.default_max_datarate = CN779_DEFAULT_MAX_DATARATE; + phy_params.min_rx1_dr_offset = CN779_MIN_RX1_DR_OFFSET; + phy_params.max_rx1_dr_offset = CN779_MAX_RX1_DR_OFFSET; + phy_params.default_rx1_dr_offset = CN779_DEFAULT_RX1_DR_OFFSET; + phy_params.min_tx_power = CN779_MIN_TX_POWER; + phy_params.max_tx_power = CN779_MAX_TX_POWER; + phy_params.default_tx_power = CN779_DEFAULT_TX_POWER; + phy_params.default_max_eirp = CN779_DEFAULT_MAX_EIRP; + phy_params.default_antenna_gain = CN779_DEFAULT_ANTENNA_GAIN; + phy_params.adr_ack_limit = CN779_ADR_ACK_LIMIT; + phy_params.adr_ack_delay = CN779_ADR_ACK_DELAY; + phy_params.max_rx_window = CN779_MAX_RX_WINDOW; + phy_params.recv_delay1 = CN779_RECEIVE_DELAY1; + phy_params.recv_delay2 = CN779_RECEIVE_DELAY2; + phy_params.join_channel_mask = CN779_JOIN_CHANNELS; + phy_params.join_accept_delay1 = CN779_JOIN_ACCEPT_DELAY1; + phy_params.join_accept_delay2 = CN779_JOIN_ACCEPT_DELAY2; + phy_params.max_fcnt_gap = CN779_MAX_FCNT_GAP; + phy_params.ack_timeout = CN779_ACKTIMEOUT; + phy_params.ack_timeout_rnd = CN779_ACK_TIMEOUT_RND; + phy_params.rx_window2_datarate = CN779_RX_WND_2_DR; + phy_params.rx_window2_frequency = CN779_RX_WND_2_FREQ; } LoRaPHYCN779::~LoRaPHYCN779() { } -PhyParam_t LoRaPHYCN779::get_phy_params(GetPhyParams_t* getPhy) -{ - PhyParam_t phyParam = { 0 }; - - switch( getPhy->Attribute ) - { - case PHY_MIN_RX_DR: - { - phyParam.Value = CN779_RX_MIN_DATARATE; - break; - } - case PHY_MIN_TX_DR: - { - phyParam.Value = CN779_TX_MIN_DATARATE; - break; - } - case PHY_DEF_TX_DR: - { - phyParam.Value = CN779_DEFAULT_DATARATE; - break; - } - case PHY_NEXT_LOWER_TX_DR: - { - phyParam.Value = GetNextLowerTxDr( getPhy->Datarate, CN779_TX_MIN_DATARATE ); - break; - } - case PHY_DEF_TX_POWER: - { - phyParam.Value = CN779_DEFAULT_TX_POWER; - break; - } - case PHY_MAX_PAYLOAD: - { - phyParam.Value = MaxPayloadOfDatarateCN779[getPhy->Datarate]; - break; - } - case PHY_MAX_PAYLOAD_REPEATER: - { - phyParam.Value = MaxPayloadOfDatarateRepeaterCN779[getPhy->Datarate]; - break; - } - case PHY_DUTY_CYCLE: - { - phyParam.Value = CN779_DUTY_CYCLE_ENABLED; - break; - } - case PHY_MAX_RX_WINDOW: - { - phyParam.Value = CN779_MAX_RX_WINDOW; - break; - } - case PHY_RECEIVE_DELAY1: - { - phyParam.Value = CN779_RECEIVE_DELAY1; - break; - } - case PHY_RECEIVE_DELAY2: - { - phyParam.Value = CN779_RECEIVE_DELAY2; - break; - } - case PHY_JOIN_ACCEPT_DELAY1: - { - phyParam.Value = CN779_JOIN_ACCEPT_DELAY1; - break; - } - case PHY_JOIN_ACCEPT_DELAY2: - { - phyParam.Value = CN779_JOIN_ACCEPT_DELAY2; - break; - } - case PHY_MAX_FCNT_GAP: - { - phyParam.Value = CN779_MAX_FCNT_GAP; - break; - } - case PHY_ACK_TIMEOUT: - { - phyParam.Value = (CN779_ACKTIMEOUT + get_random(-CN779_ACK_TIMEOUT_RND, CN779_ACK_TIMEOUT_RND)); - break; - } - case PHY_DEF_DR1_OFFSET: - { - phyParam.Value = CN779_DEFAULT_RX1_DR_OFFSET; - break; - } - case PHY_DEF_RX2_FREQUENCY: - { - phyParam.Value = CN779_RX_WND_2_FREQ; - break; - } - case PHY_DEF_RX2_DR: - { - phyParam.Value = CN779_RX_WND_2_DR; - break; - } - case PHY_CHANNELS_MASK: - { - phyParam.ChannelsMask = ChannelsMask; - break; - } - case PHY_CHANNELS_DEFAULT_MASK: - { - phyParam.ChannelsMask = ChannelsDefaultMask; - break; - } - case PHY_MAX_NB_CHANNELS: - { - phyParam.Value = CN779_MAX_NB_CHANNELS; - break; - } - case PHY_CHANNELS: - { - phyParam.Channels = Channels; - break; - } - case PHY_DEF_UPLINK_DWELL_TIME: - case PHY_DEF_DOWNLINK_DWELL_TIME: - { - phyParam.Value = 0; - break; - } - case PHY_DEF_MAX_EIRP: - { - phyParam.fValue = CN779_DEFAULT_MAX_EIRP; - break; - } - case PHY_DEF_ANTENNA_GAIN: - { - phyParam.fValue = CN779_DEFAULT_ANTENNA_GAIN; - break; - } - case PHY_NB_JOIN_TRIALS: - case PHY_DEF_NB_JOIN_TRIALS: - { - phyParam.Value = 48; - break; - } - default: - { - break; - } - } - - return phyParam; -} - -void LoRaPHYCN779::set_band_tx_done(SetBandTxDoneParams_t* txDone) -{ - set_last_tx_done( txDone->Joined, &Bands[Channels[txDone->Channel].band], txDone->LastTxDoneTime ); -} - -void LoRaPHYCN779::load_defaults(InitType_t type) -{ - switch( type ) - { - case INIT_TYPE_INIT: - { - // Channels - const channel_params_t channel1 = CN779_LC1; - const channel_params_t channel2 = CN779_LC2; - const channel_params_t channel3 = CN779_LC3; - Channels[0] = channel1; - Channels[1] = channel2; - Channels[2] = channel3; - - // Initialize the channels default mask - ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 ); - // Update the channels mask - copy_channel_mask( ChannelsMask, ChannelsDefaultMask, 1 ); - break; - } - case INIT_TYPE_RESTORE: - { - // Restore channels default mask - ChannelsMask[0] |= ChannelsDefaultMask[0]; - break; - } - default: - { - break; - } - } -} - -bool LoRaPHYCN779::verify(VerifyParams_t* verify, PhyAttribute_t phyAttribute) -{ - switch( phyAttribute ) - { - case PHY_TX_DR: - { - return val_in_range( verify->DatarateParams.Datarate, CN779_TX_MIN_DATARATE, CN779_TX_MAX_DATARATE ); - } - case PHY_DEF_TX_DR: - { - return val_in_range( verify->DatarateParams.Datarate, DR_0, DR_5 ); - } - case PHY_RX_DR: - { - return val_in_range( verify->DatarateParams.Datarate, CN779_RX_MIN_DATARATE, CN779_RX_MAX_DATARATE ); - } - case PHY_DEF_TX_POWER: - case PHY_TX_POWER: - { - // Remark: switched min and max! - return val_in_range( verify->TxPower, CN779_MAX_TX_POWER, CN779_MIN_TX_POWER ); - } - case PHY_DUTY_CYCLE: - { - return CN779_DUTY_CYCLE_ENABLED; - } - case PHY_NB_JOIN_TRIALS: - { - if( verify->NbJoinTrials < 48 ) - { - return false; - } - break; - } - default: - return false; - } - return true; -} - -void LoRaPHYCN779::apply_cf_list(ApplyCFListParams_t* applyCFList) -{ - channel_params_t newChannel; - ChannelAddParams_t channelAdd; - ChannelRemoveParams_t channelRemove; - - // Setup default datarate range - newChannel.dr_range.value = ( DR_5 << 4 ) | DR_0; - - // Size of the optional CF list - if( applyCFList->Size != 16 ) - { - return; - } - - // Last byte is RFU, don't take it into account - for( uint8_t i = 0, chanIdx = CN779_NUMB_DEFAULT_CHANNELS; chanIdx < CN779_MAX_NB_CHANNELS; i+=3, chanIdx++ ) - { - if( chanIdx < ( CN779_NUMB_CHANNELS_CF_LIST + CN779_NUMB_DEFAULT_CHANNELS ) ) - { - // Channel frequency - newChannel.frequency = (uint32_t) applyCFList->Payload[i]; - newChannel.frequency |= ( (uint32_t) applyCFList->Payload[i + 1] << 8 ); - newChannel.frequency |= ( (uint32_t) applyCFList->Payload[i + 2] << 16 ); - newChannel.frequency *= 100; - - // Initialize alternative frequency to 0 - newChannel.rx1_frequency = 0; - } - else - { - newChannel.frequency = 0; - newChannel.dr_range.value = 0; - newChannel.rx1_frequency = 0; - } - - if( newChannel.frequency != 0 ) - { - channelAdd.NewChannel = &newChannel; - channelAdd.ChannelId = chanIdx; - - // Try to add all channels - add_channel(&channelAdd); - } - else - { - channelRemove.ChannelId = chanIdx; - - remove_channel(&channelRemove); - } - } -} - -bool LoRaPHYCN779::set_channel_mask(ChanMaskSetParams_t* chanMaskSet) -{ - switch( chanMaskSet->ChannelsMaskType ) - { - case CHANNELS_MASK: - { - copy_channel_mask( ChannelsMask, chanMaskSet->ChannelsMaskIn, 1 ); - break; - } - case CHANNELS_DEFAULT_MASK: - { - copy_channel_mask( ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 1 ); - break; - } - default: - return false; - } - return true; -} - -bool LoRaPHYCN779::get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut, - int8_t* txPowOut, uint32_t* adrAckCounter) -{ - bool adrAckReq = false; - int8_t datarate = adrNext->Datarate; - int8_t txPower = adrNext->TxPower; - GetPhyParams_t getPhy; - PhyParam_t phyParam; - - // Report back the adr ack counter - *adrAckCounter = adrNext->AdrAckCounter; - - if( adrNext->AdrEnabled == true ) - { - if( datarate == CN779_TX_MIN_DATARATE ) - { - *adrAckCounter = 0; - adrAckReq = false; - } - else - { - if( adrNext->AdrAckCounter >= CN779_ADR_ACK_LIMIT ) - { - adrAckReq = true; - txPower = CN779_MAX_TX_POWER; - } - else - { - adrAckReq = false; - } - if( adrNext->AdrAckCounter >= ( CN779_ADR_ACK_LIMIT + CN779_ADR_ACK_DELAY ) ) - { - if( ( adrNext->AdrAckCounter % CN779_ADR_ACK_DELAY ) == 1 ) - { - // Decrease the datarate - getPhy.Attribute = PHY_NEXT_LOWER_TX_DR; - getPhy.Datarate = datarate; - getPhy.UplinkDwellTime = adrNext->UplinkDwellTime; - phyParam = get_phy_params(&getPhy); - datarate = phyParam.Value; - - if( datarate == CN779_TX_MIN_DATARATE ) - { - // We must set adrAckReq to false as soon as we reach the lowest datarate - adrAckReq = false; - if( adrNext->UpdateChanMask == true ) - { - // Re-enable default channels - ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); - } - } - } - } - } - } - - *drOut = datarate; - *txPowOut = txPower; - return adrAckReq; -} - -void LoRaPHYCN779::compute_rx_win_params(int8_t datarate, uint8_t minRxSymbols, - uint32_t rxError, - rx_config_params_t *rxConfigParams) -{ - double tSymbol = 0.0; - - // Get the datarate, perform a boundary check - rxConfigParams->datarate = MIN( datarate, CN779_RX_MAX_DATARATE ); - rxConfigParams->bandwidth = GetBandwidth( rxConfigParams->datarate ); - - if( rxConfigParams->datarate == DR_7 ) - { // FSK - tSymbol = compute_symb_timeout_fsk( DataratesCN779[rxConfigParams->datarate] ); - } - else - { // LoRa - tSymbol = compute_symb_timeout_lora( DataratesCN779[rxConfigParams->datarate], BandwidthsCN779[rxConfigParams->datarate] ); - } - - get_rx_window_params( tSymbol, minRxSymbols, rxError, RADIO_WAKEUP_TIME, &rxConfigParams->window_timeout, &rxConfigParams->window_offset ); -} - -bool LoRaPHYCN779::rx_config(rx_config_params_t* rxConfig, int8_t* datarate) -{ - radio_modems_t modem; - int8_t dr = rxConfig->datarate; - uint8_t maxPayload = 0; - int8_t phyDr = 0; - uint32_t frequency = rxConfig->frequency; - - if(_radio->get_status() != RF_IDLE ) - { - return false; - } - - if( rxConfig->rx_slot == RX_SLOT_WIN_1) - { - // Apply window 1 frequency - frequency = Channels[rxConfig->channel].frequency; - // Apply the alternative RX 1 window frequency, if it is available - if( Channels[rxConfig->channel].rx1_frequency != 0 ) - { - frequency = Channels[rxConfig->channel].rx1_frequency; - } - } - - // Read the physical datarate from the datarates table - phyDr = DataratesCN779[dr]; - - _radio->set_channel(frequency); - - // Radio configuration - if( dr == DR_7 ) - { - modem = MODEM_FSK; - _radio->set_rx_config(modem, 50000, phyDr * 1000, 0, 83333, 5, rxConfig->window_timeout, false, 0, true, 0, 0, false, rxConfig->is_rx_continuous); - } - else - { - modem = MODEM_LORA; - _radio->set_rx_config(modem, rxConfig->bandwidth, phyDr, 1, 0, 8, rxConfig->window_timeout, false, 0, false, 0, 0, true, rxConfig->is_rx_continuous); - } - - if( rxConfig->is_repeater_supported == true ) - { - maxPayload = MaxPayloadOfDatarateRepeaterCN779[dr]; - } - else - { - maxPayload = MaxPayloadOfDatarateCN779[dr]; - } - _radio->set_max_payload_length(modem, maxPayload + LORA_MAC_FRMPAYLOAD_OVERHEAD); - - *datarate = (uint8_t) dr; - return true; -} - -bool LoRaPHYCN779::tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - lorawan_time_t* txTimeOnAir) -{ - radio_modems_t modem; - int8_t phyDr = DataratesCN779[txConfig->Datarate]; - int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, Bands[Channels[txConfig->Channel].band].max_tx_pwr, txConfig->Datarate, ChannelsMask ); - uint32_t bandwidth = GetBandwidth( txConfig->Datarate ); - int8_t phyTxPower = 0; - - // Calculate physical TX power - phyTxPower = compute_tx_power( txPowerLimited, txConfig->MaxEirp, txConfig->AntennaGain ); - - // Setup the radio frequency - _radio->set_channel(Channels[txConfig->Channel].frequency); - - if( txConfig->Datarate == DR_7 ) - { // High Speed FSK channel - modem = MODEM_FSK; - _radio->set_tx_config(modem, phyTxPower, 25000, bandwidth, phyDr * 1000, 0, 5, false, true, 0, 0, false, 3000); - } - else - { - modem = MODEM_LORA; - _radio->set_tx_config(modem, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 3000); - } - - // Setup maximum payload lenght of the radio driver - _radio->set_max_payload_length(modem, txConfig->PktLen); - // Get the time-on-air of the next tx frame - *txTimeOnAir = _radio->time_on_air(modem, txConfig->PktLen); - - *txPower = txPowerLimited; - return true; -} - -uint8_t LoRaPHYCN779::link_ADR_request(LinkAdrReqParams_t* linkAdrReq, - int8_t* drOut, int8_t* txPowOut, - uint8_t* nbRepOut, uint8_t* nbBytesParsed) -{ - uint8_t status = 0x07; - RegionCommonLinkAdrParams_t linkAdrParams; - uint8_t nextIndex = 0; - uint8_t bytesProcessed = 0; - uint16_t chMask = 0; - GetPhyParams_t getPhy; - PhyParam_t phyParam; - RegionCommonLinkAdrReqVerifyParams_t linkAdrVerifyParams; - - while( bytesProcessed < linkAdrReq->PayloadSize ) - { - // Get ADR request parameters - nextIndex = parse_link_ADR_req( &( linkAdrReq->Payload[bytesProcessed] ), &linkAdrParams ); - - if( nextIndex == 0 ) - break; // break loop, since no more request has been found - - // Update bytes processed - bytesProcessed += nextIndex; - - // Revert status, as we only check the last ADR request for the channel mask KO - status = 0x07; - - // Setup temporary channels mask - chMask = linkAdrParams.ChMask; - - // Verify channels mask - if( ( linkAdrParams.ChMaskCtrl == 0 ) && ( chMask == 0 ) ) - { - status &= 0xFE; // Channel mask KO - } - else if( ( ( linkAdrParams.ChMaskCtrl >= 1 ) && ( linkAdrParams.ChMaskCtrl <= 5 )) || - ( linkAdrParams.ChMaskCtrl >= 7 ) ) - { - // RFU - status &= 0xFE; // Channel mask KO - } - else - { - for( uint8_t i = 0; i < CN779_MAX_NB_CHANNELS; i++ ) - { - if( linkAdrParams.ChMaskCtrl == 6 ) - { - if( Channels[i].frequency != 0 ) - { - chMask |= 1 << i; - } - } - else - { - if( ( ( chMask & ( 1 << i ) ) != 0 ) && - ( Channels[i].frequency == 0 ) ) - {// Trying to enable an undefined channel - status &= 0xFE; // Channel mask KO - } - } - } - } - } - - // Get the minimum possible datarate - getPhy.Attribute = PHY_MIN_TX_DR; - getPhy.UplinkDwellTime = linkAdrReq->UplinkDwellTime; - phyParam = get_phy_params(&getPhy); - - linkAdrVerifyParams.Status = status; - linkAdrVerifyParams.AdrEnabled = linkAdrReq->AdrEnabled; - linkAdrVerifyParams.Datarate = linkAdrParams.Datarate; - linkAdrVerifyParams.TxPower = linkAdrParams.TxPower; - linkAdrVerifyParams.NbRep = linkAdrParams.NbRep; - linkAdrVerifyParams.CurrentDatarate = linkAdrReq->CurrentDatarate; - linkAdrVerifyParams.CurrentTxPower = linkAdrReq->CurrentTxPower; - linkAdrVerifyParams.CurrentNbRep = linkAdrReq->CurrentNbRep; - linkAdrVerifyParams.NbChannels = CN779_MAX_NB_CHANNELS; - linkAdrVerifyParams.ChannelsMask = &chMask; - linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value; - linkAdrVerifyParams.MaxDatarate = CN779_TX_MAX_DATARATE; - linkAdrVerifyParams.Channels = Channels; - linkAdrVerifyParams.MinTxPower = CN779_MIN_TX_POWER; - linkAdrVerifyParams.MaxTxPower = CN779_MAX_TX_POWER; - - // Verify the parameters and update, if necessary - status = verify_link_ADR_req( &linkAdrVerifyParams, &linkAdrParams.Datarate, &linkAdrParams.TxPower, &linkAdrParams.NbRep ); - - // Update channelsMask if everything is correct - if( status == 0x07 ) - { - // Set the channels mask to a default value - memset( ChannelsMask, 0, sizeof( ChannelsMask ) ); - // Update the channels mask - ChannelsMask[0] = chMask; - } - - // Update status variables - *drOut = linkAdrParams.Datarate; - *txPowOut = linkAdrParams.TxPower; - *nbRepOut = linkAdrParams.NbRep; - *nbBytesParsed = bytesProcessed; - - return status; -} - -uint8_t LoRaPHYCN779::setup_rx_params(RxParamSetupReqParams_t* rxParamSetupReq) -{ - uint8_t status = 0x07; - - // Verify radio frequency - if(_radio->check_rf_frequency(rxParamSetupReq->Frequency) == false ) - { - status &= 0xFE; // Channel frequency KO - } - - // Verify datarate - if( val_in_range( rxParamSetupReq->Datarate, CN779_RX_MIN_DATARATE, CN779_RX_MAX_DATARATE ) == 0 ) - { - status &= 0xFD; // Datarate KO - } - - // Verify datarate offset - if( val_in_range( rxParamSetupReq->DrOffset, CN779_MIN_RX1_DR_OFFSET, CN779_MAX_RX1_DR_OFFSET ) == 0 ) - { - status &= 0xFB; // Rx1DrOffset range KO - } - - return status; -} - -uint8_t LoRaPHYCN779::request_new_channel(NewChannelReqParams_t* newChannelReq) -{ - uint8_t status = 0x03; - ChannelAddParams_t channelAdd; - ChannelRemoveParams_t channelRemove; - - if( newChannelReq->NewChannel->frequency == 0 ) - { - channelRemove.ChannelId = newChannelReq->ChannelId; - - // Remove - if(remove_channel(&channelRemove) == false ) - { - status &= 0xFC; - } - } - else - { - channelAdd.NewChannel = newChannelReq->NewChannel; - channelAdd.ChannelId = newChannelReq->ChannelId; - - switch (add_channel(&channelAdd)) - { - case LORAWAN_STATUS_OK: - { - break; - } - case LORAWAN_STATUS_FREQUENCY_INVALID: - { - status &= 0xFE; - break; - } - case LORAWAN_STATUS_DATARATE_INVALID: - { - status &= 0xFD; - break; - } - case LORAWAN_STATUS_FREQ_AND_DR_INVALID: - { - status &= 0xFC; - break; - } - default: - { - status &= 0xFC; - break; - } - } - } - - return status; -} - -int8_t LoRaPHYCN779::setup_tx_params(TxParamSetupReqParams_t* txParamSetupReq) -{ - return -1; -} - -uint8_t LoRaPHYCN779::dl_channel_request(DlChannelReqParams_t* dlChannelReq) -{ - uint8_t status = 0x03; - - // Verify if the frequency is supported - if( VerifyTxFreq(dlChannelReq->Rx1Frequency, _radio) == false ) - { - status &= 0xFE; - } - - // Verify if an uplink frequency exists - if( Channels[dlChannelReq->ChannelId].frequency == 0 ) - { - status &= 0xFD; - } - - // Apply Rx1 frequency, if the status is OK - if( status == 0x03 ) - { - Channels[dlChannelReq->ChannelId].rx1_frequency = dlChannelReq->Rx1Frequency; - } - - return status; -} - -int8_t LoRaPHYCN779::get_alternate_DR(AlternateDrParams_t* alternateDr) -{ - int8_t datarate = 0; - - if( ( alternateDr->NbTrials % 48 ) == 0 ) - { - datarate = DR_0; - } - else if( ( alternateDr->NbTrials % 32 ) == 0 ) - { - datarate = DR_1; - } - else if( ( alternateDr->NbTrials % 24 ) == 0 ) - { - datarate = DR_2; - } - else if( ( alternateDr->NbTrials % 16 ) == 0 ) - { - datarate = DR_3; - } - else if( ( alternateDr->NbTrials % 8 ) == 0 ) - { - datarate = DR_4; - } - else - { - datarate = DR_5; - } - return datarate; -} - -void LoRaPHYCN779::calculate_backoff(CalcBackOffParams_t* calcBackOff) -{ - RegionCommonCalcBackOffParams_t calcBackOffParams; - - calcBackOffParams.Channels = Channels; - calcBackOffParams.Bands = Bands; - calcBackOffParams.LastTxIsJoinRequest = calcBackOff->LastTxIsJoinRequest; - calcBackOffParams.Joined = calcBackOff->Joined; - calcBackOffParams.DutyCycleEnabled = calcBackOff->DutyCycleEnabled; - calcBackOffParams.Channel = calcBackOff->Channel; - calcBackOffParams.ElapsedTime = calcBackOff->ElapsedTime; - calcBackOffParams.TxTimeOnAir = calcBackOff->TxTimeOnAir; - - get_DC_backoff( &calcBackOffParams ); -} - -bool LoRaPHYCN779::set_next_channel(NextChanParams_t* nextChanParams, - uint8_t* channel, lorawan_time_t* time, - lorawan_time_t* aggregatedTimeOff) -{ - uint8_t nbEnabledChannels = 0; - uint8_t delayTx = 0; - uint8_t enabledChannels[CN779_MAX_NB_CHANNELS] = { 0 }; - lorawan_time_t nextTxDelay = 0; - - if( num_active_channels( ChannelsMask, 0, 1 ) == 0 ) - { // Reactivate default channels - ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); - } - - if( nextChanParams->AggrTimeOff <= _lora_time.TimerGetElapsedTime( nextChanParams->LastAggrTx ) ) - { - // Reset Aggregated time off - *aggregatedTimeOff = 0; - - // Update bands Time OFF - nextTxDelay = update_band_timeoff( nextChanParams->Joined, nextChanParams->DutyCycleEnabled, Bands, CN779_MAX_NB_BANDS ); - - // Search how many channels are enabled - nbEnabledChannels = CountNbOfEnabledChannels( nextChanParams->Joined, nextChanParams->Datarate, - ChannelsMask, Channels, - Bands, enabledChannels, &delayTx ); - } - else - { - delayTx++; - nextTxDelay = nextChanParams->AggrTimeOff - _lora_time.TimerGetElapsedTime( nextChanParams->LastAggrTx ); - } - - if( nbEnabledChannels > 0 ) - { - // We found a valid channel - *channel = enabledChannels[get_random( 0, nbEnabledChannels - 1 )]; - - *time = 0; - return true; - } - else - { - if( delayTx > 0 ) - { - // Delay transmission due to AggregatedTimeOff or to a band time off - *time = nextTxDelay; - return true; - } - // Datarate not supported by any channel, restore defaults - ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); - *time = 0; - return false; - } -} - -lorawan_status_t LoRaPHYCN779::add_channel(ChannelAddParams_t* channelAdd) -{ - uint8_t band = 0; - bool drInvalid = false; - bool freqInvalid = false; - uint8_t id = channelAdd->ChannelId; - - if( id >= CN779_MAX_NB_CHANNELS ) - { - return LORAWAN_STATUS_PARAMETER_INVALID; - } - - // Validate the datarate range - if( val_in_range( channelAdd->NewChannel->dr_range.fields.min, CN779_TX_MIN_DATARATE, CN779_TX_MAX_DATARATE ) == 0 ) - { - drInvalid = true; - } - if( val_in_range( channelAdd->NewChannel->dr_range.fields.max, CN779_TX_MIN_DATARATE, CN779_TX_MAX_DATARATE ) == 0 ) - { - drInvalid = true; - } - if( channelAdd->NewChannel->dr_range.fields.min > channelAdd->NewChannel->dr_range.fields.max ) - { - drInvalid = true; - } - - // Default channels don't accept all values - if( id < CN779_NUMB_DEFAULT_CHANNELS ) - { - // Validate the datarate range for min: must be DR_0 - if( channelAdd->NewChannel->dr_range.fields.min > DR_0 ) - { - drInvalid = true; - } - // Validate the datarate range for max: must be DR_5 <= Max <= TX_MAX_DATARATE - if( val_in_range( channelAdd->NewChannel->dr_range.fields.max, DR_5, CN779_TX_MAX_DATARATE ) == 0 ) - { - drInvalid = true; - } - // We are not allowed to change the frequency - if( channelAdd->NewChannel->frequency != Channels[id].frequency ) - { - freqInvalid = true; - } - } - - // Check frequency - if( freqInvalid == false ) - { - if( VerifyTxFreq(channelAdd->NewChannel->frequency, _radio) == false ) - { - freqInvalid = true; - } - } - - // Check status - if( ( drInvalid == true ) && ( freqInvalid == true ) ) - { - return LORAWAN_STATUS_FREQ_AND_DR_INVALID; - } - if( drInvalid == true ) - { - return LORAWAN_STATUS_DATARATE_INVALID; - } - if( freqInvalid == true ) - { - return LORAWAN_STATUS_FREQUENCY_INVALID; - } - - memcpy( &(Channels[id]), channelAdd->NewChannel, sizeof( Channels[id] ) ); - Channels[id].band = band; - ChannelsMask[0] |= ( 1 << id ); - return LORAWAN_STATUS_OK; -} - -bool LoRaPHYCN779::remove_channel(ChannelRemoveParams_t* channelRemove) -{ - uint8_t id = channelRemove->ChannelId; - - if( id < CN779_NUMB_DEFAULT_CHANNELS ) - { - return false; - } - - // Remove the channel from the list of channels - const channel_params_t empty_channel = { 0, 0, { 0 }, 0 }; - Channels[id] = empty_channel; - - return disable_channel( ChannelsMask, id, CN779_MAX_NB_CHANNELS ); -} - -void LoRaPHYCN779::set_tx_cont_mode(ContinuousWaveParams_t* continuousWave) -{ - int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, Bands[Channels[continuousWave->Channel].band].max_tx_pwr, continuousWave->Datarate, ChannelsMask ); - int8_t phyTxPower = 0; - uint32_t frequency = Channels[continuousWave->Channel].frequency; - - // Calculate physical TX power - phyTxPower = compute_tx_power( txPowerLimited, continuousWave->MaxEirp, continuousWave->AntennaGain ); - - _radio->set_tx_continuous_wave(frequency, phyTxPower, continuousWave->Timeout); -} - -uint8_t LoRaPHYCN779::apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset) -{ - int8_t datarate = dr - drOffset; - - if( datarate < 0 ) - { - datarate = DR_0; - } - return datarate; -} diff --git a/features/lorawan/lorastack/phy/LoRaPHYCN779.h b/features/lorawan/lorastack/phy/LoRaPHYCN779.h index e45f2a7c4f..06d1bdc85f 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYCN779.h +++ b/features/lorawan/lorastack/phy/LoRaPHYCN779.h @@ -33,7 +33,6 @@ #define MBED_OS_LORAPHY_CN779_H_ #include "LoRaPHY.h" -#include "netsocket/LoRaRadio.h" #define CN779_MAX_NB_CHANNELS 16 @@ -49,306 +48,26 @@ public: LoRaPHYCN779(LoRaWANTimeHandler &lora_time); virtual ~LoRaPHYCN779(); - /*! - * \brief The function gets a value of a specific PHY attribute. - * - * \param [in] getPhy A pointer to the function parameters. - * - * \retval The structure containing the PHY parameter. - */ - virtual PhyParam_t get_phy_params(GetPhyParams_t* getPhy ); - - /*! - * \brief Updates the last TX done parameters of the current channel. - * - * \param [in] txDone A pointer to the function parameters. - */ - virtual void set_band_tx_done(SetBandTxDoneParams_t* txDone ); - - /*! - * \brief Initializes the channels masks and the channels. - * - * \param [in] type Sets the initialization type. - */ - virtual void load_defaults(InitType_t type ); - - /*! - * \brief Verifies a parameter. - * - * \param [in] verify A pointer to the function parameters. - * - * \param [in] phyAttribute The attribute to verify. - * - * \retval True, if the parameter is valid. - */ - virtual bool verify(VerifyParams_t* verify, PhyAttribute_t phyAttribute ); - - /*! - * \brief The function parses the input buffer and sets up the channels of the CF list. - * - * \param [in] applyCFList A pointer to the function parameters. - */ - virtual void apply_cf_list(ApplyCFListParams_t* applyCFList ); - - /*! - * \brief Sets a channels mask. - * - * \param [in] chanMaskSet A pointer to the function parameters. - * - * \retval True, if the channels mask could be set. - */ - virtual bool set_channel_mask(ChanMaskSetParams_t* chanMaskSet ); - - /*! - * \brief Calculates the next datarate to set, when ADR is on or off. - * - * \param [in] adrNext A pointer to the function parameters. - * - * \param [out] drOut The calculated datarate for the next TX. - * - * \param [out] txPowOut The TX power for the next TX. - * - * \param [out] adrAckCounter The calculated ADR acknowledgement counter. - * - * \retval True, if an ADR request should be performed. - */ - virtual bool get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut, - int8_t* txPowOut, uint32_t* adrAckCounter ); - - /*! - * \brief Configuration of the RX windows. - * - * \param [in] rxConfig A pointer to the function parameters. - * - * \param [out] datarate The datarate index set. - * - * \retval True, if the configuration was applied successfully. - */ - virtual bool rx_config(rx_config_params_t* rxConfig, int8_t* datarate ); - - /* - * RX window precise timing - * - * For more details please consult the following document, chapter 3.1.2. - * http://www.semtech.com/images/datasheet/SX1272_settings_for_LoRaWAN_v2.0.pdf - * or - * http://www.semtech.com/images/datasheet/SX1276_settings_for_LoRaWAN_v2.0.pdf - * - * Downlink start: T = Tx + 1s (+/- 20 us) - * | - * TRxEarly | TRxLate - * | | | - * | | +---+---+---+---+---+---+---+---+ - * | | | Latest Rx window | - * | | +---+---+---+---+---+---+---+---+ - * | | | - * +---+---+---+---+---+---+---+---+ - * | Earliest Rx window | - * +---+---+---+---+---+---+---+---+ - * | - * +---+---+---+---+---+---+---+---+ - *Downlink preamble 8 symbols | | | | | | | | | - * +---+---+---+---+---+---+---+---+ - * - * Worst case Rx window timings - * - * TRxLate = DEFAULT_MIN_RX_SYMBOLS * tSymbol - RADIO_WAKEUP_TIME - * TRxEarly = 8 - DEFAULT_MIN_RX_SYMBOLS * tSymbol - RxWindowTimeout - RADIO_WAKEUP_TIME - * - * TRxLate - TRxEarly = 2 * DEFAULT_SYSTEM_MAX_RX_ERROR - * - * RxOffset = ( TRxLate + TRxEarly ) / 2 - * - * RxWindowTimeout = ( 2 * DEFAULT_MIN_RX_SYMBOLS - 8 ) * tSymbol + 2 * DEFAULT_SYSTEM_MAX_RX_ERROR - * RxOffset = 4 * tSymbol - RxWindowTimeout / 2 - RADIO_WAKE_UP_TIME - * - * The minimum value of RxWindowTimeout must be 5 symbols which implies that the system always tolerates at least an error of 1.5 * tSymbol - */ - /*! - * Computes the RX window timeout and offset. - * - * \param [in] datarate The RX window datarate index to be used. - * - * \param [in] minRxSymbols The minimum required number of symbols to detect an RX frame. - * - * \param [in] rxError The system maximum timing error of the receiver in milliseconds. - * The receiver will turn on in a [-rxError : +rxError] ms - * interval around RxOffset. - * - * \param [out] rxConfigParams Returns the updated WindowTimeout and WindowOffset fields. - */ - virtual void compute_rx_win_params(int8_t datarate, - uint8_t minRxSymbols, - uint32_t rxError, - rx_config_params_t *rxConfigParams); - - /*! - * \brief TX configuration. - * - * \param [in] txConfig A pointer to the function parameters. - * - * \param [out] txPower The TX power index set. - * - * \param [out] txTimeOnAir The time-on-air of the frame. - * - * \retval True, if the configuration was applied successfully. - */ - virtual bool tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - lorawan_time_t* txTimeOnAir ); - - /*! - * \brief The function processes a Link ADR request. - * - * \param [in] linkAdrReq A pointer to the function parameters. - * - * \param [out] drOut The datarate applied. - * - * \param [out] txPowOut The TX power applied. - * - * \param [out] nbRepOut The number of repetitions to apply. - * - * \param [out] nbBytesParsed The number of bytes parsed. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t link_ADR_request(LinkAdrReqParams_t* linkAdrReq, - int8_t* drOut, int8_t* txPowOut, - uint8_t* nbRepOut, - uint8_t* nbBytesParsed ); - - /*! - * \brief The function processes a RX parameter setup request. - * - * \param [in] rxParamSetupReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t setup_rx_params(RxParamSetupReqParams_t* rxParamSetupReq ); - - /*! - * \brief The function processes a new channel request. - * - * \param [in] newChannelReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t request_new_channel(NewChannelReqParams_t* newChannelReq ); - - /*! - * \brief The function processes a TX ParamSetup request. - * - * \param [in] txParamSetupReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - * Returns -1, if the functionality is not implemented. In this case, the end node - * shall ignore the command. - */ - virtual int8_t setup_tx_params(TxParamSetupReqParams_t* txParamSetupReq ); - - /*! - * \brief The function processes a DlChannel request. - * - * \param [in] dlChannelReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t dl_channel_request(DlChannelReqParams_t* dlChannelReq ); - - /*! - * \brief Alternates the datarate of the channel for the join request. - * - * \param [in] alternateDr A pointer to the function parameters. - * - * \retval The datarate to apply. - */ - virtual int8_t get_alternate_DR(AlternateDrParams_t* alternateDr ); - - /*! - * \brief Calculates the back-off time. - * - * \param [in] calcBackOff A pointer to the function parameters. - */ - virtual void calculate_backoff(CalcBackOffParams_t* calcBackOff ); - - /*! - * \brief Searches and sets the next random available channel. - * - * \param [in] nextChanParams The parameters for the next channel. - * - * \param [out] channel The next channel to use for TX. - * - * \param [out] time The time to wait for the next transmission according to the duty - * cycle. - * - * \param [out] aggregatedTimeOff Updates the aggregated time off. - * - * \retval Function status [1: OK, 0: Unable to find a channel on the current datarate]. - */ - virtual bool set_next_channel(NextChanParams_t* nextChanParams, - uint8_t* channel, lorawan_time_t* time, - lorawan_time_t* aggregatedTimeOff ); - - /*! - * \brief Adds a channel. - * - * \param [in] channelAdd A pointer to the function parameters. - * - * \retval The status of the operation. - */ - virtual lorawan_status_t add_channel(ChannelAddParams_t* channelAdd ); - - /*! - * \brief Removes a channel. - * - * \param [in] channelRemove A pointer to the function parameters. - * - * \retval True, if the channel was removed successfully. - */ - virtual bool remove_channel(ChannelRemoveParams_t* channelRemove ); - - /*! - * \brief Sets the radio into continuous wave mode. - * - * \param [in] continuousWave A pointer to the function parameters. - */ - virtual void set_tx_cont_mode(ContinuousWaveParams_t* continuousWave ); - - /*! - * \brief Computes a new datarate according to the given offset. - * - * \param [in] downlinkDwellTime The downlink dwell time configuration. 0: No limit, 1: 400ms - * - * \param [in] dr The current datarate. - * - * \param [in] drOffset The offset to be applied. - * - * \retval newDr The computed datarate. - */ - virtual uint8_t apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ); - private: - uint8_t CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, channel_params_t* channels, band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ); - - // Global attributes /*! * LoRaMAC channels */ - channel_params_t Channels[CN779_MAX_NB_CHANNELS]; + channel_params_t channels[CN779_MAX_NB_CHANNELS]; /*! * LoRaMac bands */ - band_t Bands[CN779_MAX_NB_BANDS]; + band_t bands[CN779_MAX_NB_BANDS]; /*! * LoRaMac channels mask */ - uint16_t ChannelsMask[CN779_CHANNELS_MASK_SIZE]; + uint16_t channel_masks[CN779_CHANNELS_MASK_SIZE]; /*! * LoRaMac channels default mask */ - uint16_t ChannelsDefaultMask[CN779_CHANNELS_MASK_SIZE]; + uint16_t default_channel_masks[CN779_CHANNELS_MASK_SIZE]; }; #endif /* MBED_OS_LORAPHY_CN779_H_ */ diff --git a/features/lorawan/lorastack/phy/LoRaPHYEU433.cpp b/features/lorawan/lorastack/phy/LoRaPHYEU433.cpp index ccb0c8ff1a..8df46d53d5 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYEU433.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYEU433.cpp @@ -30,9 +30,7 @@ */ #include "LoRaPHYEU433.h" - #include "lora_phy_ds.h" -#include "LoRaRadio.h" /*! * Number of default channels @@ -69,6 +67,8 @@ */ #define EU433_DEFAULT_DATARATE DR_0 +#define EU433_DEFAULT_MAX_DATARATE DR_5 + /*! * Minimal Rx1 receive datarate offset */ @@ -185,1061 +185,135 @@ * Band 0 definition * { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff } */ -#define EU433_BAND0 { 100, EU433_MAX_TX_POWER, 0, 0, 0 } // 1.0 % +static const band_t EU433_BAND0 = {100, EU433_MAX_TX_POWER, 0, 0, 0, 433175000, 434665000}; // 1.0 % /*! * LoRaMac default channel 1 * Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } */ -#define EU433_LC1 { 433175000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } +static const channel_params_t EU433_LC1 = {433175000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0}; /*! * LoRaMac default channel 2 * Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } */ -#define EU433_LC2 { 433375000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } +static const channel_params_t EU433_LC2 = {433375000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0}; /*! * LoRaMac default channel 3 * Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } */ -#define EU433_LC3 { 433575000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } +static const channel_params_t EU433_LC3 = {433575000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0}; /*! * LoRaMac channels which are allowed for the join procedure */ -#define EU433_JOIN_CHANNELS ( uint16_t )( LC( 1 ) | LC( 2 ) | LC( 3 ) ) +#define EU433_JOIN_CHANNELS (uint16_t) (LC(1) | LC(2) | LC(3)) /*! * Data rates table definition */ -static const uint8_t DataratesEU433[] = { 12, 11, 10, 9, 8, 7, 7, 50 }; +static const uint8_t datarates_EU433[] = {12, 11, 10, 9, 8, 7, 7, 50}; /*! * Bandwidths table definition in Hz */ -static const uint32_t BandwidthsEU433[] = { 125000, 125000, 125000, 125000, 125000, 125000, 250000, 0 }; +static const uint32_t bandwidths_EU433[] = {125000, 125000, 125000, 125000, 125000, 125000, 250000, 0}; /*! * Maximum payload with respect to the datarate index. Cannot operate with repeater. */ -static const uint8_t MaxPayloadOfDatarateEU433[] = { 51, 51, 51, 115, 242, 242, 242, 242 }; +static const uint8_t max_payloads_EU433[] = {51, 51, 51, 115, 242, 242, 242, 242}; /*! * Maximum payload with respect to the datarate index. Can operate with repeater. */ -static const uint8_t MaxPayloadOfDatarateRepeaterEU433[] = { 51, 51, 51, 115, 222, 222, 222, 222 }; +static const uint8_t max_payloads_with_repeater_EU433[] = {51, 51, 51, 115, 222, 222, 222, 222}; -// Static functions -static int8_t GetNextLowerTxDr( int8_t dr, int8_t minDr ) -{ - uint8_t nextLowerDr = 0; - - if( dr == minDr ) - { - nextLowerDr = minDr; - } - else - { - nextLowerDr = dr - 1; - } - return nextLowerDr; -} - -static uint32_t GetBandwidth( uint32_t drIndex ) -{ - switch( BandwidthsEU433[drIndex] ) - { - default: - case 125000: - return 0; - case 250000: - return 1; - case 500000: - return 2; - } -} - -static int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower, int8_t datarate, uint16_t* channelsMask ) -{ - int8_t txPowerResult = txPower; - - // Limit tx power to the band max - txPowerResult = MAX( txPower, maxBandTxPower ); - - return txPowerResult; -} - -static bool VerifyTxFreq( uint32_t freq, LoRaRadio *radio ) -{ - // Check radio driver support - if(radio->check_rf_frequency(freq) == false ) - { - return false; - } - - if( ( freq < 433175000 ) || ( freq > 434665000 ) ) - { - return false; - } - return true; -} - -uint8_t LoRaPHYEU433::CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, channel_params_t* channels, band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ) -{ - uint8_t nbEnabledChannels = 0; - uint8_t delayTransmission = 0; - - for( uint8_t i = 0, k = 0; i < EU433_MAX_NB_CHANNELS; i += 16, k++ ) - { - for( uint8_t j = 0; j < 16; j++ ) - { - if( ( channelsMask[k] & ( 1 << j ) ) != 0 ) - { - if( channels[i + j].frequency == 0 ) - { // Check if the channel is enabled - continue; - } - if( joined == false ) - { - if( ( EU433_JOIN_CHANNELS & ( 1 << j ) ) == 0 ) - { - continue; - } - } - if( val_in_range( datarate, channels[i + j].dr_range.fields.min, - channels[i + j].dr_range.fields.max ) == 0 ) - { // Check if the current channel selection supports the given datarate - continue; - } - if( bands[channels[i + j].band].off_time > 0 ) - { // Check if the band is available for transmission - delayTransmission++; - continue; - } - enabledChannels[nbEnabledChannels++] = i + j; - } - } - } - - *delayTx = delayTransmission; - return nbEnabledChannels; -} - LoRaPHYEU433::LoRaPHYEU433(LoRaWANTimeHandler &lora_time) - : LoRaPHY(lora_time) + : LoRaPHY(lora_time) { - const band_t band0 = EU433_BAND0; - Bands[0] = band0; + bands[0] = EU433_BAND0; + + // Channels + channels[0] = EU433_LC1; + channels[1] = EU433_LC2;; + channels[2] = EU433_LC3;; + + // Initialize the channels default mask + default_channel_masks[0] = LC(1) + LC(2) + LC(3); + // Update the channels mask + copy_channel_mask(channel_masks, default_channel_masks, EU433_CHANNELS_MASK_SIZE); + + // set default channels + phy_params.channels.channel_list = channels; + phy_params.channels.channel_list_size = EU433_MAX_NB_CHANNELS; + phy_params.channels.mask_list = channel_masks; + phy_params.channels.default_mask_list = default_channel_masks; + phy_params.channels.mask_list_size = EU433_CHANNELS_MASK_SIZE; + + // set bands for EU433 spectrum + phy_params.bands.table = bands; + phy_params.bands.size = EU433_MAX_NB_BANDS; + + // set bandwidths available in EU433 spectrum + phy_params.bandwidths.table = (void *) bandwidths_EU433; + phy_params.bandwidths.size = 8; + + // set data rates available in EU433 spectrum + phy_params.datarates.table = (void *) datarates_EU433; + phy_params.datarates.size = 8; + + // set payload sizes with respect to data rates + phy_params.payloads.table = (void *) max_payloads_EU433; + phy_params.payloads.size = 8; + phy_params.payloads_with_repeater.table = (void *) max_payloads_with_repeater_EU433; + phy_params.payloads.size = 8; + + // dwell time setting + phy_params.ul_dwell_time_setting = 0; + phy_params.dl_dwell_time_setting = 0; + + // set initial and default parameters + phy_params.duty_cycle_enabled = EU433_DUTY_CYCLE_ENABLED; + phy_params.accept_tx_param_setup_req = false; + phy_params.fsk_supported = true; + phy_params.cflist_supported = true; + phy_params.dl_channel_req_supported = true; + phy_params.custom_channelplans_supported = true; + phy_params.default_channel_cnt = EU433_NUMB_DEFAULT_CHANNELS; + phy_params.max_channel_cnt = EU433_MAX_NB_CHANNELS; + phy_params.cflist_channel_cnt = EU433_NUMB_CHANNELS_CF_LIST; + phy_params.min_tx_datarate = EU433_TX_MIN_DATARATE; + phy_params.max_tx_datarate = EU433_TX_MAX_DATARATE; + phy_params.min_rx_datarate = EU433_RX_MIN_DATARATE; + phy_params.max_rx_datarate = EU433_RX_MAX_DATARATE; + phy_params.default_datarate = EU433_DEFAULT_DATARATE; + phy_params.default_max_datarate = EU433_DEFAULT_MAX_DATARATE; + phy_params.min_rx1_dr_offset = EU433_MIN_RX1_DR_OFFSET; + phy_params.max_rx1_dr_offset = EU433_MAX_RX1_DR_OFFSET; + phy_params.default_rx1_dr_offset = EU433_DEFAULT_RX1_DR_OFFSET; + phy_params.min_tx_power = EU433_MIN_TX_POWER; + phy_params.max_tx_power = EU433_MAX_TX_POWER; + phy_params.default_tx_power = EU433_DEFAULT_TX_POWER; + phy_params.default_max_eirp = EU433_DEFAULT_MAX_EIRP; + phy_params.default_antenna_gain = EU433_DEFAULT_ANTENNA_GAIN; + phy_params.adr_ack_limit = EU433_ADR_ACK_LIMIT; + phy_params.adr_ack_delay = EU433_ADR_ACK_DELAY; + phy_params.max_rx_window = EU433_MAX_RX_WINDOW; + phy_params.recv_delay1 = EU433_RECEIVE_DELAY1; + phy_params.recv_delay2 = EU433_RECEIVE_DELAY2; + phy_params.join_channel_mask = EU433_JOIN_CHANNELS; + phy_params.join_accept_delay1 = EU433_JOIN_ACCEPT_DELAY1; + phy_params.join_accept_delay2 = EU433_JOIN_ACCEPT_DELAY2; + phy_params.max_fcnt_gap = EU433_MAX_FCNT_GAP; + phy_params.ack_timeout = EU433_ACKTIMEOUT; + phy_params.ack_timeout_rnd = EU433_ACK_TIMEOUT_RND; + phy_params.rx_window2_datarate = EU433_RX_WND_2_DR; + phy_params.rx_window2_frequency = EU433_RX_WND_2_FREQ; } LoRaPHYEU433::~LoRaPHYEU433() { } - -PhyParam_t LoRaPHYEU433::get_phy_params(GetPhyParams_t* getPhy) -{ - PhyParam_t phyParam = { 0 }; - - switch( getPhy->Attribute ) - { - case PHY_MIN_RX_DR: - { - phyParam.Value = EU433_RX_MIN_DATARATE; - break; - } - case PHY_MIN_TX_DR: - { - phyParam.Value = EU433_TX_MIN_DATARATE; - break; - } - case PHY_DEF_TX_DR: - { - phyParam.Value = EU433_DEFAULT_DATARATE; - break; - } - case PHY_NEXT_LOWER_TX_DR: - { - phyParam.Value = GetNextLowerTxDr( getPhy->Datarate, EU433_TX_MIN_DATARATE ); - break; - } - case PHY_DEF_TX_POWER: - { - phyParam.Value = EU433_DEFAULT_TX_POWER; - break; - } - case PHY_MAX_PAYLOAD: - { - phyParam.Value = MaxPayloadOfDatarateEU433[getPhy->Datarate]; - break; - } - case PHY_MAX_PAYLOAD_REPEATER: - { - phyParam.Value = MaxPayloadOfDatarateRepeaterEU433[getPhy->Datarate]; - break; - } - case PHY_DUTY_CYCLE: - { - phyParam.Value = EU433_DUTY_CYCLE_ENABLED; - break; - } - case PHY_MAX_RX_WINDOW: - { - phyParam.Value = EU433_MAX_RX_WINDOW; - break; - } - case PHY_RECEIVE_DELAY1: - { - phyParam.Value = EU433_RECEIVE_DELAY1; - break; - } - case PHY_RECEIVE_DELAY2: - { - phyParam.Value = EU433_RECEIVE_DELAY2; - break; - } - case PHY_JOIN_ACCEPT_DELAY1: - { - phyParam.Value = EU433_JOIN_ACCEPT_DELAY1; - break; - } - case PHY_JOIN_ACCEPT_DELAY2: - { - phyParam.Value = EU433_JOIN_ACCEPT_DELAY2; - break; - } - case PHY_MAX_FCNT_GAP: - { - phyParam.Value = EU433_MAX_FCNT_GAP; - break; - } - case PHY_ACK_TIMEOUT: - { - phyParam.Value = ( EU433_ACKTIMEOUT + get_random( -EU433_ACK_TIMEOUT_RND, EU433_ACK_TIMEOUT_RND ) ); - break; - } - case PHY_DEF_DR1_OFFSET: - { - phyParam.Value = EU433_DEFAULT_RX1_DR_OFFSET; - break; - } - case PHY_DEF_RX2_FREQUENCY: - { - phyParam.Value = EU433_RX_WND_2_FREQ; - break; - } - case PHY_DEF_RX2_DR: - { - phyParam.Value = EU433_RX_WND_2_DR; - break; - } - case PHY_CHANNELS_MASK: - { - phyParam.ChannelsMask = ChannelsMask; - break; - } - case PHY_CHANNELS_DEFAULT_MASK: - { - phyParam.ChannelsMask = ChannelsDefaultMask; - break; - } - case PHY_MAX_NB_CHANNELS: - { - phyParam.Value = EU433_MAX_NB_CHANNELS; - break; - } - case PHY_CHANNELS: - { - phyParam.Channels = Channels; - break; - } - case PHY_DEF_UPLINK_DWELL_TIME: - case PHY_DEF_DOWNLINK_DWELL_TIME: - { - phyParam.Value = 0; - break; - } - case PHY_DEF_MAX_EIRP: - { - phyParam.fValue = EU433_DEFAULT_MAX_EIRP; - break; - } - case PHY_DEF_ANTENNA_GAIN: - { - phyParam.fValue = EU433_DEFAULT_ANTENNA_GAIN; - break; - } - case PHY_NB_JOIN_TRIALS: - case PHY_DEF_NB_JOIN_TRIALS: - { - phyParam.Value = 48; - break; - } - default: - { - break; - } - } - - return phyParam; -} - -void LoRaPHYEU433::set_band_tx_done(SetBandTxDoneParams_t* txDone) -{ - set_last_tx_done( txDone->Joined, &Bands[Channels[txDone->Channel].band], txDone->LastTxDoneTime ); -} - -void LoRaPHYEU433::load_defaults(InitType_t type) -{ - switch( type ) - { - case INIT_TYPE_INIT: - { - // Channels - const channel_params_t channel1 = EU433_LC1; - const channel_params_t channel2 = EU433_LC2; - const channel_params_t channel3 = EU433_LC3; - Channels[0] = channel1; - Channels[1] = channel2; - Channels[2] = channel3; - - // Initialize the channels default mask - ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 ); - // Update the channels mask - copy_channel_mask( ChannelsMask, ChannelsDefaultMask, 1 ); - break; - } - case INIT_TYPE_RESTORE: - { - // Restore channels default mask - ChannelsMask[0] |= ChannelsDefaultMask[0]; - break; - } - default: - { - break; - } - } -} - -bool LoRaPHYEU433::verify(VerifyParams_t* verify, PhyAttribute_t phyAttribute) -{ - switch( phyAttribute ) - { - case PHY_TX_DR: - { - return val_in_range( verify->DatarateParams.Datarate, EU433_TX_MIN_DATARATE, EU433_TX_MAX_DATARATE ); - } - case PHY_DEF_TX_DR: - { - return val_in_range( verify->DatarateParams.Datarate, DR_0, DR_5 ); - } - case PHY_RX_DR: - { - return val_in_range( verify->DatarateParams.Datarate, EU433_RX_MIN_DATARATE, EU433_RX_MAX_DATARATE ); - } - case PHY_DEF_TX_POWER: - case PHY_TX_POWER: - { - // Remark: switched min and max! - return val_in_range( verify->TxPower, EU433_MAX_TX_POWER, EU433_MIN_TX_POWER ); - } - case PHY_DUTY_CYCLE: - { - return EU433_DUTY_CYCLE_ENABLED; - } - case PHY_NB_JOIN_TRIALS: - { - if( verify->NbJoinTrials < 48 ) - { - return false; - } - break; - } - default: - return false; - } - return true; -} - -void LoRaPHYEU433::apply_cf_list(ApplyCFListParams_t* applyCFList) -{ - channel_params_t newChannel; - ChannelAddParams_t channelAdd; - ChannelRemoveParams_t channelRemove; - - // Setup default datarate range - newChannel.dr_range.value = ( DR_5 << 4 ) | DR_0; - - // Size of the optional CF list - if( applyCFList->Size != 16 ) - { - return; - } - - // Last byte is RFU, don't take it into account - for( uint8_t i = 0, chanIdx = EU433_NUMB_DEFAULT_CHANNELS; chanIdx < EU433_MAX_NB_CHANNELS; i+=3, chanIdx++ ) - { - if( chanIdx < ( EU433_NUMB_CHANNELS_CF_LIST + EU433_NUMB_DEFAULT_CHANNELS ) ) - { - // Channel frequency - newChannel.frequency = (uint32_t) applyCFList->Payload[i]; - newChannel.frequency |= ( (uint32_t) applyCFList->Payload[i + 1] << 8 ); - newChannel.frequency |= ( (uint32_t) applyCFList->Payload[i + 2] << 16 ); - newChannel.frequency *= 100; - - // Initialize alternative frequency to 0 - newChannel.rx1_frequency = 0; - } - else - { - newChannel.frequency = 0; - newChannel.dr_range.value = 0; - newChannel.rx1_frequency = 0; - } - - if( newChannel.frequency != 0 ) - { - channelAdd.NewChannel = &newChannel; - channelAdd.ChannelId = chanIdx; - - // Try to add all channels - add_channel( &channelAdd ); - } - else - { - channelRemove.ChannelId = chanIdx; - - remove_channel( &channelRemove ); - } - } -} - -bool LoRaPHYEU433::set_channel_mask(ChanMaskSetParams_t* chanMaskSet) -{ - switch( chanMaskSet->ChannelsMaskType ) - { - case CHANNELS_MASK: - { - copy_channel_mask( ChannelsMask, chanMaskSet->ChannelsMaskIn, 1 ); - break; - } - case CHANNELS_DEFAULT_MASK: - { - copy_channel_mask( ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 1 ); - break; - } - default: - return false; - } - return true; -} - -bool LoRaPHYEU433::get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut, - int8_t* txPowOut, uint32_t* adrAckCounter) -{ - bool adrAckReq = false; - int8_t datarate = adrNext->Datarate; - int8_t txPower = adrNext->TxPower; - GetPhyParams_t getPhy; - PhyParam_t phyParam; - - // Report back the adr ack counter - *adrAckCounter = adrNext->AdrAckCounter; - - if( adrNext->AdrEnabled == true ) - { - if( datarate == EU433_TX_MIN_DATARATE ) - { - *adrAckCounter = 0; - adrAckReq = false; - } - else - { - if( adrNext->AdrAckCounter >= EU433_ADR_ACK_LIMIT ) - { - adrAckReq = true; - txPower = EU433_MAX_TX_POWER; - } - else - { - adrAckReq = false; - } - if( adrNext->AdrAckCounter >= ( EU433_ADR_ACK_LIMIT + EU433_ADR_ACK_DELAY ) ) - { - if( ( adrNext->AdrAckCounter % EU433_ADR_ACK_DELAY ) == 1 ) - { - // Decrease the datarate - getPhy.Attribute = PHY_NEXT_LOWER_TX_DR; - getPhy.Datarate = datarate; - getPhy.UplinkDwellTime = adrNext->UplinkDwellTime; - phyParam = get_phy_params( &getPhy ); - datarate = phyParam.Value; - - if( datarate == EU433_TX_MIN_DATARATE ) - { - // We must set adrAckReq to false as soon as we reach the lowest datarate - adrAckReq = false; - if( adrNext->UpdateChanMask == true ) - { - // Re-enable default channels - ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); - } - } - } - } - } - } - - *drOut = datarate; - *txPowOut = txPower; - return adrAckReq; -} - -void LoRaPHYEU433::compute_rx_win_params(int8_t datarate, uint8_t minRxSymbols, - uint32_t rxError, - rx_config_params_t *rxConfigParams) -{ - double tSymbol = 0.0; - - // Get the datarate, perform a boundary check - rxConfigParams->datarate = MIN( datarate, EU433_RX_MAX_DATARATE ); - rxConfigParams->bandwidth = GetBandwidth( rxConfigParams->datarate ); - - if( rxConfigParams->datarate == DR_7 ) - { // FSK - tSymbol = compute_symb_timeout_fsk( DataratesEU433[rxConfigParams->datarate] ); - } - else - { // LoRa - tSymbol = compute_symb_timeout_lora( DataratesEU433[rxConfigParams->datarate], BandwidthsEU433[rxConfigParams->datarate] ); - } - - get_rx_window_params( tSymbol, minRxSymbols, rxError, RADIO_WAKEUP_TIME, &rxConfigParams->window_timeout, &rxConfigParams->window_offset ); -} - -bool LoRaPHYEU433::rx_config(rx_config_params_t* rxConfig, int8_t* datarate) -{ - radio_modems_t modem; - int8_t dr = rxConfig->datarate; - uint8_t maxPayload = 0; - int8_t phyDr = 0; - uint32_t frequency = rxConfig->frequency; - - if( _radio->get_status() != RF_IDLE ) - { - return false; - } - - if( rxConfig->rx_slot == RX_SLOT_WIN_1 ) - { - // Apply window 1 frequency - frequency = Channels[rxConfig->channel].frequency; - // Apply the alternative RX 1 window frequency, if it is available - if( Channels[rxConfig->channel].rx1_frequency != 0 ) - { - frequency = Channels[rxConfig->channel].rx1_frequency; - } - } - - // Read the physical datarate from the datarates table - phyDr = DataratesEU433[dr]; - - _radio->set_channel( frequency ); - - // Radio configuration - if( dr == DR_7 ) - { - modem = MODEM_FSK; - _radio->set_rx_config( modem, 50000, phyDr * 1000, 0, 83333, 5, - rxConfig->window_timeout, false, 0, true, 0, 0, - false, rxConfig->is_rx_continuous ); - } - else - { - modem = MODEM_LORA; - _radio->set_rx_config( modem, rxConfig->bandwidth, phyDr, 1, 0, 8, - rxConfig->window_timeout, false, 0, false, 0, 0, - true, rxConfig->is_rx_continuous ); - } - - if( rxConfig->is_repeater_supported == true ) - { - maxPayload = MaxPayloadOfDatarateRepeaterEU433[dr]; - } - else - { - maxPayload = MaxPayloadOfDatarateEU433[dr]; - } - _radio->set_max_payload_length( modem, maxPayload + LORA_MAC_FRMPAYLOAD_OVERHEAD ); - - *datarate = (uint8_t) dr; - return true; -} - -bool LoRaPHYEU433::tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - lorawan_time_t* txTimeOnAir) -{ - radio_modems_t modem; - int8_t phyDr = DataratesEU433[txConfig->Datarate]; - int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, Bands[Channels[txConfig->Channel].band].max_tx_pwr, txConfig->Datarate, ChannelsMask ); - uint32_t bandwidth = GetBandwidth( txConfig->Datarate ); - int8_t phyTxPower = 0; - - // Calculate physical TX power - phyTxPower = compute_tx_power( txPowerLimited, txConfig->MaxEirp, txConfig->AntennaGain ); - - // Setup the radio frequency - _radio->set_channel( Channels[txConfig->Channel].frequency ); - - if( txConfig->Datarate == DR_7 ) - { // High Speed FSK channel - modem = MODEM_FSK; - _radio->set_tx_config( modem, phyTxPower, 25000, bandwidth, phyDr * 1000, 0, 5, false, true, 0, 0, false, 3000 ); - } - else - { - modem = MODEM_LORA; - _radio->set_tx_config( modem, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 3000 ); - } - - // Setup maximum payload lenght of the radio driver - _radio->set_max_payload_length( modem, txConfig->PktLen ); - // Get the time-on-air of the next tx frame - *txTimeOnAir = _radio->time_on_air( modem, txConfig->PktLen ); - - *txPower = txPowerLimited; - return true; -} - -uint8_t LoRaPHYEU433::link_ADR_request(LinkAdrReqParams_t* linkAdrReq, - int8_t* drOut, int8_t* txPowOut, - uint8_t* nbRepOut, uint8_t* nbBytesParsed) -{ - uint8_t status = 0x07; - RegionCommonLinkAdrParams_t linkAdrParams; - uint8_t nextIndex = 0; - uint8_t bytesProcessed = 0; - uint16_t chMask = 0; - GetPhyParams_t getPhy; - PhyParam_t phyParam; - RegionCommonLinkAdrReqVerifyParams_t linkAdrVerifyParams; - - while( bytesProcessed < linkAdrReq->PayloadSize ) - { - // Get ADR request parameters - nextIndex = parse_link_ADR_req( &( linkAdrReq->Payload[bytesProcessed] ), &linkAdrParams ); - - if( nextIndex == 0 ) - break; // break loop, since no more request has been found - - // Update bytes processed - bytesProcessed += nextIndex; - - // Revert status, as we only check the last ADR request for the channel mask KO - status = 0x07; - - // Setup temporary channels mask - chMask = linkAdrParams.ChMask; - - // Verify channels mask - if( ( linkAdrParams.ChMaskCtrl == 0 ) && ( chMask == 0 ) ) - { - status &= 0xFE; // Channel mask KO - } - else if( ( ( linkAdrParams.ChMaskCtrl >= 1 ) && ( linkAdrParams.ChMaskCtrl <= 5 )) || - ( linkAdrParams.ChMaskCtrl >= 7 ) ) - { - // RFU - status &= 0xFE; // Channel mask KO - } - else - { - for( uint8_t i = 0; i < EU433_MAX_NB_CHANNELS; i++ ) - { - if( linkAdrParams.ChMaskCtrl == 6 ) - { - if( Channels[i].frequency != 0 ) - { - chMask |= 1 << i; - } - } - else - { - if( ( ( chMask & ( 1 << i ) ) != 0 ) && - ( Channels[i].frequency == 0 ) ) - {// Trying to enable an undefined channel - status &= 0xFE; // Channel mask KO - } - } - } - } - } - - // Get the minimum possible datarate - getPhy.Attribute = PHY_MIN_TX_DR; - getPhy.UplinkDwellTime = linkAdrReq->UplinkDwellTime; - phyParam = get_phy_params( &getPhy ); - - linkAdrVerifyParams.Status = status; - linkAdrVerifyParams.AdrEnabled = linkAdrReq->AdrEnabled; - linkAdrVerifyParams.Datarate = linkAdrParams.Datarate; - linkAdrVerifyParams.TxPower = linkAdrParams.TxPower; - linkAdrVerifyParams.NbRep = linkAdrParams.NbRep; - linkAdrVerifyParams.CurrentDatarate = linkAdrReq->CurrentDatarate; - linkAdrVerifyParams.CurrentTxPower = linkAdrReq->CurrentTxPower; - linkAdrVerifyParams.CurrentNbRep = linkAdrReq->CurrentNbRep; - linkAdrVerifyParams.NbChannels = EU433_MAX_NB_CHANNELS; - linkAdrVerifyParams.ChannelsMask = &chMask; - linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value; - linkAdrVerifyParams.MaxDatarate = EU433_TX_MAX_DATARATE; - linkAdrVerifyParams.Channels = Channels; - linkAdrVerifyParams.MinTxPower = EU433_MIN_TX_POWER; - linkAdrVerifyParams.MaxTxPower = EU433_MAX_TX_POWER; - - // Verify the parameters and update, if necessary - status = verify_link_ADR_req( &linkAdrVerifyParams, &linkAdrParams.Datarate, &linkAdrParams.TxPower, &linkAdrParams.NbRep ); - - // Update channelsMask if everything is correct - if( status == 0x07 ) - { - // Set the channels mask to a default value - memset( ChannelsMask, 0, sizeof( ChannelsMask ) ); - // Update the channels mask - ChannelsMask[0] = chMask; - } - - // Update status variables - *drOut = linkAdrParams.Datarate; - *txPowOut = linkAdrParams.TxPower; - *nbRepOut = linkAdrParams.NbRep; - *nbBytesParsed = bytesProcessed; - - return status; -} - -uint8_t LoRaPHYEU433::setup_rx_params(RxParamSetupReqParams_t* rxParamSetupReq) -{ - uint8_t status = 0x07; - - // Verify radio frequency - if( _radio->check_rf_frequency( rxParamSetupReq->Frequency ) == false ) - { - status &= 0xFE; // Channel frequency KO - } - - // Verify datarate - if( val_in_range( rxParamSetupReq->Datarate, EU433_RX_MIN_DATARATE, EU433_RX_MAX_DATARATE ) == 0 ) - { - status &= 0xFD; // Datarate KO - } - - // Verify datarate offset - if( val_in_range( rxParamSetupReq->DrOffset, EU433_MIN_RX1_DR_OFFSET, EU433_MAX_RX1_DR_OFFSET ) == 0 ) - { - status &= 0xFB; // Rx1DrOffset range KO - } - - return status; -} - -uint8_t LoRaPHYEU433::request_new_channel(NewChannelReqParams_t* newChannelReq) -{ - uint8_t status = 0x03; - ChannelAddParams_t channelAdd; - ChannelRemoveParams_t channelRemove; - - if( newChannelReq->NewChannel->frequency == 0 ) - { - channelRemove.ChannelId = newChannelReq->ChannelId; - - // Remove - if( remove_channel( &channelRemove ) == false ) - { - status &= 0xFC; - } - } - else - { - channelAdd.NewChannel = newChannelReq->NewChannel; - channelAdd.ChannelId = newChannelReq->ChannelId; - - switch( add_channel( &channelAdd ) ) - { - case LORAWAN_STATUS_OK: - { - break; - } - case LORAWAN_STATUS_FREQUENCY_INVALID: - { - status &= 0xFE; - break; - } - case LORAWAN_STATUS_DATARATE_INVALID: - { - status &= 0xFD; - break; - } - case LORAWAN_STATUS_FREQ_AND_DR_INVALID: - { - status &= 0xFC; - break; - } - default: - { - status &= 0xFC; - break; - } - } - } - - return status; -} - -int8_t LoRaPHYEU433::setup_tx_params(TxParamSetupReqParams_t* txParamSetupReq) -{ - return -1; -} - -uint8_t LoRaPHYEU433::dl_channel_request(DlChannelReqParams_t* dlChannelReq) -{ - uint8_t status = 0x03; - - // Verify if the frequency is supported - if( VerifyTxFreq( dlChannelReq->Rx1Frequency, _radio ) == false ) - { - status &= 0xFE; - } - - // Verify if an uplink frequency exists - if( Channels[dlChannelReq->ChannelId].frequency == 0 ) - { - status &= 0xFD; - } - - // Apply Rx1 frequency, if the status is OK - if( status == 0x03 ) - { - Channels[dlChannelReq->ChannelId].rx1_frequency = dlChannelReq->Rx1Frequency; - } - - return status; -} - -int8_t LoRaPHYEU433::get_alternate_DR(AlternateDrParams_t* alternateDr) -{ - int8_t datarate = 0; - - if( ( alternateDr->NbTrials % 48 ) == 0 ) - { - datarate = DR_0; - } - else if( ( alternateDr->NbTrials % 32 ) == 0 ) - { - datarate = DR_1; - } - else if( ( alternateDr->NbTrials % 24 ) == 0 ) - { - datarate = DR_2; - } - else if( ( alternateDr->NbTrials % 16 ) == 0 ) - { - datarate = DR_3; - } - else if( ( alternateDr->NbTrials % 8 ) == 0 ) - { - datarate = DR_4; - } - else - { - datarate = DR_5; - } - return datarate; -} - -void LoRaPHYEU433::calculate_backoff(CalcBackOffParams_t* calcBackOff) -{ - RegionCommonCalcBackOffParams_t calcBackOffParams; - - calcBackOffParams.Channels = Channels; - calcBackOffParams.Bands = Bands; - calcBackOffParams.LastTxIsJoinRequest = calcBackOff->LastTxIsJoinRequest; - calcBackOffParams.Joined = calcBackOff->Joined; - calcBackOffParams.DutyCycleEnabled = calcBackOff->DutyCycleEnabled; - calcBackOffParams.Channel = calcBackOff->Channel; - calcBackOffParams.ElapsedTime = calcBackOff->ElapsedTime; - calcBackOffParams.TxTimeOnAir = calcBackOff->TxTimeOnAir; - - get_DC_backoff( &calcBackOffParams ); -} - -bool LoRaPHYEU433::set_next_channel(NextChanParams_t* nextChanParams, - uint8_t* channel, lorawan_time_t* time, - lorawan_time_t* aggregatedTimeOff) -{ - uint8_t nbEnabledChannels = 0; - uint8_t delayTx = 0; - uint8_t enabledChannels[EU433_MAX_NB_CHANNELS] = { 0 }; - lorawan_time_t nextTxDelay = 0; - - if( num_active_channels( ChannelsMask, 0, 1 ) == 0 ) - { // Reactivate default channels - ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); - } - - if( nextChanParams->AggrTimeOff <= _lora_time.TimerGetElapsedTime( nextChanParams->LastAggrTx ) ) - { - // Reset Aggregated time off - *aggregatedTimeOff = 0; - - // Update bands Time OFF - nextTxDelay = update_band_timeoff( nextChanParams->Joined, nextChanParams->DutyCycleEnabled, Bands, EU433_MAX_NB_BANDS ); - - // Search how many channels are enabled - nbEnabledChannels = CountNbOfEnabledChannels( nextChanParams->Joined, nextChanParams->Datarate, - ChannelsMask, Channels, - Bands, enabledChannels, &delayTx ); - } - else - { - delayTx++; - nextTxDelay = nextChanParams->AggrTimeOff - _lora_time.TimerGetElapsedTime( nextChanParams->LastAggrTx ); - } - - if( nbEnabledChannels > 0 ) - { - // We found a valid channel - *channel = enabledChannels[get_random( 0, nbEnabledChannels - 1 )]; - - *time = 0; - return true; - } - else - { - if( delayTx > 0 ) - { - // Delay transmission due to AggregatedTimeOff or to a band time off - *time = nextTxDelay; - return true; - } - // Datarate not supported by any channel, restore defaults - ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); - *time = 0; - return false; - } -} - -lorawan_status_t LoRaPHYEU433::add_channel(ChannelAddParams_t* channelAdd) -{ - uint8_t band = 0; - bool drInvalid = false; - bool freqInvalid = false; - uint8_t id = channelAdd->ChannelId; - - if( id >= EU433_MAX_NB_CHANNELS ) - { - return LORAWAN_STATUS_PARAMETER_INVALID; - } - - // Validate the datarate range - if( val_in_range( channelAdd->NewChannel->dr_range.fields.min, EU433_TX_MIN_DATARATE, EU433_TX_MAX_DATARATE ) == 0 ) - { - drInvalid = true; - } - if( val_in_range( channelAdd->NewChannel->dr_range.fields.max, EU433_TX_MIN_DATARATE, EU433_TX_MAX_DATARATE ) == 0 ) - { - drInvalid = true; - } - if( channelAdd->NewChannel->dr_range.fields.min > channelAdd->NewChannel->dr_range.fields.max ) - { - drInvalid = true; - } - - // Default channels don't accept all values - if( id < EU433_NUMB_DEFAULT_CHANNELS ) - { - // Validate the datarate range for min: must be DR_0 - if( channelAdd->NewChannel->dr_range.fields.min > DR_0 ) - { - drInvalid = true; - } - // Validate the datarate range for max: must be DR_5 <= Max <= TX_MAX_DATARATE - if( val_in_range( channelAdd->NewChannel->dr_range.fields.max, DR_5, EU433_TX_MAX_DATARATE ) == 0 ) - { - drInvalid = true; - } - // We are not allowed to change the frequency - if( channelAdd->NewChannel->frequency != Channels[id].frequency ) - { - freqInvalid = true; - } - } - - // Check frequency - if( freqInvalid == false ) - { - if( VerifyTxFreq( channelAdd->NewChannel->frequency, _radio ) == false ) - { - freqInvalid = true; - } - } - - // Check status - if( ( drInvalid == true ) && ( freqInvalid == true ) ) - { - return LORAWAN_STATUS_FREQ_AND_DR_INVALID; - } - if( drInvalid == true ) - { - return LORAWAN_STATUS_DATARATE_INVALID; - } - if( freqInvalid == true ) - { - return LORAWAN_STATUS_FREQUENCY_INVALID; - } - - memcpy( &(Channels[id]), channelAdd->NewChannel, sizeof( Channels[id] ) ); - Channels[id].band = band; - ChannelsMask[0] |= ( 1 << id ); - return LORAWAN_STATUS_OK; -} - -bool LoRaPHYEU433::remove_channel(ChannelRemoveParams_t* channelRemove) -{ - uint8_t id = channelRemove->ChannelId; - - if( id < EU433_NUMB_DEFAULT_CHANNELS ) - { - return false; - } - - // Remove the channel from the list of channels - const channel_params_t empty_channel = { 0, 0, { 0 }, 0 }; - Channels[id] = empty_channel; - - return disable_channel( ChannelsMask, id, EU433_MAX_NB_CHANNELS ); -} - -void LoRaPHYEU433::set_tx_cont_mode(ContinuousWaveParams_t* continuousWave) -{ - int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, Bands[Channels[continuousWave->Channel].band].max_tx_pwr, continuousWave->Datarate, ChannelsMask ); - int8_t phyTxPower = 0; - uint32_t frequency = Channels[continuousWave->Channel].frequency; - - // Calculate physical TX power - phyTxPower = compute_tx_power( txPowerLimited, continuousWave->MaxEirp, continuousWave->AntennaGain ); - - _radio->set_tx_continuous_wave( frequency, phyTxPower, continuousWave->Timeout ); -} - -uint8_t LoRaPHYEU433::apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset) -{ - int8_t datarate = dr - drOffset; - - if( datarate < 0 ) - { - datarate = DR_0; - } - return datarate; -} diff --git a/features/lorawan/lorastack/phy/LoRaPHYEU433.h b/features/lorawan/lorastack/phy/LoRaPHYEU433.h index 6b5868ee77..b230b79523 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYEU433.h +++ b/features/lorawan/lorastack/phy/LoRaPHYEU433.h @@ -33,7 +33,6 @@ #define MBED_OS_LORAPHY_EU433_H_ #include "LoRaPHY.h" -#include "netsocket/LoRaRadio.h" /*! * LoRaMac maximum number of channels @@ -55,306 +54,26 @@ public: LoRaPHYEU433(LoRaWANTimeHandler &lora_time); virtual ~LoRaPHYEU433(); - /*! - * \brief The function gets a value of a specific PHY attribute. - * - * \param [in] getPhy A pointer to the function parameters. - * - * \retval The structure containing the PHY parameter. - */ - virtual PhyParam_t get_phy_params(GetPhyParams_t* getPhy ); - - /*! - * \brief Updates the last TX done parameters of the current channel. - * - * \param [in] txDone A pointer to the function parameters. - */ - virtual void set_band_tx_done(SetBandTxDoneParams_t* txDone ); - - /*! - * \brief Initializes the channels masks and the channels. - * - * \param [in] type Sets the initialization type. - */ - virtual void load_defaults(InitType_t type ); - - /*! - * \brief Verifies a parameter. - * - * \param [in] verify A pointer to the function parameters. - * - * \param [in] phyAttribute The attribute to verify. - * - * \retval True, if the parameter is valid. - */ - virtual bool verify(VerifyParams_t* verify, PhyAttribute_t phyAttribute ); - - /*! - * \brief The function parses the input buffer and sets up the channels of the CF list. - * - * \param [in] applyCFList A pointer to the function parameters. - */ - virtual void apply_cf_list(ApplyCFListParams_t* applyCFList ); - - /*! - * \brief Sets a channels mask. - * - * \param [in] chanMaskSet A pointer to the function parameters. - * - * \retval True, if the channels mask could be set. - */ - virtual bool set_channel_mask(ChanMaskSetParams_t* chanMaskSet ); - - /*! - * \brief Calculates the next datarate to set, when ADR is on or off. - * - * \param [in] adrNext A pointer to the function parameters. - * - * \param [out] drOut The calculated datarate for the next TX. - * - * \param [out] txPowOut The TX power for the next TX. - * - * \param [out] adrAckCounter The calculated ADR acknowledgement counter. - * - * \retval True, if an ADR request should be performed. - */ - virtual bool get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut, - int8_t* txPowOut, uint32_t* adrAckCounter ); - - /*! - * \brief Configuration of the RX windows. - * - * \param [in] rxConfig A pointer to the function parameters. - * - * \param [out] datarate The datarate index set. - * - * \retval True, if the configuration was applied successfully. - */ - virtual bool rx_config(rx_config_params_t* rxConfig, int8_t* datarate ); - - /* - * RX window precise timing - * - * For more details please consult the following document, chapter 3.1.2. - * http://www.semtech.com/images/datasheet/SX1272_settings_for_LoRaWAN_v2.0.pdf - * or - * http://www.semtech.com/images/datasheet/SX1276_settings_for_LoRaWAN_v2.0.pdf - * - * Downlink start: T = Tx + 1s (+/- 20 us) - * | - * TRxEarly | TRxLate - * | | | - * | | +---+---+---+---+---+---+---+---+ - * | | | Latest Rx window | - * | | +---+---+---+---+---+---+---+---+ - * | | | - * +---+---+---+---+---+---+---+---+ - * | Earliest Rx window | - * +---+---+---+---+---+---+---+---+ - * | - * +---+---+---+---+---+---+---+---+ - *Downlink preamble 8 symbols | | | | | | | | | - * +---+---+---+---+---+---+---+---+ - * - * Worst case Rx window timings - * - * TRxLate = DEFAULT_MIN_RX_SYMBOLS * tSymbol - RADIO_WAKEUP_TIME - * TRxEarly = 8 - DEFAULT_MIN_RX_SYMBOLS * tSymbol - RxWindowTimeout - RADIO_WAKEUP_TIME - * - * TRxLate - TRxEarly = 2 * DEFAULT_SYSTEM_MAX_RX_ERROR - * - * RxOffset = ( TRxLate + TRxEarly ) / 2 - * - * RxWindowTimeout = ( 2 * DEFAULT_MIN_RX_SYMBOLS - 8 ) * tSymbol + 2 * DEFAULT_SYSTEM_MAX_RX_ERROR - * RxOffset = 4 * tSymbol - RxWindowTimeout / 2 - RADIO_WAKE_UP_TIME - * - * The minimum value of RxWindowTimeout must be 5 symbols which implies that the system always tolerates at least an error of 1.5 * tSymbol - */ - /*! - * Computes the RX window timeout and offset. - * - * \param [in] datarate The RX window datarate index to be used. - * - * \param [in] minRxSymbols The minimum number of symbols required to detect an RX frame. - * - * \param [in] rxError The system maximum timing error of the receiver in milliseconds. - * The receiver will turn on in a [-rxError : +rxError] ms - * interval around RxOffset. - * - * \param [out] rxConfigParams Returns the updated WindowTimeout and WindowOffset fields. - */ - virtual void compute_rx_win_params(int8_t datarate, - uint8_t minRxSymbols, - uint32_t rxError, - rx_config_params_t *rxConfigParams); - - /*! - * \brief TX configuration. - * - * \param [in] txConfig A pointer to the function parameters. - * - * \param [out] txPower The TX power index set. - * - * \param [out] txTimeOnAir The time-on-air of the frame. - * - * \retval True, if the configuration was applied successfully. - */ - virtual bool tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - lorawan_time_t* txTimeOnAir ); - - /*! - * \brief The function processes a Link ADR request. - * - * \param [in] linkAdrReq A pointer to the function parameters. - * - * \param [out] drOut The datarate applied. - * - * \param [out] txPowOut The TX power applied. - * - * \param [out] nbRepOut The number of repetitions to apply. - * - * \param [out] nbBytesParsed The number of bytes parsed. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t link_ADR_request(LinkAdrReqParams_t* linkAdrReq, - int8_t* drOut, int8_t* txPowOut, - uint8_t* nbRepOut, - uint8_t* nbBytesParsed ); - - /*! - * \brief The function processes a RX parameter setup request. - * - * \param [in] rxParamSetupReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t setup_rx_params(RxParamSetupReqParams_t* rxParamSetupReq ); - - /*! - * \brief The function processes a new channel request. - * - * \param [in] newChannelReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t request_new_channel(NewChannelReqParams_t* newChannelReq ); - - /*! - * \brief The function processes a TX ParamSetup request. - * - * \param [in] txParamSetupReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - * Returns -1, if the functionality is not implemented. In this case, the end node - * shall ignore the command. - */ - virtual int8_t setup_tx_params(TxParamSetupReqParams_t* txParamSetupReq ); - - /*! - * \brief The function processes a DlChannel request. - * - * \param [in] dlChannelReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t dl_channel_request(DlChannelReqParams_t* dlChannelReq ); - - /*! - * \brief Alternates the datarate of the channel for the join request. - * - * \param [in] alternateDr A pointer to the function parameters. - * - * \retval The datarate to apply. - */ - virtual int8_t get_alternate_DR(AlternateDrParams_t* alternateDr ); - - /*! - * \brief Calculates the back-off time. - * - * \param [in] calcBackOff A pointer to the function parameters. - */ - virtual void calculate_backoff(CalcBackOffParams_t* calcBackOff ); - - /*! - * \brief Searches and sets the next random available channel. - * - * \param [in] nextChanParams The parameters for the next channel - * - * \param [out] channel The next channel to use for TX. - * - * \param [out] time The time to wait for the next transmission according to the duty - * cycle. - * - * \param [out] aggregatedTimeOff Updates the aggregated time off. - * - * \retval Function status [1: OK, 0: Unable to find a channel on the current datarate]. - */ - virtual bool set_next_channel(NextChanParams_t* nextChanParams, - uint8_t* channel, lorawan_time_t* time, - lorawan_time_t* aggregatedTimeOff ); - - /*! - * \brief Adds a channel. - * - * \param [in] channelAdd A pointer to the function parameters. - * - * \retval The status of the operation. - */ - virtual lorawan_status_t add_channel(ChannelAddParams_t* channelAdd ); - - /*! - * \brief Removes a channel. - * - * \param [in] channelRemove A pointer to the function parameters. - * - * \retval True, if the channel was removed successfully. - */ - virtual bool remove_channel(ChannelRemoveParams_t* channelRemove ); - - /*! - * \brief Sets the radio into continuous wave mode. - * - * \param [in] continuousWave A pointer to the function parameters. - */ - virtual void set_tx_cont_mode(ContinuousWaveParams_t* continuousWave ); - - /*! - * \brief Computes new datarate according to the given offset. - * - * \param [in] downlinkDwellTime The downlink dwell time configuration. 0: No limit, 1: 400ms - * - * \param [in] dr The current datarate. - * - * \param [in] drOffset The offset to be applied. - * - * \retval newDr The computed datarate. - */ - virtual uint8_t apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ); - private: - uint8_t CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, channel_params_t* channels, band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ); - - // Global attributes /*! * LoRaMAC channels */ - channel_params_t Channels[EU433_MAX_NB_CHANNELS]; + channel_params_t channels[EU433_MAX_NB_CHANNELS]; /*! * LoRaMac bands */ - band_t Bands[EU433_MAX_NB_BANDS]; + band_t bands[EU433_MAX_NB_BANDS]; /*! * LoRaMac channels mask */ - uint16_t ChannelsMask[EU433_CHANNELS_MASK_SIZE]; + uint16_t channel_masks[EU433_CHANNELS_MASK_SIZE]; /*! * LoRaMac channels default mask */ - uint16_t ChannelsDefaultMask[EU433_CHANNELS_MASK_SIZE]; + uint16_t default_channel_masks[EU433_CHANNELS_MASK_SIZE]; }; diff --git a/features/lorawan/lorastack/phy/LoRaPHYEU868.cpp b/features/lorawan/lorastack/phy/LoRaPHYEU868.cpp index 5ee3585270..b9e07c48ed 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYEU868.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYEU868.cpp @@ -31,7 +31,6 @@ #include "LoRaPHYEU868.h" #include "lora_phy_ds.h" -#include "LoRaRadio.h" /*! * Number of default channels @@ -68,6 +67,8 @@ */ #define EU868_DEFAULT_DATARATE DR_0 +#define EU868_DEFAULT_MAX_DATARATE DR_5 + /*! * Minimal Rx1 receive datarate offset */ @@ -161,7 +162,7 @@ /*! * Random ack timeout limits */ -#define EU868_ACK_TIMEOUT_RND 1000 +#define EU868_ACK_TIMEOUT_RND 1000 #if ( EU868_DEFAULT_DATARATE > DR_5 ) #error "A default DR higher than DR_5 may lead to connectivity loss." @@ -170,1128 +171,180 @@ /*! * Second reception window channel frequency definition. */ -#define EU868_RX_WND_2_FREQ 869525000 +#define EU868_RX_WND_2_FREQ 869525000 /*! * Second reception window channel datarate definition. */ -#define EU868_RX_WND_2_DR DR_0 +#define EU868_RX_WND_2_DR DR_0 /*! * Band 0 definition * { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff } */ -#define EU868_BAND0 { 100 , EU868_MAX_TX_POWER, 0, 0, 0 } // 1.0 % - +static const band_t EU868_BAND0 = {100 , EU868_MAX_TX_POWER, 0, 0, 0,865000000, 868000000}; // 1.0 % /*! * Band 1 definition * { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff } */ -#define EU868_BAND1 { 100 , EU868_MAX_TX_POWER, 0, 0, 0 } // 1.0 % +static const band_t EU868_BAND1 = {100 , EU868_MAX_TX_POWER, 0, 0, 0, 868100000, 868600000}; // 1.0 % /*! * Band 2 definition * Band = { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff } */ -#define EU868_BAND2 { 1000, EU868_MAX_TX_POWER, 0, 0, 0 } // 0.1 % +static const band_t EU868_BAND2 = {1000, EU868_MAX_TX_POWER, 0, 0, 0, 868700000, 869200000}; // 0.1 % /*! * Band 3 definition * Band = { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff } */ -#define EU868_BAND3 { 10 , EU868_MAX_TX_POWER, 0, 0, 0 } // 10.0 % +static const band_t EU868_BAND3 = {10 , EU868_MAX_TX_POWER, 0, 0, 0, 869400000, 869650000}; // 10.0 % /*! * Band 4 definition * Band = { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff } */ -#define EU868_BAND4 { 100 , EU868_MAX_TX_POWER, 0, 0, 0 } // 1.0 % +static const band_t EU868_BAND4 = {100 , EU868_MAX_TX_POWER, 0, 0, 0, 869700000, 870000000}; // 1.0 % + +/*! + * Band 5 definition - It's actually a sub part of Band 2 + * Band = { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff } + */ +static const band_t EU868_BAND5 = {1000, EU868_MAX_TX_POWER, 0, 0, 0, 863000000, 865000000}; // 0.1 % /*! * LoRaMac default channel 1 * Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } */ -#define EU868_LC1 { 868100000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 1 } +static const channel_params_t EU868_LC1 = {868100000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 1}; /*! * LoRaMac default channel 2 * Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } */ -#define EU868_LC2 { 868300000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 1 } +static const channel_params_t EU868_LC2 = {868300000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 1}; /*! * LoRaMac default channel 3 * Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } */ -#define EU868_LC3 { 868500000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 1 } +static const channel_params_t EU868_LC3 = {868500000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 1}; /*! * LoRaMac channels which are allowed for the join procedure */ -#define EU868_JOIN_CHANNELS ( uint16_t )( LC( 1 ) | LC( 2 ) | LC( 3 ) ) +#define EU868_JOIN_CHANNELS (uint16_t)(LC(1) | LC(2) | LC(3)) /*! * Data rates table definition */ -static const uint8_t DataratesEU868[] = { 12, 11, 10, 9, 8, 7, 7, 50 }; +static const uint8_t datarates_EU868[] = {12, 11, 10, 9, 8, 7, 7, 50}; /*! * Bandwidths table definition in Hz */ -static const uint32_t BandwidthsEU868[] = { 125000, 125000, 125000, 125000, 125000, 125000, 250000, 0 }; +static const uint32_t bandwidths_EU868[] = {125000, 125000, 125000, 125000, 125000, 125000, 250000, 0}; /*! * Maximum payload with respect to the datarate index. Cannot operate with repeater. */ -static const uint8_t MaxPayloadOfDatarateEU868[] = { 51, 51, 51, 115, 242, 242, 242, 242 }; +static const uint8_t max_payloads_EU868[] = {51, 51, 51, 115, 242, 242, 242, 242}; /*! * Maximum payload with respect to the datarate index. Can operate with repeater. */ -static const uint8_t MaxPayloadOfDatarateRepeaterEU868[] = { 51, 51, 51, 115, 222, 222, 222, 222 }; - - -// Static functions -static int8_t GetNextLowerTxDr( int8_t dr, int8_t minDr ) -{ - uint8_t nextLowerDr = 0; - - if( dr == minDr ) - { - nextLowerDr = minDr; - } - else - { - nextLowerDr = dr - 1; - } - return nextLowerDr; -} - -static uint32_t GetBandwidth( uint32_t drIndex ) -{ - switch( BandwidthsEU868[drIndex] ) - { - default: - case 125000: - return 0; - case 250000: - return 1; - case 500000: - return 2; - } -} - -static int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower, int8_t datarate, uint16_t* channelsMask ) -{ - int8_t txPowerResult = txPower; - - // Limit tx power to the band max - txPowerResult = MAX( txPower, maxBandTxPower ); - - return txPowerResult; -} - -static bool VerifyTxFreq( uint32_t freq, uint8_t *band, LoRaRadio *radio ) -{ - // Check radio driver support - if( radio->check_rf_frequency( freq ) == false ) - { - return false; - } - - // Check frequency bands - if( ( freq >= 863000000 ) && ( freq < 865000000 ) ) - { - *band = 2; - } - else if( ( freq >= 865000000 ) && ( freq <= 868000000 ) ) - { - *band = 0; - } - else if( ( freq > 868000000 ) && ( freq <= 868600000 ) ) - { - *band = 1; - } - else if( ( freq >= 868700000 ) && ( freq <= 869200000 ) ) - { - *band = 2; - } - else if( ( freq >= 869400000 ) && ( freq <= 869650000 ) ) - { - *band = 3; - } - else if( ( freq >= 869700000 ) && ( freq <= 870000000 ) ) - { - *band = 4; - } - else - { - return false; - } - return true; -} - -uint8_t LoRaPHYEU868::CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, channel_params_t* channels, band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ) -{ - uint8_t nbEnabledChannels = 0; - uint8_t delayTransmission = 0; - - for( uint8_t i = 0, k = 0; i < EU868_MAX_NB_CHANNELS; i += 16, k++ ) - { - for( uint8_t j = 0; j < 16; j++ ) - { - if( ( channelsMask[k] & ( 1 << j ) ) != 0 ) - { - if( channels[i + j].frequency == 0 ) - { // Check if the channel is enabled - continue; - } - if( joined == false ) - { - if( ( EU868_JOIN_CHANNELS & ( 1 << j ) ) == 0 ) - { - continue; - } - } - if( val_in_range( datarate, channels[i + j].dr_range.fields.min, - channels[i + j].dr_range.fields.max ) == 0 ) - { // Check if the current channel selection supports the given datarate - continue; - } - if( bands[channels[i + j].band].off_time > 0 ) - { // Check if the band is available for transmission - delayTransmission++; - continue; - } - enabledChannels[nbEnabledChannels++] = i + j; - } - } - } - - *delayTx = delayTransmission; - return nbEnabledChannels; -} +static const uint8_t max_payloads_repeater_EU868[] = {51, 51, 51, 115, 222, 222, 222, 222}; LoRaPHYEU868::LoRaPHYEU868(LoRaWANTimeHandler &lora_time) : LoRaPHY(lora_time) { - const band_t band0 = EU868_BAND0; - const band_t band1 = EU868_BAND1; - const band_t band2 = EU868_BAND2; - const band_t band3 = EU868_BAND3; - const band_t band4 = EU868_BAND4; + bands[0] = EU868_BAND0; + bands[1] = EU868_BAND1; + bands[2] = EU868_BAND2; + bands[3] = EU868_BAND3; + bands[4] = EU868_BAND4; + bands[5] = EU868_BAND5; - Bands[0] = band0; - Bands[1] = band1; - Bands[2] = band2; - Bands[3] = band3; - Bands[4] = band4; + // Default Channels are always enabled, rest will be added later + channels[0] = EU868_LC1; + channels[1] = EU868_LC2; + channels[2] = EU868_LC3; + + // Initialize the channels default mask + default_channel_masks[0] = LC(1) + LC(2) + LC(3); + // Update the channels mask + copy_channel_mask(channel_masks, default_channel_masks, 1); + + // set default channels + phy_params.channels.channel_list = channels; + phy_params.channels.channel_list_size = EU868_MAX_NB_CHANNELS; + phy_params.channels.mask_list = channel_masks; + phy_params.channels.default_mask_list = default_channel_masks; + phy_params.channels.mask_list_size = EU868_CHANNELS_MASK_SIZE; + + // set bands for EU868 spectrum + phy_params.bands.table = (void *) bands; + phy_params.bands.size = EU868_MAX_NB_BANDS; + + // set bandwidths available in EU868 spectrum + phy_params.bandwidths.table = (void *) bandwidths_EU868; + phy_params.bandwidths.size = 8; + + // set data rates available in EU868 spectrum + phy_params.datarates.table = (void *) datarates_EU868; + phy_params.datarates.size = 8; + + // set payload sizes with respect to data rates + phy_params.payloads.table = (void *) max_payloads_EU868; + phy_params.payloads.size = 8; + phy_params.payloads_with_repeater.table = (void *) max_payloads_repeater_EU868; + phy_params.payloads.size = 8; + + // dwell time setting + phy_params.ul_dwell_time_setting = 0; + phy_params.dl_dwell_time_setting = 0; + + // set initial and default parameters + phy_params.duty_cycle_enabled = EU868_DUTY_CYCLE_ENABLED; + phy_params.accept_tx_param_setup_req = true; + phy_params.fsk_supported = true; + phy_params.cflist_supported = true; + phy_params.dl_channel_req_supported = true; + phy_params.custom_channelplans_supported = true; + phy_params.default_channel_cnt = EU868_NUMB_DEFAULT_CHANNELS; + phy_params.max_channel_cnt = EU868_MAX_NB_CHANNELS; + phy_params.cflist_channel_cnt = EU868_NUMB_CHANNELS_CF_LIST; + phy_params.min_tx_datarate = EU868_TX_MIN_DATARATE; + phy_params.max_tx_datarate = EU868_TX_MAX_DATARATE; + phy_params.min_rx_datarate = EU868_RX_MIN_DATARATE; + phy_params.max_rx_datarate = EU868_RX_MAX_DATARATE; + phy_params.default_datarate = EU868_DEFAULT_DATARATE; + phy_params.default_max_datarate = EU868_DEFAULT_MAX_DATARATE; + phy_params.min_rx1_dr_offset = EU868_MIN_RX1_DR_OFFSET; + phy_params.max_rx1_dr_offset = EU868_MAX_RX1_DR_OFFSET; + phy_params.default_rx1_dr_offset = EU868_DEFAULT_RX1_DR_OFFSET; + phy_params.min_tx_power = EU868_MIN_TX_POWER; + phy_params.max_tx_power = EU868_MAX_TX_POWER; + phy_params.default_tx_power = EU868_DEFAULT_TX_POWER; + phy_params.default_max_eirp = EU868_DEFAULT_MAX_EIRP; + phy_params.default_antenna_gain = EU868_DEFAULT_ANTENNA_GAIN; + phy_params.adr_ack_limit = EU868_ADR_ACK_LIMIT; + phy_params.adr_ack_delay = EU868_ADR_ACK_DELAY; + phy_params.max_rx_window = EU868_MAX_RX_WINDOW; + phy_params.recv_delay1 = EU868_RECEIVE_DELAY1; + phy_params.recv_delay2 = EU868_RECEIVE_DELAY2; + phy_params.join_channel_mask = EU868_JOIN_CHANNELS; + phy_params.join_accept_delay1 = EU868_JOIN_ACCEPT_DELAY1; + phy_params.join_accept_delay2 = EU868_JOIN_ACCEPT_DELAY2; + phy_params.max_fcnt_gap = EU868_MAX_FCNT_GAP; + phy_params.ack_timeout = EU868_ACKTIMEOUT; + phy_params.ack_timeout_rnd = EU868_ACK_TIMEOUT_RND; + phy_params.rx_window2_datarate = EU868_RX_WND_2_DR; + phy_params.rx_window2_frequency = EU868_RX_WND_2_FREQ; } LoRaPHYEU868::~LoRaPHYEU868() { } -PhyParam_t LoRaPHYEU868::get_phy_params(GetPhyParams_t* getPhy) -{ - PhyParam_t phyParam = { 0 }; - - switch( getPhy->Attribute ) - { - case PHY_MIN_RX_DR: - { - phyParam.Value = EU868_RX_MIN_DATARATE; - break; - } - case PHY_MIN_TX_DR: - { - phyParam.Value = EU868_TX_MIN_DATARATE; - break; - } - case PHY_DEF_TX_DR: - { - phyParam.Value = EU868_DEFAULT_DATARATE; - break; - } - case PHY_NEXT_LOWER_TX_DR: - { - phyParam.Value = GetNextLowerTxDr( getPhy->Datarate, EU868_TX_MIN_DATARATE ); - break; - } - case PHY_DEF_TX_POWER: - { - phyParam.Value = EU868_DEFAULT_TX_POWER; - break; - } - case PHY_MAX_PAYLOAD: - { - phyParam.Value = MaxPayloadOfDatarateEU868[getPhy->Datarate]; - break; - } - case PHY_MAX_PAYLOAD_REPEATER: - { - phyParam.Value = MaxPayloadOfDatarateRepeaterEU868[getPhy->Datarate]; - break; - } - case PHY_DUTY_CYCLE: - { - phyParam.Value = EU868_DUTY_CYCLE_ENABLED; - break; - } - case PHY_MAX_RX_WINDOW: - { - phyParam.Value = EU868_MAX_RX_WINDOW; - break; - } - case PHY_RECEIVE_DELAY1: - { - phyParam.Value = EU868_RECEIVE_DELAY1; - break; - } - case PHY_RECEIVE_DELAY2: - { - phyParam.Value = EU868_RECEIVE_DELAY2; - break; - } - case PHY_JOIN_ACCEPT_DELAY1: - { - phyParam.Value = EU868_JOIN_ACCEPT_DELAY1; - break; - } - case PHY_JOIN_ACCEPT_DELAY2: - { - phyParam.Value = EU868_JOIN_ACCEPT_DELAY2; - break; - } - case PHY_MAX_FCNT_GAP: - { - phyParam.Value = EU868_MAX_FCNT_GAP; - break; - } - case PHY_ACK_TIMEOUT: - { - phyParam.Value = ( EU868_ACKTIMEOUT + get_random( -EU868_ACK_TIMEOUT_RND, EU868_ACK_TIMEOUT_RND ) ); - break; - } - case PHY_DEF_DR1_OFFSET: - { - phyParam.Value = EU868_DEFAULT_RX1_DR_OFFSET; - break; - } - case PHY_DEF_RX2_FREQUENCY: - { - phyParam.Value = EU868_RX_WND_2_FREQ; - break; - } - case PHY_DEF_RX2_DR: - { - phyParam.Value = EU868_RX_WND_2_DR; - break; - } - case PHY_CHANNELS_MASK: - { - phyParam.ChannelsMask = ChannelsMask; - break; - } - case PHY_CHANNELS_DEFAULT_MASK: - { - phyParam.ChannelsMask = ChannelsDefaultMask; - break; - } - case PHY_MAX_NB_CHANNELS: - { - phyParam.Value = EU868_MAX_NB_CHANNELS; - break; - } - case PHY_CHANNELS: - { - phyParam.Channels = Channels; - break; - } - case PHY_DEF_UPLINK_DWELL_TIME: - case PHY_DEF_DOWNLINK_DWELL_TIME: - { - phyParam.Value = 0; - break; - } - case PHY_DEF_MAX_EIRP: - { - phyParam.fValue = EU868_DEFAULT_MAX_EIRP; - break; - } - case PHY_DEF_ANTENNA_GAIN: - { - phyParam.fValue = EU868_DEFAULT_ANTENNA_GAIN; - break; - } - case PHY_NB_JOIN_TRIALS: - case PHY_DEF_NB_JOIN_TRIALS: - { - phyParam.Value = 48; - break; - } - default: - { - break; - } - } - - return phyParam; -} - -void LoRaPHYEU868::set_band_tx_done(SetBandTxDoneParams_t* txDone) -{ - set_last_tx_done( txDone->Joined, &Bands[Channels[txDone->Channel].band], txDone->LastTxDoneTime ); -} - -void LoRaPHYEU868::load_defaults(InitType_t type) -{ - switch( type ) - { - case INIT_TYPE_INIT: - { - // Channels - const channel_params_t channel1 = EU868_LC1; - const channel_params_t channel2 = EU868_LC2; - const channel_params_t channel3 = EU868_LC3; - Channels[0] = channel1; - Channels[1] = channel2; - Channels[2] = channel3; - - // Initialize the channels default mask - ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 ); - // Update the channels mask - copy_channel_mask( ChannelsMask, ChannelsDefaultMask, 1 ); - break; - } - case INIT_TYPE_RESTORE: - { - // Restore channels default mask - ChannelsMask[0] |= ChannelsDefaultMask[0]; - break; - } - default: - { - break; - } - } -} - -bool LoRaPHYEU868::verify(VerifyParams_t* verify, PhyAttribute_t phyAttribute) -{ - switch( phyAttribute ) - { - case PHY_TX_DR: - { - return val_in_range( verify->DatarateParams.Datarate, EU868_TX_MIN_DATARATE, EU868_TX_MAX_DATARATE ); - } - case PHY_DEF_TX_DR: - { - return val_in_range( verify->DatarateParams.Datarate, DR_0, DR_5 ); - } - case PHY_RX_DR: - { - return val_in_range( verify->DatarateParams.Datarate, EU868_RX_MIN_DATARATE, EU868_RX_MAX_DATARATE ); - } - case PHY_DEF_TX_POWER: - case PHY_TX_POWER: - { - // Remark: switched min and max! - return val_in_range( verify->TxPower, EU868_MAX_TX_POWER, EU868_MIN_TX_POWER ); - } - case PHY_DUTY_CYCLE: - { - return EU868_DUTY_CYCLE_ENABLED; - } - case PHY_NB_JOIN_TRIALS: - { - if( verify->NbJoinTrials < 48 ) - { - return false; - } - break; - } - default: - return false; - } - return true; -} - -void LoRaPHYEU868::apply_cf_list(ApplyCFListParams_t* applyCFList) -{ - channel_params_t newChannel; - ChannelAddParams_t channelAdd; - ChannelRemoveParams_t channelRemove; - - // Setup default datarate range - newChannel.dr_range.value = ( DR_5 << 4 ) | DR_0; - - // Size of the optional CF list - if( applyCFList->Size != 16 ) - { - return; - } - - // Last byte is RFU, don't take it into account - for( uint8_t i = 0, chanIdx = EU868_NUMB_DEFAULT_CHANNELS; chanIdx < EU868_MAX_NB_CHANNELS; i+=3, chanIdx++ ) - { - if( chanIdx < ( EU868_NUMB_CHANNELS_CF_LIST + EU868_NUMB_DEFAULT_CHANNELS ) ) - { - // Channel frequency - newChannel.frequency = (uint32_t) applyCFList->Payload[i]; - newChannel.frequency |= ( (uint32_t) applyCFList->Payload[i + 1] << 8 ); - newChannel.frequency |= ( (uint32_t) applyCFList->Payload[i + 2] << 16 ); - newChannel.frequency *= 100; - - // Initialize alternative frequency to 0 - newChannel.rx1_frequency = 0; - } - else - { - newChannel.frequency = 0; - newChannel.dr_range.value = 0; - newChannel.rx1_frequency = 0; - } - - if( newChannel.frequency != 0 ) - { - channelAdd.NewChannel = &newChannel; - channelAdd.ChannelId = chanIdx; - - // Try to add all channels - add_channel( &channelAdd ); - } - else - { - channelRemove.ChannelId = chanIdx; - - remove_channel( &channelRemove ); - } - } -} - -bool LoRaPHYEU868::set_channel_mask(ChanMaskSetParams_t* chanMaskSet) -{ - switch( chanMaskSet->ChannelsMaskType ) - { - case CHANNELS_MASK: - { - copy_channel_mask( ChannelsMask, chanMaskSet->ChannelsMaskIn, 1 ); - break; - } - case CHANNELS_DEFAULT_MASK: - { - copy_channel_mask( ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 1 ); - break; - } - default: - return false; - } - return true; -} - -bool LoRaPHYEU868::get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut, - int8_t* txPowOut, uint32_t* adrAckCounter) -{ - bool adrAckReq = false; - int8_t datarate = adrNext->Datarate; - int8_t txPower = adrNext->TxPower; - GetPhyParams_t getPhy; - PhyParam_t phyParam; - - // Report back the adr ack counter - *adrAckCounter = adrNext->AdrAckCounter; - - if( adrNext->AdrEnabled == true ) - { - if( datarate == EU868_TX_MIN_DATARATE ) - { - *adrAckCounter = 0; - adrAckReq = false; - } - else - { - if( adrNext->AdrAckCounter >= EU868_ADR_ACK_LIMIT ) - { - adrAckReq = true; - txPower = EU868_MAX_TX_POWER; - } - else - { - adrAckReq = false; - } - if( adrNext->AdrAckCounter >= ( EU868_ADR_ACK_LIMIT + EU868_ADR_ACK_DELAY ) ) - { - if( ( adrNext->AdrAckCounter % EU868_ADR_ACK_DELAY ) == 1 ) - { - // Decrease the datarate - getPhy.Attribute = PHY_NEXT_LOWER_TX_DR; - getPhy.Datarate = datarate; - getPhy.UplinkDwellTime = adrNext->UplinkDwellTime; - phyParam = get_phy_params( &getPhy ); - datarate = phyParam.Value; - - if( datarate == EU868_TX_MIN_DATARATE ) - { - // We must set adrAckReq to false as soon as we reach the lowest datarate - adrAckReq = false; - if( adrNext->UpdateChanMask == true ) - { - // Re-enable default channels - ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); - } - } - } - } - } - } - - *drOut = datarate; - *txPowOut = txPower; - return adrAckReq; -} - -void LoRaPHYEU868::compute_rx_win_params(int8_t datarate, uint8_t minRxSymbols, - uint32_t rxError, - rx_config_params_t *rxConfigParams) -{ - double tSymbol = 0.0; - - // Get the datarate, perform a boundary check - rxConfigParams->datarate = MIN( datarate, EU868_RX_MAX_DATARATE ); - rxConfigParams->bandwidth = GetBandwidth( rxConfigParams->datarate ); - - if( rxConfigParams->datarate == DR_7 ) - { // FSK - tSymbol = compute_symb_timeout_fsk( DataratesEU868[rxConfigParams->datarate] ); - } - else - { // LoRa - tSymbol = compute_symb_timeout_lora( DataratesEU868[rxConfigParams->datarate], BandwidthsEU868[rxConfigParams->datarate] ); - } - - get_rx_window_params( tSymbol, minRxSymbols, rxError, RADIO_WAKEUP_TIME, &rxConfigParams->window_timeout, &rxConfigParams->window_offset ); -} - -bool LoRaPHYEU868::rx_config(rx_config_params_t* rxConfig, int8_t* datarate) -{ - radio_modems_t modem; - int8_t dr = rxConfig->datarate; - uint8_t maxPayload = 0; - int8_t phyDr = 0; - uint32_t frequency = rxConfig->frequency; - - if( _radio->get_status() != RF_IDLE ) - { - return false; - } - - if( rxConfig->rx_slot == RX_SLOT_WIN_1 ) - { - // Apply window 1 frequency - frequency = Channels[rxConfig->channel].frequency; - // Apply the alternative RX 1 window frequency, if it is available - if( Channels[rxConfig->channel].rx1_frequency != 0 ) - { - frequency = Channels[rxConfig->channel].rx1_frequency; - } - } - - // Read the physical datarate from the datarates table - phyDr = DataratesEU868[dr]; - - _radio->set_channel( frequency ); - - // Radio configuration - if( dr == DR_7 ) - { - modem = MODEM_FSK; - _radio->set_rx_config( modem, 50000, phyDr * 1000, 0, 83333, 5, rxConfig->window_timeout, false, 0, true, 0, 0, false, rxConfig->is_rx_continuous ); - } - else - { - modem = MODEM_LORA; - _radio->set_rx_config( modem, rxConfig->bandwidth, phyDr, 1, 0, 8, rxConfig->window_timeout, false, 0, false, 0, 0, true, rxConfig->is_rx_continuous ); - } - - if( rxConfig->is_repeater_supported == true ) - { - maxPayload = MaxPayloadOfDatarateRepeaterEU868[dr]; - } - else - { - maxPayload = MaxPayloadOfDatarateEU868[dr]; - } - - _radio->set_max_payload_length( modem, maxPayload + LORA_MAC_FRMPAYLOAD_OVERHEAD ); - - *datarate = (uint8_t) dr; - return true; -} - -bool LoRaPHYEU868::tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - lorawan_time_t* txTimeOnAir) -{ - radio_modems_t modem; - int8_t phyDr = DataratesEU868[txConfig->Datarate]; - int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, Bands[Channels[txConfig->Channel].band].max_tx_pwr, txConfig->Datarate, ChannelsMask ); - uint32_t bandwidth = GetBandwidth( txConfig->Datarate ); - int8_t phyTxPower = 0; - - // Calculate physical TX power - phyTxPower = compute_tx_power( txPowerLimited, txConfig->MaxEirp, txConfig->AntennaGain ); - - // Setup the radio frequency - _radio->set_channel( Channels[txConfig->Channel].frequency ); - - if( txConfig->Datarate == DR_7 ) - { // High Speed FSK channel - modem = MODEM_FSK; - _radio->set_tx_config( modem, phyTxPower, 25000, bandwidth, phyDr * 1000, 0, 5, false, true, 0, 0, false, 3000 ); - } - else - { - modem = MODEM_LORA; - _radio->set_tx_config( modem, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 3000 ); - } - - // Setup maximum payload lenght of the radio driver - _radio->set_max_payload_length( modem, txConfig->PktLen ); - // Get the time-on-air of the next tx frame - *txTimeOnAir = _radio->time_on_air( modem, txConfig->PktLen ); - - *txPower = txPowerLimited; - return true; -} - -uint8_t LoRaPHYEU868::link_ADR_request(LinkAdrReqParams_t* linkAdrReq, - int8_t* drOut, int8_t* txPowOut, - uint8_t* nbRepOut, uint8_t* nbBytesParsed) -{ - uint8_t status = 0x07; - RegionCommonLinkAdrParams_t linkAdrParams; - uint8_t nextIndex = 0; - uint8_t bytesProcessed = 0; - uint16_t chMask = 0; - GetPhyParams_t getPhy; - PhyParam_t phyParam; - RegionCommonLinkAdrReqVerifyParams_t linkAdrVerifyParams; - - while( bytesProcessed < linkAdrReq->PayloadSize ) - { - // Get ADR request parameters - nextIndex = parse_link_ADR_req( &( linkAdrReq->Payload[bytesProcessed] ), &linkAdrParams ); - - if( nextIndex == 0 ) - break; // break loop, since no more request has been found - - // Update bytes processed - bytesProcessed += nextIndex; - - // Revert status, as we only check the last ADR request for the channel mask KO - status = 0x07; - - // Setup temporary channels mask - chMask = linkAdrParams.ChMask; - - // Verify channels mask - if( ( linkAdrParams.ChMaskCtrl == 0 ) && ( chMask == 0 ) ) - { - status &= 0xFE; // Channel mask KO - } - else if( ( ( linkAdrParams.ChMaskCtrl >= 1 ) && ( linkAdrParams.ChMaskCtrl <= 5 )) || - ( linkAdrParams.ChMaskCtrl >= 7 ) ) - { - // RFU - status &= 0xFE; // Channel mask KO - } - else - { - for( uint8_t i = 0; i < EU868_MAX_NB_CHANNELS; i++ ) - { - if( linkAdrParams.ChMaskCtrl == 6 ) - { - if( Channels[i].frequency != 0 ) - { - chMask |= 1 << i; - } - } - else - { - if( ( ( chMask & ( 1 << i ) ) != 0 ) && - ( Channels[i].frequency == 0 ) ) - {// Trying to enable an undefined channel - status &= 0xFE; // Channel mask KO - } - } - } - } - } - - // Get the minimum possible datarate - getPhy.Attribute = PHY_MIN_TX_DR; - getPhy.UplinkDwellTime = linkAdrReq->UplinkDwellTime; - phyParam = get_phy_params( &getPhy ); - - linkAdrVerifyParams.Status = status; - linkAdrVerifyParams.AdrEnabled = linkAdrReq->AdrEnabled; - linkAdrVerifyParams.Datarate = linkAdrParams.Datarate; - linkAdrVerifyParams.TxPower = linkAdrParams.TxPower; - linkAdrVerifyParams.NbRep = linkAdrParams.NbRep; - linkAdrVerifyParams.CurrentDatarate = linkAdrReq->CurrentDatarate; - linkAdrVerifyParams.CurrentTxPower = linkAdrReq->CurrentTxPower; - linkAdrVerifyParams.CurrentNbRep = linkAdrReq->CurrentNbRep; - linkAdrVerifyParams.NbChannels = EU868_MAX_NB_CHANNELS; - linkAdrVerifyParams.ChannelsMask = &chMask; - linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value; - linkAdrVerifyParams.MaxDatarate = EU868_TX_MAX_DATARATE; - linkAdrVerifyParams.Channels = Channels; - linkAdrVerifyParams.MinTxPower = EU868_MIN_TX_POWER; - linkAdrVerifyParams.MaxTxPower = EU868_MAX_TX_POWER; - - // Verify the parameters and update, if necessary - status = verify_link_ADR_req( &linkAdrVerifyParams, &linkAdrParams.Datarate, &linkAdrParams.TxPower, &linkAdrParams.NbRep ); - - // Update channelsMask if everything is correct - if( status == 0x07 ) - { - // Set the channels mask to a default value - memset( ChannelsMask, 0, sizeof( ChannelsMask ) ); - // Update the channels mask - ChannelsMask[0] = chMask; - } - - // Update status variables - *drOut = linkAdrParams.Datarate; - *txPowOut = linkAdrParams.TxPower; - *nbRepOut = linkAdrParams.NbRep; - *nbBytesParsed = bytesProcessed; - - return status; -} - -uint8_t LoRaPHYEU868::setup_rx_params(RxParamSetupReqParams_t* rxParamSetupReq) -{ - uint8_t status = 0x07; - - // Verify radio frequency - if( _radio->check_rf_frequency( rxParamSetupReq->Frequency ) == false ) - { - status &= 0xFE; // Channel frequency KO - } - - // Verify datarate - if( val_in_range( rxParamSetupReq->Datarate, EU868_RX_MIN_DATARATE, EU868_RX_MAX_DATARATE ) == 0 ) - { - status &= 0xFD; // Datarate KO - } - - // Verify datarate offset - if( val_in_range( rxParamSetupReq->DrOffset, EU868_MIN_RX1_DR_OFFSET, EU868_MAX_RX1_DR_OFFSET ) == 0 ) - { - status &= 0xFB; // Rx1DrOffset range KO - } - - return status; -} - -uint8_t LoRaPHYEU868::request_new_channel(NewChannelReqParams_t* newChannelReq) -{ - uint8_t status = 0x03; - ChannelAddParams_t channelAdd; - ChannelRemoveParams_t channelRemove; - - if( newChannelReq->NewChannel->frequency == 0 ) - { - channelRemove.ChannelId = newChannelReq->ChannelId; - - // Remove - if( remove_channel( &channelRemove ) == false ) - { - status &= 0xFC; - } - } - else - { - channelAdd.NewChannel = newChannelReq->NewChannel; - channelAdd.ChannelId = newChannelReq->ChannelId; - - switch( add_channel( &channelAdd ) ) - { - case LORAWAN_STATUS_OK: - { - break; - } - case LORAWAN_STATUS_FREQUENCY_INVALID: - { - status &= 0xFE; - break; - } - case LORAWAN_STATUS_DATARATE_INVALID: - { - status &= 0xFD; - break; - } - case LORAWAN_STATUS_FREQ_AND_DR_INVALID: - { - status &= 0xFC; - break; - } - default: - { - status &= 0xFC; - break; - } - } - } - - return status; -} - -int8_t LoRaPHYEU868::setup_tx_params(TxParamSetupReqParams_t* txParamSetupReq) -{ - return -1; -} - -uint8_t LoRaPHYEU868::dl_channel_request(DlChannelReqParams_t* dlChannelReq) -{ - uint8_t status = 0x03; - uint8_t band = 0; - - // Verify if the frequency is supported - if( VerifyTxFreq( dlChannelReq->Rx1Frequency, &band, _radio ) == false ) - { - status &= 0xFE; - } - - // Verify if an uplink frequency exists - if( Channels[dlChannelReq->ChannelId].frequency == 0 ) - { - status &= 0xFD; - } - - // Apply Rx1 frequency, if the status is OK - if( status == 0x03 ) - { - Channels[dlChannelReq->ChannelId].rx1_frequency = dlChannelReq->Rx1Frequency; - } - - return status; -} - -int8_t LoRaPHYEU868::get_alternate_DR(AlternateDrParams_t* alternateDr) -{ - int8_t datarate = 0; - - if( ( alternateDr->NbTrials % 48 ) == 0 ) - { - datarate = DR_0; - } - else if( ( alternateDr->NbTrials % 32 ) == 0 ) - { - datarate = DR_1; - } - else if( ( alternateDr->NbTrials % 24 ) == 0 ) - { - datarate = DR_2; - } - else if( ( alternateDr->NbTrials % 16 ) == 0 ) - { - datarate = DR_3; - } - else if( ( alternateDr->NbTrials % 8 ) == 0 ) - { - datarate = DR_4; - } - else - { - datarate = DR_5; - } - return datarate; -} - -void LoRaPHYEU868::calculate_backoff(CalcBackOffParams_t* calcBackOff) -{ - RegionCommonCalcBackOffParams_t calcBackOffParams; - - calcBackOffParams.Channels = Channels; - calcBackOffParams.Bands = Bands; - calcBackOffParams.LastTxIsJoinRequest = calcBackOff->LastTxIsJoinRequest; - calcBackOffParams.Joined = calcBackOff->Joined; - calcBackOffParams.DutyCycleEnabled = calcBackOff->DutyCycleEnabled; - calcBackOffParams.Channel = calcBackOff->Channel; - calcBackOffParams.ElapsedTime = calcBackOff->ElapsedTime; - calcBackOffParams.TxTimeOnAir = calcBackOff->TxTimeOnAir; - - get_DC_backoff( &calcBackOffParams ); -} - -bool LoRaPHYEU868::set_next_channel(NextChanParams_t* nextChanParams, - uint8_t* channel, lorawan_time_t* time, - lorawan_time_t* aggregatedTimeOff) -{ - uint8_t nbEnabledChannels = 0; - uint8_t delayTx = 0; - uint8_t enabledChannels[EU868_MAX_NB_CHANNELS] = { 0 }; - lorawan_time_t nextTxDelay = 0; - - if( num_active_channels( ChannelsMask, 0, 1 ) == 0 ) - { // Reactivate default channels - ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); - } - - if( nextChanParams->AggrTimeOff <= _lora_time.TimerGetElapsedTime( nextChanParams->LastAggrTx ) ) - { - // Reset Aggregated time off - *aggregatedTimeOff = 0; - - // Update bands Time OFF - nextTxDelay = update_band_timeoff( nextChanParams->Joined, nextChanParams->DutyCycleEnabled, Bands, EU868_MAX_NB_BANDS ); - - // Search how many channels are enabled - nbEnabledChannels = CountNbOfEnabledChannels( nextChanParams->Joined, nextChanParams->Datarate, - ChannelsMask, Channels, - Bands, enabledChannels, &delayTx ); - } - else - { - delayTx++; - nextTxDelay = nextChanParams->AggrTimeOff - _lora_time.TimerGetElapsedTime( nextChanParams->LastAggrTx ); - } - - if( nbEnabledChannels > 0 ) - { - // We found a valid channel - *channel = enabledChannels[get_random( 0, nbEnabledChannels - 1 )]; - - *time = 0; - return true; - } - else - { - if( delayTx > 0 ) - { - // Delay transmission due to AggregatedTimeOff or to a band time off - *time = nextTxDelay; - return true; - } - // Datarate not supported by any channel, restore defaults - ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); - *time = 0; - return false; - } -} - -lorawan_status_t LoRaPHYEU868::add_channel(ChannelAddParams_t* channelAdd) -{ - uint8_t band = 0; - bool drInvalid = false; - bool freqInvalid = false; - uint8_t id = channelAdd->ChannelId; - - if( id >= EU868_MAX_NB_CHANNELS ) - { - return LORAWAN_STATUS_PARAMETER_INVALID; - } - - // Validate the datarate range - if( val_in_range( channelAdd->NewChannel->dr_range.fields.min, EU868_TX_MIN_DATARATE, EU868_TX_MAX_DATARATE ) == 0 ) - { - drInvalid = true; - } - if( val_in_range( channelAdd->NewChannel->dr_range.fields.max, EU868_TX_MIN_DATARATE, EU868_TX_MAX_DATARATE ) == 0 ) - { - drInvalid = true; - } - if( channelAdd->NewChannel->dr_range.fields.min > channelAdd->NewChannel->dr_range.fields.max ) - { - drInvalid = true; - } - - // Default channels don't accept all values - if( id < EU868_NUMB_DEFAULT_CHANNELS ) - { - // Validate the datarate range for min: must be DR_0 - if( channelAdd->NewChannel->dr_range.fields.min > DR_0 ) - { - drInvalid = true; - } - // Validate the datarate range for max: must be DR_5 <= Max <= TX_MAX_DATARATE - if( val_in_range( channelAdd->NewChannel->dr_range.fields.max, DR_5, EU868_TX_MAX_DATARATE ) == 0 ) - { - drInvalid = true; - } - // We are not allowed to change the frequency - if( channelAdd->NewChannel->frequency != Channels[id].frequency ) - { - freqInvalid = true; - } - } - - // Check frequency - if( freqInvalid == false ) - { - if( VerifyTxFreq( channelAdd->NewChannel->frequency, &band, _radio ) == false ) - { - freqInvalid = true; - } - } - - // Check status - if( ( drInvalid == true ) && ( freqInvalid == true ) ) - { - return LORAWAN_STATUS_FREQ_AND_DR_INVALID; - } - if( drInvalid == true ) - { - return LORAWAN_STATUS_DATARATE_INVALID; - } - if( freqInvalid == true ) - { - return LORAWAN_STATUS_FREQUENCY_INVALID; - } - - memcpy( &(Channels[id]), channelAdd->NewChannel, sizeof( Channels[id] ) ); - Channels[id].band = band; - ChannelsMask[0] |= ( 1 << id ); - return LORAWAN_STATUS_OK; -} - -bool LoRaPHYEU868::remove_channel(ChannelRemoveParams_t* channelRemove) -{ - uint8_t id = channelRemove->ChannelId; - - if( id < EU868_NUMB_DEFAULT_CHANNELS ) - { - return false; - } - - // Remove the channel from the list of channels - const channel_params_t empty_channel = { 0, 0, { 0 }, 0 }; - Channels[id] = empty_channel; - - return disable_channel( ChannelsMask, id, EU868_MAX_NB_CHANNELS ); -} - -void LoRaPHYEU868::set_tx_cont_mode(ContinuousWaveParams_t* continuousWave) -{ - int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, Bands[Channels[continuousWave->Channel].band].max_tx_pwr, continuousWave->Datarate, ChannelsMask ); - int8_t phyTxPower = 0; - uint32_t frequency = Channels[continuousWave->Channel].frequency; - - // Calculate physical TX power - phyTxPower = compute_tx_power( txPowerLimited, continuousWave->MaxEirp, continuousWave->AntennaGain ); - - _radio->set_tx_continuous_wave( frequency, phyTxPower, continuousWave->Timeout ); -} - -uint8_t LoRaPHYEU868::apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset) -{ - int8_t datarate = dr - drOffset; - - if( datarate < 0 ) - { - datarate = DR_0; - } - return datarate; -} diff --git a/features/lorawan/lorastack/phy/LoRaPHYEU868.h b/features/lorawan/lorastack/phy/LoRaPHYEU868.h index beaffb777e..3131321b1c 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYEU868.h +++ b/features/lorawan/lorastack/phy/LoRaPHYEU868.h @@ -33,7 +33,6 @@ #define MBED_OS_LORAPHY_EU868_H_ #include "LoRaPHY.h" -#include "netsocket/LoRaRadio.h" /*! * LoRaMac maximum number of channels @@ -42,317 +41,42 @@ /*! * Maximum number of bands + * + * We have broken down EU-868 MHz BAND 2 into two parts. That's why + * total number of sub-bands is 6. + * from 863 MHz to 865 MHz region is part of BAND 2, however + * we call it Band-5 here. Duty cycle limit is 0.1 % in this sub band. */ -#define EU868_MAX_NB_BANDS 5 +#define EU868_MAX_NB_BANDS 6 #define EU868_CHANNELS_MASK_SIZE 1 - class LoRaPHYEU868 : public LoRaPHY { public: LoRaPHYEU868(LoRaWANTimeHandler &lora_time); virtual ~LoRaPHYEU868(); - /*! - * \brief The function gets a value of a specific PHY attribute. - * - * \param [in] getPhy A pointer to the function parameters. - * - * \retval The structure containing the PHY parameter. - */ - virtual PhyParam_t get_phy_params(GetPhyParams_t* getPhy ); - - /*! - * \brief Updates the last TX done parameters of the current channel. - * - * \param [in] txDone A pointer to the function parameters. - */ - virtual void set_band_tx_done(SetBandTxDoneParams_t* txDone ); - - /*! - * \brief Initializes the channels masks and the channels. - * - * \param [in] type Sets the initialization type. - */ - virtual void load_defaults(InitType_t type ); - - /*! - * \brief Verifies a parameter. - * - * \param [in] verify A pointer to the function parameters. - * - * \param [in] phyAttribute The attribute to verify. - * - * \retval True, if the parameter is valid. - */ - virtual bool verify(VerifyParams_t* verify, PhyAttribute_t phyAttribute ); - - /*! - * \brief The function parses the input buffer and sets up the channels of the CF list. - * - * \param [in] applyCFList A pointer to the function parameters. - */ - virtual void apply_cf_list(ApplyCFListParams_t* applyCFList ); - - /*! - * \brief Sets a channels mask. - * - * \param [in] chanMaskSet A pointer to the function parameters. - * - * \retval True, if the channels mask could be set. - */ - virtual bool set_channel_mask(ChanMaskSetParams_t* chanMaskSet ); - - /*! - * \brief Calculates the next datarate to set, when ADR is on or off. - * - * \param [in] adrNext A pointer to the function parameters. - * - * \param [out] drOut The calculated datarate for the next TX. - * - * \param [out] txPowOut The TX power for the next TX. - * - * \param [out] adrAckCounter The calculated ADR acknowledgement counter. - * - * \retval True, if an ADR request should be performed. - */ - virtual bool get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut, - int8_t* txPowOut, uint32_t* adrAckCounter ); - - /*! - * \brief Configuration of the RX windows. - * - * \param [in] rxConfig A pointer to the function parameters. - * - * \param [out] datarate The datarate index set. - * - * \retval True, if the configuration was applied successfully. - */ - virtual bool rx_config(rx_config_params_t* rxConfig, int8_t* datarate ); - - /* - * RX window precise timing - * - * For more details please consult the following document, chapter 3.1.2. - * http://www.semtech.com/images/datasheet/SX1272_settings_for_LoRaWAN_v2.0.pdf - * or - * http://www.semtech.com/images/datasheet/SX1276_settings_for_LoRaWAN_v2.0.pdf - * - * Downlink start: T = Tx + 1s (+/- 20 us) - * | - * TRxEarly | TRxLate - * | | | - * | | +---+---+---+---+---+---+---+---+ - * | | | Latest Rx window | - * | | +---+---+---+---+---+---+---+---+ - * | | | - * +---+---+---+---+---+---+---+---+ - * | Earliest Rx window | - * +---+---+---+---+---+---+---+---+ - * | - * +---+---+---+---+---+---+---+---+ - *Downlink preamble 8 symbols | | | | | | | | | - * +---+---+---+---+---+---+---+---+ - * - * Worst case Rx window timings - * - * TRxLate = DEFAULT_MIN_RX_SYMBOLS * tSymbol - RADIO_WAKEUP_TIME - * TRxEarly = 8 - DEFAULT_MIN_RX_SYMBOLS * tSymbol - RxWindowTimeout - RADIO_WAKEUP_TIME - * - * TRxLate - TRxEarly = 2 * DEFAULT_SYSTEM_MAX_RX_ERROR - * - * RxOffset = ( TRxLate + TRxEarly ) / 2 - * - * RxWindowTimeout = ( 2 * DEFAULT_MIN_RX_SYMBOLS - 8 ) * tSymbol + 2 * DEFAULT_SYSTEM_MAX_RX_ERROR - * RxOffset = 4 * tSymbol - RxWindowTimeout / 2 - RADIO_WAKE_UP_TIME - * - * The minimum value of RxWindowTimeout must be 5 symbols which implies that the system always tolerates at least an error of 1.5 * tSymbol - */ - /*! - * Computes the RX window timeout and offset. - * - * \param [in] datarate The RX window datarate index to be used. - * - * \param [in] minRxSymbols The minimum number of symbols required to detect an RX frame. - * - * \param [in] rxError The system maximum timing error of the receiver in milliseconds. - * The receiver will turn on in a [-rxError : +rxError] ms - * interval around RxOffset. - * - * \param [out] rxConfigParams Returns the updated WindowTimeout and WindowOffset fields. - */ - virtual void compute_rx_win_params(int8_t datarate, - uint8_t minRxSymbols, - uint32_t rxError, - rx_config_params_t *rxConfigParams); - - /*! - * \brief TX configuration. - * - * \param [in] txConfig A pointer to the function parameters. - * - * \param [out] txPower The TX power index set. - * - * \param [out] txTimeOnAir The time-on-air of the frame. - * - * \retval True, if the configuration was applied successfully. - */ - virtual bool tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - lorawan_time_t* txTimeOnAir ); - - /*! - * \brief The function processes a Link ADR request. - * - * \param [in] linkAdrReq A pointer to the function parameters. - * - * \param [out] drOut The datarate applied. - * - * \param [out] txPowOut The TX power applied. - * - * \param [out] nbRepOut The number of repetitions to apply. - * - * \param [out] nbBytesParsed The number of bytes parsed. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t link_ADR_request(LinkAdrReqParams_t* linkAdrReq, - int8_t* drOut, int8_t* txPowOut, - uint8_t* nbRepOut, - uint8_t* nbBytesParsed ); - - /*! - * \brief The function processes a RX parameter setup request. - * - * \param [in] rxParamSetupReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t setup_rx_params(RxParamSetupReqParams_t* rxParamSetupReq ); - - /*! - * \brief The function processes a new channel request. - * - * \param [in] newChannelReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t request_new_channel(NewChannelReqParams_t* newChannelReq ); - - /*! - * \brief The function processes a TX ParamSetup request. - * - * \param [in] txParamSetupReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - * Returns -1, if the functionality is not implemented. In this case, the end node - * shall ignore the command. - */ - virtual int8_t setup_tx_params(TxParamSetupReqParams_t* txParamSetupReq ); - - /*! - * \brief The function processes a DlChannel request. - * - * \param [in] dlChannelReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t dl_channel_request(DlChannelReqParams_t* dlChannelReq ); - - /*! - * \brief Alternates the datarate of the channel for the join request. - * - * \param [in] alternateDr A pointer to the function parameters. - * - * \retval The datarate to apply. - */ - virtual int8_t get_alternate_DR(AlternateDrParams_t* alternateDr ); - - /*! - * \brief Calculates the back-off time. - * - * \param [in] calcBackOff A pointer to the function parameters. - */ - virtual void calculate_backoff(CalcBackOffParams_t* calcBackOff ); - - /*! - * \brief Searches and sets the next random available channel. - * - * \param [in] nextChanParams The parameters for the next channel. - * - * \param [out] channel The next channel to use for TX. - * - * \param [out] time The time to wait for the next transmission according to the duty cycle. - * - * \param [out] aggregatedTimeOff Updates the aggregated time off. - * - * \retval The function status [1: OK, 0: Unable to find a channel on the current datarate]. - */ - virtual bool set_next_channel(NextChanParams_t* nextChanParams, - uint8_t* channel, lorawan_time_t* time, - lorawan_time_t* aggregatedTimeOff ); - - /*! - * \brief Adds a channel. - * - * \param [in] channelAdd A pointer to the function parameters. - * - * \retval The status of the operation. - */ - virtual lorawan_status_t add_channel(ChannelAddParams_t* channelAdd ); - - /*! - * \brief Removes a channel. - * - * \param [in] channelRemove A pointer to the function parameters. - * - * \retval True, if the channel was removed successfully. - */ - virtual bool remove_channel(ChannelRemoveParams_t* channelRemove ); - - /*! - * \brief Sets the radio into continuous wave mode. - * - * \param [in] continuousWave A pointer to the function parameters. - */ - virtual void set_tx_cont_mode(ContinuousWaveParams_t* continuousWave ); - - /*! - * \brief Computes a new datarate according to the given offset. - * - * \param [in] downlinkDwellTime The downlink dwell time configuration. 0: No limit, 1: 400ms - * - * \param [in] dr The current datarate. - * - * \param [in] drOffset The offset to be applied. - * - * \retval newDr The computed datarate. - */ - virtual uint8_t apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ); - private: - uint8_t CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, channel_params_t* channels, band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ); - - // Global attributes /*! * LoRaMAC channels */ - channel_params_t Channels[EU868_MAX_NB_CHANNELS]; + channel_params_t channels[EU868_MAX_NB_CHANNELS]; /*! * LoRaMac bands */ - band_t Bands[EU868_MAX_NB_BANDS]; + band_t bands[EU868_MAX_NB_BANDS]; /*! * LoRaMac channels mask */ - uint16_t ChannelsMask[EU868_CHANNELS_MASK_SIZE]; + uint16_t channel_masks[EU868_CHANNELS_MASK_SIZE]; /*! * LoRaMac channels default mask */ - uint16_t ChannelsDefaultMask[EU868_CHANNELS_MASK_SIZE]; + uint16_t default_channel_masks[EU868_CHANNELS_MASK_SIZE]; }; #endif /* MBED_OS_LORAPHY_EU868_H_ */ diff --git a/features/lorawan/lorastack/phy/LoRaPHYIN865.cpp b/features/lorawan/lorastack/phy/LoRaPHYIN865.cpp index 651868fce8..c0661c8238 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYIN865.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYIN865.cpp @@ -30,9 +30,7 @@ */ #include "LoRaPHYIN865.h" - #include "lora_phy_ds.h" -#include "LoRaRadio.h" /*! @@ -69,6 +67,7 @@ * Default datarate used by the node */ #define IN865_DEFAULT_DATARATE DR_0 +#define IN865_DEFAULT_MAX_DATARATE DR_5 /*! * Minimal Rx1 receive datarate offset @@ -183,25 +182,25 @@ * Band 0 definition * { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff } */ -#define IN865_BAND0 { 1 , IN865_MAX_TX_POWER, 0, 0, 0 } // 100.0 % +static const band_t IN865_BAND0 = { 1 , IN865_MAX_TX_POWER, 0, 0, 0, 865000000, 867000000 }; // 100.0 % /*! * LoRaMac default channel 1 * Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } */ -#define IN865_LC1 { 865062500, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } +static const channel_params_t IN865_LC1 = { 865062500, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }; /*! * LoRaMac default channel 2 * Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } */ -#define IN865_LC2 { 865402500, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } +static const channel_params_t IN865_LC2 = { 865402500, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }; /*! * LoRaMac default channel 3 * Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } */ -#define IN865_LC3 { 865985000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } +static const channel_params_t IN865_LC3 = { 865985000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }; /*! * LoRaMac channels which are allowed for the join procedure @@ -211,1034 +210,117 @@ /*! * Data rates table definition */ -static const uint8_t DataratesIN865[] = { 12, 11, 10, 9, 8, 7, 7, 50 }; +static const uint8_t datarates_IN865[] = { 12, 11, 10, 9, 8, 7, 7, 50 }; /*! * Bandwidths table definition in Hz */ -static const uint32_t BandwidthsIN865[] = { 125000, 125000, 125000, 125000, 125000, 125000, 250000, 0 }; +static const uint32_t bandwidths_IN865[] = { 125000, 125000, 125000, 125000, 125000, 125000, 250000, 0 }; /*! * Maximum payload with respect to the datarate index. Cannot operate with repeater. */ -static const uint8_t MaxPayloadOfDatarateIN865[] = { 51, 51, 51, 115, 242, 242, 242, 242 }; +static const uint8_t max_payloads_IN865[] = { 51, 51, 51, 115, 242, 242, 242, 242 }; /*! * Maximum payload with respect to the datarate index. Can operate with repeater. */ -static const uint8_t MaxPayloadOfDatarateRepeaterIN865[] = { 51, 51, 51, 115, 222, 222, 222, 222 }; +static const uint8_t max_payloads_with_repeater[] = { 51, 51, 51, 115, 222, 222, 222, 222 }; /*! * Effective datarate offsets for receive window 1. */ -static const int8_t EffectiveRx1DrOffsetIN865[] = { 0, 1, 2, 3, 4, 5, -1, -2 }; - - -// Static functions -static int8_t GetNextLowerTxDr( int8_t dr, int8_t minDr ) -{ - uint8_t nextLowerDr = 0; - - if( dr == minDr ) - { - nextLowerDr = minDr; - } - else if( dr == DR_7 ) - { - nextLowerDr = DR_5; - } - else - { - nextLowerDr = dr - 1; - } - return nextLowerDr; -} - -static uint32_t GetBandwidth( uint32_t drIndex ) -{ - switch( BandwidthsIN865[drIndex] ) - { - default: - case 125000: - return 0; - case 250000: - return 1; - case 500000: - return 2; - } -} - -static int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower, int8_t datarate, uint16_t* channelsMask ) -{ - int8_t txPowerResult = txPower; - - // Limit tx power to the band max - txPowerResult = MAX( txPower, maxBandTxPower ); - - return txPowerResult; -} - -static bool VerifyTxFreq( uint32_t freq, uint8_t *band, LoRaRadio *radio ) -{ - // Check radio driver support - if( radio->check_rf_frequency( freq ) == false ) - { - return false; - } - - if( ( freq < 865000000 ) || ( freq > 867000000 ) ) - { - return false; - } - return true; -} - -uint8_t LoRaPHYIN865::CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, channel_params_t* channels, band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ) -{ - uint8_t nbEnabledChannels = 0; - uint8_t delayTransmission = 0; - - for( uint8_t i = 0, k = 0; i < IN865_MAX_NB_CHANNELS; i += 16, k++ ) - { - for( uint8_t j = 0; j < 16; j++ ) - { - if( ( channelsMask[k] & ( 1 << j ) ) != 0 ) - { - if( channels[i + j].frequency == 0 ) - { // Check if the channel is enabled - continue; - } - if( joined == false ) - { - if( ( IN865_JOIN_CHANNELS & ( 1 << j ) ) == 0 ) - { - continue; - } - } - if( val_in_range( datarate, channels[i + j].dr_range.fields.min, - channels[i + j].dr_range.fields.max ) == 0 ) - { // Check if the current channel selection supports the given datarate - continue; - } - if( bands[channels[i + j].band].off_time > 0 ) - { // Check if the band is available for transmission - delayTransmission++; - continue; - } - enabledChannels[nbEnabledChannels++] = i + j; - } - } - } - - *delayTx = delayTransmission; - return nbEnabledChannels; -} +static const int8_t rx1_dr_offset_IN865[] = { 0, 1, 2, 3, 4, 5, -1, -2 }; LoRaPHYIN865::LoRaPHYIN865(LoRaWANTimeHandler &lora_time) - : LoRaPHY(lora_time) + : LoRaPHY(lora_time) { - const band_t band0 = IN865_BAND0; - Bands[0] = band0; + bands[0] = IN865_BAND0; + + // Default Channels are always enabled, rest will be added later + channels[0] = IN865_LC1; + channels[1] = IN865_LC2; + channels[2] = IN865_LC3; + + // Initialize the channels default mask + default_channel_masks[0] = LC(1) + LC(2) + LC(3); + // Update the channels mask + copy_channel_mask(channel_masks, default_channel_masks, 1); + + // set default channels + phy_params.channels.channel_list = channels; + phy_params.channels.channel_list_size = IN865_MAX_NB_CHANNELS; + phy_params.channels.mask_list = channel_masks; + phy_params.channels.default_mask_list = default_channel_masks; + phy_params.channels.mask_list_size = IN865_CHANNELS_MASK_SIZE; + + // set bands for IN865 spectrum + phy_params.bands.table = (void *) bands; + phy_params.bands.size = IN865_MAX_NB_BANDS; + + // set bandwidths available in IN865 spectrum + phy_params.bandwidths.table = (void *) bandwidths_IN865; + phy_params.bandwidths.size = 8; + + // set data rates available in IN865 spectrum + phy_params.datarates.table = (void *) datarates_IN865; + phy_params.datarates.size = 8; + + // set payload sizes with respect to data rates + phy_params.payloads.table = (void *) max_payloads_IN865; + phy_params.payloads.size = 8; + phy_params.payloads_with_repeater.table = (void *) max_payloads_with_repeater; + phy_params.payloads.size = 8; + + // dwell time setting + phy_params.ul_dwell_time_setting = 0; + phy_params.dl_dwell_time_setting = 0; + + // set initial and default parameters + phy_params.duty_cycle_enabled = IN865_DUTY_CYCLE_ENABLED; + phy_params.accept_tx_param_setup_req = false; + phy_params.fsk_supported = true; + phy_params.cflist_supported = true; + phy_params.dl_channel_req_supported = true; + phy_params.custom_channelplans_supported = true; + phy_params.default_channel_cnt = IN865_NUMB_DEFAULT_CHANNELS; + phy_params.max_channel_cnt = IN865_MAX_NB_CHANNELS; + phy_params.cflist_channel_cnt = IN865_NUMB_CHANNELS_CF_LIST; + phy_params.min_tx_datarate = IN865_TX_MIN_DATARATE; + phy_params.max_tx_datarate = IN865_TX_MAX_DATARATE; + phy_params.min_rx_datarate = IN865_RX_MIN_DATARATE; + phy_params.max_rx_datarate = IN865_RX_MAX_DATARATE; + phy_params.default_datarate = IN865_DEFAULT_DATARATE; + phy_params.default_max_datarate = IN865_DEFAULT_MAX_DATARATE; + phy_params.min_rx1_dr_offset = IN865_MIN_RX1_DR_OFFSET; + phy_params.max_rx1_dr_offset = IN865_MAX_RX1_DR_OFFSET; + phy_params.default_rx1_dr_offset = IN865_DEFAULT_RX1_DR_OFFSET; + phy_params.min_tx_power = IN865_MIN_TX_POWER; + phy_params.max_tx_power = IN865_MAX_TX_POWER; + phy_params.default_tx_power = IN865_DEFAULT_TX_POWER; + phy_params.default_max_eirp = IN865_DEFAULT_MAX_EIRP; + phy_params.default_antenna_gain = IN865_DEFAULT_ANTENNA_GAIN; + phy_params.adr_ack_limit = IN865_ADR_ACK_LIMIT; + phy_params.adr_ack_delay = IN865_ADR_ACK_DELAY; + phy_params.max_rx_window = IN865_MAX_RX_WINDOW; + phy_params.recv_delay1 = IN865_RECEIVE_DELAY1; + phy_params.recv_delay2 = IN865_RECEIVE_DELAY2; + phy_params.join_channel_mask = IN865_JOIN_CHANNELS; + phy_params.join_accept_delay1 = IN865_JOIN_ACCEPT_DELAY1; + phy_params.join_accept_delay2 = IN865_JOIN_ACCEPT_DELAY2; + phy_params.max_fcnt_gap = IN865_MAX_FCNT_GAP; + phy_params.ack_timeout = IN865_ACKTIMEOUT; + phy_params.ack_timeout_rnd = IN865_ACK_TIMEOUT_RND; + phy_params.rx_window2_datarate = IN865_RX_WND_2_DR; + phy_params.rx_window2_frequency = IN865_RX_WND_2_FREQ; } LoRaPHYIN865::~LoRaPHYIN865() { } -PhyParam_t LoRaPHYIN865::get_phy_params(GetPhyParams_t* getPhy) -{ - PhyParam_t phyParam = { 0 }; - - switch( getPhy->Attribute ) - { - case PHY_MIN_RX_DR: - { - phyParam.Value = IN865_RX_MIN_DATARATE; - break; - } - case PHY_MIN_TX_DR: - { - phyParam.Value = IN865_TX_MIN_DATARATE; - break; - } - case PHY_DEF_TX_DR: - { - phyParam.Value = IN865_DEFAULT_DATARATE; - break; - } - case PHY_NEXT_LOWER_TX_DR: - { - phyParam.Value = GetNextLowerTxDr( getPhy->Datarate, IN865_TX_MIN_DATARATE ); - break; - } - case PHY_DEF_TX_POWER: - { - phyParam.Value = IN865_DEFAULT_TX_POWER; - break; - } - case PHY_MAX_PAYLOAD: - { - phyParam.Value = MaxPayloadOfDatarateIN865[getPhy->Datarate]; - break; - } - case PHY_MAX_PAYLOAD_REPEATER: - { - phyParam.Value = MaxPayloadOfDatarateRepeaterIN865[getPhy->Datarate]; - break; - } - case PHY_DUTY_CYCLE: - { - phyParam.Value = IN865_DUTY_CYCLE_ENABLED; - break; - } - case PHY_MAX_RX_WINDOW: - { - phyParam.Value = IN865_MAX_RX_WINDOW; - break; - } - case PHY_RECEIVE_DELAY1: - { - phyParam.Value = IN865_RECEIVE_DELAY1; - break; - } - case PHY_RECEIVE_DELAY2: - { - phyParam.Value = IN865_RECEIVE_DELAY2; - break; - } - case PHY_JOIN_ACCEPT_DELAY1: - { - phyParam.Value = IN865_JOIN_ACCEPT_DELAY1; - break; - } - case PHY_JOIN_ACCEPT_DELAY2: - { - phyParam.Value = IN865_JOIN_ACCEPT_DELAY2; - break; - } - case PHY_MAX_FCNT_GAP: - { - phyParam.Value = IN865_MAX_FCNT_GAP; - break; - } - case PHY_ACK_TIMEOUT: - { - phyParam.Value = ( IN865_ACKTIMEOUT + get_random( -IN865_ACK_TIMEOUT_RND, IN865_ACK_TIMEOUT_RND ) ); - break; - } - case PHY_DEF_DR1_OFFSET: - { - phyParam.Value = IN865_DEFAULT_RX1_DR_OFFSET; - break; - } - case PHY_DEF_RX2_FREQUENCY: - { - phyParam.Value = IN865_RX_WND_2_FREQ; - break; - } - case PHY_DEF_RX2_DR: - { - phyParam.Value = IN865_RX_WND_2_DR; - break; - } - case PHY_CHANNELS_MASK: - { - phyParam.ChannelsMask = ChannelsMask; - break; - } - case PHY_CHANNELS_DEFAULT_MASK: - { - phyParam.ChannelsMask = ChannelsDefaultMask; - break; - } - case PHY_MAX_NB_CHANNELS: - { - phyParam.Value = IN865_MAX_NB_CHANNELS; - break; - } - case PHY_CHANNELS: - { - phyParam.Channels = Channels; - break; - } - case PHY_DEF_UPLINK_DWELL_TIME: - case PHY_DEF_DOWNLINK_DWELL_TIME: - { - phyParam.Value = 0; - break; - } - case PHY_DEF_MAX_EIRP: - { - phyParam.fValue = IN865_DEFAULT_MAX_EIRP; - break; - } - case PHY_DEF_ANTENNA_GAIN: - { - phyParam.fValue = IN865_DEFAULT_ANTENNA_GAIN; - break; - } - case PHY_NB_JOIN_TRIALS: - case PHY_DEF_NB_JOIN_TRIALS: - { - phyParam.Value = 48; - break; - } - default: - { - break; - } - } - - return phyParam; -} - -void LoRaPHYIN865::set_band_tx_done(SetBandTxDoneParams_t* txDone) -{ - set_last_tx_done( txDone->Joined, &Bands[Channels[txDone->Channel].band], txDone->LastTxDoneTime ); -} - -void LoRaPHYIN865::load_defaults(InitType_t type) -{ - switch( type ) - { - case INIT_TYPE_INIT: - { - // Channels - const channel_params_t channel1 = IN865_LC1; - const channel_params_t channel2 = IN865_LC2; - const channel_params_t channel3 = IN865_LC3; - Channels[0] = channel1; - Channels[1] = channel2; - Channels[2] = channel3; - - // Initialize the channels default mask - ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 ); - // Update the channels mask - copy_channel_mask( ChannelsMask, ChannelsDefaultMask, 1 ); - break; - } - case INIT_TYPE_RESTORE: - { - // Restore channels default mask - ChannelsMask[0] |= ChannelsDefaultMask[0]; - break; - } - default: - { - break; - } - } -} - -bool LoRaPHYIN865::verify(VerifyParams_t* verify, PhyAttribute_t phyAttribute) -{ - switch( phyAttribute ) - { - case PHY_TX_DR: - { - return val_in_range( verify->DatarateParams.Datarate, IN865_TX_MIN_DATARATE, IN865_TX_MAX_DATARATE ); - } - case PHY_DEF_TX_DR: - { - return val_in_range( verify->DatarateParams.Datarate, DR_0, DR_5 ); - } - case PHY_RX_DR: - { - return val_in_range( verify->DatarateParams.Datarate, IN865_RX_MIN_DATARATE, IN865_RX_MAX_DATARATE ); - } - case PHY_DEF_TX_POWER: - case PHY_TX_POWER: - { - // Remark: switched min and max! - return val_in_range( verify->TxPower, IN865_MAX_TX_POWER, IN865_MIN_TX_POWER ); - } - case PHY_DUTY_CYCLE: - { - return IN865_DUTY_CYCLE_ENABLED; - } - case PHY_NB_JOIN_TRIALS: - { - if( verify->NbJoinTrials < 48 ) - { - return false; - } - break; - } - default: - return false; - } - return true; -} - -void LoRaPHYIN865::apply_cf_list(ApplyCFListParams_t* applyCFList) -{ - channel_params_t newChannel; - ChannelAddParams_t channelAdd; - ChannelRemoveParams_t channelRemove; - - // Setup default datarate range - newChannel.dr_range.value = ( DR_5 << 4 ) | DR_0; - - // Size of the optional CF list - if( applyCFList->Size != 16 ) - { - return; - } - - // Last byte is RFU, don't take it into account - for( uint8_t i = 0, chanIdx = IN865_NUMB_DEFAULT_CHANNELS; chanIdx < IN865_MAX_NB_CHANNELS; i+=3, chanIdx++ ) - { - if( chanIdx < ( IN865_NUMB_CHANNELS_CF_LIST + IN865_NUMB_DEFAULT_CHANNELS ) ) - { - // Channel frequency - newChannel.frequency = (uint32_t) applyCFList->Payload[i]; - newChannel.frequency |= ( (uint32_t) applyCFList->Payload[i + 1] << 8 ); - newChannel.frequency |= ( (uint32_t) applyCFList->Payload[i + 2] << 16 ); - newChannel.frequency *= 100; - - // Initialize alternative frequency to 0 - newChannel.rx1_frequency = 0; - } - else - { - newChannel.frequency = 0; - newChannel.dr_range.value = 0; - newChannel.rx1_frequency = 0; - } - - if( newChannel.frequency != 0 ) - { - channelAdd.NewChannel = &newChannel; - channelAdd.ChannelId = chanIdx; - - // Try to add all channels - add_channel( &channelAdd ); - } - else - { - channelRemove.ChannelId = chanIdx; - - remove_channel( &channelRemove ); - } - } -} - -bool LoRaPHYIN865::set_channel_mask(ChanMaskSetParams_t* chanMaskSet) -{ - switch( chanMaskSet->ChannelsMaskType ) - { - case CHANNELS_MASK: - { - copy_channel_mask( ChannelsMask, chanMaskSet->ChannelsMaskIn, 1 ); - break; - } - case CHANNELS_DEFAULT_MASK: - { - copy_channel_mask( ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 1 ); - break; - } - default: - return false; - } - return true; -} - -bool LoRaPHYIN865::get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut, - int8_t* txPowOut, uint32_t* adrAckCounter) -{ - bool adrAckReq = false; - int8_t datarate = adrNext->Datarate; - int8_t txPower = adrNext->TxPower; - GetPhyParams_t getPhy; - PhyParam_t phyParam; - - // Report back the adr ack counter - *adrAckCounter = adrNext->AdrAckCounter; - - if( adrNext->AdrEnabled == true ) - { - if( datarate == IN865_TX_MIN_DATARATE ) - { - *adrAckCounter = 0; - adrAckReq = false; - } - else - { - if( adrNext->AdrAckCounter >= IN865_ADR_ACK_LIMIT ) - { - adrAckReq = true; - txPower = IN865_MAX_TX_POWER; - } - else - { - adrAckReq = false; - } - if( adrNext->AdrAckCounter >= ( IN865_ADR_ACK_LIMIT + IN865_ADR_ACK_DELAY ) ) - { - if( ( adrNext->AdrAckCounter % IN865_ADR_ACK_DELAY ) == 1 ) - { - // Decrease the datarate - getPhy.Attribute = PHY_NEXT_LOWER_TX_DR; - getPhy.Datarate = datarate; - getPhy.UplinkDwellTime = adrNext->UplinkDwellTime; - phyParam = get_phy_params( &getPhy ); - datarate = phyParam.Value; - - if( datarate == IN865_TX_MIN_DATARATE ) - { - // We must set adrAckReq to false as soon as we reach the lowest datarate - adrAckReq = false; - if( adrNext->UpdateChanMask == true ) - { - // Re-enable default channels - ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); - } - } - } - } - } - } - - *drOut = datarate; - *txPowOut = txPower; - return adrAckReq; -} - -void LoRaPHYIN865::compute_rx_win_params(int8_t datarate, uint8_t minRxSymbols, - uint32_t rxError, - rx_config_params_t *rxConfigParams) -{ - double tSymbol = 0.0; - - // Get the datarate, perform a boundary check - rxConfigParams->datarate = MIN( datarate, IN865_RX_MAX_DATARATE ); - rxConfigParams->bandwidth = GetBandwidth( rxConfigParams->datarate ); - - if( rxConfigParams->datarate == DR_7 ) - { // FSK - tSymbol = compute_symb_timeout_fsk( DataratesIN865[rxConfigParams->datarate] ); - } - else - { // LoRa - tSymbol = compute_symb_timeout_lora( DataratesIN865[rxConfigParams->datarate], BandwidthsIN865[rxConfigParams->datarate] ); - } - - get_rx_window_params( tSymbol, minRxSymbols, rxError, RADIO_WAKEUP_TIME, &rxConfigParams->window_timeout, &rxConfigParams->window_offset ); -} - -bool LoRaPHYIN865::rx_config(rx_config_params_t* rxConfig, int8_t* datarate) -{ - radio_modems_t modem; - int8_t dr = rxConfig->datarate; - uint8_t maxPayload = 0; - int8_t phyDr = 0; - uint32_t frequency = rxConfig->frequency; - - if( _radio->get_status() != RF_IDLE ) - { - return false; - } - - if( rxConfig->rx_slot == RX_SLOT_WIN_1 ) - { - // Apply window 1 frequency - frequency = Channels[rxConfig->channel].frequency; - // Apply the alternative RX 1 window frequency, if it is available - if( Channels[rxConfig->channel].rx1_frequency != 0 ) - { - frequency = Channels[rxConfig->channel].rx1_frequency; - } - } - - // Read the physical datarate from the datarates table - phyDr = DataratesIN865[dr]; - - _radio->set_channel( frequency ); - - // Radio configuration - if( dr == DR_7 ) - { - modem = MODEM_FSK; - _radio->set_rx_config( modem, 50000, phyDr * 1000, 0, 83333, 5, rxConfig->window_timeout, false, 0, true, 0, 0, false, rxConfig->is_rx_continuous ); - } - else - { - modem = MODEM_LORA; - _radio->set_rx_config( modem, rxConfig->bandwidth, phyDr, 1, 0, 8, rxConfig->window_timeout, false, 0, false, 0, 0, true, rxConfig->is_rx_continuous ); - } - - if( rxConfig->is_repeater_supported == true ) - { - maxPayload = MaxPayloadOfDatarateRepeaterIN865[dr]; - } - else - { - maxPayload = MaxPayloadOfDatarateIN865[dr]; - } - _radio->set_max_payload_length( modem, maxPayload + LORA_MAC_FRMPAYLOAD_OVERHEAD ); - - *datarate = (uint8_t) dr; - return true; -} - -bool LoRaPHYIN865::tx_config(TxConfigParams_t* txConfig, int8_t* txPower, lorawan_time_t* txTimeOnAir) -{ - radio_modems_t modem; - int8_t phyDr = DataratesIN865[txConfig->Datarate]; - int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, Bands[Channels[txConfig->Channel].band].max_tx_pwr, txConfig->Datarate, ChannelsMask ); - uint32_t bandwidth = GetBandwidth( txConfig->Datarate ); - int8_t phyTxPower = 0; - - // Calculate physical TX power - phyTxPower = compute_tx_power( txPowerLimited, txConfig->MaxEirp, txConfig->AntennaGain ); - - // Setup the radio frequency - _radio->set_channel( Channels[txConfig->Channel].frequency ); - - if( txConfig->Datarate == DR_7 ) - { // High Speed FSK channel - modem = MODEM_FSK; - _radio->set_tx_config( modem, phyTxPower, 25000, bandwidth, phyDr * 1000, 0, 5, false, true, 0, 0, false, 3000 ); - } - else - { - modem = MODEM_LORA; - _radio->set_tx_config( modem, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 3000 ); - } - - // Setup maximum payload lenght of the radio driver - _radio->set_max_payload_length( modem, txConfig->PktLen ); - // Get the time-on-air of the next tx frame - *txTimeOnAir = _radio->time_on_air( modem, txConfig->PktLen ); - - *txPower = txPowerLimited; - return true; -} - -uint8_t LoRaPHYIN865::link_ADR_request(LinkAdrReqParams_t* linkAdrReq, - int8_t* drOut, int8_t* txPowOut, - uint8_t* nbRepOut, uint8_t* nbBytesParsed) -{ - uint8_t status = 0x07; - RegionCommonLinkAdrParams_t linkAdrParams; - uint8_t nextIndex = 0; - uint8_t bytesProcessed = 0; - uint16_t chMask = 0; - GetPhyParams_t getPhy; - PhyParam_t phyParam; - RegionCommonLinkAdrReqVerifyParams_t linkAdrVerifyParams; - - while( bytesProcessed < linkAdrReq->PayloadSize ) - { - // Get ADR request parameters - nextIndex = parse_link_ADR_req( &( linkAdrReq->Payload[bytesProcessed] ), &linkAdrParams ); - - if( nextIndex == 0 ) - break; // break loop, since no more request has been found - - // Update bytes processed - bytesProcessed += nextIndex; - - // Revert status, as we only check the last ADR request for the channel mask KO - status = 0x07; - - // Setup temporary channels mask - chMask = linkAdrParams.ChMask; - - // Verify channels mask - if( ( linkAdrParams.ChMaskCtrl == 0 ) && ( chMask == 0 ) ) - { - status &= 0xFE; // Channel mask KO - } - else if( ( ( linkAdrParams.ChMaskCtrl >= 1 ) && ( linkAdrParams.ChMaskCtrl <= 5 )) || - ( linkAdrParams.ChMaskCtrl >= 7 ) ) - { - // RFU - status &= 0xFE; // Channel mask KO - } - else - { - for( uint8_t i = 0; i < IN865_MAX_NB_CHANNELS; i++ ) - { - if( linkAdrParams.ChMaskCtrl == 6 ) - { - if( Channels[i].frequency != 0 ) - { - chMask |= 1 << i; - } - } - else - { - if( ( ( chMask & ( 1 << i ) ) != 0 ) && - ( Channels[i].frequency == 0 ) ) - {// Trying to enable an undefined channel - status &= 0xFE; // Channel mask KO - } - } - } - } - } - - // Get the minimum possible datarate - getPhy.Attribute = PHY_MIN_TX_DR; - getPhy.UplinkDwellTime = linkAdrReq->UplinkDwellTime; - phyParam = get_phy_params( &getPhy ); - - linkAdrVerifyParams.Status = status; - linkAdrVerifyParams.AdrEnabled = linkAdrReq->AdrEnabled; - linkAdrVerifyParams.Datarate = linkAdrParams.Datarate; - linkAdrVerifyParams.TxPower = linkAdrParams.TxPower; - linkAdrVerifyParams.NbRep = linkAdrParams.NbRep; - linkAdrVerifyParams.CurrentDatarate = linkAdrReq->CurrentDatarate; - linkAdrVerifyParams.CurrentTxPower = linkAdrReq->CurrentTxPower; - linkAdrVerifyParams.CurrentNbRep = linkAdrReq->CurrentNbRep; - linkAdrVerifyParams.NbChannels = IN865_MAX_NB_CHANNELS; - linkAdrVerifyParams.ChannelsMask = &chMask; - linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value; - linkAdrVerifyParams.MaxDatarate = IN865_TX_MAX_DATARATE; - linkAdrVerifyParams.Channels = Channels; - linkAdrVerifyParams.MinTxPower = IN865_MIN_TX_POWER; - linkAdrVerifyParams.MaxTxPower = IN865_MAX_TX_POWER; - - // Verify the parameters and update, if necessary - status = verify_link_ADR_req( &linkAdrVerifyParams, &linkAdrParams.Datarate, &linkAdrParams.TxPower, &linkAdrParams.NbRep ); - - // Update channelsMask if everything is correct - if( status == 0x07 ) - { - // Set the channels mask to a default value - memset( ChannelsMask, 0, sizeof( ChannelsMask ) ); - // Update the channels mask - ChannelsMask[0] = chMask; - } - - // Update status variables - *drOut = linkAdrParams.Datarate; - *txPowOut = linkAdrParams.TxPower; - *nbRepOut = linkAdrParams.NbRep; - *nbBytesParsed = bytesProcessed; - - return status; -} - -uint8_t LoRaPHYIN865::setup_rx_params(RxParamSetupReqParams_t* rxParamSetupReq) -{ - uint8_t status = 0x07; - - // Verify radio frequency - if( _radio->check_rf_frequency( rxParamSetupReq->Frequency ) == false ) - { - status &= 0xFE; // Channel frequency KO - } - - // Verify datarate - if( val_in_range( rxParamSetupReq->Datarate, IN865_RX_MIN_DATARATE, IN865_RX_MAX_DATARATE ) == 0 ) - { - status &= 0xFD; // Datarate KO - } - - // Verify datarate offset - if( val_in_range( rxParamSetupReq->DrOffset, IN865_MIN_RX1_DR_OFFSET, IN865_MAX_RX1_DR_OFFSET ) == 0 ) - { - status &= 0xFB; // Rx1DrOffset range KO - } - - return status; -} - -uint8_t LoRaPHYIN865::request_new_channel(NewChannelReqParams_t* newChannelReq) -{ - uint8_t status = 0x03; - ChannelAddParams_t channelAdd; - ChannelRemoveParams_t channelRemove; - - if( newChannelReq->NewChannel->frequency == 0 ) - { - channelRemove.ChannelId = newChannelReq->ChannelId; - - // Remove - if( remove_channel( &channelRemove ) == false ) - { - status &= 0xFC; - } - } - else - { - channelAdd.NewChannel = newChannelReq->NewChannel; - channelAdd.ChannelId = newChannelReq->ChannelId; - - switch( add_channel( &channelAdd ) ) - { - case LORAWAN_STATUS_OK: - { - break; - } - case LORAWAN_STATUS_FREQUENCY_INVALID: - { - status &= 0xFE; - break; - } - case LORAWAN_STATUS_DATARATE_INVALID: - { - status &= 0xFD; - break; - } - case LORAWAN_STATUS_FREQ_AND_DR_INVALID: - { - status &= 0xFC; - break; - } - default: - { - status &= 0xFC; - break; - } - } - } - - return status; -} - -int8_t LoRaPHYIN865::setup_tx_params(TxParamSetupReqParams_t* txParamSetupReq) -{ - return -1; -} - -uint8_t LoRaPHYIN865::dl_channel_request(DlChannelReqParams_t* dlChannelReq) -{ - uint8_t status = 0x03; - uint8_t band = 0; - - // Verify if the frequency is supported - if( VerifyTxFreq( dlChannelReq->Rx1Frequency, &band, _radio ) == false ) - { - status &= 0xFE; - } - - // Verify if an uplink frequency exists - if( Channels[dlChannelReq->ChannelId].frequency == 0 ) - { - status &= 0xFD; - } - - // Apply Rx1 frequency, if the status is OK - if( status == 0x03 ) - { - Channels[dlChannelReq->ChannelId].rx1_frequency = dlChannelReq->Rx1Frequency; - } - - return status; -} - -int8_t LoRaPHYIN865::get_alternate_DR(AlternateDrParams_t* alternateDr) -{ - int8_t datarate = 0; - - if( ( alternateDr->NbTrials % 48 ) == 0 ) - { - datarate = DR_0; - } - else if( ( alternateDr->NbTrials % 32 ) == 0 ) - { - datarate = DR_1; - } - else if( ( alternateDr->NbTrials % 24 ) == 0 ) - { - datarate = DR_2; - } - else if( ( alternateDr->NbTrials % 16 ) == 0 ) - { - datarate = DR_3; - } - else if( ( alternateDr->NbTrials % 8 ) == 0 ) - { - datarate = DR_4; - } - else - { - datarate = DR_5; - } - return datarate; -} - -void LoRaPHYIN865::calculate_backoff(CalcBackOffParams_t* calcBackOff) -{ - RegionCommonCalcBackOffParams_t calcBackOffParams; - - calcBackOffParams.Channels = Channels; - calcBackOffParams.Bands = Bands; - calcBackOffParams.LastTxIsJoinRequest = calcBackOff->LastTxIsJoinRequest; - calcBackOffParams.Joined = calcBackOff->Joined; - calcBackOffParams.DutyCycleEnabled = calcBackOff->DutyCycleEnabled; - calcBackOffParams.Channel = calcBackOff->Channel; - calcBackOffParams.ElapsedTime = calcBackOff->ElapsedTime; - calcBackOffParams.TxTimeOnAir = calcBackOff->TxTimeOnAir; - - get_DC_backoff( &calcBackOffParams ); -} - -bool LoRaPHYIN865::set_next_channel(NextChanParams_t* nextChanParams, - uint8_t* channel, lorawan_time_t* time, - lorawan_time_t* aggregatedTimeOff) -{ - uint8_t nbEnabledChannels = 0; - uint8_t delayTx = 0; - uint8_t enabledChannels[IN865_MAX_NB_CHANNELS] = { 0 }; - lorawan_time_t nextTxDelay = 0; - - if( num_active_channels( ChannelsMask, 0, 1 ) == 0 ) - { // Reactivate default channels - ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); - } - - if( nextChanParams->AggrTimeOff <= _lora_time.TimerGetElapsedTime( nextChanParams->LastAggrTx ) ) - { - // Reset Aggregated time off - *aggregatedTimeOff = 0; - - // Update bands Time OFF - nextTxDelay = update_band_timeoff( nextChanParams->Joined, nextChanParams->DutyCycleEnabled, Bands, IN865_MAX_NB_BANDS ); - - // Search how many channels are enabled - nbEnabledChannels = CountNbOfEnabledChannels( nextChanParams->Joined, nextChanParams->Datarate, - ChannelsMask, Channels, - Bands, enabledChannels, &delayTx ); - } - else - { - delayTx++; - nextTxDelay = nextChanParams->AggrTimeOff - _lora_time.TimerGetElapsedTime( nextChanParams->LastAggrTx ); - } - - if( nbEnabledChannels > 0 ) - { - // We found a valid channel - *channel = enabledChannels[get_random( 0, nbEnabledChannels - 1 )]; - - *time = 0; - return true; - } - else - { - if( delayTx > 0 ) - { - // Delay transmission due to AggregatedTimeOff or to a band time off - *time = nextTxDelay; - return true; - } - // Datarate not supported by any channel, restore defaults - ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); - *time = 0; - return false; - } -} - -lorawan_status_t LoRaPHYIN865::add_channel(ChannelAddParams_t* channelAdd) -{ - uint8_t band = 0; - bool drInvalid = false; - bool freqInvalid = false; - uint8_t id = channelAdd->ChannelId; - - if( id >= IN865_MAX_NB_CHANNELS ) - { - return LORAWAN_STATUS_PARAMETER_INVALID; - } - - // Validate the datarate range - if( val_in_range( channelAdd->NewChannel->dr_range.fields.min, IN865_TX_MIN_DATARATE, IN865_TX_MAX_DATARATE ) == 0 ) - { - drInvalid = true; - } - if( val_in_range( channelAdd->NewChannel->dr_range.fields.max, IN865_TX_MIN_DATARATE, IN865_TX_MAX_DATARATE ) == 0 ) - { - drInvalid = true; - } - if( channelAdd->NewChannel->dr_range.fields.min > channelAdd->NewChannel->dr_range.fields.max ) - { - drInvalid = true; - } - - // Default channels don't accept all values - if( id < IN865_NUMB_DEFAULT_CHANNELS ) - { - // Validate the datarate range for min: must be DR_0 - if( channelAdd->NewChannel->dr_range.fields.min > DR_0 ) - { - drInvalid = true; - } - // Validate the datarate range for max: must be DR_5 <= Max <= TX_MAX_DATARATE - if( val_in_range( channelAdd->NewChannel->dr_range.fields.max, DR_5, IN865_TX_MAX_DATARATE ) == 0 ) - { - drInvalid = true; - } - // We are not allowed to change the frequency - if( channelAdd->NewChannel->frequency != Channels[id].frequency ) - { - freqInvalid = true; - } - } - - // Check frequency - if( freqInvalid == false ) - { - if( VerifyTxFreq( channelAdd->NewChannel->frequency, &band, _radio ) == false ) - { - freqInvalid = true; - } - } - - // Check status - if( ( drInvalid == true ) && ( freqInvalid == true ) ) - { - return LORAWAN_STATUS_FREQ_AND_DR_INVALID; - } - if( drInvalid == true ) - { - return LORAWAN_STATUS_DATARATE_INVALID; - } - if( freqInvalid == true ) - { - return LORAWAN_STATUS_FREQUENCY_INVALID; - } - - memcpy( &(Channels[id]), channelAdd->NewChannel, sizeof( Channels[id] ) ); - Channels[id].band = band; - ChannelsMask[0] |= ( 1 << id ); - return LORAWAN_STATUS_OK; -} - -bool LoRaPHYIN865::remove_channel(ChannelRemoveParams_t* channelRemove) -{ - uint8_t id = channelRemove->ChannelId; - - if( id < IN865_NUMB_DEFAULT_CHANNELS ) - { - return false; - } - - // Remove the channel from the list of channels - const channel_params_t empty_channel = { 0, 0, { 0 }, 0 }; - Channels[id] = empty_channel; - - return disable_channel( ChannelsMask, id, IN865_MAX_NB_CHANNELS ); -} - -void LoRaPHYIN865::set_tx_cont_mode(ContinuousWaveParams_t* continuousWave) -{ - int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, Bands[Channels[continuousWave->Channel].band].max_tx_pwr, continuousWave->Datarate, ChannelsMask ); - int8_t phyTxPower = 0; - uint32_t frequency = Channels[continuousWave->Channel].frequency; - - // Calculate physical TX power - phyTxPower = compute_tx_power( txPowerLimited, continuousWave->MaxEirp, continuousWave->AntennaGain ); - - _radio->set_tx_continuous_wave( frequency, phyTxPower, continuousWave->Timeout ); -} - -uint8_t LoRaPHYIN865::apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, - int8_t drOffset) +uint8_t LoRaPHYIN865::apply_DR_offset(int8_t dr, int8_t dr_offset) { // Apply offset formula - return MIN( DR_5, MAX( DR_0, dr - EffectiveRx1DrOffsetIN865[drOffset] ) ); + return MIN(DR_5, MAX(DR_0, dr - rx1_dr_offset_IN865[dr_offset])); } diff --git a/features/lorawan/lorastack/phy/LoRaPHYIN865.h b/features/lorawan/lorastack/phy/LoRaPHYIN865.h index a4b870095e..ddc41e6b1e 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYIN865.h +++ b/features/lorawan/lorastack/phy/LoRaPHYIN865.h @@ -33,7 +33,6 @@ #define MBED_OS_LORAPHY_IN865_H_ #include "LoRaPHY.h" -#include "netsocket/LoRaRadio.h" /*! @@ -57,305 +56,28 @@ public: LoRaPHYIN865(LoRaWANTimeHandler &lora_time); virtual ~LoRaPHYIN865(); - /*! - * \brief The function gets a value of a specific PHY attribute. - * - * \param [in] getPhy A pointer to the function parameters. - * - * \retval The structure containing the PHY parameter. - */ - virtual PhyParam_t get_phy_params(GetPhyParams_t* getPhy ); - - /*! - * \brief Updates the last TX done parameters of the current channel. - * - * \param [in] txDone A pointer to the function parameters. - */ - virtual void set_band_tx_done(SetBandTxDoneParams_t* txDone ); - - /*! - * \brief Initializes the channels masks and the channels. - * - * \param [in] type Sets the initialization type. - */ - virtual void load_defaults(InitType_t type ); - - /*! - * \brief Verifies a parameter. - * - * \param [in] verify A pointer to the function parameters. - * - * \param [in] phyAttribute The attribute to verify. - * - * \retval True, if the parameter is valid. - */ - virtual bool verify(VerifyParams_t* verify, PhyAttribute_t phyAttribute ); - - /*! - * \brief The function parses the input buffer and sets up the channels of the CF list. - * - * \param [in] applyCFList A pointer to the function parameters. - */ - virtual void apply_cf_list(ApplyCFListParams_t* applyCFList ); - - /*! - * \brief Sets a channels mask. - * - * \param [in] chanMaskSet A pointer to the function parameters. - * - * \retval True, if the channels mask could be set. - */ - virtual bool set_channel_mask(ChanMaskSetParams_t* chanMaskSet ); - - /*! - * \brief Calculates the next datarate to set, when ADR is on or off. - * - * \param [in] adrNext A pointer to the function parameters. - * - * \param [out] drOut The calculated datarate for the next TX. - * - * \param [out] txPowOut The TX power for the next TX. - * - * \param [out] adrAckCounter The calculated ADR acknowledgement counter. - * - * \retval True, if an ADR request should be performed. - */ - virtual bool get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut, - int8_t* txPowOut, uint32_t* adrAckCounter ); - - /*! - * \brief Configuration of the RX windows. - * - * \param [in] rxConfig A pointer to the function parameters. - * - * \param [out] datarate The datarate index set. - * - * \retval True, if the configuration was applied successfully. - */ - virtual bool rx_config(rx_config_params_t* rxConfig, int8_t* datarate ); - - /* - * RX window precise timing - * - * For more details, please consult the following document, chapter 3.1.2. - * http://www.semtech.com/images/datasheet/SX1272_settings_for_LoRaWAN_v2.0.pdf - * or - * http://www.semtech.com/images/datasheet/SX1276_settings_for_LoRaWAN_v2.0.pdf - * - * Downlink start: T = Tx + 1s (+/- 20 us) - * | - * TRxEarly | TRxLate - * | | | - * | | +---+---+---+---+---+---+---+---+ - * | | | Latest Rx window | - * | | +---+---+---+---+---+---+---+---+ - * | | | - * +---+---+---+---+---+---+---+---+ - * | Earliest Rx window | - * +---+---+---+---+---+---+---+---+ - * | - * +---+---+---+---+---+---+---+---+ - *Downlink preamble 8 symbols | | | | | | | | | - * +---+---+---+---+---+---+---+---+ - * - * Worst case Rx window timings - * - * TRxLate = DEFAULT_MIN_RX_SYMBOLS * tSymbol - RADIO_WAKEUP_TIME - * TRxEarly = 8 - DEFAULT_MIN_RX_SYMBOLS * tSymbol - RxWindowTimeout - RADIO_WAKEUP_TIME - * - * TRxLate - TRxEarly = 2 * DEFAULT_SYSTEM_MAX_RX_ERROR - * - * RxOffset = ( TRxLate + TRxEarly ) / 2 - * - * RxWindowTimeout = ( 2 * DEFAULT_MIN_RX_SYMBOLS - 8 ) * tSymbol + 2 * DEFAULT_SYSTEM_MAX_RX_ERROR - * RxOffset = 4 * tSymbol - RxWindowTimeout / 2 - RADIO_WAKE_UP_TIME - * - * The minimum value of RxWindowTimeout must be 5 symbols which implies that the system always tolerates at least an error of 1.5 * tSymbol - */ - /*! - * Computes the RX window timeout and offset. - * - * \param [in] datarate The RX window datarate index to be used. - * - * \param [in] minRxSymbols The minimum number of symbols required to detect an RX frame. - * - * \param [in] rxError The system maximum timing error of the receiver in milliseconds. - * The receiver will turn on in a [-rxError : +rxError] ms - * interval around RxOffset. - * - * \param [out] rxConfigParams Returns the updated WindowTimeout and WindowOffset fields. - */ - virtual void compute_rx_win_params(int8_t datarate, - uint8_t minRxSymbols, - uint32_t rxError, - rx_config_params_t *rxConfigParams); - - /*! - * \brief TX configuration. - * - * \param [in] txConfig A pointer to the function parameters. - * - * \param [out] txPower The TX power index set. - * - * \param [out] txTimeOnAir The time-on-air of the frame. - * - * \retval True, if the configuration was applied successfully. - */ - virtual bool tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - lorawan_time_t* txTimeOnAir ); - - /*! - * \brief The function processes a Link ADR request. - * - * \param [in] linkAdrReq A pointer to the function parameters. - * - * \param [out] drOut The datarate applied. - * - * \param [out] txPowOut The TX power applied. - * - * \param [out] nbRepOut The number of repetitions to apply. - * - * \param [out] nbBytesParsed The number of bytes parsed. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t link_ADR_request(LinkAdrReqParams_t* linkAdrReq, - int8_t* drOut, int8_t* txPowOut, - uint8_t* nbRepOut, - uint8_t* nbBytesParsed ); - - /*! - * \brief The function processes a RX parameter setup request. - * - * \param [in] rxParamSetupReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t setup_rx_params(RxParamSetupReqParams_t* rxParamSetupReq ); - - /*! - * \brief The function processes a new channel request. - * - * \param [in] newChannelReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t request_new_channel(NewChannelReqParams_t* newChannelReq ); - - /*! - * \brief The function processes a TX ParamSetup request. - * - * \param [in] txParamSetupReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - * Returns -1, if the functionality is not implemented. In this case, the end node - * shall ignore the command. - */ - virtual int8_t setup_tx_params(TxParamSetupReqParams_t* txParamSetupReq ); - - /*! - * \brief The function processes a DlChannel request. - * - * \param [in] dlChannelReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t dl_channel_request(DlChannelReqParams_t* dlChannelReq ); - - /*! - * \brief Alternates the datarate of the channel for the join request. - * - * \param [in] alternateDr A pointer to the function parameters. - * - * \retval The datarate to apply. - */ - virtual int8_t get_alternate_DR(AlternateDrParams_t* alternateDr ); - - /*! - * \brief Calculates the back-off time. - * - * \param [in] calcBackOff A pointer to the function parameters. - */ - virtual void calculate_backoff(CalcBackOffParams_t* calcBackOff ); - - /*! - * \brief Searches and sets the next random available channel. - * - * \param [in] nextChanParams The parameters for the next channel. - * - * \param [out] channel The next channel to use for TX. - * - * \param [out] time The time to wait for the next transmission according to the duty cycle. - * - * \param [out] aggregatedTimeOff Updates the aggregated time off. - * - * \retval The function status [1: OK, 0: Unable to find a channel on the current datarate]. - */ - virtual bool set_next_channel(NextChanParams_t* nextChanParams, - uint8_t* channel, lorawan_time_t* time, - lorawan_time_t* aggregatedTimeOff ); - - /*! - * \brief Adds a channel. - * - * \param [in] channelAdd A pPointer to the function parameters. - * - * \retval The status of the operation. - */ - virtual lorawan_status_t add_channel(ChannelAddParams_t* channelAdd ); - - /*! - * \brief Removes a channel. - * - * \param [in] channelRemove A pointer to the function parameters. - * - * \retval True, if the channel was removed successfully. - */ - virtual bool remove_channel(ChannelRemoveParams_t* channelRemove ); - - /*! - * \brief Sets the radio into continuous wave mode. - * - * \param [in] continuousWave A pointer to the function parameters. - */ - virtual void set_tx_cont_mode(ContinuousWaveParams_t* continuousWave ); - - /*! - * \brief Computes a new datarate according to the given offset. - * - * \param [in] downlinkDwellTime The downlink dwell time configuration. 0: No limit, 1: 400ms - * - * \param [in] dr The current datarate. - * - * \param [in] drOffset The offset to be applied. - * - * \retval newDr The computed datarate. - */ - virtual uint8_t apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ); + virtual uint8_t apply_DR_offset(int8_t dr, int8_t dr_offset ); private: - uint8_t CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, channel_params_t* channels, band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ); - - // Global attributes /*! * LoRaMAC channels */ - channel_params_t Channels[IN865_MAX_NB_CHANNELS]; + channel_params_t channels[IN865_MAX_NB_CHANNELS]; /*! * LoRaMac bands */ - band_t Bands[IN865_MAX_NB_BANDS]; + band_t bands[IN865_MAX_NB_BANDS]; /*! * LoRaMac channels mask */ - uint16_t ChannelsMask[IN865_CHANNELS_MASK_SIZE]; + uint16_t channel_masks[IN865_CHANNELS_MASK_SIZE]; /*! * LoRaMac channels default mask */ - uint16_t ChannelsDefaultMask[IN865_CHANNELS_MASK_SIZE]; + uint16_t default_channel_masks[IN865_CHANNELS_MASK_SIZE]; }; #endif /* MBED_OS_LORAPHY_IN865_H_ */ diff --git a/features/lorawan/lorastack/phy/LoRaPHYKR920.cpp b/features/lorawan/lorastack/phy/LoRaPHYKR920.cpp index e2a96046b0..1ea6660efe 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYKR920.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYKR920.cpp @@ -30,9 +30,7 @@ */ #include "LoRaPHYKR920.h" - #include "lora_phy_ds.h" -#include "LoRaRadio.h" /*! @@ -188,25 +186,25 @@ * Band 0 definition * { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff } */ -#define KR920_BAND0 { 1 , KR920_MAX_TX_POWER, 0, 0, 0 } // 100.0 % +static const band_t KR920_BAND0 = { 1 , KR920_MAX_TX_POWER, 0, 0, 0 }; // 100.0 % /*! * LoRaMac default channel 1 * Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } */ -#define KR920_LC1 { 922100000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } +static const channel_params_t KR920_LC1 = { 922100000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }; /*! * LoRaMac default channel 2 * Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } */ -#define KR920_LC2 { 922300000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } +static const channel_params_t KR920_LC2 = { 922300000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }; /*! * LoRaMac default channel 3 * Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band } */ -#define KR920_LC3 { 922500000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 } +static const channel_params_t KR920_LC3 = { 922500000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }; /*! * LoRaMac channels which are allowed for the join procedure @@ -226,1034 +224,282 @@ /*! * Data rates table definition */ -static const uint8_t DataratesKR920[] = { 12, 11, 10, 9, 8, 7 }; +static const uint8_t datarates_KR920[] = { 12, 11, 10, 9, 8, 7 }; /*! * Bandwidths table definition in Hz */ -static const uint32_t BandwidthsKR920[] = { 125000, 125000, 125000, 125000, 125000, 125000 }; +static const uint32_t bandwidths_KR920[] = { 125000, 125000, 125000, 125000, 125000, 125000 }; /*! * Maximum payload with respect to the datarate index. Can operate with and without a repeater. */ -static const uint8_t MaxPayloadOfDatarateKR920[] = { 51, 51, 51, 115, 242, 242 }; +static const uint8_t max_payloads_KR920[] = { 51, 51, 51, 115, 242, 242 }; /*! * Maximum payload with respect to the datarate index. Can operate with repeater. */ -static const uint8_t MaxPayloadOfDatarateRepeaterKR920[] = { 51, 51, 51, 115, 222, 222 }; - - -// Static functions -static int8_t GetNextLowerTxDr( int8_t dr, int8_t minDr ) -{ - uint8_t nextLowerDr = 0; - - if( dr == minDr ) - { - nextLowerDr = minDr; - } - else - { - nextLowerDr = dr - 1; - } - return nextLowerDr; -} - -static int8_t GetMaxEIRP( uint32_t freq ) -{ - if( freq >= 922100000 ) - {// Limit to 14dBm - return KR920_DEFAULT_MAX_EIRP_HIGH; - } - // Limit to 10dBm - return KR920_DEFAULT_MAX_EIRP_LOW; -} - -static uint32_t GetBandwidth( uint32_t drIndex ) -{ - switch( BandwidthsKR920[drIndex] ) - { - default: - case 125000: - return 0; - case 250000: - return 1; - case 500000: - return 2; - } -} - -static int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower, int8_t datarate, uint16_t* channelsMask ) -{ - int8_t txPowerResult = txPower; - - // Limit tx power to the band max - txPowerResult = MAX( txPower, maxBandTxPower ); - - return txPowerResult; -} - -static bool VerifyTxFreq( uint32_t freq, LoRaRadio *radio ) -{ - uint32_t tmpFreq = freq; - - // Check radio driver support - if( radio->check_rf_frequency( tmpFreq ) == false ) - { - return false; - } - - // Verify if the frequency is valid. The frequency must be in a specified - // range and can be set to specific values. - if( ( tmpFreq >= 920900000 ) && ( tmpFreq <=923300000 ) ) - { - // Range ok, check for specific value - tmpFreq -= 920900000; - if( ( tmpFreq % 200000 ) == 0 ) - { - return true; - } - } - return false; -} - -uint8_t LoRaPHYKR920::CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, channel_params_t* channels, band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ) -{ - uint8_t nbEnabledChannels = 0; - uint8_t delayTransmission = 0; - - for( uint8_t i = 0, k = 0; i < KR920_MAX_NB_CHANNELS; i += 16, k++ ) - { - for( uint8_t j = 0; j < 16; j++ ) - { - if( ( channelsMask[k] & ( 1 << j ) ) != 0 ) - { - if( channels[i + j].frequency == 0 ) - { // Check if the channel is enabled - continue; - } - if( joined == false ) - { - if( ( KR920_JOIN_CHANNELS & ( 1 << j ) ) == 0 ) - { - continue; - } - } - if( val_in_range( datarate, channels[i + j].dr_range.fields.min, - channels[i + j].dr_range.fields.max ) == 0 ) - { // Check if the current channel selection supports the given datarate - continue; - } - if( bands[channels[i + j].band].off_time > 0 ) - { // Check if the band is available for transmission - delayTransmission++; - continue; - } - enabledChannels[nbEnabledChannels++] = i + j; - } - } - } - - *delayTx = delayTransmission; - return nbEnabledChannels; -} +static const uint8_t max_payloads_with_repeater_KR920[] = { 51, 51, 51, 115, 222, 222 }; LoRaPHYKR920::LoRaPHYKR920(LoRaWANTimeHandler &lora_time) : LoRaPHY(lora_time) { - const band_t band0 = KR920_BAND0; - Bands[0] = band0; + bands[0] = KR920_BAND0; + + // Channels + channels[0] = KR920_LC1; + channels[1] = KR920_LC2; + channels[2] = KR920_LC3; + + // Initialize the channels default mask + default_channel_masks[0] = LC( 1 ) + LC( 2 ) + LC( 3 ); + // Update the channels mask + copy_channel_mask(channel_masks, default_channel_masks, KR920_CHANNELS_MASK_SIZE); + + // set default channels + phy_params.channels.channel_list = channels; + phy_params.channels.channel_list_size = KR920_MAX_NB_CHANNELS; + phy_params.channels.mask_list = channel_masks; + phy_params.channels.default_mask_list = default_channel_masks; + phy_params.channels.mask_list_size = KR920_CHANNELS_MASK_SIZE; + + // set bands for KR920 spectrum + phy_params.bands.table = (void *) bands; + phy_params.bands.size = KR920_MAX_NB_BANDS; + + // set bandwidths available in KR920 spectrum + phy_params.bandwidths.table = (void *) bandwidths_KR920; + phy_params.bandwidths.size = 6; + + // set data rates available in KR920 spectrum + phy_params.datarates.table = (void *) datarates_KR920; + phy_params.datarates.size = 6; + + // set payload sizes with respect to data rates + phy_params.payloads.table = (void *) max_payloads_KR920; + phy_params.payloads.size = 6; + phy_params.payloads_with_repeater.table = (void *) max_payloads_with_repeater_KR920; + phy_params.payloads.size = 6; + + // dwell time setting + phy_params.ul_dwell_time_setting = 0; + phy_params.dl_dwell_time_setting = 0; + + // set initial and default parameters + phy_params.duty_cycle_enabled = KR920_DUTY_CYCLE_ENABLED; + phy_params.accept_tx_param_setup_req = false; + phy_params.fsk_supported = false; + phy_params.cflist_supported = true; + phy_params.dl_channel_req_supported = true; + phy_params.custom_channelplans_supported = true; + phy_params.default_channel_cnt = KR920_NUMB_DEFAULT_CHANNELS; + phy_params.max_channel_cnt = KR920_MAX_NB_CHANNELS; + phy_params.cflist_channel_cnt = KR920_NUMB_CHANNELS_CF_LIST; + phy_params.min_tx_datarate = KR920_TX_MIN_DATARATE; + phy_params.max_tx_datarate = KR920_TX_MAX_DATARATE; + phy_params.min_rx_datarate = KR920_RX_MIN_DATARATE; + phy_params.max_rx_datarate = KR920_RX_MAX_DATARATE; + phy_params.default_datarate = KR920_DEFAULT_DATARATE; + phy_params.default_max_datarate = KR920_TX_MAX_DATARATE; + phy_params.min_rx1_dr_offset = KR920_MIN_RX1_DR_OFFSET; + phy_params.max_rx1_dr_offset = KR920_MAX_RX1_DR_OFFSET; + phy_params.default_rx1_dr_offset = KR920_DEFAULT_RX1_DR_OFFSET; + phy_params.min_tx_power = KR920_MIN_TX_POWER; + phy_params.max_tx_power = KR920_MAX_TX_POWER; + phy_params.default_tx_power = KR920_DEFAULT_TX_POWER; + phy_params.default_max_eirp = KR920_DEFAULT_MAX_EIRP_HIGH; + phy_params.default_antenna_gain = KR920_DEFAULT_ANTENNA_GAIN; + phy_params.adr_ack_limit = KR920_ADR_ACK_LIMIT; + phy_params.adr_ack_delay = KR920_ADR_ACK_DELAY; + phy_params.max_rx_window = KR920_MAX_RX_WINDOW; + phy_params.recv_delay1 = KR920_RECEIVE_DELAY1; + phy_params.recv_delay2 = KR920_RECEIVE_DELAY2; + phy_params.join_channel_mask = KR920_JOIN_CHANNELS; + phy_params.join_accept_delay1 = KR920_JOIN_ACCEPT_DELAY1; + phy_params.join_accept_delay2 = KR920_JOIN_ACCEPT_DELAY2; + phy_params.max_fcnt_gap = KR920_MAX_FCNT_GAP; + phy_params.ack_timeout = KR920_ACKTIMEOUT; + phy_params.ack_timeout_rnd = KR920_ACK_TIMEOUT_RND; + phy_params.rx_window2_datarate = KR920_RX_WND_2_DR; + phy_params.rx_window2_frequency = KR920_RX_WND_2_FREQ; } LoRaPHYKR920::~LoRaPHYKR920() { } -PhyParam_t LoRaPHYKR920::get_phy_params(GetPhyParams_t* getPhy) +int8_t LoRaPHYKR920::get_max_eirp(uint32_t freq) { - PhyParam_t phyParam = { 0 }; - - switch( getPhy->Attribute ) - { - case PHY_MIN_RX_DR: - { - phyParam.Value = KR920_RX_MIN_DATARATE; - break; - } - case PHY_MIN_TX_DR: - { - phyParam.Value = KR920_TX_MIN_DATARATE; - break; - } - case PHY_DEF_TX_DR: - { - phyParam.Value = KR920_DEFAULT_DATARATE; - break; - } - case PHY_NEXT_LOWER_TX_DR: - { - phyParam.Value = GetNextLowerTxDr( getPhy->Datarate, KR920_TX_MIN_DATARATE ); - break; - } - case PHY_DEF_TX_POWER: - { - phyParam.Value = KR920_DEFAULT_TX_POWER; - break; - } - case PHY_MAX_PAYLOAD: - { - phyParam.Value = MaxPayloadOfDatarateKR920[getPhy->Datarate]; - break; - } - case PHY_MAX_PAYLOAD_REPEATER: - { - phyParam.Value = MaxPayloadOfDatarateRepeaterKR920[getPhy->Datarate]; - break; - } - case PHY_DUTY_CYCLE: - { - phyParam.Value = KR920_DUTY_CYCLE_ENABLED; - break; - } - case PHY_MAX_RX_WINDOW: - { - phyParam.Value = KR920_MAX_RX_WINDOW; - break; - } - case PHY_RECEIVE_DELAY1: - { - phyParam.Value = KR920_RECEIVE_DELAY1; - break; - } - case PHY_RECEIVE_DELAY2: - { - phyParam.Value = KR920_RECEIVE_DELAY2; - break; - } - case PHY_JOIN_ACCEPT_DELAY1: - { - phyParam.Value = KR920_JOIN_ACCEPT_DELAY1; - break; - } - case PHY_JOIN_ACCEPT_DELAY2: - { - phyParam.Value = KR920_JOIN_ACCEPT_DELAY2; - break; - } - case PHY_MAX_FCNT_GAP: - { - phyParam.Value = KR920_MAX_FCNT_GAP; - break; - } - case PHY_ACK_TIMEOUT: - { - phyParam.Value = ( KR920_ACKTIMEOUT + get_random( -KR920_ACK_TIMEOUT_RND, KR920_ACK_TIMEOUT_RND ) ); - break; - } - case PHY_DEF_DR1_OFFSET: - { - phyParam.Value = KR920_DEFAULT_RX1_DR_OFFSET; - break; - } - case PHY_DEF_RX2_FREQUENCY: - { - phyParam.Value = KR920_RX_WND_2_FREQ; - break; - } - case PHY_DEF_RX2_DR: - { - phyParam.Value = KR920_RX_WND_2_DR; - break; - } - case PHY_CHANNELS_MASK: - { - phyParam.ChannelsMask = ChannelsMask; - break; - } - case PHY_CHANNELS_DEFAULT_MASK: - { - phyParam.ChannelsMask = ChannelsDefaultMask; - break; - } - case PHY_MAX_NB_CHANNELS: - { - phyParam.Value = KR920_MAX_NB_CHANNELS; - break; - } - case PHY_CHANNELS: - { - phyParam.Channels = Channels; - break; - } - case PHY_DEF_UPLINK_DWELL_TIME: - case PHY_DEF_DOWNLINK_DWELL_TIME: - { - phyParam.Value = 0; - break; - } - case PHY_DEF_MAX_EIRP: - { - // We set the higher maximum EIRP as default value. - // The reason for this is, that the frequency may - // change during a channel selection for the next uplink. - // The value has to be recalculated in the TX configuration. - phyParam.fValue = KR920_DEFAULT_MAX_EIRP_HIGH; - break; - } - case PHY_DEF_ANTENNA_GAIN: - { - phyParam.fValue = KR920_DEFAULT_ANTENNA_GAIN; - break; - } - case PHY_NB_JOIN_TRIALS: - case PHY_DEF_NB_JOIN_TRIALS: - { - phyParam.Value = 48; - break; - } - default: - { - break; - } + if (freq >= 922100000) {// Limit to 14dBm + return KR920_DEFAULT_MAX_EIRP_HIGH; } - return phyParam; + // Limit to 10dBm + return KR920_DEFAULT_MAX_EIRP_LOW; } -void LoRaPHYKR920::set_band_tx_done(SetBandTxDoneParams_t* txDone) + +bool LoRaPHYKR920::verify_frequency(uint32_t freq) { - set_last_tx_done( txDone->Joined, &Bands[Channels[txDone->Channel].band], txDone->LastTxDoneTime ); -} + uint32_t tmpFreq = freq; -void LoRaPHYKR920::load_defaults(InitType_t type) -{ - switch( type ) - { - case INIT_TYPE_INIT: - { - // Channels - const channel_params_t channel1 = KR920_LC1; - const channel_params_t channel2 = KR920_LC2; - const channel_params_t channel3 = KR920_LC3; - Channels[0] = channel1; - Channels[1] = channel2; - Channels[2] = channel3; + _radio->lock(); - // Initialize the channels default mask - ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 ); - // Update the channels mask - copy_channel_mask( ChannelsMask, ChannelsDefaultMask, 1 ); - break; - } - case INIT_TYPE_RESTORE: - { - // Restore channels default mask - ChannelsMask[0] |= ChannelsDefaultMask[0]; - break; - } - default: - { - break; - } - } -} - -bool LoRaPHYKR920::verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) -{ - switch( phyAttribute ) - { - case PHY_TX_DR: - { - return val_in_range( verify->DatarateParams.Datarate, KR920_TX_MIN_DATARATE, KR920_TX_MAX_DATARATE ); - } - case PHY_DEF_TX_DR: - { - return val_in_range( verify->DatarateParams.Datarate, DR_0, DR_5 ); - } - case PHY_RX_DR: - { - return val_in_range( verify->DatarateParams.Datarate, KR920_RX_MIN_DATARATE, KR920_RX_MAX_DATARATE ); - } - case PHY_DEF_TX_POWER: - case PHY_TX_POWER: - { - // Remark: switched min and max! - return val_in_range( verify->TxPower, KR920_MAX_TX_POWER, KR920_MIN_TX_POWER ); - } - case PHY_DUTY_CYCLE: - { - return KR920_DUTY_CYCLE_ENABLED; - } - case PHY_NB_JOIN_TRIALS: - { - if( verify->NbJoinTrials < 48 ) - { - return false; - } - break; - } - default: - return false; - } - return true; -} - -void LoRaPHYKR920::apply_cf_list(ApplyCFListParams_t* applyCFList) -{ - channel_params_t newChannel; - ChannelAddParams_t channelAdd; - ChannelRemoveParams_t channelRemove; - - // Setup default datarate range - newChannel.dr_range.value = ( DR_5 << 4 ) | DR_0; - - // Size of the optional CF list - if( applyCFList->Size != 16 ) - { - return; - } - - // Last byte is RFU, don't take it into account - for( uint8_t i = 0, chanIdx = KR920_NUMB_DEFAULT_CHANNELS; chanIdx < KR920_MAX_NB_CHANNELS; i+=3, chanIdx++ ) - { - if( chanIdx < ( KR920_NUMB_CHANNELS_CF_LIST + KR920_NUMB_DEFAULT_CHANNELS ) ) - { - // Channel frequency - newChannel.frequency = (uint32_t) applyCFList->Payload[i]; - newChannel.frequency |= ( (uint32_t) applyCFList->Payload[i + 1] << 8 ); - newChannel.frequency |= ( (uint32_t) applyCFList->Payload[i + 2] << 16 ); - newChannel.frequency *= 100; - - // Initialize alternative frequency to 0 - newChannel.rx1_frequency = 0; - } - else - { - newChannel.frequency = 0; - newChannel.dr_range.value = 0; - newChannel.rx1_frequency = 0; - } - - if( newChannel.frequency != 0 ) - { - channelAdd.NewChannel = &newChannel; - channelAdd.ChannelId = chanIdx; - - // Try to add all channels - add_channel( &channelAdd ); - } - else - { - channelRemove.ChannelId = chanIdx; - - remove_channel( &channelRemove ); - } - } -} - -bool LoRaPHYKR920::set_channel_mask(ChanMaskSetParams_t* chanMaskSet) -{ - switch( chanMaskSet->ChannelsMaskType ) - { - case CHANNELS_MASK: - { - copy_channel_mask( ChannelsMask, chanMaskSet->ChannelsMaskIn, 1 ); - break; - } - case CHANNELS_DEFAULT_MASK: - { - copy_channel_mask( ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 1 ); - break; - } - default: - return false; - } - return true; -} - -bool LoRaPHYKR920::get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut, - int8_t* txPowOut, uint32_t* adrAckCounter) -{ - bool adrAckReq = false; - int8_t datarate = adrNext->Datarate; - int8_t txPower = adrNext->TxPower; - GetPhyParams_t getPhy; - PhyParam_t phyParam; - - // Report back the adr ack counter - *adrAckCounter = adrNext->AdrAckCounter; - - if( adrNext->AdrEnabled == true ) - { - if( datarate == KR920_TX_MIN_DATARATE ) - { - *adrAckCounter = 0; - adrAckReq = false; - } - else - { - if( adrNext->AdrAckCounter >= KR920_ADR_ACK_LIMIT ) - { - adrAckReq = true; - txPower = KR920_MAX_TX_POWER; - } - else - { - adrAckReq = false; - } - if( adrNext->AdrAckCounter >= ( KR920_ADR_ACK_LIMIT + KR920_ADR_ACK_DELAY ) ) - { - if( ( adrNext->AdrAckCounter % KR920_ADR_ACK_DELAY ) == 1 ) - { - // Decrease the datarate - getPhy.Attribute = PHY_NEXT_LOWER_TX_DR; - getPhy.Datarate = datarate; - getPhy.UplinkDwellTime = adrNext->UplinkDwellTime; - phyParam = get_phy_params( &getPhy ); - datarate = phyParam.Value; - - if( datarate == KR920_TX_MIN_DATARATE ) - { - // We must set adrAckReq to false as soon as we reach the lowest datarate - adrAckReq = false; - if( adrNext->UpdateChanMask == true ) - { - // Re-enable default channels - ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); - } - } - } - } - } - } - - *drOut = datarate; - *txPowOut = txPower; - return adrAckReq; -} - -void LoRaPHYKR920::compute_rx_win_params(int8_t datarate, uint8_t minRxSymbols, - uint32_t rxError, - rx_config_params_t *rxConfigParams) -{ - double tSymbol = 0.0; - - // Get the datarate, perform a boundary check - rxConfigParams->datarate = MIN( datarate, KR920_RX_MAX_DATARATE ); - rxConfigParams->bandwidth = GetBandwidth( rxConfigParams->datarate ); - - tSymbol = compute_symb_timeout_lora( DataratesKR920[rxConfigParams->datarate], BandwidthsKR920[rxConfigParams->datarate] ); - - get_rx_window_params( tSymbol, minRxSymbols, rxError, RADIO_WAKEUP_TIME, &rxConfigParams->window_timeout, &rxConfigParams->window_offset ); -} - -bool LoRaPHYKR920::rx_config(rx_config_params_t* rxConfig, int8_t* datarate) -{ - int8_t dr = rxConfig->datarate; - uint8_t maxPayload = 0; - int8_t phyDr = 0; - uint32_t frequency = rxConfig->frequency; - - if( _radio->get_status() != RF_IDLE ) - { + if (_radio->check_rf_frequency(tmpFreq) == false) { + _radio->unlock(); return false; } - if( rxConfig->rx_slot == RX_SLOT_WIN_1 ) - { - // Apply window 1 frequency - frequency = Channels[rxConfig->channel].frequency; - // Apply the alternative RX 1 window frequency, if it is available - if( Channels[rxConfig->channel].rx1_frequency != 0 ) - { - frequency = Channels[rxConfig->channel].rx1_frequency; + _radio->unlock(); + + // Verify if the frequency is valid. The frequency must be in a specified + // range and can be set to specific values. + if ((tmpFreq >= 920900000) && (tmpFreq <=923300000)) { + // Range ok, check for specific value + tmpFreq -= 920900000; + if ((tmpFreq % 200000) == 0) { + return true; } } - // Read the physical datarate from the datarates table - phyDr = DataratesKR920[dr]; - - _radio->set_channel( frequency ); - - // Radio configuration - _radio->set_rx_config( MODEM_LORA, rxConfig->bandwidth, phyDr, 1, 0, 8, - rxConfig->window_timeout, false, 0, false, 0, 0, true, - rxConfig->is_rx_continuous ); - maxPayload = MaxPayloadOfDatarateKR920[dr]; - _radio->set_max_payload_length( MODEM_LORA, maxPayload + LORA_MAC_FRMPAYLOAD_OVERHEAD ); - - *datarate = (uint8_t) dr; - return true; + return false; } -bool LoRaPHYKR920::tx_config(TxConfigParams_t* txConfig, int8_t* txPower, lorawan_time_t* txTimeOnAir) +bool LoRaPHYKR920::tx_config(tx_config_params_t* config, int8_t* tx_power, + lorawan_time_t* tx_toa) { - int8_t phyDr = DataratesKR920[txConfig->Datarate]; - int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, Bands[Channels[txConfig->Channel].band].max_tx_pwr, txConfig->Datarate, ChannelsMask ); - uint32_t bandwidth = GetBandwidth( txConfig->Datarate ); - float maxEIRP = GetMaxEIRP( Channels[txConfig->Channel].frequency ); - int8_t phyTxPower = 0; + int8_t phy_dr = datarates_KR920[config->datarate]; - // Take the minimum between the maxEIRP and txConfig->MaxEirp. + if (config->tx_power > bands[channels[config->channel].band].max_tx_pwr) { + config->tx_power = bands[channels[config->channel].band].max_tx_pwr; + } + + uint32_t bandwidth = get_bandwidth(config->datarate); + float max_eirp = get_max_eirp(channels[config->channel].frequency); + int8_t phy_tx_power = 0; + + // Take the minimum between the max_eirp and txConfig->MaxEirp. // The value of txConfig->MaxEirp could have changed during runtime, e.g. due to a MAC command. - maxEIRP = MIN( txConfig->MaxEirp, maxEIRP ); + max_eirp = MIN(config->max_eirp, max_eirp); // Calculate physical TX power - phyTxPower = compute_tx_power( txPowerLimited, maxEIRP, txConfig->AntennaGain ); + phy_tx_power = compute_tx_power(config->tx_power, max_eirp, config->antenna_gain); // Setup the radio frequency - _radio->set_channel( Channels[txConfig->Channel].frequency ); + _radio->lock(); - _radio->set_tx_config( MODEM_LORA, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 3000 ); + _radio->set_channel(channels[config->channel].frequency); + + _radio->set_tx_config(MODEM_LORA, phy_tx_power, 0, bandwidth, phy_dr, 1, 8, + false, true, 0, 0, false, 3000 ); // Setup maximum payload lenght of the radio driver - _radio->set_max_payload_length( MODEM_LORA, txConfig->PktLen ); + _radio->set_max_payload_length(MODEM_LORA, config->pkt_len); // Get the time-on-air of the next tx frame - *txTimeOnAir =_radio->time_on_air( MODEM_LORA, txConfig->PktLen ); + *tx_toa =_radio->time_on_air(MODEM_LORA, config->pkt_len); - *txPower = txPowerLimited; + _radio->unlock(); + + *tx_power = config->tx_power; return true; } -uint8_t LoRaPHYKR920::link_ADR_request(LinkAdrReqParams_t* linkAdrReq, - int8_t* drOut, int8_t* txPowOut, - uint8_t* nbRepOut, uint8_t* nbBytesParsed) -{ - uint8_t status = 0x07; - RegionCommonLinkAdrParams_t linkAdrParams; - uint8_t nextIndex = 0; - uint8_t bytesProcessed = 0; - uint16_t chMask = 0; - GetPhyParams_t getPhy; - PhyParam_t phyParam; - RegionCommonLinkAdrReqVerifyParams_t linkAdrVerifyParams; - - while( bytesProcessed < linkAdrReq->PayloadSize ) - { - // Get ADR request parameters - nextIndex = parse_link_ADR_req( &( linkAdrReq->Payload[bytesProcessed] ), &linkAdrParams ); - - if( nextIndex == 0 ) - break; // break loop, since no more request has been found - - // Update bytes processed - bytesProcessed += nextIndex; - - // Revert status, as we only check the last ADR request for the channel mask KO - status = 0x07; - - // Setup temporary channels mask - chMask = linkAdrParams.ChMask; - - // Verify channels mask - if( ( linkAdrParams.ChMaskCtrl == 0 ) && ( chMask == 0 ) ) - { - status &= 0xFE; // Channel mask KO - } - else if( ( ( linkAdrParams.ChMaskCtrl >= 1 ) && ( linkAdrParams.ChMaskCtrl <= 5 )) || - ( linkAdrParams.ChMaskCtrl >= 7 ) ) - { - // RFU - status &= 0xFE; // Channel mask KO - } - else - { - for( uint8_t i = 0; i < KR920_MAX_NB_CHANNELS; i++ ) - { - if( linkAdrParams.ChMaskCtrl == 6 ) - { - if( Channels[i].frequency != 0 ) - { - chMask |= 1 << i; - } - } - else - { - if( ( ( chMask & ( 1 << i ) ) != 0 ) && - ( Channels[i].frequency == 0 ) ) - {// Trying to enable an undefined channel - status &= 0xFE; // Channel mask KO - } - } - } - } - } - - // Get the minimum possible datarate - getPhy.Attribute = PHY_MIN_TX_DR; - getPhy.UplinkDwellTime = linkAdrReq->UplinkDwellTime; - phyParam = get_phy_params( &getPhy ); - - linkAdrVerifyParams.Status = status; - linkAdrVerifyParams.AdrEnabled = linkAdrReq->AdrEnabled; - linkAdrVerifyParams.Datarate = linkAdrParams.Datarate; - linkAdrVerifyParams.TxPower = linkAdrParams.TxPower; - linkAdrVerifyParams.NbRep = linkAdrParams.NbRep; - linkAdrVerifyParams.CurrentDatarate = linkAdrReq->CurrentDatarate; - linkAdrVerifyParams.CurrentTxPower = linkAdrReq->CurrentTxPower; - linkAdrVerifyParams.CurrentNbRep = linkAdrReq->CurrentNbRep; - linkAdrVerifyParams.NbChannels = KR920_MAX_NB_CHANNELS; - linkAdrVerifyParams.ChannelsMask = &chMask; - linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value; - linkAdrVerifyParams.MaxDatarate = KR920_TX_MAX_DATARATE; - linkAdrVerifyParams.Channels = Channels; - linkAdrVerifyParams.MinTxPower = KR920_MIN_TX_POWER; - linkAdrVerifyParams.MaxTxPower = KR920_MAX_TX_POWER; - - // Verify the parameters and update, if necessary - status = verify_link_ADR_req( &linkAdrVerifyParams, &linkAdrParams.Datarate, &linkAdrParams.TxPower, &linkAdrParams.NbRep ); - - // Update channelsMask if everything is correct - if( status == 0x07 ) - { - // Set the channels mask to a default value - memset( ChannelsMask, 0, sizeof( ChannelsMask ) ); - // Update the channels mask - ChannelsMask[0] = chMask; - } - - // Update status variables - *drOut = linkAdrParams.Datarate; - *txPowOut = linkAdrParams.TxPower; - *nbRepOut = linkAdrParams.NbRep; - *nbBytesParsed = bytesProcessed; - - return status; -} - -uint8_t LoRaPHYKR920::setup_rx_params(RxParamSetupReqParams_t* rxParamSetupReq) -{ - uint8_t status = 0x07; - - // Verify radio frequency - if(_radio->check_rf_frequency( rxParamSetupReq->Frequency ) == false ) - { - status &= 0xFE; // Channel frequency KO - } - - // Verify datarate - if( val_in_range( rxParamSetupReq->Datarate, KR920_RX_MIN_DATARATE, KR920_RX_MAX_DATARATE ) == 0 ) - { - status &= 0xFD; // Datarate KO - } - - // Verify datarate offset - if( val_in_range( rxParamSetupReq->DrOffset, KR920_MIN_RX1_DR_OFFSET, KR920_MAX_RX1_DR_OFFSET ) == 0 ) - { - status &= 0xFB; // Rx1DrOffset range KO - } - - return status; -} - -uint8_t LoRaPHYKR920::request_new_channel(NewChannelReqParams_t* newChannelReq) -{ - uint8_t status = 0x03; - ChannelAddParams_t channelAdd; - ChannelRemoveParams_t channelRemove; - - if( newChannelReq->NewChannel->frequency == 0 ) - { - channelRemove.ChannelId = newChannelReq->ChannelId; - - // Remove - if( remove_channel( &channelRemove ) == false ) - { - status &= 0xFC; - } - } - else - { - channelAdd.NewChannel = newChannelReq->NewChannel; - channelAdd.ChannelId = newChannelReq->ChannelId; - - switch( add_channel( &channelAdd ) ) - { - case LORAWAN_STATUS_OK: - { - break; - } - case LORAWAN_STATUS_FREQUENCY_INVALID: - { - status &= 0xFE; - break; - } - case LORAWAN_STATUS_DATARATE_INVALID: - { - status &= 0xFD; - break; - } - case LORAWAN_STATUS_FREQ_AND_DR_INVALID: - { - status &= 0xFC; - break; - } - default: - { - status &= 0xFC; - break; - } - } - } - - return status; -} - -int8_t LoRaPHYKR920::setup_tx_params(TxParamSetupReqParams_t* txParamSetupReq) -{ - return -1; -} - -uint8_t LoRaPHYKR920::dl_channel_request(DlChannelReqParams_t* dlChannelReq) -{ - uint8_t status = 0x03; - - // Verify if the frequency is supported - if( VerifyTxFreq( dlChannelReq->Rx1Frequency, _radio ) == false ) - { - status &= 0xFE; - } - - // Verify if an uplink frequency exists - if( Channels[dlChannelReq->ChannelId].frequency == 0 ) - { - status &= 0xFD; - } - - // Apply Rx1 frequency, if the status is OK - if( status == 0x03 ) - { - Channels[dlChannelReq->ChannelId].rx1_frequency = dlChannelReq->Rx1Frequency; - } - - return status; -} - -int8_t LoRaPHYKR920::get_alternate_DR(AlternateDrParams_t* alternateDr) -{ - int8_t datarate = 0; - - if( ( alternateDr->NbTrials % 48 ) == 0 ) - { - datarate = DR_0; - } - else if( ( alternateDr->NbTrials % 32 ) == 0 ) - { - datarate = DR_1; - } - else if( ( alternateDr->NbTrials % 24 ) == 0 ) - { - datarate = DR_2; - } - else if( ( alternateDr->NbTrials % 16 ) == 0 ) - { - datarate = DR_3; - } - else if( ( alternateDr->NbTrials % 8 ) == 0 ) - { - datarate = DR_4; - } - else - { - datarate = DR_5; - } - return datarate; -} - -void LoRaPHYKR920::calculate_backoff(CalcBackOffParams_t* calcBackOff) -{ - RegionCommonCalcBackOffParams_t calcBackOffParams; - - calcBackOffParams.Channels = Channels; - calcBackOffParams.Bands = Bands; - calcBackOffParams.LastTxIsJoinRequest = calcBackOff->LastTxIsJoinRequest; - calcBackOffParams.Joined = calcBackOff->Joined; - calcBackOffParams.DutyCycleEnabled = calcBackOff->DutyCycleEnabled; - calcBackOffParams.Channel = calcBackOff->Channel; - calcBackOffParams.ElapsedTime = calcBackOff->ElapsedTime; - calcBackOffParams.TxTimeOnAir = calcBackOff->TxTimeOnAir; - - get_DC_backoff( &calcBackOffParams ); -} - -bool LoRaPHYKR920::set_next_channel(NextChanParams_t* nextChanParams, +bool LoRaPHYKR920::set_next_channel(channel_selection_params_t* params, uint8_t* channel, lorawan_time_t* time, - lorawan_time_t* aggregatedTimeOff) + lorawan_time_t* aggregate_timeoff) { - uint8_t channelNext = 0; - uint8_t nbEnabledChannels = 0; - uint8_t delayTx = 0; - uint8_t enabledChannels[KR920_MAX_NB_CHANNELS] = { 0 }; + uint8_t next_channel_idx = 0; + uint8_t nb_enabled_channels = 0; + uint8_t delay_tx = 0; + uint8_t enabled_channels[KR920_MAX_NB_CHANNELS] = {0}; lorawan_time_t nextTxDelay = 0; - if( num_active_channels( ChannelsMask, 0, 1 ) == 0 ) - { // Reactivate default channels - ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); + if (num_active_channels(channel_masks, 0, 1) == 0) { + // Reactivate default channels + channel_masks[0] |= LC(1) + LC(2) + LC(3); } - if( nextChanParams->AggrTimeOff <= _lora_time.TimerGetElapsedTime( nextChanParams->LastAggrTx ) ) - { + if (params->aggregate_timeoff <= _lora_time.TimerGetElapsedTime(params->last_aggregate_tx_time)) { // Reset Aggregated time off - *aggregatedTimeOff = 0; + *aggregate_timeoff = 0; // Update bands Time OFF - nextTxDelay = update_band_timeoff( nextChanParams->Joined, nextChanParams->DutyCycleEnabled, Bands, KR920_MAX_NB_BANDS ); + nextTxDelay = update_band_timeoff(params->joined, params->dc_enabled, + bands, KR920_MAX_NB_BANDS); // Search how many channels are enabled - nbEnabledChannels = CountNbOfEnabledChannels( nextChanParams->Joined, nextChanParams->Datarate, - ChannelsMask, Channels, - Bands, enabledChannels, &delayTx ); - } - else - { - delayTx++; - nextTxDelay = nextChanParams->AggrTimeOff - _lora_time.TimerGetElapsedTime( nextChanParams->LastAggrTx ); + nb_enabled_channels = enabled_channel_count(params->joined, params->current_datarate, + channel_masks, KR920_CHANNELS_MASK_SIZE, + enabled_channels, &delay_tx); + } else { + delay_tx++; + nextTxDelay = params->aggregate_timeoff - _lora_time.TimerGetElapsedTime(params->last_aggregate_tx_time); } - if( nbEnabledChannels > 0 ) - { - for( uint8_t i = 0, j = get_random( 0, nbEnabledChannels - 1 ); i < KR920_MAX_NB_CHANNELS; i++ ) - { - channelNext = enabledChannels[j]; - j = ( j + 1 ) % nbEnabledChannels; + if (nb_enabled_channels > 0) { + + for (uint8_t i = 0, j = get_random(0, nb_enabled_channels - 1); + i < KR920_MAX_NB_CHANNELS; i++) { + next_channel_idx = enabled_channels[j]; + j = ( j + 1 ) % nb_enabled_channels; // Perform carrier sense for KR920_CARRIER_SENSE_TIME // If the channel is free, we can stop the LBT mechanism - if( _radio->perform_carrier_sense( MODEM_LORA, - Channels[channelNext].frequency, - KR920_RSSI_FREE_TH, - KR920_CARRIER_SENSE_TIME ) == true ) - { + _radio->lock(); + + if (_radio->perform_carrier_sense(MODEM_LORA, + channels[next_channel_idx].frequency, + KR920_RSSI_FREE_TH, + KR920_CARRIER_SENSE_TIME ) == true) { // Free channel found - *channel = channelNext; + *channel = next_channel_idx; *time = 0; + _radio->unlock(); return true; } + + _radio->unlock(); } + return false; - } - else - { - if( delayTx > 0 ) - { + + } else { + + if (delay_tx > 0) { // Delay transmission due to AggregatedTimeOff or to a band time off *time = nextTxDelay; return true; } + // Datarate not supported by any channel, restore defaults - ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); + channel_masks[0] |= LC(1) + LC(2) + LC(3); *time = 0; return false; } } -lorawan_status_t LoRaPHYKR920::add_channel(ChannelAddParams_t* channelAdd) +void LoRaPHYKR920::set_tx_cont_mode(cw_mode_params_t* params, uint32_t given_frequency) { - uint8_t band = 0; - bool drInvalid = false; - bool freqInvalid = false; - uint8_t id = channelAdd->ChannelId; + (void)given_frequency; - if( id >= KR920_MAX_NB_CHANNELS ) - { - return LORAWAN_STATUS_PARAMETER_INVALID; + if (params->tx_power > bands[channels[params->channel].band].max_tx_pwr) { + params->tx_power = bands[channels[params->channel].band].max_tx_pwr; } - // Validate the datarate range - if( val_in_range( channelAdd->NewChannel->dr_range.fields.min, KR920_TX_MIN_DATARATE, KR920_TX_MAX_DATARATE ) == 0 ) - { - drInvalid = true; - } - if( val_in_range( channelAdd->NewChannel->dr_range.fields.max, KR920_TX_MIN_DATARATE, KR920_TX_MAX_DATARATE ) == 0 ) - { - drInvalid = true; - } - if( channelAdd->NewChannel->dr_range.fields.min > channelAdd->NewChannel->dr_range.fields.max ) - { - drInvalid = true; - } + float max_eirp = get_max_eirp(channels[params->channel].frequency); + int8_t phy_tx_power = 0; + uint32_t frequency = channels[params->channel].frequency; - // Default channels don't accept all values - if( id < KR920_NUMB_DEFAULT_CHANNELS ) - { - // All datarates are supported - // We are not allowed to change the frequency - if( channelAdd->NewChannel->frequency != Channels[id].frequency ) - { - freqInvalid = true; - } - } - - // Check frequency - if( freqInvalid == false ) - { - if( VerifyTxFreq( channelAdd->NewChannel->frequency, _radio ) == false ) - { - freqInvalid = true; - } - } - - // Check status - if( ( drInvalid == true ) && ( freqInvalid == true ) ) - { - return LORAWAN_STATUS_FREQ_AND_DR_INVALID; - } - if( drInvalid == true ) - { - return LORAWAN_STATUS_DATARATE_INVALID; - } - if( freqInvalid == true ) - { - return LORAWAN_STATUS_FREQUENCY_INVALID; - } - - memcpy( &(Channels[id]), channelAdd->NewChannel, sizeof( Channels[id] ) ); - Channels[id].band = band; - ChannelsMask[0] |= ( 1 << id ); - return LORAWAN_STATUS_OK; -} - -bool LoRaPHYKR920::remove_channel(ChannelRemoveParams_t* channelRemove) -{ - uint8_t id = channelRemove->ChannelId; - - if( id < KR920_NUMB_DEFAULT_CHANNELS ) - { - return false; - } - - // Remove the channel from the list of channels - const channel_params_t empty_channel = { 0, 0, { 0 }, 0 }; - Channels[id] = empty_channel; - - return disable_channel( ChannelsMask, id, KR920_MAX_NB_CHANNELS ); -} - -void LoRaPHYKR920::set_tx_cont_mode(ContinuousWaveParams_t* continuousWave) -{ - int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, Bands[Channels[continuousWave->Channel].band].max_tx_pwr, continuousWave->Datarate, ChannelsMask ); - float maxEIRP = GetMaxEIRP( Channels[continuousWave->Channel].frequency ); - int8_t phyTxPower = 0; - uint32_t frequency = Channels[continuousWave->Channel].frequency; - - // Take the minimum between the maxEIRP and continuousWave->MaxEirp. - // The value of continuousWave->MaxEirp could have changed during runtime, e.g. due to a MAC command. - maxEIRP = MIN( continuousWave->MaxEirp, maxEIRP ); + // Take the minimum between the max_eirp and params->max_eirp. + // The value of params->max_eirp could have changed during runtime, + // e.g. due to a MAC command. + max_eirp = MIN (params->max_eirp, max_eirp); // Calculate physical TX power - phyTxPower = compute_tx_power( txPowerLimited, maxEIRP, continuousWave->AntennaGain ); + phy_tx_power = compute_tx_power(params->tx_power, max_eirp, params->antenna_gain); - _radio->set_tx_continuous_wave( frequency, phyTxPower, continuousWave->Timeout ); + _radio->lock(); + _radio->set_tx_continuous_wave(frequency, phy_tx_power, params->timeout); + _radio->unlock(); } -uint8_t LoRaPHYKR920::apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset) -{ - int8_t datarate = dr - drOffset; - - if( datarate < 0 ) - { - datarate = DR_0; - } - return datarate; -} diff --git a/features/lorawan/lorastack/phy/LoRaPHYKR920.h b/features/lorawan/lorastack/phy/LoRaPHYKR920.h index 428df3989a..cbaa9779d0 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYKR920.h +++ b/features/lorawan/lorastack/phy/LoRaPHYKR920.h @@ -33,7 +33,6 @@ #define MBED_OS_LORAPHY_KR920_H_ #include "LoRaPHY.h" -#include "netsocket/LoRaRadio.h" /*! * LoRaMac maximum number of channels @@ -55,304 +54,42 @@ public: LoRaPHYKR920(LoRaWANTimeHandler &lora_time); virtual ~LoRaPHYKR920(); - /*! - * \brief The function gets a value of a specific PHY attribute. - * - * \param [in] getPhy A pointer to the function parameters. - * - * \retval The structure containing the PHY parameter. - */ - virtual PhyParam_t get_phy_params(GetPhyParams_t* getPhy ); + virtual bool verify_frequency(uint32_t freq); - /*! - * \brief Updates the last TX done parameters of the current channel. - * - * \param [in] txDone A pointer to the function parameters. - */ - virtual void set_band_tx_done(SetBandTxDoneParams_t* txDone ); + virtual bool tx_config(tx_config_params_t* config, int8_t* tx_power, + lorawan_time_t* tx_toa); - /*! - * \brief Initializes the channels masks and the channels. - * - * \param [in] type Sets the initialization type. - */ - virtual void load_defaults(InitType_t type ); + virtual bool set_next_channel(channel_selection_params_t* params, uint8_t* channel, + lorawan_time_t* time, + lorawan_time_t* aggregate_timeOff); - /*! - * \brief Verifies a parameter. - * - * \param [in] verify A pointer to the function parameters. - * - * \param [in] phyAttribute The attribute to verify. - * - * \retval True, if the parameter is valid. - */ - virtual bool verify(VerifyParams_t* verify, PhyAttribute_t phyAttribute ); + virtual void set_tx_cont_mode(cw_mode_params_t* continuousWave, + uint32_t frequency = 0); - /*! - * \brief The function parses the input buffer and sets up the channels of the CF list. - * - * \param [in] applyCFList A pointer to the function parameters. - */ - virtual void apply_cf_list(ApplyCFListParams_t* applyCFList ); - /*! - * \brief Sets a channels mask. - * - * \param [in] chanMaskSet A pointer to the function parameters. - * - * \retval True, if the channels mask could be set. - */ - virtual bool set_channel_mask(ChanMaskSetParams_t* chanMaskSet ); +private: - /*! - * \brief Calculates the next datarate to set, when ADR is on or off. - * - * \param [in] adrNext A pointer to the function parameters. - * - * \param [out] drOut The calculated datarate for the next TX. - * - * \param [out] txPowOut The TX power for the next TX. - * - * \param [out] adrAckCounter The calculated ADR acknowledgement counter. - * - * \retval True, if an ADR request should be performed. - */ - virtual bool get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut, - int8_t* txPowOut, uint32_t* adrAckCounter ); + int8_t get_max_eirp(uint32_t freq); - /*! - * \brief Configuration of the RX windows. - * - * \param [in] rxConfig A pointer to the function parameters. - * - * \param [out] datarate The datarate index set. - * - * \retval True, if the configuration was applied successfully. - */ - virtual bool rx_config(rx_config_params_t* rxConfig, int8_t* datarate ); - - /* - * RX window precise timing - * - * For more details, please consult the following document, chapter 3.1.2. - * http://www.semtech.com/images/datasheet/SX1272_settings_for_LoRaWAN_v2.0.pdf - * or - * http://www.semtech.com/images/datasheet/SX1276_settings_for_LoRaWAN_v2.0.pdf - * - * Downlink start: T = Tx + 1s (+/- 20 us) - * | - * TRxEarly | TRxLate - * | | | - * | | +---+---+---+---+---+---+---+---+ - * | | | Latest Rx window | - * | | +---+---+---+---+---+---+---+---+ - * | | | - * +---+---+---+---+---+---+---+---+ - * | Earliest Rx window | - * +---+---+---+---+---+---+---+---+ - * | - * +---+---+---+---+---+---+---+---+ - *Downlink preamble 8 symbols | | | | | | | | | - * +---+---+---+---+---+---+---+---+ - * - * Worst case Rx window timings - * - * TRxLate = DEFAULT_MIN_RX_SYMBOLS * tSymbol - RADIO_WAKEUP_TIME - * TRxEarly = 8 - DEFAULT_MIN_RX_SYMBOLS * tSymbol - RxWindowTimeout - RADIO_WAKEUP_TIME - * - * TRxLate - TRxEarly = 2 * DEFAULT_SYSTEM_MAX_RX_ERROR - * - * RxOffset = ( TRxLate + TRxEarly ) / 2 - * - * RxWindowTimeout = ( 2 * DEFAULT_MIN_RX_SYMBOLS - 8 ) * tSymbol + 2 * DEFAULT_SYSTEM_MAX_RX_ERROR - * RxOffset = 4 * tSymbol - RxWindowTimeout / 2 - RADIO_WAKE_UP_TIME - * - * The minimum value of RxWindowTimeout must be 5 symbols which implies that the system always tolerates at least an error of 1.5 * tSymbol - */ - /*! - * Computes the RX window timeout and offset. - * - * \param [in] datarate The RX window datarate index to be used. - * - * \param [in] minRxSymbols The minimum number of symbols required to detect an RX frame. - * - * \param [in] rxError The system maximum timing error of the receiver in milliseconds. - * The receiver will turn on in a [-rxError : +rxError] ms - * interval around RxOffset. - * - * \param [out] rxConfigParams Returns the updated WindowTimeout and WindowOffset fields. - */ - virtual void compute_rx_win_params(int8_t datarate, - uint8_t minRxSymbols, - uint32_t rxError, - rx_config_params_t *rxConfigParams); - - /*! - * \brief TX configuration. - * - * \param [in] txConfig A pointer to the function parameters. - * - * \param [out] txPower The TX power index set. - * - * \param [out] txTimeOnAir The time-on-air of the frame. - * - * \retval True, if the configuration was applied successfully. - */ - virtual bool tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - lorawan_time_t* txTimeOnAir ); - - /*! - * \brief The function processes a Link ADR request. - * - * \param [in] linkAdrReq A pointer to the function parameters. - * - * \param [out] drOut The datarate applied. - * - * \param [out] txPowOut The TX power applied. - * - * \param [out] nbRepOut The number of repetitions to apply. - * - * \param [out] nbBytesParsed The number of bytes parsed. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t link_ADR_request(LinkAdrReqParams_t* linkAdrReq, - int8_t* drOut, int8_t* txPowOut, - uint8_t* nbRepOut, - uint8_t* nbBytesParsed ); - - /*! - * \brief The function processes a RX parameter setup request. - * - * \param [in] rxParamSetupReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t setup_rx_params(RxParamSetupReqParams_t* rxParamSetupReq ); - - /*! - * \brief The function processes a new channel request. - * - * \param [in] newChannelReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t request_new_channel(NewChannelReqParams_t* newChannelReq ); - - /*! - * \brief The function processes a TX ParamSetup request. - * - * \param [in] txParamSetupReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - * Returns -1, if the functionality is not implemented. In this case, the end node - * shall ignore the command. - */ - virtual int8_t setup_tx_params(TxParamSetupReqParams_t* txParamSetupReq ); - - /*! - * \brief The function processes a DlChannel request. - * - * \param [in] dlChannelReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t dl_channel_request(DlChannelReqParams_t* dlChannelReq ); - - /*! - * \brief Alternates the datarate of the channel for the join request. - * - * \param [in] alternateDr A pointer to the function parameters. - * - * \retval The datarate to apply. - */ - virtual int8_t get_alternate_DR(AlternateDrParams_t* alternateDr ); - - /*! - * \brief Calculates the back-off time. - * - * \param [in] calcBackOff A pointer to the function parameters. - */ - virtual void calculate_backoff(CalcBackOffParams_t* calcBackOff ); - - /*! - * \brief Searches and sets the next random available channel. - * - * \param [in] nextChanParams The parameters for the next channel. - * - * \param [out] channel The next channel to use for TX. - * - * \param [out] time The time to wait for the next transmission according to the duty cycle. - * - * \param [out] aggregatedTimeOff Updates the aggregated time off. - * - * \retval The function status [1: OK, 0: Unable to find a channel on the current datarate]. - */ - virtual bool set_next_channel(NextChanParams_t* nextChanParams, - uint8_t* channel, lorawan_time_t* time, - lorawan_time_t* aggregatedTimeOff ); - - /*! - * \brief Adds a channel. - * - * \param [in] channelAdd A pointer to the function parameters. - * - * \retval The status of the operation. - */ - virtual lorawan_status_t add_channel(ChannelAddParams_t* channelAdd ); - - /*! - * \brief Removes a channel. - * - * \param [in] channelRemove A pointer to the function parameters. - * - * \retval True, if the channel was removed successfully. - */ - virtual bool remove_channel(ChannelRemoveParams_t* channelRemove ); - - /*! - * \brief Sets the radio into continuous wave mode. - * - * \param [in] continuousWave A pointer to the function parameters. - */ - virtual void set_tx_cont_mode(ContinuousWaveParams_t* continuousWave ); - - /*! - * \brief Computes new datarate according to the given offset. - * - * \param [in] downlinkDwellTime The downlink dwell time configuration. 0: No limit, 1: 400ms - * - * \param [in] dr The current datarate. - * - * \param [in] drOffset The offset to be applied. - * - * \retval newDr The computed datarate. - */ - virtual uint8_t apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ); - - uint8_t CountNbOfEnabledChannels( bool joined, uint8_t datarate, uint16_t* channelsMask, channel_params_t* channels, band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ); - - // Global attributes - /*! + /** * LoRaMAC channels */ - channel_params_t Channels[KR920_MAX_NB_CHANNELS]; + channel_params_t channels[KR920_MAX_NB_CHANNELS]; - /*! + /** * LoRaMac bands */ - band_t Bands[KR920_MAX_NB_BANDS]; + band_t bands[KR920_MAX_NB_BANDS]; - /*! + /** * LoRaMac channels mask */ - uint16_t ChannelsMask[KR920_CHANNELS_MASK_SIZE]; + uint16_t channel_masks[KR920_CHANNELS_MASK_SIZE]; - /*! + /** * LoRaMac channels default mask */ - uint16_t ChannelsDefaultMask[KR920_CHANNELS_MASK_SIZE]; + uint16_t default_channel_masks[KR920_CHANNELS_MASK_SIZE]; }; #endif // MBED_OS_LORAPHY_KR920_H_ diff --git a/features/lorawan/lorastack/phy/LoRaPHYUS915.cpp b/features/lorawan/lorastack/phy/LoRaPHYUS915.cpp index af4859ff99..b7cd0b862e 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYUS915.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYUS915.cpp @@ -31,7 +31,6 @@ #include "LoRaPHYUS915.h" #include "lora_phy_ds.h" -#include "LoRaRadio.h" /*! @@ -163,7 +162,7 @@ * Band 0 definition * { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff } */ -#define US915_BAND0 { 1, US915_MAX_TX_POWER, 0, 0, 0 } // 100.0 % +static const band_t US915_BAND0 = { 1, US915_MAX_TX_POWER, 0, 0, 0 }; // 100.0 % /*! * Defines the first channel for RX window 1 for US band @@ -183,17 +182,17 @@ /*! * Data rates table definition */ -static const uint8_t DataratesUS915[] = { 10, 9, 8, 7, 8, 0, 0, 0, 12, 11, 10, 9, 8, 7, 0, 0 }; +static const uint8_t datarates_US915[] = {10, 9, 8, 7, 8, 0, 0, 0, 12, 11, 10, 9, 8, 7, 0, 0}; /*! * Bandwidths table definition in Hz */ -static const uint32_t BandwidthsUS915[] = { 125000, 125000, 125000, 125000, 500000, 0, 0, 0, 500000, 500000, 500000, 500000, 500000, 500000, 0, 0 }; +static const uint32_t bandwidths_US915[] = {125000, 125000, 125000, 125000, 500000, 0, 0, 0, 500000, 500000, 500000, 500000, 500000, 500000, 0, 0}; /*! * Up/Down link data rates offset definition */ -static const int8_t DatarateOffsetsUS915[5][4] = +static const int8_t datarate_offsets_US915[5][4] = { { DR_10, DR_9 , DR_8 , DR_8 }, // DR_0 { DR_11, DR_10, DR_9 , DR_8 }, // DR_1 @@ -205,681 +204,384 @@ static const int8_t DatarateOffsetsUS915[5][4] = /*! * Maximum payload with respect to the datarate index. Cannot operate with repeater. */ -static const uint8_t MaxPayloadOfDatarateUS915[] = { 11, 53, 125, 242, 242, 0, 0, 0, 53, 129, 242, 242, 242, 242, 0, 0 }; +static const uint8_t max_payloads_US915[] = { 11, 53, 125, 242, 242, 0, 0, 0, 53, 129, 242, 242, 242, 242, 0, 0 }; /*! * Maximum payload with respect to the datarate index. Can operate with repeater. */ -static const uint8_t MaxPayloadOfDatarateRepeaterUS915[] = { 11, 53, 125, 242, 242, 0, 0, 0, 33, 109, 222, 222, 222, 222, 0, 0 }; - - -// Static functions -static int8_t GetNextLowerTxDr( int8_t dr, int8_t minDr ) -{ - uint8_t nextLowerDr = 0; - - if( dr == minDr ) - { - nextLowerDr = minDr; - } - else - { - nextLowerDr = dr - 1; - } - return nextLowerDr; -} - -static uint32_t GetBandwidth( uint32_t drIndex ) -{ - switch( BandwidthsUS915[drIndex] ) - { - default: - case 125000: - return 0; - case 250000: - return 1; - case 500000: - return 2; - } -} - -int8_t LoRaPHYUS915::LimitTxPower( int8_t txPower, int8_t maxBandTxPower, int8_t datarate, uint16_t* channelsMask ) -{ - int8_t txPowerResult = txPower; - - // Limit tx power to the band max - txPowerResult = MAX( txPower, maxBandTxPower ); - - if( datarate == DR_4 ) - {// Limit tx power to max 26dBm - txPowerResult = MAX( txPower, TX_POWER_2 ); - } - else - { - if( num_active_channels( channelsMask, 0, 4 ) < 50 ) - {// Limit tx power to max 21dBm - txPowerResult = MAX( txPower, TX_POWER_5 ); - } - } - return txPowerResult; -} - -uint8_t LoRaPHYUS915::CountNbOfEnabledChannels( uint8_t datarate, uint16_t* channelsMask, channel_params_t* channels, band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ) -{ - uint8_t nbEnabledChannels = 0; - uint8_t delayTransmission = 0; - - for( uint8_t i = 0, k = 0; i < US915_MAX_NB_CHANNELS; i += 16, k++ ) - { - for( uint8_t j = 0; j < 16; j++ ) - { - if( ( channelsMask[k] & ( 1 << j ) ) != 0 ) - { - if( channels[i + j].frequency == 0 ) - { // Check if the channel is enabled - continue; - } - if( val_in_range( datarate, channels[i + j].dr_range.fields.min, - channels[i + j].dr_range.fields.max ) == 0 ) - { // Check if the current channel selection supports the given datarate - continue; - } - if( bands[channels[i + j].band].off_time > 0 ) - { // Check if the band is available for transmission - delayTransmission++; - continue; - } - enabledChannels[nbEnabledChannels++] = i + j; - } - } - } - - *delayTx = delayTransmission; - return nbEnabledChannels; -} +static const uint8_t max_payloads_with_repeater_US915[] = {11, 53, 125, 242, 242, 0, 0, 0, 33, 109, 222, 222, 222, 222, 0, 0}; LoRaPHYUS915::LoRaPHYUS915(LoRaWANTimeHandler &lora_time) - : LoRaPHY(lora_time) + : LoRaPHY(lora_time) { - const band_t band0 = US915_BAND0; - Bands[0] = band0; + bands[0] = US915_BAND0; + + // Channels + // 125 kHz channels + for (uint8_t i = 0; i < US915_MAX_NB_CHANNELS - 8; i++) { + channels[i].frequency = 902300000 + i * 200000; + channels[i].dr_range.value = ( DR_3 << 4) | DR_0; + channels[i].band = 0; + } + // 500 kHz channels + for (uint8_t i = US915_MAX_NB_CHANNELS - 8; i < US915_MAX_NB_CHANNELS; i++) { + channels[i].frequency = 903000000 + (i - ( US915_MAX_NB_CHANNELS - 8)) * 1600000; + channels[i].dr_range.value = ( DR_4 << 4) | DR_4; + channels[i].band = 0; + } + + // ChannelsMask + default_channel_masks[0] = 0xFFFF; + default_channel_masks[1] = 0xFFFF; + default_channel_masks[2] = 0xFFFF; + default_channel_masks[3] = 0xFFFF; + default_channel_masks[4] = 0x00FF; + + memset(channel_masks, 0, sizeof(channel_masks)); + memset(current_channel_masks, 0, sizeof(current_channel_masks)); + + // Copy channels default mask + copy_channel_mask(channel_masks, default_channel_masks, US915_CHANNELS_MASK_SIZE); + + // current channel masks keep track what of the + // channels previously used, i.e., which channels should be avoided in + // next transmission + copy_channel_mask(current_channel_masks, channel_masks, US915_CHANNELS_MASK_SIZE); + + // set default channels + phy_params.channels.channel_list = channels; + phy_params.channels.channel_list_size = US915_MAX_NB_CHANNELS; + phy_params.channels.mask_list = channel_masks; + phy_params.channels.default_mask_list = default_channel_masks; + phy_params.channels.mask_list_size = US915_CHANNELS_MASK_SIZE; + + // set bands for US915 spectrum + phy_params.bands.table = (void *) bands; + phy_params.bands.size = US915_MAX_NB_BANDS; + + // set bandwidths available in US915 spectrum + phy_params.bandwidths.table = (void *) bandwidths_US915; + phy_params.bandwidths.size = 16; + + // set data rates available in US915 spectrum + phy_params.datarates.table = (void *) datarates_US915; + phy_params.datarates.size = 16; + + // set payload sizes with respect to data rates + phy_params.payloads.table = (void *) max_payloads_US915; + phy_params.payloads.size = 16; + phy_params.payloads_with_repeater.table = (void *) max_payloads_with_repeater_US915; + phy_params.payloads.size = 16; + + // dwell time setting + phy_params.ul_dwell_time_setting = 0; + phy_params.dl_dwell_time_setting = 0; + + // set initial and default parameters + phy_params.duty_cycle_enabled = US915_DUTY_CYCLE_ENABLED; + phy_params.accept_tx_param_setup_req = false; + phy_params.fsk_supported = false; + phy_params.cflist_supported = false; + phy_params.dl_channel_req_supported = false; + phy_params.custom_channelplans_supported = false; + phy_params.default_channel_cnt = US915_MAX_NB_CHANNELS; + phy_params.max_channel_cnt = US915_MAX_NB_CHANNELS; + phy_params.cflist_channel_cnt = 0; + phy_params.min_tx_datarate = US915_TX_MIN_DATARATE; + phy_params.max_tx_datarate = US915_TX_MAX_DATARATE; + phy_params.min_rx_datarate = US915_RX_MIN_DATARATE; + phy_params.max_rx_datarate = US915_RX_MAX_DATARATE; + phy_params.default_datarate = US915_DEFAULT_DATARATE; + phy_params.default_max_datarate = US915_TX_MAX_DATARATE; + phy_params.min_rx1_dr_offset = US915_MIN_RX1_DR_OFFSET; + phy_params.max_rx1_dr_offset = US915_MAX_RX1_DR_OFFSET; + phy_params.default_rx1_dr_offset = US915_DEFAULT_RX1_DR_OFFSET; + phy_params.min_tx_power = US915_MIN_TX_POWER; + phy_params.max_tx_power = US915_MAX_TX_POWER; + phy_params.default_tx_power = US915_DEFAULT_TX_POWER; + phy_params.default_max_eirp = 0; + phy_params.default_antenna_gain = 0; + phy_params.adr_ack_limit = US915_ADR_ACK_LIMIT; + phy_params.adr_ack_delay = US915_ADR_ACK_DELAY; + phy_params.max_rx_window = US915_MAX_RX_WINDOW; + phy_params.recv_delay1 = US915_RECEIVE_DELAY1; + phy_params.recv_delay2 = US915_RECEIVE_DELAY2; + + phy_params.join_accept_delay1 = US915_JOIN_ACCEPT_DELAY1; + phy_params.join_accept_delay2 = US915_JOIN_ACCEPT_DELAY2; + phy_params.max_fcnt_gap = US915_MAX_FCNT_GAP; + phy_params.ack_timeout = US915_ACKTIMEOUT; + phy_params.ack_timeout_rnd = US915_ACK_TIMEOUT_RND; + phy_params.rx_window2_datarate = US915_RX_WND_2_DR; + phy_params.rx_window2_frequency = US915_RX_WND_2_FREQ; } LoRaPHYUS915::~LoRaPHYUS915() { } -PhyParam_t LoRaPHYUS915::get_phy_params(GetPhyParams_t* getPhy) +int8_t LoRaPHYUS915::limit_tx_power(int8_t tx_power, int8_t max_band_tx_power, + int8_t datarate) { - PhyParam_t phyParam = { 0 }; + int8_t tx_power_out = tx_power; - switch( getPhy->Attribute ) - { - case PHY_MIN_RX_DR: - { - phyParam.Value = US915_RX_MIN_DATARATE; - break; - } - case PHY_MIN_TX_DR: - { - phyParam.Value = US915_TX_MIN_DATARATE; - break; - } - case PHY_DEF_TX_DR: - { - phyParam.Value = US915_DEFAULT_DATARATE; - break; - } - case PHY_NEXT_LOWER_TX_DR: - { - phyParam.Value = GetNextLowerTxDr( getPhy->Datarate, US915_TX_MIN_DATARATE ); - break; - } - case PHY_DEF_TX_POWER: - { - phyParam.Value = US915_DEFAULT_TX_POWER; - break; - } - case PHY_MAX_PAYLOAD: - { - phyParam.Value = MaxPayloadOfDatarateUS915[getPhy->Datarate]; - break; - } - case PHY_MAX_PAYLOAD_REPEATER: - { - phyParam.Value = MaxPayloadOfDatarateRepeaterUS915[getPhy->Datarate]; - break; - } - case PHY_DUTY_CYCLE: - { - phyParam.Value = US915_DUTY_CYCLE_ENABLED; - break; - } - case PHY_MAX_RX_WINDOW: - { - phyParam.Value = US915_MAX_RX_WINDOW; - break; - } - case PHY_RECEIVE_DELAY1: - { - phyParam.Value = US915_RECEIVE_DELAY1; - break; - } - case PHY_RECEIVE_DELAY2: - { - phyParam.Value = US915_RECEIVE_DELAY2; - break; - } - case PHY_JOIN_ACCEPT_DELAY1: - { - phyParam.Value = US915_JOIN_ACCEPT_DELAY1; - break; - } - case PHY_JOIN_ACCEPT_DELAY2: - { - phyParam.Value = US915_JOIN_ACCEPT_DELAY2; - break; - } - case PHY_MAX_FCNT_GAP: - { - phyParam.Value = US915_MAX_FCNT_GAP; - break; - } - case PHY_ACK_TIMEOUT: - { - phyParam.Value = ( US915_ACKTIMEOUT + get_random( -US915_ACK_TIMEOUT_RND, US915_ACK_TIMEOUT_RND ) ); - break; - } - case PHY_DEF_DR1_OFFSET: - { - phyParam.Value = US915_DEFAULT_RX1_DR_OFFSET; - break; - } - case PHY_DEF_RX2_FREQUENCY: - { - phyParam.Value = US915_RX_WND_2_FREQ; - break; - } - case PHY_DEF_RX2_DR: - { - phyParam.Value = US915_RX_WND_2_DR; - break; - } - case PHY_CHANNELS_MASK: - { - phyParam.ChannelsMask = ChannelsMask; - break; - } - case PHY_CHANNELS_DEFAULT_MASK: - { - phyParam.ChannelsMask = ChannelsDefaultMask; - break; - } - case PHY_MAX_NB_CHANNELS: - { - phyParam.Value = US915_MAX_NB_CHANNELS; - break; - } - case PHY_CHANNELS: - { - phyParam.Channels = Channels; - break; - } - case PHY_DEF_UPLINK_DWELL_TIME: - case PHY_DEF_DOWNLINK_DWELL_TIME: - { - phyParam.Value = 0; - break; - } - case PHY_DEF_MAX_EIRP: - case PHY_DEF_ANTENNA_GAIN: - { - phyParam.fValue = 0; - break; - } - case PHY_NB_JOIN_TRIALS: - case PHY_DEF_NB_JOIN_TRIALS: - { - phyParam.Value = 2; - break; - } - default: - { - break; + // Limit tx power to the band max + tx_power_out = MAX (tx_power, max_band_tx_power); + + if (datarate == DR_4) { + // Limit tx power to max 26dBm + tx_power_out = MAX (tx_power, TX_POWER_2); + } else { + + if (num_active_channels(channel_masks, 0, 4) < 50) { + // Limit tx power to max 21dBm + tx_power_out = MAX (tx_power, TX_POWER_5); } } - return phyParam; + return tx_power_out; } -void LoRaPHYUS915::set_band_tx_done(SetBandTxDoneParams_t* txDone) +void LoRaPHYUS915::restore_default_channels() { - set_last_tx_done( txDone->Joined, &Bands[Channels[txDone->Channel].band], txDone->LastTxDoneTime ); -} + // Copy channels default mask + copy_channel_mask(channel_masks, default_channel_masks, US915_CHANNELS_MASK_SIZE); -void LoRaPHYUS915::load_defaults(InitType_t type) -{ - switch( type ) - { - case INIT_TYPE_INIT: - { - // Channels - // 125 kHz channels - for( uint8_t i = 0; i < US915_MAX_NB_CHANNELS - 8; i++ ) - { - Channels[i].frequency = 902300000 + i * 200000; - Channels[i].dr_range.value = ( DR_3 << 4 ) | DR_0; - Channels[i].band = 0; - } - // 500 kHz channels - for( uint8_t i = US915_MAX_NB_CHANNELS - 8; i < US915_MAX_NB_CHANNELS; i++ ) - { - Channels[i].frequency = 903000000 + ( i - ( US915_MAX_NB_CHANNELS - 8 ) ) * 1600000; - Channels[i].dr_range.value = ( DR_4 << 4 ) | DR_4; - Channels[i].band = 0; - } - - // ChannelsMask - ChannelsDefaultMask[0] = 0xFFFF; - ChannelsDefaultMask[1] = 0xFFFF; - ChannelsDefaultMask[2] = 0xFFFF; - ChannelsDefaultMask[3] = 0xFFFF; - ChannelsDefaultMask[4] = 0x00FF; - ChannelsDefaultMask[5] = 0x0000; - - // Copy channels default mask - copy_channel_mask( ChannelsMask, ChannelsDefaultMask, 6 ); - - // Copy into channels mask remaining - copy_channel_mask( ChannelsMaskRemaining, ChannelsMask, 6 ); - break; - } - case INIT_TYPE_RESTORE: - { - // Copy channels default mask - copy_channel_mask( ChannelsMask, ChannelsDefaultMask, 6 ); - - for( uint8_t i = 0; i < 6; i++ ) - { // Copy-And the channels mask - ChannelsMaskRemaining[i] &= ChannelsMask[i]; - } - break; - } - default: - { - break; - } + for ( uint8_t i = 0; i < US915_CHANNELS_MASK_SIZE; i++ ) { + // Copy-And the channels mask + current_channel_masks[i] &= channel_masks[i]; } } -bool LoRaPHYUS915::verify(VerifyParams_t* verify, PhyAttribute_t phyAttribute) +bool LoRaPHYUS915::rx_config(rx_config_params_t* config, int8_t* datarate) { - switch( phyAttribute ) - { - case PHY_TX_DR: - { - return val_in_range( verify->DatarateParams.Datarate, US915_TX_MIN_DATARATE, US915_TX_MAX_DATARATE ); - } - case PHY_DEF_TX_DR: - { - return val_in_range( verify->DatarateParams.Datarate, DR_0, DR_5 ); - } - case PHY_RX_DR: - { - return val_in_range( verify->DatarateParams.Datarate, US915_RX_MIN_DATARATE, US915_RX_MAX_DATARATE ); - } - case PHY_DEF_TX_POWER: - case PHY_TX_POWER: - { - // Remark: switched min and max! - return val_in_range( verify->TxPower, US915_MAX_TX_POWER, US915_MIN_TX_POWER ); - } - case PHY_DUTY_CYCLE: - { - return US915_DUTY_CYCLE_ENABLED; - } - case PHY_NB_JOIN_TRIALS: - { - if( verify->NbJoinTrials < 2 ) - { - return false; - } - break; - } - default: - return false; - } - return true; -} + int8_t dr = config->datarate; + uint8_t max_payload = 0; + int8_t phy_dr = 0; + uint32_t frequency = config->frequency; -void LoRaPHYUS915::apply_cf_list(ApplyCFListParams_t* applyCFList) -{ - return; -} + _radio->lock(); -bool LoRaPHYUS915::set_channel_mask(ChanMaskSetParams_t* chanMaskSet) -{ - uint8_t nbChannels = num_active_channels( chanMaskSet->ChannelsMaskIn, 0, 4 ); + if (_radio->get_status() != RF_IDLE) { - // Check the number of active channels - if( ( nbChannels < 2 ) && - ( nbChannels > 0 ) ) - { + _radio->unlock(); return false; + } - switch( chanMaskSet->ChannelsMaskType ) - { - case CHANNELS_MASK: - { - copy_channel_mask( ChannelsMask, chanMaskSet->ChannelsMaskIn, 6 ); + _radio->unlock(); - for( uint8_t i = 0; i < 6; i++ ) - { // Copy-And the channels mask - ChannelsMaskRemaining[i] &= ChannelsMask[i]; - } - break; - } - case CHANNELS_DEFAULT_MASK: - { - copy_channel_mask( ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 6 ); - break; - } - default: - return false; - } - return true; -} - -bool LoRaPHYUS915::get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut, - int8_t* txPowOut, uint32_t* adrAckCounter) -{ - bool adrAckReq = false; - int8_t datarate = adrNext->Datarate; - int8_t txPower = adrNext->TxPower; - GetPhyParams_t getPhy; - PhyParam_t phyParam; - - // Report back the adr ack counter - *adrAckCounter = adrNext->AdrAckCounter; - - if( adrNext->AdrEnabled == true ) - { - if( datarate == US915_TX_MIN_DATARATE ) - { - *adrAckCounter = 0; - adrAckReq = false; - } - else - { - if( adrNext->AdrAckCounter >= US915_ADR_ACK_LIMIT ) - { - adrAckReq = true; - txPower = US915_MAX_TX_POWER; - } - else - { - adrAckReq = false; - } - if( adrNext->AdrAckCounter >= ( US915_ADR_ACK_LIMIT + US915_ADR_ACK_DELAY ) ) - { - if( ( adrNext->AdrAckCounter % US915_ADR_ACK_DELAY ) == 1 ) - { - // Decrease the datarate - getPhy.Attribute = PHY_NEXT_LOWER_TX_DR; - getPhy.Datarate = datarate; - getPhy.UplinkDwellTime = adrNext->UplinkDwellTime; - phyParam = get_phy_params( &getPhy ); - datarate = phyParam.Value; - - if( datarate == US915_TX_MIN_DATARATE ) - { - // We must set adrAckReq to false as soon as we reach the lowest datarate - adrAckReq = false; - if( adrNext->UpdateChanMask == true ) - { - // Re-enable default channels - ChannelsMask[0] = 0xFFFF; - ChannelsMask[1] = 0xFFFF; - ChannelsMask[2] = 0xFFFF; - ChannelsMask[3] = 0xFFFF; - ChannelsMask[4] = 0x00FF; - ChannelsMask[5] = 0x0000; - } - } - } - } - } - } - - *drOut = datarate; - *txPowOut = txPower; - return adrAckReq; -} - -void LoRaPHYUS915::compute_rx_win_params(int8_t datarate, uint8_t minRxSymbols, - uint32_t rxError, - rx_config_params_t *rxConfigParams) -{ - double tSymbol = 0.0; - - // Get the datarate, perform a boundary check - rxConfigParams->datarate = MIN( datarate, US915_RX_MAX_DATARATE ); - rxConfigParams->bandwidth = GetBandwidth( rxConfigParams->datarate ); - - tSymbol = compute_symb_timeout_lora( DataratesUS915[rxConfigParams->datarate], BandwidthsUS915[rxConfigParams->datarate] ); - - get_rx_window_params( tSymbol, minRxSymbols, rxError, RADIO_WAKEUP_TIME, &rxConfigParams->window_timeout, &rxConfigParams->window_offset ); -} - -bool LoRaPHYUS915::rx_config(rx_config_params_t* rxConfig, int8_t* datarate) -{ - int8_t dr = rxConfig->datarate; - uint8_t maxPayload = 0; - int8_t phyDr = 0; - uint32_t frequency = rxConfig->frequency; - - if(_radio->get_status() != RF_IDLE ) - { - return false; - } - - if( rxConfig->rx_slot == RX_SLOT_WIN_1 ) - { + // For US915 spectrum, we have 8 Downstream channels, MAC would have + // selected a channel randomly from 72 Upstream channels, that index is + // passed in rx_config_params_t. Based on that channel index, we choose the + // frequency for first RX slot + if (config->rx_slot == RX_SLOT_WIN_1) { // Apply window 1 frequency - frequency = US915_FIRST_RX1_CHANNEL + ( rxConfig->channel % 8 ) * US915_STEPWIDTH_RX1_CHANNEL; + frequency = US915_FIRST_RX1_CHANNEL + (config->channel % 8) * US915_STEPWIDTH_RX1_CHANNEL; } // Read the physical datarate from the datarates table - phyDr = DataratesUS915[dr]; + phy_dr = datarates_US915[dr]; + + _radio->lock(); _radio->set_channel( frequency ); // Radio configuration - _radio->set_rx_config( MODEM_LORA, rxConfig->bandwidth, phyDr, 1, 0, 8, - rxConfig->window_timeout, false, 0, false, 0, 0, true, - rxConfig->is_rx_continuous ); + _radio->set_rx_config(MODEM_LORA, config->bandwidth, phy_dr, 1, 0, 8, + config->window_timeout, false, 0, false, 0, 0, true, + config->is_rx_continuous); + _radio->unlock(); + + if (config->is_repeater_supported == true) { + + max_payload = max_payloads_with_repeater_US915[dr]; + + } else { + + max_payload = max_payloads_US915[dr]; - if( rxConfig->is_repeater_supported == true ) - { - maxPayload = MaxPayloadOfDatarateRepeaterUS915[dr]; } - else - { - maxPayload = MaxPayloadOfDatarateUS915[dr]; - } - _radio->set_max_payload_length( MODEM_LORA, maxPayload + LORA_MAC_FRMPAYLOAD_OVERHEAD ); + + _radio->lock(); + + _radio->set_max_payload_length(MODEM_LORA, max_payload + LORA_MAC_FRMPAYLOAD_OVERHEAD); + + _radio->unlock(); *datarate = (uint8_t) dr; return true; } -bool LoRaPHYUS915::tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - lorawan_time_t* txTimeOnAir) +bool LoRaPHYUS915::tx_config(tx_config_params_t* config, int8_t* tx_power, + lorawan_time_t* tx_toa) { - int8_t phyDr = DataratesUS915[txConfig->Datarate]; - int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, Bands[Channels[txConfig->Channel].band].max_tx_pwr, txConfig->Datarate, ChannelsMask ); - uint32_t bandwidth = GetBandwidth( txConfig->Datarate ); - int8_t phyTxPower = 0; + int8_t phy_dr = datarates_US915[config->datarate]; + int8_t tx_power_limited = limit_tx_power(config->tx_power, + bands[channels[config->channel].band].max_tx_pwr, + config->datarate); + + uint32_t bandwidth = get_bandwidth(config->datarate); + int8_t phy_tx_power = 0; // Calculate physical TX power - phyTxPower = compute_tx_power( txPowerLimited, US915_DEFAULT_MAX_ERP, 0 ); + phy_tx_power = compute_tx_power( tx_power_limited, US915_DEFAULT_MAX_ERP, 0 ); - // Setup the radio frequency - _radio->set_channel( Channels[txConfig->Channel].frequency ); + _radio->lock(); - _radio->set_tx_config( MODEM_LORA, phyTxPower, 0, bandwidth, phyDr, 1, 8, + _radio->set_channel( channels[config->channel].frequency ); + + _radio->set_tx_config( MODEM_LORA, phy_tx_power, 0, bandwidth, phy_dr, 1, 8, false, true, 0, 0, false, 3000 ); // Setup maximum payload lenght of the radio driver - _radio->set_max_payload_length( MODEM_LORA, txConfig->PktLen ); + _radio->set_max_payload_length( MODEM_LORA, config->pkt_len ); + // Get the time-on-air of the next tx frame - *txTimeOnAir = _radio->time_on_air( MODEM_LORA, txConfig->PktLen ); - *txPower = txPowerLimited; + *tx_toa = _radio->time_on_air( MODEM_LORA, config->pkt_len ); + + _radio->unlock(); + + *tx_power = tx_power_limited; return true; } -uint8_t LoRaPHYUS915::link_ADR_request(LinkAdrReqParams_t* linkAdrReq, - int8_t* drOut, int8_t* txPowOut, - uint8_t* nbRepOut, uint8_t* nbBytesParsed) +uint8_t LoRaPHYUS915::link_ADR_request(adr_req_params_t* params, + int8_t* dr_out, int8_t* tx_power_out, + uint8_t* nb_rep_out, uint8_t* nb_bytes_parsed) { uint8_t status = 0x07; - RegionCommonLinkAdrParams_t linkAdrParams; - uint8_t nextIndex = 0; - uint8_t bytesProcessed = 0; - uint16_t channelsMask[6] = { 0, 0, 0, 0, 0, 0 }; - GetPhyParams_t getPhy; - PhyParam_t phyParam; - RegionCommonLinkAdrReqVerifyParams_t linkAdrVerifyParams; + + link_adr_params_t adr_settings; + uint8_t next_idx = 0; + uint8_t bytes_processed = 0; + uint16_t temp_channel_masks[US915_CHANNELS_MASK_SIZE] = {0, 0, 0, 0, 0}; + + verify_adr_params_t verify_params; // Initialize local copy of channels mask - copy_channel_mask( channelsMask, ChannelsMask, 6 ); + copy_channel_mask(temp_channel_masks, channel_masks, US915_CHANNELS_MASK_SIZE); - while( bytesProcessed < linkAdrReq->PayloadSize ) - { - nextIndex = parse_link_ADR_req( &( linkAdrReq->Payload[bytesProcessed] ), &linkAdrParams ); + while (bytes_processed < params->payload_size) { + next_idx = parse_link_ADR_req(&(params->payload[bytes_processed]), + &adr_settings); - if( nextIndex == 0 ) + if (next_idx == 0) { break; // break loop, since no more request has been found + } // Update bytes processed - bytesProcessed += nextIndex; + bytes_processed += next_idx; // Revert status, as we only check the last ADR request for the channel mask KO status = 0x07; - if( linkAdrParams.ChMaskCtrl == 6 ) - { + if (adr_settings.ch_mask_ctrl == 6) { + // Enable all 125 kHz channels - channelsMask[0] = 0xFFFF; - channelsMask[1] = 0xFFFF; - channelsMask[2] = 0xFFFF; - channelsMask[3] = 0xFFFF; + temp_channel_masks[0] = 0xFFFF; + temp_channel_masks[1] = 0xFFFF; + temp_channel_masks[2] = 0xFFFF; + temp_channel_masks[3] = 0xFFFF; // Apply chMask to channels 64 to 71 - channelsMask[4] = linkAdrParams.ChMask; - } - else if( linkAdrParams.ChMaskCtrl == 7 ) - { + temp_channel_masks[4] = adr_settings.channel_mask; + + } else if (adr_settings.ch_mask_ctrl == 7) { + // Disable all 125 kHz channels - channelsMask[0] = 0x0000; - channelsMask[1] = 0x0000; - channelsMask[2] = 0x0000; - channelsMask[3] = 0x0000; + temp_channel_masks[0] = 0x0000; + temp_channel_masks[1] = 0x0000; + temp_channel_masks[2] = 0x0000; + temp_channel_masks[3] = 0x0000; // Apply chMask to channels 64 to 71 - channelsMask[4] = linkAdrParams.ChMask; - } - else if( linkAdrParams.ChMaskCtrl == 5 ) - { + temp_channel_masks[4] = adr_settings.channel_mask; + + } else if (adr_settings.ch_mask_ctrl == 5) { + // RFU status &= 0xFE; // Channel mask KO - } - else - { - channelsMask[linkAdrParams.ChMaskCtrl] = linkAdrParams.ChMask; + + } else { + + temp_channel_masks[adr_settings.ch_mask_ctrl] = adr_settings.channel_mask; + } } // FCC 15.247 paragraph F mandates to hop on at least 2 125 kHz channels - if( ( linkAdrParams.Datarate < DR_4 ) && ( num_active_channels( channelsMask, 0, 4 ) < 2 ) ) - { + if ((adr_settings.datarate < DR_4) && + (num_active_channels(temp_channel_masks, 0, 4) < 2)) { + status &= 0xFE; // Channel mask KO + } - // Get the minimum possible datarate - getPhy.Attribute = PHY_MIN_TX_DR; - getPhy.UplinkDwellTime = linkAdrReq->UplinkDwellTime; - phyParam = get_phy_params( &getPhy ); - - linkAdrVerifyParams.Status = status; - linkAdrVerifyParams.AdrEnabled = linkAdrReq->AdrEnabled; - linkAdrVerifyParams.Datarate = linkAdrParams.Datarate; - linkAdrVerifyParams.TxPower = linkAdrParams.TxPower; - linkAdrVerifyParams.NbRep = linkAdrParams.NbRep; - linkAdrVerifyParams.CurrentDatarate = linkAdrReq->CurrentDatarate; - linkAdrVerifyParams.CurrentTxPower = linkAdrReq->CurrentTxPower; - linkAdrVerifyParams.CurrentNbRep = linkAdrReq->CurrentNbRep; - linkAdrVerifyParams.NbChannels = US915_MAX_NB_CHANNELS; - linkAdrVerifyParams.ChannelsMask = channelsMask; - linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value; - linkAdrVerifyParams.MaxDatarate = US915_TX_MAX_DATARATE; - linkAdrVerifyParams.Channels = Channels; - linkAdrVerifyParams.MinTxPower = US915_MIN_TX_POWER; - linkAdrVerifyParams.MaxTxPower = US915_MAX_TX_POWER; + verify_params.status = status; + verify_params.adr_enabled = params->adr_enabled; + verify_params.datarate = adr_settings.datarate; + verify_params.tx_power = adr_settings.tx_power; + verify_params.nb_rep = adr_settings.nb_rep; + verify_params.current_datarate = params->current_datarate; + verify_params.current_tx_power = params->current_tx_power; + verify_params.current_nb_rep = params->current_nb_rep; + verify_params.channel_mask = temp_channel_masks; // Verify the parameters and update, if necessary - status = verify_link_ADR_req( &linkAdrVerifyParams, &linkAdrParams.Datarate, &linkAdrParams.TxPower, &linkAdrParams.NbRep ); + status = verify_link_ADR_req(&verify_params, &adr_settings.datarate, + &adr_settings.tx_power, &adr_settings.nb_rep); // Update channelsMask if everything is correct - if( status == 0x07 ) - { + if (status == 0x07) { // Copy Mask - copy_channel_mask( ChannelsMask, channelsMask, 6 ); + copy_channel_mask(channel_masks, temp_channel_masks, US915_CHANNELS_MASK_SIZE); - ChannelsMaskRemaining[0] &= ChannelsMask[0]; - ChannelsMaskRemaining[1] &= ChannelsMask[1]; - ChannelsMaskRemaining[2] &= ChannelsMask[2]; - ChannelsMaskRemaining[3] &= ChannelsMask[3]; - ChannelsMaskRemaining[4] = ChannelsMask[4]; - ChannelsMaskRemaining[5] = ChannelsMask[5]; + current_channel_masks[0] &= channel_masks[0]; + current_channel_masks[1] &= channel_masks[1]; + current_channel_masks[2] &= channel_masks[2]; + current_channel_masks[3] &= channel_masks[3]; + current_channel_masks[4] = channel_masks[4]; } // Update status variables - *drOut = linkAdrParams.Datarate; - *txPowOut = linkAdrParams.TxPower; - *nbRepOut = linkAdrParams.NbRep; - *nbBytesParsed = bytesProcessed; + *dr_out = adr_settings.datarate; + *tx_power_out = adr_settings.tx_power; + *nb_rep_out = adr_settings.nb_rep; + *nb_bytes_parsed = bytes_processed; return status; } -uint8_t LoRaPHYUS915::setup_rx_params(RxParamSetupReqParams_t* rxParamSetupReq) +uint8_t LoRaPHYUS915::accept_rx_param_setup_req(rx_param_setup_req_t* params) { uint8_t status = 0x07; - uint32_t freq = rxParamSetupReq->Frequency; + uint32_t freq = params->frequency; // Verify radio frequency - if( ( _radio->check_rf_frequency( freq ) == false ) || - ( freq < US915_FIRST_RX1_CHANNEL ) || - ( freq > US915_LAST_RX1_CHANNEL ) || - ( ( ( freq - ( uint32_t ) US915_FIRST_RX1_CHANNEL ) % ( uint32_t ) US915_STEPWIDTH_RX1_CHANNEL ) != 0 ) ) - { + if ((_radio->check_rf_frequency( freq ) == false) + || (freq < US915_FIRST_RX1_CHANNEL) + || (freq > US915_LAST_RX1_CHANNEL) + || (((freq - (uint32_t) US915_FIRST_RX1_CHANNEL) % (uint32_t) US915_STEPWIDTH_RX1_CHANNEL) != 0)) { + status &= 0xFE; // Channel frequency KO + } // Verify datarate - if( val_in_range( rxParamSetupReq->Datarate, US915_RX_MIN_DATARATE, US915_RX_MAX_DATARATE ) == 0 ) - { + if (val_in_range(params->datarate, US915_RX_MIN_DATARATE, US915_RX_MAX_DATARATE) == 0) { + status &= 0xFD; // Datarate KO + } - if( ( val_in_range( rxParamSetupReq->Datarate, DR_5, DR_7 ) == 1 ) || - ( rxParamSetupReq->Datarate > DR_13 ) ) - { + + if ((val_in_range(params->datarate, DR_5, DR_7)) || (params->datarate > DR_13)) { + status &= 0xFD; // Datarate KO + } // Verify datarate offset - if( val_in_range( rxParamSetupReq->DrOffset, US915_MIN_RX1_DR_OFFSET, US915_MAX_RX1_DR_OFFSET ) == 0 ) + if (val_in_range( params->dr_offset, US915_MIN_RX1_DR_OFFSET, US915_MAX_RX1_DR_OFFSET ) == 0 ) { status &= 0xFB; // Rx1DrOffset range KO } @@ -887,152 +589,112 @@ uint8_t LoRaPHYUS915::setup_rx_params(RxParamSetupReqParams_t* rxParamSetupReq) return status; } -uint8_t LoRaPHYUS915::request_new_channel(NewChannelReqParams_t* newChannelReq) -{ - // Datarate and frequency KO - return 0; -} - -int8_t LoRaPHYUS915::setup_tx_params(TxParamSetupReqParams_t* txParamSetupReq) -{ - return -1; -} - -uint8_t LoRaPHYUS915::dl_channel_request(DlChannelReqParams_t* dlChannelReq) -{ - return 0; -} - -int8_t LoRaPHYUS915::get_alternate_DR(AlternateDrParams_t* alternateDr) +int8_t LoRaPHYUS915::get_alternate_DR(uint8_t nb_trials) { int8_t datarate = 0; // Re-enable 500 kHz default channels - ChannelsMask[4] = 0x00FF; + channel_masks[4] = 0x00FF; - if( ( alternateDr->NbTrials & 0x01 ) == 0x01 ) - { + if ((nb_trials & 0x01) == 0x01) { datarate = DR_4; - } - else - { + } else { datarate = DR_0; } + return datarate; } -void LoRaPHYUS915::calculate_backoff(CalcBackOffParams_t* calcBackOff) -{ - RegionCommonCalcBackOffParams_t calcBackOffParams; - - calcBackOffParams.Channels = Channels; - calcBackOffParams.Bands = Bands; - calcBackOffParams.LastTxIsJoinRequest = calcBackOff->LastTxIsJoinRequest; - calcBackOffParams.Joined = calcBackOff->Joined; - calcBackOffParams.DutyCycleEnabled = calcBackOff->DutyCycleEnabled; - calcBackOffParams.Channel = calcBackOff->Channel; - calcBackOffParams.ElapsedTime = calcBackOff->ElapsedTime; - calcBackOffParams.TxTimeOnAir = calcBackOff->TxTimeOnAir; - - get_DC_backoff( &calcBackOffParams ); -} - -bool LoRaPHYUS915::set_next_channel(NextChanParams_t* nextChanParams, +bool LoRaPHYUS915::set_next_channel(channel_selection_params_t* params, uint8_t* channel, lorawan_time_t* time, - lorawan_time_t* aggregatedTimeOff) + lorawan_time_t* aggregate_timeOff) { - uint8_t nbEnabledChannels = 0; - uint8_t delayTx = 0; - uint8_t enabledChannels[US915_MAX_NB_CHANNELS] = { 0 }; - lorawan_time_t nextTxDelay = 0; + uint8_t nb_enabled_channels = 0; + uint8_t delay_tx = 0; + uint8_t enabled_channels[US915_MAX_NB_CHANNELS] = {0}; + lorawan_time_t next_tx_delay = 0; // Count 125kHz channels - if( num_active_channels( ChannelsMaskRemaining, 0, 4 ) == 0 ) - { // Reactivate default channels - copy_channel_mask( ChannelsMaskRemaining, ChannelsMask, 4 ); + if (num_active_channels(current_channel_masks, 0, 4) == 0) { + // If none of the 125 kHz Upstream channel found, + // Reactivate default channels + copy_channel_mask(current_channel_masks, channel_masks, 4); } + // Check other channels - if( nextChanParams->Datarate >= DR_4 ) - { - if( ( ChannelsMaskRemaining[4] & 0x00FF ) == 0 ) - { - ChannelsMaskRemaining[4] = ChannelsMask[4]; + if (params->current_datarate >= DR_4) { + if ((current_channel_masks[4] & 0x00FF ) == 0) { + current_channel_masks[4] = channel_masks[4]; } } - if( nextChanParams->AggrTimeOff <= _lora_time.TimerGetElapsedTime( nextChanParams->LastAggrTx ) ) - { + if (params->aggregate_timeoff <= _lora_time.TimerGetElapsedTime(params->last_aggregate_tx_time)) { // Reset Aggregated time off - *aggregatedTimeOff = 0; + *aggregate_timeOff = 0; // Update bands Time OFF - nextTxDelay = update_band_timeoff( nextChanParams->Joined, nextChanParams->DutyCycleEnabled, Bands, US915_MAX_NB_BANDS ); + next_tx_delay = update_band_timeoff(params->joined, params->dc_enabled, bands, US915_MAX_NB_BANDS); // Search how many channels are enabled - nbEnabledChannels = CountNbOfEnabledChannels( nextChanParams->Datarate, - ChannelsMaskRemaining, Channels, - Bands, enabledChannels, &delayTx ); - } - else - { - delayTx++; - nextTxDelay = nextChanParams->AggrTimeOff - _lora_time.TimerGetElapsedTime( nextChanParams->LastAggrTx ); + nb_enabled_channels = enabled_channel_count(params->joined, + params->current_datarate, + current_channel_masks, US915_CHANNELS_MASK_SIZE, + enabled_channels, &delay_tx); + } else { + delay_tx++; + next_tx_delay = params->aggregate_timeoff - _lora_time.TimerGetElapsedTime(params->last_aggregate_tx_time); } - if( nbEnabledChannels > 0 ) - { + if (nb_enabled_channels > 0) { // We found a valid channel - *channel = enabledChannels[get_random( 0, nbEnabledChannels - 1 )]; + *channel = enabled_channels[get_random( 0, nb_enabled_channels - 1 )]; // Disable the channel in the mask - disable_channel( ChannelsMaskRemaining, *channel, US915_MAX_NB_CHANNELS - 8 ); + disable_channel(current_channel_masks, *channel, US915_MAX_NB_CHANNELS - 8); *time = 0; return true; - } - else - { - if( delayTx > 0 ) - { + + } else { + + if (delay_tx > 0) { // Delay transmission due to AggregatedTimeOff or to a band time off - *time = nextTxDelay; + *time = next_tx_delay; return true; } + // Datarate not supported by any channel *time = 0; return false; } } -lorawan_status_t LoRaPHYUS915::add_channel(ChannelAddParams_t* channelAdd) +void LoRaPHYUS915::set_tx_cont_mode(cw_mode_params_t* params, uint32_t given_frequency) { - return LORAWAN_STATUS_PARAMETER_INVALID; -} + (void)given_frequency; -bool LoRaPHYUS915::remove_channel(ChannelRemoveParams_t* channelRemove) -{ - return LORAWAN_STATUS_PARAMETER_INVALID; -} - -void LoRaPHYUS915::set_tx_cont_mode(ContinuousWaveParams_t* continuousWave) -{ - int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, Bands[Channels[continuousWave->Channel].band].max_tx_pwr, continuousWave->Datarate, ChannelsMask ); + int8_t tx_power_limited = limit_tx_power(params->tx_power, + bands[channels[params->channel].band].max_tx_pwr, + params->datarate); int8_t phyTxPower = 0; - uint32_t frequency = Channels[continuousWave->Channel].frequency; + uint32_t frequency = channels[params->channel].frequency; // Calculate physical TX power - phyTxPower = compute_tx_power( txPowerLimited, US915_DEFAULT_MAX_ERP, 0 ); + phyTxPower = compute_tx_power(tx_power_limited, US915_DEFAULT_MAX_ERP, 0); - _radio->set_tx_continuous_wave( frequency, phyTxPower, continuousWave->Timeout ); + _radio->lock(); + + _radio->set_tx_continuous_wave(frequency, phyTxPower, params->timeout); + + _radio->unlock(); } -uint8_t LoRaPHYUS915::apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, - int8_t drOffset) +uint8_t LoRaPHYUS915::apply_DR_offset(int8_t dr, int8_t dr_offset) { - int8_t datarate = DatarateOffsetsUS915[dr][drOffset]; + int8_t datarate = datarate_offsets_US915[dr][dr_offset]; - if( datarate < 0 ) - { + if (datarate < 0) { datarate = DR_0; } + return datarate; } diff --git a/features/lorawan/lorastack/phy/LoRaPHYUS915.h b/features/lorawan/lorastack/phy/LoRaPHYUS915.h index 88ab2ce391..b9bc885787 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYUS915.h +++ b/features/lorawan/lorastack/phy/LoRaPHYUS915.h @@ -33,7 +33,6 @@ #define MBED_OS_LORAPHYUS_915_H_ #include "LoRaPHY.h" -#include "netsocket/LoRaRadio.h" /*! * LoRaMac maximum number of channels @@ -45,7 +44,7 @@ */ #define US915_MAX_NB_BANDS 1 -#define US915_CHANNELS_MASK_SIZE 6 +#define US915_CHANNELS_MASK_SIZE 5 class LoRaPHYUS915 : public LoRaPHY { @@ -55,311 +54,59 @@ public: LoRaPHYUS915(LoRaWANTimeHandler &lora_time); virtual ~LoRaPHYUS915(); - /*! - * \brief The function gets a value of a specific PHY attribute. - * - * \param [in] getPhy A pointer to the function parameters. - * - * \retval The structure containing the PHY parameter. - */ - virtual PhyParam_t get_phy_params(GetPhyParams_t* getPhy ); + virtual void restore_default_channels(); - /*! - * \brief Updates the last TX done parameters of the current channel. - * - * \param [in] txDone A pointer to the function parameters. - */ - virtual void set_band_tx_done(SetBandTxDoneParams_t* txDone ); + virtual bool rx_config(rx_config_params_t* config, int8_t* datarate); - /*! - * \brief Initializes the channels masks and the channels. - * - * \param [in] type Sets the initialization type. - */ - virtual void load_defaults(InitType_t type ); + virtual bool tx_config(tx_config_params_t* config, int8_t* tx_power, + lorawan_time_t* tx_toa); - /*! - * \brief Verifies a parameter. - * - * \param [in] verify A pointer to the function parameters. - * - * \param [in] phyAttribute The attribute to verify. - * - * \retval True, if the parameter is valid. - */ - virtual bool verify(VerifyParams_t* verify, PhyAttribute_t phyAttribute ); + virtual uint8_t link_ADR_request(adr_req_params_t* params, + int8_t* dr_out, int8_t* tx_power_out, + uint8_t* nb_rep_out, + uint8_t* nb_bytes_parsed); - /*! - * \brief The function parses the input buffer and sets up the channels of the CF list. - * - * \param [in] applyCFList A pointer to the function parameters. - */ - virtual void apply_cf_list(ApplyCFListParams_t* applyCFList ); + virtual uint8_t accept_rx_param_setup_req(rx_param_setup_req_t* params); - /*! - * \brief Sets a channels mask. - * - * \param [in] chanMaskSet A pointer to the function parameters. - * - * \retval True, if the channels mask could be set. - */ - virtual bool set_channel_mask(ChanMaskSetParams_t* chanMaskSet ); + virtual int8_t get_alternate_DR(uint8_t nb_trials); - /*! - * \brief Calculates the next datarate to set, when ADR is on or off. - * - * \param [in] adrNext A pointer to the function parameters. - * - * \param [out] drOut The calculated datarate for the next TX. - * - * \param [out] txPowOut The TX power for the next TX. - * - * \param [out] adrAckCounter The calculated ADR acknowledgement counter. - * - * \retval True, if an ADR request should be performed. - */ - virtual bool get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut, - int8_t* txPowOut, uint32_t* adrAckCounter ); + virtual bool set_next_channel(channel_selection_params_t* params, uint8_t* channel, + lorawan_time_t* time, lorawan_time_t* aggregate_timeOff); - /*! - * \brief Configuration of the RX windows. - * - * \param [in] rxConfig A pointer to the function parameters. - * - * \param [out] datarate The datarate index set. - * - * \retval True, if the configuration was applied successfully. - */ - virtual bool rx_config(rx_config_params_t* rxConfig, int8_t* datarate ); + virtual void set_tx_cont_mode(cw_mode_params_t* continuousWave, + uint32_t frequency = 0); - /* - * RX window precise timing - * - * For more details, please consult the following document, chapter 3.1.2. - * http://www.semtech.com/images/datasheet/SX1272_settings_for_LoRaWAN_v2.0.pdf - * or - * http://www.semtech.com/images/datasheet/SX1276_settings_for_LoRaWAN_v2.0.pdf - * - * Downlink start: T = Tx + 1s (+/- 20 us) - * | - * TRxEarly | TRxLate - * | | | - * | | +---+---+---+---+---+---+---+---+ - * | | | Latest Rx window | - * | | +---+---+---+---+---+---+---+---+ - * | | | - * +---+---+---+---+---+---+---+---+ - * | Earliest Rx window | - * +---+---+---+---+---+---+---+---+ - * | - * +---+---+---+---+---+---+---+---+ - *Downlink preamble 8 symbols | | | | | | | | | - * +---+---+---+---+---+---+---+---+ - * - * Worst case Rx window timings - * - * TRxLate = DEFAULT_MIN_RX_SYMBOLS * tSymbol - RADIO_WAKEUP_TIME - * TRxEarly = 8 - DEFAULT_MIN_RX_SYMBOLS * tSymbol - RxWindowTimeout - RADIO_WAKEUP_TIME - * - * TRxLate - TRxEarly = 2 * DEFAULT_SYSTEM_MAX_RX_ERROR - * - * RxOffset = ( TRxLate + TRxEarly ) / 2 - * - * RxWindowTimeout = ( 2 * DEFAULT_MIN_RX_SYMBOLS - 8 ) * tSymbol + 2 * DEFAULT_SYSTEM_MAX_RX_ERROR - * RxOffset = 4 * tSymbol - RxWindowTimeout / 2 - RADIO_WAKE_UP_TIME - * - * The minimum value of RxWindowTimeout must be 5 symbols which implies that the system always tolerates at least an error of 1.5 * tSymbol - */ - /*! - * Computes the RX window timeout and offset. - * - * \param [in] datarate The RX window datarate index to be used. - * - * \param [in] minRxSymbols The minimum number of symbols required to detect an RX frame. - * - * \param [in] rxError The system maximum timing error of the receiver in milliseconds. - * The receiver will turn on in a [-rxError : +rxError] ms - * interval around RxOffset. - * - * \param [out] rxConfigParams Returns the updated WindowTimeout and WindowOffset fields. - */ - virtual void compute_rx_win_params(int8_t datarate, - uint8_t minRxSymbols, - uint32_t rxError, - rx_config_params_t *rxConfigParams); - - /*! - * \brief TX configuration. - * - * \param [in] txConfig A pointer to the function parameters. - * - * \param [out] txPower The TX power index set. - * - * \param [out] txTimeOnAir The time-on-air of the frame. - * - * \retval True, if the configuration was applied successfully. - */ - virtual bool tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - lorawan_time_t* txTimeOnAir ); - - /*! - * \brief The function processes a Link ADR request. - * - * \param [in] linkAdrReq A pointer to the function parameters. - * - * \param [out] drOut The datarate applied. - * - * \param [out] txPowOut The TX power applied. - * - * \param [out] nbRepOut The number of repetitions to apply. - * - * \param [out] nbBytesParsed The number of bytes parsed. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t link_ADR_request(LinkAdrReqParams_t* linkAdrReq, - int8_t* drOut, int8_t* txPowOut, - uint8_t* nbRepOut, - uint8_t* nbBytesParsed ); - - /*! - * \brief The function processes a RX parameter setup request. - * - * \param [in] rxParamSetupReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t setup_rx_params(RxParamSetupReqParams_t* rxParamSetupReq ); - - /*! - * \brief The function processes a new channel request. - * - * \param [in] newChannelReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t request_new_channel(NewChannelReqParams_t* newChannelReq ); - - /*! - * \brief The function processes a TX ParamSetup request. - * - * \param [in] txParamSetupReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - * Returns -1, if the functionality is not implemented. In this case, the end node - * shall ignore the command. - */ - virtual int8_t setup_tx_params(TxParamSetupReqParams_t* txParamSetupReq ); - - /*! - * \brief The function processes a DlChannel request. - * - * \param [in] dlChannelReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t dl_channel_request(DlChannelReqParams_t* dlChannelReq ); - - /*! - * \brief Alternates the datarate of the channel for the join request. - * - * \param [in] alternateDr A pointer to the function parameters. - * - * \retval The datarate to apply. - */ - virtual int8_t get_alternate_DR(AlternateDrParams_t* alternateDr ); - - /*! - * \brief Calculates the back-off time. - * - * \param [in] calcBackOff A pointer to the function parameters. - */ - virtual void calculate_backoff(CalcBackOffParams_t* calcBackOff ); - - /*! - * \brief Searches and sets the next random available channel. - * - * \param [in] nextChanParams The parameters for the next channel. - * - * \param [out] channel The next channel to use for TX. - * - * \param [out] time The time to wait for the next transmission according to the duty cycle. - * - * \param [out] aggregatedTimeOff Updates the aggregated time off. - * - * \retval The function status [1: OK, 0: Unable to find a channel on the current datarate]. - */ - virtual bool set_next_channel(NextChanParams_t* nextChanParams, - uint8_t* channel, lorawan_time_t* time, - lorawan_time_t* aggregatedTimeOff ); - - /*! - * \brief Adds a channel. - * - * \param [in] channelAdd A pointer to the function parameters. - * - * \retval The status of the operation. - */ - virtual lorawan_status_t add_channel(ChannelAddParams_t* channelAdd ); - - /*! - * \brief Removes a channel. - * - * \param [in] channelRemove A pointer to the function parameters. - * - * \retval True, if the channel was removed successfully. - */ - virtual bool remove_channel(ChannelRemoveParams_t* channelRemove ); - - /*! - * \brief Sets the radio into continuous wave mode. - * - * \param [in] continuousWave A pointer to the function parameters. - */ - virtual void set_tx_cont_mode(ContinuousWaveParams_t* continuousWave ); - - /*! - * \brief Computes a new datarate according to the given offset - * - * \param [in] downlinkDwellTime The downlink dwell time configuration. 0: No limit, 1: 400ms - * - * \param [in] dr The current datarate. - * - * \param [in] drOffset The offset to be applied. - * - * \retval newDr The computed datarate. - */ - virtual uint8_t apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ); + virtual uint8_t apply_DR_offset(int8_t dr, int8_t dr_offset); private: - int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower, int8_t datarate, uint16_t* channelsMask ); - uint8_t CountNbOfEnabledChannels( uint8_t datarate, uint16_t* channelsMask, channel_params_t* channels, band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ); - // Global attributes + int8_t limit_tx_power(int8_t tx_power, int8_t max_band_tx_power, + int8_t datarate); + /*! * LoRaMAC channels */ - channel_params_t Channels[US915_MAX_NB_CHANNELS]; + channel_params_t channels[US915_MAX_NB_CHANNELS]; /*! * LoRaMac bands */ - band_t Bands[US915_MAX_NB_BANDS]; + band_t bands[US915_MAX_NB_BANDS]; /*! * LoRaMac channels mask */ - uint16_t ChannelsMask[US915_CHANNELS_MASK_SIZE]; + uint16_t channel_masks[US915_CHANNELS_MASK_SIZE]; /*! * LoRaMac channels remaining */ - uint16_t ChannelsMaskRemaining[US915_CHANNELS_MASK_SIZE]; + uint16_t current_channel_masks[US915_CHANNELS_MASK_SIZE]; /*! * LoRaMac channels default mask */ - uint16_t ChannelsDefaultMask[US915_CHANNELS_MASK_SIZE]; + uint16_t default_channel_masks[US915_CHANNELS_MASK_SIZE]; }; #endif /* MBED_OS_LORAPHY_US915_H_ */ diff --git a/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.cpp b/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.cpp index 60aa4ac810..42902f536f 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.cpp @@ -30,10 +30,7 @@ */ #include "LoRaPHYUS915Hybrid.h" - #include "lora_phy_ds.h" -#include "LoRaRadio.h" - /*! * Minimal datarate that can be used by the node @@ -164,7 +161,7 @@ * Band 0 definition * { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff } */ -#define US915_HYBRID_BAND0 { 1, US915_HYBRID_MAX_TX_POWER, 0, 0, 0 } // 100.0 % +static const band_t US915_HYBRID_BAND0 = { 1, US915_HYBRID_MAX_TX_POWER, 0, 0, 0 }; // 100.0 % /*! * Defines the first channel for RX window 1 for US band @@ -184,17 +181,17 @@ /*! * Data rates table definition */ -static const uint8_t DataratesUS915_HYBRID[] = { 10, 9, 8, 7, 8, 0, 0, 0, 12, 11, 10, 9, 8, 7, 0, 0 }; +static const uint8_t datarates_US915_HYBRID[] = { 10, 9, 8, 7, 8, 0, 0, 0, 12, 11, 10, 9, 8, 7, 0, 0 }; /*! * Bandwidths table definition in Hz */ -static const uint32_t BandwidthsUS915_HYBRID[] = { 125000, 125000, 125000, 125000, 500000, 0, 0, 0, 500000, 500000, 500000, 500000, 500000, 500000, 0, 0 }; +static const uint32_t bandwidths_US915_HYBRID[] = { 125000, 125000, 125000, 125000, 500000, 0, 0, 0, 500000, 500000, 500000, 500000, 500000, 500000, 0, 0 }; /*! * Up/Down link data rates offset definition */ -static const int8_t DatarateOffsetsUS915_HYBRID[5][4] = +static const int8_t datarate_offsets_US915_HYBRID[5][4] = { { DR_10, DR_9 , DR_8 , DR_8 }, // DR_0 { DR_11, DR_10, DR_9 , DR_8 }, // DR_1 @@ -206,923 +203,599 @@ static const int8_t DatarateOffsetsUS915_HYBRID[5][4] = /*! * Maximum payload with respect to the datarate index. Cannot operate with repeater. */ -static const uint8_t MaxPayloadOfDatarateUS915_HYBRID[] = { 11, 53, 125, 242, 242, 0, 0, 0, 53, 129, 242, 242, 242, 242, 0, 0 }; +static const uint8_t max_payloads_US915_HYBRID[] = { 11, 53, 125, 242, 242, 0, 0, 0, 53, 129, 242, 242, 242, 242, 0, 0 }; /*! * Maximum payload with respect to the datarate index. Can operate with repeater. */ -static const uint8_t MaxPayloadOfDatarateRepeaterUS915_HYBRID[] = { 11, 53, 125, 242, 242, 0, 0, 0, 33, 109, 222, 222, 222, 222, 0, 0 }; - - -// Static functions -static int8_t GetNextLowerTxDr( int8_t dr, int8_t minDr ) -{ - uint8_t nextLowerDr = 0; - - if( dr == minDr ) - { - nextLowerDr = minDr; - } - else - { - nextLowerDr = dr - 1; - } - return nextLowerDr; -} - -static uint32_t GetBandwidth( uint32_t drIndex ) -{ - switch( BandwidthsUS915_HYBRID[drIndex] ) - { - default: - case 125000: - return 0; - case 250000: - return 1; - case 500000: - return 2; - } -} - -static void ReenableChannels( uint16_t mask, uint16_t* channelsMask ) -{ - uint16_t blockMask = mask; - - for( uint8_t i = 0, j = 0; i < 4; i++, j += 2 ) - { - channelsMask[i] = 0; - if( ( blockMask & ( 1 << j ) ) != 0 ) - { - channelsMask[i] |= 0x00FF; - } - if( ( blockMask & ( 1 << ( j + 1 ) ) ) != 0 ) - { - channelsMask[i] |= 0xFF00; - } - } - channelsMask[4] = blockMask; - channelsMask[5] = 0x0000; -} - -static uint8_t CountBits( uint16_t mask, uint8_t nbBits ) -{ - uint8_t nbActiveBits = 0; - - for( uint8_t j = 0; j < nbBits; j++ ) - { - if( ( mask & ( 1 << j ) ) == ( 1 << j ) ) - { - nbActiveBits++; - } - } - return nbActiveBits; -} - -int8_t LoRaPHYUS915Hybrid::LimitTxPower( int8_t txPower, int8_t maxBandTxPower, int8_t datarate, uint16_t* channelsMask ) -{ - int8_t txPowerResult = txPower; - - // Limit tx power to the band max - txPowerResult = MAX( txPower, maxBandTxPower ); - - if( datarate == DR_4 ) - {// Limit tx power to max 26dBm - txPowerResult = MAX( txPower, TX_POWER_2 ); - } - else - { - if( num_active_channels( channelsMask, 0, 4 ) < 50 ) - {// Limit tx power to max 21dBm - txPowerResult = MAX( txPower, TX_POWER_5 ); - } - } - return txPowerResult; -} - -static bool ValidateChannelsMask( uint16_t* channelsMask ) -{ - bool chanMaskState = false; - uint16_t block1 = 0; - uint16_t block2 = 0; - uint8_t index = 0; - uint16_t channelsMaskCpy[6]; - - // Copy channels mask to not change the input - for( uint8_t i = 0; i < 4; i++ ) - { - channelsMaskCpy[i] = channelsMask[i]; - } - - for( uint8_t i = 0; i < 4; i++ ) - { - block1 = channelsMaskCpy[i] & 0x00FF; - block2 = channelsMaskCpy[i] & 0xFF00; - - if( CountBits( block1, 16 ) > 5 ) - { - channelsMaskCpy[i] &= block1; - channelsMaskCpy[4] = 1 << ( i * 2 ); - chanMaskState = true; - index = i; - break; - } - else if( CountBits( block2, 16 ) > 5 ) - { - channelsMaskCpy[i] &= block2; - channelsMaskCpy[4] = 1 << ( i * 2 + 1 ); - chanMaskState = true; - index = i; - break; - } - } - - // Do only change the channel mask, if we have found a valid block. - if( chanMaskState == true ) - { - // Copy channels mask back again - for( uint8_t i = 0; i < 4; i++ ) - { - channelsMask[i] = channelsMaskCpy[i]; - - if( i != index ) - { - channelsMask[i] = 0; - } - } - channelsMask[4] = channelsMaskCpy[4]; - } - return chanMaskState; -} - -uint8_t LoRaPHYUS915Hybrid::CountNbOfEnabledChannels( uint8_t datarate, uint16_t* channelsMask, channel_params_t* channels, band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ) -{ - uint8_t nbEnabledChannels = 0; - uint8_t delayTransmission = 0; - - for( uint8_t i = 0, k = 0; i < US915_HYBRID_MAX_NB_CHANNELS; i += 16, k++ ) - { - for( uint8_t j = 0; j < 16; j++ ) - { - if( ( channelsMask[k] & ( 1 << j ) ) != 0 ) - { - if( channels[i + j].frequency == 0 ) - { // Check if the channel is enabled - continue; - } - if( val_in_range( datarate, channels[i + j].dr_range.fields.min, - channels[i + j].dr_range.fields.max ) == 0 ) - { // Check if the current channel selection supports the given datarate - continue; - } - if( bands[channels[i + j].band].off_time > 0 ) - { // Check if the band is available for transmission - delayTransmission++; - continue; - } - enabledChannels[nbEnabledChannels++] = i + j; - } - } - } - - *delayTx = delayTransmission; - return nbEnabledChannels; -} +static const uint8_t max_payloads_with_repeater_US915_HYBRID[] = { 11, 53, 125, 242, 242, 0, 0, 0, 33, 109, 222, 222, 222, 222, 0, 0 }; LoRaPHYUS915Hybrid::LoRaPHYUS915Hybrid(LoRaWANTimeHandler &lora_time) : LoRaPHY(lora_time) { - const band_t band0 = US915_HYBRID_BAND0; - Bands[0] = band0; + bands[0] = US915_HYBRID_BAND0; + + // Channels + // 125 kHz channels + for (uint8_t i = 0; i < US915_HYBRID_MAX_NB_CHANNELS - 8; i++) { + channels[i].frequency = 902300000 + i * 200000; + channels[i].dr_range.value = ( DR_3 << 4 ) | DR_0; + channels[i].band = 0; + } + + // 500 kHz channels + for (uint8_t i = US915_HYBRID_MAX_NB_CHANNELS - 8; i < US915_HYBRID_MAX_NB_CHANNELS; i++) { + channels[i].frequency = 903000000 + (i - (US915_HYBRID_MAX_NB_CHANNELS - 8)) * 1600000; + channels[i].dr_range.value = ( DR_4 << 4 ) | DR_4; + channels[i].band = 0; + } + + // ChannelsMask + default_channel_masks[0] = 0x00FF; + default_channel_masks[1] = 0x0000; + default_channel_masks[2] = 0x0000; + default_channel_masks[3] = 0x0000; + default_channel_masks[4] = 0x0001; + + memset(channel_masks, 0, sizeof(channel_masks)); + memset(current_channel_masks, 0, sizeof(current_channel_masks)); + + // Copy channels default mask + copy_channel_mask(channel_masks, default_channel_masks, US915_HYBRID_CHANNELS_MASK_SIZE); + + // Copy into channels mask remaining + copy_channel_mask(current_channel_masks, channel_masks, US915_HYBRID_CHANNELS_MASK_SIZE); + + // set default channels + phy_params.channels.channel_list = channels; + phy_params.channels.channel_list_size = US915_HYBRID_MAX_NB_CHANNELS; + phy_params.channels.mask_list = channel_masks; + phy_params.channels.default_mask_list = default_channel_masks; + phy_params.channels.mask_list_size = US915_HYBRID_CHANNELS_MASK_SIZE; + + // set bands for US915_HYBRID spectrum + phy_params.bands.table = (void *) bands; + phy_params.bands.size = US915_HYBRID_MAX_NB_BANDS; + + // set bandwidths available in US915_HYBRID spectrum + phy_params.bandwidths.table = (void *) bandwidths_US915_HYBRID; + phy_params.bandwidths.size = 16; + + // set data rates available in US915_HYBRID spectrum + phy_params.datarates.table = (void *) datarates_US915_HYBRID; + phy_params.datarates.size = 16; + + // set payload sizes with respect to data rates + phy_params.payloads.table = (void *) max_payloads_US915_HYBRID; + phy_params.payloads.size = 16; + phy_params.payloads_with_repeater.table = (void *) max_payloads_with_repeater_US915_HYBRID; + phy_params.payloads.size = 16; + + // dwell time setting + phy_params.ul_dwell_time_setting = 0; + phy_params.dl_dwell_time_setting = 0; + + // set initial and default parameters + phy_params.duty_cycle_enabled = US915_HYBRID_DUTY_CYCLE_ENABLED; + phy_params.accept_tx_param_setup_req = false; + phy_params.fsk_supported = false; + phy_params.cflist_supported = false; + phy_params.dl_channel_req_supported = false; + phy_params.custom_channelplans_supported = false; + phy_params.default_channel_cnt = US915_HYBRID_MAX_NB_CHANNELS; + phy_params.max_channel_cnt = US915_HYBRID_MAX_NB_CHANNELS; + phy_params.cflist_channel_cnt = 0; + phy_params.min_tx_datarate = US915_HYBRID_TX_MIN_DATARATE; + phy_params.max_tx_datarate = US915_HYBRID_TX_MAX_DATARATE; + phy_params.min_rx_datarate = US915_HYBRID_RX_MIN_DATARATE; + phy_params.max_rx_datarate = US915_HYBRID_RX_MAX_DATARATE; + phy_params.default_datarate = US915_HYBRID_DEFAULT_DATARATE; + phy_params.default_max_datarate = US915_HYBRID_TX_MAX_DATARATE; + phy_params.min_rx1_dr_offset = US915_HYBRID_MIN_RX1_DR_OFFSET; + phy_params.max_rx1_dr_offset = US915_HYBRID_MAX_RX1_DR_OFFSET; + phy_params.default_rx1_dr_offset = US915_HYBRID_DEFAULT_RX1_DR_OFFSET; + phy_params.min_tx_power = US915_HYBRID_MIN_TX_POWER; + phy_params.max_tx_power = US915_HYBRID_MAX_TX_POWER; + phy_params.default_tx_power = US915_HYBRID_DEFAULT_TX_POWER; + phy_params.default_max_eirp = 0; + phy_params.default_antenna_gain = 0; + phy_params.adr_ack_limit = US915_HYBRID_ADR_ACK_LIMIT; + phy_params.adr_ack_delay = US915_HYBRID_ADR_ACK_DELAY; + phy_params.max_rx_window = US915_HYBRID_MAX_RX_WINDOW; + phy_params.recv_delay1 = US915_HYBRID_RECEIVE_DELAY1; + phy_params.recv_delay2 = US915_HYBRID_RECEIVE_DELAY2; + + phy_params.join_accept_delay1 = US915_HYBRID_JOIN_ACCEPT_DELAY1; + phy_params.join_accept_delay2 = US915_HYBRID_JOIN_ACCEPT_DELAY2; + phy_params.max_fcnt_gap = US915_HYBRID_MAX_FCNT_GAP; + phy_params.ack_timeout = US915_HYBRID_ACKTIMEOUT; + phy_params.ack_timeout_rnd = US915_HYBRID_ACK_TIMEOUT_RND; + phy_params.rx_window2_datarate = US915_HYBRID_RX_WND_2_DR; + phy_params.rx_window2_frequency = US915_HYBRID_RX_WND_2_FREQ; } LoRaPHYUS915Hybrid::~LoRaPHYUS915Hybrid() { } -PhyParam_t LoRaPHYUS915Hybrid::get_phy_params(GetPhyParams_t* getPhy) +void LoRaPHYUS915Hybrid::restore_default_channels() { - PhyParam_t phyParam = { 0 }; + // Copy channels default mask + copy_channel_mask(channel_masks, default_channel_masks, US915_HYBRID_CHANNELS_MASK_SIZE); - switch( getPhy->Attribute ) - { - case PHY_MIN_RX_DR: - { - phyParam.Value = US915_HYBRID_RX_MIN_DATARATE; - break; - } - case PHY_MIN_TX_DR: - { - phyParam.Value = US915_HYBRID_TX_MIN_DATARATE; - break; - } - case PHY_DEF_TX_DR: - { - phyParam.Value = US915_HYBRID_DEFAULT_DATARATE; - break; - } - case PHY_NEXT_LOWER_TX_DR: - { - phyParam.Value = GetNextLowerTxDr( getPhy->Datarate, US915_HYBRID_TX_MIN_DATARATE ); - break; - } - case PHY_DEF_TX_POWER: - { - phyParam.Value = US915_HYBRID_DEFAULT_TX_POWER; - break; - } - case PHY_MAX_PAYLOAD: - { - phyParam.Value = MaxPayloadOfDatarateUS915_HYBRID[getPhy->Datarate]; - break; - } - case PHY_MAX_PAYLOAD_REPEATER: - { - phyParam.Value = MaxPayloadOfDatarateRepeaterUS915_HYBRID[getPhy->Datarate]; - break; - } - case PHY_DUTY_CYCLE: - { - phyParam.Value = US915_HYBRID_DUTY_CYCLE_ENABLED; - break; - } - case PHY_MAX_RX_WINDOW: - { - phyParam.Value = US915_HYBRID_MAX_RX_WINDOW; - break; - } - case PHY_RECEIVE_DELAY1: - { - phyParam.Value = US915_HYBRID_RECEIVE_DELAY1; - break; - } - case PHY_RECEIVE_DELAY2: - { - phyParam.Value = US915_HYBRID_RECEIVE_DELAY2; - break; - } - case PHY_JOIN_ACCEPT_DELAY1: - { - phyParam.Value = US915_HYBRID_JOIN_ACCEPT_DELAY1; - break; - } - case PHY_JOIN_ACCEPT_DELAY2: - { - phyParam.Value = US915_HYBRID_JOIN_ACCEPT_DELAY2; - break; - } - case PHY_MAX_FCNT_GAP: - { - phyParam.Value = US915_HYBRID_MAX_FCNT_GAP; - break; - } - case PHY_ACK_TIMEOUT: - { - phyParam.Value = ( US915_HYBRID_ACKTIMEOUT + get_random( -US915_HYBRID_ACK_TIMEOUT_RND, US915_HYBRID_ACK_TIMEOUT_RND ) ); - break; - } - case PHY_DEF_DR1_OFFSET: - { - phyParam.Value = US915_HYBRID_DEFAULT_RX1_DR_OFFSET; - break; - } - case PHY_DEF_RX2_FREQUENCY: - { - phyParam.Value = US915_HYBRID_RX_WND_2_FREQ; - break; - } - case PHY_DEF_RX2_DR: - { - phyParam.Value = US915_HYBRID_RX_WND_2_DR; - break; - } - case PHY_CHANNELS_MASK: - { - phyParam.ChannelsMask = ChannelsMask; - break; - } - case PHY_CHANNELS_DEFAULT_MASK: - { - phyParam.ChannelsMask = ChannelsDefaultMask; - break; - } - case PHY_MAX_NB_CHANNELS: - { - phyParam.Value = US915_HYBRID_MAX_NB_CHANNELS; - break; - } - case PHY_CHANNELS: - { - phyParam.Channels = Channels; - break; - } - case PHY_DEF_UPLINK_DWELL_TIME: - case PHY_DEF_DOWNLINK_DWELL_TIME: - { - phyParam.Value = 0; - break; - } - case PHY_DEF_MAX_EIRP: - case PHY_DEF_ANTENNA_GAIN: - { - phyParam.fValue = 0; - break; - } - case PHY_NB_JOIN_TRIALS: - case PHY_DEF_NB_JOIN_TRIALS: - { - phyParam.Value = 2; - break; - } - default: - { - break; - } - } - - return phyParam; -} - -void LoRaPHYUS915Hybrid::set_band_tx_done(SetBandTxDoneParams_t* txDone) -{ - set_last_tx_done( txDone->Joined, &Bands[Channels[txDone->Channel].band], txDone->LastTxDoneTime ); -} - -void LoRaPHYUS915Hybrid::load_defaults(InitType_t type) -{ - switch( type ) - { - case INIT_TYPE_INIT: - { - // Channels - // 125 kHz channels - for( uint8_t i = 0; i < US915_HYBRID_MAX_NB_CHANNELS - 8; i++ ) - { - Channels[i].frequency = 902300000 + i * 200000; - Channels[i].dr_range.value = ( DR_3 << 4 ) | DR_0; - Channels[i].band = 0; - } - // 500 kHz channels - for( uint8_t i = US915_HYBRID_MAX_NB_CHANNELS - 8; i < US915_HYBRID_MAX_NB_CHANNELS; i++ ) - { - Channels[i].frequency = 903000000 + ( i - ( US915_HYBRID_MAX_NB_CHANNELS - 8 ) ) * 1600000; - Channels[i].dr_range.value = ( DR_4 << 4 ) | DR_4; - Channels[i].band = 0; - } - - // ChannelsMask - ChannelsDefaultMask[0] = 0x00FF; - ChannelsDefaultMask[1] = 0x0000; - ChannelsDefaultMask[2] = 0x0000; - ChannelsDefaultMask[3] = 0x0000; - ChannelsDefaultMask[4] = 0x0001; - ChannelsDefaultMask[5] = 0x0000; - - // Copy channels default mask - copy_channel_mask( ChannelsMask, ChannelsDefaultMask, 6 ); - - // Copy into channels mask remaining - copy_channel_mask( ChannelsMaskRemaining, ChannelsMask, 6 ); - break; - } - case INIT_TYPE_RESTORE: - { - ReenableChannels( ChannelsDefaultMask[4], ChannelsMask ); - - for( uint8_t i = 0; i < 6; i++ ) - { // Copy-And the channels mask - ChannelsMaskRemaining[i] &= ChannelsMask[i]; - } - } - default: - { - break; - } + for (uint8_t i = 0; i < US915_HYBRID_CHANNELS_MASK_SIZE; i++) { + // Copy-And the channels mask + current_channel_masks[i] &= channel_masks[i]; } } -bool LoRaPHYUS915Hybrid::verify(VerifyParams_t* verify, PhyAttribute_t phyAttribute) -{ - switch( phyAttribute ) - { - case PHY_TX_DR: - { - return val_in_range( verify->DatarateParams.Datarate, US915_HYBRID_TX_MIN_DATARATE, US915_HYBRID_TX_MAX_DATARATE ); - } - case PHY_DEF_TX_DR: - { - return val_in_range( verify->DatarateParams.Datarate, DR_0, DR_5 ); - } - case PHY_RX_DR: - { - return val_in_range( verify->DatarateParams.Datarate, US915_HYBRID_RX_MIN_DATARATE, US915_HYBRID_RX_MAX_DATARATE ); - } - case PHY_DEF_TX_POWER: - case PHY_TX_POWER: - { - // Remark: switched min and max! - return val_in_range( verify->TxPower, US915_HYBRID_MAX_TX_POWER, US915_HYBRID_MIN_TX_POWER ); - } - case PHY_DUTY_CYCLE: - { - return US915_HYBRID_DUTY_CYCLE_ENABLED; - } - case PHY_NB_JOIN_TRIALS: - { - if( verify->NbJoinTrials < 2 ) - { - return false; - } - break; - } - default: - return false; - } - return true; -} - -void LoRaPHYUS915Hybrid::apply_cf_list(ApplyCFListParams_t* applyCFList) -{ - return; -} - -bool LoRaPHYUS915Hybrid::set_channel_mask(ChanMaskSetParams_t* chanMaskSet) -{ - uint8_t nbChannels = num_active_channels( chanMaskSet->ChannelsMaskIn, 0, 4 ); - - // Check the number of active channels - if( ( nbChannels < 2 ) && - ( nbChannels > 0 ) ) - { - return false; - } - - // Validate the channels mask - if( ValidateChannelsMask( chanMaskSet->ChannelsMaskIn ) == false ) - { - return false; - } - - switch( chanMaskSet->ChannelsMaskType ) - { - case CHANNELS_MASK: - { - copy_channel_mask( ChannelsMask, chanMaskSet->ChannelsMaskIn, 6 ); - - for( uint8_t i = 0; i < 6; i++ ) - { // Copy-And the channels mask - ChannelsMaskRemaining[i] &= ChannelsMask[i]; - } - break; - } - case CHANNELS_DEFAULT_MASK: - { - copy_channel_mask( ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 6 ); - break; - } - default: - return false; - } - return true; -} - -bool LoRaPHYUS915Hybrid::get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut, - int8_t* txPowOut, uint32_t* adrAckCounter) +bool LoRaPHYUS915Hybrid::get_next_ADR(bool restore_channel_mask, int8_t& dr_out, + int8_t& tx_power_out, uint32_t& adr_ack_cnt) { bool adrAckReq = false; - int8_t datarate = adrNext->Datarate; - int8_t txPower = adrNext->TxPower; - GetPhyParams_t getPhy; - PhyParam_t phyParam; - // Report back the adr ack counter - *adrAckCounter = adrNext->AdrAckCounter; + get_phy_params_t get_phy; + phy_param_t phy_param; - if( adrNext->AdrEnabled == true ) - { - if( datarate == US915_HYBRID_TX_MIN_DATARATE ) - { - *adrAckCounter = 0; - adrAckReq = false; - } - else - { - if( adrNext->AdrAckCounter >= US915_HYBRID_ADR_ACK_LIMIT ) - { - adrAckReq = true; - txPower = US915_HYBRID_MAX_TX_POWER; - } - else - { + uint16_t ack_limit_plus_delay = phy_params.adr_ack_limit + phy_params.adr_ack_delay; + + if (dr_out == phy_params.min_tx_datarate) { + adr_ack_cnt = 0; + return adrAckReq; + } + + if (adr_ack_cnt < phy_params.adr_ack_limit) { + return adrAckReq; + } + + // ADR ack counter is larger than ADR-ACK-LIMIT + adrAckReq = true; + tx_power_out = phy_params.max_tx_power; + + + if (adr_ack_cnt >= ack_limit_plus_delay) { + if ((adr_ack_cnt % phy_params.adr_ack_delay) == 1) { + // Decrease the datarate + get_phy.attribute = PHY_NEXT_LOWER_TX_DR; + get_phy.datarate = dr_out; + phy_param = get_phy_params(&get_phy); + dr_out = phy_param.value; + + if (dr_out == phy_params.min_tx_datarate) { + // We must set adrAckReq to false as soon as we reach the lowest datarate adrAckReq = false; - } - if( adrNext->AdrAckCounter >= ( US915_HYBRID_ADR_ACK_LIMIT + US915_HYBRID_ADR_ACK_DELAY ) ) - { - if( ( adrNext->AdrAckCounter % US915_HYBRID_ADR_ACK_DELAY ) == 1 ) - { - // Decrease the datarate - getPhy.Attribute = PHY_NEXT_LOWER_TX_DR; - getPhy.Datarate = datarate; - getPhy.UplinkDwellTime = adrNext->UplinkDwellTime; - phyParam = get_phy_params( &getPhy ); - datarate = phyParam.Value; - - if( datarate == US915_HYBRID_TX_MIN_DATARATE ) - { - // We must set adrAckReq to false as soon as we reach the lowest datarate - adrAckReq = false; - if( adrNext->UpdateChanMask == true ) - { - // Re-enable default channels - ReenableChannels( ChannelsMask[4], ChannelsMask ); - } - } + if (restore_channel_mask) { + // Re-enable default channels + reenable_500khz_channels(channel_masks[4], channel_masks); } } } } - *drOut = datarate; - *txPowOut = txPower; return adrAckReq; } -void LoRaPHYUS915Hybrid::compute_rx_win_params(int8_t datarate, uint8_t minRxSymbols, - uint32_t rxError, rx_config_params_t *rxConfigParams) +bool LoRaPHYUS915Hybrid::rx_config(rx_config_params_t* config, int8_t* datarate) { - double tSymbol = 0.0; + int8_t dr = config->datarate; + uint8_t max_payload = 0; + int8_t phy_dr = 0; + uint32_t frequency = config->frequency; - // Get the datarate, perform a boundary check - rxConfigParams->datarate = MIN( datarate, US915_HYBRID_RX_MAX_DATARATE ); - rxConfigParams->bandwidth = GetBandwidth( rxConfigParams->datarate ); + _radio->lock(); - tSymbol = compute_symb_timeout_lora( DataratesUS915_HYBRID[rxConfigParams->datarate], BandwidthsUS915_HYBRID[rxConfigParams->datarate] ); + if (_radio->get_status() != RF_IDLE) { - get_rx_window_params( tSymbol, minRxSymbols, rxError, RADIO_WAKEUP_TIME, &rxConfigParams->window_timeout, &rxConfigParams->window_offset ); -} - -bool LoRaPHYUS915Hybrid::rx_config(rx_config_params_t* rxConfig, int8_t* datarate) -{ - int8_t dr = rxConfig->datarate; - uint8_t maxPayload = 0; - int8_t phyDr = 0; - uint32_t frequency = rxConfig->frequency; - - if( _radio->get_status() != RF_IDLE ) - { + _radio->unlock(); return false; + } - if( rxConfig->rx_slot == RX_SLOT_WIN_1 ) - { + _radio->unlock(); + + if (config->rx_slot == RX_SLOT_WIN_1) { // Apply window 1 frequency - frequency = US915_HYBRID_FIRST_RX1_CHANNEL + ( rxConfig->channel % 8 ) * US915_HYBRID_STEPWIDTH_RX1_CHANNEL; + frequency = US915_HYBRID_FIRST_RX1_CHANNEL + (config->channel % 8) * US915_HYBRID_STEPWIDTH_RX1_CHANNEL; } // Read the physical datarate from the datarates table - phyDr = DataratesUS915_HYBRID[dr]; + phy_dr = datarates_US915_HYBRID[dr]; + + _radio->lock(); _radio->set_channel( frequency ); // Radio configuration - _radio->set_rx_config( MODEM_LORA, rxConfig->bandwidth, phyDr, 1, 0, 8, rxConfig->window_timeout, false, 0, false, 0, 0, true, rxConfig->is_rx_continuous ); + _radio->set_rx_config(MODEM_LORA, config->bandwidth, phy_dr, 1, 0, 8, + config->window_timeout, false, 0, false, 0, 0, true, + config->is_rx_continuous); - if( rxConfig->is_repeater_supported == true ) - { - maxPayload = MaxPayloadOfDatarateRepeaterUS915_HYBRID[dr]; + _radio->unlock(); + + if (config->is_repeater_supported == true) { + max_payload = max_payloads_with_repeater_US915_HYBRID[dr]; + } else { + max_payload = max_payloads_US915_HYBRID[dr]; } - else - { - maxPayload = MaxPayloadOfDatarateUS915_HYBRID[dr]; - } - _radio->set_max_payload_length( MODEM_LORA, maxPayload + LORA_MAC_FRMPAYLOAD_OVERHEAD ); + + _radio->lock(); + _radio->set_max_payload_length(MODEM_LORA, max_payload + LORA_MAC_FRMPAYLOAD_OVERHEAD); + _radio->unlock(); *datarate = (uint8_t) dr; return true; } -bool LoRaPHYUS915Hybrid::tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - lorawan_time_t* txTimeOnAir) +bool LoRaPHYUS915Hybrid::tx_config(tx_config_params_t* config, int8_t* tx_power, + lorawan_time_t* tx_toa) { - int8_t phyDr = DataratesUS915_HYBRID[txConfig->Datarate]; - int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, Bands[Channels[txConfig->Channel].band].max_tx_pwr, txConfig->Datarate, ChannelsMask ); - uint32_t bandwidth = GetBandwidth( txConfig->Datarate ); - int8_t phyTxPower = 0; + int8_t phy_dr = datarates_US915_HYBRID[config->datarate]; + + int8_t tx_power_limited = limit_tx_power(config->tx_power, + bands[channels[config->channel].band].max_tx_pwr, + config->datarate); + + uint32_t bandwidth = get_bandwidth (config->datarate); + int8_t phy_tx_power = 0; // Calculate physical TX power - phyTxPower = compute_tx_power( txPowerLimited, US915_HYBRID_DEFAULT_MAX_ERP, 0 ); + phy_tx_power = compute_tx_power(tx_power_limited, US915_HYBRID_DEFAULT_MAX_ERP, 0); - // Setup the radio frequency - _radio->set_channel( Channels[txConfig->Channel].frequency ); + _radio->lock(); - _radio->set_tx_config( MODEM_LORA, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 3000 ); + _radio->set_channel( channels[config->channel].frequency ); + + _radio->set_tx_config(MODEM_LORA, phy_tx_power, 0, bandwidth, phy_dr, 1, 8, + false, true, 0, 0, false, 3000); // Setup maximum payload lenght of the radio driver - _radio->set_max_payload_length( MODEM_LORA, txConfig->PktLen ); + _radio->set_max_payload_length(MODEM_LORA, config->pkt_len); + // Get the time-on-air of the next tx frame - *txTimeOnAir = _radio->time_on_air( MODEM_LORA, txConfig->PktLen ); - *txPower = txPowerLimited; + *tx_toa = _radio->time_on_air(MODEM_LORA, config->pkt_len); + + _radio->unlock(); + *tx_power = tx_power_limited; return true; } -uint8_t LoRaPHYUS915Hybrid::link_ADR_request(LinkAdrReqParams_t* linkAdrReq, - int8_t* drOut, int8_t* txPowOut, - uint8_t* nbRepOut, - uint8_t* nbBytesParsed) +uint8_t LoRaPHYUS915Hybrid::link_ADR_request(adr_req_params_t* params, + int8_t* dr_out, int8_t* tx_power_out, + uint8_t* nb_rep_out, + uint8_t* nb_bytes_parsed) { uint8_t status = 0x07; - RegionCommonLinkAdrParams_t linkAdrParams; - uint8_t nextIndex = 0; - uint8_t bytesProcessed = 0; - uint16_t channelsMask[6] = { 0, 0, 0, 0, 0, 0 }; - GetPhyParams_t getPhy; - PhyParam_t phyParam; - RegionCommonLinkAdrReqVerifyParams_t linkAdrVerifyParams; + link_adr_params_t adr_settings; + uint8_t next_idx = 0; + uint8_t bytes_processed = 0; + uint16_t temp_channel_masks[US915_HYBRID_CHANNELS_MASK_SIZE] = {0, 0, 0, 0, 0}; + + verify_adr_params_t verify_params; // Initialize local copy of channels mask - copy_channel_mask( channelsMask, ChannelsMask, 6 ); + copy_channel_mask(temp_channel_masks, channel_masks, US915_HYBRID_CHANNELS_MASK_SIZE); - while( bytesProcessed < linkAdrReq->PayloadSize ) - { - nextIndex = parse_link_ADR_req( &( linkAdrReq->Payload[bytesProcessed] ), &linkAdrParams ); + while (bytes_processed < params->payload_size) { + next_idx = parse_link_ADR_req(&(params->payload[bytes_processed]), + &adr_settings); - if( nextIndex == 0 ) + if (next_idx == 0) { break; // break loop, since no more request has been found + } // Update bytes processed - bytesProcessed += nextIndex; + bytes_processed += next_idx; // Revert status, as we only check the last ADR request for the channel mask KO status = 0x07; - if( linkAdrParams.ChMaskCtrl == 6 ) - { + if (adr_settings.ch_mask_ctrl == 6) { // Enable all 125 kHz channels - channelsMask[0] = 0xFFFF; - channelsMask[1] = 0xFFFF; - channelsMask[2] = 0xFFFF; - channelsMask[3] = 0xFFFF; + temp_channel_masks[0] = 0xFFFF; + temp_channel_masks[1] = 0xFFFF; + temp_channel_masks[2] = 0xFFFF; + temp_channel_masks[3] = 0xFFFF; // Apply chMask to channels 64 to 71 - channelsMask[4] = linkAdrParams.ChMask; - } - else if( linkAdrParams.ChMaskCtrl == 7 ) - { + temp_channel_masks[4] = adr_settings.channel_mask; + } else if( adr_settings.ch_mask_ctrl == 7 ) { // Disable all 125 kHz channels - channelsMask[0] = 0x0000; - channelsMask[1] = 0x0000; - channelsMask[2] = 0x0000; - channelsMask[3] = 0x0000; + temp_channel_masks[0] = 0x0000; + temp_channel_masks[1] = 0x0000; + temp_channel_masks[2] = 0x0000; + temp_channel_masks[3] = 0x0000; // Apply chMask to channels 64 to 71 - channelsMask[4] = linkAdrParams.ChMask; - } - else if( linkAdrParams.ChMaskCtrl == 5 ) - { + temp_channel_masks[4] = adr_settings.channel_mask; + } else if( adr_settings.ch_mask_ctrl == 5 ) { // RFU status &= 0xFE; // Channel mask KO - } - else - { - channelsMask[linkAdrParams.ChMaskCtrl] = linkAdrParams.ChMask; + } else { + temp_channel_masks[adr_settings.ch_mask_ctrl] = adr_settings.channel_mask; } } // FCC 15.247 paragraph F mandates to hop on at least 2 125 kHz channels - if( ( linkAdrParams.Datarate < DR_4 ) && ( num_active_channels( channelsMask, 0, 4 ) < 2 ) ) - { + if ((adr_settings.datarate < DR_4) && + (num_active_channels( temp_channel_masks, 0, 4 ) < 2)) { status &= 0xFE; // Channel mask KO } - if( ValidateChannelsMask( channelsMask ) == false ) - { + if( validate_channel_mask(temp_channel_masks ) == false) { status &= 0xFE; // Channel mask KO } - // Get the minimum possible datarate - getPhy.Attribute = PHY_MIN_TX_DR; - getPhy.UplinkDwellTime = linkAdrReq->UplinkDwellTime; - phyParam = get_phy_params( &getPhy ); + verify_params.status = status; + verify_params.adr_enabled = params->adr_enabled; + verify_params.datarate = adr_settings.datarate; + verify_params.tx_power = adr_settings.tx_power; + verify_params.nb_rep = adr_settings.nb_rep; + verify_params.current_datarate = params->current_datarate; + verify_params.current_tx_power = params->current_tx_power; + verify_params.current_nb_rep = params->current_nb_rep; + verify_params.channel_mask = temp_channel_masks; - linkAdrVerifyParams.Status = status; - linkAdrVerifyParams.AdrEnabled = linkAdrReq->AdrEnabled; - linkAdrVerifyParams.Datarate = linkAdrParams.Datarate; - linkAdrVerifyParams.TxPower = linkAdrParams.TxPower; - linkAdrVerifyParams.NbRep = linkAdrParams.NbRep; - linkAdrVerifyParams.CurrentDatarate = linkAdrReq->CurrentDatarate; - linkAdrVerifyParams.CurrentTxPower = linkAdrReq->CurrentTxPower; - linkAdrVerifyParams.CurrentNbRep = linkAdrReq->CurrentNbRep; - linkAdrVerifyParams.NbChannels = US915_HYBRID_MAX_NB_CHANNELS; - linkAdrVerifyParams.ChannelsMask = channelsMask; - linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value; - linkAdrVerifyParams.MaxDatarate = US915_HYBRID_TX_MAX_DATARATE; - linkAdrVerifyParams.Channels = Channels; - linkAdrVerifyParams.MinTxPower = US915_HYBRID_MIN_TX_POWER; - linkAdrVerifyParams.MaxTxPower = US915_HYBRID_MAX_TX_POWER; // Verify the parameters and update, if necessary - status = verify_link_ADR_req( &linkAdrVerifyParams, &linkAdrParams.Datarate, &linkAdrParams.TxPower, &linkAdrParams.NbRep ); + status = verify_link_ADR_req(&verify_params, &adr_settings.datarate, + &adr_settings.tx_power, &adr_settings.nb_rep); // Update channelsMask if everything is correct - if( status == 0x07 ) - { + if (status == 0x07) { // Copy Mask - copy_channel_mask( ChannelsMask, channelsMask, 6 ); + copy_channel_mask(channel_masks, temp_channel_masks, US915_HYBRID_CHANNELS_MASK_SIZE); - ChannelsMaskRemaining[0] &= ChannelsMask[0]; - ChannelsMaskRemaining[1] &= ChannelsMask[1]; - ChannelsMaskRemaining[2] &= ChannelsMask[2]; - ChannelsMaskRemaining[3] &= ChannelsMask[3]; - ChannelsMaskRemaining[4] = ChannelsMask[4]; - ChannelsMaskRemaining[5] = ChannelsMask[5]; + current_channel_masks[0] &= channel_masks[0]; + current_channel_masks[1] &= channel_masks[1]; + current_channel_masks[2] &= channel_masks[2]; + current_channel_masks[3] &= channel_masks[3]; + current_channel_masks[4] = channel_masks[4]; } // Update status variables - *drOut = linkAdrParams.Datarate; - *txPowOut = linkAdrParams.TxPower; - *nbRepOut = linkAdrParams.NbRep; - *nbBytesParsed = bytesProcessed; + *dr_out = adr_settings.datarate; + *tx_power_out = adr_settings.tx_power; + *nb_rep_out = adr_settings.nb_rep; + *nb_bytes_parsed = bytes_processed; return status; } -uint8_t LoRaPHYUS915Hybrid::setup_rx_params(RxParamSetupReqParams_t* rxParamSetupReq) +uint8_t LoRaPHYUS915Hybrid::accept_rx_param_setup_req(rx_param_setup_req_t* params) { uint8_t status = 0x07; - uint32_t freq = rxParamSetupReq->Frequency; + uint32_t freq = params->frequency; // Verify radio frequency - if( ( _radio->check_rf_frequency( freq ) == false ) || - ( freq < US915_HYBRID_FIRST_RX1_CHANNEL ) || - ( freq > US915_HYBRID_LAST_RX1_CHANNEL ) || - ( ( ( freq - ( uint32_t ) US915_HYBRID_FIRST_RX1_CHANNEL ) % ( uint32_t ) US915_HYBRID_STEPWIDTH_RX1_CHANNEL ) != 0 ) ) - { + if ((_radio->check_rf_frequency(freq) == false) + || (freq < US915_HYBRID_FIRST_RX1_CHANNEL) + || (freq > US915_HYBRID_LAST_RX1_CHANNEL) + || (((freq - ( uint32_t ) US915_HYBRID_FIRST_RX1_CHANNEL) % (uint32_t) US915_HYBRID_STEPWIDTH_RX1_CHANNEL) != 0)) { status &= 0xFE; // Channel frequency KO } // Verify datarate - if( val_in_range( rxParamSetupReq->Datarate, US915_HYBRID_RX_MIN_DATARATE, US915_HYBRID_RX_MAX_DATARATE ) == 0 ) - { + if (val_in_range(params->datarate, US915_HYBRID_RX_MIN_DATARATE, US915_HYBRID_RX_MAX_DATARATE) == 0) { status &= 0xFD; // Datarate KO } - if( ( val_in_range( rxParamSetupReq->Datarate, DR_5, DR_7 ) == 1 ) || - ( rxParamSetupReq->Datarate > DR_13 ) ) - { + + if ((val_in_range(params->datarate, DR_5, DR_7) == 1) + || (params->datarate > DR_13)) { status &= 0xFD; // Datarate KO } // Verify datarate offset - if( val_in_range( rxParamSetupReq->DrOffset, US915_HYBRID_MIN_RX1_DR_OFFSET, US915_HYBRID_MAX_RX1_DR_OFFSET ) == 0 ) - { + if (val_in_range(params->dr_offset, US915_HYBRID_MIN_RX1_DR_OFFSET, US915_HYBRID_MAX_RX1_DR_OFFSET) == 0) { status &= 0xFB; // Rx1DrOffset range KO } return status; } -uint8_t LoRaPHYUS915Hybrid::request_new_channel(NewChannelReqParams_t* newChannelReq) -{ - // Datarate and frequency KO - return 0; -} - -int8_t LoRaPHYUS915Hybrid::setup_tx_params(TxParamSetupReqParams_t* txParamSetupReq) -{ - return -1; -} - -uint8_t LoRaPHYUS915Hybrid::dl_channel_request(DlChannelReqParams_t* dlChannelReq) -{ - return 0; -} - -int8_t LoRaPHYUS915Hybrid::get_alternate_DR(AlternateDrParams_t* alternateDr) +int8_t LoRaPHYUS915Hybrid::get_alternate_DR(uint8_t nb_trials) { int8_t datarate = 0; // Re-enable 500 kHz default channels - ReenableChannels( ChannelsMask[4], ChannelsMask ); + reenable_500khz_channels(channel_masks[4], channel_masks); - if( ( alternateDr->NbTrials & 0x01 ) == 0x01 ) - { + if ((nb_trials & 0x01) == 0x01) { datarate = DR_4; - } - else - { + } else { datarate = DR_0; } + return datarate; } -void LoRaPHYUS915Hybrid::calculate_backoff(CalcBackOffParams_t* calcBackOff) -{ - RegionCommonCalcBackOffParams_t calcBackOffParams; - - calcBackOffParams.Channels = Channels; - calcBackOffParams.Bands = Bands; - calcBackOffParams.LastTxIsJoinRequest = calcBackOff->LastTxIsJoinRequest; - calcBackOffParams.Joined = calcBackOff->Joined; - calcBackOffParams.DutyCycleEnabled = calcBackOff->DutyCycleEnabled; - calcBackOffParams.Channel = calcBackOff->Channel; - calcBackOffParams.ElapsedTime = calcBackOff->ElapsedTime; - calcBackOffParams.TxTimeOnAir = calcBackOff->TxTimeOnAir; - - get_DC_backoff( &calcBackOffParams ); -} - -bool LoRaPHYUS915Hybrid::set_next_channel(NextChanParams_t* nextChanParams, +bool LoRaPHYUS915Hybrid::set_next_channel(channel_selection_params_t* params, uint8_t* channel, lorawan_time_t* time, - lorawan_time_t* aggregatedTimeOff) + lorawan_time_t* aggregate_timeOff) { - uint8_t nbEnabledChannels = 0; - uint8_t delayTx = 0; - uint8_t enabledChannels[US915_HYBRID_MAX_NB_CHANNELS] = { 0 }; - lorawan_time_t nextTxDelay = 0; + uint8_t nb_enabled_channels = 0; + uint8_t delay_tx = 0; + uint8_t enabled_channels[US915_HYBRID_MAX_NB_CHANNELS] = {0}; + lorawan_time_t next_tx_delay = 0; // Count 125kHz channels - if( num_active_channels( ChannelsMaskRemaining, 0, 4 ) == 0 ) - { // Reactivate default channels - copy_channel_mask( ChannelsMaskRemaining, ChannelsMask, 4 ); + if (num_active_channels(current_channel_masks, 0, 4) == 0) { + // Reactivate default channels + copy_channel_mask(current_channel_masks, channel_masks, 4); } + // Check other channels - if( nextChanParams->Datarate >= DR_4 ) - { - if( ( ChannelsMaskRemaining[4] & 0x00FF ) == 0 ) - { - ChannelsMaskRemaining[4] = ChannelsMask[4]; + if (params->current_datarate >= DR_4) { + if ((current_channel_masks[4] & 0x00FF ) == 0) { + current_channel_masks[4] = channel_masks[4]; } } - if( nextChanParams->AggrTimeOff <= _lora_time.TimerGetElapsedTime( nextChanParams->LastAggrTx ) ) - { + if (params->aggregate_timeoff <= _lora_time.TimerGetElapsedTime( params->last_aggregate_tx_time)) { // Reset Aggregated time off - *aggregatedTimeOff = 0; + *aggregate_timeOff = 0; // Update bands Time OFF - nextTxDelay = update_band_timeoff( nextChanParams->Joined, nextChanParams->DutyCycleEnabled, Bands, US915_HYBRID_MAX_NB_BANDS ); + next_tx_delay = update_band_timeoff(params->joined, + params->dc_enabled, bands, + US915_HYBRID_MAX_NB_BANDS); // Search how many channels are enabled - nbEnabledChannels = CountNbOfEnabledChannels( nextChanParams->Datarate, - ChannelsMaskRemaining, Channels, - Bands, enabledChannels, &delayTx ); - } - else - { - delayTx++; - nextTxDelay = nextChanParams->AggrTimeOff - _lora_time.TimerGetElapsedTime( nextChanParams->LastAggrTx ); + nb_enabled_channels = enabled_channel_count(params->joined, + params->current_datarate, + current_channel_masks, + US915_HYBRID_CHANNELS_MASK_SIZE, + enabled_channels, &delay_tx); + } else { + delay_tx++; + next_tx_delay = params->aggregate_timeoff - _lora_time.TimerGetElapsedTime(params->last_aggregate_tx_time); } - if( nbEnabledChannels > 0 ) - { + if (nb_enabled_channels > 0) { + // We found a valid channel - *channel = enabledChannels[get_random( 0, nbEnabledChannels - 1 )]; + *channel = enabled_channels[get_random(0, nb_enabled_channels - 1)]; // Disable the channel in the mask - disable_channel( ChannelsMaskRemaining, *channel, US915_HYBRID_MAX_NB_CHANNELS - 8 ); + disable_channel(current_channel_masks, *channel, US915_HYBRID_MAX_NB_CHANNELS - 8); *time = 0; return true; - } - else - { - if( delayTx > 0 ) - { + + } else { + + if (delay_tx > 0) { // Delay transmission due to AggregatedTimeOff or to a band time off - *time = nextTxDelay; + *time = next_tx_delay; return true; } + // Datarate not supported by any channel *time = 0; return false; } } -lorawan_status_t LoRaPHYUS915Hybrid::add_channel(ChannelAddParams_t* channelAdd) +void LoRaPHYUS915Hybrid::set_tx_cont_mode(cw_mode_params_t* params, uint32_t given_frequency) { - return LORAWAN_STATUS_PARAMETER_INVALID; -} + (void)given_frequency; -bool LoRaPHYUS915Hybrid::remove_channel(ChannelRemoveParams_t* channelRemove) -{ - return LORAWAN_STATUS_PARAMETER_INVALID; -} + int8_t tx_power_limited = limit_tx_power(params->tx_power, + bands[channels[params->channel].band].max_tx_pwr, + params->datarate); -void LoRaPHYUS915Hybrid::set_tx_cont_mode(ContinuousWaveParams_t* continuousWave) -{ - int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, Bands[Channels[continuousWave->Channel].band].max_tx_pwr, continuousWave->Datarate, ChannelsMask ); - int8_t phyTxPower = 0; - uint32_t frequency = Channels[continuousWave->Channel].frequency; + int8_t phy_tx_power = 0; + uint32_t frequency = channels[params->channel].frequency; // Calculate physical TX power - phyTxPower = compute_tx_power( txPowerLimited, US915_HYBRID_DEFAULT_MAX_ERP, 0 ); + phy_tx_power = compute_tx_power(tx_power_limited, US915_HYBRID_DEFAULT_MAX_ERP, 0); - _radio->set_tx_continuous_wave( frequency, phyTxPower, continuousWave->Timeout ); + _radio->lock(); + _radio->set_tx_continuous_wave(frequency, phy_tx_power, params->timeout); + _radio->unlock(); } -uint8_t LoRaPHYUS915Hybrid::apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset) +uint8_t LoRaPHYUS915Hybrid::apply_DR_offset(int8_t dr, int8_t drOffset) { - int8_t datarate = DatarateOffsetsUS915_HYBRID[dr][drOffset]; + int8_t datarate = datarate_offsets_US915_HYBRID[dr][drOffset]; - if( datarate < 0 ) - { + if (datarate < 0) { datarate = DR_0; } + return datarate; } + + +void LoRaPHYUS915Hybrid::reenable_500khz_channels(uint16_t mask, uint16_t* channelsMask) +{ + uint16_t blockMask = mask; + + for (uint8_t i = 0, j = 0; i < 4; i++, j += 2) { + channelsMask[i] = 0; + if ((blockMask & (1 << j)) != 0) { + channelsMask[i] |= 0x00FF; + } + + if ((blockMask & (1 << (j + 1))) != 0) { + channelsMask[i] |= 0xFF00; + } + } + + channelsMask[4] = blockMask; +} + +int8_t LoRaPHYUS915Hybrid::limit_tx_power(int8_t txPower, int8_t maxBandTxPower, + int8_t datarate) +{ + int8_t txPowerResult = txPower; + + // Limit tx power to the band max + txPowerResult = MAX(txPower, maxBandTxPower); + + if (datarate == DR_4) { + + // Limit tx power to max 26dBm + txPowerResult = MAX(txPower, TX_POWER_2); + + } else { + + if (num_active_channels(channel_masks, 0, 4) < 50) { + // Limit tx power to max 21dBm + txPowerResult = MAX(txPower, TX_POWER_5); + } + } + + return txPowerResult; +} + +bool LoRaPHYUS915Hybrid::validate_channel_mask(uint16_t* channel_masks) +{ + bool mask_state = false; + + uint16_t block1 = 0; + uint16_t block2 = 0; + uint8_t index = 0; + uint16_t temp_channel_masks[US915_HYBRID_CHANNELS_MASK_SIZE]; + + // Copy channels mask to not change the input + for (uint8_t i = 0; i < 4; i++) { + temp_channel_masks[i] = channel_masks[i]; + } + + for(uint8_t i = 0; i < 4; i++) { + block1 = temp_channel_masks[i] & 0x00FF; + block2 = temp_channel_masks[i] & 0xFF00; + + if (count_bits(block1, 16) > 5) { + + temp_channel_masks[i] &= block1; + temp_channel_masks[4] = 1 << ( i * 2 ); + mask_state = true; + index = i; + break; + + } else if( count_bits( block2, 16 ) > 5 ) { + + temp_channel_masks[i] &= block2; + temp_channel_masks[4] = 1 << ( i * 2 + 1 ); + mask_state = true; + index = i; + break; + + } + } + + // Do change the channel mask, if we have found a valid block. + if (mask_state == true) { + // Copy channels mask back again + for (uint8_t i = 0; i < 4; i++) { + channel_masks[i] = temp_channel_masks[i]; + + if (i != index) { + channel_masks[i] = 0; + } + } + + channel_masks[4] = temp_channel_masks[4]; + } + + return mask_state; +} diff --git a/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.h b/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.h index b894492665..9d7262fb41 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.h +++ b/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.h @@ -29,11 +29,10 @@ * */ -#ifndef MBED_OS_LORAPHY_US915HYBRID_H_ +#ifndef MBED_OS_LORAPHY_US915_HYBRID_H_ #define MBED_OS_LORAPHY_US915_HYBRID_H_ #include "LoRaPHY.h" -#include "netsocket/LoRaRadio.h" /*! @@ -46,7 +45,7 @@ */ #define US915_HYBRID_MAX_NB_BANDS 1 -#define US915_HYBRID_CHANNELS_MASK_SIZE 6 +#define US915_HYBRID_CHANNELS_MASK_SIZE 5 class LoRaPHYUS915Hybrid : public LoRaPHY { @@ -56,311 +55,63 @@ public: LoRaPHYUS915Hybrid(LoRaWANTimeHandler &lora_time); virtual ~LoRaPHYUS915Hybrid(); - /*! - * \brief The function gets a value of a specific PHY attribute. - * - * \param [in] getPhy A pointer to the function parameters. - * - * \retval The structure containing the PHY parameter. - */ - virtual PhyParam_t get_phy_params(GetPhyParams_t* getPhy ); + virtual void restore_default_channels(); - /*! - * \brief Updates the last TX done parameters of the current channel. - * - * \param [in] txDone A pointer to the function parameters. - */ - virtual void set_band_tx_done(SetBandTxDoneParams_t* txDone ); + virtual bool get_next_ADR(bool restore_channel_mask, int8_t& dr_out, + int8_t& tx_power_out, uint32_t& adr_ack_cnt); - /*! - * \brief Initializes the channels masks and the channels. - * - * \param [in] type Sets the initialization type. - */ - virtual void load_defaults(InitType_t type ); + virtual bool rx_config(rx_config_params_t* rxConfig, int8_t* datarate); - /*! - * \brief Verifies a parameter. - * - * \param [in] verify A pointer to the function parameters. - * - * \param [in] phyAttribute The attribute to verify. - * - * \retval True, if the parameter is valid. - */ - virtual bool verify(VerifyParams_t* verify, PhyAttribute_t phyAttribute ); + virtual bool tx_config(tx_config_params_t* tx_config, int8_t* tx_power, + lorawan_time_t* tx_toa); - /*! - * \brief The function parses the input buffer and sets up the channels of the CF list. - * - * \param [in] applyCFList A pointer to the function parameters. - */ - virtual void apply_cf_list(ApplyCFListParams_t* applyCFList ); + virtual uint8_t link_ADR_request(adr_req_params_t* params, + int8_t* dr_out, int8_t* tx_power_out, + uint8_t* nb_rep_out, + uint8_t* nb_bytes_parsed); - /*! - * \brief Sets a channels mask. - * - * \param [in] chanMaskSet A pointer to the function parameters. - * - * \retval True, if the channels mask could be set. - */ - virtual bool set_channel_mask(ChanMaskSetParams_t* chanMaskSet ); + virtual uint8_t accept_rx_param_setup_req(rx_param_setup_req_t* params); - /*! - * \brief Calculates the next datarate to set, when ADR is on or off. - * - * \param [in] adrNext A pointer to the function parameters. - * - * \param [out] drOut The calculated datarate for the next TX. - * - * \param [out] txPowOut The TX power for the next TX. - * - * \param [out] adrAckCounter The calculated ADR acknowledgement counter. - * - * \retval True, if an ADR request should be performed. - */ - virtual bool get_next_ADR(AdrNextParams_t* adrNext, int8_t* drOut, - int8_t* txPowOut, uint32_t* adrAckCounter ); + virtual int8_t get_alternate_DR(uint8_t nb_trials); - /*! - * \brief Configuration of the RX windows. - * - * \param [in] rxConfig A pointer to the function parameters. - * - * \param [out] datarate The datarate index set. - * - * \retval True, if the configuration was applied successfully. - */ - virtual bool rx_config(rx_config_params_t* rxConfig, int8_t* datarate ); - - /* - * RX window precise timing - * - * For more details, please consult the following document, chapter 3.1.2. - * http://www.semtech.com/images/datasheet/SX1272_settings_for_LoRaWAN_v2.0.pdf - * or - * http://www.semtech.com/images/datasheet/SX1276_settings_for_LoRaWAN_v2.0.pdf - * - * Downlink start: T = Tx + 1s (+/- 20 us) - * | - * TRxEarly | TRxLate - * | | | - * | | +---+---+---+---+---+---+---+---+ - * | | | Latest Rx window | - * | | +---+---+---+---+---+---+---+---+ - * | | | - * +---+---+---+---+---+---+---+---+ - * | Earliest Rx window | - * +---+---+---+---+---+---+---+---+ - * | - * +---+---+---+---+---+---+---+---+ - *Downlink preamble 8 symbols | | | | | | | | | - * +---+---+---+---+---+---+---+---+ - * - * Worst case Rx window timings - * - * TRxLate = DEFAULT_MIN_RX_SYMBOLS * tSymbol - RADIO_WAKEUP_TIME - * TRxEarly = 8 - DEFAULT_MIN_RX_SYMBOLS * tSymbol - RxWindowTimeout - RADIO_WAKEUP_TIME - * - * TRxLate - TRxEarly = 2 * DEFAULT_SYSTEM_MAX_RX_ERROR - * - * RxOffset = ( TRxLate + TRxEarly ) / 2 - * - * RxWindowTimeout = ( 2 * DEFAULT_MIN_RX_SYMBOLS - 8 ) * tSymbol + 2 * DEFAULT_SYSTEM_MAX_RX_ERROR - * RxOffset = 4 * tSymbol - RxWindowTimeout / 2 - RADIO_WAKE_UP_TIME - * - * The minimum value of RxWindowTimeout must be 5 symbols which implies that the system always tolerates at least an error of 1.5 * tSymbol - */ - /*! - * Computes the RX window timeout and offset. - * - * \param [in] datarate The RX window datarate index to be used. - * - * \param [in] minRxSymbols The minimum number of symbols required to detect an RX frame. - * - * \param [in] rxError The system maximum timing error of the receiver in milliseconds. - * The receiver will turn on in a [-rxError : +rxError] ms - * interval around RxOffset. - * - * \param [out] rxConfigParams Returns the updated WindowTimeout and WindowOffset fields. - */ - virtual void compute_rx_win_params(int8_t datarate, - uint8_t minRxSymbols, - uint32_t rxError, - rx_config_params_t *rxConfigParams); - - /*! - * \brief TX configuration. - * - * \param [in] txConfig A pointer to the function parameters. - * - * \param [out] txPower The TX power index set. - * - * \param [out] txTimeOnAir The time-on-air of the frame. - * - * \retval True, if the configuration was applied successfully. - */ - virtual bool tx_config(TxConfigParams_t* txConfig, int8_t* txPower, - lorawan_time_t* txTimeOnAir ); - - /*! - * \brief The function processes a Link ADR request. - * - * \param [in] linkAdrReq A pointer to the function parameters. - * - * \param [out] drOut The datarate applied. - * - * \param [out] txPowOut The TX power applied. - * - * \param [out] nbRepOut The number of repetitions to apply. - * - * \param [out] nbBytesParsed The number of bytes parsed. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t link_ADR_request(LinkAdrReqParams_t* linkAdrReq, - int8_t* drOut, int8_t* txPowOut, - uint8_t* nbRepOut, - uint8_t* nbBytesParsed ); - - /*! - * \brief The function processes a RX parameter setup request. - * - * \param [in] rxParamSetupReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t setup_rx_params(RxParamSetupReqParams_t* rxParamSetupReq ); - - /*! - * \brief The function processes a new channel request. - * - * \param [in] newChannelReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t request_new_channel(NewChannelReqParams_t* newChannelReq ); - - /*! - * \brief The function processes a TX ParamSetup request. - * - * \param [in] txParamSetupReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - * Returns -1, if the functionality is not implemented. In this case, the end node - * shall ignore the command. - */ - virtual int8_t setup_tx_params(TxParamSetupReqParams_t* txParamSetupReq ); - - /*! - * \brief The function processes a DlChannel request. - * - * \param [in] dlChannelReq A pointer to the function parameters. - * - * \retval The status of the operation, according to the LoRaMAC specification. - */ - virtual uint8_t dl_channel_request(DlChannelReqParams_t* dlChannelReq ); - - /*! - * \brief Alternates the datarate of the channel for the join request. - * - * \param [in] alternateDr A pointer to the function parameters. - * - * \retval The datarate to apply. - */ - virtual int8_t get_alternate_DR(AlternateDrParams_t* alternateDr ); - - /*! - * \brief Calculates the back-off time. - * - * \param [in] calcBackOff A pointer to the function parameters. - */ - virtual void calculate_backoff(CalcBackOffParams_t* calcBackOff ); - - /*! - * \brief Searches and sets the next random available channel. - * - * \param [in] nextChanParams The parameters for the next channel. - * - * \param [out] channel The next channel to use for TX. - * - * \param [out] time The time to wait for the next transmission according to the duty cycle. - * - * \param [out] aggregatedTimeOff Updates the aggregated time off. - * - * \retval The function status [1: OK, 0: Unable to find a channel on the current datarate]. - */ - virtual bool set_next_channel(NextChanParams_t* nextChanParams, + virtual bool set_next_channel(channel_selection_params_t* params, uint8_t* channel, lorawan_time_t* time, - lorawan_time_t* aggregatedTimeOff ); + lorawan_time_t* aggregate_timeoff); - /*! - * \brief Adds a channel. - * - * \param [in] channelAdd A pointer to the function parameters. - * - * \retval The status of the operation. - */ - virtual lorawan_status_t add_channel(ChannelAddParams_t* channelAdd ); + virtual void set_tx_cont_mode(cw_mode_params_t* continuousWave, + uint32_t frequency = 0); - /*! - * \brief Removes a channel. - * - * \param [in] channelRemove A pointer to the function parameters. - * - * \retval True, if the channel was removed successfully. - */ - virtual bool remove_channel(ChannelRemoveParams_t* channelRemove ); - - /*! - * \brief Sets the radio into continuous wave mode. - * - * \param [in] continuousWave A pointer to the function parameters. - */ - virtual void set_tx_cont_mode(ContinuousWaveParams_t* continuousWave ); - - /*! - * \brief Computes a new datarate according to the given offset. - * - * \param [in] downlinkDwellTime The downlink dwell time configuration. 0: No limit, 1: 400ms - * - * \param [in] dr The current datarate. - * - * \param [in] drOffset The offset to be applied. - * - * \retval newDr The computed datarate. - */ - virtual uint8_t apply_DR_offset(uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset ); + virtual uint8_t apply_DR_offset(int8_t dr, int8_t dr_offset); private: - int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower, int8_t datarate, uint16_t* channelsMask ); - uint8_t CountNbOfEnabledChannels( uint8_t datarate, uint16_t* channelsMask, channel_params_t* channels, band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx ); + int8_t limit_tx_power(int8_t tx_power, int8_t max_band_tx_power, int8_t datarate); + bool validate_channel_mask(uint16_t* channel_mask); + void reenable_500khz_channels(uint16_t mask, uint16_t* channel_mask); - // Global attributes /*! * LoRaMAC channels */ - channel_params_t Channels[US915_HYBRID_MAX_NB_CHANNELS]; + channel_params_t channels[US915_HYBRID_MAX_NB_CHANNELS]; /*! * LoRaMac bands */ - band_t Bands[US915_HYBRID_MAX_NB_BANDS]; + band_t bands[US915_HYBRID_MAX_NB_BANDS]; /*! * LoRaMac channels mask */ - uint16_t ChannelsMask[US915_HYBRID_CHANNELS_MASK_SIZE]; + uint16_t channel_masks[US915_HYBRID_CHANNELS_MASK_SIZE]; /*! * LoRaMac channels remaining */ - uint16_t ChannelsMaskRemaining[US915_HYBRID_CHANNELS_MASK_SIZE]; + uint16_t current_channel_masks[US915_HYBRID_CHANNELS_MASK_SIZE]; /*! * LoRaMac channels default mask */ - uint16_t ChannelsDefaultMask[US915_HYBRID_CHANNELS_MASK_SIZE]; + uint16_t default_channel_masks[US915_HYBRID_CHANNELS_MASK_SIZE]; }; #endif /* MBED_OS_LORAPHY_US915HYBRID_H_ */ diff --git a/features/lorawan/lorastack/phy/lora_phy_ds.h b/features/lorawan/lorastack/phy/lora_phy_ds.h index b4d6351e3e..1eed06771f 100644 --- a/features/lorawan/lorastack/phy/lora_phy_ds.h +++ b/features/lorawan/lorastack/phy/lora_phy_ds.h @@ -527,7 +527,7 @@ /*! * Enumeration of PHY attributes. */ -typedef enum ePhyAttribute +typedef enum phy_attributes__e { /*! * The minimum RX datarate. @@ -661,466 +661,481 @@ typedef enum ePhyAttribute * The next lower datarate. */ PHY_NEXT_LOWER_TX_DR -}PhyAttribute_t; +} phy_attributes_t; /*! - * Enumeration of initialization types. + * Keeps value in response to a call to + * get_phy_params() API. */ -typedef enum eInitType -{ - /*! - * Performs an initialization and overwrites all existing data. - */ - INIT_TYPE_INIT, - /*! - * Restores default channels only. - */ - INIT_TYPE_RESTORE -}InitType_t; - -/*! - * Selects a given or a default channel mask. - */ -typedef enum eChannelsMask -{ - /*! - * The channels mask. - */ - CHANNELS_MASK, - /*! - * The channels default mask. - */ - CHANNELS_DEFAULT_MASK -}ChannelsMask_t; - -/*! - * The union for the structure uGetPhyParams. - */ -typedef union uPhyParam +typedef union phy_param_u { /*! * A parameter value. */ - uint32_t Value; + uint32_t value; /*! * A floating point value. */ - float fValue; + float f_value; /*! * A pointer to the channels mask. */ - uint16_t* ChannelsMask; + uint16_t* channel_mask; /*! * A pointer to the channels. */ - channel_params_t* Channels; -}PhyParam_t; + channel_params_t* channel_params; +} phy_param_t; -/*! +/** * The parameter structure for the function RegionGetPhyParam. */ -typedef struct sGetPhyParams +typedef struct { - /*! + /** * Set up the parameter to get. */ - PhyAttribute_t Attribute; - /*! - * Datarate. + phy_attributes_t attribute; + + /** * The parameter is needed for the following queries: * PHY_MAX_PAYLOAD, PHY_MAX_PAYLOAD_REPEATER, PHY_NEXT_LOWER_TX_DR. */ - int8_t Datarate; - /*! - * Uplink dwell time. - * The parameter is needed for the following queries: - * PHY_MIN_TX_DR, PHY_MAX_PAYLOAD, PHY_MAX_PAYLOAD_REPEATER, PHY_NEXT_LOWER_TX_DR. - */ - uint8_t UplinkDwellTime; - /*! - * Downlink dwell time. - * The parameter is needed for the following queries: - * PHY_MIN_RX_DR, PHY_MAX_PAYLOAD, PHY_MAX_PAYLOAD_REPEATER. - */ - uint8_t DownlinkDwellTime; -}GetPhyParams_t; + int8_t datarate; -/*! +} get_phy_params_t; + +/** * The parameter structure for the function RegionSetBandTxDone. */ -typedef struct sSetBandTxDoneParams +typedef struct { - /*! + /** * The channel to update. */ - uint8_t Channel; - /*! + uint8_t channel; + /** * Joined set to true, if the node has joined the network. */ - bool Joined; - /*! + bool joined; + /** * The last TX done time. */ - lorawan_time_t LastTxDoneTime; -}SetBandTxDoneParams_t; + lorawan_time_t last_tx_done_time; +} set_band_txdone_params_t; -/*! - * The parameter structure for the function RegionVerify. +/** + * The parameter verification structure. */ -typedef union uVerifyParams +typedef union { - /*! + /** * The TX power to verify. */ - int8_t TxPower; - /*! + int8_t tx_power; + /** * Set to true, if the duty cycle is enabled, otherwise false. */ - bool DutyCycle; - /*! + bool duty_cycle; + /** * The number of join trials. */ - uint8_t NbJoinTrials; - /*! + uint8_t nb_join_trials; + /** * The datarate to verify. */ - struct sDatarateParams - { - /*! - * The datarate to verify. - */ - int8_t Datarate; - /*! - * The downlink dwell time. - */ - uint8_t DownlinkDwellTime; - /*! - * The uplink dwell time. - */ - uint8_t UplinkDwellTime; - }DatarateParams; -}VerifyParams_t; + int8_t datarate; -/*! +} verification_params_t; + +/** * The parameter structure for the function RegionApplyCFList. */ -typedef struct sApplyCFListParams +typedef struct { - /*! + /** * The payload containing the CF list. */ - uint8_t* Payload; - /*! + uint8_t* payload; + /** * The size of the payload. */ - uint8_t Size; -}ApplyCFListParams_t; + uint8_t size; +} cflist_params_t; -/*! - * The parameter structure for the function RegionChanMaskSet. +/** + * TX configuration parameters. */ -typedef struct sChanMaskSetParams +typedef struct { - /*! - * A pointer to the channels mask which should be set. - */ - uint16_t* ChannelsMaskIn; - /*! - * A pointer to the channels mask which should be set. - */ - ChannelsMask_t ChannelsMaskType; -}ChanMaskSetParams_t; - -/*! - * The parameter structure for the function RegionAdrNext. - */ -typedef struct sAdrNextParams -{ - /*! - * Set to true, if the function should update the channels mask. - */ - bool UpdateChanMask; - /*! - * Set to true, if ADR is enabled. - */ - bool AdrEnabled; - /*! - * The ADR ack counter. - */ - uint32_t AdrAckCounter; - /*! - * The datarate used currently. - */ - int8_t Datarate; - /*! - * The TX power used currently. - */ - int8_t TxPower; - /*! - * UplinkDwellTime - */ - uint8_t UplinkDwellTime; -}AdrNextParams_t; - -/*! - * The parameter structure for the function RegionTxConfig. - */ -typedef struct sTxConfigParams -{ - /*! + /** * The TX channel. */ - uint8_t Channel; - /*! + uint8_t channel; + /** * The TX datarate. */ - int8_t Datarate; - /*! + int8_t datarate; + /** * The TX power. */ - int8_t TxPower; - /*! + int8_t tx_power; + /** * The Max EIRP, if applicable. */ - float MaxEirp; - /*! + float max_eirp; + /** * The antenna gain, if applicable. */ - float AntennaGain; - /*! + float antenna_gain; + /** * The frame length to set up. */ - uint16_t PktLen; -}TxConfigParams_t; + uint16_t pkt_len; +} tx_config_params_t; -/*! - * The parameter structure for the function RegionLinkAdrReq. +/** + * This structure contains parameters for ADR request coming from + * network server. */ -typedef struct sLinkAdrReqParams +typedef struct { /*! * A pointer to the payload containing the MAC commands. */ - uint8_t* Payload; + uint8_t* payload; /*! * The size of the payload. */ - uint8_t PayloadSize; + uint8_t payload_size; /*! * The uplink dwell time. */ - uint8_t UplinkDwellTime; + uint8_t ul_dwell_time; /*! * Set to true, if ADR is enabled. */ - bool AdrEnabled; + bool adr_enabled; /*! * The current datarate. */ - int8_t CurrentDatarate; + int8_t current_datarate; /*! * The current TX power. */ - int8_t CurrentTxPower; + int8_t current_tx_power; /*! * The current number of repetitions. */ - uint8_t CurrentNbRep; -}LinkAdrReqParams_t; + uint8_t current_nb_rep; +} adr_req_params_t; -/*! - * The parameter structure for the function RegionRxParamSetupReq. +/** + * Structure containing data for local ADR settings */ -typedef struct sRxParamSetupReqParams +typedef struct link_adr_params_s +{ + /** + * The number of repetitions. + */ + uint8_t nb_rep; + /** + * Datarate. + */ + int8_t datarate; + /** + * TX power. + */ + int8_t tx_power; + /** + * Channels mask control field. + */ + uint8_t ch_mask_ctrl; + /** + * Channels mask field. + */ + uint16_t channel_mask; +} link_adr_params_t; + +/** + * Structure used to store ADR values received from network + * for verification (legality) purposes. + */ +typedef struct verify_adr_params_s { /*! + * The current status of the AdrLinkRequest. + */ + uint8_t status; + /*! + * Set to true, if ADR is enabled. + */ + bool adr_enabled; + /*! + * The datarate the AdrLinkRequest wants to set. + */ + int8_t datarate; + /*! + * The TX power the AdrLinkRequest wants to set. + */ + int8_t tx_power; + /*! + * The number of repetitions the AdrLinkRequest wants to set. + */ + uint8_t nb_rep; + /*! + * The current datarate the node is using. + */ + int8_t current_datarate; + /*! + * The current TX power the node is using. + */ + int8_t current_tx_power; + /*! + * The current number of repetitions the node is using. + */ + int8_t current_nb_rep; + + /*! + * A pointer to the first element of the channels mask. + */ + uint16_t* channel_mask; +} verify_adr_params_t; + +/** + * Contains rx parameter setup request coming from + * network server. + */ +typedef struct rx_param_setup_req_s +{ + /** * The datarate to set up. */ - int8_t Datarate; - /*! + int8_t datarate; + /** * The datarate offset. */ - int8_t DrOffset; - /*! + int8_t dr_offset; + /** * The frequency to set up. */ - uint32_t Frequency; -}RxParamSetupReqParams_t; + uint32_t frequency; +} rx_param_setup_req_t; -/*! - * The parameter structure for the function RegionNewChannelReq. +/** + * Contains tx parameter setup request coming from + * network server. */ -typedef struct sNewChannelReqParams +typedef struct tx_param_setup_req_s { - /*! - * A pointer to the new channels. - */ - channel_params_t* NewChannel; - /*! - * The channel ID. - */ - int8_t ChannelId; -}NewChannelReqParams_t; - -/*! - * The parameter structure for the function RegionTxParamSetupReq. - */ -typedef struct sTxParamSetupReqParams -{ - /*! + /** * The uplink dwell time. */ - uint8_t UplinkDwellTime; - /*! + uint8_t ul_dwell_time; + /** * The downlink dwell time. */ - uint8_t DownlinkDwellTime; - /*! + uint8_t dl_dwell_time; + /** * The max EIRP. */ - uint8_t MaxEirp; -}TxParamSetupReqParams_t; + uint8_t max_eirp; +} tx_param_setup_req_t; -/*! +/** + * A structure that holds new channel parameters coming + * from the network server. + */ +typedef struct new_channel_req_params_s +{ + /** + * A pointer to the new channel's parameters. + */ + channel_params_t* new_channel; + /** + * The channel ID. + */ + int8_t channel_id; + +} new_channel_req_params_t; + +/** * The parameter structure for the function RegionDlChannelReq. */ -typedef struct sDlChannelReqParams +typedef struct dl_channel_req_params_s { - /*! + /** * The channel ID to add the frequency. */ - uint8_t ChannelId; - /*! + uint8_t channel_id; + /** * The alternative frequency for the Rx1 window. */ - uint32_t Rx1Frequency; -}DlChannelReqParams_t; - -/*! - * The parameter structure for the function RegionAlternateDr. - */ -typedef struct sAlternateDrParams -{ - /*! - * The number of trials. - */ - uint16_t NbTrials; -}AlternateDrParams_t; + uint32_t rx1_frequency; +} dl_channel_req_params_t; /*! * The parameter structure for the function RegionCalcBackOff. */ -typedef struct sCalcBackOffParams +typedef struct backoff_params_s { - /*! + /** * Set to true, if the node has already joined a network, otherwise false. */ - bool Joined; - /*! - * Joined set to true, if the last uplink was a join request. + bool joined; + /** + * set to true, if the last uplink was a join request. */ - bool LastTxIsJoinRequest; - /*! + bool last_tx_was_join_req; + /** * Set to true, if the duty cycle is enabled, otherwise false. */ - bool DutyCycleEnabled; - /*! + bool dc_enabled; + /** * The current channel index. */ - uint8_t Channel; - /*! + uint8_t channel; + /** * Elapsed time since the start of the node. */ - lorawan_time_t ElapsedTime; - /*! + lorawan_time_t elapsed_time; + /** * Time-on-air of the last transmission. */ - lorawan_time_t TxTimeOnAir; -}CalcBackOffParams_t; + lorawan_time_t tx_toa; -/*! +} backoff_params_t; + +/** * The parameter structure for the function RegionNextChannel. */ -typedef struct sNextChanParams +typedef struct channel_selection_params_s { - /*! + /** * The aggregated time-off time. */ - lorawan_time_t AggrTimeOff; - /*! + lorawan_time_t aggregate_timeoff; + /** * The time of the last aggregated TX. */ - lorawan_time_t LastAggrTx; - /*! + lorawan_time_t last_aggregate_tx_time; + /** * The current datarate. */ - int8_t Datarate; - /*! + int8_t current_datarate; + /** * Set to true, if the node has already joined a network, otherwise false. */ - bool Joined; - /*! + bool joined; + /** * Set to true, if the duty cycle is enabled, otherwise false. */ - bool DutyCycleEnabled; -}NextChanParams_t; - -/*! - * The parameter structure for the function RegionChannelsAdd. - */ -typedef struct sChannelAddParams -{ - /*! - * A pointer to the new channel to add. - */ - channel_params_t* NewChannel; - /*! - * The channel ID to add. - */ - uint8_t ChannelId; -}ChannelAddParams_t; - -/*! - * The parameter structure for the function RegionChannelsRemove. - */ -typedef struct sChannelRemoveParams -{ - /*! - * The channel ID to remove. - */ - uint8_t ChannelId; -}ChannelRemoveParams_t; + bool dc_enabled; +} channel_selection_params_t; /*! * The parameter structure for the function RegionContinuousWave. */ -typedef struct sContinuousWaveParams +typedef struct continuous_wave_mode_params_s { /*! * The current channel index. */ - uint8_t Channel; + uint8_t channel; /*! * The datarate. Used to limit the TX power. */ - int8_t Datarate; + int8_t datarate; /*! * The TX power to set up. */ - int8_t TxPower; + int8_t tx_power; /*! * The max EIRP, if applicable. */ - float MaxEirp; + float max_eirp; /*! * The antenna gain, if applicable. */ - float AntennaGain; + float antenna_gain; /*! * Specifies the time the radio will stay in CW mode. */ - uint16_t Timeout; -}ContinuousWaveParams_t; + uint16_t timeout; +} cw_mode_params_t; + +typedef struct { + void *table; + uint8_t size; +} loraphy_table_t; + +typedef struct { + channel_params_t *channel_list; + uint8_t channel_list_size; + + uint16_t *mask_list; + uint16_t *default_mask_list; + uint8_t mask_list_size; + +} loraphy_channels_t; + +typedef struct { + bool duty_cycle_enabled; + bool accept_tx_param_setup_req; + bool fsk_supported; + bool cflist_supported; + bool custom_channelplans_supported; + bool dl_channel_req_supported; + + uint8_t default_channel_cnt; + uint8_t cflist_channel_cnt; + uint8_t max_channel_cnt; + uint8_t min_tx_power; + uint8_t max_tx_power; + uint8_t default_tx_power; + uint8_t adr_ack_limit; + uint8_t adr_ack_delay; + + uint8_t min_tx_datarate; + uint8_t max_tx_datarate; + uint8_t min_rx_datarate; + uint8_t max_rx_datarate; + uint8_t default_datarate; + uint8_t default_max_datarate; + uint8_t min_rx1_dr_offset; + uint8_t max_rx1_dr_offset; + uint8_t default_rx1_dr_offset; + uint8_t dwell_limit_datarate; + + uint16_t max_rx_window; + uint16_t recv_delay1; + uint16_t recv_delay2; + uint16_t join_accept_delay1; + uint16_t join_accept_delay2; + uint16_t join_channel_mask; + uint16_t max_fcnt_gap; + uint16_t ack_timeout; + uint16_t ack_timeout_rnd; + + float default_max_eirp; + float default_antenna_gain; + + uint8_t rx_window2_datarate; + uint32_t rx_window2_frequency; + + loraphy_table_t bands; + loraphy_table_t bandwidths; + loraphy_table_t datarates; + loraphy_table_t payloads; + loraphy_table_t payloads_with_repeater; + + loraphy_channels_t channels; + + + unsigned ul_dwell_time_setting : 1; + unsigned dl_dwell_time_setting : 1; + +} loraphy_params_t; #endif /* MBED_OS_LORA_PHY_DATASTRUCTURES_ */ diff --git a/features/lorawan/mbed_lib.json b/features/lorawan/mbed_lib.json index 0a7f80776d..f88e0a5cc0 100644 --- a/features/lorawan/mbed_lib.json +++ b/features/lorawan/mbed_lib.json @@ -10,8 +10,8 @@ "value": true }, "nb-trials": { - "help": "Indicates how many times join can be tried, default: 8", - "value": 8 + "help": "Indicates how many times join can be tried, default: 12", + "value": 12 }, "device-eui": { "help": "Mote device IEEE EUI", diff --git a/features/lorawan/system/lorawan_data_structures.h b/features/lorawan/system/lorawan_data_structures.h index 01dee24dc6..96f48543e4 100644 --- a/features/lorawan/system/lorawan_data_structures.h +++ b/features/lorawan/system/lorawan_data_structures.h @@ -207,6 +207,14 @@ typedef struct { * The device off time. */ lorawan_time_t off_time; + /*! + * Lower band boundry + */ + uint32_t lower_band_freq; + /*! + * Higher band boundry + */ + uint32_t higher_band_freq; } band_t; /*! @@ -2007,7 +2015,7 @@ typedef struct { /*! * The RX datarate. */ - int8_t datarate; + uint8_t datarate; /*! * The RX bandwidth. */ From f0fe1229cf4eb71f799bf3a86ae84d9a94a90db7 Mon Sep 17 00:00:00 2001 From: Hasnain Virk Date: Fri, 9 Feb 2018 12:17:33 +0200 Subject: [PATCH 19/23] Moving LoRaRadio and LoRaWANBAse to lorawan LoRaRadio and LoRaWANBase use to exist under netsocket/. However, their logical location should be where the actual stack exists. --- features/{netsocket => lorawan}/LoRaRadio.h | 3 +-- features/{netsocket => lorawan}/LoRaWANBase.h | 0 features/lorawan/LoRaWANInterface.h | 4 ++-- features/lorawan/lorastack/phy/LoRaPHY.h | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) rename features/{netsocket => lorawan}/LoRaRadio.h (99%) rename features/{netsocket => lorawan}/LoRaWANBase.h (100%) diff --git a/features/netsocket/LoRaRadio.h b/features/lorawan/LoRaRadio.h similarity index 99% rename from features/netsocket/LoRaRadio.h rename to features/lorawan/LoRaRadio.h index 983c1dbf17..e78bdb3fbf 100644 --- a/features/netsocket/LoRaRadio.h +++ b/features/lorawan/LoRaRadio.h @@ -18,9 +18,8 @@ #ifndef LORARADIO_H_ #define LORARADIO_H_ -#include +#include "platform/Callback.h" #include "PinNames.h" -#include "Callback.h" /** * Structure to hold RF controls for LoRa Radio. diff --git a/features/netsocket/LoRaWANBase.h b/features/lorawan/LoRaWANBase.h similarity index 100% rename from features/netsocket/LoRaWANBase.h rename to features/lorawan/LoRaWANBase.h diff --git a/features/lorawan/LoRaWANInterface.h b/features/lorawan/LoRaWANInterface.h index 3889526ebf..f8d35b425f 100644 --- a/features/lorawan/LoRaWANInterface.h +++ b/features/lorawan/LoRaWANInterface.h @@ -19,9 +19,9 @@ #define LORAWANINTERFACE_H_ #include "platform/Callback.h" -#include "netsocket/LoRaWANBase.h" #include "lorawan/LoRaWANStack.h" -#include "netsocket/LoRaRadio.h" +#include "lorawan/LoRaRadio.h" +#include "lorawan/LoRaWANBase.h" class LoRaWANInterface: public LoRaWANBase { diff --git a/features/lorawan/lorastack/phy/LoRaPHY.h b/features/lorawan/lorastack/phy/LoRaPHY.h index cf433665e1..61bb1f5828 100644 --- a/features/lorawan/lorastack/phy/LoRaPHY.h +++ b/features/lorawan/lorastack/phy/LoRaPHY.h @@ -34,9 +34,9 @@ #ifndef MBED_OS_LORAPHY_BASE_ #define MBED_OS_LORAPHY_BASE_ +#include "lorawan/LoRaRadio.h" #include "lorawan/system/LoRaWANTimer.h" #include "lorawan/lorastack/phy/lora_phy_ds.h" -#include "netsocket/LoRaRadio.h" #include "platform/NonCopyable.h" class LoRaPHY : private mbed::NonCopyable { From 20bce2f21c6c4b7f7ac11703e6990641dad4693e Mon Sep 17 00:00:00 2001 From: Hasnain Virk Date: Fri, 9 Feb 2018 12:52:17 +0200 Subject: [PATCH 20/23] Style changes for LoRaWANTimer & a warning fix Method naming, doxygen style etc are made to follow Mbed-OS guidelines. A warning fix in LoRaWANstack. --- features/lorawan/LoRaWANStack.cpp | 4 +- features/lorawan/lorastack/mac/LoRaMac.cpp | 74 +++++++++---------- features/lorawan/lorastack/phy/LoRaPHY.cpp | 12 +-- .../lorawan/lorastack/phy/LoRaPHYAS923.cpp | 4 +- .../lorawan/lorastack/phy/LoRaPHYAU915.cpp | 4 +- .../lorawan/lorastack/phy/LoRaPHYKR920.cpp | 4 +- .../lorawan/lorastack/phy/LoRaPHYUS915.cpp | 4 +- .../lorastack/phy/LoRaPHYUS915Hybrid.cpp | 4 +- features/lorawan/system/LoRaWANTimer.cpp | 14 ++-- features/lorawan/system/LoRaWANTimer.h | 55 +++++++------- 10 files changed, 87 insertions(+), 92 deletions(-) diff --git a/features/lorawan/LoRaWANStack.cpp b/features/lorawan/LoRaWANStack.cpp index 4ced8af0c3..63013be3ab 100644 --- a/features/lorawan/LoRaWANStack.cpp +++ b/features/lorawan/LoRaWANStack.cpp @@ -153,7 +153,7 @@ lorawan_status_t LoRaWANStack::initialize_mac_layer(EventQueue *queue) _compliance_test.app_data_buffer = compliance_test_buffer; #endif - _lora_time.TimerTimeCounterInit(queue); + _lora_time.activate_timer_subsystem(queue); _loramac.LoRaMacInitialization(&LoRaMacPrimitives, &_lora_phy, queue); loramac_mib_req_confirm_t mib_req; @@ -680,7 +680,7 @@ int16_t LoRaWANStack::handle_tx(uint8_t port, const uint8_t* data, // send user the length of data which is scheduled now. // user should take care of the pending data. - return (status == LORAWAN_STATUS_OK) ? _tx_msg.f_buffer_size : status; + return (status == LORAWAN_STATUS_OK) ? _tx_msg.f_buffer_size : (int16_t) status; } int16_t LoRaWANStack::handle_rx(const uint8_t port, uint8_t* data, diff --git a/features/lorawan/lorastack/mac/LoRaMac.cpp b/features/lorawan/lorastack/mac/LoRaMac.cpp index 6c3fca6217..fb55cb38f2 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.cpp +++ b/features/lorawan/lorastack/mac/LoRaMac.cpp @@ -222,7 +222,7 @@ void LoRaMac::OnRadioTxDone( void ) get_phy_params_t getPhy; phy_param_t phyParam; set_band_txdone_params_t txDone; - lorawan_time_t curTime = _lora_time.TimerGetCurrentTime( ); + lorawan_time_t curTime = _lora_time.get_current_time( ); loramac_mlme_confirm_t mlme_confirm = mlme.get_confirmation(); if( _params.dev_class != CLASS_C ) @@ -237,16 +237,16 @@ void LoRaMac::OnRadioTxDone( void ) // Setup timers if( _params.is_rx_window_enabled == true ) { - _lora_time.TimerStart( _params.timers.rx_window1_timer, _params.rx_window1_delay ); + _lora_time.start( _params.timers.rx_window1_timer, _params.rx_window1_delay ); if( _params.dev_class != CLASS_C ) { - _lora_time.TimerStart( _params.timers.rx_window2_timer, _params.rx_window2_delay ); + _lora_time.start( _params.timers.rx_window2_timer, _params.rx_window2_delay ); } if( ( _params.dev_class == CLASS_C ) || ( _params.is_node_ack_requested == true ) ) { getPhy.attribute = PHY_ACK_TIMEOUT; phyParam = lora_phy->get_phy_params(&getPhy); - _lora_time.TimerStart( _params.timers.ack_timeout_timer, _params.rx_window2_delay + phyParam.value ); + _lora_time.start( _params.timers.ack_timeout_timer, _params.rx_window2_delay + phyParam.value ); } } else @@ -301,7 +301,7 @@ void LoRaMac::PrepareRxDoneAbort( void ) _params.flags.bits.mac_done = 1; // Trig OnMacCheckTimerEvent call as soon as possible - _lora_time.TimerStart( _params.timers.mac_state_check_timer, 1 ); + _lora_time.start( _params.timers.mac_state_check_timer, 1 ); } void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) @@ -349,7 +349,7 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 lora_phy->put_radio_to_sleep(); - _lora_time.TimerStop( _params.timers.rx_window2_timer ); + _lora_time.stop( _params.timers.rx_window2_timer ); macHdr.value = payload[pktHeaderLen++]; @@ -702,7 +702,7 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 // Stop the AckTimeout timer as no more retransmissions // are needed. - _lora_time.TimerStop( _params.timers.ack_timeout_timer ); + _lora_time.stop( _params.timers.ack_timeout_timer ); } else { @@ -712,7 +712,7 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 { // Stop the AckTimeout timer as no more retransmissions // are needed. - _lora_time.TimerStop( _params.timers.ack_timeout_timer ); + _lora_time.stop( _params.timers.ack_timeout_timer ); } } } @@ -750,7 +750,7 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 _params.flags.bits.mac_done = 1; // Trig OnMacCheckTimerEvent call as soon as possible - _lora_time.TimerStart( _params.timers.mac_state_check_timer, 1 ); + _lora_time.start( _params.timers.mac_state_check_timer, 1 ); } void LoRaMac::OnRadioTxTimeout( void ) @@ -791,9 +791,9 @@ void LoRaMac::OnRadioRxError( void ) mlme.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_RX1_ERROR; - if( _lora_time.TimerGetElapsedTime( _params.timers.aggregated_last_tx_time ) >= _params.rx_window2_delay ) + if( _lora_time.get_elapsed_time( _params.timers.aggregated_last_tx_time ) >= _params.rx_window2_delay ) { - _lora_time.TimerStop( _params.timers.rx_window2_timer ); + _lora_time.stop( _params.timers.rx_window2_timer ); _params.flags.bits.mac_done = 1; } } @@ -829,9 +829,9 @@ void LoRaMac::OnRadioRxTimeout( void ) } mlme.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_RX1_TIMEOUT; - if( _lora_time.TimerGetElapsedTime( _params.timers.aggregated_last_tx_time ) >= _params.rx_window2_delay ) + if( _lora_time.get_elapsed_time( _params.timers.aggregated_last_tx_time ) >= _params.rx_window2_delay ) { - _lora_time.TimerStop( _params.timers.rx_window2_timer ); + _lora_time.stop( _params.timers.rx_window2_timer ); _params.flags.bits.mac_done = 1; } } @@ -860,7 +860,7 @@ void LoRaMac::OnMacStateCheckTimerEvent( void ) phy_param_t phyParam; bool txTimeout = false; - _lora_time.TimerStop( _params.timers.mac_state_check_timer ); + _lora_time.stop( _params.timers.mac_state_check_timer ); if( _params.flags.bits.mac_done == 1 ) { @@ -1045,7 +1045,7 @@ void LoRaMac::OnMacStateCheckTimerEvent( void ) else { // Operation not finished restart timer - _lora_time.TimerStart( _params.timers.mac_state_check_timer, MAC_STATE_CHECK_TIMEOUT ); + _lora_time.start( _params.timers.mac_state_check_timer, MAC_STATE_CHECK_TIMEOUT ); } // Handle MCPS indication @@ -1078,7 +1078,7 @@ void LoRaMac::OnTxDelayedTimerEvent( void ) lorawan_status_t status = LORAWAN_STATUS_OK; - _lora_time.TimerStop( _params.timers.tx_delayed_timer ); + _lora_time.stop( _params.timers.tx_delayed_timer ); _params.mac_state &= ~LORAMAC_TX_DELAYED; if( ( _params.flags.bits.mlme_req == 1 ) && ( mlme.get_confirmation().req_type == MLME_JOIN ) ) @@ -1108,7 +1108,7 @@ void LoRaMac::OnTxDelayedTimerEvent( void ) void LoRaMac::OnRxWindow1TimerEvent( void ) { - _lora_time.TimerStop( _params.timers.rx_window1_timer ); + _lora_time.stop( _params.timers.rx_window1_timer ); _params.rx_slot= RX_SLOT_WIN_1; _params.rx_window1_config.channel = _params.channel; @@ -1129,7 +1129,7 @@ void LoRaMac::OnRxWindow1TimerEvent( void ) void LoRaMac::OnRxWindow2TimerEvent( void ) { - _lora_time.TimerStop( _params.timers.rx_window2_timer ); + _lora_time.stop( _params.timers.rx_window2_timer ); _params.rx_window2_config.channel = _params.channel; _params.rx_window2_config.frequency = _params.sys_params.rx2_channel.frequency; @@ -1156,7 +1156,7 @@ void LoRaMac::OnRxWindow2TimerEvent( void ) void LoRaMac::OnAckTimeoutTimerEvent( void ) { - _lora_time.TimerStop( _params.timers.ack_timeout_timer ); + _lora_time.stop( _params.timers.ack_timeout_timer ); if( _params.is_node_ack_requested == true ) { @@ -1325,7 +1325,7 @@ lorawan_status_t LoRaMac::ScheduleTx( void ) _params.mac_state |= LORAMAC_TX_DELAYED; tr_debug("Next Transmission in %lu ms", dutyCycleTimeOff); - _lora_time.TimerStart( _params.timers.tx_delayed_timer, dutyCycleTimeOff ); + _lora_time.start( _params.timers.tx_delayed_timer, dutyCycleTimeOff ); return LORAWAN_STATUS_OK; } @@ -1339,7 +1339,7 @@ void LoRaMac::CalculateBackOff( uint8_t channel ) _params.is_dutycycle_on = MBED_CONF_LORA_DUTY_CYCLE_ON; calcBackOff.dc_enabled = _params.is_dutycycle_on; calcBackOff.channel = channel; - calcBackOff.elapsed_time = _lora_time.TimerGetElapsedTime( _params.timers.mac_init_time ); + calcBackOff.elapsed_time = _lora_time.get_elapsed_time( _params.timers.mac_init_time ); calcBackOff.tx_toa = _params.timers.tx_toa; calcBackOff.last_tx_was_join_req = _params.is_last_tx_join_request; @@ -1668,7 +1668,7 @@ lorawan_status_t LoRaMac::SendFrameOnChannel( uint8_t channel ) mlme.get_confirmation().tx_toa = _params.timers.tx_toa; // Starts the MAC layer status check timer - _lora_time.TimerStart( _params.timers.mac_state_check_timer, MAC_STATE_CHECK_TIMEOUT ); + _lora_time.start( _params.timers.mac_state_check_timer, MAC_STATE_CHECK_TIMEOUT ); if( _params.is_nwk_joined == false ) { @@ -1697,7 +1697,7 @@ lorawan_status_t LoRaMac::SetTxContinuousWave( uint16_t timeout ) lora_phy->set_tx_cont_mode(&continuousWave); // Starts the MAC layer status check timer - _lora_time.TimerStart( _params.timers.mac_state_check_timer, MAC_STATE_CHECK_TIMEOUT ); + _lora_time.start( _params.timers.mac_state_check_timer, MAC_STATE_CHECK_TIMEOUT ); _params.mac_state |= LORAMAC_TX_RUNNING; @@ -1718,7 +1718,7 @@ lorawan_status_t LoRaMac::SetTxContinuousWave1( uint16_t timeout, uint32_t frequ lora_phy->set_tx_cont_mode(&continuousWave); // Starts the MAC layer status check timer - _lora_time.TimerStart( _params.timers.mac_state_check_timer, MAC_STATE_CHECK_TIMEOUT ); + _lora_time.start( _params.timers.mac_state_check_timer, MAC_STATE_CHECK_TIMEOUT ); _params.mac_state |= LORAMAC_TX_RUNNING; @@ -1846,19 +1846,19 @@ lorawan_status_t LoRaMac::LoRaMacInitialization(loramac_primitives_t *primitives lora_phy->put_radio_to_sleep(); // Initialize timers - _lora_time.TimerInit(_params.timers.mac_state_check_timer, + _lora_time.init(_params.timers.mac_state_check_timer, mbed::callback(this, &LoRaMac::handle_mac_state_check_timer_event)); - _lora_time.TimerInit(_params.timers.tx_delayed_timer, + _lora_time.init(_params.timers.tx_delayed_timer, mbed::callback(this, &LoRaMac::handle_delayed_tx_timer_event)); - _lora_time.TimerInit(_params.timers.rx_window1_timer, + _lora_time.init(_params.timers.rx_window1_timer, mbed::callback(this, &LoRaMac::handle_rx1_timer_event)); - _lora_time.TimerInit(_params.timers.rx_window2_timer, + _lora_time.init(_params.timers.rx_window2_timer, mbed::callback(this, &LoRaMac::handle_rx2_timer_event)); - _lora_time.TimerInit(_params.timers.ack_timeout_timer, + _lora_time.init(_params.timers.ack_timeout_timer, mbed::callback(this, &LoRaMac::handle_ack_timeout)); // Store the current initialization time - _params.timers.mac_init_time = _lora_time.TimerGetCurrentTime(); + _params.timers.mac_init_time = _lora_time.get_current_time(); return LORAWAN_STATUS_OK; } @@ -1866,11 +1866,11 @@ lorawan_status_t LoRaMac::LoRaMacInitialization(loramac_primitives_t *primitives void LoRaMac::disconnect() { // Cancel all timers - _lora_time.TimerStop(_params.timers.mac_state_check_timer); - _lora_time.TimerStop(_params.timers.tx_delayed_timer); - _lora_time.TimerStop(_params.timers.rx_window1_timer); - _lora_time.TimerStop(_params.timers.rx_window2_timer); - _lora_time.TimerStop(_params.timers.ack_timeout_timer); + _lora_time.stop(_params.timers.mac_state_check_timer); + _lora_time.stop(_params.timers.tx_delayed_timer); + _lora_time.stop(_params.timers.rx_window1_timer); + _lora_time.stop(_params.timers.rx_window2_timer); + _lora_time.stop(_params.timers.ack_timeout_timer); // Put radio to sleep lora_phy->put_radio_to_sleep(); @@ -2110,13 +2110,13 @@ radio_events_t *LoRaMac::GetPhyEventHandlers() lorawan_status_t LoRaMac::LoRaMacSetTxTimer( uint32_t TxDutyCycleTime ) { - _lora_time.TimerStart(tx_next_packet_timer, TxDutyCycleTime); + _lora_time.start(tx_next_packet_timer, TxDutyCycleTime); return LORAWAN_STATUS_OK; } lorawan_status_t LoRaMac::LoRaMacStopTxTimer( ) { - _lora_time.TimerStop(tx_next_packet_timer); + _lora_time.stop(tx_next_packet_timer); return LORAWAN_STATUS_OK; } diff --git a/features/lorawan/lorastack/phy/LoRaPHY.cpp b/features/lorawan/lorastack/phy/LoRaPHY.cpp index 72234139c1..c563daba2f 100644 --- a/features/lorawan/lorastack/phy/LoRaPHY.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHY.cpp @@ -264,9 +264,9 @@ lorawan_time_t LoRaPHY::update_band_timeoff(bool joined, bool duty_cycle, for (uint8_t i = 0; i < nb_bands; i++) { if (joined == false) { - uint32_t txDoneTime = MAX(_lora_time.TimerGetElapsedTime(bands[i].last_join_tx_time), + uint32_t txDoneTime = MAX(_lora_time.get_elapsed_time(bands[i].last_join_tx_time), (duty_cycle == true) ? - _lora_time.TimerGetElapsedTime(bands[i].last_tx_time) : 0); + _lora_time.get_elapsed_time(bands[i].last_tx_time) : 0); if (bands[i].off_time <= txDoneTime) { bands[i].off_time = 0; @@ -280,12 +280,12 @@ lorawan_time_t LoRaPHY::update_band_timeoff(bool joined, bool duty_cycle, // if network has been joined if (duty_cycle == true) { - if( bands[i].off_time <= _lora_time.TimerGetElapsedTime(bands[i].last_tx_time)) { + if( bands[i].off_time <= _lora_time.get_elapsed_time(bands[i].last_tx_time)) { bands[i].off_time = 0; } if(bands[i].off_time != 0 ) { - next_tx_delay = MIN(bands[i].off_time - _lora_time.TimerGetElapsedTime(bands[i].last_tx_time), + next_tx_delay = MIN(bands[i].off_time - _lora_time.get_elapsed_time(bands[i].last_tx_time), next_tx_delay); } } else { @@ -1230,7 +1230,7 @@ bool LoRaPHY::set_next_channel(channel_selection_params_t* params, } if (params->aggregate_timeoff - <= _lora_time.TimerGetElapsedTime(params->last_aggregate_tx_time)) { + <= _lora_time.get_elapsed_time(params->last_aggregate_tx_time)) { // Reset Aggregated time off *aggregate_timeoff = 0; @@ -1247,7 +1247,7 @@ bool LoRaPHY::set_next_channel(channel_selection_params_t* params, } else { delay_tx++; next_tx_delay = params->aggregate_timeoff - - _lora_time.TimerGetElapsedTime(params->last_aggregate_tx_time); + - _lora_time.get_elapsed_time(params->last_aggregate_tx_time); } if (channel_count > 0) { diff --git a/features/lorawan/lorastack/phy/LoRaPHYAS923.cpp b/features/lorawan/lorastack/phy/LoRaPHYAS923.cpp index f871b1ebcd..2c00a0a3f9 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYAS923.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYAS923.cpp @@ -349,7 +349,7 @@ bool LoRaPHYAS923::set_next_channel(channel_selection_params_t* next_channel_pra channel_masks[0] |= LC(1) + LC(2); } - if (next_channel_prams->aggregate_timeoff <= _lora_time.TimerGetElapsedTime(next_channel_prams->last_aggregate_tx_time)) { + if (next_channel_prams->aggregate_timeoff <= _lora_time.get_elapsed_time(next_channel_prams->last_aggregate_tx_time)) { // Reset Aggregated time off *aggregate_timeoff = 0; @@ -366,7 +366,7 @@ bool LoRaPHYAS923::set_next_channel(channel_selection_params_t* next_channel_pra enabled_channels, &delay_tx); } else { delay_tx++; - next_tx_delay = next_channel_prams->aggregate_timeoff - _lora_time.TimerGetElapsedTime(next_channel_prams->last_aggregate_tx_time); + next_tx_delay = next_channel_prams->aggregate_timeoff - _lora_time.get_elapsed_time(next_channel_prams->last_aggregate_tx_time); } if (nb_enabled_channels > 0) { diff --git a/features/lorawan/lorastack/phy/LoRaPHYAU915.cpp b/features/lorawan/lorastack/phy/LoRaPHYAU915.cpp index 992fc7295f..1b3d50da09 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYAU915.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYAU915.cpp @@ -578,7 +578,7 @@ bool LoRaPHYAU915::set_next_channel(channel_selection_params_t* next_chan_params } } - if (next_chan_params->aggregate_timeoff <= _lora_time.TimerGetElapsedTime(next_chan_params->last_aggregate_tx_time)) { + if (next_chan_params->aggregate_timeoff <= _lora_time.get_elapsed_time(next_chan_params->last_aggregate_tx_time)) { // Reset Aggregated time off *aggregated_timeOff = 0; @@ -595,7 +595,7 @@ bool LoRaPHYAU915::set_next_channel(channel_selection_params_t* next_chan_params enabled_channels, &delay_tx); } else { delay_tx++; - next_tx_delay = next_chan_params->aggregate_timeoff - _lora_time.TimerGetElapsedTime(next_chan_params->last_aggregate_tx_time); + next_tx_delay = next_chan_params->aggregate_timeoff - _lora_time.get_elapsed_time(next_chan_params->last_aggregate_tx_time); } if (nb_enabled_channels > 0) { diff --git a/features/lorawan/lorastack/phy/LoRaPHYKR920.cpp b/features/lorawan/lorastack/phy/LoRaPHYKR920.cpp index 1ea6660efe..bb28fa93e3 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYKR920.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYKR920.cpp @@ -419,7 +419,7 @@ bool LoRaPHYKR920::set_next_channel(channel_selection_params_t* params, channel_masks[0] |= LC(1) + LC(2) + LC(3); } - if (params->aggregate_timeoff <= _lora_time.TimerGetElapsedTime(params->last_aggregate_tx_time)) { + if (params->aggregate_timeoff <= _lora_time.get_elapsed_time(params->last_aggregate_tx_time)) { // Reset Aggregated time off *aggregate_timeoff = 0; @@ -433,7 +433,7 @@ bool LoRaPHYKR920::set_next_channel(channel_selection_params_t* params, enabled_channels, &delay_tx); } else { delay_tx++; - nextTxDelay = params->aggregate_timeoff - _lora_time.TimerGetElapsedTime(params->last_aggregate_tx_time); + nextTxDelay = params->aggregate_timeoff - _lora_time.get_elapsed_time(params->last_aggregate_tx_time); } if (nb_enabled_channels > 0) { diff --git a/features/lorawan/lorastack/phy/LoRaPHYUS915.cpp b/features/lorawan/lorastack/phy/LoRaPHYUS915.cpp index b7cd0b862e..89b3c29600 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYUS915.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYUS915.cpp @@ -628,7 +628,7 @@ bool LoRaPHYUS915::set_next_channel(channel_selection_params_t* params, } } - if (params->aggregate_timeoff <= _lora_time.TimerGetElapsedTime(params->last_aggregate_tx_time)) { + if (params->aggregate_timeoff <= _lora_time.get_elapsed_time(params->last_aggregate_tx_time)) { // Reset Aggregated time off *aggregate_timeOff = 0; @@ -642,7 +642,7 @@ bool LoRaPHYUS915::set_next_channel(channel_selection_params_t* params, enabled_channels, &delay_tx); } else { delay_tx++; - next_tx_delay = params->aggregate_timeoff - _lora_time.TimerGetElapsedTime(params->last_aggregate_tx_time); + next_tx_delay = params->aggregate_timeoff - _lora_time.get_elapsed_time(params->last_aggregate_tx_time); } if (nb_enabled_channels > 0) { diff --git a/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.cpp b/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.cpp index 42902f536f..b48e990c8a 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.cpp @@ -629,7 +629,7 @@ bool LoRaPHYUS915Hybrid::set_next_channel(channel_selection_params_t* params, } } - if (params->aggregate_timeoff <= _lora_time.TimerGetElapsedTime( params->last_aggregate_tx_time)) { + if (params->aggregate_timeoff <= _lora_time.get_elapsed_time( params->last_aggregate_tx_time)) { // Reset Aggregated time off *aggregate_timeOff = 0; @@ -646,7 +646,7 @@ bool LoRaPHYUS915Hybrid::set_next_channel(channel_selection_params_t* params, enabled_channels, &delay_tx); } else { delay_tx++; - next_tx_delay = params->aggregate_timeoff - _lora_time.TimerGetElapsedTime(params->last_aggregate_tx_time); + next_tx_delay = params->aggregate_timeoff - _lora_time.get_elapsed_time(params->last_aggregate_tx_time); } if (nb_enabled_channels > 0) { diff --git a/features/lorawan/system/LoRaWANTimer.cpp b/features/lorawan/system/LoRaWANTimer.cpp index 3c25db431e..4497f75db2 100644 --- a/features/lorawan/system/LoRaWANTimer.cpp +++ b/features/lorawan/system/LoRaWANTimer.cpp @@ -29,35 +29,35 @@ LoRaWANTimeHandler::~LoRaWANTimeHandler() { } -void LoRaWANTimeHandler::TimerTimeCounterInit(events::EventQueue *queue) +void LoRaWANTimeHandler::activate_timer_subsystem(events::EventQueue *queue) { _queue = queue; } -lorawan_time_t LoRaWANTimeHandler::TimerGetCurrentTime( void ) +lorawan_time_t LoRaWANTimeHandler::get_current_time( void ) { const uint32_t current_time = _queue->tick(); return (lorawan_time_t)current_time; } -lorawan_time_t LoRaWANTimeHandler::TimerGetElapsedTime( lorawan_time_t savedTime ) +lorawan_time_t LoRaWANTimeHandler::get_elapsed_time(lorawan_time_t saved_time) { - return TimerGetCurrentTime() - savedTime; + return get_current_time() - saved_time; } -void LoRaWANTimeHandler::TimerInit( timer_event_t &obj, mbed::Callback callback) +void LoRaWANTimeHandler::init(timer_event_t &obj, mbed::Callback callback) { obj.callback = callback; obj.timer_id = 0; } -void LoRaWANTimeHandler::TimerStart( timer_event_t &obj, const uint32_t timeout ) +void LoRaWANTimeHandler::start(timer_event_t &obj, const uint32_t timeout) { obj.timer_id = _queue->call_in(timeout, obj.callback); MBED_ASSERT(obj.timer_id != 0); } -void LoRaWANTimeHandler::TimerStop( timer_event_t &obj ) +void LoRaWANTimeHandler::stop(timer_event_t &obj) { _queue->cancel(obj.timer_id); obj.timer_id = 0; diff --git a/features/lorawan/system/LoRaWANTimer.h b/features/lorawan/system/LoRaWANTimer.h index fef22e153b..2b5118eb67 100644 --- a/features/lorawan/system/LoRaWANTimer.h +++ b/features/lorawan/system/LoRaWANTimer.h @@ -31,55 +31,50 @@ public: LoRaWANTimeHandler(); ~LoRaWANTimeHandler(); - /*! - * \brief Initializes the timer used to get the current time. + /** Activates the timer subsystem. * - * \remark The current time corresponds to the time since system startup. + * Embeds EventQueue object to timer subsystem which is subsequently + * used to extract timer information. * - * \param [in] queue Handle to EventQueue object + * @param [in] queue Handle to EventQueue object */ - void TimerTimeCounterInit(events::EventQueue *queue); + void activate_timer_subsystem(events::EventQueue *queue); - /*! - * \brief Read the current time. + /** Read the current time. * - * \retval time The current time. + * @return time The current time. */ - lorawan_time_t TimerGetCurrentTime( void ); + lorawan_time_t get_current_time(void); - /*! - * \brief Return the time elapsed since a fixed moment in time. + /** Return the time elapsed since a fixed moment in time. * - * \param [in] savedTime The fixed moment in time. - * \retval time The elapsed time. + * @param [in] saved_time The fixed moment in time. + * @return time The elapsed time. */ - lorawan_time_t TimerGetElapsedTime( lorawan_time_t savedTime ); + lorawan_time_t get_elapsed_time(lorawan_time_t saved_time); - /*! - * \brief Initializes the timer object. + /** Initializes the timer object. * - * \remark The TimerSetValue function must be called before starting the timer. - * This function initializes the timestamp and reloads the value at 0. + * @remark The TimerSetValue function must be called before starting the timer. + * This function initializes the time-stamp and reloads the value at 0. * - * \param [in] obj The structure containing the timer object parameters. - * \param [in] callback The function callback called at the end of the timeout. + * @param [in] obj The structure containing the timer object parameters. + * @param [in] callback The function callback called at the end of the timeout. */ - void TimerInit( timer_event_t &obj, mbed::Callback callback); + void init(timer_event_t &obj, mbed::Callback callback); - /*! - * \brief Starts and adds the timer object to the list of timer events. + /** Starts and adds the timer object to the list of timer events. * - * \param [in] obj The structure containing the timer object parameters. - * \param [in] timeout The new timeout value. + * @param [in] obj The structure containing the timer object parameters. + * @param [in] timeout The new timeout value. */ - void TimerStart( timer_event_t &obj, const uint32_t timeout ); + void start(timer_event_t &obj, const uint32_t timeout); - /*! - * \brief Stops and removes the timer object from the list of timer events. + /** Stops and removes the timer object from the list of timer events. * - * \param [in] obj The structure containing the timer object parameters. + * @param [in] obj The structure containing the timer object parameters. */ - void TimerStop( timer_event_t &obj ); + void stop(timer_event_t &obj); private: events::EventQueue *_queue; From 7224fbae1c3ca7ffba54df36d13128c2dcf241cf Mon Sep 17 00:00:00 2001 From: Hasnain Virk Date: Fri, 9 Feb 2018 16:23:33 +0200 Subject: [PATCH 21/23] Style Changes in MAC layer Style changed according to Mbed-OS guidelines. --- features/lorawan/LoRaWANStack.cpp | 22 +- features/lorawan/lorastack/mac/LoRaMac.cpp | 1657 ++++++++--------- features/lorawan/lorastack/mac/LoRaMac.h | 543 +++--- .../lorawan/lorastack/mac/LoRaMacCommand.cpp | 452 +++-- .../lorawan/lorastack/mac/LoRaMacCommand.h | 149 +- .../lorawan/lorastack/mac/LoRaMacCrypto.cpp | 244 +-- .../lorawan/lorastack/mac/LoRaMacCrypto.h | 106 +- .../lorawan/lorastack/mac/LoRaMacMcps.cpp | 44 +- features/lorawan/lorastack/mac/LoRaMacMib.cpp | 34 +- .../lorawan/lorastack/mac/LoRaMacMlme.cpp | 58 +- features/lorawan/lorastack/mac/LoRaMacMlme.h | 4 +- .../lorawan/system/lorawan_data_structures.h | 2 +- 12 files changed, 1594 insertions(+), 1721 deletions(-) diff --git a/features/lorawan/LoRaWANStack.cpp b/features/lorawan/LoRaWANStack.cpp index 63013be3ab..9b176368cf 100644 --- a/features/lorawan/LoRaWANStack.cpp +++ b/features/lorawan/LoRaWANStack.cpp @@ -130,7 +130,7 @@ LoRaWANStack& LoRaWANStack::get_lorawan_stack() radio_events_t *LoRaWANStack::bind_radio_driver(LoRaRadio& radio) { // Store pointer to callback routines inside MAC layer (non-IRQ safe) - _mac_handlers = _loramac.GetPhyEventHandlers(); + _mac_handlers = _loramac.get_phy_event_handlers(); // passes the reference to radio driver down to PHY layer _lora_phy.set_radio_instance(radio); return _mac_handlers; @@ -154,7 +154,7 @@ lorawan_status_t LoRaWANStack::initialize_mac_layer(EventQueue *queue) #endif _lora_time.activate_timer_subsystem(queue); - _loramac.LoRaMacInitialization(&LoRaMacPrimitives, &_lora_phy, queue); + _loramac.initialize(&LoRaMacPrimitives, &_lora_phy, queue); loramac_mib_req_confirm_t mib_req; @@ -267,7 +267,7 @@ lorawan_status_t LoRaWANStack::send_compliance_test_frame_to_mac() uint16_t LoRaWANStack::check_possible_tx_size(uint16_t size) { loramac_tx_info_t tx_info; - if (_loramac.LoRaMacQueryTxPossible(size, &tx_info) == LORAWAN_STATUS_LENGTH_ERROR) { + if (_loramac.query_tx_possible(size, &tx_info) == LORAWAN_STATUS_LENGTH_ERROR) { // Cannot transmit this much. Return how much data can be sent // at the moment return tx_info.max_possible_payload_size; @@ -404,7 +404,7 @@ lorawan_status_t LoRaWANStack::add_channels(const lorawan_channelplan_t &channel return LORAWAN_STATUS_NOT_INITIALIZED; } - return _loramac.AddChannelPlan(channel_plan); + return _loramac.add_channel_plan(channel_plan); } lorawan_status_t LoRaWANStack::drop_channel_list() @@ -414,7 +414,7 @@ lorawan_status_t LoRaWANStack::drop_channel_list() return LORAWAN_STATUS_NOT_INITIALIZED; } - return _loramac.RemoveChannelPlan(); + return _loramac.remove_channel_plan(); } lorawan_status_t LoRaWANStack::remove_a_channel(uint8_t channel_id) @@ -425,7 +425,7 @@ lorawan_status_t LoRaWANStack::remove_a_channel(uint8_t channel_id) return LORAWAN_STATUS_NOT_INITIALIZED; } - return _loramac.RemoveSingleChannel(channel_id); + return _loramac.remove_single_channel(channel_id); } lorawan_status_t LoRaWANStack::get_enabled_channels(lorawan_channelplan_t& channel_plan) @@ -438,7 +438,7 @@ lorawan_status_t LoRaWANStack::get_enabled_channels(lorawan_channelplan_t& chann return LORAWAN_STATUS_BUSY; } - return _loramac.GetChannelPlan(channel_plan); + return _loramac.get_channel_plan(channel_plan); } lorawan_status_t LoRaWANStack::enable_adaptive_datarate(bool adr_enabled) @@ -771,7 +771,7 @@ lorawan_status_t LoRaWANStack::mlme_request_handler(loramac_mlme_req_t *mlme_req return LORAWAN_STATUS_PARAMETER_INVALID; } - return _loramac.LoRaMacMlmeRequest(mlme_request); + return _loramac.mlme_request(mlme_request); } /** MLME-Confirm event function @@ -843,7 +843,7 @@ lorawan_status_t LoRaWANStack::mcps_request_handler(loramac_mcps_req_t *mcps_req return LORAWAN_STATUS_PARAMETER_INVALID; } - return _loramac.LoRaMacMcpsRequest(mcps_request); + return _loramac.mcps_request(mcps_request); } /** MCPS-Confirm event function @@ -1154,7 +1154,7 @@ lorawan_status_t LoRaWANStack::mib_set_request(loramac_mib_req_confirm_t *mib_se if (NULL == mib_set_params) { return LORAWAN_STATUS_PARAMETER_INVALID; } - return _loramac.LoRaMacMibSetRequestConfirm(mib_set_params); + return _loramac.mib_set_request_confirm(mib_set_params); } lorawan_status_t LoRaWANStack::mib_get_request(loramac_mib_req_confirm_t *mib_get_params) @@ -1162,7 +1162,7 @@ lorawan_status_t LoRaWANStack::mib_get_request(loramac_mib_req_confirm_t *mib_ge if(NULL == mib_get_params) { return LORAWAN_STATUS_PARAMETER_INVALID; } - return _loramac.LoRaMacMibGetRequestConfirm(mib_get_params); + return _loramac.mib_get_request_confirm(mib_get_params); } lorawan_status_t LoRaWANStack::set_link_check_request() diff --git a/features/lorawan/lorastack/mac/LoRaMac.cpp b/features/lorawan/lorastack/mac/LoRaMac.cpp index fb55cb38f2..ab5c2b9358 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.cpp +++ b/features/lorawan/lorastack/mac/LoRaMac.cpp @@ -36,7 +36,6 @@ SPDX-License-Identifier: BSD-3-Clause using namespace events; - /*! * Maximum length of the fOpts field */ @@ -116,7 +115,7 @@ LoRaMac::LoRaMac(LoRaWANTimeHandler &lora_time) _params.sys_params.adr_on = false; _params.sys_params.max_duty_cycle = 0; - LoRaMacPrimitives = NULL; + mac_primitives = NULL; ev_queue = NULL; } @@ -130,35 +129,35 @@ LoRaMac::~LoRaMac() **************************************************************************/ void LoRaMac::handle_tx_done(void) { - const int ret = ev_queue->call(this, &LoRaMac::OnRadioTxDone); + const int ret = ev_queue->call(this, &LoRaMac::on_radio_tx_done); MBED_ASSERT(ret != 0); (void)ret; } void LoRaMac::handle_rx_done(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr) { - const int ret = ev_queue->call(this, &LoRaMac::OnRadioRxDone, payload, size, rssi, snr); + const int ret = ev_queue->call(this, &LoRaMac::on_radio_rx_done, payload, size, rssi, snr); MBED_ASSERT(ret != 0); (void)ret; } void LoRaMac::handle_rx_error(void) { - const int ret = ev_queue->call(this, &LoRaMac::OnRadioRxError); + const int ret = ev_queue->call(this, &LoRaMac::on_radio_rx_error); MBED_ASSERT(ret != 0); (void)ret; } void LoRaMac::handle_rx_timeout(void) { - const int ret = ev_queue->call(this, &LoRaMac::OnRadioRxTimeout); + const int ret = ev_queue->call(this, &LoRaMac::on_radio_rx_timeout); MBED_ASSERT(ret != 0); (void)ret; } void LoRaMac::handle_tx_timeout(void) { - const int ret = ev_queue->call(this, &LoRaMac::OnRadioTxTimeout); + const int ret = ev_queue->call(this, &LoRaMac::on_radio_tx_timeout); MBED_ASSERT(ret != 0); (void)ret; } @@ -181,35 +180,35 @@ void LoRaMac::handle_fhss_change_channel(uint8_t cur_channel) void LoRaMac::handle_mac_state_check_timer_event(void) { - const int ret = ev_queue->call(this, &LoRaMac::OnMacStateCheckTimerEvent); + const int ret = ev_queue->call(this, &LoRaMac::on_mac_state_check_timer_event); MBED_ASSERT(ret != 0); (void)ret; } void LoRaMac::handle_delayed_tx_timer_event(void) { - const int ret = ev_queue->call(this, &LoRaMac::OnTxDelayedTimerEvent); + const int ret = ev_queue->call(this, &LoRaMac::on_tx_delayed_timer_event); MBED_ASSERT(ret != 0); (void)ret; } void LoRaMac::handle_ack_timeout() { - const int ret = ev_queue->call(this, &LoRaMac::OnAckTimeoutTimerEvent); + const int ret = ev_queue->call(this, &LoRaMac::on_ack_timeout_timer_event); MBED_ASSERT(ret != 0); (void)ret; } void LoRaMac::handle_rx1_timer_event(void) { - const int ret = ev_queue->call(this, &LoRaMac::OnRxWindow1TimerEvent); + const int ret = ev_queue->call(this, &LoRaMac::on_rx_window1_timer_event); MBED_ASSERT(ret != 0); (void)ret; } void LoRaMac::handle_rx2_timer_event(void) { - const int ret = ev_queue->call(this, &LoRaMac::OnRxWindow2TimerEvent); + const int ret = ev_queue->call(this, &LoRaMac::on_rx_window2_timer_event); MBED_ASSERT(ret != 0); (void)ret; } @@ -217,121 +216,116 @@ void LoRaMac::handle_rx2_timer_event(void) /*************************************************************************** * Radio event callbacks - delegated to Radio driver * **************************************************************************/ -void LoRaMac::OnRadioTxDone( void ) +void LoRaMac::on_radio_tx_done( void ) { - get_phy_params_t getPhy; - phy_param_t phyParam; - set_band_txdone_params_t txDone; - lorawan_time_t curTime = _lora_time.get_current_time( ); + get_phy_params_t get_phy; + phy_param_t phy_param; + set_band_txdone_params_t tx_done_params; + lorawan_time_t cur_time = _lora_time.get_current_time( ); loramac_mlme_confirm_t mlme_confirm = mlme.get_confirmation(); - if( _params.dev_class != CLASS_C ) - { + if (_params.dev_class != CLASS_C) { lora_phy->put_radio_to_sleep(); - } - else - { - OpenContinuousRx2Window( ); + } else { + open_continuous_rx2_window(); } // Setup timers - if( _params.is_rx_window_enabled == true ) - { - _lora_time.start( _params.timers.rx_window1_timer, _params.rx_window1_delay ); - if( _params.dev_class != CLASS_C ) - { - _lora_time.start( _params.timers.rx_window2_timer, _params.rx_window2_delay ); + if(_params.is_rx_window_enabled == true) { + _lora_time.start(_params.timers.rx_window1_timer, _params.rx_window1_delay); + + if (_params.dev_class != CLASS_C) { + _lora_time.start(_params.timers.rx_window2_timer, _params.rx_window2_delay); } - if( ( _params.dev_class == CLASS_C ) || ( _params.is_node_ack_requested == true ) ) - { - getPhy.attribute = PHY_ACK_TIMEOUT; - phyParam = lora_phy->get_phy_params(&getPhy); - _lora_time.start( _params.timers.ack_timeout_timer, _params.rx_window2_delay + phyParam.value ); + + if ((_params.dev_class == CLASS_C ) || + (_params.is_node_ack_requested == true)) { + get_phy.attribute = PHY_ACK_TIMEOUT; + phy_param = lora_phy->get_phy_params(&get_phy); + _lora_time.start(_params.timers.ack_timeout_timer, + _params.rx_window2_delay + phy_param.value); } - } - else - { + } else { mcps.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_OK; mlme_confirm.status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT; - if( _params.flags.value == 0 ) - { + if (_params.flags.value == 0) { _params.flags.bits.mcps_req = 1; } + _params.flags.bits.mac_done = 1; } // Verify if the last uplink was a join request - if( ( _params.flags.bits.mlme_req == 1 ) && ( mlme_confirm.req_type == MLME_JOIN ) ) - { + if ((_params.flags.bits.mlme_req == 1) && + (mlme_confirm.req_type == MLME_JOIN)) { _params.is_last_tx_join_request = true; - } - else - { + } else { _params.is_last_tx_join_request = false; } // Store last Tx channel _params.last_channel_idx = _params.channel; - // Update last tx done time for the current channel - txDone.channel = _params.channel; - txDone.joined = _params.is_nwk_joined; - txDone.last_tx_done_time = curTime; - lora_phy->set_last_tx_done(&txDone); - // Update Aggregated last tx done time - _params.timers.aggregated_last_tx_time = curTime; - if( _params.is_node_ack_requested == false ) - { + // Update last tx done time for the current channel + tx_done_params.channel = _params.channel; + tx_done_params.joined = _params.is_nwk_joined; + tx_done_params.last_tx_done_time = cur_time; + lora_phy->set_last_tx_done(&tx_done_params); + + // Update Aggregated last tx done time + _params.timers.aggregated_last_tx_time = cur_time; + + if (_params.is_node_ack_requested == false) { mcps.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_OK; _params.ul_nb_rep_counter++; } } -void LoRaMac::PrepareRxDoneAbort( void ) +void LoRaMac::prepare_rx_done_abort(void) { _params.mac_state |= LORAMAC_RX_ABORT; - if( _params.is_node_ack_requested ) - { + if (_params.is_node_ack_requested) { handle_ack_timeout(); } _params.flags.bits.mcps_ind = 1; _params.flags.bits.mac_done = 1; - // Trig OnMacCheckTimerEvent call as soon as possible - _lora_time.start( _params.timers.mac_state_check_timer, 1 ); + // Trigger MAC state check event timer as soon as possible + _lora_time.start(_params.timers.mac_state_check_timer, 1); } -void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) +void LoRaMac::on_radio_rx_done(uint8_t *payload, uint16_t size, int16_t rssi, + int8_t snr) { - loramac_mhdr_t macHdr; - loramac_frame_ctrl_t fCtrl; - cflist_params_t applyCFList; - get_phy_params_t getPhy; - phy_param_t phyParam; - bool skipIndication = false; + loramac_mhdr_t mac_hdr; + loramac_frame_ctrl_t fctrl; + cflist_params_t cflist; + get_phy_params_t get_phy; + phy_param_t phy_param; + bool skip_indication = false; - uint8_t pktHeaderLen = 0; + uint8_t pkt_header_len = 0; uint32_t address = 0; - uint8_t appPayloadStartIndex = 0; - uint8_t frameLen = 0; + uint8_t app_payload_start_index = 0; + uint8_t frame_len = 0; uint32_t mic = 0; - uint32_t micRx = 0; + uint32_t mic_rx = 0; - uint16_t sequenceCounter = 0; - uint16_t sequenceCounterPrev = 0; - uint16_t sequenceCounterDiff = 0; - uint32_t downLinkCounter = 0; + uint16_t sequence_counter = 0; + uint16_t sequence_counter_prev = 0; + uint16_t sequence_counter_diff = 0; + uint32_t downlink_counter = 0; - multicast_params_t *curMulticastParams = NULL; - uint8_t *nwkSKey = _params.keys.nwk_skey; - uint8_t *appSKey = _params.keys.app_skey; + multicast_params_t *cur_multicast_params = NULL; + uint8_t *nwk_skey = _params.keys.nwk_skey; + uint8_t *app_skey = _params.keys.app_skey; uint8_t multicast = 0; - bool isMicOk = false; + bool is_mic_ok = false; mcps.get_confirmation().ack_received = false; mcps.get_indication().rssi = rssi; @@ -351,365 +345,340 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 _lora_time.stop( _params.timers.rx_window2_timer ); - macHdr.value = payload[pktHeaderLen++]; + mac_hdr.value = payload[pkt_header_len++]; + + switch (mac_hdr.bits.mtype) { - switch( macHdr.bits.mtype ) - { case FRAME_TYPE_JOIN_ACCEPT: - if( _params.is_nwk_joined == true ) - { + if (_params.is_nwk_joined == true) { mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_ERROR; - PrepareRxDoneAbort( ); + prepare_rx_done_abort(); return; } - if (0 != LoRaMacJoinDecrypt( payload + 1, size - 1, - _params.keys.app_key, - _params.payload + 1 )) { + if (0 != decrypt_join_frame(payload + 1, size - 1, + _params.keys.app_key, + _params.payload + 1)) { mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL; return; } - _params.payload[0] = macHdr.value; + _params.payload[0] = mac_hdr.value; - if (0 != LoRaMacJoinComputeMic( _params.payload, size - LORAMAC_MFR_LEN, - _params.keys.app_key, &mic )) { + if (0 != compute_join_frame_mic(_params.payload, size - LORAMAC_MFR_LEN, + _params.keys.app_key, &mic)) { mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL; return; } - micRx |= ( uint32_t ) _params.payload[size - LORAMAC_MFR_LEN]; - micRx |= ( ( uint32_t ) _params.payload[size - LORAMAC_MFR_LEN + 1] << 8 ); - micRx |= ( ( uint32_t ) _params.payload[size - LORAMAC_MFR_LEN + 2] << 16 ); - micRx |= ( ( uint32_t ) _params.payload[size - LORAMAC_MFR_LEN + 3] << 24 ); + mic_rx |= (uint32_t) _params.payload[size - LORAMAC_MFR_LEN]; + mic_rx |= ((uint32_t) _params.payload[size - LORAMAC_MFR_LEN + 1] << 8); + mic_rx |= ((uint32_t) _params.payload[size - LORAMAC_MFR_LEN + 2] << 16); + mic_rx |= ((uint32_t) _params.payload[size - LORAMAC_MFR_LEN + 3] << 24); - if( micRx == mic ) - { - if (0 != LoRaMacJoinComputeSKeys( _params.keys.app_key, - _params.payload + 1, - _params.dev_nonce, - _params.keys.nwk_skey, - _params.keys.app_skey )) { + if (mic_rx == mic) { + + if (0 != compute_skeys_for_join_frame(_params.keys.app_key, + _params.payload + 1, + _params.dev_nonce, + _params.keys.nwk_skey, + _params.keys.app_skey)) { mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL; return; } - _params.net_id = ( uint32_t ) _params.payload[4]; - _params.net_id |= ( ( uint32_t ) _params.payload[5] << 8 ); - _params.net_id |= ( ( uint32_t ) _params.payload[6] << 16 ); + _params.net_id = (uint32_t) _params.payload[4]; + _params.net_id |= ((uint32_t) _params.payload[5] << 8); + _params.net_id |= ((uint32_t) _params.payload[6] << 16); - _params.dev_addr = ( uint32_t ) _params.payload[7]; - _params.dev_addr |= ( ( uint32_t ) _params.payload[8] << 8 ); - _params.dev_addr |= ( ( uint32_t ) _params.payload[9] << 16 ); - _params.dev_addr |= ( ( uint32_t ) _params.payload[10] << 24 ); + _params.dev_addr = (uint32_t) _params.payload[7]; + _params.dev_addr |= ((uint32_t) _params.payload[8] << 8); + _params.dev_addr |= ((uint32_t) _params.payload[9] << 16); + _params.dev_addr |= ((uint32_t) _params.payload[10] << 24); // DLSettings - _params.sys_params.rx1_dr_offset = ( _params.payload[11] >> 4 ) & 0x07; + _params.sys_params.rx1_dr_offset = (_params.payload[11] >> 4) & 0x07; _params.sys_params.rx2_channel.datarate = _params.payload[11] & 0x0F; // RxDelay - _params.sys_params.recv_delay1 = ( _params.payload[12] & 0x0F ); - if( _params.sys_params.recv_delay1 == 0 ) - { + _params.sys_params.recv_delay1 = (_params.payload[12] & 0x0F); + + if (_params.sys_params.recv_delay1 == 0) { _params.sys_params.recv_delay1 = 1; } + _params.sys_params.recv_delay1 *= 1000; _params.sys_params.recv_delay2 = _params.sys_params.recv_delay1 + 1000; // Apply CF list - applyCFList.payload = &_params.payload[13]; + cflist.payload = &_params.payload[13]; // Size of the regular payload is 12. Plus 1 byte MHDR and 4 bytes MIC - applyCFList.size = size - 17; + cflist.size = size - 17; - lora_phy->apply_cf_list(&applyCFList); + lora_phy->apply_cf_list(&cflist); mlme.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_OK; _params.is_nwk_joined = true; - } - else - { + } else { mlme.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL; } + break; + case FRAME_TYPE_DATA_CONFIRMED_DOWN: case FRAME_TYPE_DATA_UNCONFIRMED_DOWN: { // Check if the received payload size is valid - getPhy.datarate = mcps.get_indication().rx_datarate; - getPhy.attribute = PHY_MAX_PAYLOAD; + get_phy.datarate = mcps.get_indication().rx_datarate; + get_phy.attribute = PHY_MAX_PAYLOAD; // Get the maximum payload length - if( _params.is_repeater_supported == true ) - { - getPhy.attribute = PHY_MAX_PAYLOAD_REPEATER; + if (_params.is_repeater_supported == true) { + get_phy.attribute = PHY_MAX_PAYLOAD_REPEATER; } - phyParam = lora_phy->get_phy_params(&getPhy); - if( MAX( 0, ( int16_t )( ( int16_t )size - ( int16_t )LORA_MAC_FRMPAYLOAD_OVERHEAD ) ) > (int32_t)phyParam.value ) - { + + phy_param = lora_phy->get_phy_params(&get_phy); + + if (MAX(0, (int16_t) ((int16_t)size - (int16_t)LORA_MAC_FRMPAYLOAD_OVERHEAD )) > (int32_t)phy_param.value) { mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_ERROR; - PrepareRxDoneAbort( ); + prepare_rx_done_abort(); return; } - address = payload[pktHeaderLen++]; - address |= ( (uint32_t)payload[pktHeaderLen++] << 8 ); - address |= ( (uint32_t)payload[pktHeaderLen++] << 16 ); - address |= ( (uint32_t)payload[pktHeaderLen++] << 24 ); + address = payload[pkt_header_len++]; + address |= ((uint32_t)payload[pkt_header_len++] << 8); + address |= ((uint32_t)payload[pkt_header_len++] << 16); + address |= ((uint32_t)payload[pkt_header_len++] << 24); - if( address != _params.dev_addr ) - { - curMulticastParams = _params.multicast_channels; - while( curMulticastParams != NULL ) - { - if( address == curMulticastParams->address ) - { + if (address != _params.dev_addr) { + + cur_multicast_params = _params.multicast_channels; + + while (cur_multicast_params != NULL) { + + if (address == cur_multicast_params->address) { multicast = 1; - nwkSKey = curMulticastParams->nwk_skey; - appSKey = curMulticastParams->app_skey; - downLinkCounter = curMulticastParams->dl_frame_counter; + nwk_skey = cur_multicast_params->nwk_skey; + app_skey = cur_multicast_params->app_skey; + downlink_counter = cur_multicast_params->dl_frame_counter; break; } - curMulticastParams = curMulticastParams->Next; + + cur_multicast_params = cur_multicast_params->next; } - if( multicast == 0 ) - { + + if (multicast == 0) { // We are not the destination of this frame. mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_ADDRESS_FAIL; - PrepareRxDoneAbort( ); + prepare_rx_done_abort(); return; } - } - else - { + } else { multicast = 0; - nwkSKey = _params.keys.nwk_skey; - appSKey = _params.keys.app_skey; - downLinkCounter = _params.dl_frame_counter; + nwk_skey = _params.keys.nwk_skey; + app_skey = _params.keys.app_skey; + downlink_counter = _params.dl_frame_counter; } - fCtrl.value = payload[pktHeaderLen++]; + fctrl.value = payload[pkt_header_len++]; - sequenceCounter = ( uint16_t )payload[pktHeaderLen++]; - sequenceCounter |= ( uint16_t )payload[pktHeaderLen++] << 8; + sequence_counter = (uint16_t )payload[pkt_header_len++]; + sequence_counter |= (uint16_t)payload[pkt_header_len++] << 8; - appPayloadStartIndex = 8 + fCtrl.bits.fopts_len; + app_payload_start_index = 8 + fctrl.bits.fopts_len; - micRx |= ( uint32_t )payload[size - LORAMAC_MFR_LEN]; - micRx |= ( ( uint32_t )payload[size - LORAMAC_MFR_LEN + 1] << 8 ); - micRx |= ( ( uint32_t )payload[size - LORAMAC_MFR_LEN + 2] << 16 ); - micRx |= ( ( uint32_t )payload[size - LORAMAC_MFR_LEN + 3] << 24 ); + mic_rx |= (uint32_t)payload[size - LORAMAC_MFR_LEN]; + mic_rx |= ((uint32_t)payload[size - LORAMAC_MFR_LEN + 1] << 8); + mic_rx |= ((uint32_t)payload[size - LORAMAC_MFR_LEN + 2] << 16); + mic_rx |= ((uint32_t)payload[size - LORAMAC_MFR_LEN + 3] << 24); - sequenceCounterPrev = ( uint16_t )downLinkCounter; - sequenceCounterDiff = ( sequenceCounter - sequenceCounterPrev ); + sequence_counter_prev = (uint16_t)downlink_counter; + sequence_counter_diff = (sequence_counter - sequence_counter_prev); - if( sequenceCounterDiff < ( 1 << 15 ) ) - { - downLinkCounter += sequenceCounterDiff; - LoRaMacComputeMic( payload, size - LORAMAC_MFR_LEN, nwkSKey, address, DOWN_LINK, downLinkCounter, &mic ); - if( micRx == mic ) - { - isMicOk = true; + if (sequence_counter_diff < (1 << 15)) { + + downlink_counter += sequence_counter_diff; + compute_mic(payload, size - LORAMAC_MFR_LEN, nwk_skey, + address, DOWN_LINK, downlink_counter, &mic); + if (mic_rx == mic) { + is_mic_ok = true; } - } - else - { + + } else { // check for sequence roll-over - uint32_t downLinkCounterTmp = downLinkCounter + 0x10000 + ( int16_t )sequenceCounterDiff; - LoRaMacComputeMic( payload, size - LORAMAC_MFR_LEN, nwkSKey, address, DOWN_LINK, downLinkCounterTmp, &mic ); - if( micRx == mic ) - { - isMicOk = true; - downLinkCounter = downLinkCounterTmp; + uint32_t downlink_counter_tmp = downlink_counter + 0x10000 + (int16_t)sequence_counter_diff; + compute_mic(payload, size - LORAMAC_MFR_LEN, nwk_skey, + address, DOWN_LINK, downlink_counter_tmp, &mic); + + if (mic_rx == mic ) { + is_mic_ok = true; + downlink_counter = downlink_counter_tmp; } } // Check for a the maximum allowed counter difference - getPhy.attribute = PHY_MAX_FCNT_GAP; - phyParam = lora_phy->get_phy_params( &getPhy ); - if( sequenceCounterDiff >= phyParam.value ) - { + get_phy.attribute = PHY_MAX_FCNT_GAP; + phy_param = lora_phy->get_phy_params(&get_phy); + + if (sequence_counter_diff >= phy_param.value) { mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_TOO_MANY_FRAMES_LOSS; - mcps.get_indication().dl_frame_counter = downLinkCounter; - PrepareRxDoneAbort( ); + mcps.get_indication().dl_frame_counter = downlink_counter; + prepare_rx_done_abort( ); return; } - if( isMicOk == true ) - { + if (is_mic_ok == true) { mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_OK; mcps.get_indication().multicast = multicast; - mcps.get_indication().fpending_status = fCtrl.bits.fpending; + mcps.get_indication().fpending_status = fctrl.bits.fpending; mcps.get_indication().buffer = NULL; mcps.get_indication().buffer_size = 0; - mcps.get_indication().dl_frame_counter = downLinkCounter; + mcps.get_indication().dl_frame_counter = downlink_counter; mcps.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_OK; _params.adr_ack_counter = 0; - mac_commands.ClearRepeatBuffer(); + mac_commands.clear_repeat_buffer(); // Update 32 bits downlink counter - if( multicast == 1 ) - { + if (multicast == 1) { mcps.get_indication().type = MCPS_MULTICAST; - if( ( curMulticastParams->dl_frame_counter == downLinkCounter ) && - ( curMulticastParams->dl_frame_counter != 0 ) ) - { + if ((cur_multicast_params->dl_frame_counter == downlink_counter) && + (cur_multicast_params->dl_frame_counter != 0)) { + mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED; - mcps.get_indication().dl_frame_counter = downLinkCounter; - PrepareRxDoneAbort( ); + mcps.get_indication().dl_frame_counter = downlink_counter; + prepare_rx_done_abort(); + return; } - curMulticastParams->dl_frame_counter = downLinkCounter; - } - else - { - if( macHdr.bits.mtype == FRAME_TYPE_DATA_CONFIRMED_DOWN ) - { + + cur_multicast_params->dl_frame_counter = downlink_counter; + + } else { + + if (mac_hdr.bits.mtype == FRAME_TYPE_DATA_CONFIRMED_DOWN) { _params.is_srv_ack_requested = true; mcps.get_indication().type = MCPS_CONFIRMED; - if( ( _params.dl_frame_counter == downLinkCounter ) && - ( _params.dl_frame_counter != 0 ) ) - { + if ((_params.dl_frame_counter == downlink_counter ) && + (_params.dl_frame_counter != 0)) { // Duplicated confirmed downlink. Skip indication. // In this case, the MAC layer shall accept the MAC commands // which are included in the downlink retransmission. // It should not provide the same frame to the application // layer again. - skipIndication = true; + skip_indication = true; } - } - else - { + } else { _params.is_srv_ack_requested = false; mcps.get_indication().type = MCPS_UNCONFIRMED; - if( ( _params.dl_frame_counter == downLinkCounter ) && - ( _params.dl_frame_counter != 0 ) ) - { + if ((_params.dl_frame_counter == downlink_counter) && + (_params.dl_frame_counter != 0)) { mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED; - mcps.get_indication().dl_frame_counter = downLinkCounter; - PrepareRxDoneAbort( ); + mcps.get_indication().dl_frame_counter = downlink_counter; + prepare_rx_done_abort(); return; } } - _params.dl_frame_counter = downLinkCounter; + _params.dl_frame_counter = downlink_counter; } // This must be done before parsing the payload and the MAC commands. // We need to reset the MacCommandsBufferIndex here, since we need // to take retransmissions and repetitions into account. Error cases // will be handled in function OnMacStateCheckTimerEvent. - if( mcps.get_confirmation().req_type == MCPS_CONFIRMED ) - { - if( fCtrl.bits.ack == 1 ) - {// Reset MacCommandsBufferIndex when we have received an ACK. - mac_commands.ClearCommandBuffer(); + if (mcps.get_confirmation().req_type == MCPS_CONFIRMED) { + if (fctrl.bits.ack == 1) { + // Reset MacCommandsBufferIndex when we have received an ACK. + mac_commands.clear_command_buffer(); } - } - else - {// Reset the variable if we have received any valid frame. - mac_commands.ClearCommandBuffer(); + } else { + // Reset the variable if we have received any valid frame. + mac_commands.clear_command_buffer(); } // Process payload and MAC commands - if( ( ( size - 4 ) - appPayloadStartIndex ) > 0 ) - { - uint8_t port = payload[appPayloadStartIndex++]; - frameLen = ( size - 4 ) - appPayloadStartIndex; + if (((size - 4) - app_payload_start_index) > 0) { + uint8_t port = payload[app_payload_start_index++]; + frame_len = (size - 4) - app_payload_start_index; mcps.get_indication().port = port; - if( port == 0 ) - { + if (port == 0) { // Only allow frames which do not have fOpts - if( fCtrl.bits.fopts_len == 0 ) - { - if (0 != LoRaMacPayloadDecrypt( payload + appPayloadStartIndex, - frameLen, - nwkSKey, - address, - DOWN_LINK, - downLinkCounter, - _params.payload )) { + if (fctrl.bits.fopts_len == 0) { + if (0 != decrypt_payload(payload + app_payload_start_index, + frame_len, + nwk_skey, + address, + DOWN_LINK, + downlink_counter, + _params.payload)) { mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL; } // Decode frame payload MAC commands - if (mac_commands.ProcessMacCommands( _params.payload, 0, frameLen, snr, - mlme.get_confirmation(), - _params.sys_params, *lora_phy ) != LORAWAN_STATUS_OK ) { + if (mac_commands.process_mac_commands(_params.payload, 0, frame_len, snr, + mlme.get_confirmation(), + _params.sys_params, *lora_phy) != LORAWAN_STATUS_OK) { mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_ERROR; } + } else { + skip_indication = true; } - else - { - skipIndication = true; - } - } - else - { - if( fCtrl.bits.fopts_len > 0 ) - { + } else { + if (fctrl.bits.fopts_len > 0) { // Decode Options field MAC commands. Omit the fPort. - if (mac_commands.ProcessMacCommands( payload, 8, appPayloadStartIndex - 1, snr, - mlme.get_confirmation(), - _params.sys_params, *lora_phy ) != LORAWAN_STATUS_OK ) { + if (mac_commands.process_mac_commands(payload, 8, app_payload_start_index - 1, snr, + mlme.get_confirmation(), + _params.sys_params, *lora_phy ) != LORAWAN_STATUS_OK) { mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_ERROR; } } - if (0 != LoRaMacPayloadDecrypt( payload + appPayloadStartIndex, - frameLen, - appSKey, - address, - DOWN_LINK, - downLinkCounter, - _params.payload )) { + if (0 != decrypt_payload(payload + app_payload_start_index, + frame_len, + app_skey, + address, + DOWN_LINK, + downlink_counter, + _params.payload)) { mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL; } - if( skipIndication == false ) - { + if (skip_indication == false) { mcps.get_indication().buffer = _params.payload; - mcps.get_indication().buffer_size = frameLen; + mcps.get_indication().buffer_size = frame_len; mcps.get_indication().is_data_recvd = true; } } - } - else - { - if( fCtrl.bits.fopts_len > 0 ) - { + } else { + if (fctrl.bits.fopts_len > 0) { // Decode Options field MAC commands - if (mac_commands.ProcessMacCommands( payload, 8, appPayloadStartIndex, snr, - mlme.get_confirmation(), - _params.sys_params, *lora_phy ) != LORAWAN_STATUS_OK ) { + if (mac_commands.process_mac_commands(payload, 8, app_payload_start_index, snr, + mlme.get_confirmation(), + _params.sys_params, *lora_phy) != LORAWAN_STATUS_OK) { mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_ERROR; } } } - if( skipIndication == false ) - { + if (skip_indication == false) { // Check if the frame is an acknowledgement - if( fCtrl.bits.ack == 1 ) - { + if (fctrl.bits.ack == 1) { mcps.get_confirmation().ack_received = true; mcps.get_indication().is_ack_recvd = true; // Stop the AckTimeout timer as no more retransmissions // are needed. - _lora_time.stop( _params.timers.ack_timeout_timer ); - } - else - { + _lora_time.stop(_params.timers.ack_timeout_timer); + } else { mcps.get_confirmation().ack_received = false; - if( _params.ack_timeout_retry_counter > _params.max_ack_timeout_retries ) - { + if (_params.ack_timeout_retry_counter > _params.max_ack_timeout_retries) { // Stop the AckTimeout timer as no more retransmissions // are needed. _lora_time.stop( _params.timers.ack_timeout_timer ); @@ -719,49 +688,45 @@ void LoRaMac::OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8 // Provide always an indication, skip the callback to the user application, // in case of a confirmed downlink retransmission. _params.flags.bits.mcps_ind = 1; - _params.flags.bits.mcps_ind_skip = skipIndication; - } - else - { + _params.flags.bits.mcps_ind_skip = skip_indication; + } else { mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_MIC_FAIL; - PrepareRxDoneAbort( ); + prepare_rx_done_abort( ); return; } } + break; + case FRAME_TYPE_PROPRIETARY: { - memcpy( _params.payload, &payload[pktHeaderLen], size ); + memcpy(_params.payload, &payload[pkt_header_len], size); mcps.get_indication().type = MCPS_PROPRIETARY; mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_OK; mcps.get_indication().buffer = _params.payload; - mcps.get_indication().buffer_size = size - pktHeaderLen; + mcps.get_indication().buffer_size = size - pkt_header_len; _params.flags.bits.mcps_ind = 1; break; } default: mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_ERROR; - PrepareRxDoneAbort( ); + prepare_rx_done_abort(); break; } _params.flags.bits.mac_done = 1; - // Trig OnMacCheckTimerEvent call as soon as possible - _lora_time.start( _params.timers.mac_state_check_timer, 1 ); + _lora_time.start(_params.timers.mac_state_check_timer, 1); } -void LoRaMac::OnRadioTxTimeout( void ) +void LoRaMac::on_radio_tx_timeout( void ) { - if( _params.dev_class != CLASS_C ) - { + if (_params.dev_class != CLASS_C) { lora_phy->put_radio_to_sleep(); - } - else - { - OpenContinuousRx2Window( ); + } else { + open_continuous_rx2_window(); } mcps.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT; @@ -771,36 +736,29 @@ void LoRaMac::OnRadioTxTimeout( void ) _params.flags.bits.mac_done = 1; } -void LoRaMac::OnRadioRxError( void ) +void LoRaMac::on_radio_rx_error( void ) { - if( _params.dev_class != CLASS_C ) - { + if (_params.dev_class != CLASS_C) { lora_phy->put_radio_to_sleep(); - } - else - { - OpenContinuousRx2Window( ); + } else { + open_continuous_rx2_window(); } - if( _params.rx_slot == RX_SLOT_WIN_1 ) - { - if( _params.is_node_ack_requested == true ) - { + if (_params.rx_slot == RX_SLOT_WIN_1) { + if (_params.is_node_ack_requested == true) { mcps.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_RX1_ERROR; } mlme.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_RX1_ERROR; - if( _lora_time.get_elapsed_time( _params.timers.aggregated_last_tx_time ) >= _params.rx_window2_delay ) - { - _lora_time.stop( _params.timers.rx_window2_timer ); + if (_lora_time.get_elapsed_time(_params.timers.aggregated_last_tx_time) >= _params.rx_window2_delay) { + _lora_time.stop(_params.timers.rx_window2_timer); _params.flags.bits.mac_done = 1; } - } - else - { - if( _params.is_node_ack_requested == true ) - { + + } else { + + if (_params.is_node_ack_requested == true) { mcps.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_RX2_ERROR; } @@ -810,42 +768,34 @@ void LoRaMac::OnRadioRxError( void ) } } -void LoRaMac::OnRadioRxTimeout( void ) +void LoRaMac::on_radio_rx_timeout(void) { - if( _params.dev_class != CLASS_C ) - { + if (_params.dev_class != CLASS_C) { lora_phy->put_radio_to_sleep(); - } - else - { - OpenContinuousRx2Window( ); + } else { + open_continuous_rx2_window(); } - if( _params.rx_slot == RX_SLOT_WIN_1 ) - { - if( _params.is_node_ack_requested == true ) - { + if (_params.rx_slot == RX_SLOT_WIN_1) { + if (_params.is_node_ack_requested == true) { mcps.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_RX1_TIMEOUT; } mlme.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_RX1_TIMEOUT; - if( _lora_time.get_elapsed_time( _params.timers.aggregated_last_tx_time ) >= _params.rx_window2_delay ) - { - _lora_time.stop( _params.timers.rx_window2_timer ); + if (_lora_time.get_elapsed_time(_params.timers.aggregated_last_tx_time ) >= _params.rx_window2_delay) { + _lora_time.stop(_params.timers.rx_window2_timer); _params.flags.bits.mac_done = 1; } - } - else - { - if( _params.is_node_ack_requested == true ) - { + + } else { + + if (_params.is_node_ack_requested == true) { mcps.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT; } mlme.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT; - if( _params.dev_class != CLASS_C ) - { + if (_params.dev_class != CLASS_C) { _params.flags.bits.mac_done = 1; } } @@ -854,87 +804,74 @@ void LoRaMac::OnRadioRxTimeout( void ) /*************************************************************************** * Timer event callbacks - deliberated locally * **************************************************************************/ -void LoRaMac::OnMacStateCheckTimerEvent( void ) +void LoRaMac::on_mac_state_check_timer_event(void) { - get_phy_params_t getPhy; - phy_param_t phyParam; - bool txTimeout = false; + get_phy_params_t get_phy; + phy_param_t phy_param; + bool tx_timeout = false; - _lora_time.stop( _params.timers.mac_state_check_timer ); + _lora_time.stop(_params.timers.mac_state_check_timer); - if( _params.flags.bits.mac_done == 1 ) - { - if( ( _params.mac_state & LORAMAC_RX_ABORT ) == LORAMAC_RX_ABORT ) - { + if (_params.flags.bits.mac_done == 1) { + + if ((_params.mac_state & LORAMAC_RX_ABORT) == LORAMAC_RX_ABORT) { _params.mac_state &= ~LORAMAC_RX_ABORT; _params.mac_state &= ~LORAMAC_TX_RUNNING; } - if( ( _params.flags.bits.mlme_req == 1 ) || ( ( _params.flags.bits.mcps_req == 1 ) ) ) - { - if( ( mcps.get_confirmation().status == LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT ) || - ( mlme.get_confirmation().status == LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT ) ) - { + if ((_params.flags.bits.mlme_req == 1) || (_params.flags.bits.mcps_req == 1)) { + + if ((mcps.get_confirmation().status == LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT) || + ( mlme.get_confirmation().status == LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT)) { // Stop transmit cycle due to tx timeout. _params.mac_state &= ~LORAMAC_TX_RUNNING; - mac_commands.ClearCommandBuffer(); + mac_commands.clear_command_buffer(); mcps.get_confirmation().nb_retries = _params.ack_timeout_retry_counter; mcps.get_confirmation().ack_received = false; mcps.get_confirmation().tx_toa = 0; - txTimeout = true; + tx_timeout = true; } } - if( ( _params.is_node_ack_requested == false ) && ( txTimeout == false ) ) - { - if( ( _params.flags.bits.mlme_req == 1 ) || ( ( _params.flags.bits.mcps_req == 1 ) ) ) - { - if( ( _params.flags.bits.mlme_req == 1 ) && ( mlme.get_confirmation().req_type == MLME_JOIN ) ) - {// Procedure for the join request + if ((_params.is_node_ack_requested == false) && (tx_timeout == false)) { + if ((_params.flags.bits.mlme_req == 1) || ((_params.flags.bits.mcps_req == 1))) { + if ((_params.flags.bits.mlme_req == 1) && (mlme.get_confirmation().req_type == MLME_JOIN)) { + // Procedure for the join request mlme.get_confirmation().nb_retries = _params.join_request_trial_counter; - if( mlme.get_confirmation().status == LORAMAC_EVENT_INFO_STATUS_OK ) - {// Node joined successfully + if (mlme.get_confirmation().status == LORAMAC_EVENT_INFO_STATUS_OK) { + // Node joined successfully _params.ul_frame_counter = 0; _params.ul_nb_rep_counter = 0; _params.mac_state &= ~LORAMAC_TX_RUNNING; - } - else - { - if( _params.join_request_trial_counter >= _params.max_join_request_trials ) - { + } else { + if (_params.join_request_trial_counter >= _params.max_join_request_trials) { _params.mac_state &= ~LORAMAC_TX_RUNNING; - } - else - { + } else { _params.flags.bits.mac_done = 0; // Sends the same frame again handle_delayed_tx_timer_event(); } } - } - else - {// Procedure for all other frames - if( ( _params.ul_nb_rep_counter >= _params.sys_params.retry_num ) || ( _params.flags.bits.mcps_ind == 1 ) ) - { - if( _params.flags.bits.mcps_ind == 0 ) - { // Maximum repetitions without downlink. Reset MacCommandsBufferIndex. Increase ADR Ack counter. + } else { + // Procedure for all other frames + if ((_params.ul_nb_rep_counter >= _params.sys_params.retry_num) || + (_params.flags.bits.mcps_ind == 1)) { + if (_params.flags.bits.mcps_ind == 0) { + // Maximum repetitions without downlink. Reset MacCommandsBufferIndex. Increase ADR Ack counter. // Only process the case when the MAC did not receive a downlink. - mac_commands.ClearCommandBuffer(); + mac_commands.clear_command_buffer(); _params.adr_ack_counter++; } _params.ul_nb_rep_counter = 0; - if( _params.is_ul_frame_counter_fixed == false ) - { + if (_params.is_ul_frame_counter_fixed == false) { _params.ul_frame_counter++; } _params.mac_state &= ~LORAMAC_TX_RUNNING; - } - else - { + } else { _params.flags.bits.mac_done = 0; // Sends the same frame again handle_delayed_tx_timer_event(); @@ -943,15 +880,13 @@ void LoRaMac::OnMacStateCheckTimerEvent( void ) } } - if( _params.flags.bits.mcps_ind == 1 ) - {// Procedure if we received a frame - if( ( mcps.get_confirmation().ack_received == true ) || - ( _params.ack_timeout_retry_counter > _params.max_ack_timeout_retries ) ) - { + if (_params.flags.bits.mcps_ind == 1) { + // Procedure if we received a frame + if ((mcps.get_confirmation().ack_received == true) || + (_params.ack_timeout_retry_counter > _params.max_ack_timeout_retries)) { _params.is_ack_retry_timeout_expired = false; _params.is_node_ack_requested = false; - if( _params.is_ul_frame_counter_fixed == false ) - { + if (_params.is_ul_frame_counter_fixed == false) { _params.ul_frame_counter++; } mcps.get_confirmation().nb_retries = _params.ack_timeout_retry_counter; @@ -960,156 +895,150 @@ void LoRaMac::OnMacStateCheckTimerEvent( void ) } } - if( ( _params.is_ack_retry_timeout_expired == true ) && ( ( _params.mac_state & LORAMAC_TX_DELAYED ) == 0 ) ) - {// Retransmissions procedure for confirmed uplinks + if ((_params.is_ack_retry_timeout_expired == true) && + ((_params.mac_state & LORAMAC_TX_DELAYED) == 0)) { + + // Retransmissions procedure for confirmed uplinks _params.is_ack_retry_timeout_expired = false; - if( ( _params.ack_timeout_retry_counter < _params.max_ack_timeout_retries ) && - ( _params.ack_timeout_retry_counter <= MAX_ACK_RETRIES ) ) - { + if ((_params.ack_timeout_retry_counter < _params.max_ack_timeout_retries) && + (_params.ack_timeout_retry_counter <= MAX_ACK_RETRIES)) { + _params.ack_timeout_retry_counter++; - if( ( _params.ack_timeout_retry_counter % 2 ) == 1 ) - { - getPhy.attribute = PHY_NEXT_LOWER_TX_DR; - getPhy.datarate = _params.sys_params.channel_data_rate; - phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.channel_data_rate = phyParam.value; + if ((_params.ack_timeout_retry_counter % 2) == 1) { + get_phy.attribute = PHY_NEXT_LOWER_TX_DR; + get_phy.datarate = _params.sys_params.channel_data_rate; + phy_param = lora_phy->get_phy_params( &get_phy ); + _params.sys_params.channel_data_rate = phy_param.value; } + // Try to send the frame again - if( ScheduleTx( ) == LORAWAN_STATUS_OK ) - { + if (schedule_tx() == LORAWAN_STATUS_OK) { _params.flags.bits.mac_done = 0; - } - else - { + } else { // The DR is not applicable for the payload size mcps.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_TX_DR_PAYLOAD_SIZE_ERROR; - mac_commands.ClearCommandBuffer(); + mac_commands.clear_command_buffer(); _params.mac_state &= ~LORAMAC_TX_RUNNING; _params.is_node_ack_requested = false; mcps.get_confirmation().ack_received = false; mcps.get_confirmation().nb_retries = _params.ack_timeout_retry_counter; mcps.get_confirmation().data_rate = _params.sys_params.channel_data_rate; - if( _params.is_ul_frame_counter_fixed == false ) - { + + if (_params.is_ul_frame_counter_fixed == false) { _params.ul_frame_counter++; } } - } - else - { + } else { lora_phy->restore_default_channels(); _params.mac_state &= ~LORAMAC_TX_RUNNING; - mac_commands.ClearCommandBuffer(); + mac_commands.clear_command_buffer(); _params.is_node_ack_requested = false; mcps.get_confirmation().ack_received = false; mcps.get_confirmation().nb_retries = _params.ack_timeout_retry_counter; - if( _params.is_ul_frame_counter_fixed == false ) - { + + if (_params.is_ul_frame_counter_fixed == false) { _params.ul_frame_counter++; } } } } + // Handle reception for Class B and Class C - if( ( _params.mac_state & LORAMAC_RX ) == LORAMAC_RX ) - { + if ((_params.mac_state & LORAMAC_RX) == LORAMAC_RX) { _params.mac_state &= ~LORAMAC_RX; } - if( _params.mac_state == LORAMAC_IDLE ) - { - if( _params.flags.bits.mcps_req == 1 ) - { + + if (_params.mac_state == LORAMAC_IDLE) { + if (_params.flags.bits.mcps_req == 1) { _params.flags.bits.mcps_req = 0; - LoRaMacPrimitives->mcps_confirm( &mcps.get_confirmation() ); + mac_primitives->mcps_confirm(&mcps.get_confirmation()); } - if( _params.flags.bits.mlme_req == 1 ) - { + if (_params.flags.bits.mlme_req == 1) { _params.flags.bits.mlme_req = 0; - LoRaMacPrimitives->mlme_confirm(&mlme.get_confirmation()); + mac_primitives->mlme_confirm(&mlme.get_confirmation()); } // Verify if sticky MAC commands are pending or not - if( mac_commands.IsStickyMacCommandPending( ) == true ) - {// Setup MLME indication - SetMlmeScheduleUplinkIndication( ); + if (mac_commands.is_sticky_mac_command_pending() == true) { + // Setup MLME indication + set_mlme_schedule_ul_indication(); } // Procedure done. Reset variables. _params.flags.bits.mac_done = 0; - } - else - { + } else { // Operation not finished restart timer - _lora_time.start( _params.timers.mac_state_check_timer, MAC_STATE_CHECK_TIMEOUT ); + _lora_time.start(_params.timers.mac_state_check_timer, MAC_STATE_CHECK_TIMEOUT); } // Handle MCPS indication - if( _params.flags.bits.mcps_ind == 1 ) - { + if (_params.flags.bits.mcps_ind == 1) { _params.flags.bits.mcps_ind = 0; - if( _params.dev_class== CLASS_C ) - {// Activate RX2 window for Class C - OpenContinuousRx2Window( ); + + if (_params.dev_class== CLASS_C) { + // Activate RX2 window for Class C + open_continuous_rx2_window(); } - if( _params.flags.bits.mcps_ind_skip == 0 ) - { - LoRaMacPrimitives->mcps_indication( &mcps.get_indication() ); + + if (_params.flags.bits.mcps_ind_skip == 0) { + mac_primitives->mcps_indication(&mcps.get_indication()); } + _params.flags.bits.mcps_ind_skip = 0; } // Handle MLME indication - if( _params.flags.bits.mlme_ind == 1 ) - { + if (_params.flags.bits.mlme_ind == 1) { _params.flags.bits.mlme_ind = 0; - LoRaMacPrimitives->mlme_indication(&mlme.get_indication()); + mac_primitives->mlme_indication(&mlme.get_indication()); } } -void LoRaMac::OnTxDelayedTimerEvent( void ) +void LoRaMac::on_tx_delayed_timer_event(void) { - loramac_mhdr_t macHdr; - loramac_frame_ctrl_t fCtrl; + loramac_mhdr_t mac_hdr; + loramac_frame_ctrl_t fctrl; lorawan_status_t status = LORAWAN_STATUS_OK; - _lora_time.stop( _params.timers.tx_delayed_timer ); + _lora_time.stop(_params.timers.tx_delayed_timer); _params.mac_state &= ~LORAMAC_TX_DELAYED; - if( ( _params.flags.bits.mlme_req == 1 ) && ( mlme.get_confirmation().req_type == MLME_JOIN ) ) - { - ResetMacParameters( ); + if ((_params.flags.bits.mlme_req == 1 ) && + (mlme.get_confirmation().req_type == MLME_JOIN)) { + + reset_mac_parameters(); _params.sys_params.channel_data_rate = lora_phy->get_alternate_DR(_params.join_request_trial_counter + 1); - macHdr.value = 0; - macHdr.bits.mtype = FRAME_TYPE_JOIN_REQ; + mac_hdr.value = 0; + mac_hdr.bits.mtype = FRAME_TYPE_JOIN_REQ; - fCtrl.value = 0; - fCtrl.bits.adr = _params.sys_params.adr_on; + fctrl.value = 0; + fctrl.bits.adr = _params.sys_params.adr_on; /* In case of join request retransmissions, the stack must prepare * the frame again, because the network server keeps track of the random * LoRaMacDevNonce values to prevent reply attacks. */ - status = PrepareFrame( &macHdr, &fCtrl, 0, NULL, 0 ); + status = prepare_frame(&mac_hdr, &fctrl, 0, NULL, 0); } if (status == LORAWAN_STATUS_OK) { - ScheduleTx( ); + schedule_tx(); } else { tr_error("Delayed TX: PrepareFrame returned error %d", status); } } -void LoRaMac::OnRxWindow1TimerEvent( void ) +void LoRaMac::on_rx_window1_timer_event(void) { - _lora_time.stop( _params.timers.rx_window1_timer ); - _params.rx_slot= RX_SLOT_WIN_1; + _lora_time.stop(_params.timers.rx_window1_timer); + _params.rx_slot = RX_SLOT_WIN_1; _params.rx_window1_config.channel = _params.channel; _params.rx_window1_config.dr_offset = _params.sys_params.rx1_dr_offset; @@ -1118,18 +1047,20 @@ void LoRaMac::OnRxWindow1TimerEvent( void ) _params.rx_window1_config.is_rx_continuous = false; _params.rx_window1_config.rx_slot = _params.rx_slot; - if( _params.dev_class== CLASS_C ) - { + if (_params.dev_class == CLASS_C) { lora_phy->put_radio_to_standby(); } - lora_phy->rx_config(&_params.rx_window1_config, ( int8_t* )&mcps.get_indication().rx_datarate); - RxWindowSetup( _params.rx_window1_config.is_rx_continuous, _params.sys_params.max_rx_win_time ); + lora_phy->rx_config(&_params.rx_window1_config, + (int8_t*) &mcps.get_indication().rx_datarate); + + rx_window_setup(_params.rx_window1_config.is_rx_continuous, + _params.sys_params.max_rx_win_time); } -void LoRaMac::OnRxWindow2TimerEvent( void ) +void LoRaMac::on_rx_window2_timer_event(void) { - _lora_time.stop( _params.timers.rx_window2_timer ); + _lora_time.stop(_params.timers.rx_window2_timer); _params.rx_window2_config.channel = _params.channel; _params.rx_window2_config.frequency = _params.sys_params.rx2_channel.frequency; @@ -1137,74 +1068,72 @@ void LoRaMac::OnRxWindow2TimerEvent( void ) _params.rx_window2_config.is_repeater_supported = _params.is_repeater_supported; _params.rx_window2_config.rx_slot = RX_SLOT_WIN_2; - if( _params.dev_class!= CLASS_C ) - { + if (_params.dev_class != CLASS_C) { _params.rx_window2_config.is_rx_continuous = false; - } - else - { + } else { // Setup continuous listening for class c _params.rx_window2_config.is_rx_continuous = true; } - if(lora_phy->rx_config(&_params.rx_window2_config, ( int8_t* )&mcps.get_indication().rx_datarate) == true ) - { - RxWindowSetup( _params.rx_window2_config.is_rx_continuous, _params.sys_params.max_rx_win_time ); - _params.rx_slot= RX_SLOT_WIN_2; + if (lora_phy->rx_config(&_params.rx_window2_config, + (int8_t*) &mcps.get_indication().rx_datarate) == true) { + + rx_window_setup(_params.rx_window2_config.is_rx_continuous, + _params.sys_params.max_rx_win_time); + + _params.rx_slot = RX_SLOT_WIN_2; } } -void LoRaMac::OnAckTimeoutTimerEvent( void ) +void LoRaMac::on_ack_timeout_timer_event(void) { - _lora_time.stop( _params.timers.ack_timeout_timer ); + _lora_time.stop(_params.timers.ack_timeout_timer); - if( _params.is_node_ack_requested == true ) - { + if (_params.is_node_ack_requested == true) { _params.is_ack_retry_timeout_expired = true; _params.mac_state &= ~LORAMAC_ACK_REQ; } - if( _params.dev_class== CLASS_C ) - { + if (_params.dev_class == CLASS_C) { _params.flags.bits.mac_done = 1; } } -void LoRaMac::RxWindowSetup( bool rxContinuous, uint32_t maxRxWindow ) +void LoRaMac::rx_window_setup(bool rx_continuous, uint32_t max_rx_window_time) { - lora_phy->setup_rx_window(rxContinuous, maxRxWindow); + lora_phy->setup_rx_window(rx_continuous, max_rx_window_time); } -bool LoRaMac::ValidatePayloadLength( uint8_t lenN, int8_t datarate, uint8_t fOptsLen ) +bool LoRaMac::validate_payload_length(uint8_t length, int8_t datarate, + uint8_t fopts_len) { - get_phy_params_t getPhy; - phy_param_t phyParam; - uint16_t maxN = 0; + get_phy_params_t get_phy; + phy_param_t phy_param; + uint16_t max_value = 0; uint16_t payloadSize = 0; // Setup PHY request - getPhy.datarate = datarate; - getPhy.attribute = PHY_MAX_PAYLOAD; + get_phy.datarate = datarate; + get_phy.attribute = PHY_MAX_PAYLOAD; // Get the maximum payload length - if( _params.is_repeater_supported == true ) - { - getPhy.attribute = PHY_MAX_PAYLOAD_REPEATER; + if (_params.is_repeater_supported == true) { + get_phy.attribute = PHY_MAX_PAYLOAD_REPEATER; } - phyParam = lora_phy->get_phy_params(&getPhy); - maxN = phyParam.value; + phy_param = lora_phy->get_phy_params(&get_phy); + max_value = phy_param.value; // Calculate the resulting payload size - payloadSize = ( lenN + fOptsLen ); + payloadSize = (length + fopts_len); // Validation of the application payload size - if( ( payloadSize <= maxN ) && ( payloadSize <= LORAMAC_PHY_MAXPAYLOAD ) ) - { + if ((payloadSize <= max_value) && + (payloadSize <= LORAMAC_PHY_MAXPAYLOAD)) { return true; } return false; } -void LoRaMac::SetMlmeScheduleUplinkIndication( void ) +void LoRaMac::set_mlme_schedule_ul_indication(void) { mlme.get_indication().indication_type = MLME_SCHEDULE_UPLINK; _params.flags.bits.mlme_ind = 1; @@ -1212,23 +1141,24 @@ void LoRaMac::SetMlmeScheduleUplinkIndication( void ) // This is not actual transmission. It just schedules a message in response // to MCPS request -lorawan_status_t LoRaMac::Send( loramac_mhdr_t *macHdr, uint8_t fPort, void *fBuffer, uint16_t fBufferSize ) +lorawan_status_t LoRaMac::send(loramac_mhdr_t *machdr, uint8_t fport, + void *fbuffer, uint16_t fbuffer_size) { - loramac_frame_ctrl_t fCtrl; + loramac_frame_ctrl_t fctrl; - fCtrl.value = 0; - fCtrl.bits.fopts_len = 0; - fCtrl.bits.fpending = 0; - fCtrl.bits.ack = false; - fCtrl.bits.adr_ack_req = false; - fCtrl.bits.adr = _params.sys_params.adr_on; + fctrl.value = 0; + fctrl.bits.fopts_len = 0; + fctrl.bits.fpending = 0; + fctrl.bits.ack = false; + fctrl.bits.adr_ack_req = false; + fctrl.bits.adr = _params.sys_params.adr_on; // Prepare the frame - lorawan_status_t status = PrepareFrame( macHdr, &fCtrl, fPort, fBuffer, fBufferSize ); + lorawan_status_t status = prepare_frame(machdr, &fctrl, fport, fbuffer, + fbuffer_size); // Validate status - if( status != LORAWAN_STATUS_OK ) - { + if (status != LORAWAN_STATUS_OK) { return status; } @@ -1237,12 +1167,12 @@ lorawan_status_t LoRaMac::Send( loramac_mhdr_t *macHdr, uint8_t fPort, void *fBu mcps.get_confirmation().ack_received = false; mcps.get_confirmation().ul_frame_counter = _params.ul_frame_counter; - status = ScheduleTx( ); + status = schedule_tx(); return status; } -lorawan_status_t LoRaMac::ScheduleTx( void ) +lorawan_status_t LoRaMac::schedule_tx(void) { lorawan_time_t dutyCycleTimeOff = 0; channel_selection_params_t nextChan; @@ -1250,17 +1180,16 @@ lorawan_status_t LoRaMac::ScheduleTx( void ) phy_param_t phyParam; // Check if the device is off - if( _params.sys_params.max_duty_cycle == 255 ) - { + if (_params.sys_params.max_duty_cycle == 255) { return LORAWAN_STATUS_DEVICE_OFF; } - if( _params.sys_params.max_duty_cycle == 0 ) - { + + if (_params.sys_params.max_duty_cycle == 0) { _params.timers.aggregated_timeoff = 0; } // Update Backoff - CalculateBackOff( _params.last_channel_idx ); + calculate_backOff(_params.last_channel_idx); nextChan.aggregate_timeoff = _params.timers.aggregated_timeoff; nextChan.current_datarate = _params.sys_params.channel_data_rate; @@ -1270,12 +1199,12 @@ lorawan_status_t LoRaMac::ScheduleTx( void ) nextChan.last_aggregate_tx_time = _params.timers.aggregated_last_tx_time; // Select channel - while( lora_phy->set_next_channel(&nextChan, &_params.channel, &dutyCycleTimeOff, - &_params.timers.aggregated_timeoff ) == false ) - { + while (lora_phy->set_next_channel(&nextChan, &_params.channel, + &dutyCycleTimeOff, + &_params.timers.aggregated_timeoff) == false) { // Set the default datarate getPhy.attribute = PHY_DEF_TX_DR; - phyParam = lora_phy->get_phy_params( &getPhy ); + phyParam = lora_phy->get_phy_params(&getPhy); _params.sys_params.channel_data_rate = phyParam.value; // Update datarate in the function parameters nextChan.current_datarate = _params.sys_params.channel_data_rate; @@ -1288,73 +1217,72 @@ lorawan_status_t LoRaMac::ScheduleTx( void ) _params.sys_params.rx1_dr_offset); lora_phy->compute_rx_win_params(dr_offset, _params.sys_params.min_rx_symb, - _params.sys_params.max_sys_rx_error, - &_params.rx_window1_config ); + _params.sys_params.max_sys_rx_error, + &_params.rx_window1_config); + // Compute Rx2 windows parameters lora_phy->compute_rx_win_params(_params.sys_params.rx2_channel.datarate, _params.sys_params.min_rx_symb, _params.sys_params.max_sys_rx_error, - &_params.rx_window2_config ); + &_params.rx_window2_config); - if( _params.is_nwk_joined == false ) - { - _params.rx_window1_delay = _params.sys_params.join_accept_delay1 + _params.rx_window1_config.window_offset; - _params.rx_window2_delay = _params.sys_params.join_accept_delay2 + _params.rx_window2_config.window_offset; - } - else - { - if( ValidatePayloadLength( _params.payload_length, - _params.sys_params.channel_data_rate, - mac_commands.GetLength() ) == false ) - { + if (_params.is_nwk_joined == false) { + _params.rx_window1_delay = _params.sys_params.join_accept_delay1 + + _params.rx_window1_config.window_offset; + _params.rx_window2_delay = _params.sys_params.join_accept_delay2 + + _params.rx_window2_config.window_offset; + } else { + if (validate_payload_length(_params.payload_length, + _params.sys_params.channel_data_rate, + mac_commands.get_mac_cmd_length()) == false) { return LORAWAN_STATUS_LENGTH_ERROR; } - _params.rx_window1_delay = _params.sys_params.recv_delay1 + _params.rx_window1_config.window_offset; - _params.rx_window2_delay = _params.sys_params.recv_delay2 + _params.rx_window2_config.window_offset; + _params.rx_window1_delay = _params.sys_params.recv_delay1 + + _params.rx_window1_config.window_offset; + _params.rx_window2_delay = _params.sys_params.recv_delay2 + + _params.rx_window2_config.window_offset; } // Schedule transmission of frame - if( dutyCycleTimeOff == 0 ) - { + if (dutyCycleTimeOff == 0) { // Try to send now - return SendFrameOnChannel( _params.channel ); - } - else - { + return send_frame_on_channel(_params.channel); + } else { // Send later - prepare timer _params.mac_state |= LORAMAC_TX_DELAYED; tr_debug("Next Transmission in %lu ms", dutyCycleTimeOff); - _lora_time.start( _params.timers.tx_delayed_timer, dutyCycleTimeOff ); + _lora_time.start(_params.timers.tx_delayed_timer, dutyCycleTimeOff); return LORAWAN_STATUS_OK; } } -void LoRaMac::CalculateBackOff( uint8_t channel ) +void LoRaMac::calculate_backOff(uint8_t channel) { - backoff_params_t calcBackOff; + backoff_params_t backoff_params; - calcBackOff.joined = _params.is_nwk_joined; + backoff_params.joined = _params.is_nwk_joined; _params.is_dutycycle_on = MBED_CONF_LORA_DUTY_CYCLE_ON; - calcBackOff.dc_enabled = _params.is_dutycycle_on; - calcBackOff.channel = channel; - calcBackOff.elapsed_time = _lora_time.get_elapsed_time( _params.timers.mac_init_time ); - calcBackOff.tx_toa = _params.timers.tx_toa; - calcBackOff.last_tx_was_join_req = _params.is_last_tx_join_request; + backoff_params.dc_enabled = _params.is_dutycycle_on; + backoff_params.channel = channel; + backoff_params.elapsed_time = _lora_time.get_elapsed_time(_params.timers.mac_init_time); + backoff_params.tx_toa = _params.timers.tx_toa; + backoff_params.last_tx_was_join_req = _params.is_last_tx_join_request; // Update regional back-off - lora_phy->calculate_backoff(&calcBackOff); + lora_phy->calculate_backoff(&backoff_params); // Update aggregated time-off - _params.timers.aggregated_timeoff = _params.timers.aggregated_timeoff + - ( _params.timers.tx_toa * _params.sys_params.aggregated_duty_cycle - _params.timers.tx_toa ); + _params.timers.aggregated_timeoff = _params.timers.aggregated_timeoff + + (_params.timers.tx_toa * _params.sys_params.aggregated_duty_cycle + - _params.timers.tx_toa); } -void LoRaMac::ResetMacParameters( void ) +void LoRaMac::reset_mac_parameters(void) { - get_phy_params_t getPhy; - phy_param_t phyParam; + get_phy_params_t get_phy; + phy_param_t phy_param; _params.is_nwk_joined = false; @@ -1372,53 +1300,52 @@ void LoRaMac::ResetMacParameters( void ) _params.sys_params.max_duty_cycle = 0; _params.sys_params.aggregated_duty_cycle = 1; - mac_commands.ClearCommandBuffer(); - mac_commands.ClearRepeatBuffer(); - mac_commands.ClearMacCommandsInNextTx(); + mac_commands.clear_command_buffer(); + mac_commands.clear_repeat_buffer(); + mac_commands.clear_mac_commands_in_next_tx(); _params.is_rx_window_enabled = true; - getPhy.attribute = PHY_DEF_TX_POWER; - phyParam = lora_phy->get_phy_params( &getPhy ); + get_phy.attribute = PHY_DEF_TX_POWER; + phy_param = lora_phy->get_phy_params(&get_phy); - _params.sys_params.channel_tx_power = phyParam.value; + _params.sys_params.channel_tx_power = phy_param.value; - getPhy.attribute = PHY_DEF_TX_DR; - phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.channel_data_rate = phyParam.value; + get_phy.attribute = PHY_DEF_TX_DR; + phy_param = lora_phy->get_phy_params(&get_phy); + _params.sys_params.channel_data_rate = phy_param.value; - getPhy.attribute = PHY_DEF_DR1_OFFSET; - phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.rx1_dr_offset = phyParam.value; + get_phy.attribute = PHY_DEF_DR1_OFFSET; + phy_param = lora_phy->get_phy_params(&get_phy); + _params.sys_params.rx1_dr_offset = phy_param.value; - getPhy.attribute = PHY_DEF_RX2_FREQUENCY; - phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.rx2_channel.frequency = phyParam.value; - getPhy.attribute = PHY_DEF_RX2_DR; - phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.rx2_channel.datarate = phyParam.value; + get_phy.attribute = PHY_DEF_RX2_FREQUENCY; + phy_param = lora_phy->get_phy_params(&get_phy); + _params.sys_params.rx2_channel.frequency = phy_param.value; + get_phy.attribute = PHY_DEF_RX2_DR; + phy_param = lora_phy->get_phy_params(&get_phy); + _params.sys_params.rx2_channel.datarate = phy_param.value; - getPhy.attribute = PHY_DEF_UPLINK_DWELL_TIME; - phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.uplink_dwell_time = phyParam.value; + get_phy.attribute = PHY_DEF_UPLINK_DWELL_TIME; + phy_param = lora_phy->get_phy_params(&get_phy); + _params.sys_params.uplink_dwell_time = phy_param.value; - getPhy.attribute = PHY_DEF_MAX_EIRP; - phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.max_eirp = phyParam.value; + get_phy.attribute = PHY_DEF_MAX_EIRP; + phy_param = lora_phy->get_phy_params(&get_phy); + _params.sys_params.max_eirp = phy_param.value; - getPhy.attribute = PHY_DEF_ANTENNA_GAIN; - phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.antenna_gain = phyParam.value; + get_phy.attribute = PHY_DEF_ANTENNA_GAIN; + phy_param = lora_phy->get_phy_params(&get_phy); + _params.sys_params.antenna_gain = phy_param.value; _params.is_node_ack_requested = false; _params.is_srv_ack_requested = false; // Reset Multicast downlink counters multicast_params_t *cur = _params.multicast_channels; - while( cur != NULL ) - { + while (cur != NULL) { cur->dl_frame_counter = 0; - cur = cur->Next; + cur = cur->next; } // Initialize channel index. @@ -1426,89 +1353,89 @@ void LoRaMac::ResetMacParameters( void ) _params.last_channel_idx = _params.channel; } -bool LoRaMac::IsFPortAllowed( uint8_t fPort ) +bool LoRaMac::is_fPort_allowed (uint8_t fPort) { - if( ( fPort == 0 ) || ( fPort > 224 ) ) - { + if ((fPort == 0) || (fPort > 224)) { return false; } return true; } -void LoRaMac::OpenContinuousRx2Window( void ) +void LoRaMac::open_continuous_rx2_window (void) { - handle_rx2_timer_event( ); + handle_rx2_timer_event(); _params.rx_slot = RX_SLOT_WIN_CLASS_C; } -static void memcpy_convert_endianess( uint8_t *dst, const uint8_t *src, uint16_t size ) +static void memcpy_convert_endianess(uint8_t *dst, const uint8_t *src, + uint16_t size) { - dst = dst + ( size - 1 ); - while( size-- ) - { + dst = dst + (size - 1); + while (size--) { *dst-- = *src++; } } -lorawan_status_t LoRaMac::PrepareFrame( loramac_mhdr_t *macHdr, loramac_frame_ctrl_t *fCtrl, uint8_t fPort, void *fBuffer, uint16_t fBufferSize ) +lorawan_status_t LoRaMac::prepare_frame(loramac_mhdr_t *machdr, + loramac_frame_ctrl_t *fctrl, + uint8_t fport, void *fbuffer, + uint16_t fbuffer_size) { uint16_t i; - uint8_t pktHeaderLen = 0; + uint8_t pkt_header_len = 0; uint32_t mic = 0; - const void* payload = fBuffer; - uint8_t framePort = fPort; + const void* payload = fbuffer; + uint8_t frame_port = fport; lorawan_status_t status = LORAWAN_STATUS_OK; _params.buffer_pkt_len = 0; _params.is_node_ack_requested = false; - if( fBuffer == NULL ) - { - fBufferSize = 0; + if (fbuffer == NULL) { + fbuffer_size = 0; } - _params.payload_length = fBufferSize; + _params.payload_length = fbuffer_size; - _params.buffer[pktHeaderLen++] = macHdr->value; + _params.buffer[pkt_header_len++] = machdr->value; + + switch (machdr->bits.mtype) { - switch( macHdr->bits.mtype ) - { case FRAME_TYPE_JOIN_REQ: - _params.buffer_pkt_len = pktHeaderLen; - memcpy_convert_endianess( _params.buffer + _params.buffer_pkt_len, - _params.keys.app_eui, 8 ); + _params.buffer_pkt_len = pkt_header_len; + memcpy_convert_endianess(_params.buffer + _params.buffer_pkt_len, + _params.keys.app_eui, 8); _params.buffer_pkt_len += 8; - memcpy_convert_endianess( _params.buffer + _params.buffer_pkt_len, - _params.keys.dev_eui, 8 ); + memcpy_convert_endianess(_params.buffer + _params.buffer_pkt_len, + _params.keys.dev_eui, 8); _params.buffer_pkt_len += 8; _params.dev_nonce = lora_phy->get_radio_rng(); _params.buffer[_params.buffer_pkt_len++] = _params.dev_nonce & 0xFF; - _params.buffer[_params.buffer_pkt_len++] = ( _params.dev_nonce >> 8 ) & 0xFF; + _params.buffer[_params.buffer_pkt_len++] = (_params.dev_nonce >> 8) & 0xFF; - if (0 != LoRaMacJoinComputeMic( _params.buffer, - _params.buffer_pkt_len & 0xFF, - _params.keys.app_key, &mic )) { + if (0 != compute_join_frame_mic(_params.buffer, + _params.buffer_pkt_len & 0xFF, + _params.keys.app_key, &mic)) { return LORAWAN_STATUS_CRYPTO_FAIL; } _params.buffer[_params.buffer_pkt_len++] = mic & 0xFF; - _params.buffer[_params.buffer_pkt_len++] = ( mic >> 8 ) & 0xFF; - _params. buffer[_params.buffer_pkt_len++] = ( mic >> 16 ) & 0xFF; - _params.buffer[_params.buffer_pkt_len++] = ( mic >> 24 ) & 0xFF; + _params.buffer[_params.buffer_pkt_len++] = (mic >> 8) & 0xFF; + _params.buffer[_params.buffer_pkt_len++] = (mic >> 16) & 0xFF; + _params.buffer[_params.buffer_pkt_len++] = (mic >> 24) & 0xFF; break; case FRAME_TYPE_DATA_CONFIRMED_UP: _params.is_node_ack_requested = true; //Intentional fallthrough - case FRAME_TYPE_DATA_UNCONFIRMED_UP: - { - if( _params.is_nwk_joined == false ) - { - return LORAWAN_STATUS_NO_NETWORK_JOINED; // No network has been joined yet + case FRAME_TYPE_DATA_UNCONFIRMED_UP: { + if (_params.is_nwk_joined == false) { + // No network has been joined yet + return LORAWAN_STATUS_NO_NETWORK_JOINED; } if (_params.sys_params.adr_on) { @@ -1516,124 +1443,109 @@ lorawan_status_t LoRaMac::PrepareFrame( loramac_mhdr_t *macHdr, loramac_frame_ct _params.sys_params.channel_data_rate, _params.sys_params.channel_tx_power, _params.adr_ack_counter)) { - fCtrl->bits.adr_ack_req = 1; + fctrl->bits.adr_ack_req = 1; } } - if( _params.is_srv_ack_requested == true ) - { + if (_params.is_srv_ack_requested == true) { _params.is_srv_ack_requested = false; - fCtrl->bits.ack = 1; + fctrl->bits.ack = 1; } - _params.buffer[pktHeaderLen++] = ( _params.dev_addr ) & 0xFF; - _params.buffer[pktHeaderLen++] = ( _params.dev_addr >> 8 ) & 0xFF; - _params.buffer[pktHeaderLen++] = ( _params.dev_addr >> 16 ) & 0xFF; - _params.buffer[pktHeaderLen++] = ( _params.dev_addr >> 24 ) & 0xFF; + _params.buffer[pkt_header_len++] = (_params.dev_addr) & 0xFF; + _params.buffer[pkt_header_len++] = (_params.dev_addr >> 8) & 0xFF; + _params.buffer[pkt_header_len++] = (_params.dev_addr >> 16) & 0xFF; + _params.buffer[pkt_header_len++] = (_params.dev_addr >> 24) & 0xFF; - _params.buffer[pktHeaderLen++] = fCtrl->value; + _params.buffer[pkt_header_len++] = fctrl->value; - _params.buffer[pktHeaderLen++] = _params.ul_frame_counter & 0xFF; - _params.buffer[pktHeaderLen++] = ( _params.ul_frame_counter >> 8 ) & 0xFF; + _params.buffer[pkt_header_len++] = _params.ul_frame_counter & 0xFF; + _params.buffer[pkt_header_len++] = (_params.ul_frame_counter >> 8) + & 0xFF; // Copy the MAC commands which must be re-send into the MAC command buffer - mac_commands.CopyRepeatCommandsToBuffer(); + mac_commands.copy_repeat_commands_to_buffer(); - const uint8_t mac_commands_len = mac_commands.GetLength(); - if( ( payload != NULL ) && ( _params.payload_length > 0 ) ) - { - if( mac_commands.IsMacCommandsInNextTx() == true ) - { - if( mac_commands_len <= LORA_MAC_COMMAND_MAX_FOPTS_LENGTH ) - { - fCtrl->bits.fopts_len += mac_commands_len; + const uint8_t mac_commands_len = mac_commands.get_mac_cmd_length(); + + if ((payload != NULL) && (_params.payload_length > 0)) { + if (mac_commands.is_mac_command_in_next_tx() == true) { + if (mac_commands_len <= LORA_MAC_COMMAND_MAX_FOPTS_LENGTH) { + fctrl->bits.fopts_len += mac_commands_len; // Update FCtrl field with new value of OptionsLength - _params.buffer[0x05] = fCtrl->value; + _params.buffer[0x05] = fctrl->value; - const uint8_t *buffer = mac_commands.GetMacCommandsBuffer(); - for( i = 0; i < mac_commands_len; i++ ) - { - _params.buffer[pktHeaderLen++] = buffer[i]; + const uint8_t *buffer = + mac_commands.get_mac_commands_buffer(); + for (i = 0; i < mac_commands_len; i++) { + _params.buffer[pkt_header_len++] = buffer[i]; } - } - else - { + } else { _params.payload_length = mac_commands_len; - payload = mac_commands.GetMacCommandsBuffer(); - framePort = 0; + payload = mac_commands.get_mac_commands_buffer(); + frame_port = 0; } } - } - else - { - if( ( mac_commands_len > 0 ) && ( mac_commands.IsMacCommandsInNextTx() == true ) ) - { + } else { + if ((mac_commands_len > 0) + && (mac_commands.is_mac_command_in_next_tx() == true)) { _params.payload_length = mac_commands_len; - payload = mac_commands.GetMacCommandsBuffer(); - framePort = 0; + payload = mac_commands.get_mac_commands_buffer(); + frame_port = 0; } } // Store MAC commands which must be re-send in case the device does not receive a downlink anymore - mac_commands.ParseMacCommandsToRepeat(); + mac_commands.parse_mac_commands_to_repeat(); - if( ( payload != NULL ) && ( _params.payload_length > 0 ) ) - { - _params.buffer[pktHeaderLen++] = framePort; + if ((payload != NULL) && (_params.payload_length > 0)) { + _params.buffer[pkt_header_len++] = frame_port; - if( framePort == 0 ) - { + if (frame_port == 0) { // Reset buffer index as the mac commands are being sent on port 0 - mac_commands.ClearCommandBuffer(); - if (0 != LoRaMacPayloadEncrypt( (uint8_t* ) payload, - _params.payload_length, - _params.keys.nwk_skey, - _params.dev_addr, - UP_LINK, - _params.ul_frame_counter, - &_params.buffer[pktHeaderLen] )) { + mac_commands.clear_command_buffer(); + if (0 != encrypt_payload((uint8_t*) payload, _params.payload_length, + _params.keys.nwk_skey, _params.dev_addr, + UP_LINK, + _params.ul_frame_counter, + &_params.buffer[pkt_header_len])) { status = LORAWAN_STATUS_CRYPTO_FAIL; } - } - else - { - if (0 != LoRaMacPayloadEncrypt( (uint8_t* ) payload, - _params.payload_length, - _params.keys.app_skey, - _params.dev_addr, - UP_LINK, - _params.ul_frame_counter, - &_params.buffer[pktHeaderLen] )) { + } else { + if (0 != encrypt_payload((uint8_t*) payload, _params.payload_length, + _params.keys.app_skey, _params.dev_addr, + UP_LINK, + _params.ul_frame_counter, + &_params.buffer[pkt_header_len])) { status = LORAWAN_STATUS_CRYPTO_FAIL; } } } - _params.buffer_pkt_len = pktHeaderLen + _params.payload_length; - if (0 != LoRaMacComputeMic( _params.buffer, - _params.buffer_pkt_len, - _params.keys.nwk_skey, - _params.dev_addr, - UP_LINK, - _params.ul_frame_counter, - &mic )) { + _params.buffer_pkt_len = pkt_header_len + _params.payload_length; + + if (0 != compute_mic(_params.buffer, _params.buffer_pkt_len, + _params.keys.nwk_skey, + _params.dev_addr, + UP_LINK, + _params.ul_frame_counter, &mic)) { status = LORAWAN_STATUS_CRYPTO_FAIL; } _params.buffer[_params.buffer_pkt_len + 0] = mic & 0xFF; - _params.buffer[_params.buffer_pkt_len + 1] = ( mic >> 8 ) & 0xFF; - _params.buffer[_params.buffer_pkt_len + 2] = ( mic >> 16 ) & 0xFF; - _params.buffer[_params.buffer_pkt_len + 3] = ( mic >> 24 ) & 0xFF; + _params.buffer[_params.buffer_pkt_len + 1] = (mic >> 8) & 0xFF; + _params.buffer[_params.buffer_pkt_len + 2] = (mic >> 16) & 0xFF; + _params.buffer[_params.buffer_pkt_len + 3] = (mic >> 24) & 0xFF; _params.buffer_pkt_len += LORAMAC_MFR_LEN; } - break; + break; case FRAME_TYPE_PROPRIETARY: - if( ( fBuffer != NULL ) && (_params.payload_length > 0 ) ) - { - memcpy( _params.buffer + pktHeaderLen, ( uint8_t* ) fBuffer, _params.payload_length ); - _params.buffer_pkt_len = pktHeaderLen + _params.payload_length; + if ((fbuffer != NULL) && (_params.payload_length > 0)) { + memcpy(_params.buffer + pkt_header_len, (uint8_t*) fbuffer, + _params.payload_length); + _params.buffer_pkt_len = pkt_header_len + _params.payload_length; } break; default: @@ -1643,10 +1555,10 @@ lorawan_status_t LoRaMac::PrepareFrame( loramac_mhdr_t *macHdr, loramac_frame_ct return status; } -lorawan_status_t LoRaMac::SendFrameOnChannel( uint8_t channel ) +lorawan_status_t LoRaMac::send_frame_on_channel(uint8_t channel) { tx_config_params_t tx_config; - int8_t txPower = 0; + int8_t tx_power = 0; tx_config.channel = channel; tx_config.datarate = _params.sys_params.channel_data_rate; @@ -1655,23 +1567,23 @@ lorawan_status_t LoRaMac::SendFrameOnChannel( uint8_t channel ) tx_config.antenna_gain = _params.sys_params.antenna_gain; tx_config.pkt_len = _params.buffer_pkt_len; - lora_phy->tx_config(&tx_config, &txPower, &_params.timers.tx_toa); + lora_phy->tx_config(&tx_config, &tx_power, &_params.timers.tx_toa); mlme.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_ERROR; mcps.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_ERROR; mcps.get_confirmation().data_rate = _params.sys_params.channel_data_rate; - mcps.get_confirmation().tx_power = txPower; + mcps.get_confirmation().tx_power = tx_power; // Store the time on air mcps.get_confirmation().tx_toa = _params.timers.tx_toa; mlme.get_confirmation().tx_toa = _params.timers.tx_toa; // Starts the MAC layer status check timer - _lora_time.start( _params.timers.mac_state_check_timer, MAC_STATE_CHECK_TIMEOUT ); + _lora_time.start(_params.timers.mac_state_check_timer, + MAC_STATE_CHECK_TIMEOUT); - if( _params.is_nwk_joined == false ) - { + if (_params.is_nwk_joined == false) { _params.join_request_trial_counter++; } @@ -1683,60 +1595,62 @@ lorawan_status_t LoRaMac::SendFrameOnChannel( uint8_t channel ) return LORAWAN_STATUS_OK; } -lorawan_status_t LoRaMac::SetTxContinuousWave( uint16_t timeout ) +lorawan_status_t LoRaMac::set_tx_continuous_wave(uint16_t timeout) { - cw_mode_params_t continuousWave; + cw_mode_params_t continuous_wave; - continuousWave.channel = _params.channel; - continuousWave.datarate = _params.sys_params.channel_data_rate; - continuousWave.tx_power = _params.sys_params.channel_tx_power; - continuousWave.max_eirp = _params.sys_params.max_eirp; - continuousWave.antenna_gain = _params.sys_params.antenna_gain; - continuousWave.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(&continuousWave); + 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 ); + _lora_time.start(_params.timers.mac_state_check_timer, + MAC_STATE_CHECK_TIMEOUT); _params.mac_state |= LORAMAC_TX_RUNNING; return LORAWAN_STATUS_OK; } -lorawan_status_t LoRaMac::SetTxContinuousWave1( uint16_t timeout, uint32_t frequency, uint8_t power ) +lorawan_status_t LoRaMac::set_tx_continuous_wave1(uint16_t timeout, + uint32_t frequency, + uint8_t power) { - cw_mode_params_t continuousWave; + cw_mode_params_t continuous_wave; - continuousWave.channel = 0; - continuousWave.datarate = 0; - continuousWave.tx_power = power; - continuousWave.max_eirp = 0; - continuousWave.antenna_gain = 0; - continuousWave.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(&continuousWave); + 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 ); + _lora_time.start(_params.timers.mac_state_check_timer, + MAC_STATE_CHECK_TIMEOUT); _params.mac_state |= LORAMAC_TX_RUNNING; return LORAWAN_STATUS_OK; } -lorawan_status_t LoRaMac::LoRaMacInitialization(loramac_primitives_t *primitives, - LoRaPHY *phy, - EventQueue *queue) +lorawan_status_t LoRaMac::initialize(loramac_primitives_t *primitives, + LoRaPHY *phy, EventQueue *queue) { - get_phy_params_t getPhy; - phy_param_t phyParam; + get_phy_params_t get_phy; + phy_param_t phy_param; //store event queue pointer ev_queue = queue; - if(!primitives) - { + if (!primitives) { return LORAWAN_STATUS_PARAMETER_INVALID; } @@ -1752,9 +1666,9 @@ lorawan_status_t LoRaMac::LoRaMacInitialization(loramac_primitives_t *primitives mib.activate_mib_subsystem(this, lora_phy); // Activate channel planning subsystem - ch_plan.activate_channelplan_subsystem(lora_phy, &mib); + channel_plan.activate_channelplan_subsystem(lora_phy, &mib); - LoRaMacPrimitives = primitives; + mac_primitives = primitives; _params.flags.value = 0; @@ -1770,73 +1684,73 @@ lorawan_status_t LoRaMac::LoRaMacInitialization(loramac_primitives_t *primitives _params.timers.aggregated_timeoff = 0; // Reset to defaults - getPhy.attribute = PHY_DUTY_CYCLE; - phyParam = lora_phy->get_phy_params(&getPhy); + get_phy.attribute = PHY_DUTY_CYCLE; + phy_param = lora_phy->get_phy_params(&get_phy); // load default at this moment. Later can be changed using json - _params.is_dutycycle_on = ( bool ) phyParam.value; + _params.is_dutycycle_on = (bool) phy_param.value; - getPhy.attribute = PHY_DEF_TX_POWER; - phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.channel_tx_power = phyParam.value; + get_phy.attribute = PHY_DEF_TX_POWER; + phy_param = lora_phy->get_phy_params(&get_phy); + _params.sys_params.channel_tx_power = phy_param.value; - getPhy.attribute = PHY_DEF_TX_DR; - phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.channel_data_rate = phyParam.value; + get_phy.attribute = PHY_DEF_TX_DR; + phy_param = lora_phy->get_phy_params(&get_phy); + _params.sys_params.channel_data_rate = phy_param.value; - getPhy.attribute = PHY_MAX_RX_WINDOW; - phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.max_rx_win_time = phyParam.value; + get_phy.attribute = PHY_MAX_RX_WINDOW; + phy_param = lora_phy->get_phy_params(&get_phy); + _params.sys_params.max_rx_win_time = phy_param.value; - getPhy.attribute = PHY_RECEIVE_DELAY1; - phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.recv_delay1 = phyParam.value; + get_phy.attribute = PHY_RECEIVE_DELAY1; + phy_param = lora_phy->get_phy_params(&get_phy); + _params.sys_params.recv_delay1 = phy_param.value; - getPhy.attribute = PHY_RECEIVE_DELAY2; - phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.recv_delay2 = phyParam.value; + get_phy.attribute = PHY_RECEIVE_DELAY2; + phy_param = lora_phy->get_phy_params(&get_phy); + _params.sys_params.recv_delay2 = phy_param.value; - getPhy.attribute = PHY_JOIN_ACCEPT_DELAY1; - phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.join_accept_delay1 = phyParam.value; + get_phy.attribute = PHY_JOIN_ACCEPT_DELAY1; + phy_param = lora_phy->get_phy_params(&get_phy); + _params.sys_params.join_accept_delay1 = phy_param.value; - getPhy.attribute = PHY_JOIN_ACCEPT_DELAY2; - phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.join_accept_delay2 = phyParam.value; + get_phy.attribute = PHY_JOIN_ACCEPT_DELAY2; + phy_param = lora_phy->get_phy_params(&get_phy); + _params.sys_params.join_accept_delay2 = phy_param.value; - getPhy.attribute = PHY_DEF_DR1_OFFSET; - phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.rx1_dr_offset = phyParam.value; + get_phy.attribute = PHY_DEF_DR1_OFFSET; + phy_param = lora_phy->get_phy_params(&get_phy); + _params.sys_params.rx1_dr_offset = phy_param.value; - getPhy.attribute = PHY_DEF_RX2_FREQUENCY; - phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.rx2_channel.frequency = phyParam.value; + get_phy.attribute = PHY_DEF_RX2_FREQUENCY; + phy_param = lora_phy->get_phy_params(&get_phy); + _params.sys_params.rx2_channel.frequency = phy_param.value; - getPhy.attribute = PHY_DEF_RX2_DR; - phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.rx2_channel.datarate = phyParam.value; + get_phy.attribute = PHY_DEF_RX2_DR; + phy_param = lora_phy->get_phy_params(&get_phy); + _params.sys_params.rx2_channel.datarate = phy_param.value; - getPhy.attribute = PHY_DEF_UPLINK_DWELL_TIME; - phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.uplink_dwell_time = phyParam.value; + get_phy.attribute = PHY_DEF_UPLINK_DWELL_TIME; + phy_param = lora_phy->get_phy_params(&get_phy); + _params.sys_params.uplink_dwell_time = phy_param.value; - getPhy.attribute = PHY_DEF_DOWNLINK_DWELL_TIME; - phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.downlink_dwell_time = phyParam.value; + get_phy.attribute = PHY_DEF_DOWNLINK_DWELL_TIME; + phy_param = lora_phy->get_phy_params(&get_phy); + _params.sys_params.downlink_dwell_time = phy_param.value; - getPhy.attribute = PHY_DEF_MAX_EIRP; - phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.max_eirp = phyParam.f_value; + get_phy.attribute = PHY_DEF_MAX_EIRP; + phy_param = lora_phy->get_phy_params(&get_phy); + _params.sys_params.max_eirp = phy_param.f_value; - getPhy.attribute = PHY_DEF_ANTENNA_GAIN; - phyParam = lora_phy->get_phy_params( &getPhy ); - _params.sys_params.antenna_gain = phyParam.f_value; + get_phy.attribute = PHY_DEF_ANTENNA_GAIN; + phy_param = lora_phy->get_phy_params(&get_phy); + _params.sys_params.antenna_gain = phy_param.f_value; // Init parameters which are not set in function ResetMacParameters _params.sys_params.max_sys_rx_error = 10; _params.sys_params.min_rx_symb = 6; _params.sys_params.retry_num = 1; - ResetMacParameters( ); + reset_mac_parameters(); // Random seed initialization srand(lora_phy->get_radio_rng()); @@ -1847,15 +1761,15 @@ lorawan_status_t LoRaMac::LoRaMacInitialization(loramac_primitives_t *primitives // Initialize timers _lora_time.init(_params.timers.mac_state_check_timer, - mbed::callback(this, &LoRaMac::handle_mac_state_check_timer_event)); + mbed::callback(this, &LoRaMac::handle_mac_state_check_timer_event)); _lora_time.init(_params.timers.tx_delayed_timer, - mbed::callback(this, &LoRaMac::handle_delayed_tx_timer_event)); + mbed::callback(this, &LoRaMac::handle_delayed_tx_timer_event)); _lora_time.init(_params.timers.rx_window1_timer, - mbed::callback(this, &LoRaMac::handle_rx1_timer_event)); + mbed::callback(this, &LoRaMac::handle_rx1_timer_event)); _lora_time.init(_params.timers.rx_window2_timer, - mbed::callback(this, &LoRaMac::handle_rx2_timer_event)); + mbed::callback(this, &LoRaMac::handle_rx2_timer_event)); _lora_time.init(_params.timers.ack_timeout_timer, - mbed::callback(this, &LoRaMac::handle_ack_timeout)); + mbed::callback(this, &LoRaMac::handle_ack_timeout)); // Store the current initialization time _params.timers.mac_init_time = _lora_time.get_current_time(); @@ -1885,23 +1799,24 @@ void LoRaMac::disconnect() _params.mac_state = 0; // Clear MAC commands - mac_commands.ClearCommandBuffer(); - mac_commands.ClearRepeatBuffer(); - mac_commands.ClearMacCommandsInNextTx(); + mac_commands.clear_command_buffer(); + mac_commands.clear_repeat_buffer(); + mac_commands.clear_mac_commands_in_next_tx(); // Set internal state to idle. _params.mac_state = LORAMAC_IDLE; } -lorawan_status_t LoRaMac::LoRaMacQueryTxPossible( uint8_t size, loramac_tx_info_t* txInfo ) +lorawan_status_t LoRaMac::query_tx_possible(uint8_t size, + loramac_tx_info_t* tx_info) { - get_phy_params_t getPhy; - phy_param_t phyParam; + get_phy_params_t get_phy; + phy_param_t phy_param; - uint8_t fOptLen = mac_commands.GetLength() + mac_commands.GetRepeatLength(); + uint8_t fopt_len = mac_commands.get_mac_cmd_length() + + mac_commands.get_repeat_commands_length(); - if( txInfo == NULL ) - { + if (tx_info == NULL) { return LORAWAN_STATUS_PARAMETER_INVALID; } @@ -1913,167 +1828,143 @@ lorawan_status_t LoRaMac::LoRaMacQueryTxPossible( uint8_t size, loramac_tx_info_ } // Setup PHY request - getPhy.datarate = _params.sys_params.channel_data_rate; - getPhy.attribute = PHY_MAX_PAYLOAD; + get_phy.datarate = _params.sys_params.channel_data_rate; + get_phy.attribute = PHY_MAX_PAYLOAD; // Change request in case repeater is supported - if( _params.is_repeater_supported == true ) - { - getPhy.attribute = PHY_MAX_PAYLOAD_REPEATER; + if (_params.is_repeater_supported == true) { + get_phy.attribute = PHY_MAX_PAYLOAD_REPEATER; } - phyParam = lora_phy->get_phy_params( &getPhy ); - txInfo->current_payload_size = phyParam.value; + phy_param = lora_phy->get_phy_params(&get_phy); + tx_info->current_payload_size = phy_param.value; // Verify if the fOpts fit into the maximum payload - if( txInfo->current_payload_size >= fOptLen ) - { - txInfo->max_possible_payload_size = txInfo->current_payload_size - fOptLen; - } - else - { - txInfo->max_possible_payload_size = txInfo->current_payload_size; + if (tx_info->current_payload_size >= fopt_len) { + tx_info->max_possible_payload_size = tx_info->current_payload_size - fopt_len; + } else { + tx_info->max_possible_payload_size = tx_info->current_payload_size; // The fOpts don't fit into the maximum payload. Omit the MAC commands to // ensure that another uplink is possible. - fOptLen = 0; - mac_commands.ClearCommandBuffer(); - mac_commands.ClearRepeatBuffer(); + fopt_len = 0; + mac_commands.clear_command_buffer(); + mac_commands.clear_repeat_buffer(); } // Verify if the fOpts and the payload fit into the maximum payload - if( ValidatePayloadLength( size, _params.sys_params.channel_data_rate, - fOptLen ) == false ) - { + if (validate_payload_length(size, _params.sys_params.channel_data_rate, + fopt_len) == false) { return LORAWAN_STATUS_LENGTH_ERROR; } return LORAWAN_STATUS_OK; } -lorawan_status_t LoRaMac::AddChannelPlan(const lorawan_channelplan_t& plan) +lorawan_status_t LoRaMac::add_channel_plan(const lorawan_channelplan_t& plan) { // Validate if the MAC is in a correct state - if( ( _params.mac_state & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) - { - if( ( _params.mac_state & LORAMAC_TX_CONFIG ) != LORAMAC_TX_CONFIG ) - { + if ((_params.mac_state & LORAMAC_TX_RUNNING) == LORAMAC_TX_RUNNING) { + if ((_params.mac_state & LORAMAC_TX_CONFIG) != LORAMAC_TX_CONFIG) { return LORAWAN_STATUS_BUSY; } } - return ch_plan.set_plan(plan); + return channel_plan.set_plan(plan); } -lorawan_status_t LoRaMac::RemoveChannelPlan() +lorawan_status_t LoRaMac::remove_channel_plan() { - if( ( _params.mac_state & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) - { - if( ( _params.mac_state & LORAMAC_TX_CONFIG ) != LORAMAC_TX_CONFIG ) - { + if ((_params.mac_state & LORAMAC_TX_RUNNING) == LORAMAC_TX_RUNNING) { + if ((_params.mac_state & LORAMAC_TX_CONFIG) != LORAMAC_TX_CONFIG) { return LORAWAN_STATUS_BUSY; } } - return ch_plan.remove_plan(); + return channel_plan.remove_plan(); } -lorawan_status_t LoRaMac::GetChannelPlan(lorawan_channelplan_t& plan) +lorawan_status_t LoRaMac::get_channel_plan(lorawan_channelplan_t& plan) { - return ch_plan.get_plan(plan, &_params); + return channel_plan.get_plan(plan, &_params); } -lorawan_status_t LoRaMac::RemoveSingleChannel(uint8_t id) +lorawan_status_t LoRaMac::remove_single_channel(uint8_t id) { - if( ( _params.mac_state & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) - { - if( ( _params.mac_state & LORAMAC_TX_CONFIG ) != LORAMAC_TX_CONFIG ) - { + if ((_params.mac_state & LORAMAC_TX_RUNNING) == LORAMAC_TX_RUNNING) { + if ((_params.mac_state & LORAMAC_TX_CONFIG) != LORAMAC_TX_CONFIG) { return LORAWAN_STATUS_BUSY; } } - return ch_plan.remove_single_channel(id); + return channel_plan.remove_single_channel(id); } -lorawan_status_t LoRaMac::LoRaMacMulticastChannelLink( multicast_params_t *channelParam ) +lorawan_status_t LoRaMac::multicast_channel_link(multicast_params_t *channel_param) { - if( channelParam == NULL ) - { + if (channel_param == NULL) { return LORAWAN_STATUS_PARAMETER_INVALID; } - if( ( _params.mac_state & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) - { + if ((_params.mac_state & LORAMAC_TX_RUNNING) == LORAMAC_TX_RUNNING) { return LORAWAN_STATUS_BUSY; } // Reset downlink counter - channelParam->dl_frame_counter = 0; + channel_param->dl_frame_counter = 0; - if( _params.multicast_channels == NULL ) - { + if (_params.multicast_channels == NULL) { // New node is the fist element - _params.multicast_channels = channelParam; - } - else - { + _params.multicast_channels = channel_param; + } else { multicast_params_t *cur = _params.multicast_channels; // Search the last node in the list - while( cur->Next != NULL ) - { - cur = cur->Next; + while (cur->next != NULL) { + cur = cur->next; } // This function always finds the last node - cur->Next = channelParam; + cur->next = channel_param; } return LORAWAN_STATUS_OK; } -lorawan_status_t LoRaMac::LoRaMacMulticastChannelUnlink( multicast_params_t *channelParam ) +lorawan_status_t LoRaMac::multicast_channel_unlink( + multicast_params_t *channel_param) { - if( channelParam == NULL ) - { + if (channel_param == NULL) { return LORAWAN_STATUS_PARAMETER_INVALID; } - if( ( _params.mac_state & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) - { + if ((_params.mac_state & LORAMAC_TX_RUNNING) == LORAMAC_TX_RUNNING) { return LORAWAN_STATUS_BUSY; } - if( _params.multicast_channels != NULL ) - { - if( _params.multicast_channels == channelParam ) - { - // First element - _params.multicast_channels = channelParam->Next; - } - else - { + if (_params.multicast_channels != NULL) { + if (_params.multicast_channels == channel_param) { + // First element + _params.multicast_channels = channel_param->next; + } else { multicast_params_t *cur = _params.multicast_channels; // Search the node in the list - while( cur->Next && cur->Next != channelParam ) - { - cur = cur->Next; + while (cur->next && cur->next != channel_param) { + cur = cur->next; } // If we found the node, remove it - if( cur->Next ) - { - cur->Next = channelParam->Next; + if (cur->next) { + cur->next = channel_param->next; } } - channelParam->Next = NULL; + channel_param->next = NULL; } return LORAWAN_STATUS_OK; } -lorawan_status_t LoRaMac::LoRaMacMlmeRequest( loramac_mlme_req_t *mlmeRequest ) +lorawan_status_t LoRaMac::mlme_request( loramac_mlme_req_t *mlmeRequest ) { return mlme.set_request(mlmeRequest, &_params); } -lorawan_status_t LoRaMac::LoRaMacMcpsRequest( loramac_mcps_req_t *mcpsRequest ) +lorawan_status_t LoRaMac::mcps_request( loramac_mcps_req_t *mcpsRequest ) { if (_params.mac_state != LORAMAC_IDLE) { return LORAWAN_STATUS_BUSY; @@ -2082,25 +1973,25 @@ lorawan_status_t LoRaMac::LoRaMacMcpsRequest( loramac_mcps_req_t *mcpsRequest ) return mcps.set_request(mcpsRequest, &_params); } -lorawan_status_t LoRaMac::LoRaMacMibGetRequestConfirm( loramac_mib_req_confirm_t *mibGet ) +lorawan_status_t LoRaMac::mib_get_request_confirm( loramac_mib_req_confirm_t *mibGet ) { return mib.get_request(mibGet, &_params); } -lorawan_status_t LoRaMac::LoRaMacMibSetRequestConfirm( loramac_mib_req_confirm_t *mibSet ) +lorawan_status_t LoRaMac::mib_set_request_confirm( loramac_mib_req_confirm_t *mibSet ) { return mib.set_request(mibSet, &_params); } -radio_events_t *LoRaMac::GetPhyEventHandlers() +radio_events_t *LoRaMac::get_phy_event_handlers() { - RadioEvents.tx_done = mbed::callback(this, &LoRaMac::handle_tx_done); - RadioEvents.rx_done = mbed::callback(this, &LoRaMac::handle_rx_done); - RadioEvents.rx_error = mbed::callback(this, &LoRaMac::handle_rx_error); - RadioEvents.tx_timeout = mbed::callback(this, &LoRaMac::handle_tx_timeout); - RadioEvents.rx_timeout = mbed::callback(this, &LoRaMac::handle_rx_timeout); + radio_events.tx_done = mbed::callback(this, &LoRaMac::handle_tx_done); + radio_events.rx_done = mbed::callback(this, &LoRaMac::handle_rx_done); + radio_events.rx_error = mbed::callback(this, &LoRaMac::handle_rx_error); + radio_events.tx_timeout = mbed::callback(this, &LoRaMac::handle_tx_timeout); + radio_events.rx_timeout = mbed::callback(this, &LoRaMac::handle_rx_timeout); - return &RadioEvents; + return &radio_events; } #if defined(LORAWAN_COMPLIANCE_TEST) diff --git a/features/lorawan/lorastack/mac/LoRaMac.h b/features/lorawan/lorastack/mac/LoRaMac.h index 030f6f3e4a..b1676f8489 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.h +++ b/features/lorawan/lorastack/mac/LoRaMac.h @@ -37,8 +37,8 @@ * SPDX-License-Identifier: BSD-3-Clause * */ -#ifndef __LORAMAC_H__ -#define __LORAMAC_H__ +#ifndef MBED_LORAWAN_MAC_H__ +#define MBED_LORAWAN_MAC_H__ #include "lorawan/system/LoRaWANTimer.h" #include "lorastack/phy/LoRaPHY.h" @@ -50,63 +50,63 @@ #include "lorastack/mac/LoRaMacMib.h" #include "lorastack/mac/LoRaMacChannelPlan.h" -class LoRaMac -{ +class LoRaMac { + public: - /*! - * \brief Constructor + + /** + * Constructor */ LoRaMac(LoRaWANTimeHandler &lora_time); - /*! - * \brief Destructor + /** + * Destructor */ ~LoRaMac(); - /*! - * \brief LoRaMAC layer initialization + /** + * @brief LoRaMAC layer initialization * - * \details In addition to the initialization of the LoRaMAC layer, this + * @details In addition to the initialization of the LoRaMAC layer, this * function initializes the callback primitives of the MCPS and * MLME services. Every data field of \ref loramac_primitives_t must be * set to a valid callback function. * - * \param primitives [in] - A pointer to the structure defining the LoRaMAC + * @param primitives [in] A pointer to the structure defining the LoRaMAC * event functions. Refer to \ref loramac_primitives_t. * - * \param phy [in]- A pointer 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. + * @param queue [in] A pointer to the application provided EventQueue. * - * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: + * @return `lorawan_status_t` The status of the operation. The possible values are: * \ref LORAWAN_STATUS_OK * \ref LORAWAN_STATUS_PARAMETER_INVALID */ - lorawan_status_t LoRaMacInitialization(loramac_primitives_t *primitives, - LoRaPHY *phy, - events::EventQueue *queue); + lorawan_status_t initialize(loramac_primitives_t *primitives, LoRaPHY *phy, + events::EventQueue *queue); - /*! - * \brief Disconnect LoRaMac layer + /** + * @brief Disconnect LoRaMac layer * - * \details Cancels all outstanding requests and sets LoRaMac's + * @details Cancels all outstanding requests and sets LoRaMac's * internal state to idle. */ void disconnect(void); - /*! - * \brief Queries the LoRaMAC whether it is possible to send the next frame with + /** + * @brief Queries the LoRaMAC whether it is possible to send the next frame with * a given payload size. The LoRaMAC takes the scheduled MAC commands into * account and reports when the frame can be sent. * - * \param size [in]- The size of the applicable payload to be sent next. - * \param txInfo [out] - The structure \ref loramac_tx_info_t contains - * information on the actual maximum payload possible - * (according to the configured datarate or the next - * datarate according to ADR), and the maximum frame - * size, taking the scheduled MAC commands into account. + * @param size [in] The size of the applicable payload to be sent next. + * @param tx_info [out] The structure \ref loramac_tx_info_t contains + * information on the actual maximum payload possible + * (according to the configured datarate or the next + * datarate according to ADR), and the maximum frame + * size, taking the scheduled MAC commands into account. * - * \retval `LoRaMacStatus_t` The status of the operation. When the parameters are + * @return `lorawan_status_t` The status of the operation. When the parameters are * not valid, the function returns \ref LORAWAN_STATUS_PARAMETER_INVALID. * In case of a length error caused by the applicable payload in combination * with the MAC commands, the function returns \ref LORAWAN_STATUS_LENGTH_ERROR. @@ -116,192 +116,201 @@ public: * If the query is valid, and the LoRaMAC is able to send the frame, * the function returns \ref LORAWAN_STATUS_OK. */ - lorawan_status_t LoRaMacQueryTxPossible( uint8_t size, loramac_tx_info_t* txInfo ); + lorawan_status_t query_tx_possible(uint8_t size, loramac_tx_info_t* tx_info); - /*! - * \brief Adds a channel plan to the system. + /** + * @brief Adds a channel plan to the system. * - * \details Adds a whole channel plan or a single new channel to the. + * @details Adds a whole channel plan or a single new channel if the plan + * contains only one channel and 'plan.nb_channels' is set to 1. * Please note that this functionality is not available in all regions. * Information on the allowed ranges is available at the * LoRaWAN Regional Parameters V1.0.2rB. * - * \param plan [in] - A reference to application provided channel plan. + * @param plan [in] A reference to application provided channel plan. * - * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: + * @return `lorawan_status_t` The status of the operation. The possible values are: * \ref LORAWAN_STATUS_OK * \ref LORAWAN_STATUS_BUSY * \ref LORAWAN_STATUS_PARAMETER_INVALID */ - lorawan_status_t AddChannelPlan(const lorawan_channelplan_t& plan); + lorawan_status_t add_channel_plan(const lorawan_channelplan_t& plan); - /*! - * \brief Removes a channel plan from the system. + /** + * @brief Removes a channel plan from the system. * - * \details Removes the whole active channel plan except the 'Default Channels'.. + * @details Removes the whole active channel plan except the 'Default Channels'. * Please note that this functionality is not available in all regions. * Information on the allowed ranges is available at the * LoRaWAN Regional Parameters V1.0.2rB. * - * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: + * @return `lorawan_status_t` The status of the operation. The possible values are: * \ref LORAWAN_STATUS_OK * \ref LORAWAN_STATUS_BUSY * \ref LORAWAN_STATUS_PARAMETER_INVALID */ - lorawan_status_t RemoveChannelPlan(); + lorawan_status_t remove_channel_plan(); - /*! - * \brief Access active channel plan. + /** + * @brief Access active channel plan. * - * \details Provides access to the current active channel plan. + * @details Provides access to the current active channel plan. * - * \param plan [out] - A reference to application provided channel plan data - * structure which will be filled in with active channel - * plan. + * @param plan [out] A reference to application provided channel plan data + * structure which will be filled in with active channel + * plan. * - * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: + * @return `lorawan_status_t` The status of the operation. The possible values are: * \ref LORAWAN_STATUS_OK * \ref LORAWAN_STATUS_BUSY * \ref LORAWAN_STATUS_PARAMETER_INVALID */ - lorawan_status_t GetChannelPlan(lorawan_channelplan_t& plan); + lorawan_status_t get_channel_plan(lorawan_channelplan_t& plan); - /*! - * \brief Remove a given channel from the active plan. + /** + * @brief Remove a given channel from the active plan. * - * \details Deactivates the given channel. + * @details Deactivates the given channel. * - * \param id - Id of the channel. + * @param id Id of the channel. * - * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: + * @return `lorawan_status_t` The status of the operation. The possible values are: * \ref LORAWAN_STATUS_OK * \ref LORAWAN_STATUS_BUSY * \ref LORAWAN_STATUS_PARAMETER_INVALID */ - lorawan_status_t RemoveSingleChannel( uint8_t id ); + lorawan_status_t remove_single_channel(uint8_t id); - /*! - * \brief LoRaMAC multicast channel link service. + /** + * @brief LoRaMAC multicast channel link service. * - * \details Links a multicast channel into the linked list. + * @details Links a multicast channel into the linked list. * - * \param [in] channelParam - The multicast channel parameters to link. + * @param [in] channel_param The multicast channel parameters to link. * - * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: + * @return `lorawan_status_t` The status of the operation. The possible values are: * \ref LORAWAN_STATUS_OK * \ref LORAWAN_STATUS_BUSY * \ref LORAWAN_STATUS_PARAMETER_INVALID */ - lorawan_status_t LoRaMacMulticastChannelLink( multicast_params_t *channelParam ); + lorawan_status_t multicast_channel_link(multicast_params_t *channel_param); - /*! - * \brief LoRaMAC multicast channel unlink service. + /** + * @brief LoRaMAC multicast channel unlink service. * - * \details Unlinks a multicast channel from the linked list. + * @details Unlinks a multicast channel from the linked list. * - * \param [in] channelParam - The multicast channel parameters to unlink. + * @param [in] channel_param The multicast channel parameters to unlink. * - * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: + * @return `lorawan_status_t` The status of the operation. The possible values are: * \ref LORAWAN_STATUS_OK * \ref LORAWAN_STATUS_BUSY * \ref LORAWAN_STATUS_PARAMETER_INVALID */ - lorawan_status_t LoRaMacMulticastChannelUnlink( multicast_params_t *channelParam ); + lorawan_status_t multicast_channel_unlink(multicast_params_t *channel_param); - /*! - * \brief LoRaMAC MIB-GET. + /** + * @brief Get parameter values from MIB service. * - * \details The MAC information base service to get the attributes of the LoRaMac layer. + * @details The MAC information base service to get the attributes of the LoRaMac layer. * * The following code-snippet shows how to use the API to get the * parameter `AdrEnable`, defined by the enumeration type * \ref MIB_ADR. - * \code - * MibRequestConfirm_t mibReq; - * mibReq.Type = MIB_ADR; * - * if( LoRaMacMibGetRequestConfirm( &mibReq ) == LORAWAN_STATUS_OK ) - * { + * @code + * + * loramac_mib_req_confirm_t mib_get; + * mib_get.type = MIB_ADR; + * + * if (mib_get_request_confirm(&mib_get) == LORAWAN_STATUS_OK) { * // LoRaMAC updated the parameter mibParam.AdrEnable * } - * \endcode * - * \param [in] mibGet - The MIB-GET request to perform. Refer to \ref loramac_mib_req_confirm_t. + * @endcode * - * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: + * @param [in] mib_get The MIB-GET request to perform. Refer to + * \ref loramac_mib_req_confirm_t. + * + * @return `lorawan_status_t` The status of the operation. + * The possible values are: * \ref LORAWAN_STATUS_OK * \ref LORAWAN_STATUS_SERVICE_UNKNOWN * \ref LORAWAN_STATUS_PARAMETER_INVALID */ - lorawan_status_t LoRaMacMibGetRequestConfirm( loramac_mib_req_confirm_t *mibGet ); + lorawan_status_t mib_get_request_confirm(loramac_mib_req_confirm_t *mib_get); - /*! - * \brief LoRaMAC MIB-SET. + /** + * @brief Set attributes for MAC layer using MIB service. * - * \details The MAC information base service to set the attributes of the LoRaMac layer. + * @details The MAC information base service to set the attributes of the LoRaMac layer. * * The following code-snippet shows how to use the API to set the - * parameter `AdrEnable`, defined by the enumeration type + * parameter `adr_enable`, defined by the enumeration type * \ref MIB_ADR. * - * \code - * MibRequestConfirm_t mibReq; - * mibReq.Type = MIB_ADR; - * mibReq.Param.AdrEnable = true; + * @code * - * if( LoRaMacMibGetRequestConfirm( &mibReq ) == LORAWAN_STATUS_OK ) - * { + * loramac_mib_req_confirm_t mib_set; + * mib_set.Type = MIB_ADR; + * mib_set.param.adr_enable = true; + * + * if (mib_set_request_confirm(&mib_set) == LORAWAN_STATUS_OK) { * // LoRaMAC updated the parameter * } - * \endcode * - * \param [in] mibSet - The MIB-SET request to perform. Refer to \ref loramac_mib_req_confirm_t. + * @endcode * - * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: + * @param [in] mib_set The MIB-SET request to perform. Refer to + * \ref loramac_mib_req_confirm_t. + * + * @return `lorawan_status_t` The status of the operation. The possible values are: * \ref LORAWAN_STATUS_OK * \ref LORAWAN_STATUS_BUSY * \ref LORAWAN_STATUS_SERVICE_UNKNOWN * \ref LORAWAN_STATUS_PARAMETER_INVALID */ - lorawan_status_t LoRaMacMibSetRequestConfirm( loramac_mib_req_confirm_t *mibSet ); + lorawan_status_t mib_set_request_confirm(loramac_mib_req_confirm_t *mib_set); - /*! - * \brief LoRaMAC MLME request + /** + * @brief Set forth an MLME request. * - * \details The MAC layer management entity handles the management services. The + * @details The MAC layer management entity handles the management services. The * following code-snippet shows how to use the API to perform a * network join request. * - * \code - * static uint8_t DevEui[] = + * @code + * + * static uint8_t dev_eui[] = * { * 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 * }; - * static uint8_t AppEui[] = + * static uint8_t app_eui[] = * { * 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 * }; - * static uint8_t AppKey[] = + * static uint8_t app_key[] = * { * 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, * 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C * }; * - * MlmeReq_t mlmeReq; - * mlmeReq.Type = MLME_JOIN; - * mlmeReq.Req.Join.DevEui = DevEui; - * mlmeReq.Req.Join.AppEui = AppEui; - * mlmeReq.Req.Join.AppKey = AppKey; + * loramac_mlme_req_t mlme_req; + * mlme_req.Type = MLME_JOIN; + * mlme_req.req.join.dev_eui = dev_eui; + * mlme_req.req.join.app_eui = app_eui; + * mlme_req.req.join.app_key = app_key; * - * if( LoRaMacMlmeRequest( &mlmeReq ) == LORAWAN_STATUS_OK ) - * { + * if (LoRaMacMlmeRequest(&mlme_req) == LORAWAN_STATUS_OK) { * // Service started successfully. Waiting for the Mlme-Confirm event * } - * \endcode * - * \param [in] mlmeRequest - The MLME request to perform. Refer to \ref loramac_mlme_req_t. + * @endcode * - * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: + * @param [in] request The MLME request to perform. + * Refer to \ref loramac_mlme_req_t. + * + * @return `lorawan_status_t` The status of the operation. The possible values are: * \ref LORAWAN_STATUS_OK * \ref LORAWAN_STATUS_BUSY * \ref LORAWAN_STATUS_SERVICE_UNKNOWN @@ -310,33 +319,35 @@ public: * \ref LORAWAN_STATUS_LENGTH_ERROR * \ref LORAWAN_STATUS_DEVICE_OFF */ - lorawan_status_t LoRaMacMlmeRequest( loramac_mlme_req_t *mlmeRequest ); + lorawan_status_t mlme_request(loramac_mlme_req_t *request); - /*! - * \brief LoRaMAC MCPS request + /** + * @brief Set forth an MCPS request. * - * \details The MAC Common Part Sublayer handles the data services. The following + * @details The MAC Common Part Sublayer handles the data services. The following * code-snippet shows how to use the API to send an unconfirmed * LoRaMAC frame. * - * \code - * uint8_t myBuffer[] = { 1, 2, 3 }; + * @code * - * McpsReq_t mcpsReq; - * mcpsReq.Type = MCPS_UNCONFIRMED; - * mcpsReq.Req.Unconfirmed.fPort = 1; - * mcpsReq.Req.Unconfirmed.fBuffer = myBuffer; - * mcpsReq.Req.Unconfirmed.fBufferSize = sizeof( myBuffer ); + * uint8_t buffer[] = {1, 2, 3}; * - * if( LoRaMacMcpsRequest( &mcpsReq ) == LORAWAN_STATUS_OK ) - * { + * loramac_mcps_req_t request; + * request.type = MCPS_UNCONFIRMED; + * request.req.unconfirmed.fport = 1; + * request.req.unconfirmed.f_buffer = buffer; + * request.req.unconfirmed.f_buffer_size = sizeof(buffer); + * + * if (mcps_request(&request) == LORAWAN_STATUS_OK) { * // Service started successfully. Waiting for the MCPS-Confirm event * } - * \endcode * - * \param [in] mcpsRequest - The MCPS request to perform. Refer to \ref loramac_mcps_req_t. + * @endcode * - * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: + * @param [in] request The MCPS request to perform. + * Refer to \ref loramac_mcps_req_t. + * + * @return `lorawan_status_t` The status of the operation. The possible values are: * \ref LORAWAN_STATUS_OK * \ref LORAWAN_STATUS_BUSY * \ref LORAWAN_STATUS_SERVICE_UNKNOWN @@ -345,65 +356,76 @@ public: * \ref LORAWAN_STATUS_LENGTH_ERROR * \ref LORAWAN_STATUS_DEVICE_OFF */ - lorawan_status_t LoRaMacMcpsRequest( loramac_mcps_req_t *mcpsRequest ); + lorawan_status_t mcps_request(loramac_mcps_req_t *request); /** - * \brief LoRaMAC layer provides its callback functions for - * PHY layer + * @brief LoRaMAC layer provides its callback functions for + * PHY layer. * - * \return Pointer to callback functions for radio events + * @return Pointer to callback functions for radio events */ - radio_events_t *GetPhyEventHandlers(); + radio_events_t *get_phy_event_handlers(); - /*! - * \brief Configures the events to trigger an MLME-Indication with + /** + * @brief Configures the events to trigger an MLME-Indication with * a MLME type of MLME_SCHEDULE_UPLINK. */ - void SetMlmeScheduleUplinkIndication( void ); + void set_mlme_schedule_ul_indication(void); - /*! - * \brief LoRaMAC layer generic send frame + /** + * @brief Schedules the frame for sending. * - * \param [in] macHdr MAC header field - * \param [in] fPort MAC payload port - * \param [in] fBuffer MAC data buffer to be sent - * \param [in] fBufferSize MAC data buffer size - * \retval status Status of the operation. + * @details Prepares a full MAC frame and schedules it for physical + * transmission. + * + * @param [in] mac_hdr MAC frame header field + * @param [in] fport Payload port + * @param [in] fbuffer MAC frame data buffer to be sent + * @param [in] fbuffer_size MAC frame data buffer size + * + * @return status Status of the operation. LORAWAN_STATUS_OK in case + * of success and a negative error code in case of + * failure. */ - lorawan_status_t Send( loramac_mhdr_t *macHdr, uint8_t fPort, void *fBuffer, uint16_t fBufferSize ); + lorawan_status_t send(loramac_mhdr_t *mac_hdr, uint8_t fport, void *fbuffer, + uint16_t fbuffer_size); - /*! - * \brief Sets the radio in continuous transmission mode + /** + * @brief Puts the system in continuous transmission mode * - * \remark Uses the radio parameters set on the previous transmission. + * @remark Uses the radio parameters set on the previous transmission. * - * \param [in] timeout Time in seconds while the radio is kept in continuous wave mode - * \retval status Status of the operation. + * @param [in] timeout Time in seconds while the radio is kept in continuous wave mode + * + * @return status Status of the operation. LORAWAN_STATUS_OK in case + * of success and a negative error code in case of + * failure. */ - lorawan_status_t SetTxContinuousWave( uint16_t timeout ); + lorawan_status_t set_tx_continuous_wave(uint16_t timeout); - /*! - * \brief Sets the radio in continuous transmission mode + /** + * @brief Puts the system in continuous transmission mode * - * \remark Uses the radio parameters set on the previous transmission. + * @param [in] timeout Time in seconds while the radio is kept in continuous wave mode + * @param [in] frequency RF frequency to be set. + * @param [in] power RF output power to be set. * - * \param [in] timeout Time in seconds while the radio is kept in continuous wave mode - * \param [in] frequency RF frequency to be set. - * \param [in] power RF output power to be set. - * \retval status Status of the operation. + * @return status Status of the operation. LORAWAN_STATUS_OK in case + * of success and a negative error code in case of + * failure. */ - lorawan_status_t SetTxContinuousWave1( uint16_t timeout, uint32_t frequency, uint8_t power ); + lorawan_status_t set_tx_continuous_wave1(uint16_t timeout, uint32_t frequency, uint8_t power); - /*! - * \brief Resets MAC specific parameters to default + /** + * @brief Resets MAC specific parameters to default */ - void ResetMacParameters( void ); + void reset_mac_parameters(void); - /*! - * \brief Opens up a continuous RX 2 window. This is used for + /** + * @brief Opens up a continuous RX 2 window. This is used for * class c devices. */ - void OpenContinuousRx2Window(void); + void open_continuous_rx2_window(void); #if defined(LORAWAN_COMPLIANCE_TEST) public: // Test interface @@ -415,7 +437,7 @@ public: // Test interface * * \param [in] NextTxTime - Periodic time for next uplink. - * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: + * \retval `lorawan_status_t` The status of the operation. The possible values are: * \ref LORAWAN_STATUS_OK * \ref LORAWAN_STATUS_PARAMETER_INVALID */ @@ -426,7 +448,7 @@ public: // Test interface * * \details Stops the next tx timer. * - * \retval `LoRaMacStatus_t` The status of the operation. The possible values are: + * \retval `lorawan_status_t` The status of the operation. The possible values are: * \ref LORAWAN_STATUS_OK * \ref LORAWAN_STATUS_PARAMETER_INVALID */ @@ -480,138 +502,103 @@ private: #endif private: - /*! - * \brief Function to be executed on Radio Tx Done event + /** + * Function to be executed on Radio Tx Done event */ - void OnRadioTxDone( void ); - - /*! - * \brief This function prepares the MAC to abort the execution of function - * OnRadioRxDone in case of a reception error. - */ - void PrepareRxDoneAbort( void ); - - /*! - * \brief Function to be executed on Radio Rx Done event - */ - void OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ); - - /*! - * \brief Function executed on Radio Tx Timeout event - */ - void OnRadioTxTimeout( void ); - - /*! - * \brief Function executed on Radio Rx error event - */ - void OnRadioRxError( void ); - - /*! - * \brief Function executed on Radio Rx Timeout event - */ - void OnRadioRxTimeout( void ); - - /*! - * \brief Function executed on Resend Frame timer event. - */ - void OnMacStateCheckTimerEvent( void ); - - /*! - * \brief Function executed on duty cycle delayed Tx timer event - */ - void OnTxDelayedTimerEvent( void ); + void on_radio_tx_done(void); /** - * \brief Function to be executed when next Tx is possible + * This function prepares the MAC to abort the execution of function + * on_radio_rx_done() in case of a reception error. */ - void OnNextTx( void ); + void prepare_rx_done_abort(void); - /*! - * \brief Function executed on first Rx window timer event + /** + * Function to be executed on Radio Rx Done event */ - void OnRxWindow1TimerEvent( void ); + void on_radio_rx_done(uint8_t *payload, uint16_t size, int16_t rssi, + int8_t snr); - /*! - * \brief Function executed on second Rx window timer event + /** + * Function executed on Radio Tx Timeout event */ - void OnRxWindow2TimerEvent( void ); + void on_radio_tx_timeout(void); - /*! - * \brief Function executed on AckTimeout timer event + /** + * Function executed on Radio Rx error event */ - void OnAckTimeoutTimerEvent( void ); + void on_radio_rx_error(void); - /*! - * \brief Initializes and opens the reception window - * - * \param [in] rxContinuous Set to true, if the RX is in continuous mode - * \param [in] maxRxWindow Maximum RX window timeout + /** + * Function executed on Radio Rx Timeout event */ - void RxWindowSetup( bool rxContinuous, uint32_t maxRxWindow ); + void on_radio_rx_timeout(void); - /*! - * \brief Validates if the payload fits into the frame, taking the datarate - * into account. - * - * \details Refer to chapter 4.3.2 of the LoRaWAN specification, v1.0 - * - * \param lenN Length of the application payload. The length depends on the - * datarate and is region specific - * - * \param datarate Current datarate - * - * \param fOptsLen Length of the fOpts field - * - * \retval [false: payload does not fit into the frame, true: payload fits into - * the frame] + /** + *Function executed on Resend Frame timer event. */ - bool ValidatePayloadLength( uint8_t lenN, int8_t datarate, uint8_t fOptsLen ); + void on_mac_state_check_timer_event(void); - /*! - * \brief LoRaMAC layer frame buffer initialization - * - * \param [in] macHdr MAC header field - * \param [in] fCtrl MAC frame control field - * \param [in] fPort MAC payload port - * \param [in] fBuffer MAC data buffer to be sent - * \param [in] fBufferSize MAC data buffer size - * \retval status Status of the operation. + /** + * Function executed on duty cycle delayed Tx timer event */ - lorawan_status_t PrepareFrame( loramac_mhdr_t *macHdr, loramac_frame_ctrl_t *fCtrl, uint8_t fPort, void *fBuffer, uint16_t fBufferSize ); + void on_tx_delayed_timer_event(void); - /* - * \brief Schedules the frame according to the duty cycle - * - * \retval Status of the operation + /** + * Function executed on first Rx window timer event */ - lorawan_status_t ScheduleTx( void ); + void on_rx_window1_timer_event(void); - /* - * \brief Calculates the back-off time for the band of a channel. - * - * \param [in] channel The last Tx channel index + /** + * Function executed on second Rx window timer event */ - void CalculateBackOff( uint8_t channel ); + void on_rx_window2_timer_event(void); - /*! - * \brief LoRaMAC layer prepared frame buffer transmission with channel specification - * - * \remark PrepareFrame must be called at least once before calling this - * function. - * - * \param [in] channel Channel to transmit on - * \retval status Status of the operation. + /** + * Function executed on AckTimeout timer event */ - lorawan_status_t SendFrameOnChannel( uint8_t channel ); + void on_ack_timeout_timer_event(void); - /*! - * \brief Resets MAC specific parameters to default - * - * \param [in] fPort The fPort - * - * \retval [false: fPort not allowed, true: fPort allowed] + /** + * Initializes and opens the reception window */ - bool IsFPortAllowed( uint8_t fPort ); + void rx_window_setup(bool rx_continuous, uint32_t max_rx_window_time); + + /** + * Validates if the payload fits into the frame, taking the datarate + * into account. + * + * Please Refer to chapter 4.3.2 of the LoRaWAN specification, v1.0.2 + */ + bool validate_payload_length(uint8_t length, int8_t datarate, uint8_t fopts_len); + + /** + * Prepares MAC frame on the behest of send() API. + */ + lorawan_status_t prepare_frame(loramac_mhdr_t *mac_hdr, + loramac_frame_ctrl_t *fctrl, uint8_t fport, + void *fbuffer, uint16_t fbuffer_size); + + /** + * Schedules a transmission on the behest of send() API. + */ + lorawan_status_t schedule_tx(void); + + /** + * Calculates the back-off time for the band of a channel. + * Takes in the last used channel id as a parameter. + */ + void calculate_backOff(uint8_t channel_id); + + /** + * Hands over the MAC frame to PHY layer. + */ + lorawan_status_t send_frame_on_channel(uint8_t channel); + + /** + * Checks for Port validity. + */ + bool is_fPort_allowed(uint8_t fPort); /** * Prototypes for ISR handlers @@ -660,7 +647,7 @@ private: /** * Channel planning subsystem */ - LoRaMacChannelPlan ch_plan; + LoRaMacChannelPlan channel_plan; /** * Timer subsystem handle @@ -675,12 +662,12 @@ private: /** * Radio event callback handlers for MAC */ - radio_events_t RadioEvents; + radio_events_t radio_events; - /*! + /** * LoRaMac upper layer event functions */ - loramac_primitives_t *LoRaMacPrimitives; + loramac_primitives_t *mac_primitives; /** * EventQueue object storage @@ -688,4 +675,4 @@ private: events::EventQueue *ev_queue; }; -#endif // __LORAMAC_H__ +#endif // MBED_LORAWAN_MAC_H__ diff --git a/features/lorawan/lorastack/mac/LoRaMacCommand.cpp b/features/lorawan/lorastack/mac/LoRaMacCommand.cpp index 7d834216cd..0fc3356de3 100644 --- a/features/lorawan/lorastack/mac/LoRaMacCommand.cpp +++ b/features/lorawan/lorastack/mac/LoRaMacCommand.cpp @@ -33,183 +33,167 @@ SPDX-License-Identifier: BSD-3-Clause #define tr_error(...) (void(0)) //dummies if feature common pal is not added #endif //defined(FEATURE_COMMON_PAL) -/*! +/** * LoRaMAC max EIRP (dBm) table. */ -static const uint8_t LoRaMacMaxEirpTable[] = { 8, 10, 12, 13, 14, 16, 18, 20, 21, 24, 26, 27, 29, 30, 33, 36 }; +static const uint8_t max_eirp_table[] = { 8, 10, 12, 13, 14, 16, 18, 20, 21, 24, 26, 27, 29, 30, 33, 36 }; LoRaMacCommand::LoRaMacCommand(LoRaMac& lora_mac) : _lora_mac(lora_mac) { - MacCommandsInNextTx = false; - MacCommandsBufferIndex = 0; - MacCommandsBufferToRepeatIndex = 0; + mac_cmd_in_next_tx = false; + mac_cmd_buf_idx = 0; + mac_cmd_buf_idx_to_repeat = 0; - memset(MacCommandsBuffer, 0, sizeof(MacCommandsBuffer)); - memset(MacCommandsBufferToRepeat, 0, sizeof(MacCommandsBufferToRepeat)); + memset(mac_cmd_buffer, 0, sizeof(mac_cmd_buffer)); + memset(mac_cmd_buffer_to_repeat, 0, sizeof(mac_cmd_buffer_to_repeat)); } LoRaMacCommand::~LoRaMacCommand() { } -lorawan_status_t LoRaMacCommand::AddMacCommand(uint8_t cmd, uint8_t p1, uint8_t p2) +lorawan_status_t LoRaMacCommand::add_mac_command(uint8_t cmd, uint8_t p1, + uint8_t p2) { lorawan_status_t status = LORAWAN_STATUS_BUSY; // The maximum buffer length must take MAC commands to re-send into account. - const uint8_t bufLen = LORA_MAC_COMMAND_MAX_LENGTH - MacCommandsBufferToRepeatIndex; + const uint8_t bufLen = LORA_MAC_COMMAND_MAX_LENGTH + - mac_cmd_buf_idx_to_repeat; - switch( cmd ) - { + switch (cmd) { case MOTE_MAC_LINK_CHECK_REQ: - if( MacCommandsBufferIndex < bufLen ) - { - MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; + if (mac_cmd_buf_idx < bufLen) { + mac_cmd_buffer[mac_cmd_buf_idx++] = cmd; // No payload for this command status = LORAWAN_STATUS_OK; } break; case MOTE_MAC_LINK_ADR_ANS: - if( MacCommandsBufferIndex < ( bufLen - 1 ) ) - { - MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; + if (mac_cmd_buf_idx < (bufLen - 1)) { + mac_cmd_buffer[mac_cmd_buf_idx++] = cmd; // Margin - MacCommandsBuffer[MacCommandsBufferIndex++] = p1; + mac_cmd_buffer[mac_cmd_buf_idx++] = p1; status = LORAWAN_STATUS_OK; } break; case MOTE_MAC_DUTY_CYCLE_ANS: - if( MacCommandsBufferIndex < bufLen ) - { - MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; + if (mac_cmd_buf_idx < bufLen) { + mac_cmd_buffer[mac_cmd_buf_idx++] = cmd; // No payload for this answer status = LORAWAN_STATUS_OK; } break; case MOTE_MAC_RX_PARAM_SETUP_ANS: - if( MacCommandsBufferIndex < ( bufLen - 1 ) ) - { - MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; + if (mac_cmd_buf_idx < (bufLen - 1)) { + mac_cmd_buffer[mac_cmd_buf_idx++] = cmd; // Status: Datarate ACK, Channel ACK - MacCommandsBuffer[MacCommandsBufferIndex++] = p1; + mac_cmd_buffer[mac_cmd_buf_idx++] = p1; // This is a sticky MAC command answer. Setup indication - _lora_mac.SetMlmeScheduleUplinkIndication(); + _lora_mac.set_mlme_schedule_ul_indication(); status = LORAWAN_STATUS_OK; } break; case MOTE_MAC_DEV_STATUS_ANS: - if( MacCommandsBufferIndex < ( bufLen - 2 ) ) - { - MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; + if (mac_cmd_buf_idx < (bufLen - 2)) { + mac_cmd_buffer[mac_cmd_buf_idx++] = cmd; // 1st byte Battery // 2nd byte Margin - MacCommandsBuffer[MacCommandsBufferIndex++] = p1; - MacCommandsBuffer[MacCommandsBufferIndex++] = p2; + mac_cmd_buffer[mac_cmd_buf_idx++] = p1; + mac_cmd_buffer[mac_cmd_buf_idx++] = p2; status = LORAWAN_STATUS_OK; } break; case MOTE_MAC_NEW_CHANNEL_ANS: - if( MacCommandsBufferIndex < ( bufLen - 1 ) ) - { - MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; + if (mac_cmd_buf_idx < (bufLen - 1)) { + mac_cmd_buffer[mac_cmd_buf_idx++] = cmd; // Status: Datarate range OK, Channel frequency OK - MacCommandsBuffer[MacCommandsBufferIndex++] = p1; + mac_cmd_buffer[mac_cmd_buf_idx++] = p1; status = LORAWAN_STATUS_OK; } break; case MOTE_MAC_RX_TIMING_SETUP_ANS: - if( MacCommandsBufferIndex < bufLen ) - { - MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; + if (mac_cmd_buf_idx < bufLen) { + mac_cmd_buffer[mac_cmd_buf_idx++] = cmd; // No payload for this answer // This is a sticky MAC command answer. Setup indication - _lora_mac.SetMlmeScheduleUplinkIndication(); + _lora_mac.set_mlme_schedule_ul_indication(); status = LORAWAN_STATUS_OK; } break; case MOTE_MAC_TX_PARAM_SETUP_ANS: - if( MacCommandsBufferIndex < bufLen ) - { - MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; + if (mac_cmd_buf_idx < bufLen) { + mac_cmd_buffer[mac_cmd_buf_idx++] = cmd; // No payload for this answer status = LORAWAN_STATUS_OK; } break; case MOTE_MAC_DL_CHANNEL_ANS: - if( MacCommandsBufferIndex < bufLen ) - { - MacCommandsBuffer[MacCommandsBufferIndex++] = cmd; + if (mac_cmd_buf_idx < bufLen) { + mac_cmd_buffer[mac_cmd_buf_idx++] = cmd; // Status: Uplink frequency exists, Channel frequency OK - MacCommandsBuffer[MacCommandsBufferIndex++] = p1; + mac_cmd_buffer[mac_cmd_buf_idx++] = p1; // This is a sticky MAC command answer. Setup indication - _lora_mac.SetMlmeScheduleUplinkIndication(); + _lora_mac.set_mlme_schedule_ul_indication(); status = LORAWAN_STATUS_OK; } break; default: return LORAWAN_STATUS_SERVICE_UNKNOWN; } - if( status == LORAWAN_STATUS_OK ) - { - MacCommandsInNextTx = true; + if (status == LORAWAN_STATUS_OK) { + mac_cmd_in_next_tx = true; } return status; } -void LoRaMacCommand::ClearCommandBuffer() +void LoRaMacCommand::clear_command_buffer() { - MacCommandsBufferIndex = 0; + mac_cmd_buf_idx = 0; } -uint8_t LoRaMacCommand::GetLength() const +uint8_t LoRaMacCommand::get_mac_cmd_length() const { - return MacCommandsBufferIndex; + return mac_cmd_buf_idx; } -uint8_t *LoRaMacCommand::GetMacCommandsBuffer() +uint8_t *LoRaMacCommand::get_mac_commands_buffer() { - return MacCommandsBuffer; + return mac_cmd_buffer; } -void LoRaMacCommand::ParseMacCommandsToRepeat() +void LoRaMacCommand::parse_mac_commands_to_repeat() { uint8_t i = 0; - uint8_t cmdCount = 0; + uint8_t cmd_cnt = 0; - for( i = 0; i < MacCommandsBufferIndex; i++ ) - { - switch( MacCommandsBuffer[i] ) - { + for (i = 0; i < mac_cmd_buf_idx; i++) { + switch (mac_cmd_buffer[i]) { // STICKY case MOTE_MAC_DL_CHANNEL_ANS: - case MOTE_MAC_RX_PARAM_SETUP_ANS: - { // 1 byte payload - MacCommandsBufferToRepeat[cmdCount++] = MacCommandsBuffer[i++]; - MacCommandsBufferToRepeat[cmdCount++] = MacCommandsBuffer[i]; + case MOTE_MAC_RX_PARAM_SETUP_ANS: { // 1 byte payload + mac_cmd_buffer_to_repeat[cmd_cnt++] = mac_cmd_buffer[i++]; + mac_cmd_buffer_to_repeat[cmd_cnt++] = mac_cmd_buffer[i]; break; } - case MOTE_MAC_RX_TIMING_SETUP_ANS: - { // 0 byte payload - MacCommandsBufferToRepeat[cmdCount++] = MacCommandsBuffer[i]; + case MOTE_MAC_RX_TIMING_SETUP_ANS: { // 0 byte payload + mac_cmd_buffer_to_repeat[cmd_cnt++] = mac_cmd_buffer[i]; break; } - // NON-STICKY - case MOTE_MAC_DEV_STATUS_ANS: - { // 2 bytes payload + // NON-STICKY + case MOTE_MAC_DEV_STATUS_ANS: { // 2 bytes payload i += 2; break; } case MOTE_MAC_LINK_ADR_ANS: - case MOTE_MAC_NEW_CHANNEL_ANS: - { // 1 byte payload + case MOTE_MAC_NEW_CHANNEL_ANS: { // 1 byte payload i++; break; } case MOTE_MAC_TX_PARAM_SETUP_ANS: case MOTE_MAC_DUTY_CYCLE_ANS: - case MOTE_MAC_LINK_CHECK_REQ: - { // 0 byte payload + case MOTE_MAC_LINK_CHECK_REQ: { // 0 byte payload break; } default: @@ -217,213 +201,210 @@ void LoRaMacCommand::ParseMacCommandsToRepeat() } } - if( cmdCount > 0 ) { - MacCommandsInNextTx = true; + if (cmd_cnt > 0) { + mac_cmd_in_next_tx = true; } else { - MacCommandsInNextTx = false; + mac_cmd_in_next_tx = false; } } -void LoRaMacCommand::ClearRepeatBuffer() +void LoRaMacCommand::clear_repeat_buffer() { - MacCommandsBufferToRepeatIndex = 0; + mac_cmd_buf_idx_to_repeat = 0; } -void LoRaMacCommand::CopyRepeatCommandsToBuffer() +void LoRaMacCommand::copy_repeat_commands_to_buffer() { // Copy the MAC commands which must be re-send into the MAC command buffer - memcpy(&MacCommandsBuffer[MacCommandsBufferIndex], MacCommandsBufferToRepeat, MacCommandsBufferToRepeatIndex); - MacCommandsBufferIndex += MacCommandsBufferToRepeatIndex; + memcpy(&mac_cmd_buffer[mac_cmd_buf_idx], mac_cmd_buffer_to_repeat, mac_cmd_buf_idx_to_repeat); + mac_cmd_buf_idx += mac_cmd_buf_idx_to_repeat; } -uint8_t LoRaMacCommand::GetRepeatLength() const +uint8_t LoRaMacCommand::get_repeat_commands_length() const { - return MacCommandsBufferToRepeatIndex; + return mac_cmd_buf_idx_to_repeat; } -void LoRaMacCommand::ClearMacCommandsInNextTx() +void LoRaMacCommand::clear_mac_commands_in_next_tx() { - MacCommandsInNextTx = false; + mac_cmd_in_next_tx = false; } -bool LoRaMacCommand::IsMacCommandsInNextTx() const +bool LoRaMacCommand::is_mac_command_in_next_tx() const { - return MacCommandsInNextTx; + return mac_cmd_in_next_tx; } -lorawan_status_t LoRaMacCommand::ProcessMacCommands(uint8_t *payload, uint8_t macIndex, - uint8_t commandsSize, uint8_t snr, - loramac_mlme_confirm_t& MlmeConfirm, - lora_mac_system_params_t &LoRaMacParams, - LoRaPHY &lora_phy) +lorawan_status_t LoRaMacCommand::process_mac_commands(uint8_t *payload, + uint8_t mac_index, + uint8_t commands_size, + uint8_t snr, + loramac_mlme_confirm_t& mlme_conf, + lora_mac_system_params_t &mac_sys_params, + LoRaPHY &lora_phy) { uint8_t status = 0; lorawan_status_t ret_value = LORAWAN_STATUS_OK; - while( macIndex < commandsSize ) - { + while (mac_index < commands_size) { // Decode Frame MAC commands - switch( payload[macIndex++] ) - { + switch (payload[mac_index++]) { case SRV_MAC_LINK_CHECK_ANS: - MlmeConfirm.status = LORAMAC_EVENT_INFO_STATUS_OK; - MlmeConfirm.demod_margin = payload[macIndex++]; - MlmeConfirm.nb_gateways = payload[macIndex++]; + mlme_conf.status = LORAMAC_EVENT_INFO_STATUS_OK; + mlme_conf.demod_margin = payload[mac_index++]; + mlme_conf.nb_gateways = payload[mac_index++]; break; - case SRV_MAC_LINK_ADR_REQ: - { - adr_req_params_t linkAdrReq; - int8_t linkAdrDatarate = DR_0; - int8_t linkAdrTxPower = TX_POWER_0; - uint8_t linkAdrNbRep = 0; - uint8_t linkAdrNbBytesParsed = 0; + case SRV_MAC_LINK_ADR_REQ: { + adr_req_params_t linkAdrReq; + int8_t linkAdrDatarate = DR_0; + int8_t linkAdrTxPower = TX_POWER_0; + uint8_t linkAdrNbRep = 0; + uint8_t linkAdrNbBytesParsed = 0; - // Fill parameter structure - linkAdrReq.payload = &payload[macIndex - 1]; - linkAdrReq.payload_size = commandsSize - ( macIndex - 1 ); - linkAdrReq.adr_enabled = LoRaMacParams.adr_on; - linkAdrReq.ul_dwell_time = LoRaMacParams.uplink_dwell_time; - linkAdrReq.current_datarate = LoRaMacParams.channel_data_rate; - linkAdrReq.current_tx_power = LoRaMacParams.channel_tx_power; - linkAdrReq.current_nb_rep = LoRaMacParams.retry_num; + // Fill parameter structure + linkAdrReq.payload = &payload[mac_index - 1]; + linkAdrReq.payload_size = commands_size - (mac_index - 1); + linkAdrReq.adr_enabled = mac_sys_params.adr_on; + linkAdrReq.ul_dwell_time = mac_sys_params.uplink_dwell_time; + linkAdrReq.current_datarate = mac_sys_params.channel_data_rate; + linkAdrReq.current_tx_power = mac_sys_params.channel_tx_power; + linkAdrReq.current_nb_rep = mac_sys_params.retry_num; - // Process the ADR requests - status = lora_phy.link_ADR_request(&linkAdrReq, &linkAdrDatarate, - &linkAdrTxPower, &linkAdrNbRep, - &linkAdrNbBytesParsed); + // Process the ADR requests + status = lora_phy.link_ADR_request(&linkAdrReq, + &linkAdrDatarate, + &linkAdrTxPower, + &linkAdrNbRep, + &linkAdrNbBytesParsed); - if( ( status & 0x07 ) == 0x07 ) - { - LoRaMacParams.channel_data_rate = linkAdrDatarate; - LoRaMacParams.channel_tx_power = linkAdrTxPower; - LoRaMacParams.retry_num = linkAdrNbRep; - } - - // Add the answers to the buffer - for( uint8_t i = 0; i < ( linkAdrNbBytesParsed / 5 ); i++ ) - { - ret_value = AddMacCommand( MOTE_MAC_LINK_ADR_ANS, status, 0 ); - } - // Update MAC index - macIndex += linkAdrNbBytesParsed - 1; + if ((status & 0x07) == 0x07) { + mac_sys_params.channel_data_rate = linkAdrDatarate; + mac_sys_params.channel_tx_power = linkAdrTxPower; + mac_sys_params.retry_num = linkAdrNbRep; } + + // Add the answers to the buffer + for (uint8_t i = 0; i < (linkAdrNbBytesParsed / 5); i++) { + ret_value = add_mac_command(MOTE_MAC_LINK_ADR_ANS, status, 0); + } + // Update MAC index + mac_index += linkAdrNbBytesParsed - 1; + } break; case SRV_MAC_DUTY_CYCLE_REQ: - LoRaMacParams.max_duty_cycle = payload[macIndex++]; - LoRaMacParams.aggregated_duty_cycle = 1 << LoRaMacParams.max_duty_cycle; - ret_value = AddMacCommand( MOTE_MAC_DUTY_CYCLE_ANS, 0, 0 ); + mac_sys_params.max_duty_cycle = payload[mac_index++]; + mac_sys_params.aggregated_duty_cycle = 1 << mac_sys_params.max_duty_cycle; + ret_value = add_mac_command(MOTE_MAC_DUTY_CYCLE_ANS, 0, 0); break; - case SRV_MAC_RX_PARAM_SETUP_REQ: - { - rx_param_setup_req_t rxParamSetupReq; + case SRV_MAC_RX_PARAM_SETUP_REQ: { + rx_param_setup_req_t rxParamSetupReq; - rxParamSetupReq.dr_offset = ( payload[macIndex] >> 4 ) & 0x07; - rxParamSetupReq.datarate = payload[macIndex] & 0x0F; - macIndex++; + rxParamSetupReq.dr_offset = (payload[mac_index] >> 4) & 0x07; + rxParamSetupReq.datarate = payload[mac_index] & 0x0F; + mac_index++; - rxParamSetupReq.frequency = ( uint32_t )payload[macIndex++]; - rxParamSetupReq.frequency |= ( uint32_t )payload[macIndex++] << 8; - rxParamSetupReq.frequency |= ( uint32_t )payload[macIndex++] << 16; - rxParamSetupReq.frequency *= 100; + rxParamSetupReq.frequency = (uint32_t) payload[mac_index++]; + rxParamSetupReq.frequency |= (uint32_t) payload[mac_index++] + << 8; + rxParamSetupReq.frequency |= (uint32_t) payload[mac_index++] + << 16; + rxParamSetupReq.frequency *= 100; - // Perform request on region - status = lora_phy.accept_rx_param_setup_req(&rxParamSetupReq); + // Perform request on region + status = lora_phy.accept_rx_param_setup_req(&rxParamSetupReq); - if( ( status & 0x07 ) == 0x07 ) - { - LoRaMacParams.rx2_channel.datarate = rxParamSetupReq.datarate; - LoRaMacParams.rx2_channel.frequency = rxParamSetupReq.frequency; - LoRaMacParams.rx1_dr_offset = rxParamSetupReq.dr_offset; - } - ret_value = AddMacCommand( MOTE_MAC_RX_PARAM_SETUP_ANS, status, 0 ); + if ((status & 0x07) == 0x07) { + mac_sys_params.rx2_channel.datarate = + rxParamSetupReq.datarate; + mac_sys_params.rx2_channel.frequency = + rxParamSetupReq.frequency; + mac_sys_params.rx1_dr_offset = rxParamSetupReq.dr_offset; } + ret_value = add_mac_command(MOTE_MAC_RX_PARAM_SETUP_ANS, status, + 0); + } break; - case SRV_MAC_DEV_STATUS_REQ: - { - uint8_t batteryLevel = BAT_LEVEL_NO_MEASURE; - // we don't have a mechanism at the moment to measure - // battery levels - ret_value = AddMacCommand( MOTE_MAC_DEV_STATUS_ANS, batteryLevel, snr ); - break; - } - case SRV_MAC_NEW_CHANNEL_REQ: - { - new_channel_req_params_t newChannelReq; - channel_params_t chParam; - - newChannelReq.channel_id = payload[macIndex++]; - newChannelReq.new_channel = &chParam; - - chParam.frequency = ( uint32_t )payload[macIndex++]; - chParam.frequency |= ( uint32_t )payload[macIndex++] << 8; - chParam.frequency |= ( uint32_t )payload[macIndex++] << 16; - chParam.frequency *= 100; - chParam.rx1_frequency = 0; - chParam.dr_range.value = payload[macIndex++]; - - status = lora_phy.request_new_channel(&newChannelReq); - - ret_value = AddMacCommand( MOTE_MAC_NEW_CHANNEL_ANS, status, 0 ); - } + case SRV_MAC_DEV_STATUS_REQ: { + uint8_t batteryLevel = BAT_LEVEL_NO_MEASURE; + // we don't have a mechanism at the moment to measure + // battery levels + ret_value = add_mac_command(MOTE_MAC_DEV_STATUS_ANS, + batteryLevel, snr); break; - case SRV_MAC_RX_TIMING_SETUP_REQ: - { - uint8_t delay = payload[macIndex++] & 0x0F; + } + case SRV_MAC_NEW_CHANNEL_REQ: { + new_channel_req_params_t newChannelReq; + channel_params_t chParam; - if( delay == 0 ) - { - delay++; - } - LoRaMacParams.recv_delay1 = delay * 1000; - LoRaMacParams.recv_delay2 = LoRaMacParams.recv_delay1 + 1000; - ret_value = AddMacCommand( MOTE_MAC_RX_TIMING_SETUP_ANS, 0, 0 ); - } + newChannelReq.channel_id = payload[mac_index++]; + newChannelReq.new_channel = &chParam; + + chParam.frequency = (uint32_t) payload[mac_index++]; + chParam.frequency |= (uint32_t) payload[mac_index++] << 8; + chParam.frequency |= (uint32_t) payload[mac_index++] << 16; + chParam.frequency *= 100; + chParam.rx1_frequency = 0; + chParam.dr_range.value = payload[mac_index++]; + + status = lora_phy.request_new_channel(&newChannelReq); + + ret_value = add_mac_command(MOTE_MAC_NEW_CHANNEL_ANS, status, 0); + } break; - case SRV_MAC_TX_PARAM_SETUP_REQ: - { - tx_param_setup_req_t txParamSetupReq; - uint8_t eirpDwellTime = payload[macIndex++]; + case SRV_MAC_RX_TIMING_SETUP_REQ: { + uint8_t delay = payload[mac_index++] & 0x0F; - txParamSetupReq.ul_dwell_time = 0; - txParamSetupReq.dl_dwell_time = 0; - - if( ( eirpDwellTime & 0x20 ) == 0x20 ) - { - txParamSetupReq.dl_dwell_time = 1; - } - if( ( eirpDwellTime & 0x10 ) == 0x10 ) - { - txParamSetupReq.ul_dwell_time = 1; - } - txParamSetupReq.max_eirp = eirpDwellTime & 0x0F; - - // Check the status for correctness - if(lora_phy.accept_tx_param_setup_req(&txParamSetupReq)) - { - // Accept command - LoRaMacParams.uplink_dwell_time = txParamSetupReq.ul_dwell_time; - LoRaMacParams.downlink_dwell_time = txParamSetupReq.dl_dwell_time; - LoRaMacParams.max_eirp = LoRaMacMaxEirpTable[txParamSetupReq.max_eirp]; - // Add command response - ret_value = AddMacCommand( MOTE_MAC_TX_PARAM_SETUP_ANS, 0, 0 ); - } + if (delay == 0) { + delay++; } + mac_sys_params.recv_delay1 = delay * 1000; + mac_sys_params.recv_delay2 = mac_sys_params.recv_delay1 + 1000; + ret_value = add_mac_command(MOTE_MAC_RX_TIMING_SETUP_ANS, 0, 0); + } break; - case SRV_MAC_DL_CHANNEL_REQ: - { - dl_channel_req_params_t dlChannelReq; + case SRV_MAC_TX_PARAM_SETUP_REQ: { + tx_param_setup_req_t txParamSetupReq; + uint8_t eirpDwellTime = payload[mac_index++]; - dlChannelReq.channel_id = payload[macIndex++]; - dlChannelReq.rx1_frequency = ( uint32_t )payload[macIndex++]; - dlChannelReq.rx1_frequency |= ( uint32_t )payload[macIndex++] << 8; - dlChannelReq.rx1_frequency |= ( uint32_t )payload[macIndex++] << 16; - dlChannelReq.rx1_frequency *= 100; + txParamSetupReq.ul_dwell_time = 0; + txParamSetupReq.dl_dwell_time = 0; - status = lora_phy.dl_channel_request(&dlChannelReq); - - ret_value = AddMacCommand( MOTE_MAC_DL_CHANNEL_ANS, status, 0 ); + if ((eirpDwellTime & 0x20) == 0x20) { + txParamSetupReq.dl_dwell_time = 1; } + if ((eirpDwellTime & 0x10) == 0x10) { + txParamSetupReq.ul_dwell_time = 1; + } + txParamSetupReq.max_eirp = eirpDwellTime & 0x0F; + + // Check the status for correctness + if (lora_phy.accept_tx_param_setup_req(&txParamSetupReq)) { + // Accept command + mac_sys_params.uplink_dwell_time = + txParamSetupReq.ul_dwell_time; + mac_sys_params.downlink_dwell_time = + txParamSetupReq.dl_dwell_time; + mac_sys_params.max_eirp = + max_eirp_table[txParamSetupReq.max_eirp]; + // Add command response + ret_value = add_mac_command(MOTE_MAC_TX_PARAM_SETUP_ANS, 0, 0); + } + } + break; + case SRV_MAC_DL_CHANNEL_REQ: { + dl_channel_req_params_t dlChannelReq; + + dlChannelReq.channel_id = payload[mac_index++]; + dlChannelReq.rx1_frequency = (uint32_t) payload[mac_index++]; + dlChannelReq.rx1_frequency |= (uint32_t) payload[mac_index++] << 8; + dlChannelReq.rx1_frequency |= (uint32_t) payload[mac_index++] << 16; + dlChannelReq.rx1_frequency *= 100; + + status = lora_phy.dl_channel_request(&dlChannelReq); + + ret_value = add_mac_command(MOTE_MAC_DL_CHANNEL_ANS, status, 0); + } break; default: // Unknown command. ABORT MAC commands processing @@ -433,10 +414,9 @@ lorawan_status_t LoRaMacCommand::ProcessMacCommands(uint8_t *payload, uint8_t ma return ret_value; } -bool LoRaMacCommand::IsStickyMacCommandPending() +bool LoRaMacCommand::is_sticky_mac_command_pending() { - if( MacCommandsBufferToRepeatIndex > 0 ) - { + if (mac_cmd_buf_idx_to_repeat > 0) { // Sticky MAC commands pending return true; } diff --git a/features/lorawan/lorastack/mac/LoRaMacCommand.h b/features/lorawan/lorastack/mac/LoRaMacCommand.h index 787df24e74..3aa54c633d 100644 --- a/features/lorawan/lorastack/mac/LoRaMacCommand.h +++ b/features/lorawan/lorastack/mac/LoRaMacCommand.h @@ -51,129 +51,130 @@ class LoRaMac; -class LoRaMacCommand -{ +class LoRaMacCommand { + public: LoRaMacCommand(LoRaMac &lora_mac); ~LoRaMacCommand(); - /*! - * \brief Adds a new MAC command to be sent. + /** + * @brief Adds a new MAC command to be sent. * - * \remark MAC layer internal function + * @remark MAC layer internal function * - * \param [in] cmd MAC command to be added - * [MOTE_MAC_LINK_CHECK_REQ, - * MOTE_MAC_LINK_ADR_ANS, - * MOTE_MAC_DUTY_CYCLE_ANS, - * MOTE_MAC_RX2_PARAM_SET_ANS, - * MOTE_MAC_DEV_STATUS_ANS - * MOTE_MAC_NEW_CHANNEL_ANS] - * \param [in] p1 1st parameter ( optional depends on the command ) - * \param [in] p2 2nd parameter ( optional depends on the command ) + * @param [in] cmd MAC command to be added + * [MOTE_MAC_LINK_CHECK_REQ, + * MOTE_MAC_LINK_ADR_ANS, + * MOTE_MAC_DUTY_CYCLE_ANS, + * MOTE_MAC_RX2_PARAM_SET_ANS, + * MOTE_MAC_DEV_STATUS_ANS + * MOTE_MAC_NEW_CHANNEL_ANS] + * @param [in] p1 1st parameter (optional depends on the command) + * @param [in] p2 2nd parameter (optional depends on the command) * - * \retval status Function status [0: OK, 1: Unknown command, 2: Buffer full] + * @return status Function status [0: OK, 1: Unknown command, 2: Buffer full] */ - lorawan_status_t AddMacCommand(uint8_t cmd, uint8_t p1, uint8_t p2); + lorawan_status_t add_mac_command(uint8_t cmd, uint8_t p1, uint8_t p2); - /*! - * \brief Clear MAC command buffer. + /** + * @brief Clear MAC command buffer. */ - void ClearCommandBuffer(); + void clear_command_buffer(void); - /*! - * \brief Get the length of MAC commands + /** + * @brief Get the length of MAC commands * - * \retval status Length of used MAC buffer (bytes) + * @return status Length of used MAC buffer (bytes) */ - uint8_t GetLength() const; + uint8_t get_mac_cmd_length() const; - /*! - * \brief Get MAC command buffer + /** + * @brief Get MAC command buffer * - * \retval Pointer to MAC command buffer + * @return Pointer to MAC command buffer */ - uint8_t *GetMacCommandsBuffer(); + uint8_t *get_mac_commands_buffer(); - /*! - * \brief Parses the MAC commands which must be resent. + /** + * @brief Parses the MAC commands which must be resent. */ - void ParseMacCommandsToRepeat(); + void parse_mac_commands_to_repeat(); - /*! - * \brief Clear MAC command repeat buffer. + /** + * @brief Clear MAC command repeat buffer. */ - void ClearRepeatBuffer(); + void clear_repeat_buffer(); - /*! - * \brief Copy MAC commands from repeat buffer to actual MAC command buffer. + /** + * @brief Copy MAC commands from repeat buffer to actual MAC command buffer. */ - void CopyRepeatCommandsToBuffer(); + void copy_repeat_commands_to_buffer(); - /*! - * \brief Get the length of MAC commands in repeat buffer + /** + * @brief Get the length of MAC commands in repeat buffer * - * \retval status Length of used MAC Repeat buffer (bytes) + * @return status Length of used MAC Repeat buffer (bytes) */ - uint8_t GetRepeatLength() const; + uint8_t get_repeat_commands_length() const; - /*! - * \brief Clear MAC commands in next TX. + /** + * @brief Clear MAC commands in next TX. */ - void ClearMacCommandsInNextTx(); + void clear_mac_commands_in_next_tx(); - /*! - * \brief Check if MAC command buffer has commands to be sent in next TX + /** + * @brief Check if MAC command buffer has commands to be sent in next TX * - * \retval status True: buffer has MAC commands to be sent, false: no commands in buffer] + * @return status True: buffer has MAC commands to be sent, false: no commands in buffer] */ - bool IsMacCommandsInNextTx() const; + bool is_mac_command_in_next_tx() const; - /*! - * \brief Decodes MAC commands in the fOpts field and in the payload - - * \retval status Function status. LORAWAN_STATUS_OK if command successful. - */ - lorawan_status_t ProcessMacCommands(uint8_t *payload, uint8_t macIndex, - uint8_t commandsSize, uint8_t snr, - loramac_mlme_confirm_t& MlmeConfirm, - lora_mac_system_params_t& LoRaMacParams, - LoRaPHY& lora_phy); - - /*! - * \brief Verifies if sticky MAC commands are pending. + /** + * @brief Decodes MAC commands in the fOpts field and in the payload * - * \retval [true: sticky MAC commands pending, false: No MAC commands pending] + * @return status Function status. LORAWAN_STATUS_OK if command successful. */ - bool IsStickyMacCommandPending(); + lorawan_status_t process_mac_commands(uint8_t *payload, uint8_t mac_index, + uint8_t commands_size, uint8_t snr, + loramac_mlme_confirm_t& mlme_conf, + lora_mac_system_params_t& mac_params, + LoRaPHY& lora_phy); + + /** + * @brief Verifies if sticky MAC commands are pending. + * + * @return [true: sticky MAC commands pending, false: No MAC commands pending] + */ + bool is_sticky_mac_command_pending(); private: LoRaMac& _lora_mac; - /*! + /** * Indicates if the MAC layer wants to send MAC commands */ - bool MacCommandsInNextTx; + bool mac_cmd_in_next_tx; - /*! - * Contains the current MacCommandsBuffer index + /** + * Contains the current Mac command buffer index in 'mac_cmd_buffer' */ - uint8_t MacCommandsBufferIndex; + uint8_t mac_cmd_buf_idx; - /*! - * Contains the current MacCommandsBuffer index for MAC commands to repeat + /** + * Contains the current Mac command buffer index for MAC commands to repeat in + * 'mac_cmd_buffer_to_repeat' */ - uint8_t MacCommandsBufferToRepeatIndex; + uint8_t mac_cmd_buf_idx_to_repeat; - /*! + /** * Buffer containing the MAC layer commands */ - uint8_t MacCommandsBuffer[LORA_MAC_COMMAND_MAX_LENGTH]; + uint8_t mac_cmd_buffer[LORA_MAC_COMMAND_MAX_LENGTH]; - /*! + /** * Buffer containing the MAC layer commands which must be repeated */ - uint8_t MacCommandsBufferToRepeat[LORA_MAC_COMMAND_MAX_LENGTH]; + uint8_t mac_cmd_buffer_to_repeat[LORA_MAC_COMMAND_MAX_LENGTH]; }; #endif //__LORAMACCOMMAND_H__ diff --git a/features/lorawan/lorastack/mac/LoRaMacCrypto.cpp b/features/lorawan/lorastack/mac/LoRaMacCrypto.cpp index 5919c37a6f..75deb84197 100644 --- a/features/lorawan/lorastack/mac/LoRaMacCrypto.cpp +++ b/features/lorawan/lorastack/mac/LoRaMacCrypto.cpp @@ -41,251 +41,253 @@ /** * MIC field computation initial data */ -static uint8_t MicBlockB0[] = { 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; +static uint8_t mic_block_b0[] = {0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; /** * Contains the computed MIC field. * * \remark Only the 4 first bytes are used */ -static uint8_t Mic[16]; +static uint8_t computed_mic[16]; /** * Encryption aBlock and sBlock */ -static uint8_t aBlock[] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; -static uint8_t sBlock[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; +static uint8_t a_block[] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +static uint8_t s_block[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; /** * AES computation context variable */ -static mbedtls_aes_context AesContext; +static mbedtls_aes_context aes_ctx; /** * CMAC computation context variable */ -static mbedtls_cipher_context_t AesCmacCtx[1]; +static mbedtls_cipher_context_t aes_cmac_ctx[1]; #define AES_CMAC_KEY_LENGTH 16 -/** - * \brief Computes the LoRaMAC frame MIC field - * - * \param [in] buffer Data buffer - * \param [in] size Data buffer size - * \param [in] key AES key to be used - * \param [in] address Frame address - * \param [in] dir Frame direction [0: uplink, 1: downlink] - * \param [in] sequenceCounter Frame sequence counter - * \param [out] mic Computed MIC field - */ -int LoRaMacComputeMic( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint32_t *mic ) +int compute_mic(const uint8_t *buffer, uint16_t size, const uint8_t *key, + uint32_t address, uint8_t dir, uint32_t seq_counter, + uint32_t *mic) { int ret = 0; - MicBlockB0[5] = dir; + mic_block_b0[5] = dir; - MicBlockB0[6] = ( address ) & 0xFF; - MicBlockB0[7] = ( address >> 8 ) & 0xFF; - MicBlockB0[8] = ( address >> 16 ) & 0xFF; - MicBlockB0[9] = ( address >> 24 ) & 0xFF; + mic_block_b0[6] = (address) & 0xFF; + mic_block_b0[7] = (address >> 8) & 0xFF; + mic_block_b0[8] = (address >> 16) & 0xFF; + mic_block_b0[9] = (address >> 24) & 0xFF; - MicBlockB0[10] = ( sequenceCounter ) & 0xFF; - MicBlockB0[11] = ( sequenceCounter >> 8 ) & 0xFF; - MicBlockB0[12] = ( sequenceCounter >> 16 ) & 0xFF; - MicBlockB0[13] = ( sequenceCounter >> 24 ) & 0xFF; + mic_block_b0[10] = (seq_counter) & 0xFF; + mic_block_b0[11] = (seq_counter >> 8) & 0xFF; + mic_block_b0[12] = (seq_counter >> 16) & 0xFF; + mic_block_b0[13] = (seq_counter >> 24) & 0xFF; - MicBlockB0[15] = size & 0xFF; + mic_block_b0[15] = size & 0xFF; + + mbedtls_cipher_init(aes_cmac_ctx); - mbedtls_cipher_init(AesCmacCtx); const mbedtls_cipher_info_t* cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB); + if (NULL != cipher_info) { - ret = mbedtls_cipher_setup(AesCmacCtx, cipher_info); + ret = mbedtls_cipher_setup(aes_cmac_ctx, cipher_info); if (0 != ret) goto exit; - ret = mbedtls_cipher_cmac_starts(AesCmacCtx, key, AES_CMAC_KEY_LENGTH*8); + ret = mbedtls_cipher_cmac_starts(aes_cmac_ctx, key, + AES_CMAC_KEY_LENGTH * 8); if (0 != ret) goto exit; - ret = mbedtls_cipher_cmac_update(AesCmacCtx, MicBlockB0, LORAMAC_MIC_BLOCK_B0_SIZE); + ret = mbedtls_cipher_cmac_update(aes_cmac_ctx, mic_block_b0, + LORAMAC_MIC_BLOCK_B0_SIZE); if (0 != ret) goto exit; - ret = mbedtls_cipher_cmac_update(AesCmacCtx, buffer, size & 0xFF); + ret = mbedtls_cipher_cmac_update(aes_cmac_ctx, buffer, size & 0xFF); if (0 != ret) goto exit; - ret = mbedtls_cipher_cmac_finish(AesCmacCtx, Mic); + ret = mbedtls_cipher_cmac_finish(aes_cmac_ctx, computed_mic); if (0 != ret) goto exit; - *mic = ( uint32_t )( ( uint32_t )Mic[3] << 24 | ( uint32_t )Mic[2] << 16 | ( uint32_t )Mic[1] << 8 | ( uint32_t )Mic[0] ); + *mic = (uint32_t) ((uint32_t) computed_mic[3] << 24 + | (uint32_t) computed_mic[2] << 16 + | (uint32_t) computed_mic[1] << 8 | (uint32_t) computed_mic[0]); } else { ret = MBEDTLS_ERR_CIPHER_ALLOC_FAILED; } -exit: - mbedtls_cipher_free( AesCmacCtx ); +exit: mbedtls_cipher_free(aes_cmac_ctx); return ret; } -int LoRaMacPayloadEncrypt( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint8_t *encBuffer ) +int encrypt_payload(const uint8_t *buffer, uint16_t size, const uint8_t *key, + uint32_t address, uint8_t dir, uint32_t seq_counter, + uint8_t *enc_buffer) { uint16_t i; uint8_t bufferIndex = 0; uint16_t ctr = 1; int ret = 0; - mbedtls_aes_init(&AesContext); - ret = mbedtls_aes_setkey_enc(&AesContext, key, 16*8); + mbedtls_aes_init(&aes_ctx); + ret = mbedtls_aes_setkey_enc(&aes_ctx, key, 16 * 8); if (0 != ret) goto exit; - aBlock[5] = dir; + a_block[5] = dir; - aBlock[6] = ( address ) & 0xFF; - aBlock[7] = ( address >> 8 ) & 0xFF; - aBlock[8] = ( address >> 16 ) & 0xFF; - aBlock[9] = ( address >> 24 ) & 0xFF; + a_block[6] = (address) & 0xFF; + a_block[7] = (address >> 8) & 0xFF; + a_block[8] = (address >> 16) & 0xFF; + a_block[9] = (address >> 24) & 0xFF; - aBlock[10] = ( sequenceCounter ) & 0xFF; - aBlock[11] = ( sequenceCounter >> 8 ) & 0xFF; - aBlock[12] = ( sequenceCounter >> 16 ) & 0xFF; - aBlock[13] = ( sequenceCounter >> 24 ) & 0xFF; + a_block[10] = (seq_counter) & 0xFF; + a_block[11] = (seq_counter >> 8) & 0xFF; + a_block[12] = (seq_counter >> 16) & 0xFF; + a_block[13] = (seq_counter >> 24) & 0xFF; - while( size >= 16 ) - { - aBlock[15] = ( ( ctr ) & 0xFF ); + while (size >= 16) { + a_block[15] = ((ctr) & 0xFF); ctr++; - ret = mbedtls_aes_crypt_ecb(&AesContext, MBEDTLS_AES_ENCRYPT, aBlock, sBlock); + ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, a_block, + s_block); if (0 != ret) goto exit; - for( i = 0; i < 16; i++ ) - { - encBuffer[bufferIndex + i] = buffer[bufferIndex + i] ^ sBlock[i]; + for (i = 0; i < 16; i++) { + enc_buffer[bufferIndex + i] = buffer[bufferIndex + i] ^ s_block[i]; } size -= 16; bufferIndex += 16; } - if( size > 0 ) - { - aBlock[15] = ( ( ctr ) & 0xFF ); - ret = mbedtls_aes_crypt_ecb(&AesContext, MBEDTLS_AES_ENCRYPT, aBlock, sBlock); + if (size > 0) { + a_block[15] = ((ctr) & 0xFF); + ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, a_block, + s_block); if (0 != ret) goto exit; - for( i = 0; i < size; i++ ) - { - encBuffer[bufferIndex + i] = buffer[bufferIndex + i] ^ sBlock[i]; + for (i = 0; i < size; i++) { + enc_buffer[bufferIndex + i] = buffer[bufferIndex + i] ^ s_block[i]; } } -exit: - mbedtls_aes_free(&AesContext); +exit: mbedtls_aes_free(&aes_ctx); return ret; } -int LoRaMacPayloadDecrypt( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint8_t *decBuffer ) +int decrypt_payload(const uint8_t *buffer, uint16_t size, const uint8_t *key, + uint32_t address, uint8_t dir, uint32_t seq_counter, + uint8_t *dec_buffer) { - return LoRaMacPayloadEncrypt( buffer, size, key, address, dir, sequenceCounter, decBuffer ); + return encrypt_payload(buffer, size, key, address, dir, seq_counter, + dec_buffer); } -int LoRaMacJoinComputeMic( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t *mic ) +int compute_join_frame_mic(const uint8_t *buffer, uint16_t size, + const uint8_t *key, uint32_t *mic) { int ret = 0; - mbedtls_cipher_init(AesCmacCtx); + mbedtls_cipher_init(aes_cmac_ctx); const mbedtls_cipher_info_t* cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB); + if (NULL != cipher_info) { - ret = mbedtls_cipher_setup(AesCmacCtx, cipher_info); + ret = mbedtls_cipher_setup(aes_cmac_ctx, cipher_info); if (0 != ret) goto exit; - ret = mbedtls_cipher_cmac_starts(AesCmacCtx, key, AES_CMAC_KEY_LENGTH*8); + ret = mbedtls_cipher_cmac_starts(aes_cmac_ctx, key, + AES_CMAC_KEY_LENGTH * 8); if (0 != ret) goto exit; - ret = mbedtls_cipher_cmac_update(AesCmacCtx, buffer, size & 0xFF); + ret = mbedtls_cipher_cmac_update(aes_cmac_ctx, buffer, size & 0xFF); if (0 != ret) goto exit; - ret = mbedtls_cipher_cmac_finish(AesCmacCtx, Mic); + ret = mbedtls_cipher_cmac_finish(aes_cmac_ctx, computed_mic); if (0 != ret) goto exit; - *mic = ( uint32_t )( ( uint32_t )Mic[3] << 24 | ( uint32_t )Mic[2] << 16 | ( uint32_t )Mic[1] << 8 | ( uint32_t )Mic[0] ); + *mic = (uint32_t) ((uint32_t) computed_mic[3] << 24 + | (uint32_t) computed_mic[2] << 16 + | (uint32_t) computed_mic[1] << 8 | (uint32_t) computed_mic[0]); } else { ret = MBEDTLS_ERR_CIPHER_ALLOC_FAILED; } -exit: - mbedtls_cipher_free(AesCmacCtx); +exit: mbedtls_cipher_free(aes_cmac_ctx); return ret; } -int LoRaMacJoinDecrypt( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint8_t *decBuffer ) +int decrypt_join_frame(const uint8_t *buffer, uint16_t size, const uint8_t *key, + uint8_t *dec_buffer) { int ret = 0; - mbedtls_aes_init(&AesContext); + mbedtls_aes_init(&aes_ctx); - ret = mbedtls_aes_setkey_enc(&AesContext, key, 16*8); + ret = mbedtls_aes_setkey_enc(&aes_ctx, key, 16 * 8); if (0 != ret) goto exit; - ret = mbedtls_aes_crypt_ecb(&AesContext, MBEDTLS_AES_ENCRYPT, buffer, decBuffer); + ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, buffer, + dec_buffer); if (0 != ret) goto exit; // Check if optional CFList is included - if( size >= 16 ) - { - ret = mbedtls_aes_crypt_ecb(&AesContext, MBEDTLS_AES_ENCRYPT, buffer + 16, decBuffer + 16); + if (size >= 16) { + ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, buffer + 16, + dec_buffer + 16); } -exit: - mbedtls_aes_free(&AesContext); +exit: mbedtls_aes_free(&aes_ctx); return ret; } -int LoRaMacJoinComputeSKeys( const uint8_t *key, const uint8_t *appNonce, uint16_t devNonce, uint8_t *nwkSKey, uint8_t *appSKey ) +int compute_skeys_for_join_frame(const uint8_t *key, const uint8_t *app_nonce, + uint16_t dev_nonce, uint8_t *nwk_skey, + uint8_t *app_skey) { uint8_t nonce[16]; - uint8_t *pDevNonce = ( uint8_t * )&devNonce; + uint8_t *p_dev_nonce = (uint8_t *) &dev_nonce; int ret = 0; - mbedtls_aes_init(&AesContext); + mbedtls_aes_init(&aes_ctx); - ret = mbedtls_aes_setkey_enc(&AesContext, key, 16*8); + ret = mbedtls_aes_setkey_enc(&aes_ctx, key, 16 * 8); if (0 != ret) goto exit; - memset( nonce, 0, sizeof( nonce ) ); + memset(nonce, 0, sizeof(nonce)); nonce[0] = 0x01; - memcpy( nonce + 1, appNonce, 6 ); - memcpy( nonce + 7, pDevNonce, 2 ); - ret = mbedtls_aes_crypt_ecb(&AesContext, MBEDTLS_AES_ENCRYPT, nonce, nwkSKey); + memcpy(nonce + 1, app_nonce, 6); + memcpy(nonce + 7, p_dev_nonce, 2); + ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, nonce, nwk_skey); if (0 != ret) goto exit; - memset( nonce, 0, sizeof( nonce ) ); + memset(nonce, 0, sizeof(nonce)); nonce[0] = 0x02; - memcpy( nonce + 1, appNonce, 6 ); - memcpy( nonce + 7, pDevNonce, 2 ); - ret = mbedtls_aes_crypt_ecb(&AesContext, MBEDTLS_AES_ENCRYPT, nonce, appSKey); + memcpy(nonce + 1, app_nonce, 6); + memcpy(nonce + 7, p_dev_nonce, 2); + ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, nonce, app_skey); -exit: - mbedtls_aes_free(&AesContext); + exit: mbedtls_aes_free(&aes_ctx); return ret; } #else @@ -294,8 +296,8 @@ exit: // user knows what is wrong and in addition to that these ensure that // Mbed-OS compiles properly under normal conditions where LoRaWAN in conjunction // with mbedTLS is not being used. -int LoRaMacComputeMic( const uint8_t *, uint16_t , const uint8_t *, uint32_t, - uint8_t dir, uint32_t, uint32_t * ) +int compute_mic(const uint8_t *, uint16_t , const uint8_t *, uint32_t, + uint8_t dir, uint32_t, uint32_t *) { MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS"); @@ -303,8 +305,8 @@ int LoRaMacComputeMic( const uint8_t *, uint16_t , const uint8_t *, uint32_t, return LORAWAN_STATUS_CRYPTO_FAIL; } -int LoRaMacPayloadEncrypt( const uint8_t *, uint16_t , const uint8_t *, uint32_t, - uint8_t , uint32_t , uint8_t * ) +int encrypt_payload(const uint8_t *, uint16_t , const uint8_t *, uint32_t, + uint8_t , uint32_t , uint8_t *) { MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS"); @@ -312,15 +314,8 @@ int LoRaMacPayloadEncrypt( const uint8_t *, uint16_t , const uint8_t *, uint32_t return LORAWAN_STATUS_CRYPTO_FAIL; } -int LoRaMacPayloadDecrypt( const uint8_t *, uint16_t , const uint8_t *, uint32_t, - uint8_t , uint32_t , uint8_t * ) -{ - MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS"); - - // Never actually reaches here - return LORAWAN_STATUS_CRYPTO_FAIL; -} -int LoRaMacJoinComputeMic( const uint8_t *, uint16_t , const uint8_t *, uint32_t * ) +int decrypt_payload(const uint8_t *, uint16_t , const uint8_t *, uint32_t, + uint8_t , uint32_t , uint8_t *) { MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS"); @@ -328,7 +323,7 @@ int LoRaMacJoinComputeMic( const uint8_t *, uint16_t , const uint8_t *, uint32_t return LORAWAN_STATUS_CRYPTO_FAIL; } -int LoRaMacJoinDecrypt( const uint8_t *, uint16_t , const uint8_t *, uint8_t * ) +int compute_join_frame_mic(const uint8_t *, uint16_t , const uint8_t *, uint32_t *) { MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS"); @@ -336,7 +331,16 @@ int LoRaMacJoinDecrypt( const uint8_t *, uint16_t , const uint8_t *, uint8_t * ) return LORAWAN_STATUS_CRYPTO_FAIL; } -int LoRaMacJoinComputeSKeys( const uint8_t *, const uint8_t *, uint16_t , uint8_t *, uint8_t * ) +int decrypt_join_frame(const uint8_t *, uint16_t , const uint8_t *, uint8_t *) +{ + MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS"); + + // Never actually reaches here + return LORAWAN_STATUS_CRYPTO_FAIL; +} + +int compute_skeys_for_join_frame(const uint8_t *, const uint8_t *, uint16_t , + uint8_t *, uint8_t *) { MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS"); diff --git a/features/lorawan/lorastack/mac/LoRaMacCrypto.h b/features/lorawan/lorastack/mac/LoRaMacCrypto.h index cf09becb3e..af3fa75cff 100644 --- a/features/lorawan/lorastack/mac/LoRaMacCrypto.h +++ b/features/lorawan/lorastack/mac/LoRaMacCrypto.h @@ -29,84 +29,94 @@ SPDX-License-Identifier: BSD-3-Clause /** * Computes the LoRaMAC frame MIC field * - * \param [in] buffer - Data buffer - * \param [in] size - Data buffer size - * \param [in] key - AES key to be used - * \param [in] address - Frame address - * \param [in] dir - Frame direction [0: uplink, 1: downlink] - * \param [in] sequenceCounter - Frame sequence counter - * \param [out] mic - Computed MIC field + * @param [in] buffer - Data buffer + * @param [in] size - Data buffer size + * @param [in] key - AES key to be used + * @param [in] address - Frame address + * @param [in] dir - Frame direction [0: uplink, 1: downlink] + * @param [in] seq_counter - Frame sequence counter + * @param [out] mic - Computed MIC field * - * \return 0 if successful, or a cipher specific error code + * @return 0 if successful, or a cipher specific error code */ -int LoRaMacComputeMic( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint32_t *mic ); +int compute_mic(const uint8_t *buffer, uint16_t size, const uint8_t *key, + uint32_t address, uint8_t dir, uint32_t seq_counter, + uint32_t *mic); /** - * Computes the LoRaMAC payload encryption + * Performs payload encryption * - * \param [in] buffer - Data buffer - * \param [in] size - Data buffer size - * \param [in] key - AES key to be used - * \param [in] address - Frame address - * \param [in] dir - Frame direction [0: uplink, 1: downlink] - * \param [in] sequenceCounter - Frame sequence counter - * \param [out] encBuffer - Encrypted buffer + * @param [in] buffer - Data buffer + * @param [in] size - Data buffer size + * @param [in] key - AES key to be used + * @param [in] address - Frame address + * @param [in] dir - Frame direction [0: uplink, 1: downlink] + * @param [in] seq_counter - Frame sequence counter + * @param [out] enc_buffer - Encrypted buffer * - * \return 0 if successful, or a cipher specific error code + * @return 0 if successful, or a cipher specific error code */ -int LoRaMacPayloadEncrypt( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint8_t *encBuffer ); +int encrypt_payload(const uint8_t *buffer, uint16_t size, const uint8_t *key, + uint32_t address, uint8_t dir, uint32_t seq_counter, + uint8_t *enc_buffer); /** - * Computes the LoRaMAC payload decryption + * Performs payload decryption * - * \param [in] buffer - Data buffer - * \param [in] size - Data buffer size - * \param [in] key - AES key to be used - * \param [in] address - Frame address - * \param [in] dir - Frame direction [0: uplink, 1: downlink] - * \param [in] sequenceCounter - Frame sequence counter - * \param [out] decBuffer - Decrypted buffer + * @param [in] buffer - Data buffer + * @param [in] size - Data buffer size + * @param [in] key - AES key to be used + * @param [in] address - Frame address + * @param [in] dir - Frame direction [0: uplink, 1: downlink] + * @param [in] seq_counter - Frame sequence counter + * @param [out] dec_buffer - Decrypted buffer * - * \return 0 if successful, or a cipher specific error code + * @return 0 if successful, or a cipher specific error code */ -int LoRaMacPayloadDecrypt( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint8_t *decBuffer ); +int decrypt_payload(const uint8_t *buffer, uint16_t size, const uint8_t *key, + uint32_t address, uint8_t dir, uint32_t seq_counter, + uint8_t *dec_buffer); /** * Computes the LoRaMAC Join Request frame MIC field * - * \param [in] buffer - Data buffer - * \param [in] size - Data buffer size - * \param [in] key - AES key to be used - * \param [out] mic - Computed MIC field + * @param [in] buffer - Data buffer + * @param [in] size - Data buffer size + * @param [in] key - AES key to be used + * @param [out] mic - Computed MIC field * - * \return 0 if successful, or a cipher specific error code + * @return 0 if successful, or a cipher specific error code * */ -int LoRaMacJoinComputeMic( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t *mic ); +int compute_join_frame_mic(const uint8_t *buffer, uint16_t size, + const uint8_t *key, uint32_t *mic); /** * Computes the LoRaMAC join frame decryption * - * \param [in] buffer - Data buffer - * \param [in] size - Data buffer size - * \param [in] key - AES key to be used - * \param [out] decBuffer - Decrypted buffer + * @param [in] buffer - Data buffer + * @param [in] size - Data buffer size + * @param [in] key - AES key to be used + * @param [out] dec_buffer - Decrypted buffer * - * \return 0 if successful, or a cipher specific error code + * @return 0 if successful, or a cipher specific error code */ -int LoRaMacJoinDecrypt( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint8_t *decBuffer ); +int decrypt_join_frame(const uint8_t *buffer, uint16_t size, + const uint8_t *key, uint8_t *dec_buffer); /** * Computes the LoRaMAC join frame decryption * - * \param [in] key - AES key to be used - * \param [in] appNonce - Application nonce - * \param [in] devNonce - Device nonce - * \param [out] nwkSKey - Network session key - * \param [out] appSKey - Application session key + * @param [in] key - AES key to be used + * @param [in] app_nonce - Application nonce + * @param [in] dev_nonce - Device nonce + * @param [out] nwk_skey - Network session key + * @param [out] app_skey - Application session key * - * \return 0 if successful, or a cipher specific error code + * @return 0 if successful, or a cipher specific error code */ -int LoRaMacJoinComputeSKeys( const uint8_t *key, const uint8_t *appNonce, uint16_t devNonce, uint8_t *nwkSKey, uint8_t *appSKey ); +int compute_skeys_for_join_frame(const uint8_t *key, const uint8_t *app_nonce, + uint16_t dev_nonce, uint8_t *nwk_skey, + uint8_t *app_skey ); #endif // MBED_LORAWAN_MAC_LORAMAC_CRYPTO_H__ diff --git a/features/lorawan/lorastack/mac/LoRaMacMcps.cpp b/features/lorawan/lorastack/mac/LoRaMacMcps.cpp index 17aa3194ee..c5331abd16 100644 --- a/features/lorawan/lorastack/mac/LoRaMacMcps.cpp +++ b/features/lorawan/lorastack/mac/LoRaMacMcps.cpp @@ -52,15 +52,15 @@ lorawan_status_t LoRaMacMcps::set_request(loramac_mcps_req_t *mcpsRequest, get_phy_params_t get_phy; phy_param_t phyParam; lorawan_status_t status = LORAWAN_STATUS_SERVICE_UNKNOWN; - loramac_mhdr_t macHdr; + loramac_mhdr_t machdr; verification_params_t verify; - uint8_t fPort = 0; - void *fBuffer; - uint16_t fBufferSize; + uint8_t fport = 0; + void *fbuffer; + uint16_t fbuffer_size; int8_t datarate = DR_0; - bool readyToSend = false; + bool ready_to_send = false; - macHdr.value = 0; + machdr.value = 0; // Before performing any MCPS request, clear the confirmation structure memset((uint8_t*) &confirmation, 0, sizeof(confirmation)); @@ -72,34 +72,34 @@ lorawan_status_t LoRaMacMcps::set_request(loramac_mcps_req_t *mcpsRequest, switch (mcpsRequest->type) { case MCPS_UNCONFIRMED: { - readyToSend = true; + ready_to_send = true; params->max_ack_timeout_retries = 1; - macHdr.bits.mtype = FRAME_TYPE_DATA_UNCONFIRMED_UP; - fPort = mcpsRequest->req.unconfirmed.fport; - fBuffer = mcpsRequest->f_buffer; - fBufferSize = mcpsRequest->f_buffer_size; + machdr.bits.mtype = FRAME_TYPE_DATA_UNCONFIRMED_UP; + fport = mcpsRequest->req.unconfirmed.fport; + fbuffer = mcpsRequest->f_buffer; + fbuffer_size = mcpsRequest->f_buffer_size; datarate = mcpsRequest->req.unconfirmed.data_rate; break; } case MCPS_CONFIRMED: { - readyToSend = true; + ready_to_send = true; params->max_ack_timeout_retries = mcpsRequest->req.confirmed.nb_trials; - macHdr.bits.mtype = FRAME_TYPE_DATA_CONFIRMED_UP; - fPort = mcpsRequest->req.confirmed.fport; - fBuffer = mcpsRequest->f_buffer; - fBufferSize = mcpsRequest->f_buffer_size; + machdr.bits.mtype = FRAME_TYPE_DATA_CONFIRMED_UP; + fport = mcpsRequest->req.confirmed.fport; + fbuffer = mcpsRequest->f_buffer; + fbuffer_size = mcpsRequest->f_buffer_size; datarate = mcpsRequest->req.confirmed.data_rate; break; } case MCPS_PROPRIETARY: { - readyToSend = true; + ready_to_send = true; params->max_ack_timeout_retries = 1; - macHdr.bits.mtype = FRAME_TYPE_PROPRIETARY; - fBuffer = mcpsRequest->f_buffer; - fBufferSize = mcpsRequest->f_buffer_size; + machdr.bits.mtype = FRAME_TYPE_PROPRIETARY; + fbuffer = mcpsRequest->f_buffer; + fbuffer_size = mcpsRequest->f_buffer_size; datarate = mcpsRequest->req.proprietary.data_rate; break; } @@ -122,7 +122,7 @@ lorawan_status_t LoRaMacMcps::set_request(loramac_mcps_req_t *mcpsRequest, // Some regions have limitations for the minimum datarate. datarate = MAX(datarate, (int8_t)phyParam.value); - if (readyToSend == true) { + if (ready_to_send == true) { if (params->sys_params.adr_on == false) { verify.datarate = datarate; @@ -133,7 +133,7 @@ lorawan_status_t LoRaMacMcps::set_request(loramac_mcps_req_t *mcpsRequest, } } - status = _lora_mac->Send(&macHdr, fPort, fBuffer, fBufferSize); + status = _lora_mac->send(&machdr, fport, fbuffer, fbuffer_size); if (status == LORAWAN_STATUS_OK) { confirmation.req_type = mcpsRequest->type; params->flags.bits.mcps_req = 1; diff --git a/features/lorawan/lorastack/mac/LoRaMacMib.cpp b/features/lorawan/lorastack/mac/LoRaMacMib.cpp index 2849469494..981dd141d8 100644 --- a/features/lorawan/lorastack/mac/LoRaMacMib.cpp +++ b/features/lorawan/lorastack/mac/LoRaMacMib.cpp @@ -75,7 +75,7 @@ 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->OpenContinuousRx2Window(); + _lora_mac->open_continuous_rx2_window(); break; } } @@ -144,7 +144,7 @@ lorawan_status_t LoRaMacMib::set_request(loramac_mib_req_confirm_t *mibSet, params->sys_params.max_sys_rx_error, ¶ms->rx_window2_config); - _lora_mac->OpenContinuousRx2Window(); + _lora_mac->open_continuous_rx2_window(); } } else { status = LORAWAN_STATUS_PARAMETER_INVALID; @@ -272,7 +272,7 @@ lorawan_status_t LoRaMacMib::get_request(loramac_mib_req_confirm_t *mibGet, { lorawan_status_t status = LORAWAN_STATUS_OK; get_phy_params_t get_phy; - phy_param_t phyParam; + phy_param_t phy_param; rx2_channel_params rx2_channel; if( mibGet == NULL ) @@ -330,9 +330,9 @@ lorawan_status_t LoRaMacMib::get_request(loramac_mib_req_confirm_t *mibGet, case MIB_CHANNELS: { get_phy.attribute = PHY_CHANNELS; - phyParam = _lora_phy->get_phy_params( &get_phy ); + phy_param = _lora_phy->get_phy_params( &get_phy ); - mibGet->param.channel_list = phyParam.channel_params; + mibGet->param.channel_list = phy_param.channel_params; break; } case MIB_RX2_CHANNEL: @@ -343,12 +343,12 @@ lorawan_status_t LoRaMacMib::get_request(loramac_mib_req_confirm_t *mibGet, case MIB_RX2_DEFAULT_CHANNEL: { get_phy.attribute = PHY_DEF_RX2_DR; - phyParam = _lora_phy->get_phy_params( &get_phy ); - rx2_channel.datarate = phyParam.value; + phy_param = _lora_phy->get_phy_params( &get_phy ); + rx2_channel.datarate = phy_param.value; get_phy.attribute = PHY_DEF_RX2_FREQUENCY; - phyParam = _lora_phy->get_phy_params( &get_phy ); - rx2_channel.frequency = phyParam.value; + phy_param = _lora_phy->get_phy_params( &get_phy ); + rx2_channel.frequency = phy_param.value; mibGet->param.rx2_channel = rx2_channel; break; @@ -356,17 +356,17 @@ lorawan_status_t LoRaMacMib::get_request(loramac_mib_req_confirm_t *mibGet, case MIB_CHANNELS_DEFAULT_MASK: { get_phy.attribute = PHY_CHANNELS_DEFAULT_MASK; - phyParam = _lora_phy->get_phy_params( &get_phy ); + phy_param = _lora_phy->get_phy_params( &get_phy ); - mibGet->param.default_channel_mask = phyParam.channel_mask; + mibGet->param.default_channel_mask = phy_param.channel_mask; break; } case MIB_CHANNELS_MASK: { get_phy.attribute = PHY_CHANNELS_MASK; - phyParam = _lora_phy->get_phy_params( &get_phy ); + phy_param = _lora_phy->get_phy_params( &get_phy ); - mibGet->param.channel_mask = phyParam.channel_mask; + mibGet->param.channel_mask = phy_param.channel_mask; break; } case MIB_CHANNELS_NB_REP: @@ -402,8 +402,8 @@ lorawan_status_t LoRaMacMib::get_request(loramac_mib_req_confirm_t *mibGet, case MIB_CHANNELS_DEFAULT_DATARATE: { get_phy.attribute = PHY_DEF_TX_DR; - phyParam = _lora_phy->get_phy_params( &get_phy ); - mibGet->param.default_channel_data_rate = phyParam.value; + phy_param = _lora_phy->get_phy_params( &get_phy ); + mibGet->param.default_channel_data_rate = phy_param.value; break; } case MIB_CHANNELS_DATARATE: @@ -414,8 +414,8 @@ lorawan_status_t LoRaMacMib::get_request(loramac_mib_req_confirm_t *mibGet, case MIB_CHANNELS_DEFAULT_TX_POWER: { get_phy.attribute = PHY_DEF_TX_POWER; - phyParam = _lora_phy->get_phy_params( &get_phy ); - mibGet->param.default_channel_tx_pwr = phyParam.value; + phy_param = _lora_phy->get_phy_params( &get_phy ); + mibGet->param.default_channel_tx_pwr = phy_param.value; break; } case MIB_CHANNELS_TX_POWER: diff --git a/features/lorawan/lorastack/mac/LoRaMacMlme.cpp b/features/lorawan/lorastack/mac/LoRaMacMlme.cpp index 9f2eb6f668..35c0b623a8 100644 --- a/features/lorawan/lorastack/mac/LoRaMacMlme.cpp +++ b/features/lorawan/lorastack/mac/LoRaMacMlme.cpp @@ -43,17 +43,17 @@ void LoRaMacMlme::activate_mlme_subsystem(LoRaMac *mac, LoRaPHY *phy, _mac_cmd = cmd; } -lorawan_status_t LoRaMacMlme::set_request(loramac_mlme_req_t *mlmeRequest, +lorawan_status_t LoRaMacMlme::set_request(loramac_mlme_req_t *request, loramac_protocol_params *params) { - if (mlmeRequest && params && _lora_mac && _lora_phy && _mac_cmd) { + if (request && params && _lora_mac && _lora_phy && _mac_cmd) { lorawan_status_t status = LORAWAN_STATUS_SERVICE_UNKNOWN; - loramac_mhdr_t macHdr; + loramac_mhdr_t machdr; verification_params_t verify; get_phy_params_t get_phy; - phy_param_t phyParam; + phy_param_t phy_param; if (params->mac_state != LORAMAC_IDLE) { @@ -66,73 +66,73 @@ lorawan_status_t LoRaMacMlme::set_request(loramac_mlme_req_t *mlmeRequest, confirmation.status = LORAMAC_EVENT_INFO_STATUS_ERROR; - switch (mlmeRequest->type) { + switch (request->type) { case MLME_JOIN: { 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)) { + 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; } // Verify the parameter NbTrials for the join procedure - verify.nb_join_trials = mlmeRequest->req.join.nb_trials; + verify.nb_join_trials = request->req.join.nb_trials; if (_lora_phy->verify(&verify, PHY_NB_JOIN_TRIALS) == false) { // Value not supported, get default get_phy.attribute = PHY_DEF_NB_JOIN_TRIALS; - phyParam = _lora_phy->get_phy_params(&get_phy); - mlmeRequest->req.join.nb_trials = (uint8_t) phyParam.value; + phy_param = _lora_phy->get_phy_params(&get_phy); + request->req.join.nb_trials = (uint8_t) phy_param.value; } params->flags.bits.mlme_req = 1; - confirmation.req_type = mlmeRequest->type; + confirmation.req_type = request->type; - 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; + 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; + machdr.value = 0; + machdr.bits.mtype = FRAME_TYPE_JOIN_REQ; - _lora_mac->ResetMacParameters(); + _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); + 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 = mlmeRequest->type; + confirmation.req_type = request->type; - status = _mac_cmd->AddMacCommand(MOTE_MAC_LINK_CHECK_REQ, 0, 0); + status = _mac_cmd->add_mac_command(MOTE_MAC_LINK_CHECK_REQ, 0, 0); break; } case MLME_TXCW: { - confirmation.req_type = mlmeRequest->type; + confirmation.req_type = request->type; params->flags.bits.mlme_req = 1; - status = _lora_mac->SetTxContinuousWave(mlmeRequest->req.cw_tx_mode.timeout); + status = _lora_mac->set_tx_continuous_wave(request->req.cw_tx_mode.timeout); break; } case MLME_TXCW_1: { - confirmation.req_type = mlmeRequest->type; + confirmation.req_type = request->type; params->flags.bits.mlme_req = 1; - status = _lora_mac->SetTxContinuousWave1(mlmeRequest->req.cw_tx_mode.timeout, - mlmeRequest->req.cw_tx_mode.frequency, - mlmeRequest->req.cw_tx_mode.power); + 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: diff --git a/features/lorawan/lorastack/mac/LoRaMacMlme.h b/features/lorawan/lorastack/mac/LoRaMacMlme.h index deb73f75f2..2be3db0b71 100644 --- a/features/lorawan/lorastack/mac/LoRaMacMlme.h +++ b/features/lorawan/lorastack/mac/LoRaMacMlme.h @@ -66,13 +66,13 @@ public: * to the central MAC control. It also modifies or uses protocol information * provided in the MAC protocol data structure. * - * @param mlmeRequest pointer to MLME request 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 *mlmeRequest, loramac_protocol_params *params); + lorawan_status_t set_request(loramac_mlme_req_t *request, loramac_protocol_params *params); /** Grants access to MLME confirmation data * diff --git a/features/lorawan/system/lorawan_data_structures.h b/features/lorawan/system/lorawan_data_structures.h index 96f48543e4..10fa5995fc 100644 --- a/features/lorawan/system/lorawan_data_structures.h +++ b/features/lorawan/system/lorawan_data_structures.h @@ -368,7 +368,7 @@ typedef struct multicast_params_s { /*! * A reference pointer to the next multicast channel parameters in the list. */ - struct multicast_params_s *Next; + struct multicast_params_s *next; } multicast_params_t; /*! From 90c02f284328064385775352800c50ac29f3efcf Mon Sep 17 00:00:00 2001 From: Kimmo Vaisanen Date: Mon, 12 Feb 2018 09:51:12 +0200 Subject: [PATCH 22/23] Check correct return value mib_get_request() returns lorawan_status_t value so comparing return value to boolean is incorrect. --- features/lorawan/LoRaWANStack.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/lorawan/LoRaWANStack.cpp b/features/lorawan/LoRaWANStack.cpp index 9b176368cf..418322ed14 100644 --- a/features/lorawan/LoRaWANStack.cpp +++ b/features/lorawan/LoRaWANStack.cpp @@ -467,7 +467,7 @@ lorawan_status_t LoRaWANStack::set_channel_data_rate(uint8_t data_rate) loramac_mib_req_confirm_t mib_params; mib_params.type = MIB_ADR; - if (mib_get_request(&mib_params) == true) { + if (mib_get_request(&mib_params) != LORAWAN_STATUS_OK) { tr_error("Cannot set data rate. Please turn off ADR first."); return LORAWAN_STATUS_PARAMETER_INVALID; } From d7c22a6b09be2ca4ffffae99f3f6a625ddc6c4f3 Mon Sep 17 00:00:00 2001 From: Hasnain Virk Date: Mon, 12 Feb 2018 16:10:37 +0200 Subject: [PATCH 23/23] A few Cosmetics & methods for mask manipulation LoRaMacChannelPlan class provides APIs which are not usable for PHY layer implementations who do not support custom channel plans. So we had some code in APIs which was explicitely using magic numbers for the channel mask. Although it turned out to be not a bug as a layer down we were checking for custom channel support. However, we now check for custom channel support before going deep into PHY layer that will make the code run faster and we have done some cosmetics to the code for readability. Channel mask is manipulated with inline methods --- .../lorastack/mac/LoRaMacChannelPlan.cpp | 73 ++++--- features/lorawan/lorastack/mac/LoRaMacMib.cpp | 4 +- features/lorawan/lorastack/phy/LoRaPHY.cpp | 180 ++++++++---------- features/lorawan/lorastack/phy/LoRaPHY.h | 54 ++++-- .../lorawan/lorastack/phy/LoRaPHYAS923.cpp | 19 +- features/lorawan/lorastack/phy/LoRaPHYAS923.h | 6 +- .../lorawan/lorastack/phy/LoRaPHYAU915.cpp | 51 +++-- features/lorawan/lorastack/phy/LoRaPHYAU915.h | 12 +- .../lorawan/lorastack/phy/LoRaPHYCN470.cpp | 26 +-- features/lorawan/lorastack/phy/LoRaPHYCN470.h | 10 +- .../lorawan/lorastack/phy/LoRaPHYCN779.cpp | 10 +- features/lorawan/lorastack/phy/LoRaPHYCN779.h | 10 +- .../lorawan/lorastack/phy/LoRaPHYEU433.cpp | 10 +- features/lorawan/lorastack/phy/LoRaPHYEU433.h | 10 +- .../lorawan/lorastack/phy/LoRaPHYEU868.cpp | 10 +- features/lorawan/lorastack/phy/LoRaPHYEU868.h | 8 +- .../lorawan/lorastack/phy/LoRaPHYIN865.cpp | 10 +- features/lorawan/lorastack/phy/LoRaPHYIN865.h | 11 +- .../lorawan/lorastack/phy/LoRaPHYKR920.cpp | 28 +-- features/lorawan/lorastack/phy/LoRaPHYKR920.h | 10 +- .../lorawan/lorastack/phy/LoRaPHYUS915.cpp | 75 ++++---- features/lorawan/lorastack/phy/LoRaPHYUS915.h | 14 +- .../lorastack/phy/LoRaPHYUS915Hybrid.cpp | 95 +++++---- .../lorastack/phy/LoRaPHYUS915Hybrid.h | 12 +- features/lorawan/lorastack/phy/lora_phy_ds.h | 19 +- .../lorawan/system/lorawan_data_structures.h | 19 +- 26 files changed, 413 insertions(+), 373 deletions(-) diff --git a/features/lorawan/lorastack/mac/LoRaMacChannelPlan.cpp b/features/lorawan/lorastack/mac/LoRaMacChannelPlan.cpp index aa36de1388..584207de44 100644 --- a/features/lorawan/lorastack/mac/LoRaMacChannelPlan.cpp +++ b/features/lorawan/lorastack/mac/LoRaMacChannelPlan.cpp @@ -48,6 +48,14 @@ lorawan_status_t LoRaMacChannelPlan::set_plan(const lorawan_channelplan_t& plan) phy_param_t phy_param; uint8_t max_num_channels; + // Check if the PHY layer supports custom channel plans or not. + get_phy.attribute = PHY_CUSTOM_CHANNEL_PLAN_SUPPORT; + phy_param = _lora_phy->get_phy_params(&get_phy); + + if (!phy_param.value) { + return LORAWAN_STATUS_SERVICE_UNKNOWN; + } + // Check first how many channels the selected PHY layer supports get_phy.attribute = PHY_MAX_NB_CHANNELS; phy_param = _lora_phy->get_phy_params(&get_phy); @@ -91,18 +99,26 @@ lorawan_status_t LoRaMacChannelPlan::get_plan(lorawan_channelplan_t& plan, get_phy_params_t get_phy; phy_param_t phy_param; uint8_t max_num_channels; - uint16_t *channel_masks; + uint16_t *channel_mask; uint8_t count = 0; + // Check if the PHY layer supports custom channel plans or not. + get_phy.attribute = PHY_CUSTOM_CHANNEL_PLAN_SUPPORT; + phy_param = _lora_phy->get_phy_params(&get_phy); + + if (!phy_param.value) { + return LORAWAN_STATUS_SERVICE_UNKNOWN; + } + // Check first how many channels the selected PHY layer supports get_phy.attribute = PHY_MAX_NB_CHANNELS; phy_param = _lora_phy->get_phy_params(&get_phy); max_num_channels = (uint8_t) phy_param.value; // Now check the Default channel mask - get_phy.attribute = PHY_CHANNELS_MASK; + get_phy.attribute = PHY_CHANNEL_MASK; phy_param = _lora_phy->get_phy_params(&get_phy); - channel_masks = phy_param.channel_mask; + channel_mask = phy_param.channel_mask; // Request Mib to get channels memset(&mib_confirm, 0, sizeof(mib_confirm)); @@ -116,7 +132,7 @@ lorawan_status_t LoRaMacChannelPlan::get_plan(lorawan_channelplan_t& plan, for (uint8_t i = 0; i < max_num_channels; i++) { // skip the channels which are not enabled - if ((channel_masks[0] & (1U << i)) == 0) { + if (_lora_phy->mask_bit_test(channel_mask, i) == 0) { continue; } @@ -143,8 +159,16 @@ lorawan_status_t LoRaMacChannelPlan::remove_plan() get_phy_params_t get_phy; phy_param_t phy_param; uint8_t max_num_channels; - uint16_t *channel_masks; - uint16_t *default_channel_masks; + uint16_t *channel_mask; + uint16_t *default_channel_mask; + + // Check if the PHY layer supports custom channel plans or not. + get_phy.attribute = PHY_CUSTOM_CHANNEL_PLAN_SUPPORT; + phy_param = _lora_phy->get_phy_params(&get_phy); + + if (!phy_param.value) { + return LORAWAN_STATUS_SERVICE_UNKNOWN; + } // Check first how many channels the selected PHY layer supports get_phy.attribute = PHY_MAX_NB_CHANNELS; @@ -152,23 +176,23 @@ lorawan_status_t LoRaMacChannelPlan::remove_plan() max_num_channels = (uint8_t) phy_param.value; // Now check the channel mask for enabled channels - get_phy.attribute = PHY_CHANNELS_MASK; + get_phy.attribute = PHY_CHANNEL_MASK; phy_param = _lora_phy->get_phy_params(&get_phy); - channel_masks = phy_param.channel_mask; + channel_mask = phy_param.channel_mask; // Now check the channel mask for default channels - get_phy.attribute = PHY_CHANNELS_DEFAULT_MASK; + get_phy.attribute = PHY_DEFAULT_CHANNEL_MASK; phy_param = _lora_phy->get_phy_params(&get_phy); - default_channel_masks = phy_param.channel_mask; + default_channel_mask = phy_param.channel_mask; for (uint8_t i = 0; i < max_num_channels; i++) { // skip any default channels - if ((default_channel_masks[0] & (1U<mask_bit_test(default_channel_mask, i) != 0) { continue; } // skip any channels which are not currently enabled - if ((channel_masks[0] & (1U<mask_bit_test(channel_mask, i) == 0) { continue; } @@ -187,7 +211,14 @@ lorawan_status_t LoRaMacChannelPlan::remove_single_channel(uint8_t channel_id) get_phy_params_t get_phy; phy_param_t phy_param; uint8_t max_num_channels; - uint16_t *channel_masks; + + // Check if the PHY layer supports custom channel plans or not. + get_phy.attribute = PHY_CUSTOM_CHANNEL_PLAN_SUPPORT; + phy_param = _lora_phy->get_phy_params(&get_phy); + + if (!phy_param.value) { + return LORAWAN_STATUS_SERVICE_UNKNOWN; + } // Check first how many channels the selected PHY layer supports get_phy.attribute = PHY_MAX_NB_CHANNELS; @@ -201,21 +232,7 @@ lorawan_status_t LoRaMacChannelPlan::remove_single_channel(uint8_t channel_id) return LORAWAN_STATUS_PARAMETER_INVALID; } - // Now check the Default channel mask - get_phy.attribute = PHY_CHANNELS_DEFAULT_MASK; - phy_param = _lora_phy->get_phy_params(&get_phy); - channel_masks = phy_param.channel_mask; - - // check if the channel ID give belongs to a default channel - // Mostly the default channels are in the first mask if the region - // have multiple channel masks for various sub-bands. So we check the first - // mask only and return an error code if user sent a default channel id - if ((channel_masks[0] & (1U << channel_id)) != 0) { - return LORAWAN_STATUS_PARAMETER_INVALID; - } - - if(_lora_phy->remove_channel(channel_id) == false) - { + if (_lora_phy->remove_channel(channel_id) == false) { return LORAWAN_STATUS_PARAMETER_INVALID; } diff --git a/features/lorawan/lorastack/mac/LoRaMacMib.cpp b/features/lorawan/lorastack/mac/LoRaMacMib.cpp index 981dd141d8..39172ef569 100644 --- a/features/lorawan/lorastack/mac/LoRaMacMib.cpp +++ b/features/lorawan/lorastack/mac/LoRaMacMib.cpp @@ -355,7 +355,7 @@ lorawan_status_t LoRaMacMib::get_request(loramac_mib_req_confirm_t *mibGet, } case MIB_CHANNELS_DEFAULT_MASK: { - get_phy.attribute = PHY_CHANNELS_DEFAULT_MASK; + get_phy.attribute = PHY_DEFAULT_CHANNEL_MASK; phy_param = _lora_phy->get_phy_params( &get_phy ); mibGet->param.default_channel_mask = phy_param.channel_mask; @@ -363,7 +363,7 @@ lorawan_status_t LoRaMacMib::get_request(loramac_mib_req_confirm_t *mibGet, } case MIB_CHANNELS_MASK: { - get_phy.attribute = PHY_CHANNELS_MASK; + get_phy.attribute = PHY_CHANNEL_MASK; phy_param = _lora_phy->get_phy_params( &get_phy ); mibGet->param.channel_mask = phy_param.channel_mask; diff --git a/features/lorawan/lorastack/phy/LoRaPHY.cpp b/features/lorawan/lorastack/phy/LoRaPHY.cpp index c563daba2f..4b1c502a45 100644 --- a/features/lorawan/lorastack/phy/LoRaPHY.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHY.cpp @@ -151,23 +151,21 @@ int32_t LoRaPHY::get_random(int32_t min, int32_t max) return (int32_t) rand() % (max - min + 1) + min; } -bool LoRaPHY::verify_channel_DR(uint8_t nbChannels, uint16_t* channelsMask, - int8_t dr, int8_t minDr, int8_t maxDr, +bool LoRaPHY::verify_channel_DR(uint8_t nb_channels, uint16_t* channel_mask, + int8_t dr, int8_t min_dr, int8_t max_dr, channel_params_t* channels) { - if (val_in_range(dr, minDr, maxDr) == 0) { + if (val_in_range(dr, min_dr, max_dr) == 0) { return false; } - for (uint8_t i = 0, k = 0; i < nbChannels; i += 16, k++) { - for( uint8_t j = 0; j < 16; j++ ) { - if( ((channelsMask[k] & (1 << j)) != 0)) { - // Check datarate validity for enabled channels - if (val_in_range(dr, (channels[i + j].dr_range.fields.min & 0x0F), - (channels[i + j].dr_range.fields.max & 0x0F)) == 1 ) { - // At least 1 channel has been found we can return OK. - return true; - } + for (uint8_t i; i < phy_params.max_channel_cnt; i++) { + if (mask_bit_test(channel_mask, i)) { + // Check datarate validity for enabled channels + if (val_in_range(dr, (channels[i].dr_range.fields.min & 0x0F), + (channels[i].dr_range.fields.max & 0x0F))) { + // At least 1 channel has been found we can return OK. + return true; } } } @@ -184,17 +182,17 @@ uint8_t LoRaPHY::val_in_range( int8_t value, int8_t min, int8_t max ) return 0; } -bool LoRaPHY::disable_channel(uint16_t* channelsMask, uint8_t id, - uint8_t maxChannels) +bool LoRaPHY::disable_channel(uint16_t* channel_mask, uint8_t id, + uint8_t max_channels_num) { uint8_t index = id / 16; - if ((index > phy_params.channels.mask_list_size) || (id >= maxChannels)) { + if ((index > phy_params.channels.mask_size) || (id >= max_channels_num)) { return false; } // Deactivate channel - channelsMask[index] &= ~(1 << (id % 16)); + mask_bit_clear(channel_mask, id); return true; } @@ -204,7 +202,7 @@ uint8_t LoRaPHY::count_bits(uint16_t mask, uint8_t nbBits) uint8_t nbActiveBits = 0; for(uint8_t j = 0; j < nbBits; j++) { - if ((mask & (1 << j)) == (1 << j)) { + if (mask_bit_test(&mask, j)) { nbActiveBits++; } } @@ -212,26 +210,27 @@ uint8_t LoRaPHY::count_bits(uint16_t mask, uint8_t nbBits) return nbActiveBits; } -uint8_t LoRaPHY::num_active_channels( uint16_t* channelsMask, uint8_t startIdx, uint8_t stopIdx ) +uint8_t LoRaPHY::num_active_channels(uint16_t* channel_mask, uint8_t start_idx, + uint8_t stop_idx) { - uint8_t nbChannels = 0; + uint8_t nb_channels = 0; - if (channelsMask == NULL) { + if (channel_mask == NULL) { return 0; } - for (uint8_t i = startIdx; i < stopIdx; i++) { - nbChannels += count_bits(channelsMask[i], 16); + for (uint8_t i = start_idx; i < stop_idx; i++) { + nb_channels += count_bits(channel_mask[i], 16); } - return nbChannels; + return nb_channels; } -void LoRaPHY::copy_channel_mask(uint16_t* channelsMaskDest, uint16_t* channelsMaskSrc, uint8_t len) +void LoRaPHY::copy_channel_mask(uint16_t* dest_mask, uint16_t* src_mask, uint8_t len) { - if ((channelsMaskDest != NULL) && (channelsMaskSrc != NULL)) { + if ((dest_mask != NULL) && (src_mask != NULL)) { for( uint8_t i = 0; i < len; i++ ) { - channelsMaskDest[i] = channelsMaskSrc[i]; + dest_mask[i] = src_mask[i]; } } } @@ -443,36 +442,31 @@ uint8_t LoRaPHY::get_bandwidth(uint8_t dr) } uint8_t LoRaPHY::enabled_channel_count(bool joined, uint8_t datarate, - uint16_t *mask_list, - uint8_t mask_list_size, + const uint16_t *channel_mask, uint8_t *channel_indices, uint8_t *delayTx) { uint8_t count = 0; uint8_t delay_transmission = 0; - for (uint8_t i = 0, k = 0; i < phy_params.max_channel_cnt && k < mask_list_size; - i += CHANNELS_IN_MASK, k++) { + for (uint8_t i = 0; i < phy_params.max_channel_cnt; i++) { + if (mask_bit_test(channel_mask, i)) { - for (uint8_t j = 0; j < CHANNELS_IN_MASK; j++) { - - if ((mask_list[k] & (1 << j)) != 0) { - if (val_in_range(datarate, phy_params.channels.channel_list[i + j].dr_range.fields.min, - phy_params.channels.channel_list[i + j].dr_range.fields.max ) == 0) { - // data rate range invalid for this channel - continue; - } - - band_t *band_table = (band_t *) phy_params.bands.table; - if (band_table[phy_params.channels.channel_list[i + j].band].off_time > 0) { - // Check if the band is available for transmission - delay_transmission++; - continue; - } - - // otherwise count the channel as enabled - channel_indices[count++] = i + j; + if (val_in_range(datarate, phy_params.channels.channel_list[i].dr_range.fields.min, + phy_params.channels.channel_list[i].dr_range.fields.max ) == 0) { + // data rate range invalid for this channel + continue; } + + band_t *band_table = (band_t *) phy_params.bands.table; + if (band_table[phy_params.channels.channel_list[i].band].off_time > 0) { + // Check if the band is available for transmission + delay_transmission++; + continue; + } + + // otherwise count the channel as enabled + channel_indices[count++] = i; } } @@ -526,8 +520,7 @@ phy_param_t LoRaPHY::get_phy_params(get_phy_params_t* getPhy) break; } case PHY_MAX_PAYLOAD_REPEATER: { - uint8_t *payload_table = - (uint8_t *) phy_params.payloads_with_repeater.table; + uint8_t *payload_table = (uint8_t *) phy_params.payloads_with_repeater.table; phyParam.value = payload_table[getPhy->datarate]; break; } @@ -578,12 +571,12 @@ phy_param_t LoRaPHY::get_phy_params(get_phy_params_t* getPhy) phyParam.value = phy_params.rx_window2_datarate; break; } - case PHY_CHANNELS_MASK: { - phyParam.channel_mask = phy_params.channels.mask_list; + case PHY_CHANNEL_MASK: { + phyParam.channel_mask = phy_params.channels.mask; break; } - case PHY_CHANNELS_DEFAULT_MASK: { - phyParam.channel_mask = phy_params.channels.default_mask_list; + case PHY_DEFAULT_CHANNEL_MASK: { + phyParam.channel_mask = phy_params.channels.default_mask; break; } case PHY_MAX_NB_CHANNELS: { @@ -594,6 +587,12 @@ phy_param_t LoRaPHY::get_phy_params(get_phy_params_t* getPhy) phyParam.channel_params = phy_params.channels.channel_list; break; } + case PHY_CUSTOM_CHANNEL_PLAN_SUPPORT: + // 0 if custom channel plans are not supported (in LoRaWAN terms + // the regions who do not support custom channels are called as + // regions with dynamic channel plans) + phyParam.value = (uint32_t) phy_params.custom_channelplans_supported; + break; case PHY_DEF_UPLINK_DWELL_TIME: { phyParam.value = phy_params.ul_dwell_time_setting; break; @@ -626,8 +625,8 @@ phy_param_t LoRaPHY::get_phy_params(get_phy_params_t* getPhy) void LoRaPHY::restore_default_channels() { // Restore channels default mask - for (uint8_t i=0; i < phy_params.channels.mask_list_size; i++) { - phy_params.channels.mask_list[i] |= phy_params.channels.default_mask_list[i]; + for (uint8_t i=0; i < phy_params.channels.mask_size; i++) { + phy_params.channels.mask[i] |= phy_params.channels.default_mask[i]; } } @@ -768,7 +767,6 @@ bool LoRaPHY::get_next_ADR(bool restore_channel_mask, int8_t& dr_out, set_adr_ack_bit = true; tx_power_out = phy_params.max_tx_power; - if (adr_ack_cnt >= ack_limit_plus_delay) { if ((adr_ack_cnt % phy_params.adr_ack_delay) == 1) { // Decrease the datarate @@ -943,7 +941,7 @@ uint8_t LoRaPHY::link_ADR_request(adr_req_params_t* link_adr_req, // a channel mask list size of unity here as we know that all // the PHY layer implementations who have more than 16 channels, i.e., // have channel mask list size more than unity, override this method. - uint16_t temp_channel_masks[1] = {0}; + uint16_t temp_channel_mask[1] = {0}; verify_adr_params_t verify_params; @@ -963,10 +961,10 @@ uint8_t LoRaPHY::link_ADR_request(adr_req_params_t* link_adr_req, status = 0x07; // Setup temporary channels mask - temp_channel_masks[0] = adr_settings.channel_mask; + temp_channel_mask[0] = adr_settings.channel_mask; // Verify channels mask - if (adr_settings.ch_mask_ctrl == 0 && temp_channel_masks[0] == 0) { + if (adr_settings.ch_mask_ctrl == 0 && temp_channel_mask[0] == 0) { status &= 0xFE; // Channel mask KO } @@ -979,7 +977,7 @@ uint8_t LoRaPHY::link_ADR_request(adr_req_params_t* link_adr_req, // turn on all channels if channel mask control is 6 if (adr_settings.ch_mask_ctrl == 6) { if (phy_params.channels.channel_list[i].frequency != 0) { - temp_channel_masks[0] |= 1 << i; + mask_bit_set(temp_channel_mask, i); } continue; @@ -987,8 +985,8 @@ uint8_t LoRaPHY::link_ADR_request(adr_req_params_t* link_adr_req, // if channel mask control is 0, we test the bits and // frequencies and change the status if we find a discrepancy - if (((temp_channel_masks[0] & (1 << i)) != 0) - && (phy_params.channels.channel_list[i].frequency == 0)) { + if ((mask_bit_test(temp_channel_mask, i)) && + (phy_params.channels.channel_list[i].frequency == 0)) { // Trying to enable an undefined channel status &= 0xFE; // Channel mask KO } @@ -1011,7 +1009,7 @@ uint8_t LoRaPHY::link_ADR_request(adr_req_params_t* link_adr_req, verify_params.nb_rep = adr_settings.nb_rep; - verify_params.channel_mask = temp_channel_masks; + verify_params.channel_mask = temp_channel_mask; // Verify the parameters and update, if necessary status = verify_link_ADR_req(&verify_params, &adr_settings.datarate, @@ -1020,12 +1018,12 @@ uint8_t LoRaPHY::link_ADR_request(adr_req_params_t* link_adr_req, // Update channelsMask if everything is correct if (status == 0x07) { // Set the channels mask to a default value - memset(phy_params.channels.mask_list, 0, - sizeof(uint16_t)*phy_params.channels.mask_list_size); + memset(phy_params.channels.mask, 0, + sizeof(uint16_t)*phy_params.channels.mask_size); // Update the channels mask - copy_channel_mask(phy_params.channels.mask_list, temp_channel_masks, - phy_params.channels.mask_list_size); + copy_channel_mask(phy_params.channels.mask, temp_channel_mask, + phy_params.channels.mask_size); } // Update status variables @@ -1108,8 +1106,7 @@ uint8_t LoRaPHY::dl_channel_request(dl_channel_req_params_t* params) // Apply Rx1 frequency, if the status is OK if (status == 0x03) { - phy_params.channels.channel_list[params->channel_id].rx1_frequency - = params->rx1_frequency; + phy_params.channels.channel_list[params->channel_id].rx1_frequency = params->rx1_frequency; } return status; @@ -1196,8 +1193,7 @@ void LoRaPHY::calculate_backoff(backoff_params_t* calc_backoff) band_table[band_idx].off_time = 0; } else { // Apply band time-off. - band_table[band_idx].off_time = calc_backoff->tx_toa * duty_cycle - - calc_backoff->tx_toa; + band_table[band_idx].off_time = calc_backoff->tx_toa * duty_cycle - calc_backoff->tx_toa; } } @@ -1220,13 +1216,13 @@ bool LoRaPHY::set_next_channel(channel_selection_params_t* params, lorawan_time_t next_tx_delay = 0; band_t *band_table = (band_t *) phy_params.bands.table; - if (num_active_channels(phy_params.channels.mask_list, 0, - phy_params.channels.mask_list_size) == 0) { + if (num_active_channels(phy_params.channels.mask, 0, + phy_params.channels.mask_size) == 0) { // Reactivate default channels - copy_channel_mask(phy_params.channels.mask_list, - phy_params.channels.default_mask_list, - phy_params.channels.mask_list_size); + copy_channel_mask(phy_params.channels.mask, + phy_params.channels.default_mask, + phy_params.channels.mask_size); } if (params->aggregate_timeoff @@ -1241,8 +1237,7 @@ bool LoRaPHY::set_next_channel(channel_selection_params_t* params, // Search how many channels are enabled channel_count = enabled_channel_count(params->joined, params->current_datarate, - phy_params.channels.mask_list, - phy_params.channels.mask_list_size, + phy_params.channels.mask, enabled_channels, &delay_tx); } else { delay_tx++; @@ -1264,9 +1259,9 @@ bool LoRaPHY::set_next_channel(channel_selection_params_t* params, } // Datarate not supported by any channel, restore defaults - copy_channel_mask(phy_params.channels.mask_list, - phy_params.channels.default_mask_list, - phy_params.channels.mask_list_size); + copy_channel_mask(phy_params.channels.mask, + phy_params.channels.default_mask, + phy_params.channels.mask_size); *time = 0; return false; } @@ -1338,38 +1333,29 @@ lorawan_status_t LoRaPHY::add_channel(channel_params_t* new_channel, uint8_t id) return LORAWAN_STATUS_FREQUENCY_INVALID; } - memcpy(&(phy_params.channels.channel_list[id]), new_channel, - sizeof(phy_params.channels.channel_list[id])); + memcpy(&(phy_params.channels.channel_list[id]), new_channel, sizeof(channel_params_t)); phy_params.channels.channel_list[id].band = new_channel->band; - // if there are multiple channel masks, i.e., there are more than 16 channels - // defined by the PHY layer, we search the channel index in all masks and - // set the appropriate bit in the appropriate mask - for (uint8_t i = 0; i < phy_params.max_channel_cnt; i ++) { - if (i == id) { - phy_params.channels.mask_list[i/16] |= (1 << (i%16)); - } - } + mask_bit_set(phy_params.channels.mask, id); return LORAWAN_STATUS_OK; } bool LoRaPHY::remove_channel(uint8_t channel_id) { - if (!phy_params.custom_channelplans_supported) { + // upper layers are checking if the custom channel planning is supported or + // not. So we don't need to worry about that + if (mask_bit_test(phy_params.channels.default_mask, channel_id)) { return false; } - if (channel_id < phy_params.default_channel_cnt) { - return false; - } // Remove the channel from the list of channels const channel_params_t empty_channel = { 0, 0, { 0 }, 0 }; phy_params.channels.channel_list[channel_id] = empty_channel; - return disable_channel(phy_params.channels.mask_list, channel_id, + return disable_channel(phy_params.channels.mask, channel_id, phy_params.max_channel_cnt); } diff --git a/features/lorawan/lorastack/phy/LoRaPHY.h b/features/lorawan/lorastack/phy/LoRaPHY.h index 61bb1f5828..df8f898e7d 100644 --- a/features/lorawan/lorastack/phy/LoRaPHY.h +++ b/features/lorawan/lorastack/phy/LoRaPHY.h @@ -112,6 +112,27 @@ public: */ void calculate_backoff(backoff_params_t* backoff_params); + /** + * Tests if a channel is on or off in the channel mask + */ + inline bool mask_bit_test(const uint16_t *mask, unsigned bit) { + return mask[bit/16] & (1U << (bit % 16)); + } + + /** + * Tests if a channel is on or off in the channel mask + */ + inline void mask_bit_set(uint16_t *mask, unsigned bit) { + mask[bit/16] |= (1U << (bit % 16)); + } + + /** + * Tests if a channel is on or off in the channel mask + */ + inline void mask_bit_clear(uint16_t *mask, unsigned bit) { + mask[bit/16] &= ~(1U << (bit % 16)); + } + /** Entertain a new channel request MAC command. * * MAC command subsystem processes the new channel request coming form @@ -407,66 +428,68 @@ protected: * Verifies, if a datarate is available on an active channel. */ bool verify_channel_DR(uint8_t nbChannels, uint16_t* channelsMask, int8_t dr, - int8_t minDr, int8_t maxDr, channel_params_t* channels ); + int8_t minDr, int8_t maxDr, channel_params_t* channels); /** * Disables a channel in a given channels mask. */ - bool disable_channel( uint16_t* channelsMask, uint8_t id, uint8_t maxChannels ); + bool disable_channel(uint16_t* channel_mask, uint8_t id, uint8_t max_channels); /** * Counts number of bits on in a given mask */ - uint8_t count_bits(uint16_t mask, uint8_t nbBits); + uint8_t count_bits(uint16_t mask, uint8_t nb_bits); /** * Counts the number of active channels in a given channels mask. */ - uint8_t num_active_channels(uint16_t* channelsMask, uint8_t startIdx, - uint8_t stopIdx); + uint8_t num_active_channels(uint16_t* channel_mask, uint8_t start_idx, + uint8_t stop_idx); /** * Copy channel masks. */ - void copy_channel_mask(uint16_t* channelsMaskDest, uint16_t* channelsMaskSrc, - uint8_t len ); + void copy_channel_mask(uint16_t* dest_mask, uint16_t* src_mask, uint8_t len); /** * Updates the time-offs of the bands. */ lorawan_time_t update_band_timeoff(bool joined, bool dutyCycle, band_t* bands, - uint8_t nbBands); + uint8_t nb_bands); /** * Parses the parameter of an LinkAdrRequest. */ - uint8_t parse_link_ADR_req(uint8_t* payload, link_adr_params_t* parseLinkAdr ); + uint8_t parse_link_ADR_req(uint8_t* payload, link_adr_params_t* adr_params); /** * Verifies and updates the datarate, the TX power and the number of repetitions * of a LinkAdrRequest. */ - uint8_t verify_link_ADR_req( verify_adr_params_t* verifyParams, int8_t* dr, int8_t* txPow, uint8_t* nbRep ); + uint8_t verify_link_ADR_req(verify_adr_params_t* verify_params, int8_t* dr, + int8_t* tx_pow, uint8_t* nb_rep); /** * Computes the symbol time for LoRa modulation. */ - double compute_symb_timeout_lora( uint8_t phyDr, uint32_t bandwidth ); + double compute_symb_timeout_lora(uint8_t phy_dr, uint32_t bandwidth ); /** * Computes the symbol time for FSK modulation. */ - double compute_symb_timeout_fsk( uint8_t phyDr ); + double compute_symb_timeout_fsk(uint8_t phy_dr); /** * Computes the RX window timeout and the RX window offset. */ - void get_rx_window_params( double tSymbol, uint8_t minRxSymbols, uint32_t rxError, uint32_t wakeUpTime, uint32_t* windowTimeout, int32_t* windowOffset ); + void get_rx_window_params(double t_symbol, uint8_t min_rx_symbols, + uint32_t rx_error, uint32_t wakeup_time, + uint32_t* window_timeout, int32_t* window_offset); /** * Computes the txPower, based on the max EIRP and the antenna gain. */ - int8_t compute_tx_power( int8_t txPowerIndex, float maxEirp, float antennaGain ); + int8_t compute_tx_power(int8_t txPowerIndex, float maxEirp, float antennaGain); /** * Provides a random number in the range provided. @@ -484,8 +507,7 @@ protected: uint8_t get_bandwidth(uint8_t dr_index); uint8_t enabled_channel_count(bool joined, uint8_t datarate, - uint16_t *mask_list, uint8_t mask_list_size, - uint8_t* enabledChannels, + const uint16_t *mask, uint8_t* enabledChannels, uint8_t* delayTx); }; diff --git a/features/lorawan/lorastack/phy/LoRaPHYAS923.cpp b/features/lorawan/lorastack/phy/LoRaPHYAS923.cpp index 2c00a0a3f9..5a10bca24b 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYAS923.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYAS923.cpp @@ -252,17 +252,17 @@ LoRaPHYAS923::LoRaPHYAS923(LoRaWANTimeHandler &lora_time) channels[1] = AS923_LC2; // Initialize the default channel mask - default_channel_masks[0] = LC(1) + LC(2); + default_channel_mask[0] = LC(1) + LC(2); // Update the channel mask list - copy_channel_mask(channel_masks, default_channel_masks, AS923_CHANNELS_MASK_SIZE); + copy_channel_mask(channel_mask, default_channel_mask, AS923_CHANNEL_MASK_SIZE); // set default channels phy_params.channels.channel_list = channels; phy_params.channels.channel_list_size = AS923_MAX_NB_CHANNELS; - phy_params.channels.mask_list = channel_masks; - phy_params.channels.default_mask_list = default_channel_masks; - phy_params.channels.mask_list_size = AS923_CHANNELS_MASK_SIZE; + phy_params.channels.mask = channel_mask; + phy_params.channels.default_mask = default_channel_mask; + phy_params.channels.mask_size = AS923_CHANNEL_MASK_SIZE; // set bands for AS923 spectrum phy_params.bands.table = (void *) bands; @@ -344,9 +344,9 @@ bool LoRaPHYAS923::set_next_channel(channel_selection_params_t* next_channel_pra uint8_t enabled_channels[AS923_MAX_NB_CHANNELS] = { 0 }; lorawan_time_t next_tx_delay = 0; - if (num_active_channels(channel_masks, 0, 1) == 0) { + if (num_active_channels(channel_mask, 0, 1) == 0) { // Reactivate default channels - channel_masks[0] |= LC(1) + LC(2); + channel_mask[0] |= LC(1) + LC(2); } if (next_channel_prams->aggregate_timeoff <= _lora_time.get_elapsed_time(next_channel_prams->last_aggregate_tx_time)) { @@ -361,8 +361,7 @@ bool LoRaPHYAS923::set_next_channel(channel_selection_params_t* next_channel_pra // Search how many channels are enabled nb_enabled_channels = enabled_channel_count(next_channel_prams->joined, next_channel_prams->current_datarate, - channel_masks, - AS923_CHANNELS_MASK_SIZE, + channel_mask, enabled_channels, &delay_tx); } else { delay_tx++; @@ -402,7 +401,7 @@ bool LoRaPHYAS923::set_next_channel(channel_selection_params_t* next_channel_pra } // Datarate not supported by any channel, restore defaults - channel_masks[0] |= LC( 1 ) + LC( 2 ); + channel_mask[0] |= LC( 1 ) + LC( 2 ); *time = 0; return false; } diff --git a/features/lorawan/lorastack/phy/LoRaPHYAS923.h b/features/lorawan/lorastack/phy/LoRaPHYAS923.h index c4be485950..17f943dbce 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYAS923.h +++ b/features/lorawan/lorastack/phy/LoRaPHYAS923.h @@ -44,7 +44,7 @@ */ #define AS923_MAX_NB_BANDS 1 -#define AS923_CHANNELS_MASK_SIZE 1 +#define AS923_CHANNEL_MASK_SIZE 1 class LoRaPHYAS923 : public LoRaPHY { @@ -64,8 +64,8 @@ public: private: channel_params_t channels[AS923_MAX_NB_CHANNELS]; band_t bands[AS923_MAX_NB_BANDS]; - uint16_t channel_masks[AS923_CHANNELS_MASK_SIZE]; - uint16_t default_channel_masks[AS923_CHANNELS_MASK_SIZE]; + uint16_t channel_mask[AS923_CHANNEL_MASK_SIZE]; + uint16_t default_channel_mask[AS923_CHANNEL_MASK_SIZE]; }; #endif /* MBED_OS_LORAPHY_AS923_H_ */ diff --git a/features/lorawan/lorastack/phy/LoRaPHYAU915.cpp b/features/lorawan/lorastack/phy/LoRaPHYAU915.cpp index 1b3d50da09..c1e1ecd2f9 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYAU915.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYAU915.cpp @@ -245,23 +245,23 @@ LoRaPHYAU915::LoRaPHYAU915(LoRaWANTimeHandler &lora_time) // All channels are default channels here // Join request needs to alternate between 125 KHz and 500 KHz channels // randomly. - default_channel_masks[0] = 0xFFFF; - default_channel_masks[1] = 0xFFFF; - default_channel_masks[2] = 0xFFFF; - default_channel_masks[3] = 0xFFFF; - default_channel_masks[4] = 0x00FF; + default_channel_mask[0] = 0xFFFF; + default_channel_mask[1] = 0xFFFF; + default_channel_mask[2] = 0xFFFF; + default_channel_mask[3] = 0xFFFF; + default_channel_mask[4] = 0x00FF; - memset(channel_masks, 0, sizeof(channel_masks)); - memset(current_channel_masks, 0, sizeof(current_channel_masks)); + memset(channel_mask, 0, sizeof(channel_mask)); + memset(current_channel_mask, 0, sizeof(current_channel_mask)); // Copy channels default mask - copy_channel_mask(channel_masks, default_channel_masks, AU915_CHANNELS_MASK_SIZE); + copy_channel_mask(channel_mask, default_channel_mask, AU915_CHANNEL_MASK_SIZE); // Copy into current channels mask // This mask is used to keep track of the channels which were used in // previous transmissions as the AU915 band doesn't allow concurrent // transmission on the same channel - copy_channel_mask(current_channel_masks, channel_masks, AU915_CHANNELS_MASK_SIZE); + copy_channel_mask(current_channel_mask, channel_mask, AU915_CHANNEL_MASK_SIZE); // set bands for EU868 spectrum phy_params.bands.table = (void *) bands; @@ -417,12 +417,12 @@ uint8_t LoRaPHYAU915::link_ADR_request(adr_req_params_t* params, link_adr_params_t adr_settings; uint8_t next_index = 0; uint8_t bytes_processed = 0; - uint16_t temp_channel_masks[AU915_CHANNELS_MASK_SIZE] = { 0, 0, 0, 0, 0}; + uint16_t temp_channel_masks[AU915_CHANNEL_MASK_SIZE] = { 0, 0, 0, 0, 0}; verify_adr_params_t verify_params; // Initialize local copy of channels mask - copy_channel_mask(temp_channel_masks, channel_masks, AU915_CHANNELS_MASK_SIZE); + copy_channel_mask(temp_channel_masks, channel_mask, AU915_CHANNEL_MASK_SIZE); while (bytes_processed < params->payload_size) { next_index = parse_link_ADR_req(&(params->payload[bytes_processed]), @@ -483,16 +483,16 @@ uint8_t LoRaPHYAU915::link_ADR_request(adr_req_params_t* params, status = verify_link_ADR_req(&verify_params, &adr_settings.datarate, &adr_settings.tx_power, &adr_settings.nb_rep); - // Update channelsMask if everything is correct + // Update cchannel mask if everything is correct if (status == 0x07) { // Copy Mask - copy_channel_mask(channel_masks, temp_channel_masks, AU915_CHANNELS_MASK_SIZE); + copy_channel_mask(channel_mask, temp_channel_masks, AU915_CHANNEL_MASK_SIZE); - current_channel_masks[0] &= channel_masks[0]; - current_channel_masks[1] &= channel_masks[1]; - current_channel_masks[2] &= channel_masks[2]; - current_channel_masks[3] &= channel_masks[3]; - current_channel_masks[4] = channel_masks[4]; + current_channel_mask[0] &= channel_mask[0]; + current_channel_mask[1] &= channel_mask[1]; + current_channel_mask[2] &= channel_mask[2]; + current_channel_mask[3] &= channel_mask[3]; + current_channel_mask[4] = channel_mask[4]; } // Update status variables @@ -544,7 +544,7 @@ int8_t LoRaPHYAU915::get_alternate_DR(uint8_t nb_trials) int8_t datarate = 0; // Re-enable 500 kHz default channels - channel_masks[4] = 0x00FF; + channel_mask[4] = 0x00FF; if ((nb_trials & 0x01) == 0x01) { datarate = DR_6; @@ -565,16 +565,16 @@ bool LoRaPHYAU915::set_next_channel(channel_selection_params_t* next_chan_params lorawan_time_t next_tx_delay = 0; // Count 125kHz channels - if (num_active_channels(current_channel_masks, 0, 4) == 0) { + if (num_active_channels(current_channel_mask, 0, 4) == 0) { // Reactivate 125 kHz default channels - copy_channel_mask(current_channel_masks, channel_masks, 4); + copy_channel_mask(current_channel_mask, channel_mask, 4); } // Check other channels if (next_chan_params->current_datarate >= DR_6) { - if ((current_channel_masks[4] & 0x00FF) == 0) { + if ((current_channel_mask[4] & 0x00FF) == 0) { // fall back to 500 kHz default channels - current_channel_masks[4] = channel_masks[4]; + current_channel_mask[4] = channel_mask[4]; } } @@ -590,8 +590,7 @@ bool LoRaPHYAU915::set_next_channel(channel_selection_params_t* next_chan_params // Search how many channels are enabled nb_enabled_channels = enabled_channel_count(next_chan_params->joined, next_chan_params->current_datarate, - current_channel_masks, - AU915_CHANNELS_MASK_SIZE, + current_channel_mask, enabled_channels, &delay_tx); } else { delay_tx++; @@ -602,7 +601,7 @@ bool LoRaPHYAU915::set_next_channel(channel_selection_params_t* next_chan_params // We found a valid channel *channel = enabled_channels[get_random(0, nb_enabled_channels - 1)]; // Disable the channel in the mask - disable_channel(current_channel_masks, *channel, + disable_channel(current_channel_mask, *channel, AU915_MAX_NB_CHANNELS - 8); *time = 0; diff --git a/features/lorawan/lorastack/phy/LoRaPHYAU915.h b/features/lorawan/lorastack/phy/LoRaPHYAU915.h index 7d30e39d30..5c7c358f61 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYAU915.h +++ b/features/lorawan/lorastack/phy/LoRaPHYAU915.h @@ -46,7 +46,7 @@ */ #define AU915_MAX_NB_BANDS 1 -#define AU915_CHANNELS_MASK_SIZE 5 +#define AU915_CHANNEL_MASK_SIZE 5 class LoRaPHYAU915 : public LoRaPHY{ @@ -89,19 +89,19 @@ private: band_t bands[AU915_MAX_NB_BANDS]; /*! - * LoRaMac channels mask + * LoRaMac channel mask */ - uint16_t channel_masks[AU915_CHANNELS_MASK_SIZE]; + uint16_t channel_mask[AU915_CHANNEL_MASK_SIZE]; /*! - * LoRaMac channels remaining + * Previously used channel mask */ - uint16_t current_channel_masks[AU915_CHANNELS_MASK_SIZE]; + uint16_t current_channel_mask[AU915_CHANNEL_MASK_SIZE]; /*! * LoRaMac channels default mask */ - uint16_t default_channel_masks[AU915_CHANNELS_MASK_SIZE]; + uint16_t default_channel_mask[AU915_CHANNEL_MASK_SIZE]; }; #endif /* MBED_OS_LORAPHY_AU915_H_ */ diff --git a/features/lorawan/lorastack/phy/LoRaPHYCN470.cpp b/features/lorawan/lorastack/phy/LoRaPHYCN470.cpp index eb5d0512b6..68ff3f5525 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYCN470.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYCN470.cpp @@ -219,22 +219,22 @@ LoRaPHYCN470::LoRaPHYCN470(LoRaWANTimeHandler &lora_time) } // Initialize the channels default mask - default_channel_masks[0] = 0xFFFF; - default_channel_masks[1] = 0xFFFF; - default_channel_masks[2] = 0xFFFF; - default_channel_masks[3] = 0xFFFF; - default_channel_masks[4] = 0xFFFF; - default_channel_masks[5] = 0xFFFF; + default_channel_mask[0] = 0xFFFF; + default_channel_mask[1] = 0xFFFF; + default_channel_mask[2] = 0xFFFF; + default_channel_mask[3] = 0xFFFF; + default_channel_mask[4] = 0xFFFF; + default_channel_mask[5] = 0xFFFF; // Update the channels mask - copy_channel_mask(channel_masks, default_channel_masks, CN470_CHANNELS_MASK_SIZE); + copy_channel_mask(channel_mask, default_channel_mask, CN470_CHANNEL_MASK_SIZE); // set default channels phy_params.channels.channel_list = channels; phy_params.channels.channel_list_size = CN470_MAX_NB_CHANNELS; - phy_params.channels.mask_list = channel_masks; - phy_params.channels.default_mask_list = default_channel_masks; - phy_params.channels.mask_list_size = CN470_CHANNELS_MASK_SIZE; + phy_params.channels.mask = channel_mask; + phy_params.channels.default_mask = default_channel_mask; + phy_params.channels.mask_size = CN470_CHANNEL_MASK_SIZE; // set bands for CN470 spectrum phy_params.bands.table = (void *) bands; @@ -398,12 +398,12 @@ uint8_t LoRaPHYCN470::link_ADR_request(adr_req_params_t* params, link_adr_params_t adr_settings; uint8_t next_index = 0; uint8_t bytes_processed = 0; - uint16_t temp_channel_masks[CN470_CHANNELS_MASK_SIZE] = {0, 0, 0, 0, 0, 0}; + uint16_t temp_channel_masks[CN470_CHANNEL_MASK_SIZE] = {0, 0, 0, 0, 0, 0}; verify_adr_params_t verify_params; // Initialize local copy of channels mask - copy_channel_mask(temp_channel_masks, channel_masks, CN470_CHANNELS_MASK_SIZE); + copy_channel_mask(temp_channel_masks, channel_mask, CN470_CHANNEL_MASK_SIZE); while(bytes_processed < params->payload_size) { @@ -467,7 +467,7 @@ uint8_t LoRaPHYCN470::link_ADR_request(adr_req_params_t* params, // Update channelsMask if everything is correct if (status == 0x07) { // Copy Mask - copy_channel_mask(channel_masks, temp_channel_masks, CN470_CHANNELS_MASK_SIZE); + copy_channel_mask(channel_mask, temp_channel_masks, CN470_CHANNEL_MASK_SIZE); } // Update status variables diff --git a/features/lorawan/lorastack/phy/LoRaPHYCN470.h b/features/lorawan/lorastack/phy/LoRaPHYCN470.h index 2ededa893c..846c849acb 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYCN470.h +++ b/features/lorawan/lorastack/phy/LoRaPHYCN470.h @@ -46,7 +46,7 @@ #define CN470_MAX_NB_BANDS 1 -#define CN470_CHANNELS_MASK_SIZE 6 +#define CN470_CHANNEL_MASK_SIZE 6 class LoRaPHYCN470 : public LoRaPHY { @@ -80,14 +80,14 @@ private: band_t bands[CN470_MAX_NB_BANDS]; /*! - * LoRaMac channels mask + * LoRaMac channel mask */ - uint16_t channel_masks[CN470_CHANNELS_MASK_SIZE]; + uint16_t channel_mask[CN470_CHANNEL_MASK_SIZE]; /*! - * LoRaMac channels default mask + * LoRaMac default channel mask */ - uint16_t default_channel_masks[CN470_CHANNELS_MASK_SIZE]; + uint16_t default_channel_mask[CN470_CHANNEL_MASK_SIZE]; }; #endif /* MBED_OS_LORAPHY_CN470_H_ */ diff --git a/features/lorawan/lorastack/phy/LoRaPHYCN779.cpp b/features/lorawan/lorastack/phy/LoRaPHYCN779.cpp index c85e6ac541..66783d32a2 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYCN779.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYCN779.cpp @@ -241,16 +241,16 @@ LoRaPHYCN779::LoRaPHYCN779(LoRaWANTimeHandler &lora_time) channels[2] = CN779_LC3; // Initialize the channels default mask - default_channel_masks[0] = LC(1) + LC(2) + LC(3); + default_channel_mask[0] = LC(1) + LC(2) + LC(3); // Update the channels mask - copy_channel_mask(channel_masks, default_channel_masks, CN779_CHANNELS_MASK_SIZE); + copy_channel_mask(channel_mask, default_channel_mask, CN779_CHANNEL_MASK_SIZE); // set default channels phy_params.channels.channel_list = channels; phy_params.channels.channel_list_size = CN779_MAX_NB_CHANNELS; - phy_params.channels.mask_list = channel_masks; - phy_params.channels.default_mask_list = default_channel_masks; - phy_params.channels.mask_list_size = CN779_CHANNELS_MASK_SIZE; + phy_params.channels.mask = channel_mask; + phy_params.channels.default_mask = default_channel_mask; + phy_params.channels.mask_size = CN779_CHANNEL_MASK_SIZE; // set bands for CN779 spectrum phy_params.bands.table = bands; diff --git a/features/lorawan/lorastack/phy/LoRaPHYCN779.h b/features/lorawan/lorastack/phy/LoRaPHYCN779.h index 06d1bdc85f..b931c43f84 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYCN779.h +++ b/features/lorawan/lorastack/phy/LoRaPHYCN779.h @@ -38,7 +38,7 @@ #define CN779_MAX_NB_BANDS 1 -#define CN779_CHANNELS_MASK_SIZE 1 +#define CN779_CHANNEL_MASK_SIZE 1 class LoRaPHYCN779 : public LoRaPHY { @@ -60,14 +60,14 @@ private: band_t bands[CN779_MAX_NB_BANDS]; /*! - * LoRaMac channels mask + * LoRaMac channel mask */ - uint16_t channel_masks[CN779_CHANNELS_MASK_SIZE]; + uint16_t channel_mask[CN779_CHANNEL_MASK_SIZE]; /*! - * LoRaMac channels default mask + * LoRaMac default channel mask */ - uint16_t default_channel_masks[CN779_CHANNELS_MASK_SIZE]; + uint16_t default_channel_mask[CN779_CHANNEL_MASK_SIZE]; }; #endif /* MBED_OS_LORAPHY_CN779_H_ */ diff --git a/features/lorawan/lorastack/phy/LoRaPHYEU433.cpp b/features/lorawan/lorastack/phy/LoRaPHYEU433.cpp index 8df46d53d5..6345b5395c 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYEU433.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYEU433.cpp @@ -242,16 +242,16 @@ LoRaPHYEU433::LoRaPHYEU433(LoRaWANTimeHandler &lora_time) channels[2] = EU433_LC3;; // Initialize the channels default mask - default_channel_masks[0] = LC(1) + LC(2) + LC(3); + default_channel_mask[0] = LC(1) + LC(2) + LC(3); // Update the channels mask - copy_channel_mask(channel_masks, default_channel_masks, EU433_CHANNELS_MASK_SIZE); + copy_channel_mask(channel_mask, default_channel_mask, EU433_CHANNEL_MASK_SIZE); // set default channels phy_params.channels.channel_list = channels; phy_params.channels.channel_list_size = EU433_MAX_NB_CHANNELS; - phy_params.channels.mask_list = channel_masks; - phy_params.channels.default_mask_list = default_channel_masks; - phy_params.channels.mask_list_size = EU433_CHANNELS_MASK_SIZE; + phy_params.channels.mask = channel_mask; + phy_params.channels.default_mask = default_channel_mask; + phy_params.channels.mask_size = EU433_CHANNEL_MASK_SIZE; // set bands for EU433 spectrum phy_params.bands.table = bands; diff --git a/features/lorawan/lorastack/phy/LoRaPHYEU433.h b/features/lorawan/lorastack/phy/LoRaPHYEU433.h index b230b79523..ccffc9d207 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYEU433.h +++ b/features/lorawan/lorastack/phy/LoRaPHYEU433.h @@ -44,7 +44,7 @@ */ #define EU433_MAX_NB_BANDS 1 -#define EU433_CHANNELS_MASK_SIZE 1 +#define EU433_CHANNEL_MASK_SIZE 1 class LoRaPHYEU433 : public LoRaPHY { @@ -66,14 +66,14 @@ private: band_t bands[EU433_MAX_NB_BANDS]; /*! - * LoRaMac channels mask + * LoRaMac channel mask */ - uint16_t channel_masks[EU433_CHANNELS_MASK_SIZE]; + uint16_t channel_mask[EU433_CHANNEL_MASK_SIZE]; /*! - * LoRaMac channels default mask + * LoRaMac default channel mask */ - uint16_t default_channel_masks[EU433_CHANNELS_MASK_SIZE]; + uint16_t default_channel_mask[EU433_CHANNEL_MASK_SIZE]; }; diff --git a/features/lorawan/lorastack/phy/LoRaPHYEU868.cpp b/features/lorawan/lorastack/phy/LoRaPHYEU868.cpp index b9e07c48ed..fcf8c4ce7f 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYEU868.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYEU868.cpp @@ -272,16 +272,16 @@ LoRaPHYEU868::LoRaPHYEU868(LoRaWANTimeHandler &lora_time) channels[2] = EU868_LC3; // Initialize the channels default mask - default_channel_masks[0] = LC(1) + LC(2) + LC(3); + default_channel_mask[0] = LC(1) + LC(2) + LC(3); // Update the channels mask - copy_channel_mask(channel_masks, default_channel_masks, 1); + copy_channel_mask(channel_mask, default_channel_mask, 1); // set default channels phy_params.channels.channel_list = channels; phy_params.channels.channel_list_size = EU868_MAX_NB_CHANNELS; - phy_params.channels.mask_list = channel_masks; - phy_params.channels.default_mask_list = default_channel_masks; - phy_params.channels.mask_list_size = EU868_CHANNELS_MASK_SIZE; + phy_params.channels.mask = channel_mask; + phy_params.channels.default_mask = default_channel_mask; + phy_params.channels.mask_size = EU868_CHANNEL_MASK_SIZE; // set bands for EU868 spectrum phy_params.bands.table = (void *) bands; diff --git a/features/lorawan/lorastack/phy/LoRaPHYEU868.h b/features/lorawan/lorastack/phy/LoRaPHYEU868.h index 3131321b1c..404a9f11a6 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYEU868.h +++ b/features/lorawan/lorastack/phy/LoRaPHYEU868.h @@ -49,7 +49,7 @@ */ #define EU868_MAX_NB_BANDS 6 -#define EU868_CHANNELS_MASK_SIZE 1 +#define EU868_CHANNEL_MASK_SIZE 1 class LoRaPHYEU868 : public LoRaPHY { @@ -71,12 +71,12 @@ private: /*! * LoRaMac channels mask */ - uint16_t channel_masks[EU868_CHANNELS_MASK_SIZE]; + uint16_t channel_mask[EU868_CHANNEL_MASK_SIZE]; /*! - * LoRaMac channels default mask + * LoRaMac default channel mask */ - uint16_t default_channel_masks[EU868_CHANNELS_MASK_SIZE]; + uint16_t default_channel_mask[EU868_CHANNEL_MASK_SIZE]; }; #endif /* MBED_OS_LORAPHY_EU868_H_ */ diff --git a/features/lorawan/lorastack/phy/LoRaPHYIN865.cpp b/features/lorawan/lorastack/phy/LoRaPHYIN865.cpp index c0661c8238..5ab3bc8f35 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYIN865.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYIN865.cpp @@ -243,16 +243,16 @@ LoRaPHYIN865::LoRaPHYIN865(LoRaWANTimeHandler &lora_time) channels[2] = IN865_LC3; // Initialize the channels default mask - default_channel_masks[0] = LC(1) + LC(2) + LC(3); + default_channel_mask[0] = LC(1) + LC(2) + LC(3); // Update the channels mask - copy_channel_mask(channel_masks, default_channel_masks, 1); + copy_channel_mask(channel_mask, default_channel_mask, 1); // set default channels phy_params.channels.channel_list = channels; phy_params.channels.channel_list_size = IN865_MAX_NB_CHANNELS; - phy_params.channels.mask_list = channel_masks; - phy_params.channels.default_mask_list = default_channel_masks; - phy_params.channels.mask_list_size = IN865_CHANNELS_MASK_SIZE; + phy_params.channels.mask = channel_mask; + phy_params.channels.default_mask = default_channel_mask; + phy_params.channels.mask_size = IN865_CHANNEL_MASK_SIZE; // set bands for IN865 spectrum phy_params.bands.table = (void *) bands; diff --git a/features/lorawan/lorastack/phy/LoRaPHYIN865.h b/features/lorawan/lorastack/phy/LoRaPHYIN865.h index ddc41e6b1e..5d47f67a7a 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYIN865.h +++ b/features/lorawan/lorastack/phy/LoRaPHYIN865.h @@ -45,8 +45,7 @@ */ #define IN865_MAX_NB_BANDS 1 - -#define IN865_CHANNELS_MASK_SIZE 1 +#define IN865_CHANNEL_MASK_SIZE 1 class LoRaPHYIN865 : public LoRaPHY { @@ -70,14 +69,14 @@ private: band_t bands[IN865_MAX_NB_BANDS]; /*! - * LoRaMac channels mask + * LoRaMac channel mask */ - uint16_t channel_masks[IN865_CHANNELS_MASK_SIZE]; + uint16_t channel_mask[IN865_CHANNEL_MASK_SIZE]; /*! - * LoRaMac channels default mask + * LoRaMac default channel mask */ - uint16_t default_channel_masks[IN865_CHANNELS_MASK_SIZE]; + uint16_t default_channel_mask[IN865_CHANNEL_MASK_SIZE]; }; #endif /* MBED_OS_LORAPHY_IN865_H_ */ diff --git a/features/lorawan/lorastack/phy/LoRaPHYKR920.cpp b/features/lorawan/lorastack/phy/LoRaPHYKR920.cpp index bb28fa93e3..74f67c5cc8 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYKR920.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYKR920.cpp @@ -252,16 +252,16 @@ LoRaPHYKR920::LoRaPHYKR920(LoRaWANTimeHandler &lora_time) channels[2] = KR920_LC3; // Initialize the channels default mask - default_channel_masks[0] = LC( 1 ) + LC( 2 ) + LC( 3 ); + default_channel_mask[0] = LC( 1 ) + LC( 2 ) + LC( 3 ); // Update the channels mask - copy_channel_mask(channel_masks, default_channel_masks, KR920_CHANNELS_MASK_SIZE); + copy_channel_mask(channel_mask, default_channel_mask, KR920_CHANNEL_MASK_SIZE); // set default channels phy_params.channels.channel_list = channels; phy_params.channels.channel_list_size = KR920_MAX_NB_CHANNELS; - phy_params.channels.mask_list = channel_masks; - phy_params.channels.default_mask_list = default_channel_masks; - phy_params.channels.mask_list_size = KR920_CHANNELS_MASK_SIZE; + phy_params.channels.mask = channel_mask; + phy_params.channels.default_mask = default_channel_mask; + phy_params.channels.mask_size = KR920_CHANNEL_MASK_SIZE; // set bands for KR920 spectrum phy_params.bands.table = (void *) bands; @@ -341,11 +341,11 @@ int8_t LoRaPHYKR920::get_max_eirp(uint32_t freq) bool LoRaPHYKR920::verify_frequency(uint32_t freq) { - uint32_t tmpFreq = freq; + uint32_t tmp_freq = freq; _radio->lock(); - if (_radio->check_rf_frequency(tmpFreq) == false) { + if (_radio->check_rf_frequency(tmp_freq) == false) { _radio->unlock(); return false; } @@ -354,10 +354,10 @@ bool LoRaPHYKR920::verify_frequency(uint32_t freq) // Verify if the frequency is valid. The frequency must be in a specified // range and can be set to specific values. - if ((tmpFreq >= 920900000) && (tmpFreq <=923300000)) { + if ((tmp_freq >= 920900000) && (tmp_freq <=923300000)) { // Range ok, check for specific value - tmpFreq -= 920900000; - if ((tmpFreq % 200000) == 0) { + tmp_freq -= 920900000; + if ((tmp_freq % 200000) == 0) { return true; } } @@ -414,9 +414,9 @@ bool LoRaPHYKR920::set_next_channel(channel_selection_params_t* params, uint8_t enabled_channels[KR920_MAX_NB_CHANNELS] = {0}; lorawan_time_t nextTxDelay = 0; - if (num_active_channels(channel_masks, 0, 1) == 0) { + if (num_active_channels(channel_mask, 0, 1) == 0) { // Reactivate default channels - channel_masks[0] |= LC(1) + LC(2) + LC(3); + channel_mask[0] |= LC(1) + LC(2) + LC(3); } if (params->aggregate_timeoff <= _lora_time.get_elapsed_time(params->last_aggregate_tx_time)) { @@ -429,7 +429,7 @@ bool LoRaPHYKR920::set_next_channel(channel_selection_params_t* params, // Search how many channels are enabled nb_enabled_channels = enabled_channel_count(params->joined, params->current_datarate, - channel_masks, KR920_CHANNELS_MASK_SIZE, + channel_mask, enabled_channels, &delay_tx); } else { delay_tx++; @@ -472,7 +472,7 @@ bool LoRaPHYKR920::set_next_channel(channel_selection_params_t* params, } // Datarate not supported by any channel, restore defaults - channel_masks[0] |= LC(1) + LC(2) + LC(3); + channel_mask[0] |= LC(1) + LC(2) + LC(3); *time = 0; return false; } diff --git a/features/lorawan/lorastack/phy/LoRaPHYKR920.h b/features/lorawan/lorastack/phy/LoRaPHYKR920.h index cbaa9779d0..b95c902a14 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYKR920.h +++ b/features/lorawan/lorastack/phy/LoRaPHYKR920.h @@ -44,7 +44,7 @@ */ #define KR920_MAX_NB_BANDS 1 -#define KR920_CHANNELS_MASK_SIZE 1 +#define KR920_CHANNEL_MASK_SIZE 1 class LoRaPHYKR920 : public LoRaPHY { @@ -82,14 +82,14 @@ private: band_t bands[KR920_MAX_NB_BANDS]; /** - * LoRaMac channels mask + * LoRaMac channel mask */ - uint16_t channel_masks[KR920_CHANNELS_MASK_SIZE]; + uint16_t channel_mask[KR920_CHANNEL_MASK_SIZE]; /** - * LoRaMac channels default mask + * LoRaMac default channel mask */ - uint16_t default_channel_masks[KR920_CHANNELS_MASK_SIZE]; + uint16_t default_channel_mask[KR920_CHANNEL_MASK_SIZE]; }; #endif // MBED_OS_LORAPHY_KR920_H_ diff --git a/features/lorawan/lorastack/phy/LoRaPHYUS915.cpp b/features/lorawan/lorastack/phy/LoRaPHYUS915.cpp index 89b3c29600..b89d3550eb 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYUS915.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYUS915.cpp @@ -231,29 +231,29 @@ LoRaPHYUS915::LoRaPHYUS915(LoRaWANTimeHandler &lora_time) } // ChannelsMask - default_channel_masks[0] = 0xFFFF; - default_channel_masks[1] = 0xFFFF; - default_channel_masks[2] = 0xFFFF; - default_channel_masks[3] = 0xFFFF; - default_channel_masks[4] = 0x00FF; + default_channel_mask[0] = 0xFFFF; + default_channel_mask[1] = 0xFFFF; + default_channel_mask[2] = 0xFFFF; + default_channel_mask[3] = 0xFFFF; + default_channel_mask[4] = 0x00FF; - memset(channel_masks, 0, sizeof(channel_masks)); - memset(current_channel_masks, 0, sizeof(current_channel_masks)); + memset(channel_mask, 0, sizeof(channel_mask)); + memset(current_channel_mask, 0, sizeof(current_channel_mask)); // Copy channels default mask - copy_channel_mask(channel_masks, default_channel_masks, US915_CHANNELS_MASK_SIZE); + copy_channel_mask(channel_mask, default_channel_mask, US915_CHANNEL_MASK_SIZE); // current channel masks keep track what of the // channels previously used, i.e., which channels should be avoided in // next transmission - copy_channel_mask(current_channel_masks, channel_masks, US915_CHANNELS_MASK_SIZE); + copy_channel_mask(current_channel_mask, channel_mask, US915_CHANNEL_MASK_SIZE); // set default channels phy_params.channels.channel_list = channels; phy_params.channels.channel_list_size = US915_MAX_NB_CHANNELS; - phy_params.channels.mask_list = channel_masks; - phy_params.channels.default_mask_list = default_channel_masks; - phy_params.channels.mask_list_size = US915_CHANNELS_MASK_SIZE; + phy_params.channels.mask = channel_mask; + phy_params.channels.default_mask = default_channel_mask; + phy_params.channels.mask_size = US915_CHANNEL_MASK_SIZE; // set bands for US915 spectrum phy_params.bands.table = (void *) bands; @@ -333,7 +333,7 @@ int8_t LoRaPHYUS915::limit_tx_power(int8_t tx_power, int8_t max_band_tx_power, tx_power_out = MAX (tx_power, TX_POWER_2); } else { - if (num_active_channels(channel_masks, 0, 4) < 50) { + if (num_active_channels(channel_mask, 0, 4) < 50) { // Limit tx power to max 21dBm tx_power_out = MAX (tx_power, TX_POWER_5); } @@ -345,11 +345,11 @@ int8_t LoRaPHYUS915::limit_tx_power(int8_t tx_power, int8_t max_band_tx_power, void LoRaPHYUS915::restore_default_channels() { // Copy channels default mask - copy_channel_mask(channel_masks, default_channel_masks, US915_CHANNELS_MASK_SIZE); + copy_channel_mask(channel_mask, default_channel_mask, US915_CHANNEL_MASK_SIZE); - for ( uint8_t i = 0; i < US915_CHANNELS_MASK_SIZE; i++ ) { + for ( uint8_t i = 0; i < US915_CHANNEL_MASK_SIZE; i++ ) { // Copy-And the channels mask - current_channel_masks[i] &= channel_masks[i]; + current_channel_mask[i] &= channel_mask[i]; } } @@ -429,16 +429,16 @@ bool LoRaPHYUS915::tx_config(tx_config_params_t* config, int8_t* tx_power, _radio->lock(); - _radio->set_channel( channels[config->channel].frequency ); + _radio->set_channel(channels[config->channel].frequency); - _radio->set_tx_config( MODEM_LORA, phy_tx_power, 0, bandwidth, phy_dr, 1, 8, - false, true, 0, 0, false, 3000 ); + _radio->set_tx_config(MODEM_LORA, phy_tx_power, 0, bandwidth, phy_dr, 1, 8, + false, true, 0, 0, false, 3000); // Setup maximum payload lenght of the radio driver - _radio->set_max_payload_length( MODEM_LORA, config->pkt_len ); + _radio->set_max_payload_length(MODEM_LORA, config->pkt_len); // Get the time-on-air of the next tx frame - *tx_toa = _radio->time_on_air( MODEM_LORA, config->pkt_len ); + *tx_toa = _radio->time_on_air(MODEM_LORA, config->pkt_len); _radio->unlock(); @@ -456,12 +456,12 @@ uint8_t LoRaPHYUS915::link_ADR_request(adr_req_params_t* params, link_adr_params_t adr_settings; uint8_t next_idx = 0; uint8_t bytes_processed = 0; - uint16_t temp_channel_masks[US915_CHANNELS_MASK_SIZE] = {0, 0, 0, 0, 0}; + uint16_t temp_channel_masks[US915_CHANNEL_MASK_SIZE] = {0, 0, 0, 0, 0}; verify_adr_params_t verify_params; // Initialize local copy of channels mask - copy_channel_mask(temp_channel_masks, channel_masks, US915_CHANNELS_MASK_SIZE); + copy_channel_mask(temp_channel_masks, channel_mask, US915_CHANNEL_MASK_SIZE); while (bytes_processed < params->payload_size) { next_idx = parse_link_ADR_req(&(params->payload[bytes_processed]), @@ -498,14 +498,11 @@ uint8_t LoRaPHYUS915::link_ADR_request(adr_req_params_t* params, temp_channel_masks[4] = adr_settings.channel_mask; } else if (adr_settings.ch_mask_ctrl == 5) { - // RFU status &= 0xFE; // Channel mask KO } else { - temp_channel_masks[adr_settings.ch_mask_ctrl] = adr_settings.channel_mask; - } } @@ -534,13 +531,13 @@ uint8_t LoRaPHYUS915::link_ADR_request(adr_req_params_t* params, // Update channelsMask if everything is correct if (status == 0x07) { // Copy Mask - copy_channel_mask(channel_masks, temp_channel_masks, US915_CHANNELS_MASK_SIZE); + copy_channel_mask(channel_mask, temp_channel_masks, US915_CHANNEL_MASK_SIZE); - current_channel_masks[0] &= channel_masks[0]; - current_channel_masks[1] &= channel_masks[1]; - current_channel_masks[2] &= channel_masks[2]; - current_channel_masks[3] &= channel_masks[3]; - current_channel_masks[4] = channel_masks[4]; + current_channel_mask[0] &= channel_mask[0]; + current_channel_mask[1] &= channel_mask[1]; + current_channel_mask[2] &= channel_mask[2]; + current_channel_mask[3] &= channel_mask[3]; + current_channel_mask[4] = channel_mask[4]; } // Update status variables @@ -594,7 +591,7 @@ int8_t LoRaPHYUS915::get_alternate_DR(uint8_t nb_trials) int8_t datarate = 0; // Re-enable 500 kHz default channels - channel_masks[4] = 0x00FF; + channel_mask[4] = 0x00FF; if ((nb_trials & 0x01) == 0x01) { datarate = DR_4; @@ -615,16 +612,16 @@ bool LoRaPHYUS915::set_next_channel(channel_selection_params_t* params, lorawan_time_t next_tx_delay = 0; // Count 125kHz channels - if (num_active_channels(current_channel_masks, 0, 4) == 0) { + if (num_active_channels(current_channel_mask, 0, 4) == 0) { // If none of the 125 kHz Upstream channel found, // Reactivate default channels - copy_channel_mask(current_channel_masks, channel_masks, 4); + copy_channel_mask(current_channel_mask, channel_mask, 4); } // Check other channels if (params->current_datarate >= DR_4) { - if ((current_channel_masks[4] & 0x00FF ) == 0) { - current_channel_masks[4] = channel_masks[4]; + if ((current_channel_mask[4] & 0x00FF ) == 0) { + current_channel_mask[4] = channel_mask[4]; } } @@ -638,7 +635,7 @@ bool LoRaPHYUS915::set_next_channel(channel_selection_params_t* params, // Search how many channels are enabled nb_enabled_channels = enabled_channel_count(params->joined, params->current_datarate, - current_channel_masks, US915_CHANNELS_MASK_SIZE, + current_channel_mask, enabled_channels, &delay_tx); } else { delay_tx++; @@ -649,7 +646,7 @@ bool LoRaPHYUS915::set_next_channel(channel_selection_params_t* params, // We found a valid channel *channel = enabled_channels[get_random( 0, nb_enabled_channels - 1 )]; // Disable the channel in the mask - disable_channel(current_channel_masks, *channel, US915_MAX_NB_CHANNELS - 8); + disable_channel(current_channel_mask, *channel, US915_MAX_NB_CHANNELS - 8); *time = 0; return true; diff --git a/features/lorawan/lorastack/phy/LoRaPHYUS915.h b/features/lorawan/lorastack/phy/LoRaPHYUS915.h index b9bc885787..f08944e6e7 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYUS915.h +++ b/features/lorawan/lorastack/phy/LoRaPHYUS915.h @@ -44,7 +44,7 @@ */ #define US915_MAX_NB_BANDS 1 -#define US915_CHANNELS_MASK_SIZE 5 +#define US915_CHANNEL_MASK_SIZE 5 class LoRaPHYUS915 : public LoRaPHY { @@ -94,19 +94,19 @@ private: band_t bands[US915_MAX_NB_BANDS]; /*! - * LoRaMac channels mask + * LoRaMac channel mask */ - uint16_t channel_masks[US915_CHANNELS_MASK_SIZE]; + uint16_t channel_mask[US915_CHANNEL_MASK_SIZE]; /*! - * LoRaMac channels remaining + * Previously used channel mask */ - uint16_t current_channel_masks[US915_CHANNELS_MASK_SIZE]; + uint16_t current_channel_mask[US915_CHANNEL_MASK_SIZE]; /*! - * LoRaMac channels default mask + * LoRaMac default channel mask */ - uint16_t default_channel_masks[US915_CHANNELS_MASK_SIZE]; + uint16_t default_channel_mask[US915_CHANNEL_MASK_SIZE]; }; #endif /* MBED_OS_LORAPHY_US915_H_ */ diff --git a/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.cpp b/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.cpp index b48e990c8a..9ab99e30fb 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.cpp +++ b/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.cpp @@ -231,27 +231,27 @@ LoRaPHYUS915Hybrid::LoRaPHYUS915Hybrid(LoRaWANTimeHandler &lora_time) } // ChannelsMask - default_channel_masks[0] = 0x00FF; - default_channel_masks[1] = 0x0000; - default_channel_masks[2] = 0x0000; - default_channel_masks[3] = 0x0000; - default_channel_masks[4] = 0x0001; + default_channel_mask[0] = 0x00FF; + default_channel_mask[1] = 0x0000; + default_channel_mask[2] = 0x0000; + default_channel_mask[3] = 0x0000; + default_channel_mask[4] = 0x0001; - memset(channel_masks, 0, sizeof(channel_masks)); - memset(current_channel_masks, 0, sizeof(current_channel_masks)); + memset(channel_mask, 0, sizeof(channel_mask)); + memset(current_channel_mask, 0, sizeof(current_channel_mask)); // Copy channels default mask - copy_channel_mask(channel_masks, default_channel_masks, US915_HYBRID_CHANNELS_MASK_SIZE); + copy_channel_mask(channel_mask, default_channel_mask, US915_HYBRID_CHANNEL_MASK_SIZE); // Copy into channels mask remaining - copy_channel_mask(current_channel_masks, channel_masks, US915_HYBRID_CHANNELS_MASK_SIZE); + copy_channel_mask(current_channel_mask, channel_mask, US915_HYBRID_CHANNEL_MASK_SIZE); // set default channels phy_params.channels.channel_list = channels; phy_params.channels.channel_list_size = US915_HYBRID_MAX_NB_CHANNELS; - phy_params.channels.mask_list = channel_masks; - phy_params.channels.default_mask_list = default_channel_masks; - phy_params.channels.mask_list_size = US915_HYBRID_CHANNELS_MASK_SIZE; + phy_params.channels.mask = channel_mask; + phy_params.channels.default_mask = default_channel_mask; + phy_params.channels.mask_size = US915_HYBRID_CHANNEL_MASK_SIZE; // set bands for US915_HYBRID spectrum phy_params.bands.table = (void *) bands; @@ -321,11 +321,11 @@ LoRaPHYUS915Hybrid::~LoRaPHYUS915Hybrid() void LoRaPHYUS915Hybrid::restore_default_channels() { // Copy channels default mask - copy_channel_mask(channel_masks, default_channel_masks, US915_HYBRID_CHANNELS_MASK_SIZE); + copy_channel_mask(channel_mask, default_channel_mask, US915_HYBRID_CHANNEL_MASK_SIZE); - for (uint8_t i = 0; i < US915_HYBRID_CHANNELS_MASK_SIZE; i++) { + for (uint8_t i = 0; i < US915_HYBRID_CHANNEL_MASK_SIZE; i++) { // Copy-And the channels mask - current_channel_masks[i] &= channel_masks[i]; + current_channel_mask[i] &= channel_mask[i]; } } @@ -366,7 +366,7 @@ bool LoRaPHYUS915Hybrid::get_next_ADR(bool restore_channel_mask, int8_t& dr_out, adrAckReq = false; if (restore_channel_mask) { // Re-enable default channels - reenable_500khz_channels(channel_masks[4], channel_masks); + reenable_500khz_channels(channel_mask[4], channel_mask); } } } @@ -469,12 +469,12 @@ uint8_t LoRaPHYUS915Hybrid::link_ADR_request(adr_req_params_t* params, link_adr_params_t adr_settings; uint8_t next_idx = 0; uint8_t bytes_processed = 0; - uint16_t temp_channel_masks[US915_HYBRID_CHANNELS_MASK_SIZE] = {0, 0, 0, 0, 0}; + uint16_t temp_channel_mask[US915_HYBRID_CHANNEL_MASK_SIZE] = {0, 0, 0, 0, 0}; verify_adr_params_t verify_params; // Initialize local copy of channels mask - copy_channel_mask(temp_channel_masks, channel_masks, US915_HYBRID_CHANNELS_MASK_SIZE); + copy_channel_mask(temp_channel_mask, channel_mask, US915_HYBRID_CHANNEL_MASK_SIZE); while (bytes_processed < params->payload_size) { next_idx = parse_link_ADR_req(&(params->payload[bytes_processed]), @@ -492,35 +492,35 @@ uint8_t LoRaPHYUS915Hybrid::link_ADR_request(adr_req_params_t* params, if (adr_settings.ch_mask_ctrl == 6) { // Enable all 125 kHz channels - temp_channel_masks[0] = 0xFFFF; - temp_channel_masks[1] = 0xFFFF; - temp_channel_masks[2] = 0xFFFF; - temp_channel_masks[3] = 0xFFFF; + temp_channel_mask[0] = 0xFFFF; + temp_channel_mask[1] = 0xFFFF; + temp_channel_mask[2] = 0xFFFF; + temp_channel_mask[3] = 0xFFFF; // Apply chMask to channels 64 to 71 - temp_channel_masks[4] = adr_settings.channel_mask; + temp_channel_mask[4] = adr_settings.channel_mask; } else if( adr_settings.ch_mask_ctrl == 7 ) { // Disable all 125 kHz channels - temp_channel_masks[0] = 0x0000; - temp_channel_masks[1] = 0x0000; - temp_channel_masks[2] = 0x0000; - temp_channel_masks[3] = 0x0000; + temp_channel_mask[0] = 0x0000; + temp_channel_mask[1] = 0x0000; + temp_channel_mask[2] = 0x0000; + temp_channel_mask[3] = 0x0000; // Apply chMask to channels 64 to 71 - temp_channel_masks[4] = adr_settings.channel_mask; + temp_channel_mask[4] = adr_settings.channel_mask; } else if( adr_settings.ch_mask_ctrl == 5 ) { // RFU status &= 0xFE; // Channel mask KO } else { - temp_channel_masks[adr_settings.ch_mask_ctrl] = adr_settings.channel_mask; + temp_channel_mask[adr_settings.ch_mask_ctrl] = adr_settings.channel_mask; } } // FCC 15.247 paragraph F mandates to hop on at least 2 125 kHz channels if ((adr_settings.datarate < DR_4) && - (num_active_channels( temp_channel_masks, 0, 4 ) < 2)) { + (num_active_channels( temp_channel_mask, 0, 4 ) < 2)) { status &= 0xFE; // Channel mask KO } - if( validate_channel_mask(temp_channel_masks ) == false) { + if( validate_channel_mask(temp_channel_mask ) == false) { status &= 0xFE; // Channel mask KO } @@ -532,7 +532,7 @@ uint8_t LoRaPHYUS915Hybrid::link_ADR_request(adr_req_params_t* params, verify_params.current_datarate = params->current_datarate; verify_params.current_tx_power = params->current_tx_power; verify_params.current_nb_rep = params->current_nb_rep; - verify_params.channel_mask = temp_channel_masks; + verify_params.channel_mask = temp_channel_mask; // Verify the parameters and update, if necessary @@ -542,13 +542,13 @@ uint8_t LoRaPHYUS915Hybrid::link_ADR_request(adr_req_params_t* params, // Update channelsMask if everything is correct if (status == 0x07) { // Copy Mask - copy_channel_mask(channel_masks, temp_channel_masks, US915_HYBRID_CHANNELS_MASK_SIZE); + copy_channel_mask(channel_mask, temp_channel_mask, US915_HYBRID_CHANNEL_MASK_SIZE); - current_channel_masks[0] &= channel_masks[0]; - current_channel_masks[1] &= channel_masks[1]; - current_channel_masks[2] &= channel_masks[2]; - current_channel_masks[3] &= channel_masks[3]; - current_channel_masks[4] = channel_masks[4]; + current_channel_mask[0] &= channel_mask[0]; + current_channel_mask[1] &= channel_mask[1]; + current_channel_mask[2] &= channel_mask[2]; + current_channel_mask[3] &= channel_mask[3]; + current_channel_mask[4] = channel_mask[4]; } // Update status variables @@ -596,7 +596,7 @@ int8_t LoRaPHYUS915Hybrid::get_alternate_DR(uint8_t nb_trials) int8_t datarate = 0; // Re-enable 500 kHz default channels - reenable_500khz_channels(channel_masks[4], channel_masks); + reenable_500khz_channels(channel_mask[4], channel_mask); if ((nb_trials & 0x01) == 0x01) { datarate = DR_4; @@ -617,15 +617,15 @@ bool LoRaPHYUS915Hybrid::set_next_channel(channel_selection_params_t* params, lorawan_time_t next_tx_delay = 0; // Count 125kHz channels - if (num_active_channels(current_channel_masks, 0, 4) == 0) { + if (num_active_channels(current_channel_mask, 0, 4) == 0) { // Reactivate default channels - copy_channel_mask(current_channel_masks, channel_masks, 4); + copy_channel_mask(current_channel_mask, channel_mask, 4); } // Check other channels if (params->current_datarate >= DR_4) { - if ((current_channel_masks[4] & 0x00FF ) == 0) { - current_channel_masks[4] = channel_masks[4]; + if ((current_channel_mask[4] & 0x00FF ) == 0) { + current_channel_mask[4] = channel_mask[4]; } } @@ -641,8 +641,7 @@ bool LoRaPHYUS915Hybrid::set_next_channel(channel_selection_params_t* params, // Search how many channels are enabled nb_enabled_channels = enabled_channel_count(params->joined, params->current_datarate, - current_channel_masks, - US915_HYBRID_CHANNELS_MASK_SIZE, + current_channel_mask, enabled_channels, &delay_tx); } else { delay_tx++; @@ -654,7 +653,7 @@ bool LoRaPHYUS915Hybrid::set_next_channel(channel_selection_params_t* params, // We found a valid channel *channel = enabled_channels[get_random(0, nb_enabled_channels - 1)]; // Disable the channel in the mask - disable_channel(current_channel_masks, *channel, US915_HYBRID_MAX_NB_CHANNELS - 8); + disable_channel(current_channel_mask, *channel, US915_HYBRID_MAX_NB_CHANNELS - 8); *time = 0; return true; @@ -737,7 +736,7 @@ int8_t LoRaPHYUS915Hybrid::limit_tx_power(int8_t txPower, int8_t maxBandTxPower, } else { - if (num_active_channels(channel_masks, 0, 4) < 50) { + if (num_active_channels(channel_mask, 0, 4) < 50) { // Limit tx power to max 21dBm txPowerResult = MAX(txPower, TX_POWER_5); } @@ -753,7 +752,7 @@ bool LoRaPHYUS915Hybrid::validate_channel_mask(uint16_t* channel_masks) uint16_t block1 = 0; uint16_t block2 = 0; uint8_t index = 0; - uint16_t temp_channel_masks[US915_HYBRID_CHANNELS_MASK_SIZE]; + uint16_t temp_channel_masks[US915_HYBRID_CHANNEL_MASK_SIZE]; // Copy channels mask to not change the input for (uint8_t i = 0; i < 4; i++) { diff --git a/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.h b/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.h index 9d7262fb41..08f1b58a71 100644 --- a/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.h +++ b/features/lorawan/lorastack/phy/LoRaPHYUS915Hybrid.h @@ -45,7 +45,7 @@ */ #define US915_HYBRID_MAX_NB_BANDS 1 -#define US915_HYBRID_CHANNELS_MASK_SIZE 5 +#define US915_HYBRID_CHANNEL_MASK_SIZE 5 class LoRaPHYUS915Hybrid : public LoRaPHY { @@ -101,17 +101,17 @@ private: /*! * LoRaMac channels mask */ - uint16_t channel_masks[US915_HYBRID_CHANNELS_MASK_SIZE]; + uint16_t channel_mask[US915_HYBRID_CHANNEL_MASK_SIZE]; /*! - * LoRaMac channels remaining + * Previously used channel mask */ - uint16_t current_channel_masks[US915_HYBRID_CHANNELS_MASK_SIZE]; + uint16_t current_channel_mask[US915_HYBRID_CHANNEL_MASK_SIZE]; /*! - * LoRaMac channels default mask + * LoRaMac default channel mask */ - uint16_t default_channel_masks[US915_HYBRID_CHANNELS_MASK_SIZE]; + uint16_t default_channel_mask[US915_HYBRID_CHANNEL_MASK_SIZE]; }; #endif /* MBED_OS_LORAPHY_US915HYBRID_H_ */ diff --git a/features/lorawan/lorastack/phy/lora_phy_ds.h b/features/lorawan/lorastack/phy/lora_phy_ds.h index 1eed06771f..ebcd0f6ae0 100644 --- a/features/lorawan/lorastack/phy/lora_phy_ds.h +++ b/features/lorawan/lorastack/phy/lora_phy_ds.h @@ -620,11 +620,11 @@ typedef enum phy_attributes__e /*! * The channels mask. */ - PHY_CHANNELS_MASK, + PHY_CHANNEL_MASK, /*! - * The channels default mask. + * The default channel mask. */ - PHY_CHANNELS_DEFAULT_MASK, + PHY_DEFAULT_CHANNEL_MASK, /*! * The maximum number of supported channels. */ @@ -633,6 +633,13 @@ typedef enum phy_attributes__e * The channels. */ PHY_CHANNELS, + /*! + * The PHYs that support dynamic channel plan (non-custom) + * support do not let the user add/remove to the channel plan. + * The network guides the device for the plan. So only + * EU like regions support custom channel planning. + */ + PHY_CUSTOM_CHANNEL_PLAN_SUPPORT, /*! * The default value of the uplink dwell time. */ @@ -1073,9 +1080,9 @@ typedef struct { channel_params_t *channel_list; uint8_t channel_list_size; - uint16_t *mask_list; - uint16_t *default_mask_list; - uint8_t mask_list_size; + uint16_t *mask; + uint16_t *default_mask; + uint8_t mask_size; } loraphy_channels_t; diff --git a/features/lorawan/system/lorawan_data_structures.h b/features/lorawan/system/lorawan_data_structures.h index 10fa5995fc..8a45cce370 100644 --- a/features/lorawan/system/lorawan_data_structures.h +++ b/features/lorawan/system/lorawan_data_structures.h @@ -44,6 +44,21 @@ typedef uint32_t lorawan_time_t; #define MSG_MULTICAST_FLAG 0x04 #define MSG_PROPRIETARY_FLAG 0x08 +/** + * A macro to test a if a bit is on in a channel mask or not. + */ +//#define MASK_BIT_TEST(mask, bit) (mask & (1U << bit)) +//#define MASK_BIT_TEST(mask, bit) ((mask)[(bit) / 16] & (1U << ((bit) % 16))) +/** + * A macro to clear a bit in a channel mask. + */ +//#define MASK_BIT_CLEAR(mask, bit) (mask &= ~(1 << bit)) + +/** + * A macro to clear a bit in a channel mask. + */ +//#define MASK_BIT_SET(mask, bit) (mask |= (1 << bit)) + /** * Bit mask for message flags */ @@ -2361,11 +2376,11 @@ typedef enum lora_events { RX_TIMEOUT, RX_ERROR, JOIN_FAILURE, -} lorawan_events_t; +} lorawan_event_t; typedef struct { // Mandatory. Event Callback must be provided - mbed::Callback events; + mbed::Callback events; // Rest are optional // If the user do not assign these callbacks, these callbacks would return