From 492ee5d88a56b2d7920ff8067e9a050cd8aed9d5 Mon Sep 17 00:00:00 2001 From: Miguel Luis Date: Fri, 18 Dec 2020 15:23:00 +0100 Subject: [PATCH 1/3] Fixed `REG_LR_SYNCH_TIMEOUT` register write to only happen when `symbNum` is different from 0 --- src/radio/sx126x/sx126x.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/radio/sx126x/sx126x.c b/src/radio/sx126x/sx126x.c index bb26164fd..8deeefe62 100644 --- a/src/radio/sx126x/sx126x.c +++ b/src/radio/sx126x/sx126x.c @@ -370,8 +370,11 @@ void SX126xSetLoRaSymbNumTimeout( uint8_t symbNum ) reg = mant << ( 2 * exp + 1 ); SX126xWriteCommand( RADIO_SET_LORASYMBTIMEOUT, ®, 1 ); - reg = exp + ( mant << 3 ); - SX126xWriteRegister( REG_LR_SYNCH_TIMEOUT, reg ); + if( symbNum != 0 ) + { + reg = exp + ( mant << 3 ); + SX126xWriteRegister( REG_LR_SYNCH_TIMEOUT, reg ); + } } void SX126xSetRegulatorMode( RadioRegulatorMode_t mode ) From c756d94b96b3aa7ab93154866f55592f6903e9a2 Mon Sep 17 00:00:00 2001 From: Daniel Jaeckle Date: Fri, 18 Dec 2020 16:56:09 +0100 Subject: [PATCH 2/3] Refactored Non Volatile Memory management (Big update) --- src/apps/LoRaMac/CMakeLists.txt | 8 +- src/apps/LoRaMac/common/LmHandler/LmHandler.c | 22 +- src/apps/LoRaMac/common/LmHandler/LmHandler.h | 10 +- src/apps/LoRaMac/common/LmHandlerMsgDisplay.c | 8 +- src/apps/LoRaMac/common/LmHandlerMsgDisplay.h | 4 +- src/apps/LoRaMac/common/NvmCtxMgmt.c | 381 ------ src/apps/LoRaMac/common/NvmDataMgmt.c | 272 ++++ .../common/{NvmCtxMgmt.h => NvmDataMgmt.h} | 50 +- src/apps/LoRaMac/common/cli.c | 56 + src/apps/LoRaMac/common/cli.h | 41 + .../fuota-test-01/B-L072Z-LRWAN1/main.c | 55 +- .../LoRaMac/fuota-test-01/NAMote72/main.c | 55 +- .../LoRaMac/fuota-test-01/NucleoL073/main.c | 55 +- .../LoRaMac/fuota-test-01/NucleoL152/main.c | 55 +- .../LoRaMac/fuota-test-01/NucleoL476/main.c | 55 +- src/apps/LoRaMac/fuota-test-01/SAMR34/main.c | 55 +- .../LoRaMac/fuota-test-01/SKiM880B/main.c | 55 +- .../LoRaMac/fuota-test-01/SKiM881AXL/main.c | 55 +- .../LoRaMac/fuota-test-01/SKiM980A/main.c | 55 +- .../periodic-uplink-lpp/B-L072Z-LRWAN1/main.c | 20 +- .../periodic-uplink-lpp/NAMote72/main.c | 20 +- .../periodic-uplink-lpp/NucleoL073/main.c | 20 +- .../periodic-uplink-lpp/NucleoL152/main.c | 20 +- .../periodic-uplink-lpp/NucleoL476/main.c | 20 +- .../LoRaMac/periodic-uplink-lpp/SAMR34/main.c | 20 +- .../periodic-uplink-lpp/SKiM880B/main.c | 20 +- .../periodic-uplink-lpp/SKiM881AXL/main.c | 20 +- .../periodic-uplink-lpp/SKiM980A/main.c | 20 +- src/boards/B-L072Z-LRWAN1/eeprom-board.c | 2 + src/boards/NAMote72/eeprom-board.c | 2 + src/boards/NucleoL073/eeprom-board.c | 2 + src/boards/NucleoL152/eeprom-board.c | 2 + src/boards/NucleoL476/eeprom-board.c | 4 +- src/boards/SKiM880B/eeprom-board.c | 2 + src/boards/SKiM881AXL/eeprom-board.c | 2 + src/boards/SKiM980A/eeprom-board.c | 3 + src/boards/mcu/utilities.c | 59 + src/boards/utilities.h | 44 +- src/mac/CMakeLists.txt | 46 +- src/mac/LoRaMac.c | 1171 ++++++++--------- src/mac/LoRaMac.h | 487 +++---- src/mac/LoRaMacClassB.c | 218 +-- src/mac/LoRaMacClassB.h | 23 +- src/mac/LoRaMacClassBNvm.h | 120 ++ src/mac/LoRaMacCommands.c | 75 +- src/mac/LoRaMacCommands.h | 23 +- src/mac/LoRaMacConfirmQueue.c | 93 +- src/mac/LoRaMacConfirmQueue.h | 29 +- src/mac/LoRaMacCrypto.c | 301 ++--- src/mac/LoRaMacCrypto.h | 23 +- src/mac/LoRaMacCryptoNvm.h | 124 ++ src/mac/LoRaMacTypes.h | 565 +++++++- src/mac/region/Region.c | 31 - src/mac/region/Region.h | 544 +------- src/mac/region/RegionAS923.c | 141 +- src/mac/region/RegionAS923.h | 9 - src/mac/region/RegionAU915.c | 189 ++- src/mac/region/RegionAU915.h | 9 - src/mac/region/RegionCN470.c | 131 +- src/mac/region/RegionCN470.h | 9 - src/mac/region/RegionCN779.c | 139 +- src/mac/region/RegionCN779.h | 9 - src/mac/region/RegionEU433.c | 139 +- src/mac/region/RegionEU433.h | 9 - src/mac/region/RegionEU868.c | 139 +- src/mac/region/RegionEU868.h | 9 - src/mac/region/RegionIN865.c | 140 +- src/mac/region/RegionIN865.h | 9 - src/mac/region/RegionKR920.c | 145 +- src/mac/region/RegionKR920.h | 9 - src/mac/region/RegionNvm.h | 134 ++ src/mac/region/RegionRU864.c | 135 +- src/mac/region/RegionRU864.h | 9 - src/mac/region/RegionUS915.c | 190 ++- src/mac/region/RegionUS915.h | 9 - src/mac/secure-element-nvm.h | 116 ++ src/mac/secure-element.h | 45 +- src/peripherals/CMakeLists.txt | 3 +- .../atecc608a-tnglora-se.c | 139 +- .../atecc608a-tnglora-se/se-identity.h | 2 +- src/peripherals/lr1110-se/lr1110-se.c | 131 +- src/peripherals/soft-se/soft-se.c | 171 +-- src/system/eeprom.c | 54 - src/system/eeprom.h | 75 -- src/system/nvmm.c | 208 +-- src/system/nvmm.h | 81 +- 86 files changed, 3706 insertions(+), 4553 deletions(-) delete mode 100644 src/apps/LoRaMac/common/NvmCtxMgmt.c create mode 100644 src/apps/LoRaMac/common/NvmDataMgmt.c rename src/apps/LoRaMac/common/{NvmCtxMgmt.h => NvmDataMgmt.h} (56%) create mode 100644 src/apps/LoRaMac/common/cli.c create mode 100644 src/apps/LoRaMac/common/cli.h create mode 100644 src/mac/LoRaMacClassBNvm.h create mode 100644 src/mac/LoRaMacCryptoNvm.h create mode 100644 src/mac/region/RegionNvm.h create mode 100644 src/mac/secure-element-nvm.h delete mode 100644 src/system/eeprom.c delete mode 100644 src/system/eeprom.h diff --git a/src/apps/LoRaMac/CMakeLists.txt b/src/apps/LoRaMac/CMakeLists.txt index 652839f4f..c51a5323b 100644 --- a/src/apps/LoRaMac/CMakeLists.txt +++ b/src/apps/LoRaMac/CMakeLists.txt @@ -49,8 +49,9 @@ if(SUB_PROJECT STREQUAL periodic-uplink-lpp) #--------------------------------------------------------------------------------------- list(APPEND ${PROJECT_NAME}_COMMON "${CMAKE_CURRENT_LIST_DIR}/common/CayenneLpp.c" + "${CMAKE_CURRENT_LIST_DIR}/common/cli.c" "${CMAKE_CURRENT_LIST_DIR}/common/LmHandlerMsgDisplay.c" - "${CMAKE_CURRENT_LIST_DIR}/common/NvmCtxMgmt.c" + "${CMAKE_CURRENT_LIST_DIR}/common/NvmDataMgmt.c" ) #--------------------------------------------------------------------------------------- @@ -78,7 +79,7 @@ elseif(SUB_PROJECT STREQUAL fuota-test-01) #--------------------------------------------------------------------------------------- list(APPEND ${PROJECT_NAME}_COMMON "${CMAKE_CURRENT_LIST_DIR}/common/LmHandlerMsgDisplay.c" - "${CMAKE_CURRENT_LIST_DIR}/common/NvmCtxMgmt.c" + "${CMAKE_CURRENT_LIST_DIR}/common/NvmDataMgmt.c" ) #--------------------------------------------------------------------------------------- @@ -125,6 +126,9 @@ target_compile_definitions(${PROJECT_NAME}-${SUB_PROJECT} PRIVATE ACTIVE_REGION= if(${SECURE_ELEMENT_PRE_PROVISIONED} MATCHES ON) target_compile_definitions(${PROJECT_NAME}-${SUB_PROJECT} PRIVATE -DSECURE_ELEMENT_PRE_PROVISIONED) endif() +if(${SECURE_ELEMENT} MATCHES SOFT_SE) + target_compile_definitions(${PROJECT_NAME}-${SUB_PROJECT} PRIVATE -DSOFT_SE) +endif() target_compile_definitions(${PROJECT_NAME}-${SUB_PROJECT} PUBLIC $> ) diff --git a/src/apps/LoRaMac/common/LmHandler/LmHandler.c b/src/apps/LoRaMac/common/LmHandler/LmHandler.c index 8a14c2ba9..5362969aa 100644 --- a/src/apps/LoRaMac/common/LmHandler/LmHandler.c +++ b/src/apps/LoRaMac/common/LmHandler/LmHandler.c @@ -28,7 +28,8 @@ #include "utilities.h" #include "timer.h" #include "Commissioning.h" -#include "NvmCtxMgmt.h" +#include "NvmDataMgmt.h" +#include "radio.h" #include "LmHandler.h" #include "LmhPackage.h" #include "LmhpCompliance.h" @@ -214,6 +215,7 @@ LmHandlerErrorStatus_t LmHandlerInit( LmHandlerCallbacks_t *handlerCallbacks, LmHandlerParams_t *handlerParams ) { // + uint16_t nbNvmData = 0; MibRequestConfirm_t mibReq; LmHandlerParams = handlerParams; LmHandlerCallbacks = handlerCallbacks; @@ -224,7 +226,7 @@ LmHandlerErrorStatus_t LmHandlerInit( LmHandlerCallbacks_t *handlerCallbacks, LoRaMacPrimitives.MacMlmeIndication = MlmeIndication; LoRaMacCallbacks.GetBatteryLevel = LmHandlerCallbacks->GetBatteryLevel; LoRaMacCallbacks.GetTemperatureLevel = LmHandlerCallbacks->GetTemperature; - LoRaMacCallbacks.NvmContextChange = NvmCtxMgmtEvent; + LoRaMacCallbacks.NvmDataChange = NvmDataMgmtEvent; LoRaMacCallbacks.MacProcessNotify = LmHandlerCallbacks->OnMacProcess; IsClassBSwitchPending = false; @@ -234,10 +236,13 @@ LmHandlerErrorStatus_t LmHandlerInit( LmHandlerCallbacks_t *handlerCallbacks, return LORAMAC_HANDLER_ERROR; } + // Restore data if required + nbNvmData = NvmDataMgmtRestore( ); + // Try to restore from NVM and query the mac if possible. - if( NvmCtxMgmtRestore( ) == NVMCTXMGMT_STATUS_SUCCESS ) + if( nbNvmData > 0 ) { - LmHandlerCallbacks->OnNvmContextChange( LORAMAC_HANDLER_NVM_RESTORE ); + LmHandlerCallbacks->OnNvmDataChange( LORAMAC_HANDLER_NVM_RESTORE, nbNvmData ); } else { @@ -321,6 +326,8 @@ bool LmHandlerIsBusy( void ) void LmHandlerProcess( void ) { + uint16_t size = 0; + // Process Radio IRQ if( Radio.IrqProcess != NULL ) { @@ -333,9 +340,12 @@ void LmHandlerProcess( void ) // Call all packages process functions LmHandlerPackagesProcess( ); - if( NvmCtxMgmtStore( ) == NVMCTXMGMT_STATUS_SUCCESS ) + // Store to NVM if required + size = NvmDataMgmtStore( ); + + if( size > 0 ) { - LmHandlerCallbacks->OnNvmContextChange( LORAMAC_HANDLER_NVM_STORE ); + LmHandlerCallbacks->OnNvmDataChange( LORAMAC_HANDLER_NVM_STORE, size ); } } diff --git a/src/apps/LoRaMac/common/LmHandler/LmHandler.h b/src/apps/LoRaMac/common/LmHandler/LmHandler.h index eac79e4b4..5d4b83f01 100644 --- a/src/apps/LoRaMac/common/LmHandler/LmHandler.h +++ b/src/apps/LoRaMac/common/LmHandler/LmHandler.h @@ -131,17 +131,19 @@ typedef struct LmHandlerCallbacks_s /*! *\brief Will be called each time a Radio IRQ is handled by the MAC * layer. - * + * *\warning Runs in a IRQ context. Should only change variables state. */ void ( *OnMacProcess )( void ); /*! * Notifies the upper layer that the NVM context has changed * - * \param [IN] stored Indicates if we are storing (true) or - * restoring (false) the NVM context + * \param [IN] state Indicates if we are storing (true) or + * restoring (false) the NVM context + * + * \param [IN] size Number of data bytes which were stored or restored. */ - void ( *OnNvmContextChange )( LmHandlerNvmContextStates_t state ); + void ( *OnNvmDataChange )( LmHandlerNvmContextStates_t state, uint16_t size ); /*! * Notifies the upper layer that a network parameters have been set * diff --git a/src/apps/LoRaMac/common/LmHandlerMsgDisplay.c b/src/apps/LoRaMac/common/LmHandlerMsgDisplay.c index 82e94b922..0d21090c2 100644 --- a/src/apps/LoRaMac/common/LmHandlerMsgDisplay.c +++ b/src/apps/LoRaMac/common/LmHandlerMsgDisplay.c @@ -111,16 +111,18 @@ void PrintHexBuffer( uint8_t *buffer, uint8_t size ) printf( "\n" ); } -void DisplayNvmContextChange( LmHandlerNvmContextStates_t state ) +void DisplayNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ) { if( state == LORAMAC_HANDLER_NVM_STORE ) { - printf( "\n###### ============ CTXS STORED ============ ######\n\n" ); + printf( "\n###### ============ CTXS STORED ============ ######\n" ); + } else { - printf( "\n###### =========== CTXS RESTORED =========== ######\n\n" ); + printf( "\n###### =========== CTXS RESTORED =========== ######\n" ); } + printf( "Size : %i\n\n", size ); } void DisplayNetworkParametersUpdate( CommissioningParams_t *commissioningParams ) diff --git a/src/apps/LoRaMac/common/LmHandlerMsgDisplay.h b/src/apps/LoRaMac/common/LmHandlerMsgDisplay.h index 6b61b5e01..66faf709f 100644 --- a/src/apps/LoRaMac/common/LmHandlerMsgDisplay.h +++ b/src/apps/LoRaMac/common/LmHandlerMsgDisplay.h @@ -30,8 +30,10 @@ * * \param [IN] state Indicates if we are storing (true) or * restoring (false) the NVM context + * + * \param [IN] size Number of data bytes which were stored or restored. */ -void DisplayNvmContextChange( LmHandlerNvmContextStates_t state ); +void DisplayNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ); /*! * \brief Displays updated network parameters diff --git a/src/apps/LoRaMac/common/NvmCtxMgmt.c b/src/apps/LoRaMac/common/NvmCtxMgmt.c deleted file mode 100644 index 178bc87a2..000000000 --- a/src/apps/LoRaMac/common/NvmCtxMgmt.c +++ /dev/null @@ -1,381 +0,0 @@ -/*! - * \file NvmCtxMgmt.c - * - * \brief NVM context management implementation - * - * \copyright Revised BSD License, see section \ref LICENSE. - * - * \code - * ______ _ - * / _____) _ | | - * ( (____ _____ ____ _| |_ _____ ____| |__ - * \____ \| ___ | (_ _) ___ |/ ___) _ \ - * _____) ) ____| | | || |_| ____( (___| | | | - * (______/|_____)_|_|_| \__)_____)\____)_| |_| - * (C)2013-2017 Semtech - * - * ___ _____ _ ___ _ _____ ___ ___ ___ ___ - * / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| - * \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| - * |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| - * embedded.connectivity.solutions=============== - * - * \endcode - * - * \author Miguel Luis ( Semtech ) - * - * \author Gregory Cristian ( Semtech ) - * - * \author Daniel Jaeckle ( STACKFORCE ) - * - * \author Johannes Bruder ( STACKFORCE ) - */ - -#include -#include "NvmCtxMgmt.h" -#include "utilities.h" -#include "eeprom.h" -#include "nvmm.h" - -/*! - * Enables/Disables the context storage management storage at all. Must be enabled for LoRaWAN 1.1.x. - * WARNING: Still under development and not tested yet. - */ -#define CONTEXT_MANAGEMENT_ENABLED 0 - -/*! - * Enables/Disables maximum persistent context storage management. All module contexts will be saved on a non-volatile memory. - * WARNING: Still under development and not tested yet. - */ -#define MAX_PERSISTENT_CTX_MGMT_ENABLED 0 - -#if ( MAX_PERSISTENT_CTX_MGMT_ENABLED == 1 ) -#define NVM_CTX_STORAGE_MASK 0xFF -#else -#define NVM_CTX_STORAGE_MASK 0x8C -#endif - -#if ( CONTEXT_MANAGEMENT_ENABLED == 1 ) -/*! - * LoRaMAC Structure holding contexts changed status - * in case of a \ref MLME_NVM_CTXS_UPDATE indication. - */ -typedef union uLoRaMacCtxsUpdateInfo -{ - /*! - * Byte-access to the bits - */ - uint8_t Value; - /*! - * The according context bit will be set to one - * if the context changed or 0 otherwise. - */ - struct sElements - { - /*! - * Mac core nvm context - */ - uint8_t Mac : 1; - /*! - * Region module nvm contexts - */ - uint8_t Region : 1; - /*! - * Cryto module context - */ - uint8_t Crypto : 1; - /*! - * Secure Element driver context - */ - uint8_t SecureElement : 1; - /*! - * MAC commands module context - */ - uint8_t Commands : 1; - /*! - * Class B module context - */ - uint8_t ClassB : 1; - /*! - * Confirm queue module context - */ - uint8_t ConfirmQueue : 1; - /*! - * FCnt Handler module context - */ - uint8_t FCntHandlerNvmCtx : 1; - }Elements; -}LoRaMacCtxUpdateStatus_t; - -LoRaMacCtxUpdateStatus_t CtxUpdateStatus = { .Value = 0 }; - -/* - * Nvmm handles - */ -static NvmmDataBlock_t SecureElementNvmCtxDataBlock; -static NvmmDataBlock_t CryptoNvmCtxDataBlock; -#if ( MAX_PERSISTENT_CTX_MGMT_ENABLED == 1 ) -static NvmmDataBlock_t MacNvmCtxDataBlock; -static NvmmDataBlock_t RegionNvmCtxDataBlock; -static NvmmDataBlock_t CommandsNvmCtxDataBlock; -static NvmmDataBlock_t ConfirmQueueNvmCtxDataBlock; -static NvmmDataBlock_t ClassBNvmCtxDataBlock; -#endif -#endif - -void NvmCtxMgmtEvent( LoRaMacNvmCtxModule_t module ) -{ -#if ( CONTEXT_MANAGEMENT_ENABLED == 1 ) - switch( module ) - { - case LORAMAC_NVMCTXMODULE_MAC: - { - CtxUpdateStatus.Elements.Mac = 1; - break; - } - case LORAMAC_NVMCTXMODULE_REGION: - { - CtxUpdateStatus.Elements.Region = 1; - break; - } - case LORAMAC_NVMCTXMODULE_CRYPTO: - { - CtxUpdateStatus.Elements.Crypto = 1; - break; - } - case LORAMAC_NVMCTXMODULE_SECURE_ELEMENT: - { - CtxUpdateStatus.Elements.SecureElement = 1; - break; - } - case LORAMAC_NVMCTXMODULE_COMMANDS: - { - CtxUpdateStatus.Elements.Commands = 1; - break; - } - case LORAMAC_NVMCTXMODULE_CLASS_B: - { - CtxUpdateStatus.Elements.ClassB = 1; - break; - } - case LORAMAC_NVMCTXMODULE_CONFIRM_QUEUE: - { - CtxUpdateStatus.Elements.ConfirmQueue = 1; - break; - } - default: - { - break; - } - } -#endif -} - -NvmCtxMgmtStatus_t NvmCtxMgmtStore( void ) -{ -#if ( CONTEXT_MANAGEMENT_ENABLED == 1 ) - // Read out the contexts lengths and pointers - MibRequestConfirm_t mibReq; - mibReq.Type = MIB_NVM_CTXS; - LoRaMacMibGetRequestConfirm( &mibReq ); - LoRaMacCtxs_t* MacContexts = mibReq.Param.Contexts; - - // Input checks - if( ( CtxUpdateStatus.Value & NVM_CTX_STORAGE_MASK ) == 0 ) - { - return NVMCTXMGMT_STATUS_FAIL; - } - if( LoRaMacStop( ) != LORAMAC_STATUS_OK ) - { - return NVMCTXMGMT_STATUS_FAIL; - } - - // Write - if( CtxUpdateStatus.Elements.Crypto == 1 ) - { - if( NvmmWrite( &CryptoNvmCtxDataBlock, MacContexts->CryptoNvmCtx, MacContexts->CryptoNvmCtxSize ) != NVMM_SUCCESS ) - { - return NVMCTXMGMT_STATUS_FAIL; - } - } - - if( CtxUpdateStatus.Elements.SecureElement == 1 ) - { - if( NvmmWrite( &SecureElementNvmCtxDataBlock, MacContexts->SecureElementNvmCtx, MacContexts->SecureElementNvmCtxSize ) != NVMM_SUCCESS ) - { - return NVMCTXMGMT_STATUS_FAIL; - } - } - -#if ( MAX_PERSISTENT_CTX_MGMT_ENABLED == 1 ) - if( CtxUpdateStatus.Elements.Mac == 1 ) - { - if( NvmmWrite( &MacNvmCtxDataBlock, MacContexts->MacNvmCtx, MacContexts->MacNvmCtxSize ) != NVMM_SUCCESS ) - { - return NVMCTXMGMT_STATUS_FAIL; - } - } - - if( CtxUpdateStatus.Elements.Region == 1 ) - { - if( NvmmWrite( &RegionNvmCtxDataBlock, MacContexts->RegionNvmCtx, MacContexts->RegionNvmCtxSize ) != NVMM_SUCCESS ) - { - return NVMCTXMGMT_STATUS_FAIL; - } - } - - if( CtxUpdateStatus.Elements.Commands == 1 ) - { - if( NvmmWrite( &CommandsNvmCtxDataBlock, MacContexts->CommandsNvmCtx, MacContexts->CommandsNvmCtxSize ) != NVMM_SUCCESS ) - { - return NVMCTXMGMT_STATUS_FAIL; - } - } - - if( CtxUpdateStatus.Elements.ClassB == 1 ) - { - if( NvmmWrite( &ClassBNvmCtxDataBlock, MacContexts->ClassBNvmCtx, MacContexts->ClassBNvmCtxSize ) != NVMM_SUCCESS ) - { - return NVMCTXMGMT_STATUS_FAIL; - } - } - - if( CtxUpdateStatus.Elements.ConfirmQueue == 1 ) - { - if( NvmmWrite( &ConfirmQueueNvmCtxDataBlock, MacContexts->ConfirmQueueNvmCtx, MacContexts->ConfirmQueueNvmCtxSize ) != NVMM_SUCCESS ) - { - return NVMCTXMGMT_STATUS_FAIL; - } - } -#endif - - CtxUpdateStatus.Value = 0x00; - - // Resume LoRaMac - LoRaMacStart( ); - - return NVMCTXMGMT_STATUS_SUCCESS; -#else - return NVMCTXMGMT_STATUS_FAIL; -#endif -} - -NvmCtxMgmtStatus_t NvmCtxMgmtRestore( void ) -{ -#if ( CONTEXT_MANAGEMENT_ENABLED == 1 ) - MibRequestConfirm_t mibReq; - LoRaMacCtxs_t contexts = { 0 }; - NvmCtxMgmtStatus_t status = NVMCTXMGMT_STATUS_SUCCESS; - - // Read out the contexts lengths - mibReq.Type = MIB_NVM_CTXS; - LoRaMacMibGetRequestConfirm( &mibReq ); - - - uint8_t NvmCryptoCtxRestore[mibReq.Param.Contexts->CryptoNvmCtxSize]; - uint8_t NvmSecureElementCtxRestore[mibReq.Param.Contexts->SecureElementNvmCtxSize]; -#if ( MAX_PERSISTENT_CTX_MGMT_ENABLED == 1 ) - uint8_t NvmMacCtxRestore[mibReq.Param.Contexts->MacNvmCtxSize]; - uint8_t NvmRegionCtxRestore[mibReq.Param.Contexts->RegionNvmCtxSize]; - uint8_t NvmCommandsCtxRestore[mibReq.Param.Contexts->CommandsNvmCtxSize]; - uint8_t NvmClassBCtxRestore[mibReq.Param.Contexts->ClassBNvmCtxSize]; - uint8_t NvmConfirmQueueCtxRestore[mibReq.Param.Contexts->ConfirmQueueNvmCtxSize]; -#endif - - if ( NvmmDeclare( &CryptoNvmCtxDataBlock, mibReq.Param.Contexts->CryptoNvmCtxSize ) == NVMM_SUCCESS ) - { - NvmmRead( &CryptoNvmCtxDataBlock, NvmCryptoCtxRestore, mibReq.Param.Contexts->CryptoNvmCtxSize ); - contexts.CryptoNvmCtx = &NvmCryptoCtxRestore; - contexts.CryptoNvmCtxSize = mibReq.Param.Contexts->CryptoNvmCtxSize; - } - else - { - status = NVMCTXMGMT_STATUS_FAIL; - } - - if ( NvmmDeclare( &SecureElementNvmCtxDataBlock, mibReq.Param.Contexts->SecureElementNvmCtxSize ) == NVMM_SUCCESS ) - { - NvmmRead( &SecureElementNvmCtxDataBlock, NvmSecureElementCtxRestore, mibReq.Param.Contexts->SecureElementNvmCtxSize ); - contexts.SecureElementNvmCtx = &NvmSecureElementCtxRestore; - contexts.SecureElementNvmCtxSize = mibReq.Param.Contexts->SecureElementNvmCtxSize; - } - else - { - status = NVMCTXMGMT_STATUS_FAIL; - } - -#if ( MAX_PERSISTENT_CTX_MGMT_ENABLED == 1 ) - if( NvmmDeclare( &MacNvmCtxDataBlock, mibReq.Param.Contexts->MacNvmCtxSize ) == NVMM_SUCCESS ) - { - NvmmRead( &MacNvmCtxDataBlock, NvmMacCtxRestore, mibReq.Param.Contexts->MacNvmCtxSize ); - contexts.MacNvmCtx = &NvmMacCtxRestore; - contexts.MacNvmCtxSize = mibReq.Param.Contexts->MacNvmCtxSize; - } - else - { - status = NVMCTXMGMT_STATUS_FAIL; - } - - if ( NvmmDeclare( &RegionNvmCtxDataBlock, mibReq.Param.Contexts->RegionNvmCtxSize ) == NVMM_SUCCESS ) - { - NvmmRead( &RegionNvmCtxDataBlock, NvmRegionCtxRestore, mibReq.Param.Contexts->RegionNvmCtxSize ); - contexts.RegionNvmCtx = &NvmRegionCtxRestore; - contexts.RegionNvmCtxSize = mibReq.Param.Contexts->RegionNvmCtxSize; - } - else - { - status = NVMCTXMGMT_STATUS_FAIL; - } - - if ( NvmmDeclare( &CommandsNvmCtxDataBlock, mibReq.Param.Contexts->CommandsNvmCtxSize ) == NVMM_SUCCESS ) - { - NvmmRead( &CommandsNvmCtxDataBlock, NvmCommandsCtxRestore, mibReq.Param.Contexts->CommandsNvmCtxSize ); - contexts.CommandsNvmCtx = &NvmCommandsCtxRestore; - contexts.CommandsNvmCtxSize = mibReq.Param.Contexts->CommandsNvmCtxSize; - } - else - { - status = NVMCTXMGMT_STATUS_FAIL; - } - - if ( NvmmDeclare( &ClassBNvmCtxDataBlock, mibReq.Param.Contexts->ClassBNvmCtxSize ) == NVMM_SUCCESS ) - { - NvmmRead( &ClassBNvmCtxDataBlock, NvmClassBCtxRestore, mibReq.Param.Contexts->ClassBNvmCtxSize ); - contexts.ClassBNvmCtx = &NvmClassBCtxRestore; - contexts.ClassBNvmCtxSize = mibReq.Param.Contexts->ClassBNvmCtxSize; - } - else - { - status = NVMCTXMGMT_STATUS_FAIL; - } - - if ( NvmmDeclare( &ConfirmQueueNvmCtxDataBlock, mibReq.Param.Contexts->ConfirmQueueNvmCtxSize ) == NVMM_SUCCESS ) - { - NvmmRead( &ConfirmQueueNvmCtxDataBlock, NvmConfirmQueueCtxRestore, mibReq.Param.Contexts->ConfirmQueueNvmCtxSize ); - contexts.ConfirmQueueNvmCtx = &NvmConfirmQueueCtxRestore; - contexts.ConfirmQueueNvmCtxSize = mibReq.Param.Contexts->ConfirmQueueNvmCtxSize; - } - else - { - status = NVMCTXMGMT_STATUS_FAIL; - } -#endif - - // Enforce storing all contexts - if( status == NVMCTXMGMT_STATUS_FAIL ) - { - CtxUpdateStatus.Value = 0xFF; - NvmCtxMgmtStore( ); - } - else - { // If successful query the mac to restore contexts - mibReq.Type = MIB_NVM_CTXS; - mibReq.Param.Contexts = &contexts; - LoRaMacMibSetRequestConfirm( &mibReq ); - } - - return status; -#else - return NVMCTXMGMT_STATUS_FAIL; -#endif -} diff --git a/src/apps/LoRaMac/common/NvmDataMgmt.c b/src/apps/LoRaMac/common/NvmDataMgmt.c new file mode 100644 index 000000000..f9e820d14 --- /dev/null +++ b/src/apps/LoRaMac/common/NvmDataMgmt.c @@ -0,0 +1,272 @@ +/*! + * \file NvmDataMgmt.c + * + * \brief NVM context management implementation + * + * \copyright Revised BSD License, see section \ref LICENSE. + * + * \code + * ______ _ + * / _____) _ | | + * ( (____ _____ ____ _| |_ _____ ____| |__ + * \____ \| ___ | (_ _) ___ |/ ___) _ \ + * _____) ) ____| | | || |_| ____( (___| | | | + * (______/|_____)_|_|_| \__)_____)\____)_| |_| + * (C)2013-2017 Semtech + * + * ___ _____ _ ___ _ _____ ___ ___ ___ ___ + * / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| + * \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| + * |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| + * embedded.connectivity.solutions=============== + * + * \endcode + * + * \author Miguel Luis ( Semtech ) + * + * \author Gregory Cristian ( Semtech ) + * + * \author Daniel Jaeckle ( STACKFORCE ) + * + * \author Johannes Bruder ( STACKFORCE ) + */ + +#include +#include "utilities.h" +#include "nvmm.h" +#include "LoRaMac.h" +#include "NvmDataMgmt.h" + +/*! + * Enables/Disables the context storage management storage. + * Must be enabled for LoRaWAN 1.0.4 or later. + */ +#ifndef CONTEXT_MANAGEMENT_ENABLED +#define CONTEXT_MANAGEMENT_ENABLED 1 +#endif + + +static uint16_t NvmNotifyFlags = 0; + +void NvmDataMgmtEvent( uint16_t notifyFlags ) +{ + NvmNotifyFlags = notifyFlags; +} + +uint16_t NvmDataMgmtStore( void ) +{ +#if( CONTEXT_MANAGEMENT_ENABLED == 1 ) + uint16_t offset = 0; + uint16_t dataSize = 0; + MibRequestConfirm_t mibReq; + mibReq.Type = MIB_NVM_CTXS; + LoRaMacMibGetRequestConfirm( &mibReq ); + LoRaMacNvmData_t* nvm = mibReq.Param.Contexts; + + // Input checks + if( NvmNotifyFlags == LORAMAC_NVM_NOTIFY_FLAG_NONE ) + { + // There was no update. + return 0; + } + if( LoRaMacStop( ) != LORAMAC_STATUS_OK ) + { + return 0; + } + + // Crypto + if( ( NvmNotifyFlags & LORAMAC_NVM_NOTIFY_FLAG_CRYPTO ) == + LORAMAC_NVM_NOTIFY_FLAG_CRYPTO ) + { + dataSize += NvmmWrite( ( uint8_t* ) &nvm->Crypto, sizeof( nvm->Crypto ), + offset ); + } + offset += sizeof( nvm->Crypto ); + + // MacGroup1 + if( ( NvmNotifyFlags & LORAMAC_NVM_NOTIFY_FLAG_MAC_GROUP1 ) == + LORAMAC_NVM_NOTIFY_FLAG_MAC_GROUP1 ) + { + dataSize += NvmmWrite( ( uint8_t* ) &nvm->MacGroup1, + sizeof( nvm->MacGroup1 ), offset ); + } + offset += sizeof( nvm->MacGroup1 ); + + // MacGroup2 + if( ( NvmNotifyFlags & LORAMAC_NVM_NOTIFY_FLAG_MAC_GROUP2 ) == + LORAMAC_NVM_NOTIFY_FLAG_MAC_GROUP2 ) + { + dataSize += NvmmWrite( ( uint8_t* ) &nvm->MacGroup2, + sizeof( nvm->MacGroup2 ), offset ); + } + offset += sizeof( nvm->MacGroup2 ); + + // Secure element + if( ( NvmNotifyFlags & LORAMAC_NVM_NOTIFY_FLAG_SECURE_ELEMENT ) == + LORAMAC_NVM_NOTIFY_FLAG_SECURE_ELEMENT ) + { + dataSize += NvmmWrite( ( uint8_t* ) &nvm->SecureElement, sizeof( nvm->SecureElement ), + offset ); + } + offset += sizeof( nvm->SecureElement ); + + // Region group 1 + if( ( NvmNotifyFlags & LORAMAC_NVM_NOTIFY_FLAG_REGION_GROUP1 ) == + LORAMAC_NVM_NOTIFY_FLAG_REGION_GROUP1 ) + { + dataSize += NvmmWrite( ( uint8_t* ) &nvm->RegionGroup1, + sizeof( nvm->RegionGroup1 ), offset ); + } + offset += sizeof( nvm->RegionGroup1 ); + + // Region group 2 + if( ( NvmNotifyFlags & LORAMAC_NVM_NOTIFY_FLAG_REGION_GROUP2 ) == + LORAMAC_NVM_NOTIFY_FLAG_REGION_GROUP2 ) + { + dataSize += NvmmWrite( ( uint8_t* ) &nvm->RegionGroup2, + sizeof( nvm->RegionGroup2 ), offset ); + } + offset += sizeof( nvm->RegionGroup2 ); + + // Class b + if( ( NvmNotifyFlags & LORAMAC_NVM_NOTIFY_FLAG_CLASS_B ) == + LORAMAC_NVM_NOTIFY_FLAG_CLASS_B ) + { + dataSize += NvmmWrite( ( uint8_t* ) &nvm->ClassB, sizeof( nvm->ClassB ), + offset ); + } + offset += sizeof( nvm->ClassB ); + + // Reset notification flags + NvmNotifyFlags = LORAMAC_NVM_NOTIFY_FLAG_NONE; + + // Resume LoRaMac + LoRaMacStart( ); + return dataSize; +#else + return 0; +#endif +} + +uint16_t NvmDataMgmtRestore( void ) +{ +#if( CONTEXT_MANAGEMENT_ENABLED == 1 ) + MibRequestConfirm_t mibReq; + mibReq.Type = MIB_NVM_CTXS; + LoRaMacMibGetRequestConfirm( &mibReq ); + LoRaMacNvmData_t* nvm = mibReq.Param.Contexts; + uint16_t offset = 0; + + // Crypto + if( NvmmCrc32Check( sizeof( LoRaMacCryptoNvmData_t ), offset ) == false ) + { + return 0; + } + offset += sizeof( LoRaMacCryptoNvmData_t ); + + // Mac Group 1 + if( NvmmCrc32Check( sizeof( LoRaMacNvmDataGroup1_t ), offset ) == false ) + { + return 0; + } + offset += sizeof( LoRaMacNvmDataGroup1_t ); + + // Mac Group 2 + if( NvmmCrc32Check( sizeof( LoRaMacNvmDataGroup2_t ), offset ) == false ) + { + return 0; + } + offset += sizeof( LoRaMacNvmDataGroup2_t ); + + // Secure element + if( NvmmCrc32Check( sizeof( SecureElementNvmData_t ), offset ) == false ) + { + return 0; + } + offset += sizeof( SecureElementNvmData_t ); + + // Region group 1 + if( NvmmCrc32Check( sizeof( RegionNvmDataGroup1_t ), offset ) == false ) + { + return 0; + } + offset += sizeof( RegionNvmDataGroup1_t ); + + // Region group 2 + if( NvmmCrc32Check( sizeof( RegionNvmDataGroup2_t ), offset ) == false ) + { + return 0; + } + offset += sizeof( RegionNvmDataGroup2_t ); + + // Class b + if( NvmmCrc32Check( sizeof( LoRaMacClassBNvmData_t ), offset ) == false ) + { + return 0; + } + offset += sizeof( LoRaMacClassBNvmData_t ); + + if( NvmmRead( ( uint8_t* ) nvm, sizeof( LoRaMacNvmData_t ), 0 ) == + sizeof( LoRaMacNvmData_t ) ) + { + return sizeof( LoRaMacNvmData_t ); + } +#endif + return 0; +} + +bool NvmDataMgmtFactoryReset( void ) +{ + uint16_t offset = 0; +#if( CONTEXT_MANAGEMENT_ENABLED == 1 ) + // Crypto + if( NvmmReset( sizeof( LoRaMacCryptoNvmData_t ), offset ) == false ) + { + return false; + } + offset += sizeof( LoRaMacCryptoNvmData_t ); + + // Mac Group 1 + if( NvmmReset( sizeof( LoRaMacNvmDataGroup1_t ), offset ) == false ) + { + return false; + } + offset += sizeof( LoRaMacNvmDataGroup1_t ); + + // Mac Group 2 + if( NvmmReset( sizeof( LoRaMacNvmDataGroup2_t ), offset ) == false ) + { + return false; + } + offset += sizeof( LoRaMacNvmDataGroup2_t ); + + // Secure element + if( NvmmReset( sizeof( SecureElementNvmData_t ), offset ) == false ) + { + return false; + } + offset += sizeof( SecureElementNvmData_t ); + + // Region group 1 + if( NvmmReset( sizeof( RegionNvmDataGroup1_t ), offset ) == false ) + { + return false; + } + offset += sizeof( RegionNvmDataGroup1_t ); + + // Region group 2 + if( NvmmReset( sizeof( RegionNvmDataGroup2_t ), offset ) == false ) + { + return false; + } + offset += sizeof( RegionNvmDataGroup2_t ); + + // Class b + if( NvmmReset( sizeof( LoRaMacClassBNvmData_t ), offset ) == false ) + { + return false; + } + offset += sizeof( LoRaMacClassBNvmData_t ); +#endif + return true; +} diff --git a/src/apps/LoRaMac/common/NvmCtxMgmt.h b/src/apps/LoRaMac/common/NvmDataMgmt.h similarity index 56% rename from src/apps/LoRaMac/common/NvmCtxMgmt.h rename to src/apps/LoRaMac/common/NvmDataMgmt.h index 068fe2dc4..f50df3836 100644 --- a/src/apps/LoRaMac/common/NvmCtxMgmt.h +++ b/src/apps/LoRaMac/common/NvmDataMgmt.h @@ -1,5 +1,5 @@ /*! - * \file NvmCtxMgmt.h + * \file NvmDataMgmt.h * * \brief NVM context management implementation * @@ -30,40 +30,42 @@ * * \author Johannes Bruder ( STACKFORCE ) * - * \defgroup NVMCTXMGMT NVM context management implementation + * \defgroup NVMDATAMGMT NVM context management implementation * This module implements the NVM context handling * \{ */ -#ifndef __NVMCTXMGMT_H__ -#define __NVMCTXMGMT_H__ - -#include "LoRaMac.h" +#ifndef __NVMDATAMGMT_H__ +#define __NVMDATAMGMT_H__ /*! - * Data structure containing the status of a operation + * \brief NVM Management event. + * + * \param [IN] notifyFlags Bitmap which contains the information about modules that + * changed. */ -typedef enum NvmCtxMgmtStatus_e -{ - /*! - * Operation was successful - */ - NVMCTXMGMT_STATUS_SUCCESS, - /*! - * Operation was not successful - */ - NVMCTXMGMT_STATUS_FAIL -}NvmCtxMgmtStatus_t; +void NvmDataMgmtEvent( uint16_t notifyFlags ); /*! - * \brief Calculates the next datarate to set, when ADR is on or off. + * \brief Function which stores the MAC data into NVM, if required. * - * \param [IN] adrNext Pointer to the function parameters. + * \retval Number of bytes which were stored. + */ +uint16_t NvmDataMgmtStore( void ); + +/*! + * \brief Function which restores the MAC data from NVM, if required. * + * \retval Number of bytes which were restored. */ -void NvmCtxMgmtEvent( LoRaMacNvmCtxModule_t module ); +uint16_t NvmDataMgmtRestore(void ); -NvmCtxMgmtStatus_t NvmCtxMgmtStore( void ); +/*! + * \brief Resets the NVM data. + * + * \retval Returns true, if successful. + */ +bool NvmDataMgmtFactoryReset( void ); -NvmCtxMgmtStatus_t NvmCtxMgmtRestore(void ); +/* \} */ -#endif // __NVMCTXMGMT_H__ +#endif // __NVMDATAMGMT_H__ diff --git a/src/apps/LoRaMac/common/cli.c b/src/apps/LoRaMac/common/cli.c new file mode 100644 index 000000000..88195e5e1 --- /dev/null +++ b/src/apps/LoRaMac/common/cli.c @@ -0,0 +1,56 @@ +/*! + * \file cli.h + * + * \brief Command Line Interface handling implementation + * + * \copyright Revised BSD License, see section \ref LICENSE. + * + * \code + * ______ _ + * / _____) _ | | + * ( (____ _____ ____ _| |_ _____ ____| |__ + * \____ \| ___ | (_ _) ___ |/ ___) _ \ + * _____) ) ____| | | || |_| ____( (___| | | | + * (______/|_____)_|_|_| \__)_____)\____)_| |_| + * (C)2013-2020 Semtech + * + * \endcode + */ +#include +#include +#include +#include "NvmDataMgmt.h" +#include "cli.h" + +void CliProcess( Uart_t* uart ) +{ + uint8_t data = 0; + + if( UartGetChar( uart, &data ) == 0 ) + { + if( data == '\x1B' ) + { // Escape character has been received + printf( "ESC + " ); + while( UartGetChar( uart, &data ) != 0 ) + { + } + printf( "%c\n", data ); + if( data == 'N' ) + { // N character has been received + data = 0; + // Reset NVM + if( NvmDataMgmtFactoryReset( ) == true ) + { + printf( "\n\nNVM factory reset succeed\n" ); + } + else + { + printf( "\n\nNVM factory reset failed\n" ); + } + + printf( "\n\nPLEASE RESET THE END-DEVICE\n\n" ); + while( 1 ); + } + } + } +} \ No newline at end of file diff --git a/src/apps/LoRaMac/common/cli.h b/src/apps/LoRaMac/common/cli.h new file mode 100644 index 000000000..b4cb295ee --- /dev/null +++ b/src/apps/LoRaMac/common/cli.h @@ -0,0 +1,41 @@ +/*! + * \file cli.h + * + * \brief Command Line Interface handling definition + * + * \copyright Revised BSD License, see section \ref LICENSE. + * + * \code + * ______ _ + * / _____) _ | | + * ( (____ _____ ____ _| |_ _____ ____| |__ + * \____ \| ___ | (_ _) ___ |/ ___) _ \ + * _____) ) ____| | | || |_| ____( (___| | | | + * (______/|_____)_|_|_| \__)_____)\____)_| |_| + * (C)2013-2020 Semtech + * + * \endcode + */ +#ifndef CLI_H +#define CLI_H + +#ifdef __cplusplus + extern "C" { +#endif + +#include "uart.h" + +/*! + * Process characters received on the serial interface + * \remark Characters sequence 'ESC' + 'N' execute a NVM factory reset + * All other sequences are ignored + * + * \param [IN] uart UART interface object used by the command line interface + */ +void CliProcess( Uart_t* uart ); + +#ifdef __cplusplus +} +#endif + +#endif // CLI_H diff --git a/src/apps/LoRaMac/fuota-test-01/B-L072Z-LRWAN1/main.c b/src/apps/LoRaMac/fuota-test-01/B-L072Z-LRWAN1/main.c index e4f26f90d..9ae56fb26 100644 --- a/src/apps/LoRaMac/fuota-test-01/B-L072Z-LRWAN1/main.c +++ b/src/apps/LoRaMac/fuota-test-01/B-L072Z-LRWAN1/main.c @@ -25,7 +25,9 @@ #include "utilities.h" #include "board.h" #include "gpio.h" +#include "uart.h" +#include "cli.h" #include "Commissioning.h" #include "LmHandler.h" #include "LmhpCompliance.h" @@ -129,7 +131,7 @@ static TimerEvent_t Led3Timer; static TimerEvent_t LedBeaconTimer; static void OnMacProcessNotify( void ); -static void OnNvmContextChange( LmHandlerNvmContextStates_t state ); +static void OnNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ); static void OnNetworkParametersChange( CommissioningParams_t* params ); static void OnMacMcpsRequest( LoRaMacStatus_t status, McpsReq_t *mcpsReq, TimerTime_t nextTxIn ); static void OnMacMlmeRequest( LoRaMacStatus_t status, MlmeReq_t *mlmeReq, TimerTime_t nextTxIn ); @@ -156,16 +158,6 @@ static void OnFragDone( int32_t status, uint8_t *file, uint32_t size ); static void StartTxProcess( LmHandlerTxEvents_t txEvent ); static void UplinkProcess( void ); -/*! - * Computes a CCITT 32 bits CRC - * - * \param [IN] buffer Data buffer used to compute the CRC - * \param [IN] length Data buffer length - * - * \retval crc The computed buffer of length CRC - */ -static uint32_t Crc32( uint8_t *buffer, uint16_t length ); - /*! * Function executed on TxTimer event */ @@ -197,7 +189,7 @@ static LmHandlerCallbacks_t LmHandlerCallbacks = .GetTemperature = NULL, .GetRandomSeed = BoardGetRandomSeed, .OnMacProcess = OnMacProcessNotify, - .OnNvmContextChange = OnNvmContextChange, + .OnNvmDataChange = OnNvmDataChange, .OnNetworkParametersChange = OnNetworkParametersChange, .OnMacMcpsRequest = OnMacMcpsRequest, .OnMacMlmeRequest = OnMacMlmeRequest, @@ -300,6 +292,11 @@ extern Gpio_t Led2; // Blinks every 5 seconds when beacon is acquired extern Gpio_t Led3; // Rx extern Gpio_t Led4; // App +/*! + * UART object used for command line interface handling + */ +extern Uart_t Uart2; + /*! * Main application entry point. */ @@ -328,7 +325,7 @@ int main( void ) if ( LmHandlerInit( &LmHandlerCallbacks, &LmHandlerParams ) != LORAMAC_HANDLER_SUCCESS ) { - printf( "LoRaMac wasn't properly initialized" ); + printf( "LoRaMac wasn't properly initialized\n" ); // Fatal error, endless loop. while ( 1 ) { @@ -354,6 +351,9 @@ int main( void ) while( 1 ) { + // Process characters sent over the command line interface + CliProcess( &Uart2 ); + // Processes the LoRaMac events LmHandlerProcess( ); @@ -380,9 +380,9 @@ static void OnMacProcessNotify( void ) IsMacProcessPending = 1; } -static void OnNvmContextChange( LmHandlerNvmContextStates_t state ) +static void OnNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ) { - DisplayNvmContextChange( state ); + DisplayNvmDataChange( state, size ); } static void OnNetworkParametersChange( CommissioningParams_t* params ) @@ -705,28 +705,3 @@ static void OnLedBeaconTimerEvent( void* context ) TimerStart( &LedBeaconTimer ); } - -static uint32_t Crc32( uint8_t *buffer, uint16_t length ) -{ - // The CRC calculation follows CCITT - 0x04C11DB7 - const uint32_t reversedPolynom = 0xEDB88320; - - // CRC initial value - uint32_t crc = 0xFFFFFFFF; - - if( buffer == NULL ) - { - return 0; - } - - for( uint16_t i = 0; i < length; ++i ) - { - crc ^= ( uint32_t )buffer[i]; - for( uint16_t i = 0; i < 8; i++ ) - { - crc = ( crc >> 1 ) ^ ( reversedPolynom & ~( ( crc & 0x01 ) - 1 ) ); - } - } - - return ~crc; -} diff --git a/src/apps/LoRaMac/fuota-test-01/NAMote72/main.c b/src/apps/LoRaMac/fuota-test-01/NAMote72/main.c index a1847cfea..b656382ae 100644 --- a/src/apps/LoRaMac/fuota-test-01/NAMote72/main.c +++ b/src/apps/LoRaMac/fuota-test-01/NAMote72/main.c @@ -26,9 +26,11 @@ #include "board-config.h" #include "board.h" #include "gpio.h" +#include "uart.h" #include "gps.h" #include "mpl3115.h" +#include "cli.h" #include "Commissioning.h" #include "LmHandler.h" #include "LmhpCompliance.h" @@ -127,7 +129,7 @@ static TimerEvent_t Led2Timer; static TimerEvent_t LedBeaconTimer; static void OnMacProcessNotify( void ); -static void OnNvmContextChange( LmHandlerNvmContextStates_t state ); +static void OnNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ); static void OnNetworkParametersChange( CommissioningParams_t* params ); static void OnMacMcpsRequest( LoRaMacStatus_t status, McpsReq_t *mcpsReq, TimerTime_t nextTxIn ); static void OnMacMlmeRequest( LoRaMacStatus_t status, MlmeReq_t *mlmeReq, TimerTime_t nextTxIn ); @@ -154,16 +156,6 @@ static void OnFragDone( int32_t status, uint8_t *file, uint32_t size ); static void StartTxProcess( LmHandlerTxEvents_t txEvent ); static void UplinkProcess( void ); -/*! - * Computes a CCITT 32 bits CRC - * - * \param [IN] buffer Data buffer used to compute the CRC - * \param [IN] length Data buffer length - * - * \retval crc The computed buffer of length CRC - */ -static uint32_t Crc32( uint8_t *buffer, uint16_t length ); - /*! * Function executed on TxTimer event */ @@ -190,7 +182,7 @@ static LmHandlerCallbacks_t LmHandlerCallbacks = .GetTemperature = MPL3115ReadTemperature, .GetRandomSeed = BoardGetRandomSeed, .OnMacProcess = OnMacProcessNotify, - .OnNvmContextChange = OnNvmContextChange, + .OnNvmDataChange = OnNvmDataChange, .OnNetworkParametersChange = OnNetworkParametersChange, .OnMacMcpsRequest = OnMacMcpsRequest, .OnMacMlmeRequest = OnMacMlmeRequest, @@ -292,6 +284,11 @@ extern Gpio_t Led1; // Tx extern Gpio_t Led2; // Rx extern Gpio_t Led3; // App +/*! + * UART object used for command line interface handling + */ +extern Uart_t Uart2; + /*! * Main application entry point. */ @@ -317,7 +314,7 @@ int main( void ) if ( LmHandlerInit( &LmHandlerCallbacks, &LmHandlerParams ) != LORAMAC_HANDLER_SUCCESS ) { - printf( "LoRaMac wasn't properly initialized" ); + printf( "LoRaMac wasn't properly initialized\n" ); // Fatal error, endless loop. while ( 1 ) { @@ -343,6 +340,9 @@ int main( void ) while( 1 ) { + // Process characters sent over the command line interface + CliProcess( &Uart2 ); + // Processes the LoRaMac events LmHandlerProcess( ); @@ -369,9 +369,9 @@ static void OnMacProcessNotify( void ) IsMacProcessPending = 1; } -static void OnNvmContextChange( LmHandlerNvmContextStates_t state ) +static void OnNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ) { - DisplayNvmContextChange( state ); + DisplayNvmDataChange( state, size ); } static void OnNetworkParametersChange( CommissioningParams_t* params ) @@ -684,28 +684,3 @@ static void OnLedBeaconTimerEvent( void* context ) TimerStart( &LedBeaconTimer ); } - -static uint32_t Crc32( uint8_t *buffer, uint16_t length ) -{ - // The CRC calculation follows CCITT - 0x04C11DB7 - const uint32_t reversedPolynom = 0xEDB88320; - - // CRC initial value - uint32_t crc = 0xFFFFFFFF; - - if( buffer == NULL ) - { - return 0; - } - - for( uint16_t i = 0; i < length; ++i ) - { - crc ^= ( uint32_t )buffer[i]; - for( uint16_t i = 0; i < 8; i++ ) - { - crc = ( crc >> 1 ) ^ ( reversedPolynom & ~( ( crc & 0x01 ) - 1 ) ); - } - } - - return ~crc; -} diff --git a/src/apps/LoRaMac/fuota-test-01/NucleoL073/main.c b/src/apps/LoRaMac/fuota-test-01/NucleoL073/main.c index 59d83c7b8..9aa933bd0 100644 --- a/src/apps/LoRaMac/fuota-test-01/NucleoL073/main.c +++ b/src/apps/LoRaMac/fuota-test-01/NucleoL073/main.c @@ -25,7 +25,9 @@ #include "utilities.h" #include "board.h" #include "gpio.h" +#include "uart.h" +#include "cli.h" #include "Commissioning.h" #include "LmHandler.h" #include "LmhpCompliance.h" @@ -124,7 +126,7 @@ static TimerEvent_t Led2Timer; static TimerEvent_t LedBeaconTimer; static void OnMacProcessNotify( void ); -static void OnNvmContextChange( LmHandlerNvmContextStates_t state ); +static void OnNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ); static void OnNetworkParametersChange( CommissioningParams_t* params ); static void OnMacMcpsRequest( LoRaMacStatus_t status, McpsReq_t *mcpsReq, TimerTime_t nextTxIn ); static void OnMacMlmeRequest( LoRaMacStatus_t status, MlmeReq_t *mlmeReq, TimerTime_t nextTxIn ); @@ -151,16 +153,6 @@ static void OnFragDone( int32_t status, uint8_t *file, uint32_t size ); static void StartTxProcess( LmHandlerTxEvents_t txEvent ); static void UplinkProcess( void ); -/*! - * Computes a CCITT 32 bits CRC - * - * \param [IN] buffer Data buffer used to compute the CRC - * \param [IN] length Data buffer length - * - * \retval crc The computed buffer of length CRC - */ -static uint32_t Crc32( uint8_t *buffer, uint16_t length ); - /*! * Function executed on TxTimer event */ @@ -187,7 +179,7 @@ static LmHandlerCallbacks_t LmHandlerCallbacks = .GetTemperature = NULL, .GetRandomSeed = BoardGetRandomSeed, .OnMacProcess = OnMacProcessNotify, - .OnNvmContextChange = OnNvmContextChange, + .OnNvmDataChange = OnNvmDataChange, .OnNetworkParametersChange = OnNetworkParametersChange, .OnMacMcpsRequest = OnMacMcpsRequest, .OnMacMlmeRequest = OnMacMlmeRequest, @@ -288,6 +280,11 @@ static volatile uint32_t FileRxCrc = 0; extern Gpio_t Led1; // Tx extern Gpio_t Led2; // Rx +/*! + * UART object used for command line interface handling + */ +extern Uart_t Uart2; + /*! * Main application entry point. */ @@ -313,7 +310,7 @@ int main( void ) if ( LmHandlerInit( &LmHandlerCallbacks, &LmHandlerParams ) != LORAMAC_HANDLER_SUCCESS ) { - printf( "LoRaMac wasn't properly initialized" ); + printf( "LoRaMac wasn't properly initialized\n" ); // Fatal error, endless loop. while ( 1 ) { @@ -339,6 +336,9 @@ int main( void ) while( 1 ) { + // Process characters sent over the command line interface + CliProcess( &Uart2 ); + // Processes the LoRaMac events LmHandlerProcess( ); @@ -365,9 +365,9 @@ static void OnMacProcessNotify( void ) IsMacProcessPending = 1; } -static void OnNvmContextChange( LmHandlerNvmContextStates_t state ) +static void OnNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ) { - DisplayNvmContextChange( state ); + DisplayNvmDataChange( state, size ); } static void OnNetworkParametersChange( CommissioningParams_t* params ) @@ -680,28 +680,3 @@ static void OnLedBeaconTimerEvent( void* context ) TimerStart( &LedBeaconTimer ); } - -static uint32_t Crc32( uint8_t *buffer, uint16_t length ) -{ - // The CRC calculation follows CCITT - 0x04C11DB7 - const uint32_t reversedPolynom = 0xEDB88320; - - // CRC initial value - uint32_t crc = 0xFFFFFFFF; - - if( buffer == NULL ) - { - return 0; - } - - for( uint16_t i = 0; i < length; ++i ) - { - crc ^= ( uint32_t )buffer[i]; - for( uint16_t i = 0; i < 8; i++ ) - { - crc = ( crc >> 1 ) ^ ( reversedPolynom & ~( ( crc & 0x01 ) - 1 ) ); - } - } - - return ~crc; -} diff --git a/src/apps/LoRaMac/fuota-test-01/NucleoL152/main.c b/src/apps/LoRaMac/fuota-test-01/NucleoL152/main.c index c0e158fb8..c4ca731f0 100644 --- a/src/apps/LoRaMac/fuota-test-01/NucleoL152/main.c +++ b/src/apps/LoRaMac/fuota-test-01/NucleoL152/main.c @@ -25,7 +25,9 @@ #include "utilities.h" #include "board.h" #include "gpio.h" +#include "uart.h" +#include "cli.h" #include "Commissioning.h" #include "LmHandler.h" #include "LmhpCompliance.h" @@ -124,7 +126,7 @@ static TimerEvent_t Led2Timer; static TimerEvent_t LedBeaconTimer; static void OnMacProcessNotify( void ); -static void OnNvmContextChange( LmHandlerNvmContextStates_t state ); +static void OnNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ); static void OnNetworkParametersChange( CommissioningParams_t* params ); static void OnMacMcpsRequest( LoRaMacStatus_t status, McpsReq_t *mcpsReq, TimerTime_t nextTxIn ); static void OnMacMlmeRequest( LoRaMacStatus_t status, MlmeReq_t *mlmeReq, TimerTime_t nextTxIn ); @@ -151,16 +153,6 @@ static void OnFragDone( int32_t status, uint8_t *file, uint32_t size ); static void StartTxProcess( LmHandlerTxEvents_t txEvent ); static void UplinkProcess( void ); -/*! - * Computes a CCITT 32 bits CRC - * - * \param [IN] buffer Data buffer used to compute the CRC - * \param [IN] length Data buffer length - * - * \retval crc The computed buffer of length CRC - */ -static uint32_t Crc32( uint8_t *buffer, uint16_t length ); - /*! * Function executed on TxTimer event */ @@ -187,7 +179,7 @@ static LmHandlerCallbacks_t LmHandlerCallbacks = .GetTemperature = NULL, .GetRandomSeed = BoardGetRandomSeed, .OnMacProcess = OnMacProcessNotify, - .OnNvmContextChange = OnNvmContextChange, + .OnNvmDataChange = OnNvmDataChange, .OnNetworkParametersChange = OnNetworkParametersChange, .OnMacMcpsRequest = OnMacMcpsRequest, .OnMacMlmeRequest = OnMacMlmeRequest, @@ -288,6 +280,11 @@ static volatile uint32_t FileRxCrc = 0; extern Gpio_t Led1; // Tx extern Gpio_t Led2; // Rx +/*! + * UART object used for command line interface handling + */ +extern Uart_t Uart2; + /*! * Main application entry point. */ @@ -313,7 +310,7 @@ int main( void ) if ( LmHandlerInit( &LmHandlerCallbacks, &LmHandlerParams ) != LORAMAC_HANDLER_SUCCESS ) { - printf( "LoRaMac wasn't properly initialized" ); + printf( "LoRaMac wasn't properly initialized\n" ); // Fatal error, endless loop. while ( 1 ) { @@ -339,6 +336,9 @@ int main( void ) while( 1 ) { + // Process characters sent over the command line interface + CliProcess( &Uart2 ); + // Processes the LoRaMac events LmHandlerProcess( ); @@ -365,9 +365,9 @@ static void OnMacProcessNotify( void ) IsMacProcessPending = 1; } -static void OnNvmContextChange( LmHandlerNvmContextStates_t state ) +static void OnNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ) { - DisplayNvmContextChange( state ); + DisplayNvmDataChange( state, size ); } static void OnNetworkParametersChange( CommissioningParams_t* params ) @@ -680,28 +680,3 @@ static void OnLedBeaconTimerEvent( void* context ) TimerStart( &LedBeaconTimer ); } - -static uint32_t Crc32( uint8_t *buffer, uint16_t length ) -{ - // The CRC calculation follows CCITT - 0x04C11DB7 - const uint32_t reversedPolynom = 0xEDB88320; - - // CRC initial value - uint32_t crc = 0xFFFFFFFF; - - if( buffer == NULL ) - { - return 0; - } - - for( uint16_t i = 0; i < length; ++i ) - { - crc ^= ( uint32_t )buffer[i]; - for( uint16_t i = 0; i < 8; i++ ) - { - crc = ( crc >> 1 ) ^ ( reversedPolynom & ~( ( crc & 0x01 ) - 1 ) ); - } - } - - return ~crc; -} diff --git a/src/apps/LoRaMac/fuota-test-01/NucleoL476/main.c b/src/apps/LoRaMac/fuota-test-01/NucleoL476/main.c index c647f20fd..ae2b5a55a 100644 --- a/src/apps/LoRaMac/fuota-test-01/NucleoL476/main.c +++ b/src/apps/LoRaMac/fuota-test-01/NucleoL476/main.c @@ -25,7 +25,9 @@ #include "utilities.h" #include "board.h" #include "gpio.h" +#include "uart.h" +#include "cli.h" #include "Commissioning.h" #include "LmHandler.h" #include "LmhpCompliance.h" @@ -124,7 +126,7 @@ static TimerEvent_t Led2Timer; static TimerEvent_t LedBeaconTimer; static void OnMacProcessNotify( void ); -static void OnNvmContextChange( LmHandlerNvmContextStates_t state ); +static void OnNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ); static void OnNetworkParametersChange( CommissioningParams_t* params ); static void OnMacMcpsRequest( LoRaMacStatus_t status, McpsReq_t *mcpsReq, TimerTime_t nextTxIn ); static void OnMacMlmeRequest( LoRaMacStatus_t status, MlmeReq_t *mlmeReq, TimerTime_t nextTxIn ); @@ -151,16 +153,6 @@ static void OnFragDone( int32_t status, uint8_t *file, uint32_t size ); static void StartTxProcess( LmHandlerTxEvents_t txEvent ); static void UplinkProcess( void ); -/*! - * Computes a CCITT 32 bits CRC - * - * \param [IN] buffer Data buffer used to compute the CRC - * \param [IN] length Data buffer length - * - * \retval crc The computed buffer of length CRC - */ -static uint32_t Crc32( uint8_t *buffer, uint16_t length ); - /*! * Function executed on TxTimer event */ @@ -187,7 +179,7 @@ static LmHandlerCallbacks_t LmHandlerCallbacks = .GetTemperature = NULL, .GetRandomSeed = BoardGetRandomSeed, .OnMacProcess = OnMacProcessNotify, - .OnNvmContextChange = OnNvmContextChange, + .OnNvmDataChange = OnNvmDataChange, .OnNetworkParametersChange = OnNetworkParametersChange, .OnMacMcpsRequest = OnMacMcpsRequest, .OnMacMlmeRequest = OnMacMlmeRequest, @@ -288,6 +280,11 @@ static volatile uint32_t FileRxCrc = 0; extern Gpio_t Led1; // Tx extern Gpio_t Led2; // Rx +/*! + * UART object used for command line interface handling + */ +extern Uart_t Uart2; + /*! * Main application entry point. */ @@ -313,7 +310,7 @@ int main( void ) if ( LmHandlerInit( &LmHandlerCallbacks, &LmHandlerParams ) != LORAMAC_HANDLER_SUCCESS ) { - printf( "LoRaMac wasn't properly initialized" ); + printf( "LoRaMac wasn't properly initialized\n" ); // Fatal error, endless loop. while ( 1 ) { @@ -339,6 +336,9 @@ int main( void ) while( 1 ) { + // Process characters sent over the command line interface + CliProcess( &Uart2 ); + // Processes the LoRaMac events LmHandlerProcess( ); @@ -365,9 +365,9 @@ static void OnMacProcessNotify( void ) IsMacProcessPending = 1; } -static void OnNvmContextChange( LmHandlerNvmContextStates_t state ) +static void OnNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ) { - DisplayNvmContextChange( state ); + DisplayNvmDataChange( state, size ); } static void OnNetworkParametersChange( CommissioningParams_t* params ) @@ -680,28 +680,3 @@ static void OnLedBeaconTimerEvent( void* context ) TimerStart( &LedBeaconTimer ); } - -static uint32_t Crc32( uint8_t *buffer, uint16_t length ) -{ - // The CRC calculation follows CCITT - 0x04C11DB7 - const uint32_t reversedPolynom = 0xEDB88320; - - // CRC initial value - uint32_t crc = 0xFFFFFFFF; - - if( buffer == NULL ) - { - return 0; - } - - for( uint16_t i = 0; i < length; ++i ) - { - crc ^= ( uint32_t )buffer[i]; - for( uint16_t i = 0; i < 8; i++ ) - { - crc = ( crc >> 1 ) ^ ( reversedPolynom & ~( ( crc & 0x01 ) - 1 ) ); - } - } - - return ~crc; -} diff --git a/src/apps/LoRaMac/fuota-test-01/SAMR34/main.c b/src/apps/LoRaMac/fuota-test-01/SAMR34/main.c index 93ee12879..060b14db6 100644 --- a/src/apps/LoRaMac/fuota-test-01/SAMR34/main.c +++ b/src/apps/LoRaMac/fuota-test-01/SAMR34/main.c @@ -25,7 +25,9 @@ #include "utilities.h" #include "board.h" #include "gpio.h" +#include "uart.h" +#include "cli.h" #include "Commissioning.h" #include "LmHandler.h" #include "LmhpCompliance.h" @@ -114,7 +116,7 @@ static TimerEvent_t TxTimer; static TimerEvent_t Led1Timer; static void OnMacProcessNotify( void ); -static void OnNvmContextChange( LmHandlerNvmContextStates_t state ); +static void OnNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ); static void OnNetworkParametersChange( CommissioningParams_t* params ); static void OnMacMcpsRequest( LoRaMacStatus_t status, McpsReq_t *mcpsReq, TimerTime_t nextTxIn ); static void OnMacMlmeRequest( LoRaMacStatus_t status, MlmeReq_t *mlmeReq, TimerTime_t nextTxIn ); @@ -141,16 +143,6 @@ static void OnFragDone( int32_t status, uint8_t *file, uint32_t size ); static void StartTxProcess( LmHandlerTxEvents_t txEvent ); static void UplinkProcess( void ); -/*! - * Computes a CCITT 32 bits CRC - * - * \param [IN] buffer Data buffer used to compute the CRC - * \param [IN] length Data buffer length - * - * \retval crc The computed buffer of length CRC - */ -static uint32_t Crc32( uint8_t *buffer, uint16_t length ); - /*! * Function executed on TxTimer event */ @@ -167,7 +159,7 @@ static LmHandlerCallbacks_t LmHandlerCallbacks = .GetTemperature = NULL, .GetRandomSeed = BoardGetRandomSeed, .OnMacProcess = OnMacProcessNotify, - .OnNvmContextChange = OnNvmContextChange, + .OnNvmDataChange = OnNvmDataChange, .OnNetworkParametersChange = OnNetworkParametersChange, .OnMacMcpsRequest = OnMacMcpsRequest, .OnMacMlmeRequest = OnMacMlmeRequest, @@ -267,6 +259,11 @@ static volatile uint32_t FileRxCrc = 0; */ extern Gpio_t Led1; // Rx +/*! + * UART object used for command line interface handling + */ +extern Uart_t Uart1; + /*! * Main application entry point. */ @@ -286,7 +283,7 @@ int main( void ) if ( LmHandlerInit( &LmHandlerCallbacks, &LmHandlerParams ) != LORAMAC_HANDLER_SUCCESS ) { - printf( "LoRaMac wasn't properly initialized" ); + printf( "LoRaMac wasn't properly initialized\n" ); // Fatal error, endless loop. while ( 1 ) { @@ -315,6 +312,9 @@ int main( void ) // Tick the RTC to execute callback in context of the main loop (in stead of the IRQ) TimerProcess( ); + // Process characters sent over the command line interface + CliProcess( &Uart1 ); + // Processes the LoRaMac events LmHandlerProcess( ); @@ -341,9 +341,9 @@ static void OnMacProcessNotify( void ) IsMacProcessPending = 1; } -static void OnNvmContextChange( LmHandlerNvmContextStates_t state ) +static void OnNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ) { - DisplayNvmContextChange( state ); + DisplayNvmDataChange( state, size ); } static void OnNetworkParametersChange( CommissioningParams_t* params ) @@ -625,28 +625,3 @@ static void OnLed1TimerEvent( void* context ) // Switch LED 1 ON GpioWrite( &Led1, 1 ); } - -static uint32_t Crc32( uint8_t *buffer, uint16_t length ) -{ - // The CRC calculation follows CCITT - 0x04C11DB7 - const uint32_t reversedPolynom = 0xEDB88320; - - // CRC initial value - uint32_t crc = 0xFFFFFFFF; - - if( buffer == NULL ) - { - return 0; - } - - for( uint16_t i = 0; i < length; ++i ) - { - crc ^= ( uint32_t )buffer[i]; - for( uint16_t i = 0; i < 8; i++ ) - { - crc = ( crc >> 1 ) ^ ( reversedPolynom & ~( ( crc & 0x01 ) - 1 ) ); - } - } - - return ~crc; -} diff --git a/src/apps/LoRaMac/fuota-test-01/SKiM880B/main.c b/src/apps/LoRaMac/fuota-test-01/SKiM880B/main.c index 1ad597d3d..e34866e45 100644 --- a/src/apps/LoRaMac/fuota-test-01/SKiM880B/main.c +++ b/src/apps/LoRaMac/fuota-test-01/SKiM880B/main.c @@ -25,7 +25,9 @@ #include "utilities.h" #include "board.h" #include "gpio.h" +#include "uart.h" +#include "cli.h" #include "Commissioning.h" #include "LmHandler.h" #include "LmhpCompliance.h" @@ -119,7 +121,7 @@ static TimerEvent_t Led4Timer; static TimerEvent_t Led2Timer; static void OnMacProcessNotify( void ); -static void OnNvmContextChange( LmHandlerNvmContextStates_t state ); +static void OnNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ); static void OnNetworkParametersChange( CommissioningParams_t* params ); static void OnMacMcpsRequest( LoRaMacStatus_t status, McpsReq_t *mcpsReq, TimerTime_t nextTxIn ); static void OnMacMlmeRequest( LoRaMacStatus_t status, MlmeReq_t *mlmeReq, TimerTime_t nextTxIn ); @@ -146,16 +148,6 @@ static void OnFragDone( int32_t status, uint8_t *file, uint32_t size ); static void StartTxProcess( LmHandlerTxEvents_t txEvent ); static void UplinkProcess( void ); -/*! - * Computes a CCITT 32 bits CRC - * - * \param [IN] buffer Data buffer used to compute the CRC - * \param [IN] length Data buffer length - * - * \retval crc The computed buffer of length CRC - */ -static uint32_t Crc32( uint8_t *buffer, uint16_t length ); - /*! * Function executed on TxTimer event */ @@ -177,7 +169,7 @@ static LmHandlerCallbacks_t LmHandlerCallbacks = .GetTemperature = NULL, .GetRandomSeed = BoardGetRandomSeed, .OnMacProcess = OnMacProcessNotify, - .OnNvmContextChange = OnNvmContextChange, + .OnNvmDataChange = OnNvmDataChange, .OnNetworkParametersChange = OnNetworkParametersChange, .OnMacMcpsRequest = OnMacMcpsRequest, .OnMacMlmeRequest = OnMacMlmeRequest, @@ -279,6 +271,11 @@ extern Gpio_t Led4; // Tx extern Gpio_t Led2; // Rx extern Gpio_t Led3; // App +/*! + * UART object used for command line interface handling + */ +extern Uart_t Uart1; + /*! * Main application entry point. */ @@ -301,7 +298,7 @@ int main( void ) if ( LmHandlerInit( &LmHandlerCallbacks, &LmHandlerParams ) != LORAMAC_HANDLER_SUCCESS ) { - printf( "LoRaMac wasn't properly initialized" ); + printf( "LoRaMac wasn't properly initialized\n" ); // Fatal error, endless loop. while ( 1 ) { @@ -327,6 +324,9 @@ int main( void ) while( 1 ) { + // Process characters sent over the command line interface + CliProcess( &Uart1 ); + // Processes the LoRaMac events LmHandlerProcess( ); @@ -353,9 +353,9 @@ static void OnMacProcessNotify( void ) IsMacProcessPending = 1; } -static void OnNvmContextChange( LmHandlerNvmContextStates_t state ) +static void OnNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ) { - DisplayNvmContextChange( state ); + DisplayNvmDataChange( state, size ); } static void OnNetworkParametersChange( CommissioningParams_t* params ) @@ -655,28 +655,3 @@ static void OnLed2TimerEvent( void* context ) // Switch LED 2 ON GpioWrite( &Led2, 1 ); } - -static uint32_t Crc32( uint8_t *buffer, uint16_t length ) -{ - // The CRC calculation follows CCITT - 0x04C11DB7 - const uint32_t reversedPolynom = 0xEDB88320; - - // CRC initial value - uint32_t crc = 0xFFFFFFFF; - - if( buffer == NULL ) - { - return 0; - } - - for( uint16_t i = 0; i < length; ++i ) - { - crc ^= ( uint32_t )buffer[i]; - for( uint16_t i = 0; i < 8; i++ ) - { - crc = ( crc >> 1 ) ^ ( reversedPolynom & ~( ( crc & 0x01 ) - 1 ) ); - } - } - - return ~crc; -} diff --git a/src/apps/LoRaMac/fuota-test-01/SKiM881AXL/main.c b/src/apps/LoRaMac/fuota-test-01/SKiM881AXL/main.c index 782495936..eeb23734d 100644 --- a/src/apps/LoRaMac/fuota-test-01/SKiM881AXL/main.c +++ b/src/apps/LoRaMac/fuota-test-01/SKiM881AXL/main.c @@ -25,7 +25,9 @@ #include "utilities.h" #include "board.h" #include "gpio.h" +#include "uart.h" +#include "cli.h" #include "Commissioning.h" #include "LmHandler.h" #include "LmhpCompliance.h" @@ -119,7 +121,7 @@ static TimerEvent_t Led4Timer; static TimerEvent_t Led2Timer; static void OnMacProcessNotify( void ); -static void OnNvmContextChange( LmHandlerNvmContextStates_t state ); +static void OnNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ); static void OnNetworkParametersChange( CommissioningParams_t* params ); static void OnMacMcpsRequest( LoRaMacStatus_t status, McpsReq_t *mcpsReq, TimerTime_t nextTxIn ); static void OnMacMlmeRequest( LoRaMacStatus_t status, MlmeReq_t *mlmeReq, TimerTime_t nextTxIn ); @@ -146,16 +148,6 @@ static void OnFragDone( int32_t status, uint8_t *file, uint32_t size ); static void StartTxProcess( LmHandlerTxEvents_t txEvent ); static void UplinkProcess( void ); -/*! - * Computes a CCITT 32 bits CRC - * - * \param [IN] buffer Data buffer used to compute the CRC - * \param [IN] length Data buffer length - * - * \retval crc The computed buffer of length CRC - */ -static uint32_t Crc32( uint8_t *buffer, uint16_t length ); - /*! * Function executed on TxTimer event */ @@ -177,7 +169,7 @@ static LmHandlerCallbacks_t LmHandlerCallbacks = .GetTemperature = NULL, .GetRandomSeed = BoardGetRandomSeed, .OnMacProcess = OnMacProcessNotify, - .OnNvmContextChange = OnNvmContextChange, + .OnNvmDataChange = OnNvmDataChange, .OnNetworkParametersChange = OnNetworkParametersChange, .OnMacMcpsRequest = OnMacMcpsRequest, .OnMacMlmeRequest = OnMacMlmeRequest, @@ -279,6 +271,11 @@ extern Gpio_t Led4; // Tx extern Gpio_t Led2; // Rx extern Gpio_t Led3; // App +/*! + * UART object used for command line interface handling + */ +extern Uart_t Uart1; + /*! * Main application entry point. */ @@ -301,7 +298,7 @@ int main( void ) if ( LmHandlerInit( &LmHandlerCallbacks, &LmHandlerParams ) != LORAMAC_HANDLER_SUCCESS ) { - printf( "LoRaMac wasn't properly initialized" ); + printf( "LoRaMac wasn't properly initialized\n" ); // Fatal error, endless loop. while ( 1 ) { @@ -327,6 +324,9 @@ int main( void ) while( 1 ) { + // Process characters sent over the command line interface + CliProcess( &Uart1 ); + // Processes the LoRaMac events LmHandlerProcess( ); @@ -353,9 +353,9 @@ static void OnMacProcessNotify( void ) IsMacProcessPending = 1; } -static void OnNvmContextChange( LmHandlerNvmContextStates_t state ) +static void OnNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ) { - DisplayNvmContextChange( state ); + DisplayNvmDataChange( state, size ); } static void OnNetworkParametersChange( CommissioningParams_t* params ) @@ -655,28 +655,3 @@ static void OnLed2TimerEvent( void* context ) // Switch LED 2 ON GpioWrite( &Led2, 1 ); } - -static uint32_t Crc32( uint8_t *buffer, uint16_t length ) -{ - // The CRC calculation follows CCITT - 0x04C11DB7 - const uint32_t reversedPolynom = 0xEDB88320; - - // CRC initial value - uint32_t crc = 0xFFFFFFFF; - - if( buffer == NULL ) - { - return 0; - } - - for( uint16_t i = 0; i < length; ++i ) - { - crc ^= ( uint32_t )buffer[i]; - for( uint16_t i = 0; i < 8; i++ ) - { - crc = ( crc >> 1 ) ^ ( reversedPolynom & ~( ( crc & 0x01 ) - 1 ) ); - } - } - - return ~crc; -} diff --git a/src/apps/LoRaMac/fuota-test-01/SKiM980A/main.c b/src/apps/LoRaMac/fuota-test-01/SKiM980A/main.c index b902a35fc..cb69cf692 100644 --- a/src/apps/LoRaMac/fuota-test-01/SKiM980A/main.c +++ b/src/apps/LoRaMac/fuota-test-01/SKiM980A/main.c @@ -25,7 +25,9 @@ #include "utilities.h" #include "board.h" #include "gpio.h" +#include "uart.h" +#include "cli.h" #include "Commissioning.h" #include "LmHandler.h" #include "LmhpCompliance.h" @@ -119,7 +121,7 @@ static TimerEvent_t Led4Timer; static TimerEvent_t Led2Timer; static void OnMacProcessNotify( void ); -static void OnNvmContextChange( LmHandlerNvmContextStates_t state ); +static void OnNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ); static void OnNetworkParametersChange( CommissioningParams_t* params ); static void OnMacMcpsRequest( LoRaMacStatus_t status, McpsReq_t *mcpsReq, TimerTime_t nextTxIn ); static void OnMacMlmeRequest( LoRaMacStatus_t status, MlmeReq_t *mlmeReq, TimerTime_t nextTxIn ); @@ -146,16 +148,6 @@ static void OnFragDone( int32_t status, uint8_t *file, uint32_t size ); static void StartTxProcess( LmHandlerTxEvents_t txEvent ); static void UplinkProcess( void ); -/*! - * Computes a CCITT 32 bits CRC - * - * \param [IN] buffer Data buffer used to compute the CRC - * \param [IN] length Data buffer length - * - * \retval crc The computed buffer of length CRC - */ -static uint32_t Crc32( uint8_t *buffer, uint16_t length ); - /*! * Function executed on TxTimer event */ @@ -177,7 +169,7 @@ static LmHandlerCallbacks_t LmHandlerCallbacks = .GetTemperature = NULL, .GetRandomSeed = BoardGetRandomSeed, .OnMacProcess = OnMacProcessNotify, - .OnNvmContextChange = OnNvmContextChange, + .OnNvmDataChange = OnNvmDataChange, .OnNetworkParametersChange = OnNetworkParametersChange, .OnMacMcpsRequest = OnMacMcpsRequest, .OnMacMlmeRequest = OnMacMlmeRequest, @@ -279,6 +271,11 @@ extern Gpio_t Led4; // Tx extern Gpio_t Led2; // Rx extern Gpio_t Led3; // App +/*! + * UART object used for command line interface handling + */ +extern Uart_t Uart1; + /*! * Main application entry point. */ @@ -301,7 +298,7 @@ int main( void ) if ( LmHandlerInit( &LmHandlerCallbacks, &LmHandlerParams ) != LORAMAC_HANDLER_SUCCESS ) { - printf( "LoRaMac wasn't properly initialized" ); + printf( "LoRaMac wasn't properly initialized\n" ); // Fatal error, endless loop. while ( 1 ) { @@ -327,6 +324,9 @@ int main( void ) while( 1 ) { + // Process characters sent over the command line interface + CliProcess( &Uart1 ); + // Processes the LoRaMac events LmHandlerProcess( ); @@ -353,9 +353,9 @@ static void OnMacProcessNotify( void ) IsMacProcessPending = 1; } -static void OnNvmContextChange( LmHandlerNvmContextStates_t state ) +static void OnNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ) { - DisplayNvmContextChange( state ); + DisplayNvmDataChange( state, size ); } static void OnNetworkParametersChange( CommissioningParams_t* params ) @@ -655,28 +655,3 @@ static void OnLed2TimerEvent( void* context ) // Switch LED 2 ON GpioWrite( &Led2, 1 ); } - -static uint32_t Crc32( uint8_t *buffer, uint16_t length ) -{ - // The CRC calculation follows CCITT - 0x04C11DB7 - const uint32_t reversedPolynom = 0xEDB88320; - - // CRC initial value - uint32_t crc = 0xFFFFFFFF; - - if( buffer == NULL ) - { - return 0; - } - - for( uint16_t i = 0; i < length; ++i ) - { - crc ^= ( uint32_t )buffer[i]; - for( uint16_t i = 0; i < 8; i++ ) - { - crc = ( crc >> 1 ) ^ ( reversedPolynom & ~( ( crc & 0x01 ) - 1 ) ); - } - } - - return ~crc; -} diff --git a/src/apps/LoRaMac/periodic-uplink-lpp/B-L072Z-LRWAN1/main.c b/src/apps/LoRaMac/periodic-uplink-lpp/B-L072Z-LRWAN1/main.c index 03d595cc3..35d7ed936 100644 --- a/src/apps/LoRaMac/periodic-uplink-lpp/B-L072Z-LRWAN1/main.c +++ b/src/apps/LoRaMac/periodic-uplink-lpp/B-L072Z-LRWAN1/main.c @@ -25,7 +25,9 @@ #include "utilities.h" #include "board.h" #include "gpio.h" +#include "uart.h" +#include "cli.h" #include "Commissioning.h" #include "LmHandler.h" #include "LmhpCompliance.h" @@ -148,7 +150,7 @@ static TimerEvent_t Led3Timer; static TimerEvent_t LedBeaconTimer; static void OnMacProcessNotify( void ); -static void OnNvmContextChange( LmHandlerNvmContextStates_t state ); +static void OnNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ); static void OnNetworkParametersChange( CommissioningParams_t* params ); static void OnMacMcpsRequest( LoRaMacStatus_t status, McpsReq_t *mcpsReq, TimerTime_t nextTxIn ); static void OnMacMlmeRequest( LoRaMacStatus_t status, MlmeReq_t *mlmeReq, TimerTime_t nextTxIn ); @@ -197,7 +199,7 @@ static LmHandlerCallbacks_t LmHandlerCallbacks = .GetTemperature = NULL, .GetRandomSeed = BoardGetRandomSeed, .OnMacProcess = OnMacProcessNotify, - .OnNvmContextChange = OnNvmContextChange, + .OnNvmDataChange = OnNvmDataChange, .OnNetworkParametersChange = OnNetworkParametersChange, .OnMacMcpsRequest = OnMacMcpsRequest, .OnMacMlmeRequest = OnMacMlmeRequest, @@ -245,6 +247,11 @@ extern Gpio_t Led2; // Blinks every 5 seconds when beacon is acquired extern Gpio_t Led3; // Rx extern Gpio_t Led4; // App +/*! + * UART object used for command line interface handling + */ +extern Uart_t Uart2; + /*! * Main application entry point. */ @@ -273,7 +280,7 @@ int main( void ) if ( LmHandlerInit( &LmHandlerCallbacks, &LmHandlerParams ) != LORAMAC_HANDLER_SUCCESS ) { - printf( "LoRaMac wasn't properly initialized" ); + printf( "LoRaMac wasn't properly initialized\n" ); // Fatal error, endless loop. while ( 1 ) { @@ -293,6 +300,9 @@ int main( void ) while( 1 ) { + // Process characters sent over the command line interface + CliProcess( &Uart2 ); + // Processes the LoRaMac events LmHandlerProcess( ); @@ -319,9 +329,9 @@ static void OnMacProcessNotify( void ) IsMacProcessPending = 1; } -static void OnNvmContextChange( LmHandlerNvmContextStates_t state ) +static void OnNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ) { - DisplayNvmContextChange( state ); + DisplayNvmDataChange( state, size ); } static void OnNetworkParametersChange( CommissioningParams_t* params ) diff --git a/src/apps/LoRaMac/periodic-uplink-lpp/NAMote72/main.c b/src/apps/LoRaMac/periodic-uplink-lpp/NAMote72/main.c index 69ab0761b..3f0fd8d87 100644 --- a/src/apps/LoRaMac/periodic-uplink-lpp/NAMote72/main.c +++ b/src/apps/LoRaMac/periodic-uplink-lpp/NAMote72/main.c @@ -26,9 +26,11 @@ #include "board-config.h" #include "board.h" #include "gpio.h" +#include "uart.h" #include "gps.h" #include "mpl3115.h" +#include "cli.h" #include "Commissioning.h" #include "LmHandler.h" #include "LmhpCompliance.h" @@ -146,7 +148,7 @@ static TimerEvent_t Led2Timer; static TimerEvent_t LedBeaconTimer; static void OnMacProcessNotify( void ); -static void OnNvmContextChange( LmHandlerNvmContextStates_t state ); +static void OnNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ); static void OnNetworkParametersChange( CommissioningParams_t* params ); static void OnMacMcpsRequest( LoRaMacStatus_t status, McpsReq_t *mcpsReq, TimerTime_t nextTxIn ); static void OnMacMlmeRequest( LoRaMacStatus_t status, MlmeReq_t *mlmeReq, TimerTime_t nextTxIn ); @@ -190,7 +192,7 @@ static LmHandlerCallbacks_t LmHandlerCallbacks = .GetTemperature = MPL3115ReadTemperature, .GetRandomSeed = BoardGetRandomSeed, .OnMacProcess = OnMacProcessNotify, - .OnNvmContextChange = OnNvmContextChange, + .OnNvmDataChange = OnNvmDataChange, .OnNetworkParametersChange = OnNetworkParametersChange, .OnMacMcpsRequest = OnMacMcpsRequest, .OnMacMlmeRequest = OnMacMlmeRequest, @@ -237,6 +239,11 @@ extern Gpio_t Led1; // Tx extern Gpio_t Led2; // Rx and blinks every 5 seconds when beacon is acquired extern Gpio_t Led3; // App +/*! + * UART object used for command line interface handling + */ +extern Uart_t Uart2; + /*! * Main application entry point. */ @@ -262,7 +269,7 @@ int main( void ) if ( LmHandlerInit( &LmHandlerCallbacks, &LmHandlerParams ) != LORAMAC_HANDLER_SUCCESS ) { - printf( "LoRaMac wasn't properly initialized" ); + printf( "LoRaMac wasn't properly initialized\n" ); // Fatal error, endless loop. while ( 1 ) { @@ -282,6 +289,9 @@ int main( void ) while( 1 ) { + // Process characters sent over the command line interface + CliProcess( &Uart2 ); + // Processes the LoRaMac events LmHandlerProcess( ); @@ -308,9 +318,9 @@ static void OnMacProcessNotify( void ) IsMacProcessPending = 1; } -static void OnNvmContextChange( LmHandlerNvmContextStates_t state ) +static void OnNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ) { - DisplayNvmContextChange( state ); + DisplayNvmDataChange( state, size ); } static void OnNetworkParametersChange( CommissioningParams_t* params ) diff --git a/src/apps/LoRaMac/periodic-uplink-lpp/NucleoL073/main.c b/src/apps/LoRaMac/periodic-uplink-lpp/NucleoL073/main.c index 199b89f10..504587eb2 100644 --- a/src/apps/LoRaMac/periodic-uplink-lpp/NucleoL073/main.c +++ b/src/apps/LoRaMac/periodic-uplink-lpp/NucleoL073/main.c @@ -25,7 +25,9 @@ #include "utilities.h" #include "board.h" #include "gpio.h" +#include "uart.h" +#include "cli.h" #include "Commissioning.h" #include "LmHandler.h" #include "LmhpCompliance.h" @@ -143,7 +145,7 @@ static TimerEvent_t Led2Timer; static TimerEvent_t LedBeaconTimer; static void OnMacProcessNotify( void ); -static void OnNvmContextChange( LmHandlerNvmContextStates_t state ); +static void OnNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ); static void OnNetworkParametersChange( CommissioningParams_t* params ); static void OnMacMcpsRequest( LoRaMacStatus_t status, McpsReq_t *mcpsReq, TimerTime_t nextTxIn ); static void OnMacMlmeRequest( LoRaMacStatus_t status, MlmeReq_t *mlmeReq, TimerTime_t nextTxIn ); @@ -187,7 +189,7 @@ static LmHandlerCallbacks_t LmHandlerCallbacks = .GetTemperature = NULL, .GetRandomSeed = BoardGetRandomSeed, .OnMacProcess = OnMacProcessNotify, - .OnNvmContextChange = OnNvmContextChange, + .OnNvmDataChange = OnNvmDataChange, .OnNetworkParametersChange = OnNetworkParametersChange, .OnMacMcpsRequest = OnMacMcpsRequest, .OnMacMlmeRequest = OnMacMlmeRequest, @@ -233,6 +235,11 @@ static volatile uint8_t IsTxFramePending = 0; extern Gpio_t Led1; // Tx extern Gpio_t Led2; // Rx +/*! + * UART object used for command line interface handling + */ +extern Uart_t Uart2; + /*! * Main application entry point. */ @@ -258,7 +265,7 @@ int main( void ) if ( LmHandlerInit( &LmHandlerCallbacks, &LmHandlerParams ) != LORAMAC_HANDLER_SUCCESS ) { - printf( "LoRaMac wasn't properly initialized" ); + printf( "LoRaMac wasn't properly initialized\n" ); // Fatal error, endless loop. while ( 1 ) { @@ -278,6 +285,9 @@ int main( void ) while( 1 ) { + // Process characters sent over the command line interface + CliProcess( &Uart2 ); + // Processes the LoRaMac events LmHandlerProcess( ); @@ -304,9 +314,9 @@ static void OnMacProcessNotify( void ) IsMacProcessPending = 1; } -static void OnNvmContextChange( LmHandlerNvmContextStates_t state ) +static void OnNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ) { - DisplayNvmContextChange( state ); + DisplayNvmDataChange( state, size ); } static void OnNetworkParametersChange( CommissioningParams_t* params ) diff --git a/src/apps/LoRaMac/periodic-uplink-lpp/NucleoL152/main.c b/src/apps/LoRaMac/periodic-uplink-lpp/NucleoL152/main.c index eab404502..bcae7c1f4 100644 --- a/src/apps/LoRaMac/periodic-uplink-lpp/NucleoL152/main.c +++ b/src/apps/LoRaMac/periodic-uplink-lpp/NucleoL152/main.c @@ -25,7 +25,9 @@ #include "utilities.h" #include "board.h" #include "gpio.h" +#include "uart.h" +#include "cli.h" #include "Commissioning.h" #include "LmHandler.h" #include "LmhpCompliance.h" @@ -143,7 +145,7 @@ static TimerEvent_t Led2Timer; static TimerEvent_t LedBeaconTimer; static void OnMacProcessNotify( void ); -static void OnNvmContextChange( LmHandlerNvmContextStates_t state ); +static void OnNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ); static void OnNetworkParametersChange( CommissioningParams_t* params ); static void OnMacMcpsRequest( LoRaMacStatus_t status, McpsReq_t *mcpsReq, TimerTime_t nextTxIn ); static void OnMacMlmeRequest( LoRaMacStatus_t status, MlmeReq_t *mlmeReq, TimerTime_t nextTxIn ); @@ -187,7 +189,7 @@ static LmHandlerCallbacks_t LmHandlerCallbacks = .GetTemperature = NULL, .GetRandomSeed = BoardGetRandomSeed, .OnMacProcess = OnMacProcessNotify, - .OnNvmContextChange = OnNvmContextChange, + .OnNvmDataChange = OnNvmDataChange, .OnNetworkParametersChange = OnNetworkParametersChange, .OnMacMcpsRequest = OnMacMcpsRequest, .OnMacMlmeRequest = OnMacMlmeRequest, @@ -233,6 +235,11 @@ static volatile uint8_t IsTxFramePending = 0; extern Gpio_t Led1; // Tx extern Gpio_t Led2; // Rx +/*! + * UART object used for command line interface handling + */ +extern Uart_t Uart2; + /*! * Main application entry point. */ @@ -258,7 +265,7 @@ int main( void ) if ( LmHandlerInit( &LmHandlerCallbacks, &LmHandlerParams ) != LORAMAC_HANDLER_SUCCESS ) { - printf( "LoRaMac wasn't properly initialized" ); + printf( "LoRaMac wasn't properly initialized\n" ); // Fatal error, endless loop. while ( 1 ) { @@ -278,6 +285,9 @@ int main( void ) while( 1 ) { + // Process characters sent over the command line interface + CliProcess( &Uart2 ); + // Processes the LoRaMac events LmHandlerProcess( ); @@ -304,9 +314,9 @@ static void OnMacProcessNotify( void ) IsMacProcessPending = 1; } -static void OnNvmContextChange( LmHandlerNvmContextStates_t state ) +static void OnNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ) { - DisplayNvmContextChange( state ); + DisplayNvmDataChange( state, size ); } static void OnNetworkParametersChange( CommissioningParams_t* params ) diff --git a/src/apps/LoRaMac/periodic-uplink-lpp/NucleoL476/main.c b/src/apps/LoRaMac/periodic-uplink-lpp/NucleoL476/main.c index 655021431..e46300d75 100644 --- a/src/apps/LoRaMac/periodic-uplink-lpp/NucleoL476/main.c +++ b/src/apps/LoRaMac/periodic-uplink-lpp/NucleoL476/main.c @@ -25,7 +25,9 @@ #include "utilities.h" #include "board.h" #include "gpio.h" +#include "uart.h" +#include "cli.h" #include "Commissioning.h" #include "LmHandler.h" #include "LmhpCompliance.h" @@ -143,7 +145,7 @@ static TimerEvent_t Led2Timer; static TimerEvent_t LedBeaconTimer; static void OnMacProcessNotify( void ); -static void OnNvmContextChange( LmHandlerNvmContextStates_t state ); +static void OnNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ); static void OnNetworkParametersChange( CommissioningParams_t* params ); static void OnMacMcpsRequest( LoRaMacStatus_t status, McpsReq_t *mcpsReq, TimerTime_t nextTxIn ); static void OnMacMlmeRequest( LoRaMacStatus_t status, MlmeReq_t *mlmeReq, TimerTime_t nextTxIn ); @@ -187,7 +189,7 @@ static LmHandlerCallbacks_t LmHandlerCallbacks = .GetTemperature = NULL, .GetRandomSeed = BoardGetRandomSeed, .OnMacProcess = OnMacProcessNotify, - .OnNvmContextChange = OnNvmContextChange, + .OnNvmDataChange = OnNvmDataChange, .OnNetworkParametersChange = OnNetworkParametersChange, .OnMacMcpsRequest = OnMacMcpsRequest, .OnMacMlmeRequest = OnMacMlmeRequest, @@ -233,6 +235,11 @@ static volatile uint8_t IsTxFramePending = 0; extern Gpio_t Led1; // Tx extern Gpio_t Led2; // Rx +/*! + * UART object used for command line interface handling + */ +extern Uart_t Uart2; + /*! * Main application entry point. */ @@ -258,7 +265,7 @@ int main( void ) if ( LmHandlerInit( &LmHandlerCallbacks, &LmHandlerParams ) != LORAMAC_HANDLER_SUCCESS ) { - printf( "LoRaMac wasn't properly initialized" ); + printf( "LoRaMac wasn't properly initialized\n" ); // Fatal error, endless loop. while ( 1 ) { @@ -278,6 +285,9 @@ int main( void ) while( 1 ) { + // Process characters sent over the command line interface + CliProcess( &Uart2 ); + // Processes the LoRaMac events LmHandlerProcess( ); @@ -304,9 +314,9 @@ static void OnMacProcessNotify( void ) IsMacProcessPending = 1; } -static void OnNvmContextChange( LmHandlerNvmContextStates_t state ) +static void OnNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ) { - DisplayNvmContextChange( state ); + DisplayNvmDataChange( state, size ); } static void OnNetworkParametersChange( CommissioningParams_t* params ) diff --git a/src/apps/LoRaMac/periodic-uplink-lpp/SAMR34/main.c b/src/apps/LoRaMac/periodic-uplink-lpp/SAMR34/main.c index 274d40cd4..6d2307418 100644 --- a/src/apps/LoRaMac/periodic-uplink-lpp/SAMR34/main.c +++ b/src/apps/LoRaMac/periodic-uplink-lpp/SAMR34/main.c @@ -25,7 +25,9 @@ #include "utilities.h" #include "board.h" #include "gpio.h" +#include "uart.h" +#include "cli.h" #include "Commissioning.h" #include "LmHandler.h" #include "LmhpCompliance.h" @@ -143,7 +145,7 @@ static TimerEvent_t Led2Timer; static TimerEvent_t LedBeaconTimer; static void OnMacProcessNotify( void ); -static void OnNvmContextChange( LmHandlerNvmContextStates_t state ); +static void OnNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ); static void OnNetworkParametersChange( CommissioningParams_t* params ); static void OnMacMcpsRequest( LoRaMacStatus_t status, McpsReq_t *mcpsReq, TimerTime_t nextTxIn ); static void OnMacMlmeRequest( LoRaMacStatus_t status, MlmeReq_t *mlmeReq, TimerTime_t nextTxIn ); @@ -187,7 +189,7 @@ static LmHandlerCallbacks_t LmHandlerCallbacks = .GetTemperature = NULL, .GetRandomSeed = BoardGetRandomSeed, .OnMacProcess = OnMacProcessNotify, - .OnNvmContextChange = OnNvmContextChange, + .OnNvmDataChange = OnNvmDataChange, .OnNetworkParametersChange = OnNetworkParametersChange, .OnMacMcpsRequest = OnMacMcpsRequest, .OnMacMlmeRequest = OnMacMlmeRequest, @@ -232,6 +234,11 @@ static volatile uint8_t IsTxFramePending = 0; */ extern Gpio_t Led1; // Tx +/*! + * UART object used for command line interface handling + */ +extern Uart_t Uart1; + /*! * Main application entry point. */ @@ -257,7 +264,7 @@ int main( void ) if ( LmHandlerInit( &LmHandlerCallbacks, &LmHandlerParams ) != LORAMAC_HANDLER_SUCCESS ) { - printf( "LoRaMac wasn't properly initialized" ); + printf( "LoRaMac wasn't properly initialized\n" ); // Fatal error, endless loop. while ( 1 ) { @@ -280,6 +287,9 @@ int main( void ) // Tick the RTC to execute callback in context of the main loop (in stead of the IRQ) TimerProcess( ); + // Process characters sent over the command line interface + CliProcess( &Uart1 ); + // Processes the LoRaMac events LmHandlerProcess( ); @@ -306,9 +316,9 @@ static void OnMacProcessNotify( void ) IsMacProcessPending = 1; } -static void OnNvmContextChange( LmHandlerNvmContextStates_t state ) +static void OnNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ) { - DisplayNvmContextChange( state ); + DisplayNvmDataChange( state, size ); } static void OnNetworkParametersChange( CommissioningParams_t* params ) diff --git a/src/apps/LoRaMac/periodic-uplink-lpp/SKiM880B/main.c b/src/apps/LoRaMac/periodic-uplink-lpp/SKiM880B/main.c index 7900604e0..7a4b6cf1a 100644 --- a/src/apps/LoRaMac/periodic-uplink-lpp/SKiM880B/main.c +++ b/src/apps/LoRaMac/periodic-uplink-lpp/SKiM880B/main.c @@ -25,7 +25,9 @@ #include "utilities.h" #include "board.h" #include "gpio.h" +#include "uart.h" +#include "cli.h" #include "Commissioning.h" #include "LmHandler.h" #include "LmhpCompliance.h" @@ -143,7 +145,7 @@ static TimerEvent_t Led2Timer; static TimerEvent_t LedBeaconTimer; static void OnMacProcessNotify( void ); -static void OnNvmContextChange( LmHandlerNvmContextStates_t state ); +static void OnNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ); static void OnNetworkParametersChange( CommissioningParams_t* params ); static void OnMacMcpsRequest( LoRaMacStatus_t status, McpsReq_t *mcpsReq, TimerTime_t nextTxIn ); static void OnMacMlmeRequest( LoRaMacStatus_t status, MlmeReq_t *mlmeReq, TimerTime_t nextTxIn ); @@ -187,7 +189,7 @@ static LmHandlerCallbacks_t LmHandlerCallbacks = .GetTemperature = NULL, .GetRandomSeed = BoardGetRandomSeed, .OnMacProcess = OnMacProcessNotify, - .OnNvmContextChange = OnNvmContextChange, + .OnNvmDataChange = OnNvmDataChange, .OnNetworkParametersChange = OnNetworkParametersChange, .OnMacMcpsRequest = OnMacMcpsRequest, .OnMacMlmeRequest = OnMacMlmeRequest, @@ -234,6 +236,11 @@ extern Gpio_t Led4; // Tx extern Gpio_t Led2; // Rx and blinks every 5 seconds when beacon is acquired extern Gpio_t Led3; // App +/*! + * UART object used for command line interface handling + */ +extern Uart_t Uart1; + /*! * Main application entry point. */ @@ -259,7 +266,7 @@ int main( void ) if ( LmHandlerInit( &LmHandlerCallbacks, &LmHandlerParams ) != LORAMAC_HANDLER_SUCCESS ) { - printf( "LoRaMac wasn't properly initialized" ); + printf( "LoRaMac wasn't properly initialized\n" ); // Fatal error, endless loop. while ( 1 ) { @@ -279,6 +286,9 @@ int main( void ) while( 1 ) { + // Process characters sent over the command line interface + CliProcess( &Uart1 ); + // Processes the LoRaMac events LmHandlerProcess( ); @@ -305,9 +315,9 @@ static void OnMacProcessNotify( void ) IsMacProcessPending = 1; } -static void OnNvmContextChange( LmHandlerNvmContextStates_t state ) +static void OnNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ) { - DisplayNvmContextChange( state ); + DisplayNvmDataChange( state, size ); } static void OnNetworkParametersChange( CommissioningParams_t* params ) diff --git a/src/apps/LoRaMac/periodic-uplink-lpp/SKiM881AXL/main.c b/src/apps/LoRaMac/periodic-uplink-lpp/SKiM881AXL/main.c index 4891f4a78..bfb9db7f0 100644 --- a/src/apps/LoRaMac/periodic-uplink-lpp/SKiM881AXL/main.c +++ b/src/apps/LoRaMac/periodic-uplink-lpp/SKiM881AXL/main.c @@ -25,7 +25,9 @@ #include "utilities.h" #include "board.h" #include "gpio.h" +#include "uart.h" +#include "cli.h" #include "Commissioning.h" #include "LmHandler.h" #include "LmhpCompliance.h" @@ -143,7 +145,7 @@ static TimerEvent_t Led2Timer; static TimerEvent_t LedBeaconTimer; static void OnMacProcessNotify( void ); -static void OnNvmContextChange( LmHandlerNvmContextStates_t state ); +static void OnNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ); static void OnNetworkParametersChange( CommissioningParams_t* params ); static void OnMacMcpsRequest( LoRaMacStatus_t status, McpsReq_t *mcpsReq, TimerTime_t nextTxIn ); static void OnMacMlmeRequest( LoRaMacStatus_t status, MlmeReq_t *mlmeReq, TimerTime_t nextTxIn ); @@ -187,7 +189,7 @@ static LmHandlerCallbacks_t LmHandlerCallbacks = .GetTemperature = NULL, .GetRandomSeed = BoardGetRandomSeed, .OnMacProcess = OnMacProcessNotify, - .OnNvmContextChange = OnNvmContextChange, + .OnNvmDataChange = OnNvmDataChange, .OnNetworkParametersChange = OnNetworkParametersChange, .OnMacMcpsRequest = OnMacMcpsRequest, .OnMacMlmeRequest = OnMacMlmeRequest, @@ -234,6 +236,11 @@ extern Gpio_t Led4; // Tx extern Gpio_t Led2; // Rx and blinks every 5 seconds when beacon is acquired extern Gpio_t Led3; // App +/*! + * UART object used for command line interface handling + */ +extern Uart_t Uart1; + /*! * Main application entry point. */ @@ -259,7 +266,7 @@ int main( void ) if ( LmHandlerInit( &LmHandlerCallbacks, &LmHandlerParams ) != LORAMAC_HANDLER_SUCCESS ) { - printf( "LoRaMac wasn't properly initialized" ); + printf( "LoRaMac wasn't properly initialized\n" ); // Fatal error, endless loop. while ( 1 ) { @@ -279,6 +286,9 @@ int main( void ) while( 1 ) { + // Process characters sent over the command line interface + CliProcess( &Uart1 ); + // Processes the LoRaMac events LmHandlerProcess( ); @@ -305,9 +315,9 @@ static void OnMacProcessNotify( void ) IsMacProcessPending = 1; } -static void OnNvmContextChange( LmHandlerNvmContextStates_t state ) +static void OnNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ) { - DisplayNvmContextChange( state ); + DisplayNvmDataChange( state, size ); } static void OnNetworkParametersChange( CommissioningParams_t* params ) diff --git a/src/apps/LoRaMac/periodic-uplink-lpp/SKiM980A/main.c b/src/apps/LoRaMac/periodic-uplink-lpp/SKiM980A/main.c index 56f9b6ac8..c24b8c521 100644 --- a/src/apps/LoRaMac/periodic-uplink-lpp/SKiM980A/main.c +++ b/src/apps/LoRaMac/periodic-uplink-lpp/SKiM980A/main.c @@ -25,7 +25,9 @@ #include "utilities.h" #include "board.h" #include "gpio.h" +#include "uart.h" +#include "cli.h" #include "Commissioning.h" #include "LmHandler.h" #include "LmhpCompliance.h" @@ -143,7 +145,7 @@ static TimerEvent_t Led2Timer; static TimerEvent_t LedBeaconTimer; static void OnMacProcessNotify( void ); -static void OnNvmContextChange( LmHandlerNvmContextStates_t state ); +static void OnNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ); static void OnNetworkParametersChange( CommissioningParams_t* params ); static void OnMacMcpsRequest( LoRaMacStatus_t status, McpsReq_t *mcpsReq, TimerTime_t nextTxIn ); static void OnMacMlmeRequest( LoRaMacStatus_t status, MlmeReq_t *mlmeReq, TimerTime_t nextTxIn ); @@ -187,7 +189,7 @@ static LmHandlerCallbacks_t LmHandlerCallbacks = .GetTemperature = NULL, .GetRandomSeed = BoardGetRandomSeed, .OnMacProcess = OnMacProcessNotify, - .OnNvmContextChange = OnNvmContextChange, + .OnNvmDataChange = OnNvmDataChange, .OnNetworkParametersChange = OnNetworkParametersChange, .OnMacMcpsRequest = OnMacMcpsRequest, .OnMacMlmeRequest = OnMacMlmeRequest, @@ -234,6 +236,11 @@ extern Gpio_t Led4; // Tx extern Gpio_t Led2; // Rx and blinks every 5 seconds when beacon is acquired extern Gpio_t Led3; // App +/*! + * UART object used for command line interface handling + */ +extern Uart_t Uart1; + /*! * Main application entry point. */ @@ -259,7 +266,7 @@ int main( void ) if ( LmHandlerInit( &LmHandlerCallbacks, &LmHandlerParams ) != LORAMAC_HANDLER_SUCCESS ) { - printf( "LoRaMac wasn't properly initialized" ); + printf( "LoRaMac wasn't properly initialized\n" ); // Fatal error, endless loop. while ( 1 ) { @@ -279,6 +286,9 @@ int main( void ) while( 1 ) { + // Process characters sent over the command line interface + CliProcess( &Uart1 ); + // Processes the LoRaMac events LmHandlerProcess( ); @@ -305,9 +315,9 @@ static void OnMacProcessNotify( void ) IsMacProcessPending = 1; } -static void OnNvmContextChange( LmHandlerNvmContextStates_t state ) +static void OnNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size ) { - DisplayNvmContextChange( state ); + DisplayNvmDataChange( state, size ); } static void OnNetworkParametersChange( CommissioningParams_t* params ) diff --git a/src/boards/B-L072Z-LRWAN1/eeprom-board.c b/src/boards/B-L072Z-LRWAN1/eeprom-board.c index b7e2f0303..ca7438393 100644 --- a/src/boards/B-L072Z-LRWAN1/eeprom-board.c +++ b/src/boards/B-L072Z-LRWAN1/eeprom-board.c @@ -34,6 +34,7 @@ uint8_t EepromMcuWriteBuffer( uint16_t addr, uint8_t *buffer, uint16_t size ) if( HAL_FLASHEx_DATAEEPROM_Unlock( ) == HAL_OK ) { + CRITICAL_SECTION_BEGIN( ); for( uint16_t i = 0; i < size; i++ ) { if( HAL_FLASHEx_DATAEEPROM_Program( FLASH_TYPEPROGRAMDATA_BYTE, @@ -44,6 +45,7 @@ uint8_t EepromMcuWriteBuffer( uint16_t addr, uint8_t *buffer, uint16_t size ) break; } } + CRITICAL_SECTION_END( ); status = SUCCESS; } diff --git a/src/boards/NAMote72/eeprom-board.c b/src/boards/NAMote72/eeprom-board.c index 482246949..4f3b3cfa5 100644 --- a/src/boards/NAMote72/eeprom-board.c +++ b/src/boards/NAMote72/eeprom-board.c @@ -34,6 +34,7 @@ uint8_t EepromMcuWriteBuffer( uint16_t addr, uint8_t *buffer, uint16_t size ) if( HAL_FLASHEx_DATAEEPROM_Unlock( ) == HAL_OK ) { + CRITICAL_SECTION_BEGIN( ); for( uint16_t i = 0; i < size; i++ ) { if( HAL_FLASHEx_DATAEEPROM_Program( FLASH_TYPEPROGRAMDATA_BYTE, @@ -44,6 +45,7 @@ uint8_t EepromMcuWriteBuffer( uint16_t addr, uint8_t *buffer, uint16_t size ) break; } } + CRITICAL_SECTION_END( ); status = SUCCESS; } diff --git a/src/boards/NucleoL073/eeprom-board.c b/src/boards/NucleoL073/eeprom-board.c index b7e2f0303..ca7438393 100644 --- a/src/boards/NucleoL073/eeprom-board.c +++ b/src/boards/NucleoL073/eeprom-board.c @@ -34,6 +34,7 @@ uint8_t EepromMcuWriteBuffer( uint16_t addr, uint8_t *buffer, uint16_t size ) if( HAL_FLASHEx_DATAEEPROM_Unlock( ) == HAL_OK ) { + CRITICAL_SECTION_BEGIN( ); for( uint16_t i = 0; i < size; i++ ) { if( HAL_FLASHEx_DATAEEPROM_Program( FLASH_TYPEPROGRAMDATA_BYTE, @@ -44,6 +45,7 @@ uint8_t EepromMcuWriteBuffer( uint16_t addr, uint8_t *buffer, uint16_t size ) break; } } + CRITICAL_SECTION_END( ); status = SUCCESS; } diff --git a/src/boards/NucleoL152/eeprom-board.c b/src/boards/NucleoL152/eeprom-board.c index 482246949..4f3b3cfa5 100644 --- a/src/boards/NucleoL152/eeprom-board.c +++ b/src/boards/NucleoL152/eeprom-board.c @@ -34,6 +34,7 @@ uint8_t EepromMcuWriteBuffer( uint16_t addr, uint8_t *buffer, uint16_t size ) if( HAL_FLASHEx_DATAEEPROM_Unlock( ) == HAL_OK ) { + CRITICAL_SECTION_BEGIN( ); for( uint16_t i = 0; i < size; i++ ) { if( HAL_FLASHEx_DATAEEPROM_Program( FLASH_TYPEPROGRAMDATA_BYTE, @@ -44,6 +45,7 @@ uint8_t EepromMcuWriteBuffer( uint16_t addr, uint8_t *buffer, uint16_t size ) break; } } + CRITICAL_SECTION_END( ); status = SUCCESS; } diff --git a/src/boards/NucleoL476/eeprom-board.c b/src/boards/NucleoL476/eeprom-board.c index 3e757ba02..2a7f3868e 100644 --- a/src/boards/NucleoL476/eeprom-board.c +++ b/src/boards/NucleoL476/eeprom-board.c @@ -97,14 +97,16 @@ uint8_t EepromMcuWriteBuffer( uint16_t addr, uint8_t *buffer, uint16_t size ) { uint8_t status = SUCCESS; EE_Status eeStatus = EE_OK; - + // Unlock the Flash Program Erase controller HAL_FLASH_Unlock( ); + CRITICAL_SECTION_BEGIN( ); for( uint32_t i = 0; i < size; i++ ) { eeStatus |= EE_WriteVariable8bits( EepromVirtualAddress[addr + i], buffer[i] ); } + CRITICAL_SECTION_END( ); if( eeStatus != EE_OK ) { diff --git a/src/boards/SKiM880B/eeprom-board.c b/src/boards/SKiM880B/eeprom-board.c index 482246949..4f3b3cfa5 100644 --- a/src/boards/SKiM880B/eeprom-board.c +++ b/src/boards/SKiM880B/eeprom-board.c @@ -34,6 +34,7 @@ uint8_t EepromMcuWriteBuffer( uint16_t addr, uint8_t *buffer, uint16_t size ) if( HAL_FLASHEx_DATAEEPROM_Unlock( ) == HAL_OK ) { + CRITICAL_SECTION_BEGIN( ); for( uint16_t i = 0; i < size; i++ ) { if( HAL_FLASHEx_DATAEEPROM_Program( FLASH_TYPEPROGRAMDATA_BYTE, @@ -44,6 +45,7 @@ uint8_t EepromMcuWriteBuffer( uint16_t addr, uint8_t *buffer, uint16_t size ) break; } } + CRITICAL_SECTION_END( ); status = SUCCESS; } diff --git a/src/boards/SKiM881AXL/eeprom-board.c b/src/boards/SKiM881AXL/eeprom-board.c index b7e2f0303..ca7438393 100644 --- a/src/boards/SKiM881AXL/eeprom-board.c +++ b/src/boards/SKiM881AXL/eeprom-board.c @@ -34,6 +34,7 @@ uint8_t EepromMcuWriteBuffer( uint16_t addr, uint8_t *buffer, uint16_t size ) if( HAL_FLASHEx_DATAEEPROM_Unlock( ) == HAL_OK ) { + CRITICAL_SECTION_BEGIN( ); for( uint16_t i = 0; i < size; i++ ) { if( HAL_FLASHEx_DATAEEPROM_Program( FLASH_TYPEPROGRAMDATA_BYTE, @@ -44,6 +45,7 @@ uint8_t EepromMcuWriteBuffer( uint16_t addr, uint8_t *buffer, uint16_t size ) break; } } + CRITICAL_SECTION_END( ); status = SUCCESS; } diff --git a/src/boards/SKiM980A/eeprom-board.c b/src/boards/SKiM980A/eeprom-board.c index 482246949..96bc2074c 100644 --- a/src/boards/SKiM980A/eeprom-board.c +++ b/src/boards/SKiM980A/eeprom-board.c @@ -34,6 +34,7 @@ uint8_t EepromMcuWriteBuffer( uint16_t addr, uint8_t *buffer, uint16_t size ) if( HAL_FLASHEx_DATAEEPROM_Unlock( ) == HAL_OK ) { + CRITICAL_SECTION_BEGIN( ); for( uint16_t i = 0; i < size; i++ ) { if( HAL_FLASHEx_DATAEEPROM_Program( FLASH_TYPEPROGRAMDATA_BYTE, @@ -43,7 +44,9 @@ uint8_t EepromMcuWriteBuffer( uint16_t addr, uint8_t *buffer, uint16_t size ) // Failed to write EEPROM break; } + } + CRITICAL_SECTION_END( ); status = SUCCESS; } diff --git a/src/boards/mcu/utilities.c b/src/boards/mcu/utilities.c index d32d57357..c6d69294e 100644 --- a/src/boards/mcu/utilities.c +++ b/src/boards/mcu/utilities.c @@ -90,3 +90,62 @@ int8_t Nibble2HexChar( uint8_t a ) return '?'; } } + +uint32_t Crc32( uint8_t *buffer, uint16_t length ) +{ + // The CRC calculation follows CCITT - 0x04C11DB7 + const uint32_t reversedPolynom = 0xEDB88320; + + // CRC initial value + uint32_t crc = 0xFFFFFFFF; + + if( buffer == NULL ) + { + return 0; + } + + for( uint16_t i = 0; i < length; ++i ) + { + crc ^= ( uint32_t )buffer[i]; + for( uint16_t i = 0; i < 8; i++ ) + { + crc = ( crc >> 1 ) ^ ( reversedPolynom & ~( ( crc & 0x01 ) - 1 ) ); + } + } + + return ~crc; +} + +uint32_t Crc32Init( void ) +{ + return 0xFFFFFFFF; +} + +uint32_t Crc32Update( uint32_t crcInit, uint8_t *buffer, uint16_t length ) +{ + // The CRC calculation follows CCITT - 0x04C11DB7 + const uint32_t reversedPolynom = 0xEDB88320; + + // CRC initial value + uint32_t crc = crcInit; + + if( buffer == NULL ) + { + return 0; + } + + for( uint16_t i = 0; i < length; ++i ) + { + crc ^= ( uint32_t )buffer[i]; + for( uint16_t i = 0; i < 8; i++ ) + { + crc = ( crc >> 1 ) ^ ( reversedPolynom & ~( ( crc & 0x01 ) - 1 ) ); + } + } + return crc; +} + +uint32_t Crc32Finalize( uint32_t crc ) +{ + return ~crc; +} diff --git a/src/boards/utilities.h b/src/boards/utilities.h index f84199265..dc2760093 100644 --- a/src/boards/utilities.h +++ b/src/boards/utilities.h @@ -141,6 +141,44 @@ void memset1( uint8_t *dst, uint8_t value, uint16_t size ); */ int8_t Nibble2HexChar( uint8_t a ); +/*! + * \brief Computes a CCITT 32 bits CRC + * + * \param [IN] buffer Data buffer used to compute the CRC + * \param [IN] length Data buffer length + * + * \retval crc The computed buffer of length CRC + */ +uint32_t Crc32( uint8_t *buffer, uint16_t length ); + +/*! + * \brief Computes the initial value of the CCITT 32 bits CRC. This function + * can be used with functions \ref Crc32Update and \ref Crc32Finalize. + * + * \retval crc Initial crc value. + */ +uint32_t Crc32Init( void ); + +/*! + * \brief Updates the value of the crc value. + * + * \param [IN] crcInit Previous or initial crc value. + * \param [IN] buffer Data pointer. + * \param [IN] length Length of the data. + * + * \retval crc Updated crc value. + */ +uint32_t Crc32Update( uint32_t crcInit, uint8_t *buffer, uint16_t length ); + +/*! + * \brief Finalizes the crc value after the calls to \ref Crc32Update. + * + * \param [IN] crc Recent crc value. + * + * \retval crc Updated crc value. + */ +uint32_t Crc32Finalize( uint32_t crc ); + /*! * Begins critical section */ @@ -153,20 +191,20 @@ int8_t Nibble2HexChar( uint8_t a ); /* * ============================================================================ - * Following functions must be implemented inside the specific platform + * Following functions must be implemented inside the specific platform * board.c file. * ============================================================================ */ /*! * Disable interrupts, begins critical section - * + * * \param [IN] mask Pointer to a variable where to store the CPU IRQ mask */ void BoardCriticalSectionBegin( uint32_t *mask ); /*! * Ends critical section - * + * * \param [IN] mask Pointer to a variable where the CPU IRQ mask was stored */ void BoardCriticalSectionEnd( uint32_t *mask ); diff --git a/src/mac/CMakeLists.txt b/src/mac/CMakeLists.txt index 19bfc9ee4..d1e278e1a 100644 --- a/src/mac/CMakeLists.txt +++ b/src/mac/CMakeLists.txt @@ -43,13 +43,44 @@ set_property(CACHE REGION_AS923_DEFAULT_CHANNEL_PLAN PROPERTY STRINGS ${REGION_A #--------------------------------------------------------------------------------------- # Target #--------------------------------------------------------------------------------------- +set( MAC_BUILD_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/region/RegionAS923.c + ${CMAKE_CURRENT_SOURCE_DIR}/region/RegionCN779.c + ${CMAKE_CURRENT_SOURCE_DIR}/region/RegionEU433.c + ${CMAKE_CURRENT_SOURCE_DIR}/region/RegionEU868.c + ${CMAKE_CURRENT_SOURCE_DIR}/region/RegionIN865.c + ${CMAKE_CURRENT_SOURCE_DIR}/region/RegionRU864.c + ${CMAKE_CURRENT_SOURCE_DIR}/region/RegionBaseUS.c + ${CMAKE_CURRENT_SOURCE_DIR}/region/RegionCommon.c + ${CMAKE_CURRENT_SOURCE_DIR}/region/Region.c + ${CMAKE_CURRENT_SOURCE_DIR}/LoRaMac.c + ${CMAKE_CURRENT_SOURCE_DIR}/LoRaMacAdr.c + ${CMAKE_CURRENT_SOURCE_DIR}/LoRaMacClassB.c + ${CMAKE_CURRENT_SOURCE_DIR}/LoRaMacCommands.c + ${CMAKE_CURRENT_SOURCE_DIR}/LoRaMacConfirmQueue.c + ${CMAKE_CURRENT_SOURCE_DIR}/LoRaMacCrypto.c + ${CMAKE_CURRENT_SOURCE_DIR}/LoRaMacParser.c + ${CMAKE_CURRENT_SOURCE_DIR}/LoRaMacSerializer.c ) -file(GLOB ${PROJECT_NAME}_SOURCES - "${CMAKE_CURRENT_SOURCE_DIR}/*.c" - "${CMAKE_CURRENT_SOURCE_DIR}/region/*.c" -) +if(REGION_US915 STREQUAL ON) +set( MAC_BUILD_SOURCES + ${MAC_BUILD_SOURCES} + "${CMAKE_CURRENT_SOURCE_DIR}/region/RegionUS915.c" ) +endif() + +if(REGION_AU915 STREQUAL ON) +set( MAC_BUILD_SOURCES + ${MAC_BUILD_SOURCES} + "${CMAKE_CURRENT_SOURCE_DIR}/region/RegionAU915.c" ) +endif() -add_library(${PROJECT_NAME} OBJECT EXCLUDE_FROM_ALL ${${PROJECT_NAME}_SOURCES}) +if(REGION_CN470 STREQUAL ON) +set( MAC_BUILD_SOURCES + ${MAC_BUILD_SOURCES} + "${CMAKE_CURRENT_SOURCE_DIR}/region/RegionCN470.c" ) +endif() + +add_library(${PROJECT_NAME} OBJECT EXCLUDE_FROM_ALL ${MAC_BUILD_SOURCES}) # Loops through all regions and add compile time definitions for the enabled ones. foreach( REGION ${REGION_LIST} ) @@ -64,6 +95,11 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE -DREGION_AS923_DEFAULT_CHANNE # Add define if class B is supported target_compile_definitions(${PROJECT_NAME} PRIVATE $<$:LORAMAC_CLASSB_ENABLED>) +# SecureElement NVM +if(${SECURE_ELEMENT} MATCHES SOFT_SE) + target_compile_definitions(${PROJECT_NAME} PRIVATE -DSOFT_SE) +endif() + add_dependencies(${PROJECT_NAME} board) target_include_directories( ${PROJECT_NAME} PUBLIC diff --git a/src/mac/LoRaMac.c b/src/mac/LoRaMac.c index e2afce293..0547d80ec 100644 --- a/src/mac/LoRaMac.c +++ b/src/mac/LoRaMac.c @@ -44,12 +44,13 @@ #include "LoRaMacCommands.h" #include "LoRaMacAdr.h" #include "LoRaMacSerializer.h" +#include "radio.h" #include "LoRaMac.h" #ifndef LORAMAC_VERSION /*! - * LORaWAN version definition. + * LoRaWAN version definition. */ #define LORAMAC_VERSION 0x01000300 #endif @@ -59,11 +60,6 @@ */ #define LORAMAC_PHY_MAXPAYLOAD 255 -/*! - * Maximum MAC commands buffer size - */ -#define LORA_MAC_COMMAND_MAX_LENGTH 128 - /*! * Maximum length of the fOpts field */ @@ -108,97 +104,6 @@ typedef enum eLoRaMacRequestHandling LORAMAC_REQUEST_HANDLING_ON = !LORAMAC_REQUEST_HANDLING_OFF }LoRaMacRequestHandling_t; -typedef struct sLoRaMacNvmCtx -{ - /* - * LoRaMac region. - */ - LoRaMacRegion_t Region; - /* - * LoRaMac default parameters - */ - LoRaMacParams_t MacParamsDefaults; - /* - * Network ID ( 3 bytes ) - */ - uint32_t NetID; - /* - * Mote Address - */ - uint32_t DevAddr; - /*! - * Multicast channel list - */ - MulticastCtx_t MulticastChannelList[LORAMAC_MAX_MC_CTX]; - /* - * Actual device class - */ - DeviceClass_t DeviceClass; - /* - * Indicates if the node is connected to - * a private or public network - */ - bool PublicNetwork; - /* - * LoRaMac ADR control status - */ - bool AdrCtrlOn; - /* - * Counts the number of missed ADR acknowledgements - */ - uint32_t AdrAckCounter; - - /* - * LoRaMac parameters - */ - LoRaMacParams_t MacParams; - /* - * Maximum duty cycle - * \remark Possibility to shutdown the device. - */ - uint8_t MaxDCycle; - /* - * Enables/Disables duty cycle management (Test only) - */ - bool DutyCycleOn; - /* - * Buffer containing the MAC layer commands - */ - uint8_t MacCommandsBuffer[LORA_MAC_COMMAND_MAX_LENGTH]; - /* - * 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; - /* - * Aggregated duty cycle management - */ - uint16_t AggregatedDCycle; - /* - * Aggregated duty cycle management - */ - TimerTime_t LastTxDoneTime; - TimerTime_t AggregatedTimeOff; - /* - * Stores the time at LoRaMac initialization. - * - * \remark Used for the BACKOFF_DC computation. - */ - SysTime_t InitializationTime; - /* - * Current LoRaWAN Version - */ - Version_t Version; - /* - * End-Device network activation - */ - ActivationType_t NetworkActivation; - /*! - * Last received Message integrity Code (MIC) - */ - uint32_t LastRxMic; -}LoRaMacNvmCtx_t; - typedef struct sLoRaMacCtx { /* @@ -335,13 +240,13 @@ typedef struct sLoRaMacCtx */ LoRaMacRequestHandling_t AllowRequests; /* - * Non-volatile module context structure - */ - LoRaMacNvmCtx_t* NvmCtx; - /* * Duty cycle wait time */ TimerTime_t DutyCycleWaitTime; + /* + * Buffer containing the MAC layer commands + */ + uint8_t MacCommandsBuffer[LORA_MAC_COMMAND_MAX_LENGTH]; }LoRaMacCtx_t; /* @@ -349,17 +254,7 @@ typedef struct sLoRaMacCtx */ static LoRaMacCtx_t MacCtx; -/* - * Non-volatile module context. - */ -static LoRaMacNvmCtx_t NvmMacCtx; - - - -/* - * List of module contexts. - */ -LoRaMacCtxs_t Contexts; +static LoRaMacNvmData_t Nvm; /*! * Defines the LoRaMac radio events status @@ -621,7 +516,7 @@ static void OpenContinuousRxCWindow( void ); * * \retval void Points to a structure containing all contexts */ -LoRaMacCtxs_t* GetCtxs( void ); +static LoRaMacNvmData_t* GetNvmData( void ); /*! * \brief Restoring of internal module contexts @@ -634,7 +529,7 @@ LoRaMacCtxs_t* GetCtxs( void ); * \ref LORAMAC_STATUS_OK, * \ref LORAMAC_STATUS_PARAMETER_INVALID, */ -LoRaMacStatus_t RestoreCtxs( LoRaMacCtxs_t* contexts ); +static LoRaMacStatus_t RestoreNvmData( LoRaMacNvmData_t* contexts ); /*! * \brief Determines the frame type @@ -671,6 +566,11 @@ static bool CheckRetransConfirmedUplink( void ); */ static bool StopRetransmission( void ); +/*! + * \brief Calls the callback to indicate that a context changed + */ +static void CallNvmDataChangeCallback( uint16_t notifyFlags ); + /*! * \brief Handles the ACK retries algorithm. * Increments the re-tries counter up until the specified number of @@ -685,46 +585,6 @@ static void AckTimeoutRetriesProcess( void ); */ static void AckTimeoutRetriesFinalize( void ); -/*! - * \brief Calls the callback to indicate that a context changed - */ -static void CallNvmCtxCallback( LoRaMacNvmCtxModule_t module ); - -/*! - * \brief MAC NVM Context has been changed - */ -static void EventMacNvmCtxChanged( void ); - -/*! - * \brief Region NVM Context has been changed - */ -static void EventRegionNvmCtxChanged( void ); - -/*! - * \brief Crypto NVM Context has been changed - */ -static void EventCryptoNvmCtxChanged( void ); - -/*! - * \brief Secure Element NVM Context has been changed - */ -static void EventSecureElementNvmCtxChanged( void ); - -/*! - * \brief MAC commands module nvm context has been changed - */ -static void EventCommandsNvmCtxChanged( void ); - -/*! - * \brief Class B module nvm context has been changed - */ -static void EventClassBNvmCtxChanged( void ); - -/*! - * \brief Confirm Queue module nvm context has been changed - */ -static void EventConfirmQueueNvmCtxChanged( void ); - /*! * \brief Verifies if a request is pending currently * @@ -772,6 +632,13 @@ static void LoRaMacHandleRequestEvents( void ); */ static void LoRaMacHandleIndicationEvents( void ); +/*! + * \brief This function handles callback events for NVM updates + * + * \param [IN] nvmData Data structure containing NVM data. + */ +static void LoRaMacHandleNvm( LoRaMacNvmData_t* nvmData ); + /*! * Structure used to store the radio Tx event data */ @@ -853,7 +720,7 @@ static void OnRadioRxTimeout( void ) static void UpdateRxSlotIdleState( void ) { - if( MacCtx.NvmCtx->DeviceClass != CLASS_C ) + if( Nvm.MacGroup2.DeviceClass != CLASS_C ) { MacCtx.RxSlot = RX_SLOT_NONE; } @@ -869,7 +736,7 @@ static void ProcessRadioTxDone( void ) PhyParam_t phyParam; SetBandTxDoneParams_t txDone; - if( MacCtx.NvmCtx->DeviceClass != CLASS_C ) + if( Nvm.MacGroup2.DeviceClass != CLASS_C ) { Radio.Sleep( ); } @@ -879,29 +746,29 @@ static void ProcessRadioTxDone( void ) TimerSetValue( &MacCtx.RxWindowTimer2, MacCtx.RxWindow2Delay ); TimerStart( &MacCtx.RxWindowTimer2 ); - if( ( MacCtx.NvmCtx->DeviceClass == CLASS_C ) || ( MacCtx.NodeAckRequested == true ) ) + if( ( Nvm.MacGroup2.DeviceClass == CLASS_C ) || ( MacCtx.NodeAckRequested == true ) ) { getPhy.Attribute = PHY_ACK_TIMEOUT; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); TimerSetValue( &MacCtx.AckTimeoutTimer, MacCtx.RxWindow2Delay + phyParam.Value ); TimerStart( &MacCtx.AckTimeoutTimer ); } // Update Aggregated last tx done time - MacCtx.NvmCtx->LastTxDoneTime = TxDoneParams.CurTime; + Nvm.MacGroup1.LastTxDoneTime = TxDoneParams.CurTime; // Update last tx done time for the current channel txDone.Channel = MacCtx.Channel; txDone.LastTxDoneTime = TxDoneParams.CurTime; - txDone.ElapsedTimeSinceStartUp = SysTimeSub( SysTimeGetMcuTime( ), MacCtx.NvmCtx->InitializationTime ); + txDone.ElapsedTimeSinceStartUp = SysTimeSub( SysTimeGetMcuTime( ), Nvm.MacGroup2.InitializationTime ); txDone.LastTxAirTime = MacCtx.TxTimeOnAir; txDone.Joined = true; - if( MacCtx.NvmCtx->NetworkActivation == ACTIVATION_TYPE_NONE ) + if( Nvm.MacGroup2.NetworkActivation == ACTIVATION_TYPE_NONE ) { txDone.Joined = false; } - RegionSetBandTxDone( MacCtx.NvmCtx->Region, &txDone ); + RegionSetBandTxDone( Nvm.MacGroup2.Region, &txDone ); if( MacCtx.NodeAckRequested == false ) { @@ -942,7 +809,7 @@ static void ProcessRadioRxDone( void ) uint8_t pktHeaderLen = 0; uint32_t downLinkCounter = 0; - uint32_t address = MacCtx.NvmCtx->DevAddr; + uint32_t address = Nvm.MacGroup2.DevAddr; uint8_t multicast = 0; AddressIdentifier_t addrID = UNICAST_DEV_ADDR; FCntIdentifier_t fCntID; @@ -974,7 +841,7 @@ static void ProcessRadioRxDone( void ) return; } // Check if we expect a ping or a multicast slot. - if( MacCtx.NvmCtx->DeviceClass == CLASS_B ) + if( Nvm.MacGroup2.DeviceClass == CLASS_B ) { if( LoRaMacClassBIsPingExpected( ) == true ) { @@ -1006,7 +873,7 @@ static void ProcessRadioRxDone( void ) macMsgJoinAccept.BufSize = size; // Abort in case if the device isn't joined yet and no rejoin request is ongoing. - if( MacCtx.NvmCtx->NetworkActivation != ACTIVATION_TYPE_NONE ) + if( Nvm.MacGroup2.NetworkActivation != ACTIVATION_TYPE_NONE ) { MacCtx.McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_ERROR; PrepareRxDoneAbort( ); @@ -1017,37 +884,37 @@ static void ProcessRadioRxDone( void ) if( LORAMAC_CRYPTO_SUCCESS == macCryptoStatus ) { // Network ID - MacCtx.NvmCtx->NetID = ( uint32_t ) macMsgJoinAccept.NetID[0]; - MacCtx.NvmCtx->NetID |= ( ( uint32_t ) macMsgJoinAccept.NetID[1] << 8 ); - MacCtx.NvmCtx->NetID |= ( ( uint32_t ) macMsgJoinAccept.NetID[2] << 16 ); + Nvm.MacGroup2.NetID = ( uint32_t ) macMsgJoinAccept.NetID[0]; + Nvm.MacGroup2.NetID |= ( ( uint32_t ) macMsgJoinAccept.NetID[1] << 8 ); + Nvm.MacGroup2.NetID |= ( ( uint32_t ) macMsgJoinAccept.NetID[2] << 16 ); // Device Address - MacCtx.NvmCtx->DevAddr = macMsgJoinAccept.DevAddr; + Nvm.MacGroup2.DevAddr = macMsgJoinAccept.DevAddr; // DLSettings - MacCtx.NvmCtx->MacParams.Rx1DrOffset = macMsgJoinAccept.DLSettings.Bits.RX1DRoffset; - MacCtx.NvmCtx->MacParams.Rx2Channel.Datarate = macMsgJoinAccept.DLSettings.Bits.RX2DataRate; - MacCtx.NvmCtx->MacParams.RxCChannel.Datarate = macMsgJoinAccept.DLSettings.Bits.RX2DataRate; + Nvm.MacGroup2.MacParams.Rx1DrOffset = macMsgJoinAccept.DLSettings.Bits.RX1DRoffset; + Nvm.MacGroup2.MacParams.Rx2Channel.Datarate = macMsgJoinAccept.DLSettings.Bits.RX2DataRate; + Nvm.MacGroup2.MacParams.RxCChannel.Datarate = macMsgJoinAccept.DLSettings.Bits.RX2DataRate; // RxDelay - MacCtx.NvmCtx->MacParams.ReceiveDelay1 = macMsgJoinAccept.RxDelay; - if( MacCtx.NvmCtx->MacParams.ReceiveDelay1 == 0 ) + Nvm.MacGroup2.MacParams.ReceiveDelay1 = macMsgJoinAccept.RxDelay; + if( Nvm.MacGroup2.MacParams.ReceiveDelay1 == 0 ) { - MacCtx.NvmCtx->MacParams.ReceiveDelay1 = 1; + Nvm.MacGroup2.MacParams.ReceiveDelay1 = 1; } - MacCtx.NvmCtx->MacParams.ReceiveDelay1 *= 1000; - MacCtx.NvmCtx->MacParams.ReceiveDelay2 = MacCtx.NvmCtx->MacParams.ReceiveDelay1 + 1000; + Nvm.MacGroup2.MacParams.ReceiveDelay1 *= 1000; + Nvm.MacGroup2.MacParams.ReceiveDelay2 = Nvm.MacGroup2.MacParams.ReceiveDelay1 + 1000; - MacCtx.NvmCtx->Version.Fields.Minor = 0; + Nvm.MacGroup2.Version.Fields.Minor = 0; // Apply CF list applyCFList.Payload = macMsgJoinAccept.CFList; // Size of the regular payload is 12. Plus 1 byte MHDR and 4 bytes MIC applyCFList.Size = size - 17; - RegionApplyCFList( MacCtx.NvmCtx->Region, &applyCFList ); + RegionApplyCFList( Nvm.MacGroup2.Region, &applyCFList ); - MacCtx.NvmCtx->NetworkActivation = ACTIVATION_TYPE_OTAA; + Nvm.MacGroup2.NetworkActivation = ACTIVATION_TYPE_OTAA; // MLME handling if( LoRaMacConfirmQueueIsCmdActive( MLME_JOIN ) == true ) @@ -1069,10 +936,10 @@ static void ProcessRadioRxDone( void ) // Intentional fall through case FRAME_TYPE_DATA_UNCONFIRMED_DOWN: // Check if the received payload size is valid - getPhy.UplinkDwellTime = MacCtx.NvmCtx->MacParams.DownlinkDwellTime; + getPhy.UplinkDwellTime = Nvm.MacGroup2.MacParams.DownlinkDwellTime; getPhy.Datarate = MacCtx.McpsIndication.RxDatarate; getPhy.Attribute = PHY_MAX_PAYLOAD; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); if( ( MAX( 0, ( int16_t )( ( int16_t ) size - ( int16_t ) LORAMAC_FRAME_PAYLOAD_OVERHEAD_SIZE ) ) > ( int16_t )phyParam.Value ) || ( size < LORAMAC_FRAME_PAYLOAD_MIN_SIZE ) ) { @@ -1108,14 +975,14 @@ static void ProcessRadioRxDone( void ) downLinkCounter = 0; for( uint8_t i = 0; i < LORAMAC_MAX_MC_CTX; i++ ) { - if( ( MacCtx.NvmCtx->MulticastChannelList[i].ChannelParams.Address == macMsgData.FHDR.DevAddr ) && - ( MacCtx.NvmCtx->MulticastChannelList[i].ChannelParams.IsEnabled == true ) ) + if( ( Nvm.MacGroup2.MulticastChannelList[i].ChannelParams.Address == macMsgData.FHDR.DevAddr ) && + ( Nvm.MacGroup2.MulticastChannelList[i].ChannelParams.IsEnabled == true ) ) { multicast = 1; - addrID = MacCtx.NvmCtx->MulticastChannelList[i].ChannelParams.GroupID; - downLinkCounter = *( MacCtx.NvmCtx->MulticastChannelList[i].DownLinkCounter ); - address = MacCtx.NvmCtx->MulticastChannelList[i].ChannelParams.Address; - if( MacCtx.NvmCtx->DeviceClass == CLASS_C ) + addrID = Nvm.MacGroup2.MulticastChannelList[i].ChannelParams.GroupID; + downLinkCounter = *( Nvm.MacGroup2.MulticastChannelList[i].DownLinkCounter ); + address = Nvm.MacGroup2.MulticastChannelList[i].ChannelParams.Address; + if( Nvm.MacGroup2.DeviceClass == CLASS_C ) { MacCtx.McpsIndication.RxSlot = RX_SLOT_WIN_CLASS_C_MULTICAST; } @@ -1135,19 +1002,19 @@ static void ProcessRadioRxDone( void ) // Get maximum allowed counter difference getPhy.Attribute = PHY_MAX_FCNT_GAP; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); // Get downlink frame counter value - macCryptoStatus = GetFCntDown( addrID, fType, &macMsgData, MacCtx.NvmCtx->Version, phyParam.Value, &fCntID, &downLinkCounter ); + macCryptoStatus = GetFCntDown( addrID, fType, &macMsgData, Nvm.MacGroup2.Version, phyParam.Value, &fCntID, &downLinkCounter ); if( macCryptoStatus != LORAMAC_CRYPTO_SUCCESS ) { if( macCryptoStatus == LORAMAC_CRYPTO_FAIL_FCNT_DUPLICATED ) { // Catch the case of repeated downlink frame counter MacCtx.McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED; - if( ( MacCtx.NvmCtx->Version.Fields.Minor == 0 ) && ( macHdr.Bits.MType == FRAME_TYPE_DATA_CONFIRMED_DOWN ) && ( MacCtx.NvmCtx->LastRxMic == macMsgData.MIC ) ) + if( ( Nvm.MacGroup2.Version.Fields.Minor == 0 ) && ( macHdr.Bits.MType == FRAME_TYPE_DATA_CONFIRMED_DOWN ) && ( Nvm.MacGroup1.LastRxMic == macMsgData.MIC ) ) { - MacCtx.NvmCtx->SrvAckRequested = true; + Nvm.MacGroup1.SrvAckRequested = true; } } else if( macCryptoStatus == LORAMAC_CRYPTO_FAIL_MAX_GAP_FCNT ) @@ -1198,7 +1065,7 @@ static void ProcessRadioRxDone( void ) if( ( MacCtx.McpsIndication.RxSlot == RX_SLOT_WIN_1 ) || ( MacCtx.McpsIndication.RxSlot == RX_SLOT_WIN_2 ) ) { - MacCtx.NvmCtx->AdrAckCounter = 0; + Nvm.MacGroup1.AdrAckCounter = 0; } // MCPS Indication and ack requested handling @@ -1210,16 +1077,16 @@ static void ProcessRadioRxDone( void ) { if( macHdr.Bits.MType == FRAME_TYPE_DATA_CONFIRMED_DOWN ) { - MacCtx.NvmCtx->SrvAckRequested = true; - if( MacCtx.NvmCtx->Version.Fields.Minor == 0 ) + Nvm.MacGroup1.SrvAckRequested = true; + if( Nvm.MacGroup2.Version.Fields.Minor == 0 ) { - MacCtx.NvmCtx->LastRxMic = macMsgData.MIC; + Nvm.MacGroup1.LastRxMic = macMsgData.MIC; } MacCtx.McpsIndication.McpsIndication = MCPS_CONFIRMED; } else { - MacCtx.NvmCtx->SrvAckRequested = false; + Nvm.MacGroup1.SrvAckRequested = false; MacCtx.McpsIndication.McpsIndication = MCPS_UNCONFIRMED; } } @@ -1322,7 +1189,7 @@ static void ProcessRadioRxDone( void ) } else { - if( MacCtx.NvmCtx->DeviceClass == CLASS_C ) + if( Nvm.MacGroup2.DeviceClass == CLASS_C ) { OnAckTimeoutTimerEvent( NULL ); } @@ -1334,7 +1201,7 @@ static void ProcessRadioRxDone( void ) static void ProcessRadioTxTimeout( void ) { - if( MacCtx.NvmCtx->DeviceClass != CLASS_C ) + if( Nvm.MacGroup2.DeviceClass != CLASS_C ) { Radio.Sleep( ); } @@ -1353,7 +1220,7 @@ static void HandleRadioRxErrorTimeout( LoRaMacEventInfoStatus_t rx1EventInfoStat { bool classBRx = false; - if( MacCtx.NvmCtx->DeviceClass != CLASS_C ) + if( Nvm.MacGroup2.DeviceClass != CLASS_C ) { Radio.Sleep( ); } @@ -1364,7 +1231,7 @@ static void HandleRadioRxErrorTimeout( LoRaMacEventInfoStatus_t rx1EventInfoStat LoRaMacClassBBeaconTimerEvent( NULL ); classBRx = true; } - if( MacCtx.NvmCtx->DeviceClass == CLASS_B ) + if( Nvm.MacGroup2.DeviceClass == CLASS_B ) { if( LoRaMacClassBIsPingExpected( ) == true ) { @@ -1390,7 +1257,7 @@ static void HandleRadioRxErrorTimeout( LoRaMacEventInfoStatus_t rx1EventInfoStat } LoRaMacConfirmQueueSetStatusCmn( rx1EventInfoStatus ); - if( TimerGetElapsedTime( MacCtx.NvmCtx->LastTxDoneTime ) >= MacCtx.RxWindow2Delay ) + if( TimerGetElapsedTime( Nvm.MacGroup1.LastTxDoneTime ) >= MacCtx.RxWindow2Delay ) { TimerStop( &MacCtx.RxWindowTimer2 ); MacCtx.MacFlags.Bits.MacDone = 1; @@ -1404,7 +1271,7 @@ static void HandleRadioRxErrorTimeout( LoRaMacEventInfoStatus_t rx1EventInfoStat } LoRaMacConfirmQueueSetStatusCmn( rx2EventInfoStatus ); - if( MacCtx.NvmCtx->DeviceClass != CLASS_C ) + if( Nvm.MacGroup2.DeviceClass != CLASS_C ) { MacCtx.MacFlags.Bits.MacDone = 1; } @@ -1579,7 +1446,7 @@ static void LoRaMacHandleMcpsRequest( void ) { stopRetransmission = CheckRetransConfirmedUplink( ); - if( MacCtx.NvmCtx->Version.Fields.Minor == 0 ) + if( Nvm.MacGroup2.Version.Fields.Minor == 0 ) { if( stopRetransmission == false ) { @@ -1659,6 +1526,81 @@ static void LoRaMacCheckForRxAbort( void ) } } +static void LoRaMacHandleNvm( LoRaMacNvmData_t* nvmData ) +{ + uint32_t crc = 0; + uint16_t notifyFlags = LORAMAC_NVM_NOTIFY_FLAG_NONE; + + if( MacCtx.MacState != LORAMAC_IDLE ) + { + return; + } + + // Crypto + crc = Crc32( ( uint8_t* ) &nvmData->Crypto, sizeof( nvmData->Crypto ) - + sizeof( nvmData->Crypto.Crc32 ) ); + if( crc != nvmData->Crypto.Crc32 ) + { + nvmData->Crypto.Crc32 = crc; + notifyFlags |= LORAMAC_NVM_NOTIFY_FLAG_CRYPTO; + } + + // MacGroup1 + crc = Crc32( ( uint8_t* ) &nvmData->MacGroup1, sizeof( nvmData->MacGroup1 ) - + sizeof( nvmData->MacGroup1.Crc32 ) ); + if( crc != nvmData->MacGroup1.Crc32 ) + { + nvmData->MacGroup1.Crc32 = crc; + notifyFlags |= LORAMAC_NVM_NOTIFY_FLAG_MAC_GROUP1; + } + + // MacGroup2 + crc = Crc32( ( uint8_t* ) &nvmData->MacGroup2, sizeof( nvmData->MacGroup2 ) - + sizeof( nvmData->MacGroup2.Crc32 ) ); + if( crc != nvmData->MacGroup2.Crc32 ) + { + nvmData->MacGroup2.Crc32 = crc; + notifyFlags |= LORAMAC_NVM_NOTIFY_FLAG_MAC_GROUP2; + } + + // Secure Element + crc = Crc32( ( uint8_t* ) &nvmData->SecureElement, sizeof( nvmData->SecureElement ) - + sizeof( nvmData->SecureElement.Crc32 ) ); + if( crc != nvmData->SecureElement.Crc32 ) + { + nvmData->SecureElement.Crc32 = crc; + notifyFlags |= LORAMAC_NVM_NOTIFY_FLAG_SECURE_ELEMENT; + } + + // Region + crc = Crc32( ( uint8_t* ) &nvmData->RegionGroup1, sizeof( nvmData->RegionGroup1 ) - + sizeof( nvmData->RegionGroup1.Crc32 ) ); + if( crc != nvmData->RegionGroup1.Crc32 ) + { + nvmData->RegionGroup1.Crc32 = crc; + notifyFlags |= LORAMAC_NVM_NOTIFY_FLAG_REGION_GROUP1; + } + + crc = Crc32( ( uint8_t* ) &nvmData->RegionGroup2, sizeof( nvmData->RegionGroup2 ) - + sizeof( nvmData->RegionGroup2.Crc32 ) ); + if( crc != nvmData->RegionGroup2.Crc32 ) + { + nvmData->RegionGroup2.Crc32 = crc; + notifyFlags |= LORAMAC_NVM_NOTIFY_FLAG_REGION_GROUP2; + } + + // ClassB + crc = Crc32( ( uint8_t* ) &nvmData->ClassB, sizeof( nvmData->ClassB ) - + sizeof( nvmData->ClassB.Crc32 ) ); + if( crc != nvmData->ClassB.Crc32 ) + { + nvmData->ClassB.Crc32 = crc; + notifyFlags |= LORAMAC_NVM_NOTIFY_FLAG_CLASS_B; + } + + CallNvmDataChangeCallback( notifyFlags ); +} + void LoRaMacProcess( void ) { @@ -1686,6 +1628,7 @@ void LoRaMacProcess( void ) } LoRaMacHandleRequestEvents( ); LoRaMacHandleScheduleUplinkEvent( ); + LoRaMacHandleNvm( &Nvm ); LoRaMacEnableRequests( LORAMAC_REQUEST_HANDLING_ON ); } LoRaMacHandleIndicationEvents( ); @@ -1711,7 +1654,7 @@ static void OnTxDelayedTimerEvent( void* context ) default: { // Stop retransmission attempt - MacCtx.McpsConfirm.Datarate = MacCtx.NvmCtx->MacParams.ChannelsDatarate; + MacCtx.McpsConfirm.Datarate = Nvm.MacGroup1.ChannelsDatarate; MacCtx.McpsConfirm.NbRetries = MacCtx.AckTimeoutRetriesCounter; MacCtx.McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_TX_DR_PAYLOAD_SIZE_ERROR; LoRaMacConfirmQueueSetStatusCmn( LORAMAC_EVENT_INFO_STATUS_TX_DR_PAYLOAD_SIZE_ERROR ); @@ -1724,8 +1667,8 @@ static void OnTxDelayedTimerEvent( void* context ) static void OnRxWindow1TimerEvent( void* context ) { MacCtx.RxWindow1Config.Channel = MacCtx.Channel; - MacCtx.RxWindow1Config.DrOffset = MacCtx.NvmCtx->MacParams.Rx1DrOffset; - MacCtx.RxWindow1Config.DownlinkDwellTime = MacCtx.NvmCtx->MacParams.DownlinkDwellTime; + MacCtx.RxWindow1Config.DrOffset = Nvm.MacGroup2.MacParams.Rx1DrOffset; + MacCtx.RxWindow1Config.DownlinkDwellTime = Nvm.MacGroup2.MacParams.DownlinkDwellTime; MacCtx.RxWindow1Config.RxContinuous = false; MacCtx.RxWindow1Config.RxSlot = RX_SLOT_WIN_1; @@ -1741,8 +1684,8 @@ static void OnRxWindow2TimerEvent( void* context ) return; } MacCtx.RxWindow2Config.Channel = MacCtx.Channel; - MacCtx.RxWindow2Config.Frequency = MacCtx.NvmCtx->MacParams.Rx2Channel.Frequency; - MacCtx.RxWindow2Config.DownlinkDwellTime = MacCtx.NvmCtx->MacParams.DownlinkDwellTime; + MacCtx.RxWindow2Config.Frequency = Nvm.MacGroup2.MacParams.Rx2Channel.Frequency; + MacCtx.RxWindow2Config.DownlinkDwellTime = Nvm.MacGroup2.MacParams.DownlinkDwellTime; MacCtx.RxWindow2Config.RxContinuous = false; MacCtx.RxWindow2Config.RxSlot = RX_SLOT_WIN_2; @@ -1757,7 +1700,7 @@ static void OnAckTimeoutTimerEvent( void* context ) { MacCtx.AckTimeoutRetry = true; } - if( MacCtx.NvmCtx->DeviceClass == CLASS_C ) + if( Nvm.MacGroup2.DeviceClass == CLASS_C ) { MacCtx.MacFlags.Bits.MacDone = 1; } @@ -1819,42 +1762,42 @@ static LoRaMacStatus_t SwitchClass( DeviceClass_t deviceClass ) { LoRaMacStatus_t status = LORAMAC_STATUS_PARAMETER_INVALID; - switch( MacCtx.NvmCtx->DeviceClass ) + switch( Nvm.MacGroup2.DeviceClass ) { case CLASS_A: { if( deviceClass == CLASS_A ) { // Revert back RxC parameters - MacCtx.NvmCtx->MacParams.RxCChannel = MacCtx.NvmCtx->MacParams.Rx2Channel; + Nvm.MacGroup2.MacParams.RxCChannel = Nvm.MacGroup2.MacParams.Rx2Channel; } if( deviceClass == CLASS_B ) { status = LoRaMacClassBSwitchClass( deviceClass ); if( status == LORAMAC_STATUS_OK ) { - MacCtx.NvmCtx->DeviceClass = deviceClass; + Nvm.MacGroup2.DeviceClass = deviceClass; } } if( deviceClass == CLASS_C ) { - MacCtx.NvmCtx->DeviceClass = deviceClass; + Nvm.MacGroup2.DeviceClass = deviceClass; MacCtx.RxWindowCConfig = MacCtx.RxWindow2Config; MacCtx.RxWindowCConfig.RxSlot = RX_SLOT_WIN_CLASS_C; for( int8_t i = 0; i < LORAMAC_MAX_MC_CTX; i++ ) { - if( MacCtx.NvmCtx->MulticastChannelList[i].ChannelParams.IsEnabled == true ) + if( Nvm.MacGroup2.MulticastChannelList[i].ChannelParams.IsEnabled == true ) // TODO: Check multicast channel device class. { - MacCtx.NvmCtx->MacParams.RxCChannel.Frequency = MacCtx.NvmCtx->MulticastChannelList[i].ChannelParams.RxParams.ClassC.Frequency; - MacCtx.NvmCtx->MacParams.RxCChannel.Datarate = MacCtx.NvmCtx->MulticastChannelList[i].ChannelParams.RxParams.ClassC.Datarate; + Nvm.MacGroup2.MacParams.RxCChannel.Frequency = Nvm.MacGroup2.MulticastChannelList[i].ChannelParams.RxParams.ClassC.Frequency; + Nvm.MacGroup2.MacParams.RxCChannel.Datarate = Nvm.MacGroup2.MulticastChannelList[i].ChannelParams.RxParams.ClassC.Datarate; MacCtx.RxWindowCConfig.Channel = MacCtx.Channel; - MacCtx.RxWindowCConfig.Frequency = MacCtx.NvmCtx->MacParams.RxCChannel.Frequency; - MacCtx.RxWindowCConfig.DownlinkDwellTime = MacCtx.NvmCtx->MacParams.DownlinkDwellTime; + MacCtx.RxWindowCConfig.Frequency = Nvm.MacGroup2.MacParams.RxCChannel.Frequency; + MacCtx.RxWindowCConfig.DownlinkDwellTime = Nvm.MacGroup2.MacParams.DownlinkDwellTime; MacCtx.RxWindowCConfig.RxSlot = RX_SLOT_WIN_CLASS_C_MULTICAST; MacCtx.RxWindowCConfig.RxContinuous = true; break; @@ -1877,7 +1820,7 @@ static LoRaMacStatus_t SwitchClass( DeviceClass_t deviceClass ) status = LoRaMacClassBSwitchClass( deviceClass ); if( status == LORAMAC_STATUS_OK ) { - MacCtx.NvmCtx->DeviceClass = deviceClass; + Nvm.MacGroup2.DeviceClass = deviceClass; } break; } @@ -1885,7 +1828,7 @@ static LoRaMacStatus_t SwitchClass( DeviceClass_t deviceClass ) { if( deviceClass == CLASS_A ) { - MacCtx.NvmCtx->DeviceClass = deviceClass; + Nvm.MacGroup2.DeviceClass = deviceClass; // Set the radio into sleep to setup a defined state Radio.Sleep( ); @@ -1905,10 +1848,10 @@ static uint8_t GetMaxAppPayloadWithoutFOptsLength( int8_t datarate ) PhyParam_t phyParam; // Setup PHY request - getPhy.UplinkDwellTime = MacCtx.NvmCtx->MacParams.UplinkDwellTime; + getPhy.UplinkDwellTime = Nvm.MacGroup2.MacParams.UplinkDwellTime; getPhy.Datarate = datarate; getPhy.Attribute = PHY_MAX_PAYLOAD; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); return phyParam.Value; } @@ -1978,24 +1921,22 @@ static void ProcessMacCommands( uint8_t *payload, uint8_t macIndex, uint8_t comm // Fill parameter structure linkAdrReq.Payload = &payload[macIndex - 1]; linkAdrReq.PayloadSize = commandsSize - ( macIndex - 1 ); - linkAdrReq.AdrEnabled = MacCtx.NvmCtx->AdrCtrlOn; - linkAdrReq.UplinkDwellTime = MacCtx.NvmCtx->MacParams.UplinkDwellTime; - linkAdrReq.CurrentDatarate = MacCtx.NvmCtx->MacParams.ChannelsDatarate; - linkAdrReq.CurrentTxPower = MacCtx.NvmCtx->MacParams.ChannelsTxPower; - linkAdrReq.CurrentNbRep = MacCtx.NvmCtx->MacParams.ChannelsNbTrans; - linkAdrReq.Version = MacCtx.NvmCtx->Version; + linkAdrReq.AdrEnabled = Nvm.MacGroup2.AdrCtrlOn; + linkAdrReq.UplinkDwellTime = Nvm.MacGroup2.MacParams.UplinkDwellTime; + linkAdrReq.CurrentDatarate = Nvm.MacGroup1.ChannelsDatarate; + linkAdrReq.CurrentTxPower = Nvm.MacGroup1.ChannelsTxPower; + linkAdrReq.CurrentNbRep = Nvm.MacGroup2.MacParams.ChannelsNbTrans; + linkAdrReq.Version = Nvm.MacGroup2.Version; // Process the ADR requests - status = RegionLinkAdrReq( MacCtx.NvmCtx->Region, &linkAdrReq, &linkAdrDatarate, + status = RegionLinkAdrReq( Nvm.MacGroup2.Region, &linkAdrReq, &linkAdrDatarate, &linkAdrTxPower, &linkAdrNbRep, &linkAdrNbBytesParsed ); if( ( status & 0x07 ) == 0x07 ) { - MacCtx.NvmCtx->MacParams.ChannelsDatarate = linkAdrDatarate; - MacCtx.NvmCtx->MacParams.ChannelsTxPower = linkAdrTxPower; - MacCtx.NvmCtx->MacParams.ChannelsNbTrans = linkAdrNbRep; - EventMacNvmCtxChanged( ); - EventRegionNvmCtxChanged( ); + Nvm.MacGroup1.ChannelsDatarate = linkAdrDatarate; + Nvm.MacGroup1.ChannelsTxPower = linkAdrTxPower; + Nvm.MacGroup2.MacParams.ChannelsNbTrans = linkAdrNbRep; } // Add the answers to the buffer @@ -2010,10 +1951,9 @@ static void ProcessMacCommands( uint8_t *payload, uint8_t macIndex, uint8_t comm } case SRV_MAC_DUTY_CYCLE_REQ: { - MacCtx.NvmCtx->MaxDCycle = payload[macIndex++] & 0x0F; - MacCtx.NvmCtx->AggregatedDCycle = 1 << MacCtx.NvmCtx->MaxDCycle; + Nvm.MacGroup2.MaxDCycle = payload[macIndex++] & 0x0F; + Nvm.MacGroup2.AggregatedDCycle = 1 << Nvm.MacGroup2.MaxDCycle; LoRaMacCommandsAddCmd( MOTE_MAC_DUTY_CYCLE_ANS, macCmdPayload, 0 ); - EventMacNvmCtxChanged( ); break; } case SRV_MAC_RX_PARAM_SETUP_REQ: @@ -2031,16 +1971,15 @@ static void ProcessMacCommands( uint8_t *payload, uint8_t macIndex, uint8_t comm rxParamSetupReq.Frequency *= 100; // Perform request on region - status = RegionRxParamSetupReq( MacCtx.NvmCtx->Region, &rxParamSetupReq ); + status = RegionRxParamSetupReq( Nvm.MacGroup2.Region, &rxParamSetupReq ); if( ( status & 0x07 ) == 0x07 ) { - MacCtx.NvmCtx->MacParams.Rx2Channel.Datarate = rxParamSetupReq.Datarate; - MacCtx.NvmCtx->MacParams.RxCChannel.Datarate = rxParamSetupReq.Datarate; - MacCtx.NvmCtx->MacParams.Rx2Channel.Frequency = rxParamSetupReq.Frequency; - MacCtx.NvmCtx->MacParams.RxCChannel.Frequency = rxParamSetupReq.Frequency; - MacCtx.NvmCtx->MacParams.Rx1DrOffset = rxParamSetupReq.DrOffset; - EventMacNvmCtxChanged( ); + Nvm.MacGroup2.MacParams.Rx2Channel.Datarate = rxParamSetupReq.Datarate; + Nvm.MacGroup2.MacParams.RxCChannel.Datarate = rxParamSetupReq.Datarate; + Nvm.MacGroup2.MacParams.Rx2Channel.Frequency = rxParamSetupReq.Frequency; + Nvm.MacGroup2.MacParams.RxCChannel.Frequency = rxParamSetupReq.Frequency; + Nvm.MacGroup2.MacParams.Rx1DrOffset = rxParamSetupReq.DrOffset; } macCmdPayload[0] = status; LoRaMacCommandsAddCmd( MOTE_MAC_RX_PARAM_SETUP_ANS, macCmdPayload, 1 ); @@ -2076,16 +2015,12 @@ static void ProcessMacCommands( uint8_t *payload, uint8_t macIndex, uint8_t comm chParam.Rx1Frequency = 0; chParam.DrRange.Value = payload[macIndex++]; - status = ( uint8_t )RegionNewChannelReq( MacCtx.NvmCtx->Region, &newChannelReq ); + status = ( uint8_t )RegionNewChannelReq( Nvm.MacGroup2.Region, &newChannelReq ); if( ( int8_t )status >= 0 ) { macCmdPayload[0] = status; LoRaMacCommandsAddCmd( MOTE_MAC_NEW_CHANNEL_ANS, macCmdPayload, 1 ); - if( status == 0x03 ) - { - EventRegionNvmCtxChanged( ); - } } break; } @@ -2097,12 +2032,11 @@ static void ProcessMacCommands( uint8_t *payload, uint8_t macIndex, uint8_t comm { delay++; } - MacCtx.NvmCtx->MacParams.ReceiveDelay1 = delay * 1000; - MacCtx.NvmCtx->MacParams.ReceiveDelay2 = MacCtx.NvmCtx->MacParams.ReceiveDelay1 + 1000; + Nvm.MacGroup2.MacParams.ReceiveDelay1 = delay * 1000; + Nvm.MacGroup2.MacParams.ReceiveDelay2 = Nvm.MacGroup2.MacParams.ReceiveDelay1 + 1000; LoRaMacCommandsAddCmd( MOTE_MAC_RX_TIMING_SETUP_ANS, macCmdPayload, 0 ); // Setup indication to inform the application SetMlmeScheduleUplinkIndication( ); - EventMacNvmCtxChanged( ); break; } case SRV_MAC_TX_PARAM_SETUP_REQ: @@ -2126,21 +2060,20 @@ static void ProcessMacCommands( uint8_t *payload, uint8_t macIndex, uint8_t comm txParamSetupReq.MaxEirp = eirpDwellTime & 0x0F; // Check the status for correctness - if( RegionTxParamSetupReq( MacCtx.NvmCtx->Region, &txParamSetupReq ) != -1 ) + if( RegionTxParamSetupReq( Nvm.MacGroup2.Region, &txParamSetupReq ) != -1 ) { // Accept command - MacCtx.NvmCtx->MacParams.UplinkDwellTime = txParamSetupReq.UplinkDwellTime; - MacCtx.NvmCtx->MacParams.DownlinkDwellTime = txParamSetupReq.DownlinkDwellTime; - MacCtx.NvmCtx->MacParams.MaxEirp = LoRaMacMaxEirpTable[txParamSetupReq.MaxEirp]; + Nvm.MacGroup2.MacParams.UplinkDwellTime = txParamSetupReq.UplinkDwellTime; + Nvm.MacGroup2.MacParams.DownlinkDwellTime = txParamSetupReq.DownlinkDwellTime; + Nvm.MacGroup2.MacParams.MaxEirp = LoRaMacMaxEirpTable[txParamSetupReq.MaxEirp]; // Update the datarate in case of the new configuration limits it getPhy.Attribute = PHY_MIN_TX_DR; - getPhy.UplinkDwellTime = MacCtx.NvmCtx->MacParams.UplinkDwellTime; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); - MacCtx.NvmCtx->MacParams.ChannelsDatarate = MAX( MacCtx.NvmCtx->MacParams.ChannelsDatarate, ( int8_t )phyParam.Value ); + getPhy.UplinkDwellTime = Nvm.MacGroup2.MacParams.UplinkDwellTime; + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); + Nvm.MacGroup1.ChannelsDatarate = MAX( Nvm.MacGroup1.ChannelsDatarate, ( int8_t )phyParam.Value ); // Add command response LoRaMacCommandsAddCmd( MOTE_MAC_TX_PARAM_SETUP_ANS, macCmdPayload, 0 ); - EventMacNvmCtxChanged( ); } break; } @@ -2155,7 +2088,7 @@ static void ProcessMacCommands( uint8_t *payload, uint8_t macIndex, uint8_t comm dlChannelReq.Rx1Frequency |= ( uint32_t ) payload[macIndex++] << 16; dlChannelReq.Rx1Frequency *= 100; - status = ( uint8_t )RegionDlChannelReq( MacCtx.NvmCtx->Region, &dlChannelReq ); + status = ( uint8_t )RegionDlChannelReq( Nvm.MacGroup2.Region, &dlChannelReq ); if( ( int8_t )status >= 0 ) { @@ -2163,10 +2096,6 @@ static void ProcessMacCommands( uint8_t *payload, uint8_t macIndex, uint8_t comm LoRaMacCommandsAddCmd( MOTE_MAC_DL_CHANNEL_ANS, macCmdPayload, 1 ); // Setup indication to inform the application SetMlmeScheduleUplinkIndication( ); - if( status == 0x03 ) - { - EventRegionNvmCtxChanged( ); - } } break; } @@ -2283,27 +2212,27 @@ LoRaMacStatus_t Send( LoRaMacHeader_t* macHdr, uint8_t fPort, void* fBuffer, uin { LoRaMacFrameCtrl_t fCtrl; LoRaMacStatus_t status = LORAMAC_STATUS_PARAMETER_INVALID; - int8_t datarate = MacCtx.NvmCtx->MacParams.ChannelsDatarate; - int8_t txPower = MacCtx.NvmCtx->MacParams.ChannelsTxPower; - uint32_t adrAckCounter = MacCtx.NvmCtx->AdrAckCounter; + int8_t datarate = Nvm.MacGroup1.ChannelsDatarate; + int8_t txPower = Nvm.MacGroup1.ChannelsTxPower; + uint32_t adrAckCounter = Nvm.MacGroup1.AdrAckCounter; CalcNextAdrParams_t adrNext; // Check if we are joined - if( MacCtx.NvmCtx->NetworkActivation == ACTIVATION_TYPE_NONE ) + if( Nvm.MacGroup2.NetworkActivation == ACTIVATION_TYPE_NONE ) { return LORAMAC_STATUS_NO_NETWORK_JOINED; } - if( MacCtx.NvmCtx->MaxDCycle == 0 ) + if( Nvm.MacGroup2.MaxDCycle == 0 ) { - MacCtx.NvmCtx->AggregatedTimeOff = 0; + Nvm.MacGroup1.AggregatedTimeOff = 0; } fCtrl.Value = 0; fCtrl.Bits.FOptsLen = 0; - fCtrl.Bits.Adr = MacCtx.NvmCtx->AdrCtrlOn; + fCtrl.Bits.Adr = Nvm.MacGroup2.AdrCtrlOn; // Check class b - if( MacCtx.NvmCtx->DeviceClass == CLASS_B ) + if( Nvm.MacGroup2.DeviceClass == CLASS_B ) { fCtrl.Bits.FPending = 1; } @@ -2313,25 +2242,25 @@ LoRaMacStatus_t Send( LoRaMacHeader_t* macHdr, uint8_t fPort, void* fBuffer, uin } // Check server ack - if( MacCtx.NvmCtx->SrvAckRequested == true ) + if( Nvm.MacGroup1.SrvAckRequested == true ) { fCtrl.Bits.Ack = 1; } // ADR next request - adrNext.Version = MacCtx.NvmCtx->Version; + adrNext.Version = Nvm.MacGroup2.Version; adrNext.UpdateChanMask = true; adrNext.AdrEnabled = fCtrl.Bits.Adr; - adrNext.AdrAckCounter = MacCtx.NvmCtx->AdrAckCounter; + adrNext.AdrAckCounter = Nvm.MacGroup1.AdrAckCounter; adrNext.AdrAckLimit = MacCtx.AdrAckLimit; adrNext.AdrAckDelay = MacCtx.AdrAckDelay; - adrNext.Datarate = MacCtx.NvmCtx->MacParams.ChannelsDatarate; - adrNext.TxPower = MacCtx.NvmCtx->MacParams.ChannelsTxPower; - adrNext.UplinkDwellTime = MacCtx.NvmCtx->MacParams.UplinkDwellTime; - adrNext.Region = MacCtx.NvmCtx->Region; + adrNext.Datarate = Nvm.MacGroup1.ChannelsDatarate; + adrNext.TxPower = Nvm.MacGroup1.ChannelsTxPower; + adrNext.UplinkDwellTime = Nvm.MacGroup2.MacParams.UplinkDwellTime; + adrNext.Region = Nvm.MacGroup2.Region; - fCtrl.Bits.AdrAckReq = LoRaMacAdrCalcNext( &adrNext, &MacCtx.NvmCtx->MacParams.ChannelsDatarate, - &MacCtx.NvmCtx->MacParams.ChannelsTxPower, &adrAckCounter ); + fCtrl.Bits.AdrAckReq = LoRaMacAdrCalcNext( &adrNext, &Nvm.MacGroup1.ChannelsDatarate, + &Nvm.MacGroup1.ChannelsTxPower, &adrAckCounter ); // Prepare the frame status = PrepareFrame( macHdr, &fCtrl, fPort, fBuffer, fBufferSize ); @@ -2348,14 +2277,14 @@ LoRaMacStatus_t Send( LoRaMacHeader_t* macHdr, uint8_t fPort, void* fBuffer, uin { // Bad case - restore // Store local variables - MacCtx.NvmCtx->MacParams.ChannelsDatarate = datarate; - MacCtx.NvmCtx->MacParams.ChannelsTxPower = txPower; + Nvm.MacGroup1.ChannelsDatarate = datarate; + Nvm.MacGroup1.ChannelsTxPower = txPower; } else { // Good case - MacCtx.NvmCtx->SrvAckRequested = false; - MacCtx.NvmCtx->AdrAckCounter = adrAckCounter; + Nvm.MacGroup1.SrvAckRequested = false; + Nvm.MacGroup1.AdrAckCounter = adrAckCounter; // Remove all none sticky MAC commands if( LoRaMacCommandsRemoveNoneStickyCmds( ) != LORAMAC_COMMANDS_SUCCESS ) { @@ -2410,7 +2339,7 @@ static LoRaMacStatus_t CheckForClassBCollision( void ) return LORAMAC_STATUS_BUSY_BEACON_RESERVED_TIME; } - if( MacCtx.NvmCtx->DeviceClass == CLASS_B ) + if( Nvm.MacGroup2.DeviceClass == CLASS_B ) { if( LoRaMacClassBIsPingExpected( ) == true ) { @@ -2427,29 +2356,29 @@ static LoRaMacStatus_t CheckForClassBCollision( void ) static void ComputeRxWindowParameters( void ) { // Compute Rx1 windows parameters - RegionComputeRxWindowParameters( MacCtx.NvmCtx->Region, - RegionApplyDrOffset( MacCtx.NvmCtx->Region, - MacCtx.NvmCtx->MacParams.DownlinkDwellTime, - MacCtx.NvmCtx->MacParams.ChannelsDatarate, - MacCtx.NvmCtx->MacParams.Rx1DrOffset ), - MacCtx.NvmCtx->MacParams.MinRxSymbols, - MacCtx.NvmCtx->MacParams.SystemMaxRxError, + RegionComputeRxWindowParameters( Nvm.MacGroup2.Region, + RegionApplyDrOffset( Nvm.MacGroup2.Region, + Nvm.MacGroup2.MacParams.DownlinkDwellTime, + Nvm.MacGroup1.ChannelsDatarate, + Nvm.MacGroup2.MacParams.Rx1DrOffset ), + Nvm.MacGroup2.MacParams.MinRxSymbols, + Nvm.MacGroup2.MacParams.SystemMaxRxError, &MacCtx.RxWindow1Config ); // Compute Rx2 windows parameters - RegionComputeRxWindowParameters( MacCtx.NvmCtx->Region, - MacCtx.NvmCtx->MacParams.Rx2Channel.Datarate, - MacCtx.NvmCtx->MacParams.MinRxSymbols, - MacCtx.NvmCtx->MacParams.SystemMaxRxError, + RegionComputeRxWindowParameters( Nvm.MacGroup2.Region, + Nvm.MacGroup2.MacParams.Rx2Channel.Datarate, + Nvm.MacGroup2.MacParams.MinRxSymbols, + Nvm.MacGroup2.MacParams.SystemMaxRxError, &MacCtx.RxWindow2Config ); // Default setup, in case the device joined - MacCtx.RxWindow1Delay = MacCtx.NvmCtx->MacParams.ReceiveDelay1 + MacCtx.RxWindow1Config.WindowOffset; - MacCtx.RxWindow2Delay = MacCtx.NvmCtx->MacParams.ReceiveDelay2 + MacCtx.RxWindow2Config.WindowOffset; + MacCtx.RxWindow1Delay = Nvm.MacGroup2.MacParams.ReceiveDelay1 + MacCtx.RxWindow1Config.WindowOffset; + MacCtx.RxWindow2Delay = Nvm.MacGroup2.MacParams.ReceiveDelay2 + MacCtx.RxWindow2Config.WindowOffset; - if( MacCtx.NvmCtx->NetworkActivation == ACTIVATION_TYPE_NONE ) + if( Nvm.MacGroup2.NetworkActivation == ACTIVATION_TYPE_NONE ) { - MacCtx.RxWindow1Delay = MacCtx.NvmCtx->MacParams.JoinAcceptDelay1 + MacCtx.RxWindow1Config.WindowOffset; - MacCtx.RxWindow2Delay = MacCtx.NvmCtx->MacParams.JoinAcceptDelay2 + MacCtx.RxWindow2Config.WindowOffset; + MacCtx.RxWindow1Delay = Nvm.MacGroup2.MacParams.JoinAcceptDelay1 + MacCtx.RxWindow1Config.WindowOffset; + MacCtx.RxWindow2Delay = Nvm.MacGroup2.MacParams.JoinAcceptDelay2 + MacCtx.RxWindow2Config.WindowOffset; } } @@ -2457,14 +2386,14 @@ static LoRaMacStatus_t VerifyTxFrame( void ) { size_t macCmdsSize = 0; - if( MacCtx.NvmCtx->NetworkActivation != ACTIVATION_TYPE_NONE ) + if( Nvm.MacGroup2.NetworkActivation != ACTIVATION_TYPE_NONE ) { if( LoRaMacCommandsGetSizeSerializedCmds( &macCmdsSize ) != LORAMAC_COMMANDS_SUCCESS ) { return LORAMAC_STATUS_MAC_COMMAD_ERROR; } - if( ValidatePayloadLength( MacCtx.AppDataSize, MacCtx.NvmCtx->MacParams.ChannelsDatarate, macCmdsSize ) == false ) + if( ValidatePayloadLength( MacCtx.AppDataSize, Nvm.MacGroup1.ChannelsDatarate, macCmdsSize ) == false ) { return LORAMAC_STATUS_LENGTH_ERROR; } @@ -2524,24 +2453,24 @@ static LoRaMacStatus_t ScheduleTx( bool allowDelayedTx ) return status; } - nextChan.AggrTimeOff = MacCtx.NvmCtx->AggregatedTimeOff; - nextChan.Datarate = MacCtx.NvmCtx->MacParams.ChannelsDatarate; - nextChan.DutyCycleEnabled = MacCtx.NvmCtx->DutyCycleOn; - nextChan.ElapsedTimeSinceStartUp = SysTimeSub( SysTimeGetMcuTime( ), MacCtx.NvmCtx->InitializationTime ); - nextChan.LastAggrTx = MacCtx.NvmCtx->LastTxDoneTime; + nextChan.AggrTimeOff = Nvm.MacGroup1.AggregatedTimeOff; + nextChan.Datarate = Nvm.MacGroup1.ChannelsDatarate; + nextChan.DutyCycleEnabled = Nvm.MacGroup2.DutyCycleOn; + nextChan.ElapsedTimeSinceStartUp = SysTimeSub( SysTimeGetMcuTime( ), Nvm.MacGroup2.InitializationTime ); + nextChan.LastAggrTx = Nvm.MacGroup1.LastTxDoneTime; nextChan.LastTxIsJoinRequest = false; nextChan.Joined = true; nextChan.PktLen = MacCtx.PktBufferLen; // Setup the parameters based on the join status - if( MacCtx.NvmCtx->NetworkActivation == ACTIVATION_TYPE_NONE ) + if( Nvm.MacGroup2.NetworkActivation == ACTIVATION_TYPE_NONE ) { nextChan.LastTxIsJoinRequest = true; nextChan.Joined = false; } // Select channel - status = RegionNextChannel( MacCtx.NvmCtx->Region, &nextChan, &MacCtx.Channel, &MacCtx.DutyCycleWaitTime, &MacCtx.NvmCtx->AggregatedTimeOff ); + status = RegionNextChannel( Nvm.MacGroup2.Region, &nextChan, &MacCtx.Channel, &MacCtx.DutyCycleWaitTime, &Nvm.MacGroup1.AggregatedTimeOff ); if( status != LORAMAC_STATUS_OK ) { @@ -2624,11 +2553,11 @@ static void CalculateBackOff( void ) { // Make sure that the calculation of the backoff time for the aggregated time off will only be done in // case the value is zero. It will be set to zero in the function RegionNextChannel. - if( MacCtx.NvmCtx->AggregatedTimeOff == 0 ) + if( Nvm.MacGroup1.AggregatedTimeOff == 0 ) { // Update aggregated time-off. This must be an assignment and no incremental // update as we do only calculate the time-off based on the last transmission - MacCtx.NvmCtx->AggregatedTimeOff = ( MacCtx.TxTimeOnAir * MacCtx.NvmCtx->AggregatedDCycle - MacCtx.TxTimeOnAir ); + Nvm.MacGroup1.AggregatedTimeOff = ( MacCtx.TxTimeOnAir * Nvm.MacGroup2.AggregatedDCycle - MacCtx.TxTimeOnAir ); } } @@ -2658,45 +2587,46 @@ static void ResetMacParameters( void ) LoRaMacClassBCallback_t classBCallbacks; LoRaMacClassBParams_t classBParams; - MacCtx.NvmCtx->NetworkActivation = ACTIVATION_TYPE_NONE; + Nvm.MacGroup2.NetworkActivation = ACTIVATION_TYPE_NONE; // ADR counter - MacCtx.NvmCtx->AdrAckCounter = 0; + Nvm.MacGroup1.AdrAckCounter = 0; MacCtx.ChannelsNbTransCounter = 0; MacCtx.AckTimeoutRetries = 1; MacCtx.AckTimeoutRetriesCounter = 1; MacCtx.AckTimeoutRetry = false; - MacCtx.NvmCtx->MaxDCycle = 0; - MacCtx.NvmCtx->AggregatedDCycle = 1; + Nvm.MacGroup2.MaxDCycle = 0; + Nvm.MacGroup2.AggregatedDCycle = 1; - MacCtx.NvmCtx->MacParams.ChannelsTxPower = MacCtx.NvmCtx->MacParamsDefaults.ChannelsTxPower; - MacCtx.NvmCtx->MacParams.ChannelsDatarate = MacCtx.NvmCtx->MacParamsDefaults.ChannelsDatarate; - MacCtx.NvmCtx->MacParams.Rx1DrOffset = MacCtx.NvmCtx->MacParamsDefaults.Rx1DrOffset; - MacCtx.NvmCtx->MacParams.Rx2Channel = MacCtx.NvmCtx->MacParamsDefaults.Rx2Channel; - MacCtx.NvmCtx->MacParams.RxCChannel = MacCtx.NvmCtx->MacParamsDefaults.RxCChannel; - MacCtx.NvmCtx->MacParams.UplinkDwellTime = MacCtx.NvmCtx->MacParamsDefaults.UplinkDwellTime; - MacCtx.NvmCtx->MacParams.DownlinkDwellTime = MacCtx.NvmCtx->MacParamsDefaults.DownlinkDwellTime; - MacCtx.NvmCtx->MacParams.MaxEirp = MacCtx.NvmCtx->MacParamsDefaults.MaxEirp; - MacCtx.NvmCtx->MacParams.AntennaGain = MacCtx.NvmCtx->MacParamsDefaults.AntennaGain; + Nvm.MacGroup1.ChannelsTxPower = Nvm.MacGroup2.ChannelsTxPowerDefault; + Nvm.MacGroup1.ChannelsDatarate = Nvm.MacGroup2.ChannelsDatarateDefault; + Nvm.MacGroup2.MacParams.Rx1DrOffset = Nvm.MacGroup2.MacParamsDefaults.Rx1DrOffset; + Nvm.MacGroup2.MacParams.Rx2Channel = Nvm.MacGroup2.MacParamsDefaults.Rx2Channel; + Nvm.MacGroup2.MacParams.RxCChannel = Nvm.MacGroup2.MacParamsDefaults.RxCChannel; + Nvm.MacGroup2.MacParams.UplinkDwellTime = Nvm.MacGroup2.MacParamsDefaults.UplinkDwellTime; + Nvm.MacGroup2.MacParams.DownlinkDwellTime = Nvm.MacGroup2.MacParamsDefaults.DownlinkDwellTime; + Nvm.MacGroup2.MacParams.MaxEirp = Nvm.MacGroup2.MacParamsDefaults.MaxEirp; + Nvm.MacGroup2.MacParams.AntennaGain = Nvm.MacGroup2.MacParamsDefaults.AntennaGain; MacCtx.NodeAckRequested = false; - MacCtx.NvmCtx->SrvAckRequested = false; + Nvm.MacGroup1.SrvAckRequested = false; // Reset to application defaults InitDefaultsParams_t params; params.Type = INIT_TYPE_RESET_TO_DEFAULT_CHANNELS; - params.NvmCtx = NULL; - RegionInitDefaults( MacCtx.NvmCtx->Region, ¶ms ); + params.NvmGroup1 = &Nvm.RegionGroup1; + params.NvmGroup2 = &Nvm.RegionGroup2; + RegionInitDefaults( Nvm.MacGroup2.Region, ¶ms ); // Initialize channel index. MacCtx.Channel = 0; // Initialize Rx2 config parameters. MacCtx.RxWindow2Config.Channel = MacCtx.Channel; - MacCtx.RxWindow2Config.Frequency = MacCtx.NvmCtx->MacParams.Rx2Channel.Frequency; - MacCtx.RxWindow2Config.DownlinkDwellTime = MacCtx.NvmCtx->MacParams.DownlinkDwellTime; + MacCtx.RxWindow2Config.Frequency = Nvm.MacGroup2.MacParams.Rx2Channel.Frequency; + MacCtx.RxWindow2Config.DownlinkDwellTime = Nvm.MacGroup2.MacParams.DownlinkDwellTime; MacCtx.RxWindow2Config.RxContinuous = false; MacCtx.RxWindow2Config.RxSlot = RX_SLOT_WIN_2; @@ -2721,12 +2651,12 @@ static void ResetMacParameters( void ) classBParams.McpsIndication = &MacCtx.McpsIndication; classBParams.MlmeConfirm = &MacCtx.MlmeConfirm; classBParams.LoRaMacFlags = &MacCtx.MacFlags; - classBParams.LoRaMacDevAddr = &MacCtx.NvmCtx->DevAddr; - classBParams.LoRaMacRegion = &MacCtx.NvmCtx->Region; - classBParams.LoRaMacParams = &MacCtx.NvmCtx->MacParams; - classBParams.MulticastChannels = &MacCtx.NvmCtx->MulticastChannelList[0]; + classBParams.LoRaMacDevAddr = &Nvm.MacGroup2.DevAddr; + classBParams.LoRaMacRegion = &Nvm.MacGroup2.Region; + classBParams.LoRaMacParams = &Nvm.MacGroup2.MacParams; + classBParams.MulticastChannels = &Nvm.MacGroup2.MulticastChannelList[0]; - LoRaMacClassBInit( &classBParams, &classBCallbacks, &EventClassBNvmCtxChanged ); + LoRaMacClassBInit( &classBParams, &classBCallbacks, &Nvm.ClassB ); } /*! @@ -2742,9 +2672,9 @@ static void RxWindowSetup( TimerEvent_t* rxTimer, RxConfigParams_t* rxConfig ) // Ensure the radio is Idle Radio.Standby( ); - if( RegionRxConfig( MacCtx.NvmCtx->Region, rxConfig, ( int8_t* )&MacCtx.McpsIndication.RxDatarate ) == true ) + if( RegionRxConfig( Nvm.MacGroup2.Region, rxConfig, ( int8_t* )&MacCtx.McpsIndication.RxDatarate ) == true ) { - Radio.Rx( MacCtx.NvmCtx->MacParams.MaxRxWindow ); + Radio.Rx( Nvm.MacGroup2.MacParams.MaxRxWindow ); MacCtx.RxSlot = rxConfig->RxSlot; } } @@ -2752,10 +2682,10 @@ static void RxWindowSetup( TimerEvent_t* rxTimer, RxConfigParams_t* rxConfig ) static void OpenContinuousRxCWindow( void ) { // Compute RxC windows parameters - RegionComputeRxWindowParameters( MacCtx.NvmCtx->Region, - MacCtx.NvmCtx->MacParams.RxCChannel.Datarate, - MacCtx.NvmCtx->MacParams.MinRxSymbols, - MacCtx.NvmCtx->MacParams.SystemMaxRxError, + RegionComputeRxWindowParameters( Nvm.MacGroup2.Region, + Nvm.MacGroup2.MacParams.RxCChannel.Datarate, + Nvm.MacGroup2.MacParams.MinRxSymbols, + Nvm.MacGroup2.MacParams.SystemMaxRxError, &MacCtx.RxWindowCConfig ); MacCtx.RxWindowCConfig.RxSlot = RX_SLOT_WIN_CLASS_C; @@ -2764,7 +2694,7 @@ static void OpenContinuousRxCWindow( void ) // At this point the Radio should be idle. // Thus, there is no need to set the radio in standby mode. - if( RegionRxConfig( MacCtx.NvmCtx->Region, &MacCtx.RxWindowCConfig, ( int8_t* )&MacCtx.McpsIndication.RxDatarate ) == true ) + if( RegionRxConfig( Nvm.MacGroup2.Region, &MacCtx.RxWindowCConfig, ( int8_t* )&MacCtx.McpsIndication.RxDatarate ) == true ) { Radio.Rx( 0 ); // Continuous mode MacCtx.RxSlot = MacCtx.RxWindowCConfig.RxSlot; @@ -2799,7 +2729,7 @@ LoRaMacStatus_t PrepareFrame( LoRaMacHeader_t* macHdr, LoRaMacFrameCtrl_t* fCtrl MacCtx.TxMsg.Message.Data.BufSize = LORAMAC_PHY_MAXPAYLOAD; MacCtx.TxMsg.Message.Data.MHDR.Value = macHdr->Value; MacCtx.TxMsg.Message.Data.FPort = fPort; - MacCtx.TxMsg.Message.Data.FHDR.DevAddr = MacCtx.NvmCtx->DevAddr; + MacCtx.TxMsg.Message.Data.FHDR.DevAddr = Nvm.MacGroup2.DevAddr; MacCtx.TxMsg.Message.Data.FHDR.FCtrl.Value = fCtrl->Value; MacCtx.TxMsg.Message.Data.FRMPayloadSize = MacCtx.AppDataSize; MacCtx.TxMsg.Message.Data.FRMPayload = MacCtx.AppData; @@ -2823,7 +2753,7 @@ LoRaMacStatus_t PrepareFrame( LoRaMacHeader_t* macHdr, LoRaMacFrameCtrl_t* fCtrl if( macCmdsSize > 0 ) { - availableSize = GetMaxAppPayloadWithoutFOptsLength( MacCtx.NvmCtx->MacParams.ChannelsDatarate ); + availableSize = GetMaxAppPayloadWithoutFOptsLength( Nvm.MacGroup1.ChannelsDatarate ); // There is application payload available and the MAC commands fit into FOpts field. if( ( MacCtx.AppDataSize > 0 ) && ( macCmdsSize <= LORA_MAC_COMMAND_MAX_FOPTS_LENGTH ) ) @@ -2840,7 +2770,7 @@ LoRaMacStatus_t PrepareFrame( LoRaMacHeader_t* macHdr, LoRaMacFrameCtrl_t* fCtrl else if( ( MacCtx.AppDataSize > 0 ) && ( macCmdsSize > LORA_MAC_COMMAND_MAX_FOPTS_LENGTH ) ) { - if( LoRaMacCommandsSerializeCmds( availableSize, &macCmdsSize, MacCtx.NvmCtx->MacCommandsBuffer ) != LORAMAC_COMMANDS_SUCCESS ) + if( LoRaMacCommandsSerializeCmds( availableSize, &macCmdsSize, MacCtx.MacCommandsBuffer ) != LORAMAC_COMMANDS_SUCCESS ) { return LORAMAC_STATUS_MAC_COMMAD_ERROR; } @@ -2849,14 +2779,14 @@ LoRaMacStatus_t PrepareFrame( LoRaMacHeader_t* macHdr, LoRaMacFrameCtrl_t* fCtrl // No application payload available therefore add all mac commands to the FRMPayload. else { - if( LoRaMacCommandsSerializeCmds( availableSize, &macCmdsSize, MacCtx.NvmCtx->MacCommandsBuffer ) != LORAMAC_COMMANDS_SUCCESS ) + if( LoRaMacCommandsSerializeCmds( availableSize, &macCmdsSize, MacCtx.MacCommandsBuffer ) != LORAMAC_COMMANDS_SUCCESS ) { return LORAMAC_STATUS_MAC_COMMAD_ERROR; } // Force FPort to be zero MacCtx.TxMsg.Message.Data.FPort = 0; - MacCtx.TxMsg.Message.Data.FRMPayload = MacCtx.NvmCtx->MacCommandsBuffer; + MacCtx.TxMsg.Message.Data.FRMPayload = MacCtx.MacCommandsBuffer; MacCtx.TxMsg.Message.Data.FRMPayloadSize = macCmdsSize; } } @@ -2883,16 +2813,16 @@ LoRaMacStatus_t SendFrameOnChannel( uint8_t channel ) int8_t txPower = 0; txConfig.Channel = channel; - txConfig.Datarate = MacCtx.NvmCtx->MacParams.ChannelsDatarate; - txConfig.TxPower = MacCtx.NvmCtx->MacParams.ChannelsTxPower; - txConfig.MaxEirp = MacCtx.NvmCtx->MacParams.MaxEirp; - txConfig.AntennaGain = MacCtx.NvmCtx->MacParams.AntennaGain; + txConfig.Datarate = Nvm.MacGroup1.ChannelsDatarate; + txConfig.TxPower = Nvm.MacGroup1.ChannelsTxPower; + txConfig.MaxEirp = Nvm.MacGroup2.MacParams.MaxEirp; + txConfig.AntennaGain = Nvm.MacGroup2.MacParams.AntennaGain; txConfig.PktLen = MacCtx.PktBufferLen; - RegionTxConfig( MacCtx.NvmCtx->Region, &txConfig, &txPower, &MacCtx.TxTimeOnAir ); + RegionTxConfig( Nvm.MacGroup2.Region, &txConfig, &txPower, &MacCtx.TxTimeOnAir ); MacCtx.McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR; - MacCtx.McpsConfirm.Datarate = MacCtx.NvmCtx->MacParams.ChannelsDatarate; + MacCtx.McpsConfirm.Datarate = Nvm.MacGroup1.ChannelsDatarate; MacCtx.McpsConfirm.TxPower = txPower; MacCtx.McpsConfirm.Channel = channel; @@ -2912,7 +2842,7 @@ LoRaMacStatus_t SendFrameOnChannel( uint8_t channel ) } } - if( MacCtx.NvmCtx->DeviceClass == CLASS_B ) + if( Nvm.MacGroup2.DeviceClass == CLASS_B ) { // Stop slots for class b LoRaMacClassBStopRxSlots( ); @@ -2921,7 +2851,7 @@ LoRaMacStatus_t SendFrameOnChannel( uint8_t channel ) LoRaMacClassBHaltBeaconing( ); // Secure frame - status = SecureFrame( MacCtx.NvmCtx->MacParams.ChannelsDatarate, MacCtx.Channel ); + status = SecureFrame( Nvm.MacGroup1.ChannelsDatarate, MacCtx.Channel ); if( status != LORAMAC_STATUS_OK ) { return status; @@ -2944,13 +2874,13 @@ LoRaMacStatus_t SetTxContinuousWave( uint16_t timeout ) ContinuousWaveParams_t continuousWave; continuousWave.Channel = MacCtx.Channel; - continuousWave.Datarate = MacCtx.NvmCtx->MacParams.ChannelsDatarate; - continuousWave.TxPower = MacCtx.NvmCtx->MacParams.ChannelsTxPower; - continuousWave.MaxEirp = MacCtx.NvmCtx->MacParams.MaxEirp; - continuousWave.AntennaGain = MacCtx.NvmCtx->MacParams.AntennaGain; + continuousWave.Datarate = Nvm.MacGroup1.ChannelsDatarate; + continuousWave.TxPower = Nvm.MacGroup1.ChannelsTxPower; + continuousWave.MaxEirp = Nvm.MacGroup2.MacParams.MaxEirp; + continuousWave.AntennaGain = Nvm.MacGroup2.MacParams.AntennaGain; continuousWave.Timeout = timeout; - RegionSetContinuousWave( MacCtx.NvmCtx->Region, &continuousWave ); + RegionSetContinuousWave( Nvm.MacGroup2.Region, &continuousWave ); MacCtx.MacState |= LORAMAC_TX_RUNNING; @@ -2966,24 +2896,17 @@ LoRaMacStatus_t SetTxContinuousWave1( uint16_t timeout, uint32_t frequency, int8 return LORAMAC_STATUS_OK; } -LoRaMacCtxs_t* GetCtxs( void ) +LoRaMacNvmData_t* GetNvmData( void ) { - Contexts.MacNvmCtx = &NvmMacCtx; - Contexts.MacNvmCtxSize = sizeof( NvmMacCtx ); - Contexts.CryptoNvmCtx = LoRaMacCryptoGetNvmCtx( &Contexts.CryptoNvmCtxSize ); - GetNvmCtxParams_t params ={ 0 }; - Contexts.RegionNvmCtx = RegionGetNvmCtx( MacCtx.NvmCtx->Region, ¶ms ); - Contexts.RegionNvmCtxSize = params.nvmCtxSize; - Contexts.SecureElementNvmCtx = SecureElementGetNvmCtx( &Contexts.SecureElementNvmCtxSize ); - Contexts.CommandsNvmCtx = LoRaMacCommandsGetNvmCtx( &Contexts.CommandsNvmCtxSize ); - Contexts.ClassBNvmCtx = LoRaMacClassBGetNvmCtx( &Contexts.ClassBNvmCtxSize ); - Contexts.ConfirmQueueNvmCtx = LoRaMacConfirmQueueGetNvmCtx( &Contexts.ConfirmQueueNvmCtxSize ); - return &Contexts; + return &Nvm; } -LoRaMacStatus_t RestoreCtxs( LoRaMacCtxs_t* contexts ) +LoRaMacStatus_t RestoreNvmData( LoRaMacNvmData_t* nvm ) { - if( contexts == NULL ) + uint32_t crc = 0; + + // Status and parameter validation + if( nvm == NULL ) { return LORAMAC_STATUS_PARAMETER_INVALID; } @@ -2992,46 +2915,64 @@ LoRaMacStatus_t RestoreCtxs( LoRaMacCtxs_t* contexts ) return LORAMAC_STATUS_BUSY; } - if( contexts->MacNvmCtx != NULL ) + // Crypto + crc = Crc32( ( uint8_t* ) &nvm->Crypto, sizeof( nvm->Crypto ) - + sizeof( nvm->Crypto.Crc32 ) ); + if( crc == nvm->Crypto.Crc32 ) { - memcpy1( ( uint8_t* ) &NvmMacCtx, ( uint8_t* ) contexts->MacNvmCtx, contexts->MacNvmCtxSize ); + memcpy1( ( uint8_t* ) &Nvm.Crypto, ( uint8_t* ) &nvm->Crypto, + sizeof( Nvm.Crypto ) ); } - InitDefaultsParams_t params; - params.Type = INIT_TYPE_RESTORE_CTX; - params.NvmCtx = contexts->RegionNvmCtx; - RegionInitDefaults( MacCtx.NvmCtx->Region, ¶ms ); - - // Initialize RxC config parameters. - MacCtx.RxWindowCConfig.Channel = MacCtx.Channel; - MacCtx.RxWindowCConfig.Frequency = MacCtx.NvmCtx->MacParams.RxCChannel.Frequency; - MacCtx.RxWindowCConfig.DownlinkDwellTime = MacCtx.NvmCtx->MacParams.DownlinkDwellTime; - MacCtx.RxWindowCConfig.RxContinuous = true; - MacCtx.RxWindowCConfig.RxSlot = RX_SLOT_WIN_CLASS_C; - - if( SecureElementRestoreNvmCtx( contexts->SecureElementNvmCtx ) != SECURE_ELEMENT_SUCCESS ) + // MacGroup1 + crc = Crc32( ( uint8_t* ) &nvm->MacGroup1, sizeof( nvm->MacGroup1 ) - + sizeof( nvm->MacGroup1.Crc32 ) ); + if( crc == nvm->MacGroup1.Crc32 ) { - return LORAMAC_STATUS_CRYPTO_ERROR; + memcpy1( ( uint8_t* ) &Nvm.MacGroup1, ( uint8_t* ) &nvm->MacGroup1, + sizeof( Nvm.MacGroup1 ) ); } - if( LoRaMacCryptoRestoreNvmCtx( contexts->CryptoNvmCtx ) != LORAMAC_CRYPTO_SUCCESS ) + // MacGroup2 + crc = Crc32( ( uint8_t* ) &nvm->MacGroup2, sizeof( nvm->MacGroup2 ) - + sizeof( nvm->MacGroup2.Crc32 ) ); + if( crc == nvm->MacGroup2.Crc32 ) { - return LORAMAC_STATUS_CRYPTO_ERROR; + memcpy1( ( uint8_t* ) &Nvm.MacGroup2, ( uint8_t* ) &nvm->MacGroup2, + sizeof( Nvm.MacGroup2 ) ); + + // Initialize RxC config parameters. + MacCtx.RxWindowCConfig.Channel = MacCtx.Channel; + MacCtx.RxWindowCConfig.Frequency = Nvm.MacGroup2.MacParams.RxCChannel.Frequency; + MacCtx.RxWindowCConfig.DownlinkDwellTime = Nvm.MacGroup2.MacParams.DownlinkDwellTime; + MacCtx.RxWindowCConfig.RxContinuous = true; + MacCtx.RxWindowCConfig.RxSlot = RX_SLOT_WIN_CLASS_C; } - if( LoRaMacCommandsRestoreNvmCtx( contexts->CommandsNvmCtx ) != LORAMAC_COMMANDS_SUCCESS ) + // Secure Element + crc = Crc32( ( uint8_t* ) &nvm->SecureElement, sizeof( nvm->SecureElement ) - + sizeof( nvm->SecureElement.Crc32 ) ); + if( crc == nvm->SecureElement.Crc32 ) { - return LORAMAC_STATUS_MAC_COMMAD_ERROR; + memcpy1( ( uint8_t* ) &Nvm.SecureElement,( uint8_t* ) &nvm->SecureElement, + sizeof( Nvm.SecureElement ) ); } - if( LoRaMacClassBRestoreNvmCtx( contexts->ClassBNvmCtx ) != true ) + // Region + crc = Crc32( ( uint8_t* ) &nvm->RegionGroup1, sizeof( nvm->RegionGroup1 ) - + sizeof( nvm->RegionGroup1.Crc32 ) ); + if( crc == nvm->RegionGroup1.Crc32 ) { - return LORAMAC_STATUS_CLASS_B_ERROR; + memcpy1( ( uint8_t* ) &Nvm.RegionGroup1,( uint8_t* ) &nvm->RegionGroup1, + sizeof( Nvm.RegionGroup1 ) ); } - if( LoRaMacConfirmQueueRestoreNvmCtx( contexts->ConfirmQueueNvmCtx ) != true ) + crc = Crc32( ( uint8_t* ) &nvm->ClassB, sizeof( nvm->ClassB ) - + sizeof( nvm->ClassB.Crc32 ) ); + if( crc == nvm->ClassB.Crc32 ) { - return LORAMAC_STATUS_CONFIRM_QUEUE_ERROR; + memcpy1( ( uint8_t* ) &Nvm.ClassB,( uint8_t* ) &nvm->ClassB, + sizeof( Nvm.ClassB ) ); } return LORAMAC_STATUS_OK; @@ -3093,14 +3034,14 @@ static bool CheckRetransUnconfirmedUplink( void ) { // Unconfirmed uplink, when all retransmissions are done. if( MacCtx.ChannelsNbTransCounter >= - MacCtx.NvmCtx->MacParams.ChannelsNbTrans ) + Nvm.MacGroup2.MacParams.ChannelsNbTrans ) { return true; } else if( MacCtx.MacFlags.Bits.McpsInd == 1 ) { // For Class A stop in each case - if( MacCtx.NvmCtx->DeviceClass == CLASS_A ) + if( Nvm.MacGroup2.DeviceClass == CLASS_A ) { return true; } @@ -3140,9 +3081,9 @@ static bool StopRetransmission( void ) ( MacCtx.McpsIndication.RxSlot != RX_SLOT_WIN_2 ) ) ) { // Maximum repetitions without downlink. Increase ADR Ack counter. // Only process the case when the MAC did not receive a downlink. - if( MacCtx.NvmCtx->AdrCtrlOn == true ) + if( Nvm.MacGroup2.AdrCtrlOn == true ) { - MacCtx.NvmCtx->AdrAckCounter++; + Nvm.MacGroup1.AdrAckCounter++; } } @@ -3154,6 +3095,15 @@ static bool StopRetransmission( void ) return true; } +static void CallNvmDataChangeCallback( uint16_t notifyFlags ) +{ + if( ( MacCtx.MacCallbacks != NULL ) && + ( MacCtx.MacCallbacks->NvmDataChange != NULL ) ) + { + MacCtx.MacCallbacks->NvmDataChange ( notifyFlags ); + } +} + static void AckTimeoutRetriesProcess( void ) { if( MacCtx.AckTimeoutRetriesCounter < MacCtx.AckTimeoutRetries ) @@ -3165,10 +3115,10 @@ static void AckTimeoutRetriesProcess( void ) PhyParam_t phyParam; getPhy.Attribute = PHY_NEXT_LOWER_TX_DR; - getPhy.UplinkDwellTime = MacCtx.NvmCtx->MacParams.UplinkDwellTime; - getPhy.Datarate = MacCtx.NvmCtx->MacParams.ChannelsDatarate; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); - MacCtx.NvmCtx->MacParams.ChannelsDatarate = phyParam.Value; + getPhy.UplinkDwellTime = Nvm.MacGroup2.MacParams.UplinkDwellTime; + getPhy.Datarate = Nvm.MacGroup1.ChannelsDatarate; + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); + Nvm.MacGroup1.ChannelsDatarate = phyParam.Value; } } } @@ -3179,8 +3129,9 @@ static void AckTimeoutRetriesFinalize( void ) { InitDefaultsParams_t params; params.Type = INIT_TYPE_ACTIVATE_DEFAULT_CHANNELS; - params.NvmCtx = Contexts.RegionNvmCtx; - RegionInitDefaults( MacCtx.NvmCtx->Region, ¶ms ); + params.NvmGroup1 = &Nvm.RegionGroup1; + params.NvmGroup2 = &Nvm.RegionGroup2; + RegionInitDefaults( Nvm.MacGroup2.Region, ¶ms ); MacCtx.NodeAckRequested = false; MacCtx.McpsConfirm.AckReceived = false; @@ -3188,49 +3139,6 @@ static void AckTimeoutRetriesFinalize( void ) MacCtx.McpsConfirm.NbRetries = MacCtx.AckTimeoutRetriesCounter; } -static void CallNvmCtxCallback( LoRaMacNvmCtxModule_t module ) -{ - if( ( MacCtx.MacCallbacks != NULL ) && ( MacCtx.MacCallbacks->NvmContextChange != NULL ) ) - { - MacCtx.MacCallbacks->NvmContextChange( module ); - } -} - -static void EventMacNvmCtxChanged( void ) -{ - CallNvmCtxCallback( LORAMAC_NVMCTXMODULE_MAC ); -} - -static void EventRegionNvmCtxChanged( void ) -{ - CallNvmCtxCallback( LORAMAC_NVMCTXMODULE_REGION ); -} - -static void EventCryptoNvmCtxChanged( void ) -{ - CallNvmCtxCallback( LORAMAC_NVMCTXMODULE_CRYPTO ); -} - -static void EventSecureElementNvmCtxChanged( void ) -{ - CallNvmCtxCallback( LORAMAC_NVMCTXMODULE_SECURE_ELEMENT ); -} - -static void EventCommandsNvmCtxChanged( void ) -{ - CallNvmCtxCallback( LORAMAC_NVMCTXMODULE_COMMANDS ); -} - -static void EventClassBNvmCtxChanged( void ) -{ - CallNvmCtxCallback( LORAMAC_NVMCTXMODULE_CLASS_B ); -} - -static void EventConfirmQueueNvmCtxChanged( void ) -{ - CallNvmCtxCallback( LORAMAC_NVMCTXMODULE_CONFIRM_QUEUE ); -} - static uint8_t IsRequestPending( void ) { if( ( MacCtx.MacFlags.Bits.MlmeReq == 1 ) || @@ -3267,115 +3175,115 @@ LoRaMacStatus_t LoRaMacInitialization( LoRaMacPrimitives_t* primitives, LoRaMacC } // Confirm queue reset - LoRaMacConfirmQueueInit( primitives, EventConfirmQueueNvmCtxChanged ); + LoRaMacConfirmQueueInit( primitives ); // Initialize the module context with zeros - memset1( ( uint8_t* ) &NvmMacCtx, 0x00, sizeof( LoRaMacNvmCtx_t ) ); + memset1( ( uint8_t* ) &Nvm, 0x00, sizeof( LoRaMacNvmData_t ) ); memset1( ( uint8_t* ) &MacCtx, 0x00, sizeof( LoRaMacCtx_t ) ); - MacCtx.NvmCtx = &NvmMacCtx; // Set non zero variables to its default value MacCtx.AckTimeoutRetriesCounter = 1; MacCtx.AckTimeoutRetries = 1; - MacCtx.NvmCtx->Region = region; - MacCtx.NvmCtx->DeviceClass = CLASS_A; + Nvm.MacGroup2.Region = region; + Nvm.MacGroup2.DeviceClass = CLASS_A; // Setup version - MacCtx.NvmCtx->Version.Value = LORAMAC_VERSION; + Nvm.MacGroup2.Version.Value = LORAMAC_VERSION; // Reset to defaults getPhy.Attribute = PHY_DUTY_CYCLE; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); - MacCtx.NvmCtx->DutyCycleOn = ( bool ) phyParam.Value; + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); + Nvm.MacGroup2.DutyCycleOn = ( bool ) phyParam.Value; getPhy.Attribute = PHY_DEF_TX_POWER; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); - MacCtx.NvmCtx->MacParamsDefaults.ChannelsTxPower = phyParam.Value; + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); + Nvm.MacGroup2.ChannelsTxPowerDefault = phyParam.Value; getPhy.Attribute = PHY_DEF_TX_DR; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); - MacCtx.NvmCtx->MacParamsDefaults.ChannelsDatarate = phyParam.Value; + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); + Nvm.MacGroup2.ChannelsDatarateDefault = phyParam.Value; getPhy.Attribute = PHY_MAX_RX_WINDOW; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); - MacCtx.NvmCtx->MacParamsDefaults.MaxRxWindow = phyParam.Value; + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); + Nvm.MacGroup2.MacParamsDefaults.MaxRxWindow = phyParam.Value; getPhy.Attribute = PHY_RECEIVE_DELAY1; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); - MacCtx.NvmCtx->MacParamsDefaults.ReceiveDelay1 = phyParam.Value; + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); + Nvm.MacGroup2.MacParamsDefaults.ReceiveDelay1 = phyParam.Value; getPhy.Attribute = PHY_RECEIVE_DELAY2; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); - MacCtx.NvmCtx->MacParamsDefaults.ReceiveDelay2 = phyParam.Value; + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); + Nvm.MacGroup2.MacParamsDefaults.ReceiveDelay2 = phyParam.Value; getPhy.Attribute = PHY_JOIN_ACCEPT_DELAY1; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); - MacCtx.NvmCtx->MacParamsDefaults.JoinAcceptDelay1 = phyParam.Value; + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); + Nvm.MacGroup2.MacParamsDefaults.JoinAcceptDelay1 = phyParam.Value; getPhy.Attribute = PHY_JOIN_ACCEPT_DELAY2; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); - MacCtx.NvmCtx->MacParamsDefaults.JoinAcceptDelay2 = phyParam.Value; + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); + Nvm.MacGroup2.MacParamsDefaults.JoinAcceptDelay2 = phyParam.Value; getPhy.Attribute = PHY_DEF_DR1_OFFSET; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); - MacCtx.NvmCtx->MacParamsDefaults.Rx1DrOffset = phyParam.Value; + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); + Nvm.MacGroup2.MacParamsDefaults.Rx1DrOffset = phyParam.Value; getPhy.Attribute = PHY_DEF_RX2_FREQUENCY; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); - MacCtx.NvmCtx->MacParamsDefaults.Rx2Channel.Frequency = phyParam.Value; - MacCtx.NvmCtx->MacParamsDefaults.RxCChannel.Frequency = phyParam.Value; + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); + Nvm.MacGroup2.MacParamsDefaults.Rx2Channel.Frequency = phyParam.Value; + Nvm.MacGroup2.MacParamsDefaults.RxCChannel.Frequency = phyParam.Value; getPhy.Attribute = PHY_DEF_RX2_DR; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); - MacCtx.NvmCtx->MacParamsDefaults.Rx2Channel.Datarate = phyParam.Value; - MacCtx.NvmCtx->MacParamsDefaults.RxCChannel.Datarate = phyParam.Value; + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); + Nvm.MacGroup2.MacParamsDefaults.Rx2Channel.Datarate = phyParam.Value; + Nvm.MacGroup2.MacParamsDefaults.RxCChannel.Datarate = phyParam.Value; getPhy.Attribute = PHY_DEF_UPLINK_DWELL_TIME; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); - MacCtx.NvmCtx->MacParamsDefaults.UplinkDwellTime = phyParam.Value; + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); + Nvm.MacGroup2.MacParamsDefaults.UplinkDwellTime = phyParam.Value; getPhy.Attribute = PHY_DEF_DOWNLINK_DWELL_TIME; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); - MacCtx.NvmCtx->MacParamsDefaults.DownlinkDwellTime = phyParam.Value; + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); + Nvm.MacGroup2.MacParamsDefaults.DownlinkDwellTime = phyParam.Value; getPhy.Attribute = PHY_DEF_MAX_EIRP; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); - MacCtx.NvmCtx->MacParamsDefaults.MaxEirp = phyParam.fValue; + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); + Nvm.MacGroup2.MacParamsDefaults.MaxEirp = phyParam.fValue; getPhy.Attribute = PHY_DEF_ANTENNA_GAIN; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); - MacCtx.NvmCtx->MacParamsDefaults.AntennaGain = phyParam.fValue; + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); + Nvm.MacGroup2.MacParamsDefaults.AntennaGain = phyParam.fValue; getPhy.Attribute = PHY_DEF_ADR_ACK_LIMIT; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); MacCtx.AdrAckLimit = phyParam.Value; getPhy.Attribute = PHY_DEF_ADR_ACK_DELAY; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); MacCtx.AdrAckDelay = phyParam.Value; // Init parameters which are not set in function ResetMacParameters - MacCtx.NvmCtx->MacParamsDefaults.ChannelsNbTrans = 1; - MacCtx.NvmCtx->MacParamsDefaults.SystemMaxRxError = 10; - MacCtx.NvmCtx->MacParamsDefaults.MinRxSymbols = 6; - - MacCtx.NvmCtx->MacParams.SystemMaxRxError = MacCtx.NvmCtx->MacParamsDefaults.SystemMaxRxError; - MacCtx.NvmCtx->MacParams.MinRxSymbols = MacCtx.NvmCtx->MacParamsDefaults.MinRxSymbols; - MacCtx.NvmCtx->MacParams.MaxRxWindow = MacCtx.NvmCtx->MacParamsDefaults.MaxRxWindow; - MacCtx.NvmCtx->MacParams.ReceiveDelay1 = MacCtx.NvmCtx->MacParamsDefaults.ReceiveDelay1; - MacCtx.NvmCtx->MacParams.ReceiveDelay2 = MacCtx.NvmCtx->MacParamsDefaults.ReceiveDelay2; - MacCtx.NvmCtx->MacParams.JoinAcceptDelay1 = MacCtx.NvmCtx->MacParamsDefaults.JoinAcceptDelay1; - MacCtx.NvmCtx->MacParams.JoinAcceptDelay2 = MacCtx.NvmCtx->MacParamsDefaults.JoinAcceptDelay2; - MacCtx.NvmCtx->MacParams.ChannelsNbTrans = MacCtx.NvmCtx->MacParamsDefaults.ChannelsNbTrans; + Nvm.MacGroup2.MacParamsDefaults.ChannelsNbTrans = 1; + Nvm.MacGroup2.MacParamsDefaults.SystemMaxRxError = 10; + Nvm.MacGroup2.MacParamsDefaults.MinRxSymbols = 6; + + Nvm.MacGroup2.MacParams.SystemMaxRxError = Nvm.MacGroup2.MacParamsDefaults.SystemMaxRxError; + Nvm.MacGroup2.MacParams.MinRxSymbols = Nvm.MacGroup2.MacParamsDefaults.MinRxSymbols; + Nvm.MacGroup2.MacParams.MaxRxWindow = Nvm.MacGroup2.MacParamsDefaults.MaxRxWindow; + Nvm.MacGroup2.MacParams.ReceiveDelay1 = Nvm.MacGroup2.MacParamsDefaults.ReceiveDelay1; + Nvm.MacGroup2.MacParams.ReceiveDelay2 = Nvm.MacGroup2.MacParamsDefaults.ReceiveDelay2; + Nvm.MacGroup2.MacParams.JoinAcceptDelay1 = Nvm.MacGroup2.MacParamsDefaults.JoinAcceptDelay1; + Nvm.MacGroup2.MacParams.JoinAcceptDelay2 = Nvm.MacGroup2.MacParamsDefaults.JoinAcceptDelay2; + Nvm.MacGroup2.MacParams.ChannelsNbTrans = Nvm.MacGroup2.MacParamsDefaults.ChannelsNbTrans; InitDefaultsParams_t params; params.Type = INIT_TYPE_DEFAULTS; - params.NvmCtx = NULL; - RegionInitDefaults( MacCtx.NvmCtx->Region, ¶ms ); + params.NvmGroup1 = &Nvm.RegionGroup1; + params.NvmGroup2 = &Nvm.RegionGroup2; + RegionInitDefaults( Nvm.MacGroup2.Region, ¶ms ); ResetMacParameters( ); - MacCtx.NvmCtx->PublicNetwork = true; + Nvm.MacGroup2.PublicNetwork = true; MacCtx.MacPrimitives = primitives; MacCtx.MacCallbacks = callbacks; @@ -3383,8 +3291,8 @@ LoRaMacStatus_t LoRaMacInitialization( LoRaMacPrimitives_t* primitives, LoRaMacC MacCtx.MacState = LORAMAC_STOPPED; // Reset duty cycle times - MacCtx.NvmCtx->LastTxDoneTime = 0; - MacCtx.NvmCtx->AggregatedTimeOff = 0; + Nvm.MacGroup1.LastTxDoneTime = 0; + Nvm.MacGroup1.AggregatedTimeOff = 0; // Initialize timers TimerInit( &MacCtx.TxDelayedTimer, OnTxDelayedTimerEvent ); @@ -3393,7 +3301,7 @@ LoRaMacStatus_t LoRaMacInitialization( LoRaMacPrimitives_t* primitives, LoRaMacC TimerInit( &MacCtx.AckTimeoutTimer, OnAckTimeoutTimerEvent ); // Store the current initialization time - MacCtx.NvmCtx->InitializationTime = SysTimeGetMcuTime( ); + Nvm.MacGroup2.InitializationTime = SysTimeGetMcuTime( ); // Initialize Radio driver MacCtx.RadioEvents.TxDone = OnRadioTxDone; @@ -3404,25 +3312,25 @@ LoRaMacStatus_t LoRaMacInitialization( LoRaMacPrimitives_t* primitives, LoRaMacC Radio.Init( &MacCtx.RadioEvents ); // Initialize the Secure Element driver - if( SecureElementInit( EventSecureElementNvmCtxChanged ) != SECURE_ELEMENT_SUCCESS ) + if( SecureElementInit( &Nvm.SecureElement ) != SECURE_ELEMENT_SUCCESS ) { return LORAMAC_STATUS_CRYPTO_ERROR; } // Initialize Crypto module - if( LoRaMacCryptoInit( EventCryptoNvmCtxChanged ) != LORAMAC_CRYPTO_SUCCESS ) + if( LoRaMacCryptoInit( &Nvm.Crypto ) != LORAMAC_CRYPTO_SUCCESS ) { return LORAMAC_STATUS_CRYPTO_ERROR; } // Initialize MAC commands module - if( LoRaMacCommandsInit( EventCommandsNvmCtxChanged ) != LORAMAC_COMMANDS_SUCCESS ) + if( LoRaMacCommandsInit( ) != LORAMAC_COMMANDS_SUCCESS ) { return LORAMAC_STATUS_MAC_COMMAD_ERROR; } // Set multicast downlink counter reference - if( LoRaMacCryptoSetMulticastReference( MacCtx.NvmCtx->MulticastChannelList ) != LORAMAC_CRYPTO_SUCCESS ) + if( LoRaMacCryptoSetMulticastReference( Nvm.MacGroup2.MulticastChannelList ) != LORAMAC_CRYPTO_SUCCESS ) { return LORAMAC_STATUS_CRYPTO_ERROR; } @@ -3430,7 +3338,7 @@ LoRaMacStatus_t LoRaMacInitialization( LoRaMacPrimitives_t* primitives, LoRaMacC // Random seed initialization srand1( Radio.Random( ) ); - Radio.SetPublicNetwork( MacCtx.NvmCtx->PublicNetwork ); + Radio.SetPublicNetwork( Nvm.MacGroup2.PublicNetwork ); Radio.Sleep( ); LoRaMacEnableRequests( LORAMAC_REQUEST_HANDLING_ON ); @@ -3461,9 +3369,9 @@ LoRaMacStatus_t LoRaMacStop( void ) LoRaMacStatus_t LoRaMacQueryTxPossible( uint8_t size, LoRaMacTxInfo_t* txInfo ) { CalcNextAdrParams_t adrNext; - uint32_t adrAckCounter = MacCtx.NvmCtx->AdrAckCounter; - int8_t datarate = MacCtx.NvmCtx->MacParamsDefaults.ChannelsDatarate; - int8_t txPower = MacCtx.NvmCtx->MacParamsDefaults.ChannelsTxPower; + uint32_t adrAckCounter = Nvm.MacGroup1.AdrAckCounter; + int8_t datarate = Nvm.MacGroup2.ChannelsDatarateDefault; + int8_t txPower = Nvm.MacGroup2.ChannelsTxPowerDefault; size_t macCmdsSize = 0; if( txInfo == NULL ) @@ -3472,16 +3380,16 @@ LoRaMacStatus_t LoRaMacQueryTxPossible( uint8_t size, LoRaMacTxInfo_t* txInfo ) } // Setup ADR request - adrNext.Version = MacCtx.NvmCtx->Version; + adrNext.Version = Nvm.MacGroup2.Version; adrNext.UpdateChanMask = false; - adrNext.AdrEnabled = MacCtx.NvmCtx->AdrCtrlOn; - adrNext.AdrAckCounter = MacCtx.NvmCtx->AdrAckCounter; + adrNext.AdrEnabled = Nvm.MacGroup2.AdrCtrlOn; + adrNext.AdrAckCounter = Nvm.MacGroup1.AdrAckCounter; adrNext.AdrAckLimit = MacCtx.AdrAckLimit; adrNext.AdrAckDelay = MacCtx.AdrAckDelay; - adrNext.Datarate = MacCtx.NvmCtx->MacParams.ChannelsDatarate; - adrNext.TxPower = MacCtx.NvmCtx->MacParams.ChannelsTxPower; - adrNext.UplinkDwellTime = MacCtx.NvmCtx->MacParams.UplinkDwellTime; - adrNext.Region = MacCtx.NvmCtx->Region; + adrNext.Datarate = Nvm.MacGroup1.ChannelsDatarate; + adrNext.TxPower = Nvm.MacGroup1.ChannelsTxPower; + adrNext.UplinkDwellTime = Nvm.MacGroup2.MacParams.UplinkDwellTime; + adrNext.Region = Nvm.MacGroup2.Region; // We call the function for information purposes only. We don't want to // apply the datarate, the tx power and the ADR ack counter. @@ -3531,12 +3439,12 @@ LoRaMacStatus_t LoRaMacMibGetRequestConfirm( MibRequestConfirm_t* mibGet ) { case MIB_DEVICE_CLASS: { - mibGet->Param.Class = MacCtx.NvmCtx->DeviceClass; + mibGet->Param.Class = Nvm.MacGroup2.DeviceClass; break; } case MIB_NETWORK_ACTIVATION: { - mibGet->Param.NetworkActivation = MacCtx.NvmCtx->NetworkActivation; + mibGet->Param.NetworkActivation = Nvm.MacGroup2.NetworkActivation; break; } case MIB_DEV_EUI: @@ -3556,56 +3464,56 @@ LoRaMacStatus_t LoRaMacMibGetRequestConfirm( MibRequestConfirm_t* mibGet ) } case MIB_ADR: { - mibGet->Param.AdrEnable = MacCtx.NvmCtx->AdrCtrlOn; + mibGet->Param.AdrEnable = Nvm.MacGroup2.AdrCtrlOn; break; } case MIB_NET_ID: { - mibGet->Param.NetID = MacCtx.NvmCtx->NetID; + mibGet->Param.NetID = Nvm.MacGroup2.NetID; break; } case MIB_DEV_ADDR: { - mibGet->Param.DevAddr = MacCtx.NvmCtx->DevAddr; + mibGet->Param.DevAddr = Nvm.MacGroup2.DevAddr; break; } case MIB_PUBLIC_NETWORK: { - mibGet->Param.EnablePublicNetwork = MacCtx.NvmCtx->PublicNetwork; + mibGet->Param.EnablePublicNetwork = Nvm.MacGroup2.PublicNetwork; break; } case MIB_CHANNELS: { getPhy.Attribute = PHY_CHANNELS; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); mibGet->Param.ChannelList = phyParam.Channels; break; } case MIB_RX2_CHANNEL: { - mibGet->Param.Rx2Channel = MacCtx.NvmCtx->MacParams.Rx2Channel; + mibGet->Param.Rx2Channel = Nvm.MacGroup2.MacParams.Rx2Channel; break; } case MIB_RX2_DEFAULT_CHANNEL: { - mibGet->Param.Rx2Channel = MacCtx.NvmCtx->MacParamsDefaults.Rx2Channel; + mibGet->Param.Rx2Channel = Nvm.MacGroup2.MacParamsDefaults.Rx2Channel; break; } case MIB_RXC_CHANNEL: { - mibGet->Param.RxCChannel = MacCtx.NvmCtx->MacParams.RxCChannel; + mibGet->Param.RxCChannel = Nvm.MacGroup2.MacParams.RxCChannel; break; } case MIB_RXC_DEFAULT_CHANNEL: { - mibGet->Param.RxCChannel = MacCtx.NvmCtx->MacParamsDefaults.RxCChannel; + mibGet->Param.RxCChannel = Nvm.MacGroup2.MacParamsDefaults.RxCChannel; break; } case MIB_CHANNELS_DEFAULT_MASK: { getPhy.Attribute = PHY_CHANNELS_DEFAULT_MASK; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); mibGet->Param.ChannelsDefaultMask = phyParam.ChannelsMask; break; @@ -3613,89 +3521,89 @@ LoRaMacStatus_t LoRaMacMibGetRequestConfirm( MibRequestConfirm_t* mibGet ) case MIB_CHANNELS_MASK: { getPhy.Attribute = PHY_CHANNELS_MASK; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); mibGet->Param.ChannelsMask = phyParam.ChannelsMask; break; } case MIB_CHANNELS_NB_TRANS: { - mibGet->Param.ChannelsNbTrans = MacCtx.NvmCtx->MacParams.ChannelsNbTrans; + mibGet->Param.ChannelsNbTrans = Nvm.MacGroup2.MacParams.ChannelsNbTrans; break; } case MIB_MAX_RX_WINDOW_DURATION: { - mibGet->Param.MaxRxWindow = MacCtx.NvmCtx->MacParams.MaxRxWindow; + mibGet->Param.MaxRxWindow = Nvm.MacGroup2.MacParams.MaxRxWindow; break; } case MIB_RECEIVE_DELAY_1: { - mibGet->Param.ReceiveDelay1 = MacCtx.NvmCtx->MacParams.ReceiveDelay1; + mibGet->Param.ReceiveDelay1 = Nvm.MacGroup2.MacParams.ReceiveDelay1; break; } case MIB_RECEIVE_DELAY_2: { - mibGet->Param.ReceiveDelay2 = MacCtx.NvmCtx->MacParams.ReceiveDelay2; + mibGet->Param.ReceiveDelay2 = Nvm.MacGroup2.MacParams.ReceiveDelay2; break; } case MIB_JOIN_ACCEPT_DELAY_1: { - mibGet->Param.JoinAcceptDelay1 = MacCtx.NvmCtx->MacParams.JoinAcceptDelay1; + mibGet->Param.JoinAcceptDelay1 = Nvm.MacGroup2.MacParams.JoinAcceptDelay1; break; } case MIB_JOIN_ACCEPT_DELAY_2: { - mibGet->Param.JoinAcceptDelay2 = MacCtx.NvmCtx->MacParams.JoinAcceptDelay2; + mibGet->Param.JoinAcceptDelay2 = Nvm.MacGroup2.MacParams.JoinAcceptDelay2; break; } case MIB_CHANNELS_DEFAULT_DATARATE: { - mibGet->Param.ChannelsDefaultDatarate = MacCtx.NvmCtx->MacParamsDefaults.ChannelsDatarate; + mibGet->Param.ChannelsDefaultDatarate = Nvm.MacGroup2.ChannelsDatarateDefault; break; } case MIB_CHANNELS_DATARATE: { - mibGet->Param.ChannelsDatarate = MacCtx.NvmCtx->MacParams.ChannelsDatarate; + mibGet->Param.ChannelsDatarate = Nvm.MacGroup1.ChannelsDatarate; break; } case MIB_CHANNELS_DEFAULT_TX_POWER: { - mibGet->Param.ChannelsDefaultTxPower = MacCtx.NvmCtx->MacParamsDefaults.ChannelsTxPower; + mibGet->Param.ChannelsDefaultTxPower = Nvm.MacGroup2.ChannelsTxPowerDefault; break; } case MIB_CHANNELS_TX_POWER: { - mibGet->Param.ChannelsTxPower = MacCtx.NvmCtx->MacParams.ChannelsTxPower; + mibGet->Param.ChannelsTxPower = Nvm.MacGroup1.ChannelsTxPower; break; } case MIB_SYSTEM_MAX_RX_ERROR: { - mibGet->Param.SystemMaxRxError = MacCtx.NvmCtx->MacParams.SystemMaxRxError; + mibGet->Param.SystemMaxRxError = Nvm.MacGroup2.MacParams.SystemMaxRxError; break; } case MIB_MIN_RX_SYMBOLS: { - mibGet->Param.MinRxSymbols = MacCtx.NvmCtx->MacParams.MinRxSymbols; + mibGet->Param.MinRxSymbols = Nvm.MacGroup2.MacParams.MinRxSymbols; break; } case MIB_ANTENNA_GAIN: { - mibGet->Param.AntennaGain = MacCtx.NvmCtx->MacParams.AntennaGain; + mibGet->Param.AntennaGain = Nvm.MacGroup2.MacParams.AntennaGain; break; } case MIB_NVM_CTXS: { - mibGet->Param.Contexts = GetCtxs( ); + mibGet->Param.Contexts = GetNvmData( ); break; } case MIB_DEFAULT_ANTENNA_GAIN: { - mibGet->Param.DefaultAntennaGain = MacCtx.NvmCtx->MacParamsDefaults.AntennaGain; + mibGet->Param.DefaultAntennaGain = Nvm.MacGroup2.MacParamsDefaults.AntennaGain; break; } case MIB_LORAWAN_VERSION: { - mibGet->Param.LrWanVersion.LoRaWan = MacCtx.NvmCtx->Version; + mibGet->Param.LrWanVersion.LoRaWan = Nvm.MacGroup2.Version; mibGet->Param.LrWanVersion.LoRaWanRegion = RegionGetVersion( ); break; } @@ -3734,7 +3642,7 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) { if( mibSet->Param.NetworkActivation != ACTIVATION_TYPE_OTAA ) { - MacCtx.NvmCtx->NetworkActivation = mibSet->Param.NetworkActivation; + Nvm.MacGroup2.NetworkActivation = mibSet->Param.NetworkActivation; } else { // Do not allow to set ACTIVATION_TYPE_OTAA since the MAC will set it automatically after a successful join process. @@ -3768,17 +3676,17 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) } case MIB_ADR: { - MacCtx.NvmCtx->AdrCtrlOn = mibSet->Param.AdrEnable; + Nvm.MacGroup2.AdrCtrlOn = mibSet->Param.AdrEnable; break; } case MIB_NET_ID: { - MacCtx.NvmCtx->NetID = mibSet->Param.NetID; + Nvm.MacGroup2.NetID = mibSet->Param.NetID; break; } case MIB_DEV_ADDR: { - MacCtx.NvmCtx->DevAddr = mibSet->Param.DevAddr; + Nvm.MacGroup2.DevAddr = mibSet->Param.DevAddr; break; } case MIB_APP_KEY: @@ -4098,18 +4006,18 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) } case MIB_PUBLIC_NETWORK: { - MacCtx.NvmCtx->PublicNetwork = mibSet->Param.EnablePublicNetwork; - Radio.SetPublicNetwork( MacCtx.NvmCtx->PublicNetwork ); + Nvm.MacGroup2.PublicNetwork = mibSet->Param.EnablePublicNetwork; + Radio.SetPublicNetwork( Nvm.MacGroup2.PublicNetwork ); break; } case MIB_RX2_CHANNEL: { verify.DatarateParams.Datarate = mibSet->Param.Rx2Channel.Datarate; - verify.DatarateParams.DownlinkDwellTime = MacCtx.NvmCtx->MacParams.DownlinkDwellTime; + verify.DatarateParams.DownlinkDwellTime = Nvm.MacGroup2.MacParams.DownlinkDwellTime; - if( RegionVerify( MacCtx.NvmCtx->Region, &verify, PHY_RX_DR ) == true ) + if( RegionVerify( Nvm.MacGroup2.Region, &verify, PHY_RX_DR ) == true ) { - MacCtx.NvmCtx->MacParams.Rx2Channel = mibSet->Param.Rx2Channel; + Nvm.MacGroup2.MacParams.Rx2Channel = mibSet->Param.Rx2Channel; } else { @@ -4120,11 +4028,11 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) case MIB_RX2_DEFAULT_CHANNEL: { verify.DatarateParams.Datarate = mibSet->Param.Rx2Channel.Datarate; - verify.DatarateParams.DownlinkDwellTime = MacCtx.NvmCtx->MacParams.DownlinkDwellTime; + verify.DatarateParams.DownlinkDwellTime = Nvm.MacGroup2.MacParams.DownlinkDwellTime; - if( RegionVerify( MacCtx.NvmCtx->Region, &verify, PHY_RX_DR ) == true ) + if( RegionVerify( Nvm.MacGroup2.Region, &verify, PHY_RX_DR ) == true ) { - MacCtx.NvmCtx->MacParamsDefaults.Rx2Channel = mibSet->Param.Rx2DefaultChannel; + Nvm.MacGroup2.MacParamsDefaults.Rx2Channel = mibSet->Param.Rx2DefaultChannel; } else { @@ -4135,13 +4043,13 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) case MIB_RXC_CHANNEL: { verify.DatarateParams.Datarate = mibSet->Param.RxCChannel.Datarate; - verify.DatarateParams.DownlinkDwellTime = MacCtx.NvmCtx->MacParams.DownlinkDwellTime; + verify.DatarateParams.DownlinkDwellTime = Nvm.MacGroup2.MacParams.DownlinkDwellTime; - if( RegionVerify( MacCtx.NvmCtx->Region, &verify, PHY_RX_DR ) == true ) + if( RegionVerify( Nvm.MacGroup2.Region, &verify, PHY_RX_DR ) == true ) { - MacCtx.NvmCtx->MacParams.RxCChannel = mibSet->Param.RxCChannel; + Nvm.MacGroup2.MacParams.RxCChannel = mibSet->Param.RxCChannel; - if( ( MacCtx.NvmCtx->DeviceClass == CLASS_C ) && ( MacCtx.NvmCtx->NetworkActivation != ACTIVATION_TYPE_NONE ) ) + if( ( Nvm.MacGroup2.DeviceClass == CLASS_C ) && ( Nvm.MacGroup2.NetworkActivation != ACTIVATION_TYPE_NONE ) ) { // 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 @@ -4161,11 +4069,11 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) case MIB_RXC_DEFAULT_CHANNEL: { verify.DatarateParams.Datarate = mibSet->Param.RxCChannel.Datarate; - verify.DatarateParams.DownlinkDwellTime = MacCtx.NvmCtx->MacParams.DownlinkDwellTime; + verify.DatarateParams.DownlinkDwellTime = Nvm.MacGroup2.MacParams.DownlinkDwellTime; - if( RegionVerify( MacCtx.NvmCtx->Region, &verify, PHY_RX_DR ) == true ) + if( RegionVerify( Nvm.MacGroup2.Region, &verify, PHY_RX_DR ) == true ) { - MacCtx.NvmCtx->MacParamsDefaults.RxCChannel = mibSet->Param.RxCDefaultChannel; + Nvm.MacGroup2.MacParamsDefaults.RxCChannel = mibSet->Param.RxCDefaultChannel; } else { @@ -4178,7 +4086,7 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) chanMaskSet.ChannelsMaskIn = mibSet->Param.ChannelsDefaultMask; chanMaskSet.ChannelsMaskType = CHANNELS_DEFAULT_MASK; - if( RegionChanMaskSet( MacCtx.NvmCtx->Region, &chanMaskSet ) == false ) + if( RegionChanMaskSet( Nvm.MacGroup2.Region, &chanMaskSet ) == false ) { status = LORAMAC_STATUS_PARAMETER_INVALID; } @@ -4189,7 +4097,7 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) chanMaskSet.ChannelsMaskIn = mibSet->Param.ChannelsMask; chanMaskSet.ChannelsMaskType = CHANNELS_MASK; - if( RegionChanMaskSet( MacCtx.NvmCtx->Region, &chanMaskSet ) == false ) + if( RegionChanMaskSet( Nvm.MacGroup2.Region, &chanMaskSet ) == false ) { status = LORAMAC_STATUS_PARAMETER_INVALID; } @@ -4200,7 +4108,7 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) if( ( mibSet->Param.ChannelsNbTrans >= 1 ) && ( mibSet->Param.ChannelsNbTrans <= 15 ) ) { - MacCtx.NvmCtx->MacParams.ChannelsNbTrans = mibSet->Param.ChannelsNbTrans; + Nvm.MacGroup2.MacParams.ChannelsNbTrans = mibSet->Param.ChannelsNbTrans; } else { @@ -4210,36 +4118,36 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) } case MIB_MAX_RX_WINDOW_DURATION: { - MacCtx.NvmCtx->MacParams.MaxRxWindow = mibSet->Param.MaxRxWindow; + Nvm.MacGroup2.MacParams.MaxRxWindow = mibSet->Param.MaxRxWindow; break; } case MIB_RECEIVE_DELAY_1: { - MacCtx.NvmCtx->MacParams.ReceiveDelay1 = mibSet->Param.ReceiveDelay1; + Nvm.MacGroup2.MacParams.ReceiveDelay1 = mibSet->Param.ReceiveDelay1; break; } case MIB_RECEIVE_DELAY_2: { - MacCtx.NvmCtx->MacParams.ReceiveDelay2 = mibSet->Param.ReceiveDelay2; + Nvm.MacGroup2.MacParams.ReceiveDelay2 = mibSet->Param.ReceiveDelay2; break; } case MIB_JOIN_ACCEPT_DELAY_1: { - MacCtx.NvmCtx->MacParams.JoinAcceptDelay1 = mibSet->Param.JoinAcceptDelay1; + Nvm.MacGroup2.MacParams.JoinAcceptDelay1 = mibSet->Param.JoinAcceptDelay1; break; } case MIB_JOIN_ACCEPT_DELAY_2: { - MacCtx.NvmCtx->MacParams.JoinAcceptDelay2 = mibSet->Param.JoinAcceptDelay2; + Nvm.MacGroup2.MacParams.JoinAcceptDelay2 = mibSet->Param.JoinAcceptDelay2; break; } case MIB_CHANNELS_DEFAULT_DATARATE: { verify.DatarateParams.Datarate = mibSet->Param.ChannelsDefaultDatarate; - if( RegionVerify( MacCtx.NvmCtx->Region, &verify, PHY_DEF_TX_DR ) == true ) + if( RegionVerify( Nvm.MacGroup2.Region, &verify, PHY_DEF_TX_DR ) == true ) { - MacCtx.NvmCtx->MacParamsDefaults.ChannelsDatarate = verify.DatarateParams.Datarate; + Nvm.MacGroup2.ChannelsDatarateDefault = verify.DatarateParams.Datarate; } else { @@ -4250,11 +4158,11 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) case MIB_CHANNELS_DATARATE: { verify.DatarateParams.Datarate = mibSet->Param.ChannelsDatarate; - verify.DatarateParams.UplinkDwellTime = MacCtx.NvmCtx->MacParams.UplinkDwellTime; + verify.DatarateParams.UplinkDwellTime = Nvm.MacGroup2.MacParams.UplinkDwellTime; - if( RegionVerify( MacCtx.NvmCtx->Region, &verify, PHY_TX_DR ) == true ) + if( RegionVerify( Nvm.MacGroup2.Region, &verify, PHY_TX_DR ) == true ) { - MacCtx.NvmCtx->MacParams.ChannelsDatarate = verify.DatarateParams.Datarate; + Nvm.MacGroup1.ChannelsDatarate = verify.DatarateParams.Datarate; } else { @@ -4266,9 +4174,9 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) { verify.TxPower = mibSet->Param.ChannelsDefaultTxPower; - if( RegionVerify( MacCtx.NvmCtx->Region, &verify, PHY_DEF_TX_POWER ) == true ) + if( RegionVerify( Nvm.MacGroup2.Region, &verify, PHY_DEF_TX_POWER ) == true ) { - MacCtx.NvmCtx->MacParamsDefaults.ChannelsTxPower = verify.TxPower; + Nvm.MacGroup2.ChannelsTxPowerDefault = verify.TxPower; } else { @@ -4280,9 +4188,9 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) { verify.TxPower = mibSet->Param.ChannelsTxPower; - if( RegionVerify( MacCtx.NvmCtx->Region, &verify, PHY_TX_POWER ) == true ) + if( RegionVerify( Nvm.MacGroup2.Region, &verify, PHY_TX_POWER ) == true ) { - MacCtx.NvmCtx->MacParams.ChannelsTxPower = verify.TxPower; + Nvm.MacGroup1.ChannelsTxPower = verify.TxPower; } else { @@ -4292,29 +4200,29 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) } case MIB_SYSTEM_MAX_RX_ERROR: { - MacCtx.NvmCtx->MacParams.SystemMaxRxError = MacCtx.NvmCtx->MacParamsDefaults.SystemMaxRxError = mibSet->Param.SystemMaxRxError; + Nvm.MacGroup2.MacParams.SystemMaxRxError = Nvm.MacGroup2.MacParamsDefaults.SystemMaxRxError = mibSet->Param.SystemMaxRxError; break; } case MIB_MIN_RX_SYMBOLS: { - MacCtx.NvmCtx->MacParams.MinRxSymbols = MacCtx.NvmCtx->MacParamsDefaults.MinRxSymbols = mibSet->Param.MinRxSymbols; + Nvm.MacGroup2.MacParams.MinRxSymbols = Nvm.MacGroup2.MacParamsDefaults.MinRxSymbols = mibSet->Param.MinRxSymbols; break; } case MIB_ANTENNA_GAIN: { - MacCtx.NvmCtx->MacParams.AntennaGain = mibSet->Param.AntennaGain; + Nvm.MacGroup2.MacParams.AntennaGain = mibSet->Param.AntennaGain; break; } case MIB_DEFAULT_ANTENNA_GAIN: { - MacCtx.NvmCtx->MacParamsDefaults.AntennaGain = mibSet->Param.DefaultAntennaGain; + Nvm.MacGroup2.MacParamsDefaults.AntennaGain = mibSet->Param.DefaultAntennaGain; break; } case MIB_NVM_CTXS: { if( mibSet->Param.Contexts != 0 ) { - status = RestoreCtxs( mibSet->Param.Contexts ); + status = RestoreNvmData( mibSet->Param.Contexts ); } else { @@ -4326,7 +4234,7 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) { if( mibSet->Param.AbpLrWanVersion.Fields.Minor <= 1 ) { - MacCtx.NvmCtx->Version = mibSet->Param.AbpLrWanVersion; + Nvm.MacGroup2.Version = mibSet->Param.AbpLrWanVersion; if( LORAMAC_CRYPTO_SUCCESS != LoRaMacCryptoSetLrWanVersion( mibSet->Param.AbpLrWanVersion ) ) { @@ -4345,8 +4253,6 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet ) break; } } - EventRegionNvmCtxChanged( ); - EventMacNvmCtxChanged( ); return status; } @@ -4365,9 +4271,7 @@ LoRaMacStatus_t LoRaMacChannelAdd( uint8_t id, ChannelParams_t params ) channelAdd.NewChannel = ¶ms; channelAdd.ChannelId = id; - - EventRegionNvmCtxChanged( ); - return RegionChannelAdd( MacCtx.NvmCtx->Region, &channelAdd ); + return RegionChannelAdd( Nvm.MacGroup2.Region, &channelAdd ); } LoRaMacStatus_t LoRaMacChannelRemove( uint8_t id ) @@ -4384,12 +4288,10 @@ LoRaMacStatus_t LoRaMacChannelRemove( uint8_t id ) channelRemove.ChannelId = id; - if( RegionChannelsRemove( MacCtx.NvmCtx->Region, &channelRemove ) == false ) + if( RegionChannelsRemove( Nvm.MacGroup2.Region, &channelRemove ) == false ) { return LORAMAC_STATUS_PARAMETER_INVALID; } - - EventRegionNvmCtxChanged( ); return LORAMAC_STATUS_OK; } @@ -4405,7 +4307,7 @@ LoRaMacStatus_t LoRaMacMcChannelSetup( McChannelParams_t *channel ) return LORAMAC_STATUS_MC_GROUP_UNDEFINED; } - MacCtx.NvmCtx->MulticastChannelList[channel->GroupID].ChannelParams = *channel; + Nvm.MacGroup2.MulticastChannelList[channel->GroupID].ChannelParams = *channel; if( channel->IsRemotelySetup == true ) { @@ -4437,14 +4339,11 @@ LoRaMacStatus_t LoRaMacMcChannelSetup( McChannelParams_t *channel ) if( channel->Class == CLASS_B ) { // Calculate class b parameters - LoRaMacClassBSetMulticastPeriodicity( &MacCtx.NvmCtx->MulticastChannelList[channel->GroupID] ); + LoRaMacClassBSetMulticastPeriodicity( &Nvm.MacGroup2.MulticastChannelList[channel->GroupID] ); } // Reset multicast channel downlink counter to initial value. - *MacCtx.NvmCtx->MulticastChannelList[channel->GroupID].DownLinkCounter = FCNT_DOWN_INITAL_VALUE; - - EventMacNvmCtxChanged( ); - EventRegionNvmCtxChanged( ); + *Nvm.MacGroup2.MulticastChannelList[channel->GroupID].DownLinkCounter = FCNT_DOWN_INITAL_VALUE; return LORAMAC_STATUS_OK; } @@ -4456,7 +4355,7 @@ LoRaMacStatus_t LoRaMacMcChannelDelete( AddressIdentifier_t groupID ) } if( ( groupID >= LORAMAC_MAX_MC_CTX ) || - ( MacCtx.NvmCtx->MulticastChannelList[groupID].ChannelParams.IsEnabled == false ) ) + ( Nvm.MacGroup2.MulticastChannelList[groupID].ChannelParams.IsEnabled == false ) ) { return LORAMAC_STATUS_MC_GROUP_UNDEFINED; } @@ -4466,10 +4365,7 @@ LoRaMacStatus_t LoRaMacMcChannelDelete( AddressIdentifier_t groupID ) // Set all channel fields with 0 memset1( ( uint8_t* )&channel, 0, sizeof( McChannelParams_t ) ); - MacCtx.NvmCtx->MulticastChannelList[groupID].ChannelParams = channel; - - EventMacNvmCtxChanged( ); - EventRegionNvmCtxChanged( ); + Nvm.MacGroup2.MulticastChannelList[groupID].ChannelParams = channel; return LORAMAC_STATUS_OK; } @@ -4477,7 +4373,7 @@ uint8_t LoRaMacMcChannelGetGroupId( uint32_t mcAddress ) { for( uint8_t i = 0; i < LORAMAC_MAX_MC_CTX; i++ ) { - if( mcAddress == MacCtx.NvmCtx->MulticastChannelList[i].ChannelParams.Address ) + if( mcAddress == Nvm.MacGroup2.MulticastChannelList[i].ChannelParams.Address ) { return i; } @@ -4494,14 +4390,14 @@ LoRaMacStatus_t LoRaMacMcChannelSetupRxParams( AddressIdentifier_t groupID, McRx return LORAMAC_STATUS_BUSY; } - DeviceClass_t devClass = MacCtx.NvmCtx->MulticastChannelList[groupID].ChannelParams.Class; + DeviceClass_t devClass = Nvm.MacGroup2.MulticastChannelList[groupID].ChannelParams.Class; if( ( devClass == CLASS_A ) || ( devClass > CLASS_C ) ) { return LORAMAC_STATUS_PARAMETER_INVALID; } if( ( groupID >= LORAMAC_MAX_MC_CTX ) || - ( MacCtx.NvmCtx->MulticastChannelList[groupID].ChannelParams.IsEnabled == false ) ) + ( Nvm.MacGroup2.MulticastChannelList[groupID].ChannelParams.IsEnabled == false ) ) { return LORAMAC_STATUS_MC_GROUP_UNDEFINED; } @@ -4517,9 +4413,9 @@ LoRaMacStatus_t LoRaMacMcChannelSetupRxParams( AddressIdentifier_t groupID, McRx { verify.DatarateParams.Datarate = rxParams->ClassC.Datarate; } - verify.DatarateParams.DownlinkDwellTime = MacCtx.NvmCtx->MacParams.DownlinkDwellTime; + verify.DatarateParams.DownlinkDwellTime = Nvm.MacGroup2.MacParams.DownlinkDwellTime; - if( RegionVerify( MacCtx.NvmCtx->Region, &verify, PHY_RX_DR ) == true ) + if( RegionVerify( Nvm.MacGroup2.Region, &verify, PHY_RX_DR ) == true ) { *status &= 0xFB; // datarate OK } @@ -4533,7 +4429,7 @@ LoRaMacStatus_t LoRaMacMcChannelSetupRxParams( AddressIdentifier_t groupID, McRx { verify.Frequency = rxParams->ClassC.Frequency; } - if( RegionVerify( MacCtx.NvmCtx->Region, &verify, PHY_FREQUENCY ) == true ) + if( RegionVerify( Nvm.MacGroup2.Region, &verify, PHY_FREQUENCY ) == true ) { *status &= 0xF7; // frequency OK } @@ -4541,11 +4437,8 @@ LoRaMacStatus_t LoRaMacMcChannelSetupRxParams( AddressIdentifier_t groupID, McRx if( *status == ( groupID & 0x03 ) ) { // Apply parameters - MacCtx.NvmCtx->MulticastChannelList[groupID].ChannelParams.RxParams = *rxParams; + Nvm.MacGroup2.MulticastChannelList[groupID].ChannelParams.RxParams = *rxParams; } - - EventMacNvmCtxChanged( ); - EventRegionNvmCtxChanged( ); return LORAMAC_STATUS_OK; } @@ -4590,7 +4483,7 @@ LoRaMacStatus_t LoRaMacMlmeRequest( MlmeReq_t* mlmeRequest ) ResetMacParameters( ); - MacCtx.NvmCtx->MacParams.ChannelsDatarate = RegionAlternateDr( MacCtx.NvmCtx->Region, mlmeRequest->Req.Join.Datarate, ALTERNATE_DR ); + Nvm.MacGroup1.ChannelsDatarate = RegionAlternateDr( Nvm.MacGroup2.Region, mlmeRequest->Req.Join.Datarate, ALTERNATE_DR ); queueElement.Status = LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL; @@ -4599,7 +4492,7 @@ LoRaMacStatus_t LoRaMacMlmeRequest( MlmeReq_t* mlmeRequest ) if( status != LORAMAC_STATUS_OK ) { // Revert back the previous datarate ( mainly used for US915 like regions ) - MacCtx.NvmCtx->MacParams.ChannelsDatarate = RegionAlternateDr( MacCtx.NvmCtx->Region, mlmeRequest->Req.Join.Datarate, ALTERNATE_DR_RESTORE ); + Nvm.MacGroup1.ChannelsDatarate = RegionAlternateDr( Nvm.MacGroup2.Region, mlmeRequest->Req.Join.Datarate, ALTERNATE_DR_RESTORE ); } break; } @@ -4636,7 +4529,7 @@ LoRaMacStatus_t LoRaMacMlmeRequest( MlmeReq_t* mlmeRequest ) } case MLME_PING_SLOT_INFO: { - if( MacCtx.NvmCtx->DeviceClass == CLASS_A ) + if( Nvm.MacGroup2.DeviceClass == CLASS_A ) { uint8_t value = mlmeRequest->Req.PingSlotInfo.PingSlot.Value; @@ -4698,7 +4591,6 @@ LoRaMacStatus_t LoRaMacMlmeRequest( MlmeReq_t* mlmeRequest ) else { LoRaMacConfirmQueueAdd( &queueElement ); - EventMacNvmCtxChanged( ); } return status; } @@ -4775,22 +4667,22 @@ LoRaMacStatus_t LoRaMacMcpsRequest( McpsReq_t* mcpsRequest ) // Get the minimum possible datarate getPhy.Attribute = PHY_MIN_TX_DR; - getPhy.UplinkDwellTime = MacCtx.NvmCtx->MacParams.UplinkDwellTime; - phyParam = RegionGetPhyParam( MacCtx.NvmCtx->Region, &getPhy ); + getPhy.UplinkDwellTime = Nvm.MacGroup2.MacParams.UplinkDwellTime; + phyParam = RegionGetPhyParam( Nvm.MacGroup2.Region, &getPhy ); // Apply the minimum possible datarate. // Some regions have limitations for the minimum datarate. datarate = MAX( datarate, ( int8_t )phyParam.Value ); if( readyToSend == true ) { - if( MacCtx.NvmCtx->AdrCtrlOn == false ) + if( Nvm.MacGroup2.AdrCtrlOn == false ) { verify.DatarateParams.Datarate = datarate; - verify.DatarateParams.UplinkDwellTime = MacCtx.NvmCtx->MacParams.UplinkDwellTime; + verify.DatarateParams.UplinkDwellTime = Nvm.MacGroup2.MacParams.UplinkDwellTime; - if( RegionVerify( MacCtx.NvmCtx->Region, &verify, PHY_TX_DR ) == true ) + if( RegionVerify( Nvm.MacGroup2.Region, &verify, PHY_TX_DR ) == true ) { - MacCtx.NvmCtx->MacParams.ChannelsDatarate = verify.DatarateParams.Datarate; + Nvm.MacGroup1.ChannelsDatarate = verify.DatarateParams.Datarate; } else { @@ -4803,7 +4695,6 @@ LoRaMacStatus_t LoRaMacMcpsRequest( McpsReq_t* mcpsRequest ) { MacCtx.McpsConfirm.McpsRequest = mcpsRequest->Type; MacCtx.MacFlags.Bits.McpsReq = 1; - EventMacNvmCtxChanged( ); } else { @@ -4823,9 +4714,9 @@ void LoRaMacTestSetDutyCycleOn( bool enable ) verify.DutyCycle = enable; - if( RegionVerify( MacCtx.NvmCtx->Region, &verify, PHY_DUTY_CYCLE ) == true ) + if( RegionVerify( Nvm.MacGroup2.Region, &verify, PHY_DUTY_CYCLE ) == true ) { - MacCtx.NvmCtx->DutyCycleOn = enable; + Nvm.MacGroup2.DutyCycleOn = enable; } } diff --git a/src/mac/LoRaMac.h b/src/mac/LoRaMac.h index 3dc6fb2f6..dc6209cf9 100644 --- a/src/mac/LoRaMac.h +++ b/src/mac/LoRaMac.h @@ -73,12 +73,16 @@ extern "C" #include #include -#include "utilities.h" + #include "timer.h" #include "systime.h" -#include "radio.h" #include "LoRaMacTypes.h" +#include "RegionNvm.h" +#include "LoRaMacCryptoNvm.h" +#include "secure-element-nvm.h" +#include "LoRaMacClassBNvm.h" + /*! * Maximum number of times the MAC layer tries to get an acknowledge. */ @@ -102,7 +106,53 @@ extern "C" /*! * Start value for multicast keys enumeration */ -#define LORAMAC_CRYPTO_MULTICAST_KEYS 127 +#define LORAMAC_CRYPTO_MULTICAST_KEYS 127 + +/*! + * Maximum MAC commands buffer size + */ +#define LORA_MAC_COMMAND_MAX_LENGTH 128 + + +/*! + * Bitmap value + */ +#define LORAMAC_NVM_NOTIFY_FLAG_NONE 0x00 + +/*! + * Bitmap value for the NVM group crypto. + */ +#define LORAMAC_NVM_NOTIFY_FLAG_CRYPTO 0x01 + +/*! + * Bitmap value for the NVM group MAC 1. + */ +#define LORAMAC_NVM_NOTIFY_FLAG_MAC_GROUP1 0x02 + +/*! + * Bitmap value for the NVM group MAC 2. + */ +#define LORAMAC_NVM_NOTIFY_FLAG_MAC_GROUP2 0x04 + +/*! + * Bitmap value for the NVM group secure element. + */ +#define LORAMAC_NVM_NOTIFY_FLAG_SECURE_ELEMENT 0x08 + +/*! + * Bitmap value for the NVM group 1 region. + */ +#define LORAMAC_NVM_NOTIFY_FLAG_REGION_GROUP1 0x10 + +/*! + * Bitmap value for the NVM group 2 region. + */ +#define LORAMAC_NVM_NOTIFY_FLAG_REGION_GROUP2 0x20 + +/*! + * Bitmap value for the NVM group class b. + */ +#define LORAMAC_NVM_NOTIFY_FLAG_CLASS_B 0x40 /*! * End-Device activation type @@ -123,62 +173,6 @@ typedef enum eActivationType ACTIVATION_TYPE_OTAA = 2, }ActivationType_t; -/*! - * LoRaMAC channels parameters definition - */ -typedef union uDrRange -{ - /*! - * Byte-access to the bits - */ - int8_t Value; - /*! - * Structure to store the minimum and the maximum datarate - */ - struct sFields - { - /*! - * Minimum data rate - * - * LoRaWAN Regional Parameters V1.0.2rB - * - * The allowed ranges are region specific. Please refer to \ref DR_0 to \ref DR_15 for details. - */ - int8_t Min : 4; - /*! - * Maximum data rate - * - * LoRaWAN Regional Parameters V1.0.2rB - * - * 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; - -/*! - * LoRaMAC channel definition - */ -typedef struct sChannelParams -{ - /*! - * Frequency in Hz - */ - uint32_t Frequency; - /*! - * Alternative frequency for RX window 1 - */ - uint32_t Rx1Frequency; - /*! - * Data rate definition - */ - DrRange_t DrRange; - /*! - * Band index - */ - uint8_t Band; -}ChannelParams_t; - /*! * LoRaMAC receive window channel parameters */ @@ -233,82 +227,11 @@ typedef enum eLoRaMacRxSlot RX_SLOT_NONE, }LoRaMacRxSlot_t; -/*! - * LoRaMAC structure to hold internal context pointers and its lengths - */ -typedef struct sLoRaMacCtxs -{ - /*! - * \brief Pointer to Mac context - */ - void* MacNvmCtx; - /*! - * \brief Size of Mac context - */ - size_t MacNvmCtxSize; - /*! - * \brief Pointer to region context - */ - void* RegionNvmCtx; - /*! - * \brief Size of region context - */ - size_t RegionNvmCtxSize; - /*! - * \brief Pointer to crypto module context - */ - void* CryptoNvmCtx; - /*! - * \brief Size of crypto module context - */ - size_t CryptoNvmCtxSize; - /*! - * \brief Pointer to secure element driver context - */ - void* SecureElementNvmCtx; - /*! - * \brief Size of secure element driver context - */ - size_t SecureElementNvmCtxSize; - /*! - * \brief Pointer to MAC commands module context - */ - void* CommandsNvmCtx; - /*! - * \brief Size of MAC commands module context - */ - size_t CommandsNvmCtxSize; - /*! - * \brief Pointer to Class B module context - */ - void* ClassBNvmCtx; - /*! - * \brief Size of MAC Class B module context - */ - size_t ClassBNvmCtxSize; - /*! - * \brief Pointer to MLME Confirm queue module context - */ - void* ConfirmQueueNvmCtx; - /*! - * \brief Size of MLME Confirm queue module context - */ - size_t ConfirmQueueNvmCtxSize; -}LoRaMacCtxs_t; - /*! * Global MAC layer parameters */ typedef struct sLoRaMacParams { - /*! - * Channels TX power - */ - int8_t ChannelsTxPower; - /*! - * Channels data rate - */ - int8_t ChannelsDatarate; /*! * System overall timing error in milliseconds. * [-SystemMaxRxError : +SystemMaxRxError] @@ -566,6 +489,211 @@ typedef union eLoRaMacFlags_t }Bits; }LoRaMacFlags_t; +/*! + * LoRaMAC region enumeration + */ +typedef enum eLoRaMacRegion +{ + /*! + * AS band on 923MHz + */ + LORAMAC_REGION_AS923, + /*! + * Australian band on 915MHz + */ + LORAMAC_REGION_AU915, + /*! + * Chinese band on 470MHz + */ + LORAMAC_REGION_CN470, + /*! + * Chinese band on 779MHz + */ + LORAMAC_REGION_CN779, + /*! + * European band on 433MHz + */ + LORAMAC_REGION_EU433, + /*! + * European band on 868MHz + */ + LORAMAC_REGION_EU868, + /*! + * South korean band on 920MHz + */ + LORAMAC_REGION_KR920, + /*! + * India band on 865MHz + */ + LORAMAC_REGION_IN865, + /*! + * North american band on 915MHz + */ + LORAMAC_REGION_US915, + /*! + * Russia band on 864MHz + */ + LORAMAC_REGION_RU864, +}LoRaMacRegion_t; + +typedef struct sLoRaMacNvmDataGroup1 +{ + /*! + * Counts the number of missed ADR acknowledgements + */ + uint32_t AdrAckCounter; + /*! + * Last transmission time. + */ + TimerTime_t LastTxDoneTime; + /*! + * Aggregated time off. + */ + TimerTime_t AggregatedTimeOff; + /*! + * Last received Message integrity Code (MIC) + */ + uint32_t LastRxMic; + /*! + * Channels TX power + */ + int8_t ChannelsTxPower; + /*! + * Channels data rate + */ + int8_t ChannelsDatarate; + /*! + * 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; + /*! + * CRC32 value of the MacGroup1 data structure. + */ + uint32_t Crc32; +}LoRaMacNvmDataGroup1_t; + +typedef struct sLoRaMacNvmDataGroup2 +{ + /* + * LoRaMac region. + */ + LoRaMacRegion_t Region; + /* + * LoRaMac parameters + */ + LoRaMacParams_t MacParams; + /* + * LoRaMac default parameters + */ + LoRaMacParams_t MacParamsDefaults; + /*! + * Channels TX power + */ + int8_t ChannelsTxPowerDefault; + /*! + * Channels data rate + */ + int8_t ChannelsDatarateDefault; + /* + * Network ID ( 3 bytes ) + */ + uint32_t NetID; + /* + * Mote Address + */ + uint32_t DevAddr; + /*! + * Multicast channel list + */ + MulticastCtx_t MulticastChannelList[LORAMAC_MAX_MC_CTX]; + /* + * Actual device class + */ + DeviceClass_t DeviceClass; + /* + * Indicates if the node is connected to + * a private or public network + */ + bool PublicNetwork; + /* + * LoRaMac ADR control status + */ + bool AdrCtrlOn; + /* + * Maximum duty cycle + * \remark Possibility to shutdown the device. + */ + uint8_t MaxDCycle; + /* + * Enables/Disables duty cycle management (Test only) + */ + bool DutyCycleOn; + /* + * Aggregated duty cycle management + */ + uint16_t AggregatedDCycle; + /* + * Stores the time at LoRaMac initialization. + * + * \remark Used for the BACKOFF_DC computation. + */ + SysTime_t InitializationTime; + /* + * Current LoRaWAN Version + */ + Version_t Version; + /* + * End-Device network activation + */ + ActivationType_t NetworkActivation; + /*! + * CRC32 value of the MacGroup2 data structure. + */ + uint32_t Crc32; +}LoRaMacNvmDataGroup2_t; + +/*! + * LoRaMAC data structure for non-volatile memory (NVM). + * This structure contains data which must be stored in NVM. + */ +typedef struct sLoRaMacNvmData +{ + /*! + * Parameters related to the crypto layer. Change with every TX/RX + * procedure. + */ + LoRaMacCryptoNvmData_t Crypto; + /*! + * Parameters related to the MAC which change with high probability after + * every TX/RX procedure. + */ + LoRaMacNvmDataGroup1_t MacGroup1; + /*! + * Parameters related to the MAC which do not change very likely with every + * TX/RX procedure. + */ + LoRaMacNvmDataGroup2_t MacGroup2; + /*! + * Parameters related to the secure-element. + */ + SecureElementNvmData_t SecureElement; + /*! + * Parameters related to the regional implementation which change with high + * probability after every TX/RX procedure. + */ + RegionNvmDataGroup1_t RegionGroup1; + /*! + * Parameters related to the regional implementation which do not change + * very likely with every TX/RX procedure. + */ + RegionNvmDataGroup2_t RegionGroup2; + /*! + * Parameters related to class b. + */ + LoRaMacClassBNvmData_t ClassB; +}LoRaMacNvmData_t; + /*! * * \brief LoRaMAC data services @@ -1957,11 +2085,12 @@ typedef union uMibParam */ float DefaultAntennaGain; /*! - * Structure holding pointers to internal non-volatile contexts and its lengths. + * Returns a pointer to the structure holding all data which shall be stored + * in the NVM. * * Related MIB type: \ref MIB_NVM_CTXS */ - LoRaMacCtxs_t* Contexts; + LoRaMacNvmData_t* Contexts; /* * LoRaWAN MAC layer operating version when activated by ABP. * @@ -2207,89 +2336,6 @@ typedef enum eLoRaMacStatus LORAMAC_STATUS_ERROR }LoRaMacStatus_t; -/*! - * LoRaMAC region enumeration - */ -typedef enum eLoRaMacRegion_t -{ - /*! - * AS band on 923MHz - */ - LORAMAC_REGION_AS923, - /*! - * Australian band on 915MHz - */ - LORAMAC_REGION_AU915, - /*! - * Chinese band on 470MHz - */ - LORAMAC_REGION_CN470, - /*! - * Chinese band on 779MHz - */ - LORAMAC_REGION_CN779, - /*! - * European band on 433MHz - */ - LORAMAC_REGION_EU433, - /*! - * European band on 868MHz - */ - LORAMAC_REGION_EU868, - /*! - * South korean band on 920MHz - */ - LORAMAC_REGION_KR920, - /*! - * India band on 865MHz - */ - LORAMAC_REGION_IN865, - /*! - * North american band on 915MHz - */ - LORAMAC_REGION_US915, - /*! - * Russia band on 864MHz - */ - LORAMAC_REGION_RU864, -}LoRaMacRegion_t; - -/*! - * Enumeration of modules which have a context - */ -typedef enum LoRaMacNvmCtxModule_e -{ - /*! - * Context for the MAC - */ - LORAMAC_NVMCTXMODULE_MAC, - /*! - * Context for the regions - */ - LORAMAC_NVMCTXMODULE_REGION, - /*! - * Context for the crypto module - */ - LORAMAC_NVMCTXMODULE_CRYPTO, - /*! - * Context for the secure element - */ - LORAMAC_NVMCTXMODULE_SECURE_ELEMENT, - /*! - * Context for the command queue - */ - LORAMAC_NVMCTXMODULE_COMMANDS, - /*! - * Context for class b - */ - LORAMAC_NVMCTXMODULE_CLASS_B, - /*! - * Context for the confirm queue - */ - LORAMAC_NVMCTXMODULE_CONFIRM_QUEUE, -}LoRaMacNvmCtxModule_t; - - /*! * LoRaMAC events structure * Used to notify upper layers of MAC events @@ -2345,9 +2391,10 @@ typedef struct sLoRaMacCallback /*! * \brief Will be called when an attribute has changed in one of the context. * - * \param Context that changed + * \param notifyFlags Bitmap that contains the modules which changed. + * Refer to \ref LoRaMacNvmData_t. */ - void ( *NvmContextChange )( LoRaMacNvmCtxModule_t module ); + void ( *NvmDataChange )( uint16_t notifyFlags ); /*! *\brief Will be called each time a Radio IRQ is handled by the MAC * layer. @@ -2672,12 +2719,6 @@ LoRaMacStatus_t LoRaMacMcpsRequest( McpsReq_t* mcpsRequest ); */ LoRaMacStatus_t LoRaMacDeInitialization( void ); -/*! - * Automatically add the Region.h file at the end of LoRaMac.h file. - * This is required because Region.h uses definitions from LoRaMac.h - */ -#include "region/Region.h" - /*! \} defgroup LORAMAC */ #ifdef __cplusplus diff --git a/src/mac/LoRaMacClassB.c b/src/mac/LoRaMacClassB.c index e898f3865..7704c525b 100644 --- a/src/mac/LoRaMacClassB.c +++ b/src/mac/LoRaMacClassB.c @@ -22,82 +22,16 @@ Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jae #include "secure-element.h" #include "LoRaMac.h" #include "LoRaMacClassB.h" +#include "LoRaMacClassBNvm.h" #include "LoRaMacClassBConfig.h" #include "LoRaMacCrypto.h" #include "LoRaMacConfirmQueue.h" +#include "radio.h" +#include "region/Region.h" #ifdef LORAMAC_CLASSB_ENABLED -/* - * LoRaMac Class B Context structure for NVM parameters - * related to ping slots - */ -typedef struct sLoRaMacClassBPingSlotNvmCtx -{ - struct sPingSlotCtrlNvm - { - /*! - * Set when the server assigned a ping slot to the node - */ - uint8_t Assigned : 1; - /*! - * Set when a custom frequency is used - */ - uint8_t CustomFreq : 1; - }Ctrl; - /*! - * Number of ping slots - */ - uint8_t PingNb; - /*! - * Period of the ping slots - */ - uint16_t PingPeriod; - /*! - * Reception frequency of the ping slot windows - */ - uint32_t Frequency; - /*! - * Datarate of the ping slot - */ - int8_t Datarate; -} LoRaMacClassBPingSlotNvmCtx_t; - -/* - * LoRaMac Class B Context structure for NVM parameters - * related to beaconing - */ -typedef struct sLoRaMacClassBBeaconNvmCtx -{ - struct sBeaconCtrlNvm - { - /*! - * Set if the node has a custom frequency for beaconing and ping slots - */ - uint8_t CustomFreq : 1; - }Ctrl; - /*! - * Beacon reception frequency - */ - uint32_t Frequency; -} LoRaMacClassBBeaconNvmCtx_t; - -/* - * LoRaMac Class B Context structure - */ -typedef struct sLoRaMacClassBNvmCtx -{ - /*! - * Class B ping slot context - */ - LoRaMacClassBPingSlotNvmCtx_t PingSlotCtx; - /*! - * Class B beacon context - */ - LoRaMacClassBBeaconNvmCtx_t BeaconCtx; -} LoRaMacClassBNvmCtx_t; - /* * LoRaMac Class B Context structure */ @@ -144,14 +78,6 @@ typedef struct sLoRaMacClassBCtx * in class b operation. */ LoRaMacClassBParams_t LoRaMacClassBParams; - /*! - * Callback function to notify the upper layer about context change - */ - LoRaMacClassBNvmEvent LoRaMacClassBNvmEvent; - /*! - * Non-volatile module context. - */ - LoRaMacClassBNvmCtx_t* NvmCtx; } LoRaMacClassBCtx_t; /*! @@ -170,16 +96,17 @@ typedef union uLoRaMacClassBEvents LoRaMacClassBEvents_t LoRaMacClassBEvents = { .Value = 0 }; -/* - * Non-volatile module context. - */ -static LoRaMacClassBNvmCtx_t NvmCtx; - /* * Module context. */ static LoRaMacClassBCtx_t Ctx; +/*! + * Data structure which holds the parameters which needs to be stored + * in the NVM. + */ +static LoRaMacClassBNvmData_t* ClassBNvm; + /*! * Computes the Ping Offset * @@ -362,10 +289,10 @@ static void RxBeaconSetup( TimerTime_t rxTime, bool activateDefaultChannel, uint CLASSB_BEACON_INTERVAL, true ); } - if( Ctx.NvmCtx->BeaconCtx.Ctrl.CustomFreq == 1 ) + if( ClassBNvm->BeaconCtx.Ctrl.CustomFreq == 1 ) { // Set the frequency from the BeaconFreqReq - frequency = Ctx.NvmCtx->BeaconCtx.Frequency; + frequency = ClassBNvm->BeaconCtx.Frequency; } if( Ctx.BeaconCtx.Ctrl.BeaconChannelSet == 1 ) @@ -481,7 +408,7 @@ static void InitClassB( void ) LoRaMacClassBEvents.Value = 0; // Init variables to default - memset1( ( uint8_t* ) &NvmCtx, 0, sizeof( LoRaMacClassBNvmCtx_t ) ); + memset1( ( uint8_t* ) ClassBNvm, 0, sizeof( LoRaMacClassBNvmData_t ) ); memset1( ( uint8_t* ) &Ctx.PingSlotCtx, 0, sizeof( PingSlotContext_t ) ); memset1( ( uint8_t* ) &Ctx.BeaconCtx, 0, sizeof( BeaconContext_t ) ); @@ -492,7 +419,7 @@ static void InitClassB( void ) // Setup default ping slot datarate getPhy.Attribute = PHY_PING_SLOT_CHANNEL_DR; phyParam = RegionGetPhyParam( *Ctx.LoRaMacClassBParams.LoRaMacRegion, &getPhy ); - Ctx.NvmCtx->PingSlotCtx.Datarate = ( int8_t )( phyParam.Value ); + ClassBNvm->PingSlotCtx.Datarate = ( int8_t )( phyParam.Value ); // Setup default states Ctx.BeaconState = BEACON_STATE_ACQUISITION; @@ -504,19 +431,19 @@ static void InitClassBDefaults( void ) { // This function shall reset the Class B settings to default, // but should keep important configurations - LoRaMacClassBBeaconNvmCtx_t beaconCtx = Ctx.NvmCtx->BeaconCtx; - LoRaMacClassBPingSlotNvmCtx_t pingSlotCtx = Ctx.NvmCtx->PingSlotCtx; + LoRaMacClassBBeaconNvmData_t beaconCtx = ClassBNvm->BeaconCtx; + LoRaMacClassBPingSlotNvmData_t pingSlotCtx = ClassBNvm->PingSlotCtx; InitClassB( ); // Parameters from BeaconFreqReq - Ctx.NvmCtx->BeaconCtx.Frequency = beaconCtx.Frequency; - Ctx.NvmCtx->BeaconCtx.Ctrl.CustomFreq = beaconCtx.Ctrl.CustomFreq; + ClassBNvm->BeaconCtx.Frequency = beaconCtx.Frequency; + ClassBNvm->BeaconCtx.Ctrl.CustomFreq = beaconCtx.Ctrl.CustomFreq; // Parameters from PingSlotChannelReq - Ctx.NvmCtx->PingSlotCtx.Ctrl.CustomFreq = pingSlotCtx.Ctrl.CustomFreq; - Ctx.NvmCtx->PingSlotCtx.Frequency = pingSlotCtx.Frequency; - Ctx.NvmCtx->PingSlotCtx.Datarate = pingSlotCtx.Datarate; + ClassBNvm->PingSlotCtx.Ctrl.CustomFreq = pingSlotCtx.Ctrl.CustomFreq; + ClassBNvm->PingSlotCtx.Frequency = pingSlotCtx.Frequency; + ClassBNvm->PingSlotCtx.Datarate = pingSlotCtx.Datarate; } static void EnlargeWindowTimeout( void ) @@ -619,35 +546,25 @@ static uint16_t CalcPingPeriod( uint8_t pingNb ) { return CLASSB_BEACON_WINDOW_SLOTS / pingNb; } +#endif // LORAMAC_CLASSB_ENABLED -/* - * Dummy callback in case if the user provides NULL function pointer - */ -static void NvmContextChange( void ) +void LoRaMacClassBInit( LoRaMacClassBParams_t *classBParams, LoRaMacClassBCallback_t *callbacks, + LoRaMacClassBNvmData_t* nvm ) { - if( Ctx.LoRaMacClassBNvmEvent != NULL ) +#ifdef LORAMAC_CLASSB_ENABLED + // Assign non-volatile context + if( nvm == NULL ) { - Ctx.LoRaMacClassBNvmEvent( ); + return; } -} + ClassBNvm = nvm; -#endif // LORAMAC_CLASSB_ENABLED - -void LoRaMacClassBInit( LoRaMacClassBParams_t *classBParams, LoRaMacClassBCallback_t *callbacks, LoRaMacClassBNvmEvent classBNvmCtxChanged ) -{ -#ifdef LORAMAC_CLASSB_ENABLED // Store callbacks Ctx.LoRaMacClassBCallbacks = *callbacks; // Store parameter pointers Ctx.LoRaMacClassBParams = *classBParams; - // Assign non-volatile context - Ctx.NvmCtx = &NvmCtx; - - // Assign callback - Ctx.LoRaMacClassBNvmEvent = classBNvmCtxChanged; - // Initialize timers TimerInit( &Ctx.BeaconTimer, LoRaMacClassBBeaconTimerEvent ); TimerInit( &Ctx.PingSlotTimer, LoRaMacClassBPingSlotTimerEvent ); @@ -657,35 +574,6 @@ void LoRaMacClassBInit( LoRaMacClassBParams_t *classBParams, LoRaMacClassBCallba #endif // LORAMAC_CLASSB_ENABLED } -bool LoRaMacClassBRestoreNvmCtx( void* classBNvmCtx ) -{ -#ifdef LORAMAC_CLASSB_ENABLED - // Restore module context - if( classBNvmCtx != NULL ) - { - memcpy1( ( uint8_t* ) &NvmCtx, ( uint8_t* ) classBNvmCtx, sizeof( NvmCtx ) ); - return true; - } - else - { - return false; - } -#else - return true; -#endif // LORAMAC_CLASSB_ENABLED -} - -void* LoRaMacClassBGetNvmCtx( size_t* classBNvmCtxSize ) -{ -#ifdef LORAMAC_CLASSB_ENABLED - *classBNvmCtxSize = sizeof( NvmCtx ); - return &NvmCtx; -#else - *classBNvmCtxSize = 0; - return NULL; -#endif // LORAMAC_CLASSB_ENABLED -} - void LoRaMacClassBSetBeaconState( BeaconState_t beaconState ) { #ifdef LORAMAC_CLASSB_ENABLED @@ -1037,21 +925,21 @@ static void LoRaMacClassBProcessPingSlot( void ) { ComputePingOffset( Ctx.BeaconCtx.BeaconTime.Seconds, *Ctx.LoRaMacClassBParams.LoRaMacDevAddr, - Ctx.NvmCtx->PingSlotCtx.PingPeriod, + ClassBNvm->PingSlotCtx.PingPeriod, &( Ctx.PingSlotCtx.PingOffset ) ); Ctx.PingSlotState = PINGSLOT_STATE_SET_TIMER; } // Intentional fall through case PINGSLOT_STATE_SET_TIMER: { - if( CalcNextSlotTime( Ctx.PingSlotCtx.PingOffset, Ctx.NvmCtx->PingSlotCtx.PingPeriod, Ctx.NvmCtx->PingSlotCtx.PingNb, &pingSlotTime ) == true ) + if( CalcNextSlotTime( Ctx.PingSlotCtx.PingOffset, ClassBNvm->PingSlotCtx.PingPeriod, ClassBNvm->PingSlotCtx.PingNb, &pingSlotTime ) == true ) { if( Ctx.BeaconCtx.Ctrl.BeaconAcquired == 1 ) { // Compute the symbol timeout. Apply it only, if the beacon is acquired // Otherwise, take the enlargement of the symbols into account. RegionComputeRxWindowParameters( *Ctx.LoRaMacClassBParams.LoRaMacRegion, - Ctx.NvmCtx->PingSlotCtx.Datarate, + ClassBNvm->PingSlotCtx.Datarate, Ctx.LoRaMacClassBParams.LoRaMacParams->MinRxSymbols, Ctx.LoRaMacClassBParams.LoRaMacParams->SystemMaxRxError, &pingSlotRxConfig ); @@ -1072,10 +960,10 @@ static void LoRaMacClassBProcessPingSlot( void ) } case PINGSLOT_STATE_IDLE: { - uint32_t frequency = Ctx.NvmCtx->PingSlotCtx.Frequency; + uint32_t frequency = ClassBNvm->PingSlotCtx.Frequency; // Apply a custom frequency if the following bit is set - if( Ctx.NvmCtx->PingSlotCtx.Ctrl.CustomFreq == 0 ) + if( ClassBNvm->PingSlotCtx.Ctrl.CustomFreq == 0 ) { // Restore floor plan frequency = CalcDownlinkChannelAndFrequency( *Ctx.LoRaMacClassBParams.LoRaMacDevAddr, Ctx.BeaconCtx.BeaconTime.Seconds, @@ -1088,7 +976,7 @@ static void LoRaMacClassBProcessPingSlot( void ) { Ctx.PingSlotState = PINGSLOT_STATE_RX; - pingSlotRxConfig.Datarate = Ctx.NvmCtx->PingSlotCtx.Datarate; + pingSlotRxConfig.Datarate = ClassBNvm->PingSlotCtx.Datarate; pingSlotRxConfig.DownlinkDwellTime = Ctx.LoRaMacClassBParams.LoRaMacParams->DownlinkDwellTime; pingSlotRxConfig.Frequency = frequency; pingSlotRxConfig.RxContinuous = false; @@ -1197,7 +1085,7 @@ static void LoRaMacClassBProcessMulticastSlot( void ) if( Ctx.BeaconCtx.Ctrl.BeaconAcquired == 1 ) { RegionComputeRxWindowParameters( *Ctx.LoRaMacClassBParams.LoRaMacRegion, - Ctx.NvmCtx->PingSlotCtx.Datarate, + ClassBNvm->PingSlotCtx.Datarate, Ctx.LoRaMacClassBParams.LoRaMacParams->MinRxSymbols, Ctx.LoRaMacClassBParams.LoRaMacParams->SystemMaxRxError, &multicastSlotRxConfig ); @@ -1464,9 +1352,8 @@ bool LoRaMacClassBIsBeaconModeActive( void ) void LoRaMacClassBSetPingSlotInfo( uint8_t periodicity ) { #ifdef LORAMAC_CLASSB_ENABLED - Ctx.NvmCtx->PingSlotCtx.PingNb = CalcPingNb( periodicity ); - Ctx.NvmCtx->PingSlotCtx.PingPeriod = CalcPingPeriod( Ctx.NvmCtx->PingSlotCtx.PingNb ); - NvmContextChange( ); + ClassBNvm->PingSlotCtx.PingNb = CalcPingNb( periodicity ); + ClassBNvm->PingSlotCtx.PingPeriod = CalcPingPeriod( ClassBNvm->PingSlotCtx.PingNb ); #endif // LORAMAC_CLASSB_ENABLED } @@ -1524,7 +1411,7 @@ LoRaMacStatus_t LoRaMacClassBSwitchClass( DeviceClass_t nextClass ) #ifdef LORAMAC_CLASSB_ENABLED if( nextClass == CLASS_B ) {// Switch to from class a to class b - if( ( Ctx.BeaconCtx.Ctrl.BeaconMode == 1 ) && ( Ctx.NvmCtx->PingSlotCtx.Ctrl.Assigned == 1 ) ) + if( ( Ctx.BeaconCtx.Ctrl.BeaconMode == 1 ) && ( ClassBNvm->PingSlotCtx.Ctrl.Assigned == 1 ) ) { return LORAMAC_STATUS_OK; } @@ -1553,7 +1440,7 @@ LoRaMacStatus_t LoRaMacClassBMibGetRequestConfirm( MibRequestConfirm_t *mibGet ) { case MIB_PING_SLOT_DATARATE: { - mibGet->Param.PingSlotDatarate = Ctx.NvmCtx->PingSlotCtx.Datarate; + mibGet->Param.PingSlotDatarate = ClassBNvm->PingSlotCtx.Datarate; break; } default: @@ -1577,8 +1464,7 @@ LoRaMacStatus_t LoRaMacMibClassBSetRequestConfirm( MibRequestConfirm_t *mibSet ) { case MIB_PING_SLOT_DATARATE: { - Ctx.NvmCtx->PingSlotCtx.Datarate = mibSet->Param.PingSlotDatarate; - NvmContextChange( ); + ClassBNvm->PingSlotCtx.Datarate = mibSet->Param.PingSlotDatarate; break; } default: @@ -1599,8 +1485,7 @@ void LoRaMacClassBPingSlotInfoAns( void ) if( LoRaMacConfirmQueueIsCmdActive( MLME_PING_SLOT_INFO ) == true ) { LoRaMacConfirmQueueSetStatus( LORAMAC_EVENT_INFO_STATUS_OK, MLME_PING_SLOT_INFO ); - Ctx.NvmCtx->PingSlotCtx.Ctrl.Assigned = 1; - NvmContextChange( ); + ClassBNvm->PingSlotCtx.Ctrl.Assigned = 1; } #endif // LORAMAC_CLASSB_ENABLED } @@ -1634,16 +1519,15 @@ uint8_t LoRaMacClassBPingSlotChannelReq( uint8_t datarate, uint32_t frequency ) { if( isCustomFreq == true ) { - Ctx.NvmCtx->PingSlotCtx.Ctrl.CustomFreq = 1; - Ctx.NvmCtx->PingSlotCtx.Frequency = frequency; + ClassBNvm->PingSlotCtx.Ctrl.CustomFreq = 1; + ClassBNvm->PingSlotCtx.Frequency = frequency; } else { - Ctx.NvmCtx->PingSlotCtx.Ctrl.CustomFreq = 0; - Ctx.NvmCtx->PingSlotCtx.Frequency = 0; + ClassBNvm->PingSlotCtx.Ctrl.CustomFreq = 0; + ClassBNvm->PingSlotCtx.Frequency = 0; } - Ctx.NvmCtx->PingSlotCtx.Datarate = datarate; - NvmContextChange( ); + ClassBNvm->PingSlotCtx.Datarate = datarate; } return status; @@ -1728,16 +1612,14 @@ bool LoRaMacClassBBeaconFreqReq( uint32_t frequency ) if( RegionVerify( *Ctx.LoRaMacClassBParams.LoRaMacRegion, &verify, PHY_FREQUENCY ) == true ) { - Ctx.NvmCtx->BeaconCtx.Ctrl.CustomFreq = 1; - Ctx.NvmCtx->BeaconCtx.Frequency = frequency; - NvmContextChange( ); + ClassBNvm->BeaconCtx.Ctrl.CustomFreq = 1; + ClassBNvm->BeaconCtx.Frequency = frequency; return true; } } else { - Ctx.NvmCtx->BeaconCtx.Ctrl.CustomFreq = 0; - NvmContextChange( ); + ClassBNvm->BeaconCtx.Ctrl.CustomFreq = 0; return true; } return false; @@ -1786,7 +1668,7 @@ void LoRaMacClassBStopRxSlots( void ) void LoRaMacClassBStartRxSlots( void ) { #ifdef LORAMAC_CLASSB_ENABLED - if( Ctx.NvmCtx->PingSlotCtx.Ctrl.Assigned == 1 ) + if( ClassBNvm->PingSlotCtx.Ctrl.Assigned == 1 ) { Ctx.PingSlotState = PINGSLOT_STATE_CALC_PING_OFFSET; TimerSetValue( &Ctx.PingSlotTimer, 1 ); diff --git a/src/mac/LoRaMacClassB.h b/src/mac/LoRaMacClassB.h index eca739170..aabdf605f 100644 --- a/src/mac/LoRaMacClassB.h +++ b/src/mac/LoRaMacClassB.h @@ -292,27 +292,10 @@ typedef void ( *LoRaMacClassBNvmEvent )( void ); * * \param [IN] classBParams Information and feedback parameter * \param [IN] callbacks Contains the callback which the Class B implementation needs - * \param [IN] callback function which will be called when the non-volatile context needs to be saved. + * \param [IN] nvm Pointer to an external non-volatile memory data structure. */ -void LoRaMacClassBInit( LoRaMacClassBParams_t *classBParams, LoRaMacClassBCallback_t *callbacks, LoRaMacClassBNvmEvent classBNvmCtxChanged ); - -/*! - * Restores the internal non-volatile context from passed pointer. - * - * \param [IN] classBNvmCtx - Pointer to non-volatile class B module context to be restored. - * - * \retval - Status of the operation - */ -bool LoRaMacClassBRestoreNvmCtx( void* classBNvmCtx ); - -/*! - * Returns a pointer to the internal non-volatile context. - * - * \param [IN] classBNvmCtxSize - Size of the module non-volatile context - * - * \retval - Points to a structure where the module store its non-volatile context - */ -void* LoRaMacClassBGetNvmCtx( size_t* classBNvmCtxSize ); +void LoRaMacClassBInit( LoRaMacClassBParams_t *classBParams, LoRaMacClassBCallback_t *callbacks, + LoRaMacClassBNvmData_t* nvm ); /*! * \brief Set the state of the beacon state machine diff --git a/src/mac/LoRaMacClassBNvm.h b/src/mac/LoRaMacClassBNvm.h new file mode 100644 index 000000000..dcfc141e2 --- /dev/null +++ b/src/mac/LoRaMacClassBNvm.h @@ -0,0 +1,120 @@ +/*! + * \file LoRaMacClassBNvm.h + * + * \brief LoRa MAC Class B non-volatile data. + * + * \copyright Revised BSD License, see section \ref LICENSE. + * + * \code + * ______ _ + * / _____) _ | | + * ( (____ _____ ____ _| |_ _____ ____| |__ + * \____ \| ___ | (_ _) ___ |/ ___) _ \ + * _____) ) ____| | | || |_| ____( (___| | | | + * (______/|_____)_|_|_| \__)_____)\____)_| |_| + * (C)2013 Semtech + * + * ___ _____ _ ___ _ _____ ___ ___ ___ ___ + * / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| + * \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| + * |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| + * embedded.connectivity.solutions=============== + * + * \endcode + * + * \author Miguel Luis ( Semtech ) + * + * \author Daniel Jaeckle ( STACKFORCE ) + * + * \addtogroup LORAMACCLASSB + * + * \{ + */ +#ifndef __LORAMACCLASSBNVM_H__ +#define __LORAMACCLASSBNVM_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +/*! + * LoRaMac Class B Context structure for NVM parameters + * related to ping slots + */ +typedef struct sLoRaMacClassBPingSlotNvmData +{ + struct sPingSlotCtrlNvm + { + /*! + * Set when the server assigned a ping slot to the node + */ + uint8_t Assigned : 1; + /*! + * Set when a custom frequency is used + */ + uint8_t CustomFreq : 1; + }Ctrl; + /*! + * Number of ping slots + */ + uint8_t PingNb; + /*! + * Period of the ping slots + */ + uint16_t PingPeriod; + /*! + * Reception frequency of the ping slot windows + */ + uint32_t Frequency; + /*! + * Datarate of the ping slot + */ + int8_t Datarate; +} LoRaMacClassBPingSlotNvmData_t; + +/*! + * LoRaMac Class B Context structure for NVM parameters + * related to beaconing + */ +typedef struct sLoRaMacClassBBeaconNvmData +{ + struct sBeaconCtrlNvm + { + /*! + * Set if the node has a custom frequency for beaconing and ping slots + */ + uint8_t CustomFreq : 1; + }Ctrl; + /*! + * Beacon reception frequency + */ + uint32_t Frequency; +} LoRaMacClassBBeaconNvmData_t; + +/*! + * LoRaMac Class B Context structure + */ +typedef struct sLoRaMacClassBNvmData +{ + /*! + * Class B ping slot context + */ + LoRaMacClassBPingSlotNvmData_t PingSlotCtx; + /*! + * Class B beacon context + */ + LoRaMacClassBBeaconNvmData_t BeaconCtx; + /*! + * CRC32 value of the ClassB data structure. + */ + uint32_t Crc32; +} LoRaMacClassBNvmData_t; + +#ifdef __cplusplus +} +#endif + +#endif // __LORAMACCLASSBNVM_H__ diff --git a/src/mac/LoRaMacCommands.c b/src/mac/LoRaMacCommands.c index e0ee7beab..45544de4f 100644 --- a/src/mac/LoRaMacCommands.c +++ b/src/mac/LoRaMacCommands.c @@ -67,15 +67,10 @@ typedef struct sLoRaMacCommandsCtx size_t SerializedCmdsSize; } LoRaMacCommandsCtx_t; -/*! - * Callback function to notify the upper layer about context change - */ -static LoRaMacCommandsNvmEvent CommandsNvmCtxChanged; - /*! * Non-volatile module context. */ -static LoRaMacCommandsCtx_t NvmCtx; +static LoRaMacCommandsCtx_t CommandsCtx; /* Memory management functions */ @@ -108,7 +103,7 @@ static MacCommand_t* MallocNewMacCommandSlot( void ) { uint8_t itr = 0; - while( IsSlotFree( ( const MacCommand_t* )&NvmCtx.MacCommandSlots[itr] ) == false ) + while( IsSlotFree( ( const MacCommand_t* )&CommandsCtx.MacCommandSlots[itr] ) == false ) { itr++; if( itr == NUM_OF_MAC_COMMANDS ) @@ -117,7 +112,7 @@ static MacCommand_t* MallocNewMacCommandSlot( void ) } } - return &NvmCtx.MacCommandSlots[itr]; + return &CommandsCtx.MacCommandSlots[itr]; } /*! @@ -288,50 +283,16 @@ static bool IsSticky( uint8_t cid ) } } -/* - * \brief Wrapper function for the NvmCtx - */ -static void NvmCtxCallback( void ) -{ - if( CommandsNvmCtxChanged != NULL ) - { - CommandsNvmCtxChanged( ); - } -} - -LoRaMacCommandStatus_t LoRaMacCommandsInit( LoRaMacCommandsNvmEvent commandsNvmCtxChanged ) +LoRaMacCommandStatus_t LoRaMacCommandsInit( void ) { // Initialize with default - memset1( ( uint8_t* )&NvmCtx, 0, sizeof( NvmCtx ) ); + memset1( ( uint8_t* )&CommandsCtx, 0, sizeof( CommandsCtx ) ); - LinkedListInit( &NvmCtx.MacCommandList ); - - // Assign callback - CommandsNvmCtxChanged = commandsNvmCtxChanged; + LinkedListInit( &CommandsCtx.MacCommandList ); return LORAMAC_COMMANDS_SUCCESS; } -LoRaMacCommandStatus_t LoRaMacCommandsRestoreNvmCtx( void* commandsNvmCtx ) -{ - // Restore module context - if( commandsNvmCtx != NULL ) - { - memcpy1( ( uint8_t* )&NvmCtx, ( uint8_t* )commandsNvmCtx, sizeof( NvmCtx ) ); - return LORAMAC_COMMANDS_SUCCESS; - } - else - { - return LORAMAC_COMMANDS_ERROR_NPE; - } -} - -void* LoRaMacCommandsGetNvmCtx( size_t* commandsNvmCtxSize ) -{ - *commandsNvmCtxSize = sizeof( NvmCtx ); - return &NvmCtx; -} - LoRaMacCommandStatus_t LoRaMacCommandsAddCmd( uint8_t cid, uint8_t* payload, size_t payloadSize ) { if( payload == NULL ) @@ -349,7 +310,7 @@ LoRaMacCommandStatus_t LoRaMacCommandsAddCmd( uint8_t cid, uint8_t* payload, siz } // Add it to the list of Mac commands - if( LinkedListAdd( &NvmCtx.MacCommandList, newCmd ) == false ) + if( LinkedListAdd( &CommandsCtx.MacCommandList, newCmd ) == false ) { return LORAMAC_COMMANDS_ERROR; } @@ -360,9 +321,7 @@ LoRaMacCommandStatus_t LoRaMacCommandsAddCmd( uint8_t cid, uint8_t* payload, siz memcpy1( ( uint8_t* )newCmd->Payload, payload, payloadSize ); newCmd->IsSticky = IsSticky( cid ); - NvmCtx.SerializedCmdsSize += ( CID_FIELD_SIZE + payloadSize ); - - NvmCtxCallback( ); + CommandsCtx.SerializedCmdsSize += ( CID_FIELD_SIZE + payloadSize ); return LORAMAC_COMMANDS_SUCCESS; } @@ -375,12 +334,12 @@ LoRaMacCommandStatus_t LoRaMacCommandsRemoveCmd( MacCommand_t* macCmd ) } // Remove the Mac command element from MacCommandList - if( LinkedListRemove( &NvmCtx.MacCommandList, macCmd ) == false ) + if( LinkedListRemove( &CommandsCtx.MacCommandList, macCmd ) == false ) { return LORAMAC_COMMANDS_ERROR_CMD_NOT_FOUND; } - NvmCtx.SerializedCmdsSize -= ( CID_FIELD_SIZE + macCmd->PayloadSize ); + CommandsCtx.SerializedCmdsSize -= ( CID_FIELD_SIZE + macCmd->PayloadSize ); // Free the MacCommand Slot if( FreeMacCommandSlot( macCmd ) == false ) @@ -388,8 +347,6 @@ LoRaMacCommandStatus_t LoRaMacCommandsRemoveCmd( MacCommand_t* macCmd ) return LORAMAC_COMMANDS_ERROR; } - NvmCtxCallback( ); - return LORAMAC_COMMANDS_SUCCESS; } @@ -398,7 +355,7 @@ LoRaMacCommandStatus_t LoRaMacCommandsGetCmd( uint8_t cid, MacCommand_t** macCmd MacCommand_t* curElement; // Start at the head of the list - curElement = NvmCtx.MacCommandList.First; + curElement = CommandsCtx.MacCommandList.First; // Loop through all elements until we find the element with the given CID while( ( curElement != NULL ) && ( curElement->CID != cid ) ) @@ -423,7 +380,7 @@ LoRaMacCommandStatus_t LoRaMacCommandsRemoveNoneStickyCmds( void ) MacCommand_t* nexElement; // Start at the head of the list - curElement = NvmCtx.MacCommandList.First; + curElement = CommandsCtx.MacCommandList.First; // Loop through all elements while( curElement != NULL ) @@ -449,7 +406,7 @@ LoRaMacCommandStatus_t LoRaMacCommandsRemoveStickyAnsCmds( void ) MacCommand_t* nexElement; // Start at the head of the list - curElement = NvmCtx.MacCommandList.First; + curElement = CommandsCtx.MacCommandList.First; // Loop through all elements while( curElement != NULL ) @@ -471,13 +428,13 @@ LoRaMacCommandStatus_t LoRaMacCommandsGetSizeSerializedCmds( size_t* size ) { return LORAMAC_COMMANDS_ERROR_NPE; } - *size = NvmCtx.SerializedCmdsSize; + *size = CommandsCtx.SerializedCmdsSize; return LORAMAC_COMMANDS_SUCCESS; } LoRaMacCommandStatus_t LoRaMacCommandsSerializeCmds( size_t availableSize, size_t* effectiveSize, uint8_t* buffer ) { - MacCommand_t* curElement = NvmCtx.MacCommandList.First; + MacCommand_t* curElement = CommandsCtx.MacCommandList.First; MacCommand_t* nextElement; uint8_t itr = 0; @@ -525,7 +482,7 @@ LoRaMacCommandStatus_t LoRaMacCommandsStickyCmdsPending( bool* cmdsPending ) return LORAMAC_COMMANDS_ERROR_NPE; } MacCommand_t* curElement; - curElement = NvmCtx.MacCommandList.First; + curElement = CommandsCtx.MacCommandList.First; *cmdsPending = false; diff --git a/src/mac/LoRaMacCommands.h b/src/mac/LoRaMacCommands.h index 2452efe7d..c6f76aaf0 100644 --- a/src/mac/LoRaMacCommands.h +++ b/src/mac/LoRaMacCommands.h @@ -119,30 +119,9 @@ typedef void ( *LoRaMacCommandsNvmEvent )( void ); /*! * \brief Initialization of LoRaMac MAC commands module * - * \param[IN] commandsNvmCtxChanged - Callback function which will be called when the - * non-volatile context needs to be saved. - * * \retval - Status of the operation */ -LoRaMacCommandStatus_t LoRaMacCommandsInit( LoRaMacCommandsNvmEvent commandsNvmCtxChanged ); - -/*! - * Restores the internal non-volatile context from passed pointer. - * - * \param[IN] commandsNvmCtx - Pointer to non-volatile MAC commands module context to be restored. - * - * \retval - Status of the operation - */ -LoRaMacCommandStatus_t LoRaMacCommandsRestoreNvmCtx( void* commandsNvmCtx ); - -/*! - * Returns a pointer to the internal non-volatile context. - * - * \param[IN] commandsNvmCtxSize - Size of the module non-volatile context - * - * \retval - Points to a structure where the module store its non-volatile context - */ -void* LoRaMacCommandsGetNvmCtx( size_t* commandsNvmCtxSize ); +LoRaMacCommandStatus_t LoRaMacCommandsInit( void ); /*! * \brief Adds a new MAC command to be sent. diff --git a/src/mac/LoRaMacConfirmQueue.c b/src/mac/LoRaMacConfirmQueue.c index ba809c8c5..d493bb6a7 100644 --- a/src/mac/LoRaMacConfirmQueue.c +++ b/src/mac/LoRaMacConfirmQueue.c @@ -30,7 +30,7 @@ Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jae /* * LoRaMac Confirm Queue Context NVM structure */ -typedef struct sLoRaMacConfirmQueueNvmCtx +typedef struct sLoRaMacConfirmQueueNvmData { /*! * MlmeConfirm queue data structure @@ -44,7 +44,7 @@ typedef struct sLoRaMacConfirmQueueNvmCtx * Variable which holds a common status */ LoRaMacEventInfoStatus_t CommonStatus; -} LoRaMacConfirmQueueNvmCtx_t; +} LoRaMacConfirmQueueNvmData_t; /* * LoRaMac Confirm Queue Context structure @@ -63,21 +63,12 @@ typedef struct sLoRaMacConfirmQueueCtx * Pointer to the last element of the ring buffer */ MlmeConfirmQueue_t* BufferEnd; - /* - * Callback function to notify the upper layer about context change - */ - LoRaMacConfirmQueueNvmEvent LoRaMacConfirmQueueNvmEvent; /*! * Non-volatile module context. */ - LoRaMacConfirmQueueNvmCtx_t* ConfirmQueueNvmCtx; + LoRaMacConfirmQueueNvmData_t Nvm; } LoRaMacConfirmQueueCtx_t; -/* - * Non-volatile module context. - */ -static LoRaMacConfirmQueueNvmCtx_t ConfirmQueueNvmCtx; - /* * Module context. */ @@ -85,10 +76,10 @@ static LoRaMacConfirmQueueCtx_t ConfirmQueueCtx; static MlmeConfirmQueue_t* IncreaseBufferPointer( MlmeConfirmQueue_t* bufferPointer ) { - if( bufferPointer == &ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueue[LORA_MAC_MLME_CONFIRM_QUEUE_LEN - 1] ) + if( bufferPointer == &ConfirmQueueCtx.Nvm.MlmeConfirmQueue[LORA_MAC_MLME_CONFIRM_QUEUE_LEN - 1] ) { // Reset to the first element - bufferPointer = ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueue; + bufferPointer = ConfirmQueueCtx.Nvm.MlmeConfirmQueue; } else { @@ -100,10 +91,10 @@ static MlmeConfirmQueue_t* IncreaseBufferPointer( MlmeConfirmQueue_t* bufferPoin static MlmeConfirmQueue_t* DecreaseBufferPointer( MlmeConfirmQueue_t* bufferPointer ) { - if( bufferPointer == ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueue ) + if( bufferPointer == ConfirmQueueCtx.Nvm.MlmeConfirmQueue ) { // Reset to the last element - bufferPointer = &ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueue[LORA_MAC_MLME_CONFIRM_QUEUE_LEN - 1]; + bufferPointer = &ConfirmQueueCtx.Nvm.MlmeConfirmQueue[LORA_MAC_MLME_CONFIRM_QUEUE_LEN - 1]; } else { @@ -134,12 +125,12 @@ static MlmeConfirmQueue_t* GetElement( Mlme_t request, MlmeConfirmQueue_t* buffe { MlmeConfirmQueue_t* element = bufferStart; - if( IsListEmpty( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt ) == true ) + if( IsListEmpty( ConfirmQueueCtx.Nvm.MlmeConfirmQueueCnt ) == true ) { return NULL; } - for( uint8_t elementCnt = 0; elementCnt < ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt; elementCnt++ ) + for( uint8_t elementCnt = 0; elementCnt < ConfirmQueueCtx.Nvm.MlmeConfirmQueueCnt; elementCnt++ ) { if( element->Request == request ) { @@ -152,52 +143,26 @@ static MlmeConfirmQueue_t* GetElement( Mlme_t request, MlmeConfirmQueue_t* buffe return NULL; } -void LoRaMacConfirmQueueInit( LoRaMacPrimitives_t* primitives, LoRaMacConfirmQueueNvmEvent confirmQueueNvmCtxChanged ) +void LoRaMacConfirmQueueInit( LoRaMacPrimitives_t* primitives ) { ConfirmQueueCtx.Primitives = primitives; - // Assign nvm context - ConfirmQueueCtx.ConfirmQueueNvmCtx = &ConfirmQueueNvmCtx; - // Init counter - ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt = 0; + ConfirmQueueCtx.Nvm.MlmeConfirmQueueCnt = 0; // Init buffer - ConfirmQueueCtx.BufferStart = ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueue; - ConfirmQueueCtx.BufferEnd = ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueue; + ConfirmQueueCtx.BufferStart = ConfirmQueueCtx.Nvm.MlmeConfirmQueue; + ConfirmQueueCtx.BufferEnd = ConfirmQueueCtx.Nvm.MlmeConfirmQueue; - memset1( ( uint8_t* )ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueue, 0xFF, sizeof( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueue ) ); + memset1( ( uint8_t* )ConfirmQueueCtx.Nvm.MlmeConfirmQueue, 0xFF, sizeof( ConfirmQueueCtx.Nvm.MlmeConfirmQueue ) ); // Common status - ConfirmQueueCtx.ConfirmQueueNvmCtx->CommonStatus = LORAMAC_EVENT_INFO_STATUS_ERROR; - - // Assign callback - ConfirmQueueCtx.LoRaMacConfirmQueueNvmEvent = confirmQueueNvmCtxChanged; -} - -bool LoRaMacConfirmQueueRestoreNvmCtx( void* confirmQueueNvmCtx ) -{ - // Restore module context - if( confirmQueueNvmCtx != NULL ) - { - memcpy1( ( uint8_t* )&ConfirmQueueNvmCtx, ( uint8_t* ) confirmQueueNvmCtx, sizeof( ConfirmQueueNvmCtx ) ); - return true; - } - else - { - return false; - } -} - -void* LoRaMacConfirmQueueGetNvmCtx( size_t* confirmQueueNvmCtxSize ) -{ - *confirmQueueNvmCtxSize = sizeof( ConfirmQueueNvmCtx ); - return &ConfirmQueueNvmCtx; + ConfirmQueueCtx.Nvm.CommonStatus = LORAMAC_EVENT_INFO_STATUS_ERROR; } bool LoRaMacConfirmQueueAdd( MlmeConfirmQueue_t* mlmeConfirm ) { - if( IsListFull( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt ) == true ) + if( IsListFull( ConfirmQueueCtx.Nvm.MlmeConfirmQueueCnt ) == true ) { // Protect the buffer against overwrites return false; @@ -209,7 +174,7 @@ bool LoRaMacConfirmQueueAdd( MlmeConfirmQueue_t* mlmeConfirm ) ConfirmQueueCtx.BufferEnd->RestrictCommonReadyToHandle = mlmeConfirm->RestrictCommonReadyToHandle; ConfirmQueueCtx.BufferEnd->ReadyToHandle = false; // Increase counter - ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt++; + ConfirmQueueCtx.Nvm.MlmeConfirmQueueCnt++; // Update end pointer ConfirmQueueCtx.BufferEnd = IncreaseBufferPointer( ConfirmQueueCtx.BufferEnd ); @@ -218,13 +183,13 @@ bool LoRaMacConfirmQueueAdd( MlmeConfirmQueue_t* mlmeConfirm ) bool LoRaMacConfirmQueueRemoveLast( void ) { - if( IsListEmpty( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt ) == true ) + if( IsListEmpty( ConfirmQueueCtx.Nvm.MlmeConfirmQueueCnt ) == true ) { return false; } // Increase counter - ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt--; + ConfirmQueueCtx.Nvm.MlmeConfirmQueueCnt--; // Update start pointer ConfirmQueueCtx.BufferEnd = DecreaseBufferPointer( ConfirmQueueCtx.BufferEnd ); @@ -233,13 +198,13 @@ bool LoRaMacConfirmQueueRemoveLast( void ) bool LoRaMacConfirmQueueRemoveFirst( void ) { - if( IsListEmpty( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt ) == true ) + if( IsListEmpty( ConfirmQueueCtx.Nvm.MlmeConfirmQueueCnt ) == true ) { return false; } // Increase counter - ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt--; + ConfirmQueueCtx.Nvm.MlmeConfirmQueueCnt--; // Update start pointer ConfirmQueueCtx.BufferStart = IncreaseBufferPointer( ConfirmQueueCtx.BufferStart ); @@ -250,7 +215,7 @@ void LoRaMacConfirmQueueSetStatus( LoRaMacEventInfoStatus_t status, Mlme_t reque { MlmeConfirmQueue_t* element = NULL; - if( IsListEmpty( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt ) == false ) + if( IsListEmpty( ConfirmQueueCtx.Nvm.MlmeConfirmQueueCnt ) == false ) { element = GetElement( request, ConfirmQueueCtx.BufferStart, ConfirmQueueCtx.BufferEnd ); if( element != NULL ) @@ -265,7 +230,7 @@ LoRaMacEventInfoStatus_t LoRaMacConfirmQueueGetStatus( Mlme_t request ) { MlmeConfirmQueue_t* element = NULL; - if( IsListEmpty( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt ) == false ) + if( IsListEmpty( ConfirmQueueCtx.Nvm.MlmeConfirmQueueCnt ) == false ) { element = GetElement( request, ConfirmQueueCtx.BufferStart, ConfirmQueueCtx.BufferEnd ); if( element != NULL ) @@ -280,9 +245,9 @@ void LoRaMacConfirmQueueSetStatusCmn( LoRaMacEventInfoStatus_t status ) { MlmeConfirmQueue_t* element = ConfirmQueueCtx.BufferStart; - ConfirmQueueCtx.ConfirmQueueNvmCtx->CommonStatus = status; + ConfirmQueueCtx.Nvm.CommonStatus = status; - if( IsListEmpty( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt ) == false ) + if( IsListEmpty( ConfirmQueueCtx.Nvm.MlmeConfirmQueueCnt ) == false ) { do { @@ -300,7 +265,7 @@ void LoRaMacConfirmQueueSetStatusCmn( LoRaMacEventInfoStatus_t status ) LoRaMacEventInfoStatus_t LoRaMacConfirmQueueGetStatusCmn( void ) { - return ConfirmQueueCtx.ConfirmQueueNvmCtx->CommonStatus; + return ConfirmQueueCtx.Nvm.CommonStatus; } bool LoRaMacConfirmQueueIsCmdActive( Mlme_t request ) @@ -314,7 +279,7 @@ bool LoRaMacConfirmQueueIsCmdActive( Mlme_t request ) void LoRaMacConfirmQueueHandleCb( MlmeConfirm_t* mlmeConfirm ) { - uint8_t nbElements = ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt; + uint8_t nbElements = ConfirmQueueCtx.Nvm.MlmeConfirmQueueCnt; bool readyToHandle = false; MlmeConfirmQueue_t mlmeConfirmToStore; @@ -349,12 +314,12 @@ void LoRaMacConfirmQueueHandleCb( MlmeConfirm_t* mlmeConfirm ) uint8_t LoRaMacConfirmQueueGetCnt( void ) { - return ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt; + return ConfirmQueueCtx.Nvm.MlmeConfirmQueueCnt; } bool LoRaMacConfirmQueueIsFull( void ) { - if( IsListFull( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt ) == true ) + if( IsListFull( ConfirmQueueCtx.Nvm.MlmeConfirmQueueCnt ) == true ) { return true; } diff --git a/src/mac/LoRaMacConfirmQueue.h b/src/mac/LoRaMacConfirmQueue.h index c41dcc145..b42799e01 100644 --- a/src/mac/LoRaMacConfirmQueue.h +++ b/src/mac/LoRaMacConfirmQueue.h @@ -78,39 +78,12 @@ typedef struct sMlmeConfirmQueue bool RestrictCommonReadyToHandle; }MlmeConfirmQueue_t; -/*! - * Signature of callback function to be called by this module when the - * non-volatile needs to be saved. - */ -typedef void ( *LoRaMacConfirmQueueNvmEvent )( void ); - /*! * \brief Initializes the confirm queue * * \param [IN] primitives - Pointer to the LoRaMac primitives. - * - * \param [IN] confirmQueueNvmCtxChanged - Callback function which will be called when the - * non-volatile context needs to be saved. - */ -void LoRaMacConfirmQueueInit( LoRaMacPrimitives_t* primitives, LoRaMacConfirmQueueNvmEvent confirmQueueNvmCtxChanged ); - -/*! - * Restores the internal non-volatile context from passed pointer. - * - * \param [IN] confirmQueueNvmCtx - Pointer to non-volatile class B module context to be restored. - * - * \retval [true - operation was successful, false - operation failed] - */ -bool LoRaMacConfirmQueueRestoreNvmCtx( void* confirmQueueNvmCtx ); - -/*! - * Returns a pointer to the internal non-volatile context. - * - * \param [IN] confirmQueueNvmCtxSize - Size of the module non-volatile context - * - * \retval - Points to a structure where the module store its non-volatile context */ -void* LoRaMacConfirmQueueGetNvmCtx( size_t* confirmQueueNvmCtxSize ); +void LoRaMacConfirmQueueInit( LoRaMacPrimitives_t* primitive ); /*! * \brief Adds an element to the confirm queue. diff --git a/src/mac/LoRaMacCrypto.c b/src/mac/LoRaMacCrypto.c index ace906f1b..5dbf0e40d 100644 --- a/src/mac/LoRaMacCrypto.c +++ b/src/mac/LoRaMacCrypto.c @@ -61,16 +61,6 @@ */ #define NUM_OF_SEC_CTX 5 -/* - * Size of the module context - */ -#define CRYPTO_CTX_SIZE sizeof( LoRaMacCryptoCtx_t ) - -/* - * Size of the module non volatile context - */ -#define CRYPTO_NVM_CTX_SIZE sizeof( LoRaMacCryptoNvmCtx_t ) - /* * Maximum size of the message that can be handled by the crypto operations */ @@ -81,94 +71,6 @@ */ #define CRYPTO_BUFFER_SIZE CRYPTO_MAXMESSAGE_SIZE + MIC_BLOCK_BX_SIZE -/*! - * LoRaWAN Frame counter list. - */ -typedef struct sFCntList -{ - /*! - * Uplink frame counter which is incremented with each uplink. - */ - uint32_t FCntUp; - /*! - * Network downlink frame counter which is incremented with each downlink on FPort 0 - * or when the FPort field is missing. - */ - uint32_t NFCntDown; - /*! - * Application downlink frame counter which is incremented with each downlink - * on a port different than 0. - */ - uint32_t AFCntDown; - /*! - * In case if the device is connected to a LoRaWAN 1.0 Server, - * this counter is used for every kind of downlink frame. - */ - uint32_t FCntDown; - /*! - * Multicast downlink counters - */ - uint32_t McFCntDown[LORAMAC_MAX_MC_CTX]; -#if( USE_LRWAN_1_1_X_CRYPTO == 1 ) - /* - * RJcount1 is a counter incremented with every Rejoin request Type 1 frame transmitted. - */ - uint16_t RJcount1; -#endif -}FCntList_t; - -/* - * LoRaMac Crypto Non Volatile Context structure - */ -typedef struct sLoRaMacCryptoNvmCtx -{ - /* - * Stores the information if the device is connected to a LoRaWAN network - * server with prior to 1.1.0 implementation. - */ - Version_t LrWanVersion; - /* - * Device nonce is a counter starting at 0 when the device is initially - * powered up and incremented with every JoinRequest. - */ - uint16_t DevNonce; - /* - * JoinNonce is a device specific counter value (that never repeats itself) - * provided by the join server and incremented with every JoinAccept message. - */ - uint32_t JoinNonce; - /* - * Frame counter list - */ - FCntList_t FCntList; - /* - * LastDownFCnt stores the information which frame counter was used to unsecure the last frame. - * This information is needed to compute ConfFCnt in B1 block for the MIC. - */ - uint32_t* LastDownFCnt; -}LoRaMacCryptoNvmCtx_t; - -/* - * LoRaMac Crypto Context structure - */ -typedef struct sLoRaMacCryptoCtx -{ -#if( USE_LRWAN_1_1_X_CRYPTO == 1 ) - /* - * RJcount0 is a counter incremented with every Type 0 or 2 Rejoin frame transmitted. - */ - uint16_t RJcount0; -#endif - /* - * Non volatile module context structure - */ - LoRaMacCryptoNvmCtx_t* NvmCtx; - /* - * Callback function to notify the upper layer about context change - */ - LoRaMacCryptoNvmEvent EventCryptoNvmCtxChanged; -}LoRaMacCryptoCtx_t; - /* * Key-Address item */ @@ -192,15 +94,17 @@ typedef struct sKeyAddr KeyIdentifier_t RootKey; }KeyAddr_t; +#if( USE_LRWAN_1_1_X_CRYPTO == 1 ) /* - *Crypto module context. + * RJcount0 is a counter incremented with every Type 0 or 2 Rejoin frame transmitted. */ -static LoRaMacCryptoCtx_t CryptoCtx; +static uint16_t RJcount0; +#endif /* * Non volatile module context. */ -static LoRaMacCryptoNvmCtx_t NvmCryptoCtx; +static LoRaMacCryptoNvmData_t* CryptoNvm; /* * Key-Address list @@ -214,10 +118,6 @@ static KeyAddr_t KeyAddrList[NUM_OF_SEC_CTX] = { UNICAST_DEV_ADDR, APP_S_KEY, S_NWK_S_INT_KEY, NO_KEY } }; -/* - * Local functions - */ - /* * Encrypts the payload * @@ -300,7 +200,7 @@ static LoRaMacCryptoStatus_t FOptsEncrypt( uint16_t size, uint32_t address, uint aBlock[0] = 0x01; - if( CryptoCtx.NvmCtx->LrWanVersion.Value > 0x01010000 ) + if( CryptoNvm->LrWanVersion.Value > 0x01010000 ) { // Introduced in LoRaWAN 1.1.1 specification switch( fCntID ) @@ -337,7 +237,7 @@ static LoRaMacCryptoStatus_t FOptsEncrypt( uint16_t size, uint32_t address, uint aBlock[12] = ( frameCounter >> 16 ) & 0xFF; aBlock[13] = ( frameCounter >> 24 ) & 0xFF; - if( CryptoCtx.NvmCtx->LrWanVersion.Value > 0x01010000 ) + if( CryptoNvm->LrWanVersion.Value > 0x01010000 ) { // Introduced in LoRaWAN 1.1.1 specification aBlock[15] = 0x01; @@ -385,7 +285,7 @@ static LoRaMacCryptoStatus_t PrepareB0( uint16_t msgLen, KeyIdentifier_t keyID, // confFCnt contains the frame counter value modulo 2^16 of the "confirmed" uplink or downlink frame that is being acknowledged uint16_t confFCnt = 0; - confFCnt = ( uint16_t )( CryptoCtx.NvmCtx->FCntList.FCntUp % 65536 ); + confFCnt = ( uint16_t )( CryptoNvm->FCntList.FCntUp % 65536 ); b0[1] = confFCnt & 0xFF; b0[2] = ( confFCnt >> 8 ) & 0xFF; @@ -530,7 +430,7 @@ static LoRaMacCryptoStatus_t PrepareB1( uint16_t msgLen, KeyIdentifier_t keyID, if( isAck == true ) { // confFCnt contains the frame counter value modulo 2^16 of the "confirmed" uplink frame that is being acknowledged - uint16_t confFCnt = ( uint16_t )( *CryptoCtx.NvmCtx->LastDownFCnt % 65536 ); + uint16_t confFCnt = ( uint16_t )( *CryptoNvm->LastDownFCnt % 65536 ); b1[1] = confFCnt & 0xFF; b1[2] = ( confFCnt >> 8 ) & 0xFF; } @@ -779,35 +679,35 @@ static LoRaMacCryptoStatus_t GetLastFcntDown( FCntIdentifier_t fCntID, uint32_t* switch( fCntID ) { case N_FCNT_DOWN: - *lastDown = CryptoCtx.NvmCtx->FCntList.NFCntDown; - CryptoCtx.NvmCtx->LastDownFCnt = &CryptoCtx.NvmCtx->FCntList.NFCntDown; + *lastDown = CryptoNvm->FCntList.NFCntDown; + CryptoNvm->LastDownFCnt = CryptoNvm->FCntList.NFCntDown; break; case A_FCNT_DOWN: - *lastDown = CryptoCtx.NvmCtx->FCntList.AFCntDown; - CryptoCtx.NvmCtx->LastDownFCnt = &CryptoCtx.NvmCtx->FCntList.AFCntDown; + *lastDown = CryptoNvm->FCntList.AFCntDown; + CryptoNvm->LastDownFCnt = CryptoNvm->FCntList.AFCntDown; break; case FCNT_DOWN: - *lastDown = CryptoCtx.NvmCtx->FCntList.FCntDown; - CryptoCtx.NvmCtx->LastDownFCnt = &CryptoCtx.NvmCtx->FCntList.FCntDown; + *lastDown = CryptoNvm->FCntList.FCntDown; + CryptoNvm->LastDownFCnt = CryptoNvm->FCntList.FCntDown; break; #if ( LORAMAC_MAX_MC_CTX > 0 ) case MC_FCNT_DOWN_0: - *lastDown = CryptoCtx.NvmCtx->FCntList.McFCntDown[0]; + *lastDown = CryptoNvm->FCntList.McFCntDown[0]; break; #endif #if ( LORAMAC_MAX_MC_CTX > 1 ) case MC_FCNT_DOWN_1: - *lastDown = CryptoCtx.NvmCtx->FCntList.McFCntDown[1]; + *lastDown = CryptoNvm->FCntList.McFCntDown[1]; break; #endif #if ( LORAMAC_MAX_MC_CTX > 2 ) case MC_FCNT_DOWN_2: - *lastDown = CryptoCtx.NvmCtx->FCntList.McFCntDown[2]; + *lastDown = CryptoNvm->FCntList.McFCntDown[2]; break; #endif #if ( LORAMAC_MAX_MC_CTX > 3 ) case MC_FCNT_DOWN_3: - *lastDown = CryptoCtx.NvmCtx->FCntList.McFCntDown[3]; + *lastDown = CryptoNvm->FCntList.McFCntDown[3]; break; #endif default: @@ -856,38 +756,37 @@ static void UpdateFCntDown( FCntIdentifier_t fCntID, uint32_t currentDown ) switch( fCntID ) { case N_FCNT_DOWN: - CryptoCtx.NvmCtx->FCntList.NFCntDown = currentDown; + CryptoNvm->FCntList.NFCntDown = currentDown; break; case A_FCNT_DOWN: - CryptoCtx.NvmCtx->FCntList.AFCntDown = currentDown; + CryptoNvm->FCntList.AFCntDown = currentDown; break; case FCNT_DOWN: - CryptoCtx.NvmCtx->FCntList.FCntDown = currentDown; + CryptoNvm->FCntList.FCntDown = currentDown; break; #if ( LORAMAC_MAX_MC_CTX > 0 ) case MC_FCNT_DOWN_0: - CryptoCtx.NvmCtx->FCntList.McFCntDown[0] = currentDown; + CryptoNvm->FCntList.McFCntDown[0] = currentDown; break; #endif #if ( LORAMAC_MAX_MC_CTX > 1 ) case MC_FCNT_DOWN_1: - CryptoCtx.NvmCtx->FCntList.McFCntDown[1] = currentDown; + CryptoNvm->FCntList.McFCntDown[1] = currentDown; break; #endif #if ( LORAMAC_MAX_MC_CTX > 2 ) case MC_FCNT_DOWN_2: - CryptoCtx.NvmCtx->FCntList.McFCntDown[2] = currentDown; + CryptoNvm->FCntList.McFCntDown[2] = currentDown; break; #endif #if ( LORAMAC_MAX_MC_CTX > 3 ) case MC_FCNT_DOWN_3: - CryptoCtx.NvmCtx->FCntList.McFCntDown[3] = currentDown; + CryptoNvm->FCntList.McFCntDown[3] = currentDown; break; #endif default: break; } - CryptoCtx.EventCryptoNvmCtxChanged( ); } /*! @@ -895,55 +794,39 @@ static void UpdateFCntDown( FCntIdentifier_t fCntID, uint32_t currentDown ) */ static void ResetFCnts( void ) { - CryptoCtx.NvmCtx->FCntList.FCntUp = 0; - CryptoCtx.NvmCtx->FCntList.NFCntDown = FCNT_DOWN_INITAL_VALUE; - CryptoCtx.NvmCtx->FCntList.AFCntDown = FCNT_DOWN_INITAL_VALUE; - CryptoCtx.NvmCtx->FCntList.FCntDown = FCNT_DOWN_INITAL_VALUE; - CryptoCtx.NvmCtx->LastDownFCnt = &CryptoCtx.NvmCtx->FCntList.FCntDown; + CryptoNvm->FCntList.FCntUp = 0; + CryptoNvm->FCntList.NFCntDown = FCNT_DOWN_INITAL_VALUE; + CryptoNvm->FCntList.AFCntDown = FCNT_DOWN_INITAL_VALUE; + CryptoNvm->FCntList.FCntDown = FCNT_DOWN_INITAL_VALUE; + CryptoNvm->LastDownFCnt = CryptoNvm->FCntList.FCntDown; for( int32_t i = 0; i < LORAMAC_MAX_MC_CTX; i++ ) { - CryptoCtx.NvmCtx->FCntList.McFCntDown[i] = FCNT_DOWN_INITAL_VALUE; + CryptoNvm->FCntList.McFCntDown[i] = FCNT_DOWN_INITAL_VALUE; } - - CryptoCtx.EventCryptoNvmCtxChanged( ); -} - -/* - * Dummy callback in case if the user provides NULL function pointer - */ -static void DummyCB( void ) -{ - return; } /* * API functions */ - -LoRaMacCryptoStatus_t LoRaMacCryptoInit( LoRaMacCryptoNvmEvent cryptoNvmCtxChanged ) +LoRaMacCryptoStatus_t LoRaMacCryptoInit( LoRaMacCryptoNvmData_t* nvm ) { - // Assign non volatile context - CryptoCtx.NvmCtx = &NvmCryptoCtx; - - // Assign callback - if( cryptoNvmCtxChanged != 0 ) + if( nvm == NULL ) { - CryptoCtx.EventCryptoNvmCtxChanged = cryptoNvmCtxChanged; - } - else - { - CryptoCtx.EventCryptoNvmCtxChanged = DummyCB; + return LORAMAC_CRYPTO_FAIL_PARAM; } + // Assign non volatile context + CryptoNvm = nvm; + // Initialize with default - memset1( ( uint8_t* )CryptoCtx.NvmCtx, 0, sizeof( LoRaMacCryptoNvmCtx_t ) ); + memset1( ( uint8_t* )CryptoNvm, 0, sizeof( LoRaMacCryptoNvmData_t ) ); // Set default LoRaWAN version - CryptoCtx.NvmCtx->LrWanVersion.Fields.Major = 1; - CryptoCtx.NvmCtx->LrWanVersion.Fields.Minor = 1; - CryptoCtx.NvmCtx->LrWanVersion.Fields.Patch = 1; - CryptoCtx.NvmCtx->LrWanVersion.Fields.Revision = 0; + CryptoNvm->LrWanVersion.Fields.Major = 1; + CryptoNvm->LrWanVersion.Fields.Minor = 1; + CryptoNvm->LrWanVersion.Fields.Patch = 1; + CryptoNvm->LrWanVersion.Fields.Revision = 0; // Reset frame counters ResetFCnts( ); @@ -953,30 +836,10 @@ LoRaMacCryptoStatus_t LoRaMacCryptoInit( LoRaMacCryptoNvmEvent cryptoNvmCtxChang LoRaMacCryptoStatus_t LoRaMacCryptoSetLrWanVersion( Version_t version ) { - CryptoCtx.NvmCtx->LrWanVersion = version; + CryptoNvm->LrWanVersion = version; return LORAMAC_CRYPTO_SUCCESS; } -LoRaMacCryptoStatus_t LoRaMacCryptoRestoreNvmCtx( void* cryptoNvmCtx ) -{ - // Restore module context - if( cryptoNvmCtx != 0 ) - { - memcpy1( ( uint8_t* )&NvmCryptoCtx, ( uint8_t* )cryptoNvmCtx, CRYPTO_NVM_CTX_SIZE ); - return LORAMAC_CRYPTO_SUCCESS; - } - else - { - return LORAMAC_CRYPTO_ERROR_NPE; - } -} - -void* LoRaMacCryptoGetNvmCtx( size_t* cryptoNvmCtxSize ) -{ - *cryptoNvmCtxSize = CRYPTO_NVM_CTX_SIZE; - return &NvmCryptoCtx; -} - LoRaMacCryptoStatus_t LoRaMacCryptoGetFCntUp( uint32_t* currentUp ) { if( currentUp == NULL ) @@ -984,7 +847,7 @@ LoRaMacCryptoStatus_t LoRaMacCryptoGetFCntUp( uint32_t* currentUp ) return LORAMAC_CRYPTO_ERROR_NPE; } - *currentUp = CryptoCtx.NvmCtx->FCntList.FCntUp + 1; + *currentUp = CryptoNvm->FCntList.FCntUp + 1; return LORAMAC_CRYPTO_SUCCESS; } @@ -1032,7 +895,7 @@ LoRaMacCryptoStatus_t LoRaMacCryptoGetFCntDown( FCntIdentifier_t fCntID, uint16_ } // For LoRaWAN 1.0.X only, check maxFCntGap - if( CryptoCtx.NvmCtx->LrWanVersion.Fields.Minor == 0 ) + if( CryptoNvm->LrWanVersion.Fields.Minor == 0 ) { if( ( ( int64_t )*currentDown - ( int64_t )lastDown ) >= maxFCntGap ) { @@ -1053,10 +916,10 @@ LoRaMacCryptoStatus_t LoRaMacCryptoGetRJcount( FCntIdentifier_t fCntID, uint16_t switch( fCntID ) { case RJ_COUNT_0: - *rJcount = CryptoCtx.RJcount0 + 1; + *rJcount = RJcount0 + 1; break; case RJ_COUNT_1: - *rJcount = CryptoCtx.NvmCtx->FCntList.RJcount1 + 1; + *rJcount = CryptoNvm->FCntList.RJcount1 + 1; break; default: return LORAMAC_CRYPTO_FAIL_FCNT_ID; @@ -1074,7 +937,7 @@ LoRaMacCryptoStatus_t LoRaMacCryptoSetMulticastReference( MulticastCtx_t* multic for( int32_t i = 0; i < LORAMAC_MAX_MC_CTX; i++ ) { - multicastList[i].DownLinkCounter = &CryptoCtx.NvmCtx->FCntList.McFCntDown[i]; + multicastList[i].DownLinkCounter = &CryptoNvm->FCntList.McFCntDown[i]; } return LORAMAC_CRYPTO_SUCCESS; @@ -1089,7 +952,7 @@ LoRaMacCryptoStatus_t LoRaMacCryptoSetKey( KeyIdentifier_t keyID, uint8_t* key ) if( keyID == APP_KEY ) { // Derive lifetime keys - if( LoRaMacCryptoDeriveMcRootKey( CryptoCtx.NvmCtx->LrWanVersion.Fields.Minor, keyID ) != LORAMAC_CRYPTO_SUCCESS ) + if( LoRaMacCryptoDeriveMcRootKey( CryptoNvm->LrWanVersion.Fields.Minor, keyID ) != LORAMAC_CRYPTO_SUCCESS ) { return LORAMAC_CRYPTO_ERROR_SECURE_ELEMENT_FUNC; } @@ -1113,12 +976,11 @@ LoRaMacCryptoStatus_t LoRaMacCryptoPrepareJoinRequest( LoRaMacMessageJoinRequest #if ( USE_RANDOM_DEV_NONCE == 1 ) uint32_t devNonce = 0; SecureElementRandomNumber( &devNonce ); - CryptoCtx.NvmCtx->DevNonce = devNonce; + CryptoNvm->DevNonce = devNonce; #else - CryptoCtx.NvmCtx->DevNonce++; + CryptoNvm->DevNonce++; #endif - CryptoCtx.EventCryptoNvmCtxChanged( ); - macMsg->DevNonce = CryptoCtx.NvmCtx->DevNonce; + macMsg->DevNonce = CryptoNvm->DevNonce; #if( USE_LRWAN_1_1_X_CRYPTO == 1 ) // Derive lifetime session keys @@ -1162,7 +1024,7 @@ LoRaMacCryptoStatus_t LoRaMacCryptoPrepareReJoinType1( LoRaMacMessageReJoinType1 } // Check for RJcount1 overflow - if( CryptoCtx.NvmCtx->FCntList.RJcount1 == 65535 ) + if( CryptoNvm->FCntList.RJcount1 == 65535 ) { return LORAMAC_CRYPTO_ERROR_RJCOUNT1_OVERFLOW; } @@ -1187,8 +1049,7 @@ LoRaMacCryptoStatus_t LoRaMacCryptoPrepareReJoinType1( LoRaMacMessageReJoinType1 } // Increment RJcount1 - CryptoCtx.NvmCtx->FCntList.RJcount1++; - CryptoCtx.EventCryptoNvmCtxChanged( ); + CryptoNvm->FCntList.RJcount1++; return LORAMAC_CRYPTO_SUCCESS; } @@ -1201,7 +1062,7 @@ LoRaMacCryptoStatus_t LoRaMacCryptoPrepareReJoinType0or2( LoRaMacMessageReJoinTy } // Check for RJcount0 overflow - if( CryptoCtx.RJcount0 == 65535 ) + if( RJcount0 == 65535 ) { return LORAMAC_CRYPTO_FAIL_RJCOUNT0_OVERFLOW; } @@ -1226,7 +1087,7 @@ LoRaMacCryptoStatus_t LoRaMacCryptoPrepareReJoinType0or2( LoRaMacMessageReJoinTy } // Increment RJcount0 - CryptoCtx.RJcount0++; + RJcount0++; return LORAMAC_CRYPTO_SUCCESS; } @@ -1242,13 +1103,13 @@ LoRaMacCryptoStatus_t LoRaMacCryptoHandleJoinAccept( JoinReqIdentifier_t joinReq LoRaMacCryptoStatus_t retval = LORAMAC_CRYPTO_ERROR; uint8_t decJoinAccept[LORAMAC_JOIN_ACCEPT_FRAME_MAX_SIZE] = { 0 }; uint8_t versionMinor = 0; - uint16_t nonce = CryptoCtx.NvmCtx->DevNonce; + uint16_t nonce = CryptoNvm->DevNonce; // Nonce selection depending on JoinReqType - // JOIN_REQ : CryptoCtx.NvmCtx->DevNonce - // REJOIN_REQ_0 : CryptoCtx.RJcount0 + // JOIN_REQ : CryptoNvm->DevNonce + // REJOIN_REQ_0 : RJcount0 // REJOIN_REQ_1 : CryptoCtx.RJcount1 - // REJOIN_REQ_2 : CryptoCtx.RJcount0 + // REJOIN_REQ_2 : RJcount0 if( joinReqType == JOIN_REQ ) { // Nothing to be done @@ -1259,11 +1120,11 @@ LoRaMacCryptoStatus_t LoRaMacCryptoHandleJoinAccept( JoinReqIdentifier_t joinReq // If Join-accept is a reply to a rejoin, the RJcount(0 or 1) replaces DevNonce in the key derivation process. if( ( joinReqType == REJOIN_REQ_0 ) || ( joinReqType == REJOIN_REQ_2 ) ) { - nonce = CryptoCtx.RJcount0; + nonce = RJcount0; } else { - nonce = CryptoCtx.NvmCtx->FCntList.RJcount1; + nonce = CryptoNvm->FCntList.RJcount1; } } #endif @@ -1291,14 +1152,13 @@ LoRaMacCryptoStatus_t LoRaMacCryptoHandleJoinAccept( JoinReqIdentifier_t joinReq #if( USE_JOIN_NONCE_COUNTER_CHECK == 1 ) // Check if the JoinNonce is greater as the previous one - if( currentJoinNonce > CryptoCtx.NvmCtx->JoinNonce ) + if( currentJoinNonce > CryptoNvm->JoinNonce ) #else // Check if the JoinNonce is different from the previous one - if( currentJoinNonce != CryptoCtx.NvmCtx->JoinNonce ) + if( currentJoinNonce != CryptoNvm->JoinNonce ) #endif { - CryptoCtx.NvmCtx->JoinNonce = currentJoinNonce; - CryptoCtx.EventCryptoNvmCtxChanged( ); + CryptoNvm->JoinNonce = currentJoinNonce; } else { @@ -1385,18 +1245,16 @@ LoRaMacCryptoStatus_t LoRaMacCryptoHandleJoinAccept( JoinReqIdentifier_t joinReq // Join-Accept is successfully processed // Save LoRaWAN specification version - CryptoCtx.NvmCtx->LrWanVersion.Fields.Minor = versionMinor; + CryptoNvm->LrWanVersion.Fields.Minor = versionMinor; // Reset frame counters #if( USE_LRWAN_1_1_X_CRYPTO == 1 ) - CryptoCtx.RJcount0 = 0; + RJcount0 = 0; #endif - CryptoCtx.NvmCtx->FCntList.FCntUp = 0; - CryptoCtx.NvmCtx->FCntList.FCntDown = FCNT_DOWN_INITAL_VALUE; - CryptoCtx.NvmCtx->FCntList.NFCntDown = FCNT_DOWN_INITAL_VALUE; - CryptoCtx.NvmCtx->FCntList.AFCntDown = FCNT_DOWN_INITAL_VALUE; - - CryptoCtx.EventCryptoNvmCtxChanged( ); + CryptoNvm->FCntList.FCntUp = 0; + CryptoNvm->FCntList.FCntDown = FCNT_DOWN_INITAL_VALUE; + CryptoNvm->FCntList.NFCntDown = FCNT_DOWN_INITAL_VALUE; + CryptoNvm->FCntList.AFCntDown = FCNT_DOWN_INITAL_VALUE; return LORAMAC_CRYPTO_SUCCESS; } @@ -1411,7 +1269,7 @@ LoRaMacCryptoStatus_t LoRaMacCryptoSecureMessage( uint32_t fCntUp, uint8_t txDr, return LORAMAC_CRYPTO_ERROR_NPE; } - if( fCntUp < CryptoCtx.NvmCtx->FCntList.FCntUp ) + if( fCntUp < CryptoNvm->FCntList.FCntUp ) { return LORAMAC_CRYPTO_FAIL_FCNT_SMALLER; } @@ -1423,7 +1281,7 @@ LoRaMacCryptoStatus_t LoRaMacCryptoSecureMessage( uint32_t fCntUp, uint8_t txDr, payloadDecryptionKeyID = NWK_S_ENC_KEY; } - if( fCntUp > CryptoCtx.NvmCtx->FCntList.FCntUp ) + if( fCntUp > CryptoNvm->FCntList.FCntUp ) { retval = PayloadEncrypt( macMsg->FRMPayload, macMsg->FRMPayloadSize, payloadDecryptionKeyID, macMsg->FHDR.DevAddr, UPLINK, fCntUp ); if( retval != LORAMAC_CRYPTO_SUCCESS ) @@ -1432,7 +1290,7 @@ LoRaMacCryptoStatus_t LoRaMacCryptoSecureMessage( uint32_t fCntUp, uint8_t txDr, } #if( USE_LRWAN_1_1_X_CRYPTO == 1 ) - if( CryptoCtx.NvmCtx->LrWanVersion.Fields.Minor == 1 ) + if( CryptoNvm->LrWanVersion.Fields.Minor == 1 ) { // Encrypt FOpts retval = FOptsEncrypt( macMsg->FHDR.FCtrl.Bits.FOptsLen, macMsg->FHDR.DevAddr, UPLINK, FCNT_UP, fCntUp, macMsg->FHDR.FOpts ); @@ -1452,7 +1310,7 @@ LoRaMacCryptoStatus_t LoRaMacCryptoSecureMessage( uint32_t fCntUp, uint8_t txDr, // Compute mic #if( USE_LRWAN_1_1_X_CRYPTO == 1 ) - if( CryptoCtx.NvmCtx->LrWanVersion.Fields.Minor == 1 ) + if( CryptoNvm->LrWanVersion.Fields.Minor == 1 ) { uint32_t cmacS = 0; uint32_t cmacF = 0; @@ -1490,8 +1348,7 @@ LoRaMacCryptoStatus_t LoRaMacCryptoSecureMessage( uint32_t fCntUp, uint8_t txDr, return LORAMAC_CRYPTO_ERROR_SERIALIZER; } - CryptoCtx.NvmCtx->FCntList.FCntUp = fCntUp; - CryptoCtx.EventCryptoNvmCtxChanged( ); + CryptoNvm->FCntList.FCntUp = fCntUp; return LORAMAC_CRYPTO_SUCCESS; } @@ -1537,7 +1394,7 @@ LoRaMacCryptoStatus_t LoRaMacCryptoUnsecureMessage( AddressIdentifier_t addrID, // Compute mic bool isAck = macMsg->FHDR.FCtrl.Bits.Ack; - if( CryptoCtx.NvmCtx->LrWanVersion.Fields.Minor == 0 ) + if( CryptoNvm->LrWanVersion.Fields.Minor == 0 ) { // In legacy mode the IsAck parameter is forced to be false since the ConfFCnt field is not used. isAck = false; @@ -1563,7 +1420,7 @@ LoRaMacCryptoStatus_t LoRaMacCryptoUnsecureMessage( AddressIdentifier_t addrID, } #if( USE_LRWAN_1_1_X_CRYPTO == 1 ) - if( CryptoCtx.NvmCtx->LrWanVersion.Fields.Minor == 1 ) + if( CryptoNvm->LrWanVersion.Fields.Minor == 1 ) { if( addrID == UNICAST_DEV_ADDR ) { diff --git a/src/mac/LoRaMacCrypto.h b/src/mac/LoRaMacCrypto.h index e4be4cf27..273d064f0 100644 --- a/src/mac/LoRaMacCrypto.h +++ b/src/mac/LoRaMacCrypto.h @@ -48,6 +48,7 @@ extern "C" #include "utilities.h" #include "LoRaMacTypes.h" #include "LoRaMacMessageTypes.h" +#include "LoRaMacCryptoNvm.h" /*! * Indicates if LoRaWAN 1.1.x crypto scheme is enabled @@ -168,11 +169,11 @@ typedef void ( *LoRaMacCryptoNvmEvent )( void ); * Initialization of LoRaMac Crypto module * It sets initial values of volatile variables and assigns the non-volatile context. * - * \param[IN] cryptoNvmCtxChanged - Callback function which will be called when the - * non-volatile context have to be stored. + * \param[IN] nvm - Pointer to the non-volatile memory data + * structure. * \retval - Status of the operation */ -LoRaMacCryptoStatus_t LoRaMacCryptoInit( LoRaMacCryptoNvmEvent cryptoNvmCtxChanged ); +LoRaMacCryptoStatus_t LoRaMacCryptoInit( LoRaMacCryptoNvmData_t* nvm ); /*! * Sets the LoRaWAN specification version to be used. @@ -185,22 +186,6 @@ LoRaMacCryptoStatus_t LoRaMacCryptoInit( LoRaMacCryptoNvmEvent cryptoNvmCtxChang */ LoRaMacCryptoStatus_t LoRaMacCryptoSetLrWanVersion( Version_t version ); -/*! - * Restores the internal nvm context from passed pointer. - * - * \param[IN] cryptoNmvCtx - Pointer to non-volatile crypto module context to be restored. - * \retval - Status of the operation - */ -LoRaMacCryptoStatus_t LoRaMacCryptoRestoreNvmCtx( void* cryptoNvmCtx ); - -/*! - * Returns a pointer to the internal non-volatile context. - * - * \param[IN] cryptoNvmCtxSize - Size of the module non-volatile context - * \retval - Points to a structure where the module store its non-volatile context - */ -void* LoRaMacCryptoGetNvmCtx( size_t* cryptoNvmCtxSize ); - /*! * Returns updated fCntID downlink counter value. * diff --git a/src/mac/LoRaMacCryptoNvm.h b/src/mac/LoRaMacCryptoNvm.h new file mode 100644 index 000000000..558694222 --- /dev/null +++ b/src/mac/LoRaMacCryptoNvm.h @@ -0,0 +1,124 @@ +/*! + * \file LoRaMacCryptoNvm.h + * + * \brief LoRa MAC layer cryptographic NVM data. + * + * \copyright Revised BSD License, see section \ref LICENSE. + * + * \code + * ______ _ + * / _____) _ | | + * ( (____ _____ ____ _| |_ _____ ____| |__ + * \____ \| ___ | (_ _) ___ |/ ___) _ \ + * _____) ) ____| | | || |_| ____( (___| | | | + * (______/|_____)_|_|_| \__)_____)\____)_| |_| + * (C)2013-2017 Semtech + * + * ___ _____ _ ___ _ _____ ___ ___ ___ ___ + * / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| + * \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| + * |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| + * embedded.connectivity.solutions=============== + * + * \endcode + * + * \author Miguel Luis ( Semtech ) + * + * \author Daniel Jaeckle ( STACKFORCE ) + * + * addtogroup LORAMAC + * \{ + * + */ +#ifndef __LORAMAC_CRYPTO_NVM_H__ +#define __LORAMAC_CRYPTO_NVM_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include "utilities.h" +#include "LoRaMacTypes.h" + + +/*! + * LoRaWAN Frame counter list. + */ +typedef struct sFCntList +{ + /*! + * Uplink frame counter which is incremented with each uplink. + */ + uint32_t FCntUp; + /*! + * Network downlink frame counter which is incremented with each downlink on FPort 0 + * or when the FPort field is missing. + */ + uint32_t NFCntDown; + /*! + * Application downlink frame counter which is incremented with each downlink + * on a port different than 0. + */ + uint32_t AFCntDown; + /*! + * In case if the device is connected to a LoRaWAN 1.0 Server, + * this counter is used for every kind of downlink frame. + */ + uint32_t FCntDown; + /*! + * Multicast downlink counters + */ + uint32_t McFCntDown[LORAMAC_MAX_MC_CTX]; +#if( USE_LRWAN_1_1_X_CRYPTO == 1 ) + /*! + * RJcount1 is a counter incremented with every Rejoin request Type 1 frame transmitted. + */ + uint16_t RJcount1; +#endif +}FCntList_t; + +/*! + * LoRaMac Crypto Non Volatile Context structure + */ +typedef struct sLoRaMacCryptoNvmData +{ + /*! + * Stores the information if the device is connected to a LoRaWAN network + * server with prior to 1.1.0 implementation. + */ + Version_t LrWanVersion; + /*! + * Device nonce is a counter starting at 0 when the device is initially + * powered up and incremented with every JoinRequest. + */ + uint16_t DevNonce; + /*! + * JoinNonce is a device specific counter value (that never repeats itself) + * provided by the join server and incremented with every JoinAccept message. + */ + uint32_t JoinNonce; + /*! + * Frame counter list + */ + FCntList_t FCntList; + /*! + * LastDownFCnt stores the information which frame counter was used to + * decrypt the last frame. This information is needed to compute ConfFCnt in + * B1 block for the MIC. + */ + uint32_t LastDownFCnt; + /*! + * CRC32 value of the Crypto data structure. + */ + uint32_t Crc32; +}LoRaMacCryptoNvmData_t; + +/*! \} addtogroup LORAMAC */ + +#ifdef __cplusplus +} +#endif + +#endif // __LORAMAC_CRYPTO_NVM_H__ diff --git a/src/mac/LoRaMacTypes.h b/src/mac/LoRaMacTypes.h index d233a045c..c4cb0c6a8 100644 --- a/src/mac/LoRaMacTypes.h +++ b/src/mac/LoRaMacTypes.h @@ -48,17 +48,520 @@ extern "C" /*! * Start value for unicast keys enumeration */ -#define LORAMAC_CRYPTO_UNICAST_KEYS 0 +#define LORAMAC_CRYPTO_UNICAST_KEYS 0 /*! * Start value for multicast keys enumeration */ -#define LORAMAC_CRYPTO_MULTICAST_KEYS 127 +#define LORAMAC_CRYPTO_MULTICAST_KEYS 127 /*! * Maximum number of multicast context */ -#define LORAMAC_MAX_MC_CTX 4 +#define LORAMAC_MAX_MC_CTX 4 + +/*! + * Region | SF + * ------------ | :-----: + * AS923 | SF12 - BW125 + * AU915 | SF10 - BW125 + * CN470 | SF12 - BW125 + * CN779 | SF12 - BW125 + * EU433 | SF12 - BW125 + * EU868 | SF12 - BW125 + * IN865 | SF12 - BW125 + * KR920 | SF12 - BW125 + * US915 | SF10 - BW125 + * RU864 | SF12 - BW125 + */ +#define DR_0 0 + +/*! + * Region | SF + * ------------ | :-----: + * AS923 | SF11 - BW125 + * AU915 | SF9 - BW125 + * CN470 | SF11 - BW125 + * CN779 | SF11 - BW125 + * EU433 | SF11 - BW125 + * EU868 | SF11 - BW125 + * IN865 | SF11 - BW125 + * KR920 | SF11 - BW125 + * US915 | SF9 - BW125 + * RU864 | SF11 - BW125 + */ +#define DR_1 1 + +/*! + * Region | SF + * ------------ | :-----: + * AS923 | SF10 - BW125 + * AU915 | SF8 - BW125 + * CN470 | SF10 - BW125 + * CN779 | SF10 - BW125 + * EU433 | SF10 - BW125 + * EU868 | SF10 - BW125 + * IN865 | SF10 - BW125 + * KR920 | SF10 - BW125 + * US915 | SF8 - BW125 + * RU864 | SF10 - BW125 + */ +#define DR_2 2 + +/*! + * Region | SF + * ------------ | :-----: + * AS923 | SF9 - BW125 + * AU915 | SF7 - BW125 + * CN470 | SF9 - BW125 + * CN779 | SF9 - BW125 + * EU433 | SF9 - BW125 + * EU868 | SF9 - BW125 + * IN865 | SF9 - BW125 + * KR920 | SF9 - BW125 + * US915 | SF7 - BW125 + * RU864 | SF9 - BW125 + */ +#define DR_3 3 + +/*! + * Region | SF + * ------------ | :-----: + * AS923 | SF8 - BW125 + * AU915 | SF8 - BW500 + * CN470 | SF8 - BW125 + * CN779 | SF8 - BW125 + * EU433 | SF8 - BW125 + * EU868 | SF8 - BW125 + * IN865 | SF8 - BW125 + * KR920 | SF8 - BW125 + * US915 | SF8 - BW500 + * RU864 | SF8 - BW125 + */ +#define DR_4 4 + +/*! + * Region | SF + * ------------ | :-----: + * AS923 | SF7 - BW125 + * AU915 | RFU + * CN470 | SF7 - BW125 + * CN779 | SF7 - BW125 + * EU433 | SF7 - BW125 + * EU868 | SF7 - BW125 + * IN865 | SF7 - BW125 + * KR920 | SF7 - BW125 + * US915 | RFU + * RU864 | SF7 - BW125 + */ +#define DR_5 5 + +/*! + * Region | SF + * ------------ | :-----: + * AS923 | SF7 - BW250 + * AU915 | RFU + * CN470 | SF12 - BW125 + * CN779 | SF7 - BW250 + * EU433 | SF7 - BW250 + * EU868 | SF7 - BW250 + * IN865 | SF7 - BW250 + * KR920 | RFU + * US915 | RFU + * RU864 | SF7 - BW250 + */ +#define DR_6 6 + +/*! + * Region | SF + * ------------ | :-----: + * AS923 | FSK + * AU915 | RFU + * CN470 | SF12 - BW125 + * CN779 | FSK + * EU433 | FSK + * EU868 | FSK + * IN865 | FSK + * KR920 | RFU + * US915 | RFU + * RU864 | FSK + */ +#define DR_7 7 + +/*! + * Region | SF + * ------------ | :-----: + * AS923 | RFU + * AU915 | SF12 - BW500 + * CN470 | RFU + * CN779 | RFU + * EU433 | RFU + * EU868 | RFU + * IN865 | RFU + * KR920 | RFU + * US915 | SF12 - BW500 + * RU864 | RFU + */ +#define DR_8 8 + +/*! + * Region | SF + * ------------ | :-----: + * AS923 | RFU + * AU915 | SF11 - BW500 + * CN470 | RFU + * CN779 | RFU + * EU433 | RFU + * EU868 | RFU + * IN865 | RFU + * KR920 | RFU + * US915 | SF11 - BW500 + * RU864 | RFU + */ +#define DR_9 9 + +/*! + * Region | SF + * ------------ | :-----: + * AS923 | RFU + * AU915 | SF10 - BW500 + * CN470 | RFU + * CN779 | RFU + * EU433 | RFU + * EU868 | RFU + * IN865 | RFU + * KR920 | RFU + * US915 | SF10 - BW500 + * RU864 | RFU + */ +#define DR_10 10 + +/*! + * Region | SF + * ------------ | :-----: + * AS923 | RFU + * AU915 | SF9 - BW500 + * CN470 | RFU + * CN779 | RFU + * EU433 | RFU + * EU868 | RFU + * IN865 | RFU + * KR920 | RFU + * US915 | SF9 - BW500 + * RU864 | RFU + */ +#define DR_11 11 + +/*! + * Region | SF + * ------------ | :-----: + * AS923 | RFU + * AU915 | SF8 - BW500 + * CN470 | RFU + * CN779 | RFU + * EU433 | RFU + * EU868 | RFU + * IN865 | RFU + * KR920 | RFU + * US915 | SF8 - BW500 + * RU864 | RFU + */ +#define DR_12 12 + +/*! + * Region | SF + * ------------ | :-----: + * AS923 | RFU + * AU915 | SF7 - BW500 + * CN470 | RFU + * CN779 | RFU + * EU433 | RFU + * EU868 | RFU + * IN865 | RFU + * KR920 | RFU + * US915 | SF7 - BW500 + * RU864 | RFU + */ +#define DR_13 13 + +/*! + * Region | SF + * ------------ | :-----: + * AS923 | RFU + * AU915 | RFU + * CN470 | RFU + * CN779 | RFU + * EU433 | RFU + * EU868 | RFU + * IN865 | RFU + * KR920 | RFU + * US915 | RFU + * RU864 | RFU + */ +#define DR_14 14 + +/*! + * Region | SF + * ------------ | :-----: + * AS923 | RFU + * AU915 | RFU + * CN470 | RFU + * CN779 | RFU + * EU433 | RFU + * EU868 | RFU + * IN865 | RFU + * KR920 | RFU + * US915 | RFU + * RU864 | RFU + */ +#define DR_15 15 + + + +/*! + * Region | dBM + * ------------ | :-----: + * AS923 | Max EIRP + * AU915 | Max EIRP + * CN470 | Max EIRP + * CN779 | Max EIRP + * EU433 | Max EIRP + * EU868 | Max EIRP + * IN865 | Max EIRP + * KR920 | Max EIRP + * US915 | Max ERP + * RU864 | Max EIRP + */ +#define TX_POWER_0 0 + +/*! + * Region | dBM + * ------------ | :-----: + * AS923 | Max EIRP - 2 + * AU915 | Max EIRP - 2 + * CN470 | Max EIRP - 2 + * CN779 | Max EIRP - 2 + * EU433 | Max EIRP - 2 + * EU868 | Max EIRP - 2 + * IN865 | Max EIRP - 2 + * KR920 | Max EIRP - 2 + * US915 | Max ERP - 2 + * RU864 | Max EIRP - 2 + */ +#define TX_POWER_1 1 + +/*! + * Region | dBM + * ------------ | :-----: + * AS923 | Max EIRP - 4 + * AU915 | Max EIRP - 4 + * CN470 | Max EIRP - 4 + * CN779 | Max EIRP - 4 + * EU433 | Max EIRP - 4 + * EU868 | Max EIRP - 4 + * IN865 | Max EIRP - 4 + * KR920 | Max EIRP - 4 + * US915 | Max ERP - 4 + * RU864 | Max EIRP - 4 + */ +#define TX_POWER_2 2 + +/*! + * Region | dBM + * ------------ | :-----: + * AS923 | Max EIRP - 6 + * AU915 | Max EIRP - 6 + * CN470 | Max EIRP - 6 + * CN779 | Max EIRP - 6 + * EU433 | Max EIRP - 6 + * EU868 | Max EIRP - 6 + * IN865 | Max EIRP - 6 + * KR920 | Max EIRP - 6 + * US915 | Max ERP - 6 + * RU864 | Max EIRP - 6 + */ +#define TX_POWER_3 3 + +/*! + * Region | dBM + * ------------ | :-----: + * AS923 | Max EIRP - 8 + * AU915 | Max EIRP - 8 + * CN470 | Max EIRP - 8 + * CN779 | Max EIRP - 8 + * EU433 | Max EIRP - 8 + * EU868 | Max EIRP - 8 + * IN865 | Max EIRP - 8 + * KR920 | Max EIRP - 8 + * US915 | Max ERP - 8 + * RU864 | Max EIRP - 8 + */ +#define TX_POWER_4 4 + +/*! + * Region | dBM + * ------------ | :-----: + * AS923 | Max EIRP - 10 + * AU915 | Max EIRP - 10 + * CN470 | Max EIRP - 10 + * CN779 | Max EIRP - 10 + * EU433 | Max EIRP - 10 + * EU868 | Max EIRP - 10 + * IN865 | Max EIRP - 10 + * KR920 | Max EIRP - 10 + * US915 | Max ERP - 10 + * RU864 | Max EIRP - 10 + */ +#define TX_POWER_5 5 + +/*! + * Region | dBM + * ------------ | :-----: + * AS923 | Max EIRP - 12 + * AU915 | Max EIRP - 12 + * CN470 | Max EIRP - 12 + * CN779 | - + * EU433 | - + * EU868 | Max EIRP - 12 + * IN865 | Max EIRP - 12 + * KR920 | Max EIRP - 12 + * US915 | Max ERP - 12 + * RU864 | Max EIRP - 12 + */ +#define TX_POWER_6 6 + +/*! + * Region | dBM + * ------------ | :-----: + * AS923 | Max EIRP - 14 + * AU915 | Max EIRP - 14 + * CN470 | Max EIRP - 14 + * CN779 | - + * EU433 | - + * EU868 | Max EIRP - 14 + * IN865 | Max EIRP - 14 + * KR920 | Max EIRP - 14 + * US915 | Max ERP - 14 + * RU864 | Max EIRP - 14 + */ +#define TX_POWER_7 7 + +/*! + * Region | dBM + * ------------ | :-----: + * AS923 | - + * AU915 | Max EIRP - 16 + * CN470 | - + * CN779 | - + * EU433 | - + * EU868 | - + * IN865 | Max EIRP - 16 + * KR920 | - + * US915 | Max ERP - 16 + * RU864 | - + */ +#define TX_POWER_8 8 + +/*! + * Region | dBM + * ------------ | :-----: + * AS923 | - + * AU915 | Max EIRP - 18 + * CN470 | - + * CN779 | - + * EU433 | - + * EU868 | - + * IN865 | Max EIRP - 18 + * KR920 | - + * US915 | Max ERP - 18 + * RU864 | - + */ +#define TX_POWER_9 9 + +/*! + * Region | dBM + * ------------ | :-----: + * AS923 | - + * AU915 | Max EIRP - 20 + * CN470 | - + * CN779 | - + * EU433 | - + * EU868 | - + * IN865 | Max EIRP - 20 + * KR920 | - + * US915 | Max ERP - 20 + * RU864 | - + */ +#define TX_POWER_10 10 + +/*! + * Region | dBM + * ------------ | :-----: + * AS923 | - + * AU915 | Max EIRP - 22 + * CN470 | - + * CN779 | - + * EU433 | - + * EU868 | - + * IN865 | - + * KR920 | - + * US915 | Max ERP - 22 + * RU864 | - + */ +#define TX_POWER_11 11 + +/*! + * Region | dBM + * ------------ | :-----: + * AS923 | - + * AU915 | Max EIRP - 24 + * CN470 | - + * CN779 | - + * EU433 | - + * EU868 | - + * IN865 | - + * KR920 | - + * US915 | Max ERP - 24 + * RU864 | - + */ +#define TX_POWER_12 12 + +/*! + * Region | dBM + * ------------ | :-----: + * AS923 | - + * AU915 | Max EIRP - 26 + * CN470 | - + * CN779 | - + * EU433 | - + * EU868 | - + * IN865 | - + * KR920 | - + * US915 | Max ERP - 26 + * RU864 | - + */ +#define TX_POWER_13 13 + +/*! + * Region | dBM + * ------------ | :-----: + * AS923 | - + * AU915 | Max EIRP - 28 + * CN470 | - + * CN779 | - + * EU433 | - + * EU868 | - + * IN865 | - + * KR920 | - + * US915 | Max ERP - 28 + * RU864 | - + */ +#define TX_POWER_14 14 + +/*! + * RFU + */ +#define TX_POWER_15 15 /*! * LoRaWAN devices classes definition @@ -623,6 +1126,62 @@ typedef struct sBand bool ReadyForTransmission; }Band_t; +/*! + * LoRaMAC channels parameters definition + */ +typedef union uDrRange +{ + /*! + * Byte-access to the bits + */ + int8_t Value; + /*! + * Structure to store the minimum and the maximum datarate + */ + struct sFields + { + /*! + * Minimum data rate + * + * LoRaWAN Regional Parameters V1.0.2rB + * + * The allowed ranges are region specific. Please refer to \ref DR_0 to \ref DR_15 for details. + */ + int8_t Min : 4; + /*! + * Maximum data rate + * + * LoRaWAN Regional Parameters V1.0.2rB + * + * 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; + +/*! + * LoRaMAC channel definition + */ +typedef struct sChannelParams +{ + /*! + * Frequency in Hz + */ + uint32_t Frequency; + /*! + * Alternative frequency for RX window 1 + */ + uint32_t Rx1Frequency; + /*! + * Data rate definition + */ + DrRange_t DrRange; + /*! + * Band index + */ + uint8_t Band; +}ChannelParams_t; + /*! * LoRaMAC frame types * diff --git a/src/mac/region/Region.c b/src/mac/region/Region.c index 75bb6ccc5..d3c9a63d9 100644 --- a/src/mac/region/Region.c +++ b/src/mac/region/Region.c @@ -38,7 +38,6 @@ #define AS923_GET_PHY_PARAM( ) AS923_CASE { return RegionAS923GetPhyParam( getPhy ); } #define AS923_SET_BAND_TX_DONE( ) AS923_CASE { RegionAS923SetBandTxDone( txDone ); break; } #define AS923_INIT_DEFAULTS( ) AS923_CASE { RegionAS923InitDefaults( params ); break; } -#define AS923_GET_NVM_CTX( ) AS923_CASE { return RegionAS923GetNvmCtx( params ); } #define AS923_VERIFY( ) AS923_CASE { return RegionAS923Verify( verify, phyAttribute ); } #define AS923_APPLY_CF_LIST( ) AS923_CASE { RegionAS923ApplyCFList( applyCFList ); break; } #define AS923_CHAN_MASK_SET( ) AS923_CASE { return RegionAS923ChanMaskSet( chanMaskSet ); } @@ -90,7 +89,6 @@ #define AU915_GET_PHY_PARAM( ) AU915_CASE { return RegionAU915GetPhyParam( getPhy ); } #define AU915_SET_BAND_TX_DONE( ) AU915_CASE { RegionAU915SetBandTxDone( txDone ); break; } #define AU915_INIT_DEFAULTS( ) AU915_CASE { RegionAU915InitDefaults( params ); break; } -#define AU915_GET_NVM_CTX( ) AU915_CASE { return RegionAU915GetNvmCtx( params ); } #define AU915_VERIFY( ) AU915_CASE { return RegionAU915Verify( verify, phyAttribute ); } #define AU915_APPLY_CF_LIST( ) AU915_CASE { RegionAU915ApplyCFList( applyCFList ); break; } #define AU915_CHAN_MASK_SET( ) AU915_CASE { return RegionAU915ChanMaskSet( chanMaskSet ); } @@ -142,7 +140,6 @@ #define CN470_GET_PHY_PARAM( ) CN470_CASE { return RegionCN470GetPhyParam( getPhy ); } #define CN470_SET_BAND_TX_DONE( ) CN470_CASE { RegionCN470SetBandTxDone( txDone ); break; } #define CN470_INIT_DEFAULTS( ) CN470_CASE { RegionCN470InitDefaults( params ); break; } -#define CN470_GET_NVM_CTX( ) CN470_CASE { return RegionCN470GetNvmCtx( params ); } #define CN470_VERIFY( ) CN470_CASE { return RegionCN470Verify( verify, phyAttribute ); } #define CN470_APPLY_CF_LIST( ) CN470_CASE { RegionCN470ApplyCFList( applyCFList ); break; } #define CN470_CHAN_MASK_SET( ) CN470_CASE { return RegionCN470ChanMaskSet( chanMaskSet ); } @@ -194,7 +191,6 @@ #define CN779_GET_PHY_PARAM( ) CN779_CASE { return RegionCN779GetPhyParam( getPhy ); } #define CN779_SET_BAND_TX_DONE( ) CN779_CASE { RegionCN779SetBandTxDone( txDone ); break; } #define CN779_INIT_DEFAULTS( ) CN779_CASE { RegionCN779InitDefaults( params ); break; } -#define CN779_GET_NVM_CTX( ) CN779_CASE { return RegionCN779GetNvmCtx( params ); } #define CN779_VERIFY( ) CN779_CASE { return RegionCN779Verify( verify, phyAttribute ); } #define CN779_APPLY_CF_LIST( ) CN779_CASE { RegionCN779ApplyCFList( applyCFList ); break; } #define CN779_CHAN_MASK_SET( ) CN779_CASE { return RegionCN779ChanMaskSet( chanMaskSet ); } @@ -246,7 +242,6 @@ #define EU433_GET_PHY_PARAM( ) EU433_CASE { return RegionEU433GetPhyParam( getPhy ); } #define EU433_SET_BAND_TX_DONE( ) EU433_CASE { RegionEU433SetBandTxDone( txDone ); break; } #define EU433_INIT_DEFAULTS( ) EU433_CASE { RegionEU433InitDefaults( params ); break; } -#define EU433_GET_NVM_CTX( ) EU433_CASE { return RegionEU433GetNvmCtx( params ); } #define EU433_VERIFY( ) EU433_CASE { return RegionEU433Verify( verify, phyAttribute ); } #define EU433_APPLY_CF_LIST( ) EU433_CASE { RegionEU433ApplyCFList( applyCFList ); break; } #define EU433_CHAN_MASK_SET( ) EU433_CASE { return RegionEU433ChanMaskSet( chanMaskSet ); } @@ -298,7 +293,6 @@ #define EU868_GET_PHY_PARAM( ) EU868_CASE { return RegionEU868GetPhyParam( getPhy ); } #define EU868_SET_BAND_TX_DONE( ) EU868_CASE { RegionEU868SetBandTxDone( txDone ); break; } #define EU868_INIT_DEFAULTS( ) EU868_CASE { RegionEU868InitDefaults( params ); break; } -#define EU868_GET_NVM_CTX( ) EU868_CASE { return RegionEU868GetNvmCtx( params ); } #define EU868_VERIFY( ) EU868_CASE { return RegionEU868Verify( verify, phyAttribute ); } #define EU868_APPLY_CF_LIST( ) EU868_CASE { RegionEU868ApplyCFList( applyCFList ); break; } #define EU868_CHAN_MASK_SET( ) EU868_CASE { return RegionEU868ChanMaskSet( chanMaskSet ); } @@ -350,7 +344,6 @@ #define KR920_GET_PHY_PARAM( ) KR920_CASE { return RegionKR920GetPhyParam( getPhy ); } #define KR920_SET_BAND_TX_DONE( ) KR920_CASE { RegionKR920SetBandTxDone( txDone ); break; } #define KR920_INIT_DEFAULTS( ) KR920_CASE { RegionKR920InitDefaults( params ); break; } -#define KR920_GET_NVM_CTX( ) KR920_CASE { return RegionKR920GetNvmCtx( params ); } #define KR920_VERIFY( ) KR920_CASE { return RegionKR920Verify( verify, phyAttribute ); } #define KR920_APPLY_CF_LIST( ) KR920_CASE { RegionKR920ApplyCFList( applyCFList ); break; } #define KR920_CHAN_MASK_SET( ) KR920_CASE { return RegionKR920ChanMaskSet( chanMaskSet ); } @@ -402,7 +395,6 @@ #define IN865_GET_PHY_PARAM( ) IN865_CASE { return RegionIN865GetPhyParam( getPhy ); } #define IN865_SET_BAND_TX_DONE( ) IN865_CASE { RegionIN865SetBandTxDone( txDone ); break; } #define IN865_INIT_DEFAULTS( ) IN865_CASE { RegionIN865InitDefaults( params ); break; } -#define IN865_GET_NVM_CTX( ) IN865_CASE { return RegionIN865GetNvmCtx( params ); } #define IN865_VERIFY( ) IN865_CASE { return RegionIN865Verify( verify, phyAttribute ); } #define IN865_APPLY_CF_LIST( ) IN865_CASE { RegionIN865ApplyCFList( applyCFList ); break; } #define IN865_CHAN_MASK_SET( ) IN865_CASE { return RegionIN865ChanMaskSet( chanMaskSet ); } @@ -454,7 +446,6 @@ #define US915_GET_PHY_PARAM( ) US915_CASE { return RegionUS915GetPhyParam( getPhy ); } #define US915_SET_BAND_TX_DONE( ) US915_CASE { RegionUS915SetBandTxDone( txDone ); break; } #define US915_INIT_DEFAULTS( ) US915_CASE { RegionUS915InitDefaults( params ); break; } -#define US915_GET_NVM_CTX( ) US915_CASE { return RegionUS915GetNvmCtx( params ); } #define US915_VERIFY( ) US915_CASE { return RegionUS915Verify( verify, phyAttribute ); } #define US915_APPLY_CF_LIST( ) US915_CASE { RegionUS915ApplyCFList( applyCFList ); break; } #define US915_CHAN_MASK_SET( ) US915_CASE { return RegionUS915ChanMaskSet( chanMaskSet ); } @@ -506,7 +497,6 @@ #define RU864_GET_PHY_PARAM( ) RU864_CASE { return RegionRU864GetPhyParam( getPhy ); } #define RU864_SET_BAND_TX_DONE( ) RU864_CASE { RegionRU864SetBandTxDone( txDone ); break; } #define RU864_INIT_DEFAULTS( ) RU864_CASE { RegionRU864InitDefaults( params ); break; } -#define RU864_GET_NVM_CTX( ) RU864_CASE { return RegionRU864GetNvmCtx( params ); } #define RU864_VERIFY( ) RU864_CASE { return RegionRU864Verify( verify, phyAttribute ); } #define RU864_APPLY_CF_LIST( ) RU864_CASE { RegionRU864ApplyCFList( applyCFList ); break; } #define RU864_CHAN_MASK_SET( ) RU864_CASE { return RegionRU864ChanMaskSet( chanMaskSet ); } @@ -636,27 +626,6 @@ void RegionInitDefaults( LoRaMacRegion_t region, InitDefaultsParams_t* params ) } } -void* RegionGetNvmCtx( LoRaMacRegion_t region, GetNvmCtxParams_t* params ) -{ - switch( region ) - { - AS923_GET_NVM_CTX( ); - AU915_GET_NVM_CTX( ); - CN470_GET_NVM_CTX( ); - CN779_GET_NVM_CTX( ); - EU433_GET_NVM_CTX( ); - EU868_GET_NVM_CTX( ); - KR920_GET_NVM_CTX( ); - IN865_GET_NVM_CTX( ); - US915_GET_NVM_CTX( ); - RU864_GET_NVM_CTX( ); - default: - { - return 0; - } - } -} - bool RegionVerify( LoRaMacRegion_t region, VerifyParams_t* verify, PhyAttribute_t phyAttribute ) { switch( region ) diff --git a/src/mac/region/Region.h b/src/mac/region/Region.h index 51cd5f33a..3a6aa6177 100644 --- a/src/mac/region/Region.h +++ b/src/mac/region/Region.h @@ -78,511 +78,6 @@ extern "C" -/*! - * Region | SF - * ------------ | :-----: - * AS923 | SF12 - BW125 - * AU915 | SF10 - BW125 - * CN470 | SF12 - BW125 - * CN779 | SF12 - BW125 - * EU433 | SF12 - BW125 - * EU868 | SF12 - BW125 - * IN865 | SF12 - BW125 - * KR920 | SF12 - BW125 - * US915 | SF10 - BW125 - * RU864 | SF12 - BW125 - */ -#define DR_0 0 - -/*! - * Region | SF - * ------------ | :-----: - * AS923 | SF11 - BW125 - * AU915 | SF9 - BW125 - * CN470 | SF11 - BW125 - * CN779 | SF11 - BW125 - * EU433 | SF11 - BW125 - * EU868 | SF11 - BW125 - * IN865 | SF11 - BW125 - * KR920 | SF11 - BW125 - * US915 | SF9 - BW125 - * RU864 | SF11 - BW125 - */ -#define DR_1 1 - -/*! - * Region | SF - * ------------ | :-----: - * AS923 | SF10 - BW125 - * AU915 | SF8 - BW125 - * CN470 | SF10 - BW125 - * CN779 | SF10 - BW125 - * EU433 | SF10 - BW125 - * EU868 | SF10 - BW125 - * IN865 | SF10 - BW125 - * KR920 | SF10 - BW125 - * US915 | SF8 - BW125 - * RU864 | SF10 - BW125 - */ -#define DR_2 2 - -/*! - * Region | SF - * ------------ | :-----: - * AS923 | SF9 - BW125 - * AU915 | SF7 - BW125 - * CN470 | SF9 - BW125 - * CN779 | SF9 - BW125 - * EU433 | SF9 - BW125 - * EU868 | SF9 - BW125 - * IN865 | SF9 - BW125 - * KR920 | SF9 - BW125 - * US915 | SF7 - BW125 - * RU864 | SF9 - BW125 - */ -#define DR_3 3 - -/*! - * Region | SF - * ------------ | :-----: - * AS923 | SF8 - BW125 - * AU915 | SF8 - BW500 - * CN470 | SF8 - BW125 - * CN779 | SF8 - BW125 - * EU433 | SF8 - BW125 - * EU868 | SF8 - BW125 - * IN865 | SF8 - BW125 - * KR920 | SF8 - BW125 - * US915 | SF8 - BW500 - * RU864 | SF8 - BW125 - */ -#define DR_4 4 - -/*! - * Region | SF - * ------------ | :-----: - * AS923 | SF7 - BW125 - * AU915 | RFU - * CN470 | SF7 - BW125 - * CN779 | SF7 - BW125 - * EU433 | SF7 - BW125 - * EU868 | SF7 - BW125 - * IN865 | SF7 - BW125 - * KR920 | SF7 - BW125 - * US915 | RFU - * RU864 | SF7 - BW125 - */ -#define DR_5 5 - -/*! - * Region | SF - * ------------ | :-----: - * AS923 | SF7 - BW250 - * AU915 | RFU - * CN470 | SF12 - BW125 - * CN779 | SF7 - BW250 - * EU433 | SF7 - BW250 - * EU868 | SF7 - BW250 - * IN865 | SF7 - BW250 - * KR920 | RFU - * US915 | RFU - * RU864 | SF7 - BW250 - */ -#define DR_6 6 - -/*! - * Region | SF - * ------------ | :-----: - * AS923 | FSK - * AU915 | RFU - * CN470 | SF12 - BW125 - * CN779 | FSK - * EU433 | FSK - * EU868 | FSK - * IN865 | FSK - * KR920 | RFU - * US915 | RFU - * RU864 | FSK - */ -#define DR_7 7 - -/*! - * Region | SF - * ------------ | :-----: - * AS923 | RFU - * AU915 | SF12 - BW500 - * CN470 | RFU - * CN779 | RFU - * EU433 | RFU - * EU868 | RFU - * IN865 | RFU - * KR920 | RFU - * US915 | SF12 - BW500 - * RU864 | RFU - */ -#define DR_8 8 - -/*! - * Region | SF - * ------------ | :-----: - * AS923 | RFU - * AU915 | SF11 - BW500 - * CN470 | RFU - * CN779 | RFU - * EU433 | RFU - * EU868 | RFU - * IN865 | RFU - * KR920 | RFU - * US915 | SF11 - BW500 - * RU864 | RFU - */ -#define DR_9 9 - -/*! - * Region | SF - * ------------ | :-----: - * AS923 | RFU - * AU915 | SF10 - BW500 - * CN470 | RFU - * CN779 | RFU - * EU433 | RFU - * EU868 | RFU - * IN865 | RFU - * KR920 | RFU - * US915 | SF10 - BW500 - * RU864 | RFU - */ -#define DR_10 10 - -/*! - * Region | SF - * ------------ | :-----: - * AS923 | RFU - * AU915 | SF9 - BW500 - * CN470 | RFU - * CN779 | RFU - * EU433 | RFU - * EU868 | RFU - * IN865 | RFU - * KR920 | RFU - * US915 | SF9 - BW500 - * RU864 | RFU - */ -#define DR_11 11 - -/*! - * Region | SF - * ------------ | :-----: - * AS923 | RFU - * AU915 | SF8 - BW500 - * CN470 | RFU - * CN779 | RFU - * EU433 | RFU - * EU868 | RFU - * IN865 | RFU - * KR920 | RFU - * US915 | SF8 - BW500 - * RU864 | RFU - */ -#define DR_12 12 - -/*! - * Region | SF - * ------------ | :-----: - * AS923 | RFU - * AU915 | SF7 - BW500 - * CN470 | RFU - * CN779 | RFU - * EU433 | RFU - * EU868 | RFU - * IN865 | RFU - * KR920 | RFU - * US915 | SF7 - BW500 - * RU864 | RFU - */ -#define DR_13 13 - -/*! - * Region | SF - * ------------ | :-----: - * AS923 | RFU - * AU915 | RFU - * CN470 | RFU - * CN779 | RFU - * EU433 | RFU - * EU868 | RFU - * IN865 | RFU - * KR920 | RFU - * US915 | RFU - * RU864 | RFU - */ -#define DR_14 14 - -/*! - * Region | SF - * ------------ | :-----: - * AS923 | RFU - * AU915 | RFU - * CN470 | RFU - * CN779 | RFU - * EU433 | RFU - * EU868 | RFU - * IN865 | RFU - * KR920 | RFU - * US915 | RFU - * RU864 | RFU - */ -#define DR_15 15 - - - -/*! - * Region | dBM - * ------------ | :-----: - * AS923 | Max EIRP - * AU915 | Max EIRP - * CN470 | Max EIRP - * CN779 | Max EIRP - * EU433 | Max EIRP - * EU868 | Max EIRP - * IN865 | Max EIRP - * KR920 | Max EIRP - * US915 | Max ERP - * RU864 | Max EIRP - */ -#define TX_POWER_0 0 - -/*! - * Region | dBM - * ------------ | :-----: - * AS923 | Max EIRP - 2 - * AU915 | Max EIRP - 2 - * CN470 | Max EIRP - 2 - * CN779 | Max EIRP - 2 - * EU433 | Max EIRP - 2 - * EU868 | Max EIRP - 2 - * IN865 | Max EIRP - 2 - * KR920 | Max EIRP - 2 - * US915 | Max ERP - 2 - * RU864 | Max EIRP - 2 - */ -#define TX_POWER_1 1 - -/*! - * Region | dBM - * ------------ | :-----: - * AS923 | Max EIRP - 4 - * AU915 | Max EIRP - 4 - * CN470 | Max EIRP - 4 - * CN779 | Max EIRP - 4 - * EU433 | Max EIRP - 4 - * EU868 | Max EIRP - 4 - * IN865 | Max EIRP - 4 - * KR920 | Max EIRP - 4 - * US915 | Max ERP - 4 - * RU864 | Max EIRP - 4 - */ -#define TX_POWER_2 2 - -/*! - * Region | dBM - * ------------ | :-----: - * AS923 | Max EIRP - 6 - * AU915 | Max EIRP - 6 - * CN470 | Max EIRP - 6 - * CN779 | Max EIRP - 6 - * EU433 | Max EIRP - 6 - * EU868 | Max EIRP - 6 - * IN865 | Max EIRP - 6 - * KR920 | Max EIRP - 6 - * US915 | Max ERP - 6 - * RU864 | Max EIRP - 6 - */ -#define TX_POWER_3 3 - -/*! - * Region | dBM - * ------------ | :-----: - * AS923 | Max EIRP - 8 - * AU915 | Max EIRP - 8 - * CN470 | Max EIRP - 8 - * CN779 | Max EIRP - 8 - * EU433 | Max EIRP - 8 - * EU868 | Max EIRP - 8 - * IN865 | Max EIRP - 8 - * KR920 | Max EIRP - 8 - * US915 | Max ERP - 8 - * RU864 | Max EIRP - 8 - */ -#define TX_POWER_4 4 - -/*! - * Region | dBM - * ------------ | :-----: - * AS923 | Max EIRP - 10 - * AU915 | Max EIRP - 10 - * CN470 | Max EIRP - 10 - * CN779 | Max EIRP - 10 - * EU433 | Max EIRP - 10 - * EU868 | Max EIRP - 10 - * IN865 | Max EIRP - 10 - * KR920 | Max EIRP - 10 - * US915 | Max ERP - 10 - * RU864 | Max EIRP - 10 - */ -#define TX_POWER_5 5 - -/*! - * Region | dBM - * ------------ | :-----: - * AS923 | Max EIRP - 12 - * AU915 | Max EIRP - 12 - * CN470 | Max EIRP - 12 - * CN779 | - - * EU433 | - - * EU868 | Max EIRP - 12 - * IN865 | Max EIRP - 12 - * KR920 | Max EIRP - 12 - * US915 | Max ERP - 12 - * RU864 | Max EIRP - 12 - */ -#define TX_POWER_6 6 - -/*! - * Region | dBM - * ------------ | :-----: - * AS923 | Max EIRP - 14 - * AU915 | Max EIRP - 14 - * CN470 | Max EIRP - 14 - * CN779 | - - * EU433 | - - * EU868 | Max EIRP - 14 - * IN865 | Max EIRP - 14 - * KR920 | Max EIRP - 14 - * US915 | Max ERP - 14 - * RU864 | Max EIRP - 14 - */ -#define TX_POWER_7 7 - -/*! - * Region | dBM - * ------------ | :-----: - * AS923 | - - * AU915 | Max EIRP - 16 - * CN470 | - - * CN779 | - - * EU433 | - - * EU868 | - - * IN865 | Max EIRP - 16 - * KR920 | - - * US915 | Max ERP - 16 - * RU864 | - - */ -#define TX_POWER_8 8 - -/*! - * Region | dBM - * ------------ | :-----: - * AS923 | - - * AU915 | Max EIRP - 18 - * CN470 | - - * CN779 | - - * EU433 | - - * EU868 | - - * IN865 | Max EIRP - 18 - * KR920 | - - * US915 | Max ERP - 18 - * RU864 | - - */ -#define TX_POWER_9 9 - -/*! - * Region | dBM - * ------------ | :-----: - * AS923 | - - * AU915 | Max EIRP - 20 - * CN470 | - - * CN779 | - - * EU433 | - - * EU868 | - - * IN865 | Max EIRP - 20 - * KR920 | - - * US915 | Max ERP - 20 - * RU864 | - - */ -#define TX_POWER_10 10 - -/*! - * Region | dBM - * ------------ | :-----: - * AS923 | - - * AU915 | Max EIRP - 22 - * CN470 | - - * CN779 | - - * EU433 | - - * EU868 | - - * IN865 | - - * KR920 | - - * US915 | Max ERP - 22 - * RU864 | - - */ -#define TX_POWER_11 11 - -/*! - * Region | dBM - * ------------ | :-----: - * AS923 | - - * AU915 | Max EIRP - 24 - * CN470 | - - * CN779 | - - * EU433 | - - * EU868 | - - * IN865 | - - * KR920 | - - * US915 | Max ERP - 24 - * RU864 | - - */ -#define TX_POWER_12 12 - -/*! - * Region | dBM - * ------------ | :-----: - * AS923 | - - * AU915 | Max EIRP - 26 - * CN470 | - - * CN779 | - - * EU433 | - - * EU868 | - - * IN865 | - - * KR920 | - - * US915 | Max ERP - 26 - * RU864 | - - */ -#define TX_POWER_13 13 - -/*! - * Region | dBM - * ------------ | :-----: - * AS923 | - - * AU915 | Max EIRP - 28 - * CN470 | - - * CN779 | - - * EU433 | - - * EU868 | - - * IN865 | - - * KR920 | - - * US915 | Max ERP - 28 - * RU864 | - - */ -#define TX_POWER_14 14 - -/*! - * RFU - */ -#define TX_POWER_15 15 - - - /*! * Enumeration of phy attributes. */ @@ -846,11 +341,7 @@ typedef enum eInitType * Activates the default channels. Leaves all other active channels * active. */ - INIT_TYPE_ACTIVATE_DEFAULT_CHANNELS, - /*! - * Restores internal context from passed pointer. - */ - INIT_TYPE_RESTORE_CTX + INIT_TYPE_ACTIVATE_DEFAULT_CHANNELS }InitType_t; typedef enum eChannelsMask @@ -985,26 +476,18 @@ typedef struct sSetBandTxDoneParams typedef struct sInitDefaultsParams { /*! - * Pointer to region module context to be restored. + * Pointer to region NVM group1. */ - void* NvmCtx; + void* NvmGroup1; /*! - * Sets the initialization type. + * Pointer to region NVM group2. */ - InitType_t Type; -}InitDefaultsParams_t; - -/*! - * Parameter structure for the function RegionGetNvmCtx. - */ -typedef struct sGetNvmCtxParams -{ + void* NvmGroup2; /*! - * Size of module context. + * Sets the initialization type. */ - size_t nvmCtxSize; -}GetNvmCtxParams_t; - + InitType_t Type; +}InitDefaultsParams_t; /*! * Parameter structure for the function RegionVerify. @@ -1429,17 +912,6 @@ void RegionSetBandTxDone( LoRaMacRegion_t region, SetBandTxDoneParams_t* txDone */ void RegionInitDefaults( LoRaMacRegion_t region, InitDefaultsParams_t* params ); -/*! - * \brief Returns a pointer to the internal context and its size. - * - * \param [IN] region LoRaWAN region. - * - * \param [IN] params Pointer to the function parameters. - * - * \retval Points to a structure where the module store its non-volatile context. - */ -void* RegionGetNvmCtx( LoRaMacRegion_t region, GetNvmCtxParams_t* params ); - /*! * \brief Verifies a parameter. * diff --git a/src/mac/region/RegionAS923.c b/src/mac/region/RegionAS923.c index c91c4ee9c..da5c72610 100644 --- a/src/mac/region/RegionAS923.c +++ b/src/mac/region/RegionAS923.c @@ -28,8 +28,7 @@ * * \author Daniel Jaeckle ( STACKFORCE ) */ -#include "utilities.h" - +#include "radio.h" #include "RegionCommon.h" #include "RegionAS923.h" @@ -97,33 +96,11 @@ #endif -/*! - * Region specific context - */ -typedef struct sRegionAS923NvmCtx -{ - /*! - * LoRaMAC channels - */ - ChannelParams_t Channels[ AS923_MAX_NB_CHANNELS ]; - /*! - * LoRaMac bands - */ - Band_t Bands[ AS923_MAX_NB_BANDS ]; - /*! - * LoRaMac channels mask - */ - uint16_t ChannelsMask[ CHANNELS_MASK_SIZE ]; - /*! - * LoRaMac channels default mask - */ - uint16_t ChannelsDefaultMask[ CHANNELS_MASK_SIZE ]; -}RegionAS923NvmCtx_t; - /* * Non-volatile module context. */ -static RegionAS923NvmCtx_t NvmCtx; +static RegionNvmDataGroup1_t* RegionNvmGroup1; +static RegionNvmDataGroup2_t* RegionNvmGroup2; // Static functions static bool VerifyRfFreq( uint32_t freq ) @@ -201,8 +178,8 @@ PhyParam_t RegionAS923GetPhyParam( GetPhyParams_t* getPhy ) .MaxDr = ( int8_t )AS923_TX_MAX_DATARATE, .MinDr = ( int8_t )( ( getPhy->UplinkDwellTime == 0 ) ? AS923_TX_MIN_DATARATE : AS923_DWELL_LIMIT_DATARATE ), .NbChannels = AS923_MAX_NB_CHANNELS, - .ChannelsMask = NvmCtx.ChannelsMask, - .Channels = NvmCtx.Channels, + .ChannelsMask = RegionNvmGroup2->ChannelsMask, + .Channels = RegionNvmGroup2->Channels, }; phyParam.Value = RegionCommonGetNextLowerTxDr( &nextLowerTxDrParams ); break; @@ -296,12 +273,12 @@ PhyParam_t RegionAS923GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsMask; break; } case PHY_CHANNELS_DEFAULT_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsDefaultMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsDefaultMask; break; } case PHY_MAX_NB_CHANNELS: @@ -311,7 +288,7 @@ PhyParam_t RegionAS923GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS: { - phyParam.Channels = NvmCtx.Channels; + phyParam.Channels = RegionNvmGroup2->Channels; break; } case PHY_DEF_UPLINK_DWELL_TIME: @@ -382,7 +359,7 @@ PhyParam_t RegionAS923GetPhyParam( GetPhyParams_t* getPhy ) void RegionAS923SetBandTxDone( SetBandTxDoneParams_t* txDone ) { - RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], + RegionCommonSetBandTxDone( &RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txDone->Channel].Band], txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp ); } @@ -397,45 +374,45 @@ void RegionAS923InitDefaults( InitDefaultsParams_t* params ) { case INIT_TYPE_DEFAULTS: { + if( ( params->NvmGroup1 == NULL ) || ( params->NvmGroup2 == NULL ) ) + { + return; + } + + RegionNvmGroup1 = (RegionNvmDataGroup1_t*) params->NvmGroup1; + RegionNvmGroup2 = (RegionNvmDataGroup2_t*) params->NvmGroup2; + // Default bands - memcpy1( ( uint8_t* )NvmCtx.Bands, ( uint8_t* )bands, sizeof( Band_t ) * AS923_MAX_NB_BANDS ); + memcpy1( ( uint8_t* )RegionNvmGroup1->Bands, ( uint8_t* )bands, sizeof( Band_t ) * AS923_MAX_NB_BANDS ); // Default channels - NvmCtx.Channels[0] = ( ChannelParams_t ) AS923_LC1; - NvmCtx.Channels[1] = ( ChannelParams_t ) AS923_LC2; + RegionNvmGroup2->Channels[0] = ( ChannelParams_t ) AS923_LC1; + RegionNvmGroup2->Channels[1] = ( ChannelParams_t ) AS923_LC2; // Apply frequency offset - NvmCtx.Channels[0].Frequency -= REGION_AS923_FREQ_OFFSET; - NvmCtx.Channels[1].Frequency -= REGION_AS923_FREQ_OFFSET; + RegionNvmGroup2->Channels[0].Frequency -= REGION_AS923_FREQ_OFFSET; + RegionNvmGroup2->Channels[1].Frequency -= REGION_AS923_FREQ_OFFSET; // Default ChannelsMask - NvmCtx.ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ); + RegionNvmGroup2->ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ); // Update the channels mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); break; } case INIT_TYPE_RESET_TO_DEFAULT_CHANNELS: { // Reset Channels Rx1Frequency to default 0 - NvmCtx.Channels[0].Rx1Frequency = 0; - NvmCtx.Channels[1].Rx1Frequency = 0; + RegionNvmGroup2->Channels[0].Rx1Frequency = 0; + RegionNvmGroup2->Channels[1].Rx1Frequency = 0; // Update the channels mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); break; } case INIT_TYPE_ACTIVATE_DEFAULT_CHANNELS: { // Activate channels default mask - NvmCtx.ChannelsMask[0] |= NvmCtx.ChannelsDefaultMask[0]; - break; - } - case INIT_TYPE_RESTORE_CTX: - { - if( params->NvmCtx != 0 ) - { - memcpy1( (uint8_t*) &NvmCtx, (uint8_t*) params->NvmCtx, sizeof( NvmCtx ) ); - } + RegionNvmGroup2->ChannelsMask[0] |= RegionNvmGroup2->ChannelsDefaultMask[0]; break; } default: @@ -445,12 +422,6 @@ void RegionAS923InitDefaults( InitDefaultsParams_t* params ) } } -void* RegionAS923GetNvmCtx( GetNvmCtxParams_t* params ) -{ - params->nvmCtxSize = sizeof( RegionAS923NvmCtx_t ); - return &NvmCtx; -} - bool RegionAS923Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) { switch( phyAttribute ) @@ -565,12 +536,12 @@ bool RegionAS923ChanMaskSet( ChanMaskSetParams_t* chanMaskSet ) { case CHANNELS_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, chanMaskSet->ChannelsMaskIn, 1 ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, chanMaskSet->ChannelsMaskIn, 1 ); break; } case CHANNELS_DEFAULT_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 1 ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 1 ); break; } default: @@ -614,11 +585,11 @@ bool RegionAS923RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) if( rxConfig->RxSlot == RX_SLOT_WIN_1 ) { // Apply window 1 frequency - frequency = NvmCtx.Channels[rxConfig->Channel].Frequency; + frequency = RegionNvmGroup2->Channels[rxConfig->Channel].Frequency; // Apply the alternative RX 1 window frequency, if it is available - if( NvmCtx.Channels[rxConfig->Channel].Rx1Frequency != 0 ) + if( RegionNvmGroup2->Channels[rxConfig->Channel].Rx1Frequency != 0 ) { - frequency = NvmCtx.Channels[rxConfig->Channel].Rx1Frequency; + frequency = RegionNvmGroup2->Channels[rxConfig->Channel].Rx1Frequency; } } @@ -649,7 +620,7 @@ bool RegionAS923TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime { RadioModems_t modem; int8_t phyDr = DataratesAS923[txConfig->Datarate]; - int8_t txPowerLimited = RegionCommonLimitTxPower( txConfig->TxPower, NvmCtx.Bands[NvmCtx.Channels[txConfig->Channel].Band].TxMaxPower ); + int8_t txPowerLimited = RegionCommonLimitTxPower( txConfig->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txConfig->Channel].Band].TxMaxPower ); uint32_t bandwidth = RegionCommonGetBandwidth( txConfig->Datarate, BandwidthsAS923 ); int8_t phyTxPower = 0; @@ -657,7 +628,7 @@ bool RegionAS923TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime phyTxPower = RegionCommonComputeTxPower( txPowerLimited, txConfig->MaxEirp, txConfig->AntennaGain ); // Setup the radio frequency - Radio.SetChannel( NvmCtx.Channels[txConfig->Channel].Frequency ); + Radio.SetChannel( RegionNvmGroup2->Channels[txConfig->Channel].Frequency ); if( txConfig->Datarate == DR_7 ) { // High Speed FSK channel @@ -725,7 +696,7 @@ uint8_t RegionAS923LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in { if( linkAdrParams.ChMaskCtrl == 6 ) { - if( NvmCtx.Channels[i].Frequency != 0 ) + if( RegionNvmGroup2->Channels[i].Frequency != 0 ) { chMask |= 1 << i; } @@ -733,7 +704,7 @@ uint8_t RegionAS923LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in else { if( ( ( chMask & ( 1 << i ) ) != 0 ) && - ( NvmCtx.Channels[i].Frequency == 0 ) ) + ( RegionNvmGroup2->Channels[i].Frequency == 0 ) ) {// Trying to enable an undefined channel status &= 0xFE; // Channel mask KO } @@ -759,7 +730,7 @@ uint8_t RegionAS923LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in linkAdrVerifyParams.ChannelsMask = &chMask; linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value; linkAdrVerifyParams.MaxDatarate = AS923_TX_MAX_DATARATE; - linkAdrVerifyParams.Channels = NvmCtx.Channels; + linkAdrVerifyParams.Channels = RegionNvmGroup2->Channels; linkAdrVerifyParams.MinTxPower = AS923_MIN_TX_POWER; linkAdrVerifyParams.MaxTxPower = AS923_MAX_TX_POWER; linkAdrVerifyParams.Version = linkAdrReq->Version; @@ -771,9 +742,9 @@ uint8_t RegionAS923LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in if( status == 0x07 ) { // Set the channels mask to a default value - memset1( ( uint8_t* ) NvmCtx.ChannelsMask, 0, sizeof( NvmCtx.ChannelsMask ) ); + memset1( ( uint8_t* ) RegionNvmGroup2->ChannelsMask, 0, sizeof( RegionNvmGroup2->ChannelsMask ) ); // Update the channels mask - NvmCtx.ChannelsMask[0] = chMask; + RegionNvmGroup2->ChannelsMask[0] = chMask; } // Update status variables @@ -880,7 +851,7 @@ int8_t RegionAS923DlChannelReq( DlChannelReqParams_t* dlChannelReq ) } // Verify if an uplink frequency exists - if( NvmCtx.Channels[dlChannelReq->ChannelId].Frequency == 0 ) + if( RegionNvmGroup2->Channels[dlChannelReq->ChannelId].Frequency == 0 ) { status &= 0xFD; } @@ -888,7 +859,7 @@ int8_t RegionAS923DlChannelReq( DlChannelReqParams_t* dlChannelReq ) // Apply Rx1 frequency, if the status is OK if( status == 0x03 ) { - NvmCtx.Channels[dlChannelReq->ChannelId].Rx1Frequency = dlChannelReq->Rx1Frequency; + RegionNvmGroup2->Channels[dlChannelReq->ChannelId].Rx1Frequency = dlChannelReq->Rx1Frequency; } return status; @@ -910,17 +881,17 @@ LoRaMacStatus_t RegionAS923NextChannel( NextChanParams_t* nextChanParams, uint8_ LoRaMacStatus_t status = LORAMAC_STATUS_NO_CHANNEL_FOUND; uint16_t joinChannels = AS923_JOIN_CHANNELS; - if( RegionCommonCountChannels( NvmCtx.ChannelsMask, 0, 1 ) == 0 ) + if( RegionCommonCountChannels( RegionNvmGroup2->ChannelsMask, 0, 1 ) == 0 ) { // Reactivate default channels - NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ); + RegionNvmGroup2->ChannelsMask[0] |= LC( 1 ) + LC( 2 ); } // Search how many channels are enabled countChannelsParams.Joined = nextChanParams->Joined; countChannelsParams.Datarate = nextChanParams->Datarate; - countChannelsParams.ChannelsMask = NvmCtx.ChannelsMask; - countChannelsParams.Channels = NvmCtx.Channels; - countChannelsParams.Bands = NvmCtx.Bands; + countChannelsParams.ChannelsMask = RegionNvmGroup2->ChannelsMask; + countChannelsParams.Channels = RegionNvmGroup2->Channels; + countChannelsParams.Bands = RegionNvmGroup1->Bands; countChannelsParams.MaxNbChannels = AS923_MAX_NB_CHANNELS; countChannelsParams.JoinChannels = &joinChannels; @@ -951,7 +922,7 @@ LoRaMacStatus_t RegionAS923NextChannel( NextChanParams_t* nextChanParams, uint8_ // Perform carrier sense for AS923_CARRIER_SENSE_TIME // If the channel is free, we can stop the LBT mechanism - if( Radio.IsChannelFree( NvmCtx.Channels[channelNext].Frequency, AS923_LBT_RX_BANDWIDTH, AS923_RSSI_FREE_TH, AS923_CARRIER_SENSE_TIME ) == true ) + if( Radio.IsChannelFree( RegionNvmGroup2->Channels[channelNext].Frequency, AS923_LBT_RX_BANDWIDTH, AS923_RSSI_FREE_TH, AS923_CARRIER_SENSE_TIME ) == true ) { // Free channel found *channel = channelNext; @@ -969,7 +940,7 @@ LoRaMacStatus_t RegionAS923NextChannel( NextChanParams_t* nextChanParams, uint8_ else if( status == LORAMAC_STATUS_NO_CHANNEL_FOUND ) { // Datarate not supported by any channel, restore defaults - NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ); + RegionNvmGroup2->ChannelsMask[0] |= LC( 1 ) + LC( 2 ); } return status; } @@ -1027,9 +998,9 @@ LoRaMacStatus_t RegionAS923ChannelAdd( ChannelAddParams_t* channelAdd ) return LORAMAC_STATUS_FREQUENCY_INVALID; } - memcpy1( ( uint8_t* ) &(NvmCtx.Channels[id]), ( uint8_t* ) channelAdd->NewChannel, sizeof( NvmCtx.Channels[id] ) ); - NvmCtx.Channels[id].Band = 0; - NvmCtx.ChannelsMask[0] |= ( 1 << id ); + memcpy1( ( uint8_t* ) &(RegionNvmGroup2->Channels[id]), ( uint8_t* ) channelAdd->NewChannel, sizeof( RegionNvmGroup2->Channels[id] ) ); + RegionNvmGroup2->Channels[id].Band = 0; + RegionNvmGroup2->ChannelsMask[0] |= ( 1 << id ); return LORAMAC_STATUS_OK; } @@ -1043,16 +1014,16 @@ bool RegionAS923ChannelsRemove( ChannelRemoveParams_t* channelRemove ) } // Remove the channel from the list of channels - NvmCtx.Channels[id] = ( ChannelParams_t ){ 0, 0, { 0 }, 0 }; + RegionNvmGroup2->Channels[id] = ( ChannelParams_t ){ 0, 0, { 0 }, 0 }; - return RegionCommonChanDisable( NvmCtx.ChannelsMask, id, AS923_MAX_NB_CHANNELS ); + return RegionCommonChanDisable( RegionNvmGroup2->ChannelsMask, id, AS923_MAX_NB_CHANNELS ); } void RegionAS923SetContinuousWave( ContinuousWaveParams_t* continuousWave ) { - int8_t txPowerLimited = RegionCommonLimitTxPower( continuousWave->TxPower, NvmCtx.Bands[NvmCtx.Channels[continuousWave->Channel].Band].TxMaxPower ); + int8_t txPowerLimited = RegionCommonLimitTxPower( continuousWave->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[continuousWave->Channel].Band].TxMaxPower ); int8_t phyTxPower = 0; - uint32_t frequency = NvmCtx.Channels[continuousWave->Channel].Frequency; + uint32_t frequency = RegionNvmGroup2->Channels[continuousWave->Channel].Frequency; // Calculate physical TX power phyTxPower = RegionCommonComputeTxPower( txPowerLimited, continuousWave->MaxEirp, continuousWave->AntennaGain ); diff --git a/src/mac/region/RegionAS923.h b/src/mac/region/RegionAS923.h index 68538a087..69ee293be 100644 --- a/src/mac/region/RegionAS923.h +++ b/src/mac/region/RegionAS923.h @@ -315,15 +315,6 @@ void RegionAS923SetBandTxDone( SetBandTxDoneParams_t* txDone ); */ void RegionAS923InitDefaults( InitDefaultsParams_t* params ); -/*! - * \brief Returns a pointer to the internal context and its size. - * - * \param [OUT] params Pointer to the function parameters. - * - * \retval Points to a structure where the module store its non-volatile context. - */ -void* RegionAS923GetNvmCtx( GetNvmCtxParams_t* params ); - /*! * \brief Verifies a parameter. * diff --git a/src/mac/region/RegionAU915.c b/src/mac/region/RegionAU915.c index 6ec31f256..51b656698 100644 --- a/src/mac/region/RegionAU915.c +++ b/src/mac/region/RegionAU915.c @@ -28,8 +28,7 @@ * * \author Daniel Jaeckle ( STACKFORCE ) */ -#include "utilities.h" - +#include "radio.h" #include "RegionCommon.h" #include "RegionAU915.h" #include "RegionBaseUS.h" @@ -40,45 +39,11 @@ // A mask to select only valid 500KHz channels #define CHANNELS_MASK_500KHZ_MASK 0x00FF -/*! - * Region specific context - */ -typedef struct sRegionAU915NvmCtx -{ - /*! - * LoRaMAC channels - */ - ChannelParams_t Channels[ AU915_MAX_NB_CHANNELS ]; - /*! - * LoRaMac bands - */ - Band_t Bands[ AU915_MAX_NB_BANDS ]; - /*! - * LoRaMac channels mask - */ - uint16_t ChannelsMask[ CHANNELS_MASK_SIZE ]; - /*! - * LoRaMac channels remaining - */ - uint16_t ChannelsMaskRemaining[CHANNELS_MASK_SIZE]; - /*! - * LoRaMac channels default mask - */ - uint16_t ChannelsDefaultMask[ CHANNELS_MASK_SIZE ]; - /*! - * Index of current in use 8 bit group (0: bit 0 - 7, 1: bit 8 - 15, ..., 7: bit 56 - 63) - */ - uint8_t JoinChannelGroupsCurrentIndex; - /*! - * Counter of join trials needed to alternate between DR2 and DR6, see \ref RegionAU915AlternateDr - */ - uint8_t JoinTrialsCounter; -}RegionAU915NvmCtx_t; - /* * Non-volatile module context. */ -static RegionAU915NvmCtx_t NvmCtx; +static RegionNvmDataGroup1_t* RegionNvmGroup1; +static RegionNvmDataGroup2_t* RegionNvmGroup2; static bool VerifyRfFreq( uint32_t freq ) { @@ -155,8 +120,8 @@ PhyParam_t RegionAU915GetPhyParam( GetPhyParams_t* getPhy ) .MaxDr = ( int8_t )AU915_TX_MAX_DATARATE, .MinDr = ( int8_t )( ( getPhy->UplinkDwellTime == 0 ) ? AU915_TX_MIN_DATARATE : AU915_DWELL_LIMIT_DATARATE ), .NbChannels = AU915_MAX_NB_CHANNELS, - .ChannelsMask = NvmCtx.ChannelsMask, - .Channels = NvmCtx.Channels, + .ChannelsMask = RegionNvmGroup2->ChannelsMask, + .Channels = RegionNvmGroup2->Channels, }; phyParam.Value = RegionCommonGetNextLowerTxDr( &nextLowerTxDrParams ); break; @@ -250,12 +215,12 @@ PhyParam_t RegionAU915GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsMask; break; } case PHY_CHANNELS_DEFAULT_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsDefaultMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsDefaultMask; break; } case PHY_MAX_NB_CHANNELS: @@ -265,7 +230,7 @@ PhyParam_t RegionAU915GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS: { - phyParam.Channels = NvmCtx.Channels; + phyParam.Channels = RegionNvmGroup2->Channels; break; } case PHY_DEF_UPLINK_DWELL_TIME: @@ -350,7 +315,7 @@ PhyParam_t RegionAU915GetPhyParam( GetPhyParams_t* getPhy ) void RegionAU915SetBandTxDone( SetBandTxDoneParams_t* txDone ) { - RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], + RegionCommonSetBandTxDone( &RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txDone->Channel].Band], txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp ); } @@ -365,44 +330,52 @@ void RegionAU915InitDefaults( InitDefaultsParams_t* params ) { case INIT_TYPE_DEFAULTS: { + if( ( params->NvmGroup1 == NULL ) || ( params->NvmGroup2 == NULL ) ) + { + return; + } + + RegionNvmGroup1 = (RegionNvmDataGroup1_t*) params->NvmGroup1; + RegionNvmGroup2 = (RegionNvmDataGroup2_t*) params->NvmGroup2; + // Initialize 8 bit channel groups index - NvmCtx.JoinChannelGroupsCurrentIndex = 0; + RegionNvmGroup1->JoinChannelGroupsCurrentIndex = 0; // Initialize the join trials counter - NvmCtx.JoinTrialsCounter = 0; + RegionNvmGroup1->JoinTrialsCounter = 0; // Default bands - memcpy1( ( uint8_t* )NvmCtx.Bands, ( uint8_t* )bands, sizeof( Band_t ) * AU915_MAX_NB_BANDS ); + memcpy1( ( uint8_t* )RegionNvmGroup1->Bands, ( uint8_t* )bands, sizeof( Band_t ) * AU915_MAX_NB_BANDS ); // Channels for( uint8_t i = 0; i < AU915_MAX_NB_CHANNELS - 8; i++ ) { // 125 kHz channels - NvmCtx.Channels[i].Frequency = 915200000 + i * 200000; - NvmCtx.Channels[i].DrRange.Value = ( DR_5 << 4 ) | DR_0; - NvmCtx.Channels[i].Band = 0; + RegionNvmGroup2->Channels[i].Frequency = 915200000 + i * 200000; + RegionNvmGroup2->Channels[i].DrRange.Value = ( DR_5 << 4 ) | DR_0; + RegionNvmGroup2->Channels[i].Band = 0; } for( uint8_t i = AU915_MAX_NB_CHANNELS - 8; i < AU915_MAX_NB_CHANNELS; i++ ) { // 500 kHz channels - NvmCtx.Channels[i].Frequency = 915900000 + ( i - ( AU915_MAX_NB_CHANNELS - 8 ) ) * 1600000; - NvmCtx.Channels[i].DrRange.Value = ( DR_6 << 4 ) | DR_6; - NvmCtx.Channels[i].Band = 0; + RegionNvmGroup2->Channels[i].Frequency = 915900000 + ( i - ( AU915_MAX_NB_CHANNELS - 8 ) ) * 1600000; + RegionNvmGroup2->Channels[i].DrRange.Value = ( DR_6 << 4 ) | DR_6; + RegionNvmGroup2->Channels[i].Band = 0; } // Initialize channels default mask - NvmCtx.ChannelsDefaultMask[0] = 0xFFFF; - NvmCtx.ChannelsDefaultMask[1] = 0xFFFF; - NvmCtx.ChannelsDefaultMask[2] = 0xFFFF; - NvmCtx.ChannelsDefaultMask[3] = 0xFFFF; - NvmCtx.ChannelsDefaultMask[4] = 0x00FF; - NvmCtx.ChannelsDefaultMask[5] = 0x0000; + RegionNvmGroup2->ChannelsDefaultMask[0] = 0xFFFF; + RegionNvmGroup2->ChannelsDefaultMask[1] = 0xFFFF; + RegionNvmGroup2->ChannelsDefaultMask[2] = 0xFFFF; + RegionNvmGroup2->ChannelsDefaultMask[3] = 0xFFFF; + RegionNvmGroup2->ChannelsDefaultMask[4] = 0x00FF; + RegionNvmGroup2->ChannelsDefaultMask[5] = 0x0000; // Copy channels default mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); // Copy into channels mask remaining - RegionCommonChanMaskCopy( NvmCtx.ChannelsMaskRemaining, NvmCtx.ChannelsMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup1->ChannelsMaskRemaining, RegionNvmGroup2->ChannelsMask, CHANNELS_MASK_SIZE ); break; } case INIT_TYPE_RESET_TO_DEFAULT_CHANNELS: @@ -412,19 +385,11 @@ void RegionAU915InitDefaults( InitDefaultsParams_t* params ) case INIT_TYPE_ACTIVATE_DEFAULT_CHANNELS: { // Copy channels default mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); for( uint8_t i = 0; i < CHANNELS_MASK_SIZE; i++ ) { // Copy-And the channels mask - NvmCtx.ChannelsMaskRemaining[i] &= NvmCtx.ChannelsMask[i]; - } - break; - } - case INIT_TYPE_RESTORE_CTX: - { - if( params->NvmCtx != 0 ) - { - memcpy1( (uint8_t*) &NvmCtx, (uint8_t*) params->NvmCtx, sizeof( NvmCtx ) ); + RegionNvmGroup1->ChannelsMaskRemaining[i] &= RegionNvmGroup2->ChannelsMask[i]; } break; } @@ -435,12 +400,6 @@ void RegionAU915InitDefaults( InitDefaultsParams_t* params ) } } -void* RegionAU915GetNvmCtx( GetNvmCtxParams_t* params ) -{ - params->nvmCtxSize = sizeof( RegionAU915NvmCtx_t ); - return &NvmCtx; -} - bool RegionAU915Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) { switch( phyAttribute ) @@ -504,14 +463,14 @@ void RegionAU915ApplyCFList( ApplyCFListParams_t* applyCFList ) // ChMask0 - ChMask4 must be set (every ChMask has 16 bit) for( uint8_t chMaskItr = 0, cntPayload = 0; chMaskItr <= 4; chMaskItr++, cntPayload+=2 ) { - NvmCtx.ChannelsMask[chMaskItr] = (uint16_t) (0x00FF & applyCFList->Payload[cntPayload]); - NvmCtx.ChannelsMask[chMaskItr] |= (uint16_t) (applyCFList->Payload[cntPayload+1] << 8); + RegionNvmGroup2->ChannelsMask[chMaskItr] = (uint16_t) (0x00FF & applyCFList->Payload[cntPayload]); + RegionNvmGroup2->ChannelsMask[chMaskItr] |= (uint16_t) (applyCFList->Payload[cntPayload+1] << 8); if( chMaskItr == 4 ) { - NvmCtx.ChannelsMask[chMaskItr] = NvmCtx.ChannelsMask[chMaskItr] & CHANNELS_MASK_500KHZ_MASK; + RegionNvmGroup2->ChannelsMask[chMaskItr] = RegionNvmGroup2->ChannelsMask[chMaskItr] & CHANNELS_MASK_500KHZ_MASK; } // Set the channel mask to the remaining - NvmCtx.ChannelsMaskRemaining[chMaskItr] &= NvmCtx.ChannelsMask[chMaskItr]; + RegionNvmGroup1->ChannelsMaskRemaining[chMaskItr] &= RegionNvmGroup2->ChannelsMask[chMaskItr]; } } @@ -521,20 +480,20 @@ bool RegionAU915ChanMaskSet( ChanMaskSetParams_t* chanMaskSet ) { case CHANNELS_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, chanMaskSet->ChannelsMaskIn, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, chanMaskSet->ChannelsMaskIn, CHANNELS_MASK_SIZE ); - NvmCtx.ChannelsDefaultMask[4] = NvmCtx.ChannelsDefaultMask[4] & CHANNELS_MASK_500KHZ_MASK; - NvmCtx.ChannelsDefaultMask[5] = 0x0000; + RegionNvmGroup2->ChannelsDefaultMask[4] = RegionNvmGroup2->ChannelsDefaultMask[4] & CHANNELS_MASK_500KHZ_MASK; + RegionNvmGroup2->ChannelsDefaultMask[5] = 0x0000; for( uint8_t i = 0; i < CHANNELS_MASK_SIZE; i++ ) { // Copy-And the channels mask - NvmCtx.ChannelsMaskRemaining[i] &= NvmCtx.ChannelsMask[i]; + RegionNvmGroup1->ChannelsMaskRemaining[i] &= RegionNvmGroup2->ChannelsMask[i]; } break; } case CHANNELS_DEFAULT_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, CHANNELS_MASK_SIZE ); break; } default: @@ -590,7 +549,7 @@ bool RegionAU915RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) bool RegionAU915TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir ) { int8_t phyDr = DataratesAU915[txConfig->Datarate]; - int8_t txPowerLimited = RegionCommonLimitTxPower( txConfig->TxPower, NvmCtx.Bands[NvmCtx.Channels[txConfig->Channel].Band].TxMaxPower ); + int8_t txPowerLimited = RegionCommonLimitTxPower( txConfig->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txConfig->Channel].Band].TxMaxPower ); uint32_t bandwidth = RegionCommonGetBandwidth( txConfig->Datarate, BandwidthsAU915 ); int8_t phyTxPower = 0; @@ -598,7 +557,7 @@ bool RegionAU915TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime phyTxPower = RegionCommonComputeTxPower( txPowerLimited, txConfig->MaxEirp, txConfig->AntennaGain ); // Setup the radio frequency - Radio.SetChannel( NvmCtx.Channels[txConfig->Channel].Frequency ); + Radio.SetChannel( RegionNvmGroup2->Channels[txConfig->Channel].Frequency ); Radio.SetTxConfig( MODEM_LORA, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 4000 ); @@ -624,7 +583,7 @@ uint8_t RegionAU915LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in RegionCommonLinkAdrReqVerifyParams_t linkAdrVerifyParams; // Initialize local copy of channels mask - RegionCommonChanMaskCopy( channelsMask, NvmCtx.ChannelsMask, 6 ); + RegionCommonChanMaskCopy( channelsMask, RegionNvmGroup2->ChannelsMask, 6 ); while( bytesProcessed < linkAdrReq->PayloadSize ) { @@ -742,7 +701,7 @@ uint8_t RegionAU915LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in linkAdrVerifyParams.ChannelsMask = channelsMask; linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value; linkAdrVerifyParams.MaxDatarate = AU915_TX_MAX_DATARATE; - linkAdrVerifyParams.Channels = NvmCtx.Channels; + linkAdrVerifyParams.Channels = RegionNvmGroup2->Channels; linkAdrVerifyParams.MinTxPower = AU915_MIN_TX_POWER; linkAdrVerifyParams.MaxTxPower = AU915_MAX_TX_POWER; linkAdrVerifyParams.Version = linkAdrReq->Version; @@ -754,14 +713,14 @@ uint8_t RegionAU915LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in if( status == 0x07 ) { // Copy Mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, channelsMask, 6 ); - - NvmCtx.ChannelsMaskRemaining[0] &= NvmCtx.ChannelsMask[0]; - NvmCtx.ChannelsMaskRemaining[1] &= NvmCtx.ChannelsMask[1]; - NvmCtx.ChannelsMaskRemaining[2] &= NvmCtx.ChannelsMask[2]; - NvmCtx.ChannelsMaskRemaining[3] &= NvmCtx.ChannelsMask[3]; - NvmCtx.ChannelsMaskRemaining[4] = NvmCtx.ChannelsMask[4]; - NvmCtx.ChannelsMaskRemaining[5] = NvmCtx.ChannelsMask[5]; + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, channelsMask, 6 ); + + RegionNvmGroup1->ChannelsMaskRemaining[0] &= RegionNvmGroup2->ChannelsMask[0]; + RegionNvmGroup1->ChannelsMaskRemaining[1] &= RegionNvmGroup2->ChannelsMask[1]; + RegionNvmGroup1->ChannelsMaskRemaining[2] &= RegionNvmGroup2->ChannelsMask[2]; + RegionNvmGroup1->ChannelsMaskRemaining[3] &= RegionNvmGroup2->ChannelsMask[3]; + RegionNvmGroup1->ChannelsMaskRemaining[4] = RegionNvmGroup2->ChannelsMask[4]; + RegionNvmGroup1->ChannelsMaskRemaining[5] = RegionNvmGroup2->ChannelsMask[5]; } // Update status variables @@ -827,14 +786,14 @@ int8_t RegionAU915AlternateDr( int8_t currentDr, AlternateDrType_t type ) // Eight times a 125kHz DR_2 and then one 500kHz DR_6 channel if( type == ALTERNATE_DR ) { - NvmCtx.JoinTrialsCounter++; + RegionNvmGroup1->JoinTrialsCounter++; } else { - NvmCtx.JoinTrialsCounter--; + RegionNvmGroup1->JoinTrialsCounter--; } - if( NvmCtx.JoinTrialsCounter % 9 == 0 ) + if( RegionNvmGroup1->JoinTrialsCounter % 9 == 0 ) { // Use DR_6 every 9th times. currentDr = DR_6; @@ -856,27 +815,27 @@ LoRaMacStatus_t RegionAU915NextChannel( NextChanParams_t* nextChanParams, uint8_ LoRaMacStatus_t status = LORAMAC_STATUS_NO_CHANNEL_FOUND; // Count 125kHz channels - if( RegionCommonCountChannels( NvmCtx.ChannelsMaskRemaining, 0, 4 ) == 0 ) + if( RegionCommonCountChannels( RegionNvmGroup1->ChannelsMaskRemaining, 0, 4 ) == 0 ) { // Reactivate default channels - RegionCommonChanMaskCopy( NvmCtx.ChannelsMaskRemaining, NvmCtx.ChannelsMask, 4 ); + RegionCommonChanMaskCopy( RegionNvmGroup1->ChannelsMaskRemaining, RegionNvmGroup2->ChannelsMask, 4 ); - NvmCtx.JoinChannelGroupsCurrentIndex = 0; + RegionNvmGroup1->JoinChannelGroupsCurrentIndex = 0; } // Check other channels if( nextChanParams->Datarate >= DR_6 ) { - if( ( NvmCtx.ChannelsMaskRemaining[4] & CHANNELS_MASK_500KHZ_MASK ) == 0 ) + if( ( RegionNvmGroup1->ChannelsMaskRemaining[4] & CHANNELS_MASK_500KHZ_MASK ) == 0 ) { - NvmCtx.ChannelsMaskRemaining[4] = NvmCtx.ChannelsMask[4]; + RegionNvmGroup1->ChannelsMaskRemaining[4] = RegionNvmGroup2->ChannelsMask[4]; } } // Search how many channels are enabled countChannelsParams.Joined = nextChanParams->Joined; countChannelsParams.Datarate = nextChanParams->Datarate; - countChannelsParams.ChannelsMask = NvmCtx.ChannelsMaskRemaining; - countChannelsParams.Channels = NvmCtx.Channels; - countChannelsParams.Bands = NvmCtx.Bands; + countChannelsParams.ChannelsMask = RegionNvmGroup1->ChannelsMaskRemaining; + countChannelsParams.Channels = RegionNvmGroup2->Channels; + countChannelsParams.Bands = RegionNvmGroup1->Bands; countChannelsParams.MaxNbChannels = AU915_MAX_NB_CHANNELS; countChannelsParams.JoinChannels = NULL; @@ -911,8 +870,8 @@ LoRaMacStatus_t RegionAU915NextChannel( NextChanParams_t* nextChanParams, uint8_ // 125kHz Channels (0 - 63) DR2 if( nextChanParams->Datarate == DR_2 ) { - if( RegionBaseUSComputeNext125kHzJoinChannel( ( uint16_t* ) NvmCtx.ChannelsMaskRemaining, - &NvmCtx.JoinChannelGroupsCurrentIndex, channel ) == LORAMAC_STATUS_PARAMETER_INVALID ) + if( RegionBaseUSComputeNext125kHzJoinChannel( ( uint16_t* ) RegionNvmGroup1->ChannelsMaskRemaining, + &RegionNvmGroup1->JoinChannelGroupsCurrentIndex, channel ) == LORAMAC_STATUS_PARAMETER_INVALID ) { return LORAMAC_STATUS_PARAMETER_INVALID; } @@ -922,7 +881,7 @@ LoRaMacStatus_t RegionAU915NextChannel( NextChanParams_t* nextChanParams, uint8_ { // Choose the next available channel uint8_t i = 0; - while( ( ( NvmCtx.ChannelsMaskRemaining[4] & CHANNELS_MASK_500KHZ_MASK ) & ( 1 << i ) ) == 0 ) + while( ( ( RegionNvmGroup1->ChannelsMaskRemaining[4] & CHANNELS_MASK_500KHZ_MASK ) & ( 1 << i ) ) == 0 ) { i++; } @@ -931,7 +890,7 @@ LoRaMacStatus_t RegionAU915NextChannel( NextChanParams_t* nextChanParams, uint8_ } // Disable the channel in the mask - RegionCommonChanDisable( NvmCtx.ChannelsMaskRemaining, *channel, AU915_MAX_NB_CHANNELS ); + RegionCommonChanDisable( RegionNvmGroup1->ChannelsMaskRemaining, *channel, AU915_MAX_NB_CHANNELS ); } return status; } @@ -948,9 +907,9 @@ bool RegionAU915ChannelsRemove( ChannelRemoveParams_t* channelRemove ) void RegionAU915SetContinuousWave( ContinuousWaveParams_t* continuousWave ) { - int8_t txPowerLimited = RegionCommonLimitTxPower( continuousWave->TxPower, NvmCtx.Bands[NvmCtx.Channels[continuousWave->Channel].Band].TxMaxPower ); + int8_t txPowerLimited = RegionCommonLimitTxPower( continuousWave->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[continuousWave->Channel].Band].TxMaxPower ); int8_t phyTxPower = 0; - uint32_t frequency = NvmCtx.Channels[continuousWave->Channel].Frequency; + uint32_t frequency = RegionNvmGroup2->Channels[continuousWave->Channel].Frequency; // Calculate physical TX power phyTxPower = RegionCommonComputeTxPower( txPowerLimited, continuousWave->MaxEirp, continuousWave->AntennaGain ); diff --git a/src/mac/region/RegionAU915.h b/src/mac/region/RegionAU915.h index 555fbc7b5..863426e9b 100644 --- a/src/mac/region/RegionAU915.h +++ b/src/mac/region/RegionAU915.h @@ -278,15 +278,6 @@ void RegionAU915SetBandTxDone( SetBandTxDoneParams_t* txDone ); */ void RegionAU915InitDefaults( InitDefaultsParams_t* params ); -/*! - * \brief Returns a pointer to the internal context and its size. - * - * \param [OUT] params Pointer to the function parameters. - * - * \retval Points to a structure where the module store its non-volatile context. - */ -void* RegionAU915GetNvmCtx( GetNvmCtxParams_t* params ); - /*! * \brief Verifies a parameter. * diff --git a/src/mac/region/RegionCN470.c b/src/mac/region/RegionCN470.c index 38ee560cd..a3c5789d0 100644 --- a/src/mac/region/RegionCN470.c +++ b/src/mac/region/RegionCN470.c @@ -28,8 +28,7 @@ * * \author Daniel Jaeckle ( STACKFORCE ) */ -#include "utilities.h" - +#include "radio.h" #include "RegionCommon.h" #include "RegionCN470.h" #include "RegionBaseUS.h" @@ -37,33 +36,11 @@ // Definitions #define CHANNELS_MASK_SIZE 6 -/*! - * Region specific context - */ -typedef struct sRegionCN470NvmCtx -{ - /*! - * LoRaMAC channels - */ - ChannelParams_t Channels[ CN470_MAX_NB_CHANNELS ]; - /*! - * LoRaMac bands - */ - Band_t Bands[ CN470_MAX_NB_BANDS ]; - /*! - * LoRaMac channels mask - */ - uint16_t ChannelsMask[ CHANNELS_MASK_SIZE ]; - /*! - * LoRaMac channels default mask - */ - uint16_t ChannelsDefaultMask[ CHANNELS_MASK_SIZE ]; -}RegionCN470NvmCtx_t; - /* * Non-volatile module context. */ -static RegionCN470NvmCtx_t NvmCtx; +static RegionNvmDataGroup1_t* RegionNvmGroup1; +static RegionNvmDataGroup2_t* RegionNvmGroup2; // Static functions static bool VerifyRfFreq( uint32_t freq ) @@ -127,8 +104,8 @@ PhyParam_t RegionCN470GetPhyParam( GetPhyParams_t* getPhy ) .MaxDr = ( int8_t )CN470_TX_MAX_DATARATE, .MinDr = ( int8_t )CN470_TX_MIN_DATARATE, .NbChannels = CN470_MAX_NB_CHANNELS, - .ChannelsMask = NvmCtx.ChannelsMask, - .Channels = NvmCtx.Channels, + .ChannelsMask = RegionNvmGroup2->ChannelsMask, + .Channels = RegionNvmGroup2->Channels, }; phyParam.Value = RegionCommonGetNextLowerTxDr( &nextLowerTxDrParams ); break; @@ -215,12 +192,12 @@ PhyParam_t RegionCN470GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsMask; break; } case PHY_CHANNELS_DEFAULT_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsDefaultMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsDefaultMask; break; } case PHY_MAX_NB_CHANNELS: @@ -230,7 +207,7 @@ PhyParam_t RegionCN470GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS: { - phyParam.Channels = NvmCtx.Channels; + phyParam.Channels = RegionNvmGroup2->Channels; break; } case PHY_DEF_UPLINK_DWELL_TIME: @@ -315,7 +292,7 @@ PhyParam_t RegionCN470GetPhyParam( GetPhyParams_t* getPhy ) void RegionCN470SetBandTxDone( SetBandTxDoneParams_t* txDone ) { - RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], + RegionCommonSetBandTxDone( &RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txDone->Channel].Band], txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp ); } @@ -330,28 +307,36 @@ void RegionCN470InitDefaults( InitDefaultsParams_t* params ) { case INIT_TYPE_DEFAULTS: { + if( ( params->NvmGroup1 == NULL ) || ( params->NvmGroup2 == NULL ) ) + { + return; + } + + RegionNvmGroup1 = (RegionNvmDataGroup1_t*) params->NvmGroup1; + RegionNvmGroup2 = (RegionNvmDataGroup2_t*) params->NvmGroup2; + // Default bands - memcpy1( ( uint8_t* )NvmCtx.Bands, ( uint8_t* )bands, sizeof( Band_t ) * CN470_MAX_NB_BANDS ); + memcpy1( ( uint8_t* )RegionNvmGroup1->Bands, ( uint8_t* )bands, sizeof( Band_t ) * CN470_MAX_NB_BANDS ); // Default channels for( uint8_t i = 0; i < CN470_MAX_NB_CHANNELS; i++ ) { // 125 kHz channels - NvmCtx.Channels[i].Frequency = 470300000 + i * 200000; - NvmCtx.Channels[i].DrRange.Value = ( DR_5 << 4 ) | DR_0; - NvmCtx.Channels[i].Band = 0; + RegionNvmGroup2->Channels[i].Frequency = 470300000 + i * 200000; + RegionNvmGroup2->Channels[i].DrRange.Value = ( DR_5 << 4 ) | DR_0; + RegionNvmGroup2->Channels[i].Band = 0; } // Default ChannelsMask - NvmCtx.ChannelsDefaultMask[0] = 0xFFFF; - NvmCtx.ChannelsDefaultMask[1] = 0xFFFF; - NvmCtx.ChannelsDefaultMask[2] = 0xFFFF; - NvmCtx.ChannelsDefaultMask[3] = 0xFFFF; - NvmCtx.ChannelsDefaultMask[4] = 0xFFFF; - NvmCtx.ChannelsDefaultMask[5] = 0xFFFF; + RegionNvmGroup2->ChannelsDefaultMask[0] = 0xFFFF; + RegionNvmGroup2->ChannelsDefaultMask[1] = 0xFFFF; + RegionNvmGroup2->ChannelsDefaultMask[2] = 0xFFFF; + RegionNvmGroup2->ChannelsDefaultMask[3] = 0xFFFF; + RegionNvmGroup2->ChannelsDefaultMask[4] = 0xFFFF; + RegionNvmGroup2->ChannelsDefaultMask[5] = 0xFFFF; // Copy channels default mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); break; } case INIT_TYPE_RESET_TO_DEFAULT_CHANNELS: @@ -361,15 +346,7 @@ void RegionCN470InitDefaults( InitDefaultsParams_t* params ) case INIT_TYPE_ACTIVATE_DEFAULT_CHANNELS: { // Copy channels default mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); - break; - } - case INIT_TYPE_RESTORE_CTX: - { - if( params->NvmCtx != 0 ) - { - memcpy1( (uint8_t*) &NvmCtx, (uint8_t*) params->NvmCtx, sizeof( NvmCtx ) ); - } + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); break; } default: @@ -379,12 +356,6 @@ void RegionCN470InitDefaults( InitDefaultsParams_t* params ) } } -void* RegionCN470GetNvmCtx( GetNvmCtxParams_t* params ) -{ - params->nvmCtxSize = sizeof( RegionCN470NvmCtx_t ); - return &NvmCtx; -} - bool RegionCN470Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) { switch( phyAttribute ) @@ -434,8 +405,8 @@ void RegionCN470ApplyCFList( ApplyCFListParams_t* applyCFList ) // ChMask0 - ChMask5 must be set (every ChMask has 16 bit) for( uint8_t chMaskItr = 0, cntPayload = 0; chMaskItr <= 5; chMaskItr++, cntPayload+=2 ) { - NvmCtx.ChannelsMask[chMaskItr] = (uint16_t) (0x00FF & applyCFList->Payload[cntPayload]); - NvmCtx.ChannelsMask[chMaskItr] |= (uint16_t) (applyCFList->Payload[cntPayload+1] << 8); + RegionNvmGroup2->ChannelsMask[chMaskItr] = (uint16_t) (0x00FF & applyCFList->Payload[cntPayload]); + RegionNvmGroup2->ChannelsMask[chMaskItr] |= (uint16_t) (applyCFList->Payload[cntPayload+1] << 8); } } @@ -445,12 +416,12 @@ bool RegionCN470ChanMaskSet( ChanMaskSetParams_t* chanMaskSet ) { case CHANNELS_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, chanMaskSet->ChannelsMaskIn, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, chanMaskSet->ChannelsMaskIn, CHANNELS_MASK_SIZE ); break; } case CHANNELS_DEFAULT_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, CHANNELS_MASK_SIZE ); break; } default: @@ -506,7 +477,7 @@ bool RegionCN470RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) bool RegionCN470TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir ) { int8_t phyDr = DataratesCN470[txConfig->Datarate]; - int8_t txPowerLimited = RegionCommonLimitTxPower( txConfig->TxPower, NvmCtx.Bands[NvmCtx.Channels[txConfig->Channel].Band].TxMaxPower ); + int8_t txPowerLimited = RegionCommonLimitTxPower( txConfig->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txConfig->Channel].Band].TxMaxPower ); uint32_t bandwidth = RegionCommonGetBandwidth( txConfig->Datarate, BandwidthsCN470 ); int8_t phyTxPower = 0; @@ -514,7 +485,7 @@ bool RegionCN470TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime phyTxPower = RegionCommonComputeTxPower( txPowerLimited, txConfig->MaxEirp, txConfig->AntennaGain ); // Setup the radio frequency - Radio.SetChannel( NvmCtx.Channels[txConfig->Channel].Frequency ); + Radio.SetChannel( RegionNvmGroup2->Channels[txConfig->Channel].Frequency ); Radio.SetTxConfig( MODEM_LORA, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 4000 ); @@ -540,7 +511,7 @@ uint8_t RegionCN470LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in RegionCommonLinkAdrReqVerifyParams_t linkAdrVerifyParams; // Initialize local copy of channels mask - RegionCommonChanMaskCopy( channelsMask, NvmCtx.ChannelsMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( channelsMask, RegionNvmGroup2->ChannelsMask, CHANNELS_MASK_SIZE ); while( bytesProcessed < linkAdrReq->PayloadSize ) { @@ -575,7 +546,7 @@ uint8_t RegionCN470LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in for( uint8_t i = 0; i < 16; i++ ) { if( ( ( linkAdrParams.ChMask & ( 1 << i ) ) != 0 ) && - ( NvmCtx.Channels[linkAdrParams.ChMaskCtrl * 16 + i].Frequency == 0 ) ) + ( RegionNvmGroup2->Channels[linkAdrParams.ChMaskCtrl * 16 + i].Frequency == 0 ) ) {// Trying to enable an undefined channel status &= 0xFE; // Channel mask KO } @@ -601,7 +572,7 @@ uint8_t RegionCN470LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in linkAdrVerifyParams.ChannelsMask = channelsMask; linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value; linkAdrVerifyParams.MaxDatarate = CN470_TX_MAX_DATARATE; - linkAdrVerifyParams.Channels = NvmCtx.Channels; + linkAdrVerifyParams.Channels = RegionNvmGroup2->Channels; linkAdrVerifyParams.MinTxPower = CN470_MIN_TX_POWER; linkAdrVerifyParams.MaxTxPower = CN470_MAX_TX_POWER; linkAdrVerifyParams.Version = linkAdrReq->Version; @@ -613,7 +584,7 @@ uint8_t RegionCN470LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in if( status == 0x07 ) { // Copy Mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, channelsMask, 6 ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, channelsMask, 6 ); } // Update status variables @@ -683,22 +654,22 @@ LoRaMacStatus_t RegionCN470NextChannel( NextChanParams_t* nextChanParams, uint8_ LoRaMacStatus_t status = LORAMAC_STATUS_NO_CHANNEL_FOUND; // Count 125kHz channels - if( RegionCommonCountChannels( NvmCtx.ChannelsMask, 0, CHANNELS_MASK_SIZE ) == 0 ) + if( RegionCommonCountChannels( RegionNvmGroup2->ChannelsMask, 0, CHANNELS_MASK_SIZE ) == 0 ) { // Reactivate default channels - NvmCtx.ChannelsMask[0] = 0xFFFF; - NvmCtx.ChannelsMask[1] = 0xFFFF; - NvmCtx.ChannelsMask[2] = 0xFFFF; - NvmCtx.ChannelsMask[3] = 0xFFFF; - NvmCtx.ChannelsMask[4] = 0xFFFF; - NvmCtx.ChannelsMask[5] = 0xFFFF; + RegionNvmGroup2->ChannelsMask[0] = 0xFFFF; + RegionNvmGroup2->ChannelsMask[1] = 0xFFFF; + RegionNvmGroup2->ChannelsMask[2] = 0xFFFF; + RegionNvmGroup2->ChannelsMask[3] = 0xFFFF; + RegionNvmGroup2->ChannelsMask[4] = 0xFFFF; + RegionNvmGroup2->ChannelsMask[5] = 0xFFFF; } // Search how many channels are enabled countChannelsParams.Joined = nextChanParams->Joined; countChannelsParams.Datarate = nextChanParams->Datarate; - countChannelsParams.ChannelsMask = NvmCtx.ChannelsMask; - countChannelsParams.Channels = NvmCtx.Channels; - countChannelsParams.Bands = NvmCtx.Bands; + countChannelsParams.ChannelsMask = RegionNvmGroup2->ChannelsMask; + countChannelsParams.Channels = RegionNvmGroup2->Channels; + countChannelsParams.Bands = RegionNvmGroup1->Bands; countChannelsParams.MaxNbChannels = CN470_MAX_NB_CHANNELS; countChannelsParams.JoinChannels = NULL; @@ -736,9 +707,9 @@ bool RegionCN470ChannelsRemove( ChannelRemoveParams_t* channelRemove ) void RegionCN470SetContinuousWave( ContinuousWaveParams_t* continuousWave ) { - int8_t txPowerLimited = RegionCommonLimitTxPower( continuousWave->TxPower, NvmCtx.Bands[NvmCtx.Channels[continuousWave->Channel].Band].TxMaxPower ); + int8_t txPowerLimited = RegionCommonLimitTxPower( continuousWave->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[continuousWave->Channel].Band].TxMaxPower ); int8_t phyTxPower = 0; - uint32_t frequency = NvmCtx.Channels[continuousWave->Channel].Frequency; + uint32_t frequency = RegionNvmGroup2->Channels[continuousWave->Channel].Frequency; // Calculate physical TX power phyTxPower = RegionCommonComputeTxPower( txPowerLimited, continuousWave->MaxEirp, continuousWave->AntennaGain ); diff --git a/src/mac/region/RegionCN470.h b/src/mac/region/RegionCN470.h index 4c45e9bdb..7cdab903a 100644 --- a/src/mac/region/RegionCN470.h +++ b/src/mac/region/RegionCN470.h @@ -251,15 +251,6 @@ void RegionCN470SetBandTxDone( SetBandTxDoneParams_t* txDone ); */ void RegionCN470InitDefaults( InitDefaultsParams_t* params ); -/*! - * \brief Returns a pointer to the internal context and its size. - * - * \param [OUT] params Pointer to the function parameters. - * - * \retval Points to a structure where the module store its non-volatile context. - */ -void* RegionCN470GetNvmCtx( GetNvmCtxParams_t* params ); - /*! * \brief Verifies a parameter. * diff --git a/src/mac/region/RegionCN779.c b/src/mac/region/RegionCN779.c index 9a2317991..583a87293 100644 --- a/src/mac/region/RegionCN779.c +++ b/src/mac/region/RegionCN779.c @@ -28,41 +28,18 @@ * * \author Daniel Jaeckle ( STACKFORCE ) */ -#include "utilities.h" - +#include "radio.h" #include "RegionCommon.h" #include "RegionCN779.h" // Definitions #define CHANNELS_MASK_SIZE 1 -/*! - * Region specific context - */ -typedef struct sRegionCN779NvmCtx -{ - /*! - * LoRaMAC channels - */ - ChannelParams_t Channels[ CN779_MAX_NB_CHANNELS ]; - /*! - * LoRaMac bands - */ - Band_t Bands[ CN779_MAX_NB_BANDS ]; - /*! - * LoRaMac channels mask - */ - uint16_t ChannelsMask[ CHANNELS_MASK_SIZE ]; - /*! - * LoRaMac channels default mask - */ - uint16_t ChannelsDefaultMask[ CHANNELS_MASK_SIZE ]; -}RegionCN779NvmCtx_t; - /* * Non-volatile module context. */ -static RegionCN779NvmCtx_t NvmCtx; +static RegionNvmDataGroup1_t* RegionNvmGroup1; +static RegionNvmDataGroup2_t* RegionNvmGroup2; // Static functions static bool VerifyRfFreq( uint32_t freq ) @@ -126,8 +103,8 @@ PhyParam_t RegionCN779GetPhyParam( GetPhyParams_t* getPhy ) .MaxDr = ( int8_t )CN779_TX_MAX_DATARATE, .MinDr = ( int8_t )CN779_TX_MIN_DATARATE, .NbChannels = CN779_MAX_NB_CHANNELS, - .ChannelsMask = NvmCtx.ChannelsMask, - .Channels = NvmCtx.Channels, + .ChannelsMask = RegionNvmGroup2->ChannelsMask, + .Channels = RegionNvmGroup2->Channels, }; phyParam.Value = RegionCommonGetNextLowerTxDr( &nextLowerTxDrParams ); break; @@ -214,12 +191,12 @@ PhyParam_t RegionCN779GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsMask; break; } case PHY_CHANNELS_DEFAULT_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsDefaultMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsDefaultMask; break; } case PHY_MAX_NB_CHANNELS: @@ -229,7 +206,7 @@ PhyParam_t RegionCN779GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS: { - phyParam.Channels = NvmCtx.Channels; + phyParam.Channels = RegionNvmGroup2->Channels; break; } case PHY_DEF_UPLINK_DWELL_TIME: @@ -300,7 +277,7 @@ PhyParam_t RegionCN779GetPhyParam( GetPhyParams_t* getPhy ) void RegionCN779SetBandTxDone( SetBandTxDoneParams_t* txDone ) { - RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], + RegionCommonSetBandTxDone( &RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txDone->Channel].Band], txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp ); } @@ -315,43 +292,43 @@ void RegionCN779InitDefaults( InitDefaultsParams_t* params ) { case INIT_TYPE_DEFAULTS: { + if( ( params->NvmGroup1 == NULL ) || ( params->NvmGroup2 == NULL ) ) + { + return; + } + + RegionNvmGroup1 = (RegionNvmDataGroup1_t*) params->NvmGroup1; + RegionNvmGroup2 = (RegionNvmDataGroup2_t*) params->NvmGroup2; + // Default bands - memcpy1( ( uint8_t* )NvmCtx.Bands, ( uint8_t* )bands, sizeof( Band_t ) * CN779_MAX_NB_BANDS ); + memcpy1( ( uint8_t* )RegionNvmGroup1->Bands, ( uint8_t* )bands, sizeof( Band_t ) * CN779_MAX_NB_BANDS ); // Default channels - NvmCtx.Channels[0] = ( ChannelParams_t ) CN779_LC1; - NvmCtx.Channels[1] = ( ChannelParams_t ) CN779_LC2; - NvmCtx.Channels[2] = ( ChannelParams_t ) CN779_LC3; + RegionNvmGroup2->Channels[0] = ( ChannelParams_t ) CN779_LC1; + RegionNvmGroup2->Channels[1] = ( ChannelParams_t ) CN779_LC2; + RegionNvmGroup2->Channels[2] = ( ChannelParams_t ) CN779_LC3; // Default ChannelsMask - NvmCtx.ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 ); + RegionNvmGroup2->ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 ); // Update the channels mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); break; } case INIT_TYPE_RESET_TO_DEFAULT_CHANNELS: { // Reset Channels Rx1Frequency to default 0 - NvmCtx.Channels[0].Rx1Frequency = 0; - NvmCtx.Channels[1].Rx1Frequency = 0; - NvmCtx.Channels[2].Rx1Frequency = 0; + RegionNvmGroup2->Channels[0].Rx1Frequency = 0; + RegionNvmGroup2->Channels[1].Rx1Frequency = 0; + RegionNvmGroup2->Channels[2].Rx1Frequency = 0; // Update the channels mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); break; } case INIT_TYPE_ACTIVATE_DEFAULT_CHANNELS: { // Restore channels default mask - NvmCtx.ChannelsMask[0] |= NvmCtx.ChannelsDefaultMask[0]; - break; - } - case INIT_TYPE_RESTORE_CTX: - { - if( params->NvmCtx != 0 ) - { - memcpy1( (uint8_t*) &NvmCtx, (uint8_t*) params->NvmCtx, sizeof( NvmCtx ) ); - } + RegionNvmGroup2->ChannelsMask[0] |= RegionNvmGroup2->ChannelsDefaultMask[0]; break; } default: @@ -361,12 +338,6 @@ void RegionCN779InitDefaults( InitDefaultsParams_t* params ) } } -void* RegionCN779GetNvmCtx( GetNvmCtxParams_t* params ) -{ - params->nvmCtxSize = sizeof( RegionCN779NvmCtx_t ); - return &NvmCtx; -} - bool RegionCN779Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) { switch( phyAttribute ) @@ -467,12 +438,12 @@ bool RegionCN779ChanMaskSet( ChanMaskSetParams_t* chanMaskSet ) { case CHANNELS_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, chanMaskSet->ChannelsMaskIn, 1 ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, chanMaskSet->ChannelsMaskIn, 1 ); break; } case CHANNELS_DEFAULT_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 1 ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 1 ); break; } default: @@ -516,11 +487,11 @@ bool RegionCN779RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) if( rxConfig->RxSlot == RX_SLOT_WIN_1 ) { // Apply window 1 frequency - frequency = NvmCtx.Channels[rxConfig->Channel].Frequency; + frequency = RegionNvmGroup2->Channels[rxConfig->Channel].Frequency; // Apply the alternative RX 1 window frequency, if it is available - if( NvmCtx.Channels[rxConfig->Channel].Rx1Frequency != 0 ) + if( RegionNvmGroup2->Channels[rxConfig->Channel].Rx1Frequency != 0 ) { - frequency = NvmCtx.Channels[rxConfig->Channel].Rx1Frequency; + frequency = RegionNvmGroup2->Channels[rxConfig->Channel].Rx1Frequency; } } @@ -551,7 +522,7 @@ bool RegionCN779TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime { RadioModems_t modem; int8_t phyDr = DataratesCN779[txConfig->Datarate]; - int8_t txPowerLimited = RegionCommonLimitTxPower( txConfig->TxPower, NvmCtx.Bands[NvmCtx.Channels[txConfig->Channel].Band].TxMaxPower ); + int8_t txPowerLimited = RegionCommonLimitTxPower( txConfig->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txConfig->Channel].Band].TxMaxPower ); uint32_t bandwidth = RegionCommonGetBandwidth( txConfig->Datarate, BandwidthsCN779 ); int8_t phyTxPower = 0; @@ -559,7 +530,7 @@ bool RegionCN779TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime phyTxPower = RegionCommonComputeTxPower( txPowerLimited, txConfig->MaxEirp, txConfig->AntennaGain ); // Setup the radio frequency - Radio.SetChannel( NvmCtx.Channels[txConfig->Channel].Frequency ); + Radio.SetChannel( RegionNvmGroup2->Channels[txConfig->Channel].Frequency ); if( txConfig->Datarate == DR_7 ) { // High Speed FSK channel @@ -627,7 +598,7 @@ uint8_t RegionCN779LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in { if( linkAdrParams.ChMaskCtrl == 6 ) { - if( NvmCtx.Channels[i].Frequency != 0 ) + if( RegionNvmGroup2->Channels[i].Frequency != 0 ) { chMask |= 1 << i; } @@ -635,7 +606,7 @@ uint8_t RegionCN779LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in else { if( ( ( chMask & ( 1 << i ) ) != 0 ) && - ( NvmCtx.Channels[i].Frequency == 0 ) ) + ( RegionNvmGroup2->Channels[i].Frequency == 0 ) ) {// Trying to enable an undefined channel status &= 0xFE; // Channel mask KO } @@ -661,7 +632,7 @@ uint8_t RegionCN779LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in linkAdrVerifyParams.ChannelsMask = &chMask; linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value; linkAdrVerifyParams.MaxDatarate = CN779_TX_MAX_DATARATE; - linkAdrVerifyParams.Channels = NvmCtx.Channels; + linkAdrVerifyParams.Channels = RegionNvmGroup2->Channels; linkAdrVerifyParams.MinTxPower = CN779_MIN_TX_POWER; linkAdrVerifyParams.MaxTxPower = CN779_MAX_TX_POWER; linkAdrVerifyParams.Version = linkAdrReq->Version; @@ -673,9 +644,9 @@ uint8_t RegionCN779LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in if( status == 0x07 ) { // Set the channels mask to a default value - memset1( ( uint8_t* ) NvmCtx.ChannelsMask, 0, sizeof( NvmCtx.ChannelsMask ) ); + memset1( ( uint8_t* ) RegionNvmGroup2->ChannelsMask, 0, sizeof( RegionNvmGroup2->ChannelsMask ) ); // Update the channels mask - NvmCtx.ChannelsMask[0] = chMask; + RegionNvmGroup2->ChannelsMask[0] = chMask; } // Update status variables @@ -782,7 +753,7 @@ int8_t RegionCN779DlChannelReq( DlChannelReqParams_t* dlChannelReq ) } // Verify if an uplink frequency exists - if( NvmCtx.Channels[dlChannelReq->ChannelId].Frequency == 0 ) + if( RegionNvmGroup2->Channels[dlChannelReq->ChannelId].Frequency == 0 ) { status &= 0xFD; } @@ -790,7 +761,7 @@ int8_t RegionCN779DlChannelReq( DlChannelReqParams_t* dlChannelReq ) // Apply Rx1 frequency, if the status is OK if( status == 0x03 ) { - NvmCtx.Channels[dlChannelReq->ChannelId].Rx1Frequency = dlChannelReq->Rx1Frequency; + RegionNvmGroup2->Channels[dlChannelReq->ChannelId].Rx1Frequency = dlChannelReq->Rx1Frequency; } return status; @@ -811,17 +782,17 @@ LoRaMacStatus_t RegionCN779NextChannel( NextChanParams_t* nextChanParams, uint8_ LoRaMacStatus_t status = LORAMAC_STATUS_NO_CHANNEL_FOUND; uint16_t joinChannels = CN779_JOIN_CHANNELS; - if( RegionCommonCountChannels( NvmCtx.ChannelsMask, 0, 1 ) == 0 ) + if( RegionCommonCountChannels( RegionNvmGroup2->ChannelsMask, 0, 1 ) == 0 ) { // Reactivate default channels - NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); + RegionNvmGroup2->ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); } // Search how many channels are enabled countChannelsParams.Joined = nextChanParams->Joined; countChannelsParams.Datarate = nextChanParams->Datarate; - countChannelsParams.ChannelsMask = NvmCtx.ChannelsMask; - countChannelsParams.Channels = NvmCtx.Channels; - countChannelsParams.Bands = NvmCtx.Bands; + countChannelsParams.ChannelsMask = RegionNvmGroup2->ChannelsMask; + countChannelsParams.Channels = RegionNvmGroup2->Channels; + countChannelsParams.Bands = RegionNvmGroup1->Bands; countChannelsParams.MaxNbChannels = CN779_MAX_NB_CHANNELS; countChannelsParams.JoinChannels = &joinChannels; @@ -847,7 +818,7 @@ LoRaMacStatus_t RegionCN779NextChannel( NextChanParams_t* nextChanParams, uint8_ else if( status == LORAMAC_STATUS_NO_CHANNEL_FOUND ) { // Datarate not supported by any channel, restore defaults - NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); + RegionNvmGroup2->ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); } return status; } @@ -905,9 +876,9 @@ LoRaMacStatus_t RegionCN779ChannelAdd( ChannelAddParams_t* channelAdd ) return LORAMAC_STATUS_FREQUENCY_INVALID; } - memcpy1( ( uint8_t* ) &(NvmCtx.Channels[id]), ( uint8_t* ) channelAdd->NewChannel, sizeof( NvmCtx.Channels[id] ) ); - NvmCtx.Channels[id].Band = 0; - NvmCtx.ChannelsMask[0] |= ( 1 << id ); + memcpy1( ( uint8_t* ) &(RegionNvmGroup2->Channels[id]), ( uint8_t* ) channelAdd->NewChannel, sizeof( RegionNvmGroup2->Channels[id] ) ); + RegionNvmGroup2->Channels[id].Band = 0; + RegionNvmGroup2->ChannelsMask[0] |= ( 1 << id ); return LORAMAC_STATUS_OK; } @@ -921,16 +892,16 @@ bool RegionCN779ChannelsRemove( ChannelRemoveParams_t* channelRemove ) } // Remove the channel from the list of channels - NvmCtx.Channels[id] = ( ChannelParams_t ){ 0, 0, { 0 }, 0 }; + RegionNvmGroup2->Channels[id] = ( ChannelParams_t ){ 0, 0, { 0 }, 0 }; - return RegionCommonChanDisable( NvmCtx.ChannelsMask, id, CN779_MAX_NB_CHANNELS ); + return RegionCommonChanDisable( RegionNvmGroup2->ChannelsMask, id, CN779_MAX_NB_CHANNELS ); } void RegionCN779SetContinuousWave( ContinuousWaveParams_t* continuousWave ) { - int8_t txPowerLimited = RegionCommonLimitTxPower( continuousWave->TxPower, NvmCtx.Bands[NvmCtx.Channels[continuousWave->Channel].Band].TxMaxPower ); + int8_t txPowerLimited = RegionCommonLimitTxPower( continuousWave->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[continuousWave->Channel].Band].TxMaxPower ); int8_t phyTxPower = 0; - uint32_t frequency = NvmCtx.Channels[continuousWave->Channel].Frequency; + uint32_t frequency = RegionNvmGroup2->Channels[continuousWave->Channel].Frequency; // Calculate physical TX power phyTxPower = RegionCommonComputeTxPower( txPowerLimited, continuousWave->MaxEirp, continuousWave->AntennaGain ); diff --git a/src/mac/region/RegionCN779.h b/src/mac/region/RegionCN779.h index 1d08dece1..467038ccd 100644 --- a/src/mac/region/RegionCN779.h +++ b/src/mac/region/RegionCN779.h @@ -265,15 +265,6 @@ void RegionCN779SetBandTxDone( SetBandTxDoneParams_t* txDone ); */ void RegionCN779InitDefaults( InitDefaultsParams_t* params ); -/*! - * \brief Returns a pointer to the internal context and its size. - * - * \param [OUT] params Pointer to the function parameters. - * - * \retval Points to a structure where the module store its non-volatile context. - */ -void* RegionCN779GetNvmCtx( GetNvmCtxParams_t* params ); - /*! * \brief Verifies a parameter. * diff --git a/src/mac/region/RegionEU433.c b/src/mac/region/RegionEU433.c index 3cef31f75..8398750c2 100644 --- a/src/mac/region/RegionEU433.c +++ b/src/mac/region/RegionEU433.c @@ -28,41 +28,18 @@ * * \author Daniel Jaeckle ( STACKFORCE ) */ -#include "utilities.h" - +#include "radio.h" #include "RegionCommon.h" #include "RegionEU433.h" // Definitions #define CHANNELS_MASK_SIZE 1 -/*! - * Region specific context - */ -typedef struct sRegionEU433NvmCtx -{ - /*! - * LoRaMAC channels - */ - ChannelParams_t Channels[ EU433_MAX_NB_CHANNELS ]; - /*! - * LoRaMac bands - */ - Band_t Bands[ EU433_MAX_NB_BANDS ]; - /*! - * LoRaMac channels mask - */ - uint16_t ChannelsMask[ CHANNELS_MASK_SIZE ]; - /*! - * LoRaMac channels default mask - */ - uint16_t ChannelsDefaultMask[ CHANNELS_MASK_SIZE ]; -}RegionEU433NvmCtx_t; - /* * Non-volatile module context. */ -static RegionEU433NvmCtx_t NvmCtx; +static RegionNvmDataGroup1_t* RegionNvmGroup1; +static RegionNvmDataGroup2_t* RegionNvmGroup2; // Static functions static bool VerifyRfFreq( uint32_t freq ) @@ -126,8 +103,8 @@ PhyParam_t RegionEU433GetPhyParam( GetPhyParams_t* getPhy ) .MaxDr = ( int8_t )EU433_TX_MAX_DATARATE, .MinDr = ( int8_t )EU433_TX_MIN_DATARATE, .NbChannels = EU433_MAX_NB_CHANNELS, - .ChannelsMask = NvmCtx.ChannelsMask, - .Channels = NvmCtx.Channels, + .ChannelsMask = RegionNvmGroup2->ChannelsMask, + .Channels = RegionNvmGroup2->Channels, }; phyParam.Value = RegionCommonGetNextLowerTxDr( &nextLowerTxDrParams ); break; @@ -214,12 +191,12 @@ PhyParam_t RegionEU433GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsMask; break; } case PHY_CHANNELS_DEFAULT_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsDefaultMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsDefaultMask; break; } case PHY_MAX_NB_CHANNELS: @@ -229,7 +206,7 @@ PhyParam_t RegionEU433GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS: { - phyParam.Channels = NvmCtx.Channels; + phyParam.Channels = RegionNvmGroup2->Channels; break; } case PHY_DEF_UPLINK_DWELL_TIME: @@ -300,7 +277,7 @@ PhyParam_t RegionEU433GetPhyParam( GetPhyParams_t* getPhy ) void RegionEU433SetBandTxDone( SetBandTxDoneParams_t* txDone ) { - RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], + RegionCommonSetBandTxDone( &RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txDone->Channel].Band], txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp ); } @@ -315,43 +292,43 @@ void RegionEU433InitDefaults( InitDefaultsParams_t* params ) { case INIT_TYPE_DEFAULTS: { + if( ( params->NvmGroup1 == NULL ) || ( params->NvmGroup2 == NULL ) ) + { + return; + } + + RegionNvmGroup1 = (RegionNvmDataGroup1_t*) params->NvmGroup1; + RegionNvmGroup2 = (RegionNvmDataGroup2_t*) params->NvmGroup2; + // Default bands - memcpy1( ( uint8_t* )NvmCtx.Bands, ( uint8_t* )bands, sizeof( Band_t ) * EU433_MAX_NB_BANDS ); + memcpy1( ( uint8_t* )RegionNvmGroup1->Bands, ( uint8_t* )bands, sizeof( Band_t ) * EU433_MAX_NB_BANDS ); // Default channels - NvmCtx.Channels[0] = ( ChannelParams_t ) EU433_LC1; - NvmCtx.Channels[1] = ( ChannelParams_t ) EU433_LC2; - NvmCtx.Channels[2] = ( ChannelParams_t ) EU433_LC3; + RegionNvmGroup2->Channels[0] = ( ChannelParams_t ) EU433_LC1; + RegionNvmGroup2->Channels[1] = ( ChannelParams_t ) EU433_LC2; + RegionNvmGroup2->Channels[2] = ( ChannelParams_t ) EU433_LC3; // Default ChannelsMask - NvmCtx.ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 ); + RegionNvmGroup2->ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 ); // Update the channels mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); break; } case INIT_TYPE_RESET_TO_DEFAULT_CHANNELS: { // Reset Channels Rx1Frequency to default 0 - NvmCtx.Channels[0].Rx1Frequency = 0; - NvmCtx.Channels[1].Rx1Frequency = 0; - NvmCtx.Channels[2].Rx1Frequency = 0; + RegionNvmGroup2->Channels[0].Rx1Frequency = 0; + RegionNvmGroup2->Channels[1].Rx1Frequency = 0; + RegionNvmGroup2->Channels[2].Rx1Frequency = 0; // Update the channels mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); break; } case INIT_TYPE_ACTIVATE_DEFAULT_CHANNELS: { // Restore channels default mask - NvmCtx.ChannelsMask[0] |= NvmCtx.ChannelsDefaultMask[0]; - break; - } - case INIT_TYPE_RESTORE_CTX: - { - if( params->NvmCtx != 0 ) - { - memcpy1( (uint8_t*) &NvmCtx, (uint8_t*) params->NvmCtx, sizeof( NvmCtx ) ); - } + RegionNvmGroup2->ChannelsMask[0] |= RegionNvmGroup2->ChannelsDefaultMask[0]; break; } default: @@ -361,12 +338,6 @@ void RegionEU433InitDefaults( InitDefaultsParams_t* params ) } } -void* RegionEU433GetNvmCtx( GetNvmCtxParams_t* params ) -{ - params->nvmCtxSize = sizeof( RegionEU433NvmCtx_t ); - return &NvmCtx; -} - bool RegionEU433Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) { switch( phyAttribute ) @@ -467,12 +438,12 @@ bool RegionEU433ChanMaskSet( ChanMaskSetParams_t* chanMaskSet ) { case CHANNELS_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, chanMaskSet->ChannelsMaskIn, 1 ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, chanMaskSet->ChannelsMaskIn, 1 ); break; } case CHANNELS_DEFAULT_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 1 ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 1 ); break; } default: @@ -516,11 +487,11 @@ bool RegionEU433RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) if( rxConfig->RxSlot == RX_SLOT_WIN_1 ) { // Apply window 1 frequency - frequency = NvmCtx.Channels[rxConfig->Channel].Frequency; + frequency = RegionNvmGroup2->Channels[rxConfig->Channel].Frequency; // Apply the alternative RX 1 window frequency, if it is available - if( NvmCtx.Channels[rxConfig->Channel].Rx1Frequency != 0 ) + if( RegionNvmGroup2->Channels[rxConfig->Channel].Rx1Frequency != 0 ) { - frequency = NvmCtx.Channels[rxConfig->Channel].Rx1Frequency; + frequency = RegionNvmGroup2->Channels[rxConfig->Channel].Rx1Frequency; } } @@ -551,7 +522,7 @@ bool RegionEU433TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime { RadioModems_t modem; int8_t phyDr = DataratesEU433[txConfig->Datarate]; - int8_t txPowerLimited = RegionCommonLimitTxPower( txConfig->TxPower, NvmCtx.Bands[NvmCtx.Channels[txConfig->Channel].Band].TxMaxPower ); + int8_t txPowerLimited = RegionCommonLimitTxPower( txConfig->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txConfig->Channel].Band].TxMaxPower ); uint32_t bandwidth = RegionCommonGetBandwidth( txConfig->Datarate, BandwidthsEU433 ); int8_t phyTxPower = 0; @@ -559,7 +530,7 @@ bool RegionEU433TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime phyTxPower = RegionCommonComputeTxPower( txPowerLimited, txConfig->MaxEirp, txConfig->AntennaGain ); // Setup the radio frequency - Radio.SetChannel( NvmCtx.Channels[txConfig->Channel].Frequency ); + Radio.SetChannel( RegionNvmGroup2->Channels[txConfig->Channel].Frequency ); if( txConfig->Datarate == DR_7 ) { // High Speed FSK channel @@ -627,7 +598,7 @@ uint8_t RegionEU433LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in { if( linkAdrParams.ChMaskCtrl == 6 ) { - if( NvmCtx.Channels[i].Frequency != 0 ) + if( RegionNvmGroup2->Channels[i].Frequency != 0 ) { chMask |= 1 << i; } @@ -635,7 +606,7 @@ uint8_t RegionEU433LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in else { if( ( ( chMask & ( 1 << i ) ) != 0 ) && - ( NvmCtx.Channels[i].Frequency == 0 ) ) + ( RegionNvmGroup2->Channels[i].Frequency == 0 ) ) {// Trying to enable an undefined channel status &= 0xFE; // Channel mask KO } @@ -661,7 +632,7 @@ uint8_t RegionEU433LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in linkAdrVerifyParams.ChannelsMask = &chMask; linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value; linkAdrVerifyParams.MaxDatarate = EU433_TX_MAX_DATARATE; - linkAdrVerifyParams.Channels = NvmCtx.Channels; + linkAdrVerifyParams.Channels = RegionNvmGroup2->Channels; linkAdrVerifyParams.MinTxPower = EU433_MIN_TX_POWER; linkAdrVerifyParams.MaxTxPower = EU433_MAX_TX_POWER; linkAdrVerifyParams.Version = linkAdrReq->Version; @@ -673,9 +644,9 @@ uint8_t RegionEU433LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in if( status == 0x07 ) { // Set the channels mask to a default value - memset1( ( uint8_t* ) NvmCtx.ChannelsMask, 0, sizeof( NvmCtx.ChannelsMask ) ); + memset1( ( uint8_t* ) RegionNvmGroup2->ChannelsMask, 0, sizeof( RegionNvmGroup2->ChannelsMask ) ); // Update the channels mask - NvmCtx.ChannelsMask[0] = chMask; + RegionNvmGroup2->ChannelsMask[0] = chMask; } // Update status variables @@ -782,7 +753,7 @@ int8_t RegionEU433DlChannelReq( DlChannelReqParams_t* dlChannelReq ) } // Verify if an uplink frequency exists - if( NvmCtx.Channels[dlChannelReq->ChannelId].Frequency == 0 ) + if( RegionNvmGroup2->Channels[dlChannelReq->ChannelId].Frequency == 0 ) { status &= 0xFD; } @@ -790,7 +761,7 @@ int8_t RegionEU433DlChannelReq( DlChannelReqParams_t* dlChannelReq ) // Apply Rx1 frequency, if the status is OK if( status == 0x03 ) { - NvmCtx.Channels[dlChannelReq->ChannelId].Rx1Frequency = dlChannelReq->Rx1Frequency; + RegionNvmGroup2->Channels[dlChannelReq->ChannelId].Rx1Frequency = dlChannelReq->Rx1Frequency; } return status; @@ -811,17 +782,17 @@ LoRaMacStatus_t RegionEU433NextChannel( NextChanParams_t* nextChanParams, uint8_ LoRaMacStatus_t status = LORAMAC_STATUS_NO_CHANNEL_FOUND; uint16_t joinChannels = EU433_JOIN_CHANNELS; - if( RegionCommonCountChannels( NvmCtx.ChannelsMask, 0, 1 ) == 0 ) + if( RegionCommonCountChannels( RegionNvmGroup2->ChannelsMask, 0, 1 ) == 0 ) { // Reactivate default channels - NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); + RegionNvmGroup2->ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); } // Search how many channels are enabled countChannelsParams.Joined = nextChanParams->Joined; countChannelsParams.Datarate = nextChanParams->Datarate; - countChannelsParams.ChannelsMask = NvmCtx.ChannelsMask; - countChannelsParams.Channels = NvmCtx.Channels; - countChannelsParams.Bands = NvmCtx.Bands; + countChannelsParams.ChannelsMask = RegionNvmGroup2->ChannelsMask; + countChannelsParams.Channels = RegionNvmGroup2->Channels; + countChannelsParams.Bands = RegionNvmGroup1->Bands; countChannelsParams.MaxNbChannels = EU433_MAX_NB_CHANNELS; countChannelsParams.JoinChannels = &joinChannels; @@ -847,7 +818,7 @@ LoRaMacStatus_t RegionEU433NextChannel( NextChanParams_t* nextChanParams, uint8_ else if( status == LORAMAC_STATUS_NO_CHANNEL_FOUND ) { // Datarate not supported by any channel, restore defaults - NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); + RegionNvmGroup2->ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); } return status; } @@ -905,9 +876,9 @@ LoRaMacStatus_t RegionEU433ChannelAdd( ChannelAddParams_t* channelAdd ) return LORAMAC_STATUS_FREQUENCY_INVALID; } - memcpy1( ( uint8_t* ) &(NvmCtx.Channels[id]), ( uint8_t* ) channelAdd->NewChannel, sizeof( NvmCtx.Channels[id] ) ); - NvmCtx.Channels[id].Band = 0; - NvmCtx.ChannelsMask[0] |= ( 1 << id ); + memcpy1( ( uint8_t* ) &(RegionNvmGroup2->Channels[id]), ( uint8_t* ) channelAdd->NewChannel, sizeof( RegionNvmGroup2->Channels[id] ) ); + RegionNvmGroup2->Channels[id].Band = 0; + RegionNvmGroup2->ChannelsMask[0] |= ( 1 << id ); return LORAMAC_STATUS_OK; } @@ -921,16 +892,16 @@ bool RegionEU433ChannelsRemove( ChannelRemoveParams_t* channelRemove ) } // Remove the channel from the list of channels - NvmCtx.Channels[id] = ( ChannelParams_t ){ 0, 0, { 0 }, 0 }; + RegionNvmGroup2->Channels[id] = ( ChannelParams_t ){ 0, 0, { 0 }, 0 }; - return RegionCommonChanDisable( NvmCtx.ChannelsMask, id, EU433_MAX_NB_CHANNELS ); + return RegionCommonChanDisable( RegionNvmGroup2->ChannelsMask, id, EU433_MAX_NB_CHANNELS ); } void RegionEU433SetContinuousWave( ContinuousWaveParams_t* continuousWave ) { - int8_t txPowerLimited = RegionCommonLimitTxPower( continuousWave->TxPower, NvmCtx.Bands[NvmCtx.Channels[continuousWave->Channel].Band].TxMaxPower ); + int8_t txPowerLimited = RegionCommonLimitTxPower( continuousWave->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[continuousWave->Channel].Band].TxMaxPower ); int8_t phyTxPower = 0; - uint32_t frequency = NvmCtx.Channels[continuousWave->Channel].Frequency; + uint32_t frequency = RegionNvmGroup2->Channels[continuousWave->Channel].Frequency; // Calculate physical TX power phyTxPower = RegionCommonComputeTxPower( txPowerLimited, continuousWave->MaxEirp, continuousWave->AntennaGain ); diff --git a/src/mac/region/RegionEU433.h b/src/mac/region/RegionEU433.h index 1aceda945..b56ff5237 100644 --- a/src/mac/region/RegionEU433.h +++ b/src/mac/region/RegionEU433.h @@ -266,15 +266,6 @@ void RegionEU433SetBandTxDone( SetBandTxDoneParams_t* txDone ); */ void RegionEU433InitDefaults( InitDefaultsParams_t* params ); -/*! - * \brief Returns a pointer to the internal context and its size. - * - * \param [OUT] params Pointer to the function parameters. - * - * \retval Points to a structure where the module store its non-volatile context. - */ -void* RegionEU433GetNvmCtx( GetNvmCtxParams_t* params ); - /*! * \brief Verifies a parameter. * diff --git a/src/mac/region/RegionEU868.c b/src/mac/region/RegionEU868.c index 3947215db..41cddfbbb 100644 --- a/src/mac/region/RegionEU868.c +++ b/src/mac/region/RegionEU868.c @@ -28,41 +28,18 @@ * * \author Daniel Jaeckle ( STACKFORCE ) */ -#include "utilities.h" - +#include "radio.h" #include "RegionCommon.h" #include "RegionEU868.h" // Definitions #define CHANNELS_MASK_SIZE 1 -/*! - * Region specific context - */ -typedef struct sRegionEU868NvmCtx -{ - /*! - * LoRaMAC channels - */ - ChannelParams_t Channels[ EU868_MAX_NB_CHANNELS ]; - /*! - * LoRaMac bands - */ - Band_t Bands[ EU868_MAX_NB_BANDS ]; - /*! - * LoRaMac channels mask - */ - uint16_t ChannelsMask[ CHANNELS_MASK_SIZE ]; - /*! - * LoRaMac channels default mask - */ - uint16_t ChannelsDefaultMask[ CHANNELS_MASK_SIZE ]; -}RegionEU868NvmCtx_t; - /* * Non-volatile module context. */ -static RegionEU868NvmCtx_t NvmCtx; +static RegionNvmDataGroup1_t* RegionNvmGroup1; +static RegionNvmDataGroup2_t* RegionNvmGroup2; // Static functions static bool VerifyRfFreq( uint32_t freq, uint8_t *band ) @@ -151,8 +128,8 @@ PhyParam_t RegionEU868GetPhyParam( GetPhyParams_t* getPhy ) .MaxDr = ( int8_t )EU868_TX_MAX_DATARATE, .MinDr = ( int8_t )EU868_TX_MIN_DATARATE, .NbChannels = EU868_MAX_NB_CHANNELS, - .ChannelsMask = NvmCtx.ChannelsMask, - .Channels = NvmCtx.Channels, + .ChannelsMask = RegionNvmGroup2->ChannelsMask, + .Channels = RegionNvmGroup2->Channels, }; phyParam.Value = RegionCommonGetNextLowerTxDr( &nextLowerTxDrParams ); break; @@ -239,12 +216,12 @@ PhyParam_t RegionEU868GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsMask; break; } case PHY_CHANNELS_DEFAULT_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsDefaultMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsDefaultMask; break; } case PHY_MAX_NB_CHANNELS: @@ -254,7 +231,7 @@ PhyParam_t RegionEU868GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS: { - phyParam.Channels = NvmCtx.Channels; + phyParam.Channels = RegionNvmGroup2->Channels; break; } case PHY_DEF_UPLINK_DWELL_TIME: @@ -325,7 +302,7 @@ PhyParam_t RegionEU868GetPhyParam( GetPhyParams_t* getPhy ) void RegionEU868SetBandTxDone( SetBandTxDoneParams_t* txDone ) { - RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], + RegionCommonSetBandTxDone( &RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txDone->Channel].Band], txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp ); } @@ -345,43 +322,43 @@ void RegionEU868InitDefaults( InitDefaultsParams_t* params ) { case INIT_TYPE_DEFAULTS: { + if( ( params->NvmGroup1 == NULL ) || ( params->NvmGroup2 == NULL ) ) + { + return; + } + + RegionNvmGroup1 = (RegionNvmDataGroup1_t*) params->NvmGroup1; + RegionNvmGroup2 = (RegionNvmDataGroup2_t*) params->NvmGroup2; + // Default bands - memcpy1( ( uint8_t* )NvmCtx.Bands, ( uint8_t* )bands, sizeof( Band_t ) * EU868_MAX_NB_BANDS ); + memcpy1( ( uint8_t* )RegionNvmGroup1->Bands, ( uint8_t* )bands, sizeof( Band_t ) * EU868_MAX_NB_BANDS ); // Default channels - NvmCtx.Channels[0] = ( ChannelParams_t ) EU868_LC1; - NvmCtx.Channels[1] = ( ChannelParams_t ) EU868_LC2; - NvmCtx.Channels[2] = ( ChannelParams_t ) EU868_LC3; + RegionNvmGroup2->Channels[0] = ( ChannelParams_t ) EU868_LC1; + RegionNvmGroup2->Channels[1] = ( ChannelParams_t ) EU868_LC2; + RegionNvmGroup2->Channels[2] = ( ChannelParams_t ) EU868_LC3; // Default ChannelsMask - NvmCtx.ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 ); + RegionNvmGroup2->ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 ); // Update the channels mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); break; } case INIT_TYPE_RESET_TO_DEFAULT_CHANNELS: { // Reset Channels Rx1Frequency to default 0 - NvmCtx.Channels[0].Rx1Frequency = 0; - NvmCtx.Channels[1].Rx1Frequency = 0; - NvmCtx.Channels[2].Rx1Frequency = 0; + RegionNvmGroup2->Channels[0].Rx1Frequency = 0; + RegionNvmGroup2->Channels[1].Rx1Frequency = 0; + RegionNvmGroup2->Channels[2].Rx1Frequency = 0; // Update the channels mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); break; } case INIT_TYPE_ACTIVATE_DEFAULT_CHANNELS: { // Restore channels default mask - NvmCtx.ChannelsMask[0] |= NvmCtx.ChannelsDefaultMask[0]; - break; - } - case INIT_TYPE_RESTORE_CTX: - { - if( params->NvmCtx != 0 ) - { - memcpy1( (uint8_t*) &NvmCtx, (uint8_t*) params->NvmCtx, sizeof( NvmCtx ) ); - } + RegionNvmGroup2->ChannelsMask[0] |= RegionNvmGroup2->ChannelsDefaultMask[0]; break; } default: @@ -391,12 +368,6 @@ void RegionEU868InitDefaults( InitDefaultsParams_t* params ) } } -void* RegionEU868GetNvmCtx( GetNvmCtxParams_t* params ) -{ - params->nvmCtxSize = sizeof( RegionEU868NvmCtx_t ); - return &NvmCtx; -} - bool RegionEU868Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) { switch( phyAttribute ) @@ -498,12 +469,12 @@ bool RegionEU868ChanMaskSet( ChanMaskSetParams_t* chanMaskSet ) { case CHANNELS_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, chanMaskSet->ChannelsMaskIn, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, chanMaskSet->ChannelsMaskIn, CHANNELS_MASK_SIZE ); break; } case CHANNELS_DEFAULT_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, CHANNELS_MASK_SIZE ); break; } default: @@ -547,11 +518,11 @@ bool RegionEU868RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) if( rxConfig->RxSlot == RX_SLOT_WIN_1 ) { // Apply window 1 frequency - frequency = NvmCtx.Channels[rxConfig->Channel].Frequency; + frequency = RegionNvmGroup2->Channels[rxConfig->Channel].Frequency; // Apply the alternative RX 1 window frequency, if it is available - if( NvmCtx.Channels[rxConfig->Channel].Rx1Frequency != 0 ) + if( RegionNvmGroup2->Channels[rxConfig->Channel].Rx1Frequency != 0 ) { - frequency = NvmCtx.Channels[rxConfig->Channel].Rx1Frequency; + frequency = RegionNvmGroup2->Channels[rxConfig->Channel].Rx1Frequency; } } @@ -582,7 +553,7 @@ bool RegionEU868TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime { RadioModems_t modem; int8_t phyDr = DataratesEU868[txConfig->Datarate]; - int8_t txPowerLimited = RegionCommonLimitTxPower( txConfig->TxPower, NvmCtx.Bands[NvmCtx.Channels[txConfig->Channel].Band].TxMaxPower ); + int8_t txPowerLimited = RegionCommonLimitTxPower( txConfig->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txConfig->Channel].Band].TxMaxPower ); uint32_t bandwidth = RegionCommonGetBandwidth( txConfig->Datarate, BandwidthsEU868 ); int8_t phyTxPower = 0; @@ -590,7 +561,7 @@ bool RegionEU868TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime phyTxPower = RegionCommonComputeTxPower( txPowerLimited, txConfig->MaxEirp, txConfig->AntennaGain ); // Setup the radio frequency - Radio.SetChannel( NvmCtx.Channels[txConfig->Channel].Frequency ); + Radio.SetChannel( RegionNvmGroup2->Channels[txConfig->Channel].Frequency ); if( txConfig->Datarate == DR_7 ) { // High Speed FSK channel @@ -658,7 +629,7 @@ uint8_t RegionEU868LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in { if( linkAdrParams.ChMaskCtrl == 6 ) { - if( NvmCtx.Channels[i].Frequency != 0 ) + if( RegionNvmGroup2->Channels[i].Frequency != 0 ) { chMask |= 1 << i; } @@ -666,7 +637,7 @@ uint8_t RegionEU868LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in else { if( ( ( chMask & ( 1 << i ) ) != 0 ) && - ( NvmCtx.Channels[i].Frequency == 0 ) ) + ( RegionNvmGroup2->Channels[i].Frequency == 0 ) ) {// Trying to enable an undefined channel status &= 0xFE; // Channel mask KO } @@ -692,7 +663,7 @@ uint8_t RegionEU868LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in linkAdrVerifyParams.ChannelsMask = &chMask; linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value; linkAdrVerifyParams.MaxDatarate = EU868_TX_MAX_DATARATE; - linkAdrVerifyParams.Channels = NvmCtx.Channels; + linkAdrVerifyParams.Channels = RegionNvmGroup2->Channels; linkAdrVerifyParams.MinTxPower = EU868_MIN_TX_POWER; linkAdrVerifyParams.MaxTxPower = EU868_MAX_TX_POWER; linkAdrVerifyParams.Version = linkAdrReq->Version; @@ -704,9 +675,9 @@ uint8_t RegionEU868LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in if( status == 0x07 ) { // Set the channels mask to a default value - memset1( ( uint8_t* ) NvmCtx.ChannelsMask, 0, sizeof( NvmCtx.ChannelsMask ) ); + memset1( ( uint8_t* ) RegionNvmGroup2->ChannelsMask, 0, sizeof( RegionNvmGroup2->ChannelsMask ) ); // Update the channels mask - NvmCtx.ChannelsMask[0] = chMask; + RegionNvmGroup2->ChannelsMask[0] = chMask; } // Update status variables @@ -815,7 +786,7 @@ int8_t RegionEU868DlChannelReq( DlChannelReqParams_t* dlChannelReq ) } // Verify if an uplink frequency exists - if( NvmCtx.Channels[dlChannelReq->ChannelId].Frequency == 0 ) + if( RegionNvmGroup2->Channels[dlChannelReq->ChannelId].Frequency == 0 ) { status &= 0xFD; } @@ -823,7 +794,7 @@ int8_t RegionEU868DlChannelReq( DlChannelReqParams_t* dlChannelReq ) // Apply Rx1 frequency, if the status is OK if( status == 0x03 ) { - NvmCtx.Channels[dlChannelReq->ChannelId].Rx1Frequency = dlChannelReq->Rx1Frequency; + RegionNvmGroup2->Channels[dlChannelReq->ChannelId].Rx1Frequency = dlChannelReq->Rx1Frequency; } return status; @@ -844,17 +815,17 @@ LoRaMacStatus_t RegionEU868NextChannel( NextChanParams_t* nextChanParams, uint8_ LoRaMacStatus_t status = LORAMAC_STATUS_NO_CHANNEL_FOUND; uint16_t joinChannels = EU868_JOIN_CHANNELS; - if( RegionCommonCountChannels( NvmCtx.ChannelsMask, 0, 1 ) == 0 ) + if( RegionCommonCountChannels( RegionNvmGroup2->ChannelsMask, 0, 1 ) == 0 ) { // Reactivate default channels - NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); + RegionNvmGroup2->ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); } // Search how many channels are enabled countChannelsParams.Joined = nextChanParams->Joined; countChannelsParams.Datarate = nextChanParams->Datarate; - countChannelsParams.ChannelsMask = NvmCtx.ChannelsMask; - countChannelsParams.Channels = NvmCtx.Channels; - countChannelsParams.Bands = NvmCtx.Bands; + countChannelsParams.ChannelsMask = RegionNvmGroup2->ChannelsMask; + countChannelsParams.Channels = RegionNvmGroup2->Channels; + countChannelsParams.Bands = RegionNvmGroup1->Bands; countChannelsParams.MaxNbChannels = EU868_MAX_NB_CHANNELS; countChannelsParams.JoinChannels = &joinChannels; @@ -880,7 +851,7 @@ LoRaMacStatus_t RegionEU868NextChannel( NextChanParams_t* nextChanParams, uint8_ else if( status == LORAMAC_STATUS_NO_CHANNEL_FOUND ) { // Datarate not supported by any channel, restore defaults - NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); + RegionNvmGroup2->ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); } return status; } @@ -939,9 +910,9 @@ LoRaMacStatus_t RegionEU868ChannelAdd( ChannelAddParams_t* channelAdd ) return LORAMAC_STATUS_FREQUENCY_INVALID; } - memcpy1( ( uint8_t* ) &(NvmCtx.Channels[id]), ( uint8_t* ) channelAdd->NewChannel, sizeof( NvmCtx.Channels[id] ) ); - NvmCtx.Channels[id].Band = band; - NvmCtx.ChannelsMask[0] |= ( 1 << id ); + memcpy1( ( uint8_t* ) &(RegionNvmGroup2->Channels[id]), ( uint8_t* ) channelAdd->NewChannel, sizeof( RegionNvmGroup2->Channels[id] ) ); + RegionNvmGroup2->Channels[id].Band = band; + RegionNvmGroup2->ChannelsMask[0] |= ( 1 << id ); return LORAMAC_STATUS_OK; } @@ -955,16 +926,16 @@ bool RegionEU868ChannelsRemove( ChannelRemoveParams_t* channelRemove ) } // Remove the channel from the list of channels - NvmCtx.Channels[id] = ( ChannelParams_t ){ 0, 0, { 0 }, 0 }; + RegionNvmGroup2->Channels[id] = ( ChannelParams_t ){ 0, 0, { 0 }, 0 }; - return RegionCommonChanDisable( NvmCtx.ChannelsMask, id, EU868_MAX_NB_CHANNELS ); + return RegionCommonChanDisable( RegionNvmGroup2->ChannelsMask, id, EU868_MAX_NB_CHANNELS ); } void RegionEU868SetContinuousWave( ContinuousWaveParams_t* continuousWave ) { - int8_t txPowerLimited = RegionCommonLimitTxPower( continuousWave->TxPower, NvmCtx.Bands[NvmCtx.Channels[continuousWave->Channel].Band].TxMaxPower ); + int8_t txPowerLimited = RegionCommonLimitTxPower( continuousWave->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[continuousWave->Channel].Band].TxMaxPower ); int8_t phyTxPower = 0; - uint32_t frequency = NvmCtx.Channels[continuousWave->Channel].Frequency; + uint32_t frequency = RegionNvmGroup2->Channels[continuousWave->Channel].Frequency; // Calculate physical TX power phyTxPower = RegionCommonComputeTxPower( txPowerLimited, continuousWave->MaxEirp, continuousWave->AntennaGain ); diff --git a/src/mac/region/RegionEU868.h b/src/mac/region/RegionEU868.h index 68fa681b6..116506d22 100644 --- a/src/mac/region/RegionEU868.h +++ b/src/mac/region/RegionEU868.h @@ -294,15 +294,6 @@ void RegionEU868SetBandTxDone( SetBandTxDoneParams_t* txDone ); */ void RegionEU868InitDefaults( InitDefaultsParams_t* params ); -/*! - * \brief Returns a pointer to the internal context and its size. - * - * \param [OUT] params Pointer to the function parameters. - * - * \retval Points to a structure where the module store its non-volatile context. - */ -void* RegionEU868GetNvmCtx( GetNvmCtxParams_t* params ); - /*! * \brief Verifies a parameter. * diff --git a/src/mac/region/RegionIN865.c b/src/mac/region/RegionIN865.c index 2b73ad913..3ba988eba 100644 --- a/src/mac/region/RegionIN865.c +++ b/src/mac/region/RegionIN865.c @@ -28,41 +28,19 @@ * * \author Daniel Jaeckle ( STACKFORCE ) */ -#include "utilities.h" - +#include "radio.h" #include "RegionCommon.h" #include "RegionIN865.h" // Definitions #define CHANNELS_MASK_SIZE 1 -/*! - * Region specific context - */ -typedef struct sRegionIN865NvmCtx -{ - /*! - * LoRaMAC channels - */ - ChannelParams_t Channels[ IN865_MAX_NB_CHANNELS ]; - /*! - * LoRaMac bands - */ - Band_t Bands[ IN865_MAX_NB_BANDS ]; - /*! - * LoRaMac channels mask - */ - uint16_t ChannelsMask[ CHANNELS_MASK_SIZE ]; - /*! - * LoRaMac channels default mask - */ - uint16_t ChannelsDefaultMask[ CHANNELS_MASK_SIZE ]; -}RegionIN865NvmCtx_t; - /* * Non-volatile module context. */ -static RegionIN865NvmCtx_t NvmCtx; +static RegionNvmDataGroup1_t* RegionNvmGroup1; +static RegionNvmDataGroup2_t* RegionNvmGroup2; + static bool VerifyRfFreq( uint32_t freq ) { @@ -125,8 +103,8 @@ PhyParam_t RegionIN865GetPhyParam( GetPhyParams_t* getPhy ) .MaxDr = ( int8_t )IN865_TX_MAX_DATARATE, .MinDr = ( int8_t )IN865_TX_MIN_DATARATE, .NbChannels = IN865_MAX_NB_CHANNELS, - .ChannelsMask = NvmCtx.ChannelsMask, - .Channels = NvmCtx.Channels, + .ChannelsMask = RegionNvmGroup2->ChannelsMask, + .Channels = RegionNvmGroup2->Channels, }; phyParam.Value = RegionCommonGetNextLowerTxDr( &nextLowerTxDrParams ); break; @@ -213,12 +191,12 @@ PhyParam_t RegionIN865GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsMask; break; } case PHY_CHANNELS_DEFAULT_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsDefaultMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsDefaultMask; break; } case PHY_MAX_NB_CHANNELS: @@ -228,7 +206,7 @@ PhyParam_t RegionIN865GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS: { - phyParam.Channels = NvmCtx.Channels; + phyParam.Channels = RegionNvmGroup2->Channels; break; } case PHY_DEF_UPLINK_DWELL_TIME: @@ -299,7 +277,7 @@ PhyParam_t RegionIN865GetPhyParam( GetPhyParams_t* getPhy ) void RegionIN865SetBandTxDone( SetBandTxDoneParams_t* txDone ) { - RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], + RegionCommonSetBandTxDone( &RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txDone->Channel].Band], txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp ); } @@ -314,43 +292,43 @@ void RegionIN865InitDefaults( InitDefaultsParams_t* params ) { case INIT_TYPE_DEFAULTS: { + if( ( params->NvmGroup1 == NULL ) || ( params->NvmGroup2 == NULL ) ) + { + return; + } + + RegionNvmGroup1 = (RegionNvmDataGroup1_t*) params->NvmGroup1; + RegionNvmGroup2 = (RegionNvmDataGroup2_t*) params->NvmGroup2; + // Initialize bands - memcpy1( ( uint8_t* )NvmCtx.Bands, ( uint8_t* )bands, sizeof( Band_t ) * IN865_MAX_NB_BANDS ); + memcpy1( ( uint8_t* )RegionNvmGroup1->Bands, ( uint8_t* )bands, sizeof( Band_t ) * IN865_MAX_NB_BANDS ); // Default channels - NvmCtx.Channels[0] = ( ChannelParams_t ) IN865_LC1; - NvmCtx.Channels[1] = ( ChannelParams_t ) IN865_LC2; - NvmCtx.Channels[2] = ( ChannelParams_t ) IN865_LC3; + RegionNvmGroup2->Channels[0] = ( ChannelParams_t ) IN865_LC1; + RegionNvmGroup2->Channels[1] = ( ChannelParams_t ) IN865_LC2; + RegionNvmGroup2->Channels[2] = ( ChannelParams_t ) IN865_LC3; // Initialize the channels default mask - NvmCtx.ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 ); + RegionNvmGroup2->ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 ); // Default ChannelsMask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); break; } case INIT_TYPE_RESET_TO_DEFAULT_CHANNELS: { // Reset Channels Rx1Frequency to default 0 - NvmCtx.Channels[0].Rx1Frequency = 0; - NvmCtx.Channels[1].Rx1Frequency = 0; - NvmCtx.Channels[2].Rx1Frequency = 0; + RegionNvmGroup2->Channels[0].Rx1Frequency = 0; + RegionNvmGroup2->Channels[1].Rx1Frequency = 0; + RegionNvmGroup2->Channels[2].Rx1Frequency = 0; // Default ChannelsMask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); break; } case INIT_TYPE_ACTIVATE_DEFAULT_CHANNELS: { // Restore channels default mask - NvmCtx.ChannelsMask[0] |= NvmCtx.ChannelsDefaultMask[0]; - break; - } - case INIT_TYPE_RESTORE_CTX: - { - if( params->NvmCtx != 0 ) - { - memcpy1( (uint8_t*) &NvmCtx, (uint8_t*) params->NvmCtx, sizeof( NvmCtx ) ); - } + RegionNvmGroup2->ChannelsMask[0] |= RegionNvmGroup2->ChannelsDefaultMask[0]; break; } default: @@ -360,12 +338,6 @@ void RegionIN865InitDefaults( InitDefaultsParams_t* params ) } } -void* RegionIN865GetNvmCtx( GetNvmCtxParams_t* params ) -{ - params->nvmCtxSize = sizeof( RegionIN865NvmCtx_t ); - return &NvmCtx; -} - bool RegionIN865Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) { switch( phyAttribute ) @@ -480,12 +452,12 @@ bool RegionIN865ChanMaskSet( ChanMaskSetParams_t* chanMaskSet ) { case CHANNELS_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, chanMaskSet->ChannelsMaskIn, 1 ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, chanMaskSet->ChannelsMaskIn, 1 ); break; } case CHANNELS_DEFAULT_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 1 ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 1 ); break; } default: @@ -529,11 +501,11 @@ bool RegionIN865RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) if( rxConfig->RxSlot == RX_SLOT_WIN_1 ) { // Apply window 1 frequency - frequency = NvmCtx.Channels[rxConfig->Channel].Frequency; + frequency = RegionNvmGroup2->Channels[rxConfig->Channel].Frequency; // Apply the alternative RX 1 window frequency, if it is available - if( NvmCtx.Channels[rxConfig->Channel].Rx1Frequency != 0 ) + if( RegionNvmGroup2->Channels[rxConfig->Channel].Rx1Frequency != 0 ) { - frequency = NvmCtx.Channels[rxConfig->Channel].Rx1Frequency; + frequency = RegionNvmGroup2->Channels[rxConfig->Channel].Rx1Frequency; } } @@ -564,7 +536,7 @@ bool RegionIN865TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime { RadioModems_t modem; int8_t phyDr = DataratesIN865[txConfig->Datarate]; - int8_t txPowerLimited = RegionCommonLimitTxPower( txConfig->TxPower, NvmCtx.Bands[NvmCtx.Channels[txConfig->Channel].Band].TxMaxPower ); + int8_t txPowerLimited = RegionCommonLimitTxPower( txConfig->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txConfig->Channel].Band].TxMaxPower ); uint32_t bandwidth = RegionCommonGetBandwidth( txConfig->Datarate, BandwidthsIN865 ); int8_t phyTxPower = 0; @@ -572,7 +544,7 @@ bool RegionIN865TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime phyTxPower = RegionCommonComputeTxPower( txPowerLimited, txConfig->MaxEirp, txConfig->AntennaGain ); // Setup the radio frequency - Radio.SetChannel( NvmCtx.Channels[txConfig->Channel].Frequency ); + Radio.SetChannel( RegionNvmGroup2->Channels[txConfig->Channel].Frequency ); if( txConfig->Datarate == DR_7 ) { // High Speed FSK channel @@ -640,7 +612,7 @@ uint8_t RegionIN865LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in { if( linkAdrParams.ChMaskCtrl == 6 ) { - if( NvmCtx.Channels[i].Frequency != 0 ) + if( RegionNvmGroup2->Channels[i].Frequency != 0 ) { chMask |= 1 << i; } @@ -648,7 +620,7 @@ uint8_t RegionIN865LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in else { if( ( ( chMask & ( 1 << i ) ) != 0 ) && - ( NvmCtx.Channels[i].Frequency == 0 ) ) + ( RegionNvmGroup2->Channels[i].Frequency == 0 ) ) {// Trying to enable an undefined channel status &= 0xFE; // Channel mask KO } @@ -676,7 +648,7 @@ uint8_t RegionIN865LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in linkAdrVerifyParams.ChannelsMask = &chMask; linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value; linkAdrVerifyParams.MaxDatarate = IN865_TX_MAX_DATARATE; - linkAdrVerifyParams.Channels = NvmCtx.Channels; + linkAdrVerifyParams.Channels = RegionNvmGroup2->Channels; linkAdrVerifyParams.MinTxPower = IN865_MIN_TX_POWER; linkAdrVerifyParams.MaxTxPower = IN865_MAX_TX_POWER; linkAdrVerifyParams.Version = linkAdrReq->Version; @@ -693,9 +665,9 @@ uint8_t RegionIN865LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in if( status == 0x07 ) { // Set the channels mask to a default value - memset1( ( uint8_t* ) NvmCtx.ChannelsMask, 0, sizeof( NvmCtx.ChannelsMask ) ); + memset1( ( uint8_t* ) RegionNvmGroup2->ChannelsMask, 0, sizeof( RegionNvmGroup2->ChannelsMask ) ); // Update the channels mask - NvmCtx.ChannelsMask[0] = chMask; + RegionNvmGroup2->ChannelsMask[0] = chMask; } // Update status variables @@ -804,7 +776,7 @@ int8_t RegionIN865DlChannelReq( DlChannelReqParams_t* dlChannelReq ) } // Verify if an uplink frequency exists - if( NvmCtx.Channels[dlChannelReq->ChannelId].Frequency == 0 ) + if( RegionNvmGroup2->Channels[dlChannelReq->ChannelId].Frequency == 0 ) { status &= 0xFD; } @@ -812,7 +784,7 @@ int8_t RegionIN865DlChannelReq( DlChannelReqParams_t* dlChannelReq ) // Apply Rx1 frequency, if the status is OK if( status == 0x03 ) { - NvmCtx.Channels[dlChannelReq->ChannelId].Rx1Frequency = dlChannelReq->Rx1Frequency; + RegionNvmGroup2->Channels[dlChannelReq->ChannelId].Rx1Frequency = dlChannelReq->Rx1Frequency; } return status; @@ -833,17 +805,17 @@ LoRaMacStatus_t RegionIN865NextChannel( NextChanParams_t* nextChanParams, uint8_ LoRaMacStatus_t status = LORAMAC_STATUS_NO_CHANNEL_FOUND; uint16_t joinChannels = IN865_JOIN_CHANNELS; - if( RegionCommonCountChannels( NvmCtx.ChannelsMask, 0, 1 ) == 0 ) + if( RegionCommonCountChannels( RegionNvmGroup2->ChannelsMask, 0, 1 ) == 0 ) { // Reactivate default channels - NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); + RegionNvmGroup2->ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); } // Search how many channels are enabled countChannelsParams.Joined = nextChanParams->Joined; countChannelsParams.Datarate = nextChanParams->Datarate; - countChannelsParams.ChannelsMask = NvmCtx.ChannelsMask; - countChannelsParams.Channels = NvmCtx.Channels; - countChannelsParams.Bands = NvmCtx.Bands; + countChannelsParams.ChannelsMask = RegionNvmGroup2->ChannelsMask; + countChannelsParams.Channels = RegionNvmGroup2->Channels; + countChannelsParams.Bands = RegionNvmGroup1->Bands; countChannelsParams.MaxNbChannels = IN865_MAX_NB_CHANNELS; countChannelsParams.JoinChannels = &joinChannels; @@ -869,7 +841,7 @@ LoRaMacStatus_t RegionIN865NextChannel( NextChanParams_t* nextChanParams, uint8_ else if( status == LORAMAC_STATUS_NO_CHANNEL_FOUND ) { // Datarate not supported by any channel, restore defaults - NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); + RegionNvmGroup2->ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); } return status; } @@ -927,9 +899,9 @@ LoRaMacStatus_t RegionIN865ChannelAdd( ChannelAddParams_t* channelAdd ) return LORAMAC_STATUS_FREQUENCY_INVALID; } - memcpy1( ( uint8_t* ) &(NvmCtx.Channels[id]), ( uint8_t* ) channelAdd->NewChannel, sizeof( NvmCtx.Channels[id] ) ); - NvmCtx.Channels[id].Band = 0; - NvmCtx.ChannelsMask[0] |= ( 1 << id ); + memcpy1( ( uint8_t* ) &(RegionNvmGroup2->Channels[id]), ( uint8_t* ) channelAdd->NewChannel, sizeof( RegionNvmGroup2->Channels[id] ) ); + RegionNvmGroup2->Channels[id].Band = 0; + RegionNvmGroup2->ChannelsMask[0] |= ( 1 << id ); return LORAMAC_STATUS_OK; } @@ -943,16 +915,16 @@ bool RegionIN865ChannelsRemove( ChannelRemoveParams_t* channelRemove ) } // Remove the channel from the list of channels - NvmCtx.Channels[id] = ( ChannelParams_t ){ 0, 0, { 0 }, 0 }; + RegionNvmGroup2->Channels[id] = ( ChannelParams_t ){ 0, 0, { 0 }, 0 }; - return RegionCommonChanDisable( NvmCtx.ChannelsMask, id, IN865_MAX_NB_CHANNELS ); + return RegionCommonChanDisable( RegionNvmGroup2->ChannelsMask, id, IN865_MAX_NB_CHANNELS ); } void RegionIN865SetContinuousWave( ContinuousWaveParams_t* continuousWave ) { - int8_t txPowerLimited = RegionCommonLimitTxPower( continuousWave->TxPower, NvmCtx.Bands[NvmCtx.Channels[continuousWave->Channel].Band].TxMaxPower ); + int8_t txPowerLimited = RegionCommonLimitTxPower( continuousWave->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[continuousWave->Channel].Band].TxMaxPower ); int8_t phyTxPower = 0; - uint32_t frequency = NvmCtx.Channels[continuousWave->Channel].Frequency; + uint32_t frequency = RegionNvmGroup2->Channels[continuousWave->Channel].Frequency; // Calculate physical TX power phyTxPower = RegionCommonComputeTxPower( txPowerLimited, continuousWave->MaxEirp, continuousWave->AntennaGain ); diff --git a/src/mac/region/RegionIN865.h b/src/mac/region/RegionIN865.h index 8c6f33d54..3593ac6a7 100644 --- a/src/mac/region/RegionIN865.h +++ b/src/mac/region/RegionIN865.h @@ -268,15 +268,6 @@ void RegionIN865SetBandTxDone( SetBandTxDoneParams_t* txDone ); */ void RegionIN865InitDefaults( InitDefaultsParams_t* params ); -/*! - * \brief Returns a pointer to the internal context and its size. - * - * \param [OUT] params Pointer to the function parameters. - * - * \retval Points to a structure where the module store its non-volatile context. - */ -void* RegionIN865GetNvmCtx( GetNvmCtxParams_t* params ); - /*! * \brief Verifies a parameter. * diff --git a/src/mac/region/RegionKR920.c b/src/mac/region/RegionKR920.c index 0c93fc099..0b84b59f7 100644 --- a/src/mac/region/RegionKR920.c +++ b/src/mac/region/RegionKR920.c @@ -28,8 +28,7 @@ * * \author Daniel Jaeckle ( STACKFORCE ) */ -#include "utilities.h" - +#include "radio.h" #include "RegionCommon.h" #include "RegionKR920.h" @@ -42,33 +41,11 @@ */ #define KR920_LBT_RX_BANDWIDTH 200000 -/*! - * Region specific context - */ -typedef struct sRegionKR920NvmCtx -{ - /*! - * LoRaMAC channels - */ - ChannelParams_t Channels[ KR920_MAX_NB_CHANNELS ]; - /*! - * LoRaMac bands - */ - Band_t Bands[ KR920_MAX_NB_BANDS ]; - /*! - * LoRaMac channels mask - */ - uint16_t ChannelsMask[ CHANNELS_MASK_SIZE ]; - /*! - * LoRaMac channels default mask - */ - uint16_t ChannelsDefaultMask[ CHANNELS_MASK_SIZE ]; -}RegionKR920NvmCtx_t; - /* * Non-volatile module context. */ -static RegionKR920NvmCtx_t NvmCtx; +static RegionNvmDataGroup1_t* RegionNvmGroup1; +static RegionNvmDataGroup2_t* RegionNvmGroup2; // Static functions static int8_t GetMaxEIRP( uint32_t freq ) @@ -142,8 +119,8 @@ PhyParam_t RegionKR920GetPhyParam( GetPhyParams_t* getPhy ) .MaxDr = ( int8_t )KR920_TX_MAX_DATARATE, .MinDr = ( int8_t )KR920_TX_MIN_DATARATE, .NbChannels = KR920_MAX_NB_CHANNELS, - .ChannelsMask = NvmCtx.ChannelsMask, - .Channels = NvmCtx.Channels, + .ChannelsMask = RegionNvmGroup2->ChannelsMask, + .Channels = RegionNvmGroup2->Channels, }; phyParam.Value = RegionCommonGetNextLowerTxDr( &nextLowerTxDrParams ); break; @@ -230,12 +207,12 @@ PhyParam_t RegionKR920GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsMask; break; } case PHY_CHANNELS_DEFAULT_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsDefaultMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsDefaultMask; break; } case PHY_MAX_NB_CHANNELS: @@ -245,7 +222,7 @@ PhyParam_t RegionKR920GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS: { - phyParam.Channels = NvmCtx.Channels; + phyParam.Channels = RegionNvmGroup2->Channels; break; } case PHY_DEF_UPLINK_DWELL_TIME: @@ -320,7 +297,7 @@ PhyParam_t RegionKR920GetPhyParam( GetPhyParams_t* getPhy ) void RegionKR920SetBandTxDone( SetBandTxDoneParams_t* txDone ) { - RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], + RegionCommonSetBandTxDone( &RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txDone->Channel].Band], txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp ); } @@ -335,43 +312,43 @@ void RegionKR920InitDefaults( InitDefaultsParams_t* params ) { case INIT_TYPE_DEFAULTS: { + if( ( params->NvmGroup1 == NULL ) || ( params->NvmGroup2 == NULL ) ) + { + return; + } + + RegionNvmGroup1 = (RegionNvmDataGroup1_t*) params->NvmGroup1; + RegionNvmGroup2 = (RegionNvmDataGroup2_t*) params->NvmGroup2; + // Initialize bands - memcpy1( ( uint8_t* )NvmCtx.Bands, ( uint8_t* )bands, sizeof( Band_t ) * KR920_MAX_NB_BANDS ); + memcpy1( ( uint8_t* )RegionNvmGroup1->Bands, ( uint8_t* )bands, sizeof( Band_t ) * KR920_MAX_NB_BANDS ); // Default channels - NvmCtx.Channels[0] = ( ChannelParams_t ) KR920_LC1; - NvmCtx.Channels[1] = ( ChannelParams_t ) KR920_LC2; - NvmCtx.Channels[2] = ( ChannelParams_t ) KR920_LC3; + RegionNvmGroup2->Channels[0] = ( ChannelParams_t ) KR920_LC1; + RegionNvmGroup2->Channels[1] = ( ChannelParams_t ) KR920_LC2; + RegionNvmGroup2->Channels[2] = ( ChannelParams_t ) KR920_LC3; // Default ChannelsMask - NvmCtx.ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 ); + RegionNvmGroup2->ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 ); // Update the channels mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); break; } case INIT_TYPE_RESET_TO_DEFAULT_CHANNELS: { // Reset Channels Rx1Frequency to default 0 - NvmCtx.Channels[0].Rx1Frequency = 0; - NvmCtx.Channels[1].Rx1Frequency = 0; - NvmCtx.Channels[2].Rx1Frequency = 0; + RegionNvmGroup2->Channels[0].Rx1Frequency = 0; + RegionNvmGroup2->Channels[1].Rx1Frequency = 0; + RegionNvmGroup2->Channels[2].Rx1Frequency = 0; // Update the channels mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); break; } case INIT_TYPE_ACTIVATE_DEFAULT_CHANNELS: { // Restore channels default mask - NvmCtx.ChannelsMask[0] |= NvmCtx.ChannelsDefaultMask[0]; - break; - } - case INIT_TYPE_RESTORE_CTX: - { - if( params->NvmCtx != 0 ) - { - memcpy1( (uint8_t*) &NvmCtx, (uint8_t*) params->NvmCtx, sizeof( NvmCtx ) ); - } + RegionNvmGroup2->ChannelsMask[0] |= RegionNvmGroup2->ChannelsDefaultMask[0]; break; } default: @@ -381,12 +358,6 @@ void RegionKR920InitDefaults( InitDefaultsParams_t* params ) } } -void* RegionKR920GetNvmCtx( GetNvmCtxParams_t* params ) -{ - params->nvmCtxSize = sizeof( RegionKR920NvmCtx_t ); - return &NvmCtx; -} - bool RegionKR920Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) { switch( phyAttribute ) @@ -487,12 +458,12 @@ bool RegionKR920ChanMaskSet( ChanMaskSetParams_t* chanMaskSet ) { case CHANNELS_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, chanMaskSet->ChannelsMaskIn, 1 ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, chanMaskSet->ChannelsMaskIn, 1 ); break; } case CHANNELS_DEFAULT_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 1 ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 1 ); break; } default: @@ -528,11 +499,11 @@ bool RegionKR920RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) if( rxConfig->RxSlot == RX_SLOT_WIN_1 ) { // Apply window 1 frequency - frequency = NvmCtx.Channels[rxConfig->Channel].Frequency; + frequency = RegionNvmGroup2->Channels[rxConfig->Channel].Frequency; // Apply the alternative RX 1 window frequency, if it is available - if( NvmCtx.Channels[rxConfig->Channel].Rx1Frequency != 0 ) + if( RegionNvmGroup2->Channels[rxConfig->Channel].Rx1Frequency != 0 ) { - frequency = NvmCtx.Channels[rxConfig->Channel].Rx1Frequency; + frequency = RegionNvmGroup2->Channels[rxConfig->Channel].Rx1Frequency; } } @@ -552,9 +523,9 @@ bool RegionKR920RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) bool RegionKR920TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir ) { int8_t phyDr = DataratesKR920[txConfig->Datarate]; - int8_t txPowerLimited = RegionCommonLimitTxPower( txConfig->TxPower, NvmCtx.Bands[NvmCtx.Channels[txConfig->Channel].Band].TxMaxPower ); + int8_t txPowerLimited = RegionCommonLimitTxPower( txConfig->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txConfig->Channel].Band].TxMaxPower ); uint32_t bandwidth = RegionCommonGetBandwidth( txConfig->Datarate, BandwidthsKR920 ); - float maxEIRP = GetMaxEIRP( NvmCtx.Channels[txConfig->Channel].Frequency ); + float maxEIRP = GetMaxEIRP( RegionNvmGroup2->Channels[txConfig->Channel].Frequency ); int8_t phyTxPower = 0; // Take the minimum between the maxEIRP and txConfig->MaxEirp. @@ -565,7 +536,7 @@ bool RegionKR920TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime phyTxPower = RegionCommonComputeTxPower( txPowerLimited, maxEIRP, txConfig->AntennaGain ); // Setup the radio frequency - Radio.SetChannel( NvmCtx.Channels[txConfig->Channel].Frequency ); + Radio.SetChannel( RegionNvmGroup2->Channels[txConfig->Channel].Frequency ); Radio.SetTxConfig( MODEM_LORA, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 4000 ); @@ -623,7 +594,7 @@ uint8_t RegionKR920LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in { if( linkAdrParams.ChMaskCtrl == 6 ) { - if( NvmCtx.Channels[i].Frequency != 0 ) + if( RegionNvmGroup2->Channels[i].Frequency != 0 ) { chMask |= 1 << i; } @@ -631,7 +602,7 @@ uint8_t RegionKR920LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in else { if( ( ( chMask & ( 1 << i ) ) != 0 ) && - ( NvmCtx.Channels[i].Frequency == 0 ) ) + ( RegionNvmGroup2->Channels[i].Frequency == 0 ) ) {// Trying to enable an undefined channel status &= 0xFE; // Channel mask KO } @@ -657,7 +628,7 @@ uint8_t RegionKR920LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in linkAdrVerifyParams.ChannelsMask = &chMask; linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value; linkAdrVerifyParams.MaxDatarate = KR920_TX_MAX_DATARATE; - linkAdrVerifyParams.Channels = NvmCtx.Channels; + linkAdrVerifyParams.Channels = RegionNvmGroup2->Channels; linkAdrVerifyParams.MinTxPower = KR920_MIN_TX_POWER; linkAdrVerifyParams.MaxTxPower = KR920_MAX_TX_POWER; linkAdrVerifyParams.Version = linkAdrReq->Version; @@ -669,9 +640,9 @@ uint8_t RegionKR920LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in if( status == 0x07 ) { // Set the channels mask to a default value - memset1( ( uint8_t* ) NvmCtx.ChannelsMask, 0, sizeof( NvmCtx.ChannelsMask ) ); + memset1( ( uint8_t* ) RegionNvmGroup2->ChannelsMask, 0, sizeof( RegionNvmGroup2->ChannelsMask ) ); // Update the channels mask - NvmCtx.ChannelsMask[0] = chMask; + RegionNvmGroup2->ChannelsMask[0] = chMask; } // Update status variables @@ -778,7 +749,7 @@ int8_t RegionKR920DlChannelReq( DlChannelReqParams_t* dlChannelReq ) } // Verify if an uplink frequency exists - if( NvmCtx.Channels[dlChannelReq->ChannelId].Frequency == 0 ) + if( RegionNvmGroup2->Channels[dlChannelReq->ChannelId].Frequency == 0 ) { status &= 0xFD; } @@ -786,7 +757,7 @@ int8_t RegionKR920DlChannelReq( DlChannelReqParams_t* dlChannelReq ) // Apply Rx1 frequency, if the status is OK if( status == 0x03 ) { - NvmCtx.Channels[dlChannelReq->ChannelId].Rx1Frequency = dlChannelReq->Rx1Frequency; + RegionNvmGroup2->Channels[dlChannelReq->ChannelId].Rx1Frequency = dlChannelReq->Rx1Frequency; } return status; @@ -808,17 +779,17 @@ LoRaMacStatus_t RegionKR920NextChannel( NextChanParams_t* nextChanParams, uint8_ LoRaMacStatus_t status = LORAMAC_STATUS_NO_CHANNEL_FOUND; uint16_t joinChannels = KR920_JOIN_CHANNELS; - if( RegionCommonCountChannels( NvmCtx.ChannelsMask, 0, 1 ) == 0 ) + if( RegionCommonCountChannels( RegionNvmGroup2->ChannelsMask, 0, 1 ) == 0 ) { // Reactivate default channels - NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); + RegionNvmGroup2->ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); } // Search how many channels are enabled countChannelsParams.Joined = nextChanParams->Joined; countChannelsParams.Datarate = nextChanParams->Datarate; - countChannelsParams.ChannelsMask = NvmCtx.ChannelsMask; - countChannelsParams.Channels = NvmCtx.Channels; - countChannelsParams.Bands = NvmCtx.Bands; + countChannelsParams.ChannelsMask = RegionNvmGroup2->ChannelsMask; + countChannelsParams.Channels = RegionNvmGroup2->Channels; + countChannelsParams.Bands = RegionNvmGroup1->Bands; countChannelsParams.MaxNbChannels = KR920_MAX_NB_CHANNELS; countChannelsParams.JoinChannels = &joinChannels; @@ -845,7 +816,7 @@ LoRaMacStatus_t RegionKR920NextChannel( NextChanParams_t* nextChanParams, uint8_ // Perform carrier sense for KR920_CARRIER_SENSE_TIME // If the channel is free, we can stop the LBT mechanism - if( Radio.IsChannelFree( NvmCtx.Channels[channelNext].Frequency, KR920_LBT_RX_BANDWIDTH, KR920_RSSI_FREE_TH, KR920_CARRIER_SENSE_TIME ) == true ) + if( Radio.IsChannelFree( RegionNvmGroup2->Channels[channelNext].Frequency, KR920_LBT_RX_BANDWIDTH, KR920_RSSI_FREE_TH, KR920_CARRIER_SENSE_TIME ) == true ) { // Free channel found *channel = channelNext; @@ -859,7 +830,7 @@ LoRaMacStatus_t RegionKR920NextChannel( NextChanParams_t* nextChanParams, uint8_ else if( status == LORAMAC_STATUS_NO_CHANNEL_FOUND ) { // Datarate not supported by any channel, restore defaults - NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); + RegionNvmGroup2->ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 ); } return status; } @@ -917,9 +888,9 @@ LoRaMacStatus_t RegionKR920ChannelAdd( ChannelAddParams_t* channelAdd ) return LORAMAC_STATUS_FREQUENCY_INVALID; } - memcpy1( ( uint8_t* ) &(NvmCtx.Channels[id]), ( uint8_t* ) channelAdd->NewChannel, sizeof( NvmCtx.Channels[id] ) ); - NvmCtx.Channels[id].Band = 0; - NvmCtx.ChannelsMask[0] |= ( 1 << id ); + memcpy1( ( uint8_t* ) &(RegionNvmGroup2->Channels[id]), ( uint8_t* ) channelAdd->NewChannel, sizeof( RegionNvmGroup2->Channels[id] ) ); + RegionNvmGroup2->Channels[id].Band = 0; + RegionNvmGroup2->ChannelsMask[0] |= ( 1 << id ); return LORAMAC_STATUS_OK; } @@ -933,17 +904,17 @@ bool RegionKR920ChannelsRemove( ChannelRemoveParams_t* channelRemove ) } // Remove the channel from the list of channels - NvmCtx.Channels[id] = ( ChannelParams_t ){ 0, 0, { 0 }, 0 }; + RegionNvmGroup2->Channels[id] = ( ChannelParams_t ){ 0, 0, { 0 }, 0 }; - return RegionCommonChanDisable( NvmCtx.ChannelsMask, id, KR920_MAX_NB_CHANNELS ); + return RegionCommonChanDisable( RegionNvmGroup2->ChannelsMask, id, KR920_MAX_NB_CHANNELS ); } void RegionKR920SetContinuousWave( ContinuousWaveParams_t* continuousWave ) { - int8_t txPowerLimited = RegionCommonLimitTxPower( continuousWave->TxPower, NvmCtx.Bands[NvmCtx.Channels[continuousWave->Channel].Band].TxMaxPower ); - float maxEIRP = GetMaxEIRP( NvmCtx.Channels[continuousWave->Channel].Frequency ); + int8_t txPowerLimited = RegionCommonLimitTxPower( continuousWave->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[continuousWave->Channel].Band].TxMaxPower ); + float maxEIRP = GetMaxEIRP( RegionNvmGroup2->Channels[continuousWave->Channel].Frequency ); int8_t phyTxPower = 0; - uint32_t frequency = NvmCtx.Channels[continuousWave->Channel].Frequency; + uint32_t frequency = RegionNvmGroup2->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/src/mac/region/RegionKR920.h b/src/mac/region/RegionKR920.h index 50b119c54..afc088ec1 100644 --- a/src/mac/region/RegionKR920.h +++ b/src/mac/region/RegionKR920.h @@ -278,15 +278,6 @@ void RegionKR920SetBandTxDone( SetBandTxDoneParams_t* txDone ); */ void RegionKR920InitDefaults( InitDefaultsParams_t* params ); -/*! - * \brief Returns a pointer to the internal context and its size. - * - * \param [OUT] params Pointer to the function parameters. - * - * \retval Points to a structure where the module store its non-volatile context. - */ -void* RegionKR920GetNvmCtx( GetNvmCtxParams_t* params ); - /*! * \brief Verifies a parameter. * diff --git a/src/mac/region/RegionNvm.h b/src/mac/region/RegionNvm.h new file mode 100644 index 000000000..fc619b045 --- /dev/null +++ b/src/mac/region/RegionNvm.h @@ -0,0 +1,134 @@ +/*! + * \file RegionNvm.h + * + * \brief Region independent non-volatile data. + * + * \copyright Revised BSD License, see section \ref LICENSE. + * + * \code + * ______ _ + * / _____) _ | | + * ( (____ _____ ____ _| |_ _____ ____| |__ + * \____ \| ___ | (_ _) ___ |/ ___) _ \ + * _____) ) ____| | | || |_| ____( (___| | | | + * (______/|_____)_|_|_| \__)_____)\____)_| |_| + * (C)2013-2017 Semtech + * + * ___ _____ _ ___ _ _____ ___ ___ ___ ___ + * / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| + * \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| + * |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| + * embedded.connectivity.solutions=============== + * + * \endcode + * + * \author Miguel Luis ( Semtech ) + * + * \author Daniel Jaeckle ( STACKFORCE ) + * + * \addtogroup REGIONCOMMON + * + * \{ + */ +#ifndef __REGIONNVM_H__ +#define __REGIONNVM_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "LoRaMacTypes.h" + +// Selection of REGION_NVM_MAX_NB_CHANNELS +#if defined( REGION_CN470 ) + #define REGION_NVM_MAX_NB_CHANNELS 96 +#elif defined( REGION_US915 ) || defined( REGION_AU915 ) + #define REGION_NVM_MAX_NB_CHANNELS 72 +#elif defined( REGION_AS923 ) || defined( REGION_CN779 ) || \ + defined( REGION_EU433 ) || defined( REGION_EU868 ) || \ + defined( REGION_IN865 ) || defined( REGION_KR920 ) + #define REGION_NVM_MAX_NB_CHANNELS 16 +#else + // Region_RU864 + #define REGION_NVM_MAX_NB_CHANNELS 8 +#endif + +// Selection of REGION_NVM_MAX_NB_BANDS +#if defined( REGION_EU868 ) + #define REGION_NVM_MAX_NB_BANDS 6 +#else + // All others + #define REGION_NVM_MAX_NB_BANDS 1 +#endif + +// Selection of REGION_NVM_CHANNELS_MASK_SIZE +#if defined( REGION_CN470 ) || defined( REGION_US915 ) || \ + defined( REGION_AU915 ) + #define REGION_NVM_CHANNELS_MASK_SIZE 6 +#else + // All others + #define REGION_NVM_CHANNELS_MASK_SIZE 1 +#endif + +/*! + * Region specific data which must be stored in the NVM. + */ +typedef struct sRegionNvmDataGroup1 +{ + /*! + * LoRaMac bands + */ + Band_t Bands[ REGION_NVM_MAX_NB_BANDS ]; +#if defined( REGION_US915 ) || defined( REGION_AU915 ) + /*! + * LoRaMac channels remaining + */ + uint16_t ChannelsMaskRemaining[ REGION_NVM_CHANNELS_MASK_SIZE ]; + /*! + * Index of current in use 8 bit group (0: bit 0 - 7, 1: bit 8 - 15, ..., + * 7: bit 56 - 63) + */ + uint8_t JoinChannelGroupsCurrentIndex; + /*! + * Counter of join trials needed to alternate between datarates. + */ + uint8_t JoinTrialsCounter; +#endif + /*! + * CRC32 value of the Region data structure. + */ + uint32_t Crc32; +}RegionNvmDataGroup1_t; + +/*! + * Region specific data which must be stored in the NVM. + * Parameters which do not change very frequently. + */ +typedef struct sRegionNvmDataGroup2 +{ + /*! + * LoRaMAC channels + */ + ChannelParams_t Channels[ REGION_NVM_MAX_NB_CHANNELS ]; + /*! + * LoRaMac channels mask + */ + uint16_t ChannelsMask[ REGION_NVM_CHANNELS_MASK_SIZE ]; + /*! + * LoRaMac channels default mask + */ + uint16_t ChannelsDefaultMask[ REGION_NVM_CHANNELS_MASK_SIZE ]; + /*! + * CRC32 value of the Region data structure. + */ + uint32_t Crc32; +}RegionNvmDataGroup2_t; + +/*! \} addtogroup REGIONCOMMON */ + +#ifdef __cplusplus +} +#endif + +#endif // __REGIONNVM_H__ diff --git a/src/mac/region/RegionRU864.c b/src/mac/region/RegionRU864.c index 2eab8173f..7eb528ea2 100644 --- a/src/mac/region/RegionRU864.c +++ b/src/mac/region/RegionRU864.c @@ -28,41 +28,18 @@ * * \author Daniel Jaeckle ( STACKFORCE ) */ -#include "utilities.h" - +#include "radio.h" #include "RegionCommon.h" #include "RegionRU864.h" // Definitions #define CHANNELS_MASK_SIZE 1 -/*! - * Region specific context - */ -typedef struct sRegionRU864NvmCtx -{ - /*! - * LoRaMAC channels - */ - ChannelParams_t Channels[ RU864_MAX_NB_CHANNELS ]; - /*! - * LoRaMac bands - */ - Band_t Bands[ RU864_MAX_NB_BANDS ]; - /*! - * LoRaMac channels mask - */ - uint16_t ChannelsMask[ CHANNELS_MASK_SIZE ]; - /*! - * LoRaMac channels default mask - */ - uint16_t ChannelsDefaultMask[ CHANNELS_MASK_SIZE ]; -}RegionRU864NvmCtx_t; - /* * Non-volatile module context. */ -static RegionRU864NvmCtx_t NvmCtx; +static RegionNvmDataGroup1_t* RegionNvmGroup1; +static RegionNvmDataGroup2_t* RegionNvmGroup2; // Static functions static bool VerifyRfFreq( uint32_t freq ) @@ -127,8 +104,8 @@ PhyParam_t RegionRU864GetPhyParam( GetPhyParams_t* getPhy ) .MaxDr = ( int8_t )RU864_TX_MAX_DATARATE, .MinDr = ( int8_t )RU864_TX_MIN_DATARATE, .NbChannels = RU864_MAX_NB_CHANNELS, - .ChannelsMask = NvmCtx.ChannelsMask, - .Channels = NvmCtx.Channels, + .ChannelsMask = RegionNvmGroup2->ChannelsMask, + .Channels = RegionNvmGroup2->Channels, }; phyParam.Value = RegionCommonGetNextLowerTxDr( &nextLowerTxDrParams ); break; @@ -215,12 +192,12 @@ PhyParam_t RegionRU864GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsMask; break; } case PHY_CHANNELS_DEFAULT_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsDefaultMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsDefaultMask; break; } case PHY_MAX_NB_CHANNELS: @@ -230,7 +207,7 @@ PhyParam_t RegionRU864GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS: { - phyParam.Channels = NvmCtx.Channels; + phyParam.Channels = RegionNvmGroup2->Channels; break; } case PHY_DEF_UPLINK_DWELL_TIME: @@ -301,7 +278,7 @@ PhyParam_t RegionRU864GetPhyParam( GetPhyParams_t* getPhy ) void RegionRU864SetBandTxDone( SetBandTxDoneParams_t* txDone ) { - RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], + RegionCommonSetBandTxDone( &RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txDone->Channel].Band], txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp ); } @@ -316,41 +293,41 @@ void RegionRU864InitDefaults( InitDefaultsParams_t* params ) { case INIT_TYPE_DEFAULTS: { + if( ( params->NvmGroup1 == NULL ) || ( params->NvmGroup2 == NULL ) ) + { + return; + } + + RegionNvmGroup1 = (RegionNvmDataGroup1_t*) params->NvmGroup1; + RegionNvmGroup2 = (RegionNvmDataGroup2_t*) params->NvmGroup2; + // Default bands - memcpy1( ( uint8_t* )NvmCtx.Bands, ( uint8_t* )bands, sizeof( Band_t ) * RU864_MAX_NB_BANDS ); + memcpy1( ( uint8_t* )RegionNvmGroup1->Bands, ( uint8_t* )bands, sizeof( Band_t ) * RU864_MAX_NB_BANDS ); // Default channels - NvmCtx.Channels[0] = ( ChannelParams_t ) RU864_LC1; - NvmCtx.Channels[1] = ( ChannelParams_t ) RU864_LC2; + RegionNvmGroup2->Channels[0] = ( ChannelParams_t ) RU864_LC1; + RegionNvmGroup2->Channels[1] = ( ChannelParams_t ) RU864_LC2; // Default ChannelsMask - NvmCtx.ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ); + RegionNvmGroup2->ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ); // Update the channels mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); break; } case INIT_TYPE_RESET_TO_DEFAULT_CHANNELS: { // Reset Channels Rx1Frequency to default 0 - NvmCtx.Channels[0].Rx1Frequency = 0; - NvmCtx.Channels[1].Rx1Frequency = 0; + RegionNvmGroup2->Channels[0].Rx1Frequency = 0; + RegionNvmGroup2->Channels[1].Rx1Frequency = 0; // Update the channels mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); break; } case INIT_TYPE_ACTIVATE_DEFAULT_CHANNELS: { // Restore channels default mask - NvmCtx.ChannelsMask[0] |= NvmCtx.ChannelsDefaultMask[0]; - break; - } - case INIT_TYPE_RESTORE_CTX: - { - if( params->NvmCtx != 0 ) - { - memcpy1( (uint8_t*) &NvmCtx, (uint8_t*) params->NvmCtx, sizeof( NvmCtx ) ); - } + RegionNvmGroup2->ChannelsMask[0] |= RegionNvmGroup2->ChannelsDefaultMask[0]; break; } default: @@ -360,12 +337,6 @@ void RegionRU864InitDefaults( InitDefaultsParams_t* params ) } } -void* RegionRU864GetNvmCtx( GetNvmCtxParams_t* params ) -{ - params->nvmCtxSize = sizeof( RegionRU864NvmCtx_t ); - return &NvmCtx; -} - bool RegionRU864Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) { switch( phyAttribute ) @@ -466,12 +437,12 @@ bool RegionRU864ChanMaskSet( ChanMaskSetParams_t* chanMaskSet ) { case CHANNELS_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, chanMaskSet->ChannelsMaskIn, 1 ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, chanMaskSet->ChannelsMaskIn, 1 ); break; } case CHANNELS_DEFAULT_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 1 ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 1 ); break; } default: @@ -515,11 +486,11 @@ bool RegionRU864RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) if( rxConfig->RxSlot == RX_SLOT_WIN_1 ) { // Apply window 1 frequency - frequency = NvmCtx.Channels[rxConfig->Channel].Frequency; + frequency = RegionNvmGroup2->Channels[rxConfig->Channel].Frequency; // Apply the alternative RX 1 window frequency, if it is available - if( NvmCtx.Channels[rxConfig->Channel].Rx1Frequency != 0 ) + if( RegionNvmGroup2->Channels[rxConfig->Channel].Rx1Frequency != 0 ) { - frequency = NvmCtx.Channels[rxConfig->Channel].Rx1Frequency; + frequency = RegionNvmGroup2->Channels[rxConfig->Channel].Rx1Frequency; } } @@ -550,7 +521,7 @@ bool RegionRU864TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime { RadioModems_t modem; int8_t phyDr = DataratesRU864[txConfig->Datarate]; - int8_t txPowerLimited = RegionCommonLimitTxPower( txConfig->TxPower, NvmCtx.Bands[NvmCtx.Channels[txConfig->Channel].Band].TxMaxPower ); + int8_t txPowerLimited = RegionCommonLimitTxPower( txConfig->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txConfig->Channel].Band].TxMaxPower ); uint32_t bandwidth = RegionCommonGetBandwidth( txConfig->Datarate, BandwidthsRU864 ); int8_t phyTxPower = 0; @@ -558,7 +529,7 @@ bool RegionRU864TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime phyTxPower = RegionCommonComputeTxPower( txPowerLimited, txConfig->MaxEirp, txConfig->AntennaGain ); // Setup the radio frequency - Radio.SetChannel( NvmCtx.Channels[txConfig->Channel].Frequency ); + Radio.SetChannel( RegionNvmGroup2->Channels[txConfig->Channel].Frequency ); if( txConfig->Datarate == DR_7 ) { // High Speed FSK channel @@ -626,7 +597,7 @@ uint8_t RegionRU864LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in { if( linkAdrParams.ChMaskCtrl == 6 ) { - if( NvmCtx.Channels[i].Frequency != 0 ) + if( RegionNvmGroup2->Channels[i].Frequency != 0 ) { chMask |= 1 << i; } @@ -634,7 +605,7 @@ uint8_t RegionRU864LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in else { if( ( ( chMask & ( 1 << i ) ) != 0 ) && - ( NvmCtx.Channels[i].Frequency == 0 ) ) + ( RegionNvmGroup2->Channels[i].Frequency == 0 ) ) {// Trying to enable an undefined channel status &= 0xFE; // Channel mask KO } @@ -660,7 +631,7 @@ uint8_t RegionRU864LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in linkAdrVerifyParams.ChannelsMask = &chMask; linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value; linkAdrVerifyParams.MaxDatarate = RU864_TX_MAX_DATARATE; - linkAdrVerifyParams.Channels = NvmCtx.Channels; + linkAdrVerifyParams.Channels = RegionNvmGroup2->Channels; linkAdrVerifyParams.MinTxPower = RU864_MIN_TX_POWER; linkAdrVerifyParams.MaxTxPower = RU864_MAX_TX_POWER; linkAdrVerifyParams.Version = linkAdrReq->Version; @@ -672,9 +643,9 @@ uint8_t RegionRU864LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in if( status == 0x07 ) { // Set the channels mask to a default value - memset1( ( uint8_t* ) NvmCtx.ChannelsMask, 0, sizeof( NvmCtx.ChannelsMask ) ); + memset1( ( uint8_t* ) RegionNvmGroup2->ChannelsMask, 0, sizeof( RegionNvmGroup2->ChannelsMask ) ); // Update the channels mask - NvmCtx.ChannelsMask[0] = chMask; + RegionNvmGroup2->ChannelsMask[0] = chMask; } // Update status variables @@ -781,7 +752,7 @@ int8_t RegionRU864DlChannelReq( DlChannelReqParams_t* dlChannelReq ) } // Verify if an uplink frequency exists - if( NvmCtx.Channels[dlChannelReq->ChannelId].Frequency == 0 ) + if( RegionNvmGroup2->Channels[dlChannelReq->ChannelId].Frequency == 0 ) { status &= 0xFD; } @@ -789,7 +760,7 @@ int8_t RegionRU864DlChannelReq( DlChannelReqParams_t* dlChannelReq ) // Apply Rx1 frequency, if the status is OK if( status == 0x03 ) { - NvmCtx.Channels[dlChannelReq->ChannelId].Rx1Frequency = dlChannelReq->Rx1Frequency; + RegionNvmGroup2->Channels[dlChannelReq->ChannelId].Rx1Frequency = dlChannelReq->Rx1Frequency; } return status; @@ -810,17 +781,17 @@ LoRaMacStatus_t RegionRU864NextChannel( NextChanParams_t* nextChanParams, uint8_ LoRaMacStatus_t status = LORAMAC_STATUS_NO_CHANNEL_FOUND; uint16_t joinChannels = RU864_JOIN_CHANNELS; - if( RegionCommonCountChannels( NvmCtx.ChannelsMask, 0, 1 ) == 0 ) + if( RegionCommonCountChannels( RegionNvmGroup2->ChannelsMask, 0, 1 ) == 0 ) { // Reactivate default channels - NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ); + RegionNvmGroup2->ChannelsMask[0] |= LC( 1 ) + LC( 2 ); } // Search how many channels are enabled countChannelsParams.Joined = nextChanParams->Joined; countChannelsParams.Datarate = nextChanParams->Datarate; - countChannelsParams.ChannelsMask = NvmCtx.ChannelsMask; - countChannelsParams.Channels = NvmCtx.Channels; - countChannelsParams.Bands = NvmCtx.Bands; + countChannelsParams.ChannelsMask = RegionNvmGroup2->ChannelsMask; + countChannelsParams.Channels = RegionNvmGroup2->Channels; + countChannelsParams.Bands = RegionNvmGroup1->Bands; countChannelsParams.MaxNbChannels = RU864_MAX_NB_CHANNELS; countChannelsParams.JoinChannels = &joinChannels; @@ -846,7 +817,7 @@ LoRaMacStatus_t RegionRU864NextChannel( NextChanParams_t* nextChanParams, uint8_ else if( status == LORAMAC_STATUS_NO_CHANNEL_FOUND ) { // Datarate not supported by any channel, restore defaults - NvmCtx.ChannelsMask[0] |= LC( 1 ) + LC( 2 ); + RegionNvmGroup2->ChannelsMask[0] |= LC( 1 ) + LC( 2 ); } return status; } @@ -904,9 +875,9 @@ LoRaMacStatus_t RegionRU864ChannelAdd( ChannelAddParams_t* channelAdd ) return LORAMAC_STATUS_FREQUENCY_INVALID; } - memcpy1( ( uint8_t* ) &(NvmCtx.Channels[id]), ( uint8_t* ) channelAdd->NewChannel, sizeof( NvmCtx.Channels[id] ) ); - NvmCtx.Channels[id].Band = 0; - NvmCtx.ChannelsMask[0] |= ( 1 << id ); + memcpy1( ( uint8_t* ) &(RegionNvmGroup2->Channels[id]), ( uint8_t* ) channelAdd->NewChannel, sizeof( RegionNvmGroup2->Channels[id] ) ); + RegionNvmGroup2->Channels[id].Band = 0; + RegionNvmGroup2->ChannelsMask[0] |= ( 1 << id ); return LORAMAC_STATUS_OK; } @@ -920,16 +891,16 @@ bool RegionRU864ChannelsRemove( ChannelRemoveParams_t* channelRemove ) } // Remove the channel from the list of channels - NvmCtx.Channels[id] = ( ChannelParams_t ){ 0, 0, { 0 }, 0 }; + RegionNvmGroup2->Channels[id] = ( ChannelParams_t ){ 0, 0, { 0 }, 0 }; - return RegionCommonChanDisable( NvmCtx.ChannelsMask, id, RU864_MAX_NB_CHANNELS ); + return RegionCommonChanDisable( RegionNvmGroup2->ChannelsMask, id, RU864_MAX_NB_CHANNELS ); } void RegionRU864SetContinuousWave( ContinuousWaveParams_t* continuousWave ) { - int8_t txPowerLimited = RegionCommonLimitTxPower( continuousWave->TxPower, NvmCtx.Bands[NvmCtx.Channels[continuousWave->Channel].Band].TxMaxPower ); + int8_t txPowerLimited = RegionCommonLimitTxPower( continuousWave->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[continuousWave->Channel].Band].TxMaxPower ); int8_t phyTxPower = 0; - uint32_t frequency = NvmCtx.Channels[continuousWave->Channel].Frequency; + uint32_t frequency = RegionNvmGroup2->Channels[continuousWave->Channel].Frequency; // Calculate physical TX power phyTxPower = RegionCommonComputeTxPower( txPowerLimited, continuousWave->MaxEirp, continuousWave->AntennaGain ); diff --git a/src/mac/region/RegionRU864.h b/src/mac/region/RegionRU864.h index 4120c1867..fb5193acf 100644 --- a/src/mac/region/RegionRU864.h +++ b/src/mac/region/RegionRU864.h @@ -256,15 +256,6 @@ void RegionRU864SetBandTxDone( SetBandTxDoneParams_t* txDone ); */ void RegionRU864InitDefaults( InitDefaultsParams_t* params ); -/*! - * \brief Returns a pointer to the internal context and its size. - * - * \param [OUT] params Pointer to the function parameters. - * - * \retval Points to a structure where the module store its non-volatile context. - */ -void* RegionRU864GetNvmCtx( GetNvmCtxParams_t* params ); - /*! * \brief Verifies a parameter. * diff --git a/src/mac/region/RegionUS915.c b/src/mac/region/RegionUS915.c index 89af6125d..f471ee52b 100644 --- a/src/mac/region/RegionUS915.c +++ b/src/mac/region/RegionUS915.c @@ -28,8 +28,7 @@ * * \author Daniel Jaeckle ( STACKFORCE ) */ -#include "utilities.h" - +#include "radio.h" #include "RegionCommon.h" #include "RegionUS915.h" #include "RegionBaseUS.h" @@ -40,47 +39,12 @@ // A mask to select only valid 500KHz channels #define CHANNELS_MASK_500KHZ_MASK 0x00FF -/*! - * Region specific context - */ -typedef struct sRegionUS915NvmCtx -{ - /*! - * LoRaMAC channels - */ - ChannelParams_t Channels[ US915_MAX_NB_CHANNELS ]; - /*! - * LoRaMac bands - */ - Band_t Bands[ US915_MAX_NB_BANDS ]; - /*! - * LoRaMac channels mask - */ - uint16_t ChannelsMask[ CHANNELS_MASK_SIZE ]; - /*! - * LoRaMac channels remaining - */ - uint16_t ChannelsMaskRemaining[CHANNELS_MASK_SIZE]; - /*! - * LoRaMac channels default mask - */ - uint16_t ChannelsDefaultMask[ CHANNELS_MASK_SIZE ]; - /*! - * Index of current in use 8 bit group (0: bit 0 - 7, 1: bit 8 - 15, ..., 7: bit 56 - 63) - */ - uint8_t JoinChannelGroupsCurrentIndex; - /*! - * Counter of join trials needed to alternate between DR0 and DR4, see \ref RegionUS915AlternateDr - */ - uint8_t JoinTrialsCounter; -}RegionUS915NvmCtx_t; - /* * Non-volatile module context. */ -static RegionUS915NvmCtx_t NvmCtx; +static RegionNvmDataGroup1_t* RegionNvmGroup1; +static RegionNvmDataGroup2_t* RegionNvmGroup2; -// Static functions static int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower, int8_t datarate, uint16_t* channelsMask ) { int8_t txPowerResult = txPower; @@ -163,8 +127,8 @@ PhyParam_t RegionUS915GetPhyParam( GetPhyParams_t* getPhy ) .MaxDr = ( int8_t )US915_TX_MAX_DATARATE, .MinDr = ( int8_t )US915_TX_MIN_DATARATE, .NbChannels = US915_MAX_NB_CHANNELS, - .ChannelsMask = NvmCtx.ChannelsMask, - .Channels = NvmCtx.Channels, + .ChannelsMask = RegionNvmGroup2->ChannelsMask, + .Channels = RegionNvmGroup2->Channels, }; phyParam.Value = RegionCommonGetNextLowerTxDr( &nextLowerTxDrParams ); break; @@ -251,12 +215,12 @@ PhyParam_t RegionUS915GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsMask; break; } case PHY_CHANNELS_DEFAULT_MASK: { - phyParam.ChannelsMask = NvmCtx.ChannelsDefaultMask; + phyParam.ChannelsMask = RegionNvmGroup2->ChannelsDefaultMask; break; } case PHY_MAX_NB_CHANNELS: @@ -266,7 +230,7 @@ PhyParam_t RegionUS915GetPhyParam( GetPhyParams_t* getPhy ) } case PHY_CHANNELS: { - phyParam.Channels = NvmCtx.Channels; + phyParam.Channels = RegionNvmGroup2->Channels; break; } case PHY_DEF_UPLINK_DWELL_TIME: @@ -351,7 +315,7 @@ PhyParam_t RegionUS915GetPhyParam( GetPhyParams_t* getPhy ) void RegionUS915SetBandTxDone( SetBandTxDoneParams_t* txDone ) { - RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], + RegionCommonSetBandTxDone( &RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txDone->Channel].Band], txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp ); } @@ -366,44 +330,52 @@ void RegionUS915InitDefaults( InitDefaultsParams_t* params ) { case INIT_TYPE_DEFAULTS: { + if( ( params->NvmGroup1 == NULL ) || ( params->NvmGroup2 == NULL ) ) + { + return; + } + + RegionNvmGroup1 = (RegionNvmDataGroup1_t*) params->NvmGroup1; + RegionNvmGroup2 = (RegionNvmDataGroup2_t*) params->NvmGroup2; + // Initialize 8 bit channel groups index - NvmCtx.JoinChannelGroupsCurrentIndex = 0; + RegionNvmGroup1->JoinChannelGroupsCurrentIndex = 0; // Initialize the join trials counter - NvmCtx.JoinTrialsCounter = 0; + RegionNvmGroup1->JoinTrialsCounter = 0; // Default bands - memcpy1( ( uint8_t* )NvmCtx.Bands, ( uint8_t* )bands, sizeof( Band_t ) * US915_MAX_NB_BANDS ); + memcpy1( ( uint8_t* )RegionNvmGroup1->Bands, ( uint8_t* )bands, sizeof( Band_t ) * US915_MAX_NB_BANDS ); // Default channels for( uint8_t i = 0; i < US915_MAX_NB_CHANNELS - 8; i++ ) { // 125 kHz channels - NvmCtx.Channels[i].Frequency = 902300000 + i * 200000; - NvmCtx.Channels[i].DrRange.Value = ( DR_3 << 4 ) | DR_0; - NvmCtx.Channels[i].Band = 0; + RegionNvmGroup2->Channels[i].Frequency = 902300000 + i * 200000; + RegionNvmGroup2->Channels[i].DrRange.Value = ( DR_3 << 4 ) | DR_0; + RegionNvmGroup2->Channels[i].Band = 0; } for( uint8_t i = US915_MAX_NB_CHANNELS - 8; i < US915_MAX_NB_CHANNELS; i++ ) { // 500 kHz channels - NvmCtx.Channels[i].Frequency = 903000000 + ( i - ( US915_MAX_NB_CHANNELS - 8 ) ) * 1600000; - NvmCtx.Channels[i].DrRange.Value = ( DR_4 << 4 ) | DR_4; - NvmCtx.Channels[i].Band = 0; + RegionNvmGroup2->Channels[i].Frequency = 903000000 + ( i - ( US915_MAX_NB_CHANNELS - 8 ) ) * 1600000; + RegionNvmGroup2->Channels[i].DrRange.Value = ( DR_4 << 4 ) | DR_4; + RegionNvmGroup2->Channels[i].Band = 0; } // Default ChannelsMask - NvmCtx.ChannelsDefaultMask[0] = 0xFFFF; - NvmCtx.ChannelsDefaultMask[1] = 0xFFFF; - NvmCtx.ChannelsDefaultMask[2] = 0xFFFF; - NvmCtx.ChannelsDefaultMask[3] = 0xFFFF; - NvmCtx.ChannelsDefaultMask[4] = 0x00FF; - NvmCtx.ChannelsDefaultMask[5] = 0x0000; + RegionNvmGroup2->ChannelsDefaultMask[0] = 0xFFFF; + RegionNvmGroup2->ChannelsDefaultMask[1] = 0xFFFF; + RegionNvmGroup2->ChannelsDefaultMask[2] = 0xFFFF; + RegionNvmGroup2->ChannelsDefaultMask[3] = 0xFFFF; + RegionNvmGroup2->ChannelsDefaultMask[4] = 0x00FF; + RegionNvmGroup2->ChannelsDefaultMask[5] = 0x0000; // Copy channels default mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); // Copy into channels mask remaining - RegionCommonChanMaskCopy( NvmCtx.ChannelsMaskRemaining, NvmCtx.ChannelsMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup1->ChannelsMaskRemaining, RegionNvmGroup2->ChannelsMask, CHANNELS_MASK_SIZE ); break; } case INIT_TYPE_RESET_TO_DEFAULT_CHANNELS: @@ -413,19 +385,11 @@ void RegionUS915InitDefaults( InitDefaultsParams_t* params ) case INIT_TYPE_ACTIVATE_DEFAULT_CHANNELS: { // Copy channels default mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE ); for( uint8_t i = 0; i < CHANNELS_MASK_SIZE; i++ ) { // Copy-And the channels mask - NvmCtx.ChannelsMaskRemaining[i] &= NvmCtx.ChannelsMask[i]; - } - break; - } - case INIT_TYPE_RESTORE_CTX: - { - if( params->NvmCtx != 0 ) - { - memcpy1( (uint8_t*) &NvmCtx, (uint8_t*) params->NvmCtx, sizeof( NvmCtx ) ); + RegionNvmGroup1->ChannelsMaskRemaining[i] &= RegionNvmGroup2->ChannelsMask[i]; } break; } @@ -436,12 +400,6 @@ void RegionUS915InitDefaults( InitDefaultsParams_t* params ) } } -void* RegionUS915GetNvmCtx( GetNvmCtxParams_t* params ) -{ - params->nvmCtxSize = sizeof( RegionUS915NvmCtx_t ); - return &NvmCtx; -} - bool RegionUS915Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute ) { switch( phyAttribute ) @@ -491,14 +449,14 @@ void RegionUS915ApplyCFList( ApplyCFListParams_t* applyCFList ) // ChMask0 - ChMask4 must be set (every ChMask has 16 bit) for( uint8_t chMaskItr = 0, cntPayload = 0; chMaskItr <= 4; chMaskItr++, cntPayload+=2 ) { - NvmCtx.ChannelsMask[chMaskItr] = (uint16_t) (0x00FF & applyCFList->Payload[cntPayload]); - NvmCtx.ChannelsMask[chMaskItr] |= (uint16_t) (applyCFList->Payload[cntPayload+1] << 8); + RegionNvmGroup2->ChannelsMask[chMaskItr] = (uint16_t) (0x00FF & applyCFList->Payload[cntPayload]); + RegionNvmGroup2->ChannelsMask[chMaskItr] |= (uint16_t) (applyCFList->Payload[cntPayload+1] << 8); if( chMaskItr == 4 ) { - NvmCtx.ChannelsMask[chMaskItr] = NvmCtx.ChannelsMask[chMaskItr] & CHANNELS_MASK_500KHZ_MASK; + RegionNvmGroup2->ChannelsMask[chMaskItr] = RegionNvmGroup2->ChannelsMask[chMaskItr] & CHANNELS_MASK_500KHZ_MASK; } // Set the channel mask to the remaining - NvmCtx.ChannelsMaskRemaining[chMaskItr] &= NvmCtx.ChannelsMask[chMaskItr]; + RegionNvmGroup1->ChannelsMaskRemaining[chMaskItr] &= RegionNvmGroup2->ChannelsMask[chMaskItr]; } } @@ -517,20 +475,20 @@ bool RegionUS915ChanMaskSet( ChanMaskSetParams_t* chanMaskSet ) { case CHANNELS_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, chanMaskSet->ChannelsMaskIn, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, chanMaskSet->ChannelsMaskIn, CHANNELS_MASK_SIZE ); - NvmCtx.ChannelsDefaultMask[4] = NvmCtx.ChannelsDefaultMask[4] & CHANNELS_MASK_500KHZ_MASK; - NvmCtx.ChannelsDefaultMask[5] = 0x0000; + RegionNvmGroup2->ChannelsDefaultMask[4] = RegionNvmGroup2->ChannelsDefaultMask[4] & CHANNELS_MASK_500KHZ_MASK; + RegionNvmGroup2->ChannelsDefaultMask[5] = 0x0000; for( uint8_t i = 0; i < CHANNELS_MASK_SIZE; i++ ) { // Copy-And the channels mask - NvmCtx.ChannelsMaskRemaining[i] &= NvmCtx.ChannelsMask[i]; + RegionNvmGroup1->ChannelsMaskRemaining[i] &= RegionNvmGroup2->ChannelsMask[i]; } break; } case CHANNELS_DEFAULT_MASK: { - RegionCommonChanMaskCopy( NvmCtx.ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, CHANNELS_MASK_SIZE ); break; } default: @@ -586,7 +544,7 @@ bool RegionUS915RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate ) bool RegionUS915TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir ) { int8_t phyDr = DataratesUS915[txConfig->Datarate]; - int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, NvmCtx.Bands[NvmCtx.Channels[txConfig->Channel].Band].TxMaxPower, txConfig->Datarate, NvmCtx.ChannelsMask ); + int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txConfig->Channel].Band].TxMaxPower, txConfig->Datarate, RegionNvmGroup2->ChannelsMask ); uint32_t bandwidth = RegionCommonGetBandwidth( txConfig->Datarate, BandwidthsUS915 ); int8_t phyTxPower = 0; @@ -594,7 +552,7 @@ bool RegionUS915TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime phyTxPower = RegionCommonComputeTxPower( txPowerLimited, US915_DEFAULT_MAX_ERP, 0 ); // Setup the radio frequency - Radio.SetChannel( NvmCtx.Channels[txConfig->Channel].Frequency ); + Radio.SetChannel( RegionNvmGroup2->Channels[txConfig->Channel].Frequency ); Radio.SetTxConfig( MODEM_LORA, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 4000 ); @@ -620,7 +578,7 @@ uint8_t RegionUS915LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in RegionCommonLinkAdrReqVerifyParams_t linkAdrVerifyParams; // Initialize local copy of channels mask - RegionCommonChanMaskCopy( channelsMask, NvmCtx.ChannelsMask, CHANNELS_MASK_SIZE ); + RegionCommonChanMaskCopy( channelsMask, RegionNvmGroup2->ChannelsMask, CHANNELS_MASK_SIZE ); while( bytesProcessed < linkAdrReq->PayloadSize ) { @@ -739,7 +697,7 @@ uint8_t RegionUS915LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in linkAdrVerifyParams.ChannelsMask = channelsMask; linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value; linkAdrVerifyParams.MaxDatarate = US915_TX_MAX_DATARATE; - linkAdrVerifyParams.Channels = NvmCtx.Channels; + linkAdrVerifyParams.Channels = RegionNvmGroup2->Channels; linkAdrVerifyParams.MinTxPower = US915_MIN_TX_POWER; linkAdrVerifyParams.MaxTxPower = US915_MAX_TX_POWER; linkAdrVerifyParams.Version = linkAdrReq->Version; @@ -751,14 +709,14 @@ uint8_t RegionUS915LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, in if( status == 0x07 ) { // Copy Mask - RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, channelsMask, 6 ); - - NvmCtx.ChannelsMaskRemaining[0] &= NvmCtx.ChannelsMask[0]; - NvmCtx.ChannelsMaskRemaining[1] &= NvmCtx.ChannelsMask[1]; - NvmCtx.ChannelsMaskRemaining[2] &= NvmCtx.ChannelsMask[2]; - NvmCtx.ChannelsMaskRemaining[3] &= NvmCtx.ChannelsMask[3]; - NvmCtx.ChannelsMaskRemaining[4] = NvmCtx.ChannelsMask[4]; - NvmCtx.ChannelsMaskRemaining[5] = NvmCtx.ChannelsMask[5]; + RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, channelsMask, 6 ); + + RegionNvmGroup1->ChannelsMaskRemaining[0] &= RegionNvmGroup2->ChannelsMask[0]; + RegionNvmGroup1->ChannelsMaskRemaining[1] &= RegionNvmGroup2->ChannelsMask[1]; + RegionNvmGroup1->ChannelsMaskRemaining[2] &= RegionNvmGroup2->ChannelsMask[2]; + RegionNvmGroup1->ChannelsMaskRemaining[3] &= RegionNvmGroup2->ChannelsMask[3]; + RegionNvmGroup1->ChannelsMaskRemaining[4] = RegionNvmGroup2->ChannelsMask[4]; + RegionNvmGroup1->ChannelsMaskRemaining[5] = RegionNvmGroup2->ChannelsMask[5]; } // Update status variables @@ -824,14 +782,14 @@ int8_t RegionUS915AlternateDr( int8_t currentDr, AlternateDrType_t type ) // Eight times a 125kHz DR_0 and then one 500kHz DR_4 channel if( type == ALTERNATE_DR ) { - NvmCtx.JoinTrialsCounter++; + RegionNvmGroup1->JoinTrialsCounter++; } else { - NvmCtx.JoinTrialsCounter--; + RegionNvmGroup1->JoinTrialsCounter--; } - if( NvmCtx.JoinTrialsCounter % 9 == 0 ) + if( RegionNvmGroup1->JoinTrialsCounter % 9 == 0 ) { // Use DR_4 every 9th times. currentDr = DR_4; @@ -853,27 +811,27 @@ LoRaMacStatus_t RegionUS915NextChannel( NextChanParams_t* nextChanParams, uint8_ LoRaMacStatus_t status = LORAMAC_STATUS_NO_CHANNEL_FOUND; // Count 125kHz channels - if( RegionCommonCountChannels( NvmCtx.ChannelsMaskRemaining, 0, 4 ) == 0 ) + if( RegionCommonCountChannels( RegionNvmGroup1->ChannelsMaskRemaining, 0, 4 ) == 0 ) { // Reactivate default channels - RegionCommonChanMaskCopy( NvmCtx.ChannelsMaskRemaining, NvmCtx.ChannelsMask, 4 ); + RegionCommonChanMaskCopy( RegionNvmGroup1->ChannelsMaskRemaining, RegionNvmGroup2->ChannelsMask, 4 ); - NvmCtx.JoinChannelGroupsCurrentIndex = 0; + RegionNvmGroup1->JoinChannelGroupsCurrentIndex = 0; } // Check other channels if( nextChanParams->Datarate >= DR_4 ) { - if( ( NvmCtx.ChannelsMaskRemaining[4] & CHANNELS_MASK_500KHZ_MASK ) == 0 ) + if( ( RegionNvmGroup1->ChannelsMaskRemaining[4] & CHANNELS_MASK_500KHZ_MASK ) == 0 ) { - NvmCtx.ChannelsMaskRemaining[4] = NvmCtx.ChannelsMask[4]; + RegionNvmGroup1->ChannelsMaskRemaining[4] = RegionNvmGroup2->ChannelsMask[4]; } } // Search how many channels are enabled countChannelsParams.Joined = nextChanParams->Joined; countChannelsParams.Datarate = nextChanParams->Datarate; - countChannelsParams.ChannelsMask = NvmCtx.ChannelsMaskRemaining; - countChannelsParams.Channels = NvmCtx.Channels; - countChannelsParams.Bands = NvmCtx.Bands; + countChannelsParams.ChannelsMask = RegionNvmGroup1->ChannelsMaskRemaining; + countChannelsParams.Channels = RegionNvmGroup2->Channels; + countChannelsParams.Bands = RegionNvmGroup1->Bands; countChannelsParams.MaxNbChannels = US915_MAX_NB_CHANNELS; countChannelsParams.JoinChannels = NULL; @@ -908,8 +866,8 @@ LoRaMacStatus_t RegionUS915NextChannel( NextChanParams_t* nextChanParams, uint8_ // 125kHz Channels (0 - 63) DR0 if( nextChanParams->Datarate == DR_0 ) { - if( RegionBaseUSComputeNext125kHzJoinChannel( ( uint16_t* ) NvmCtx.ChannelsMaskRemaining, - &NvmCtx.JoinChannelGroupsCurrentIndex, channel ) == LORAMAC_STATUS_PARAMETER_INVALID ) + if( RegionBaseUSComputeNext125kHzJoinChannel( ( uint16_t* ) RegionNvmGroup1->ChannelsMaskRemaining, + &RegionNvmGroup1->JoinChannelGroupsCurrentIndex, channel ) == LORAMAC_STATUS_PARAMETER_INVALID ) { return LORAMAC_STATUS_PARAMETER_INVALID; } @@ -919,7 +877,7 @@ LoRaMacStatus_t RegionUS915NextChannel( NextChanParams_t* nextChanParams, uint8_ { // Choose the next available channel uint8_t i = 0; - while( ( ( NvmCtx.ChannelsMaskRemaining[4] & CHANNELS_MASK_500KHZ_MASK ) & ( 1 << i ) ) == 0 ) + while( ( ( RegionNvmGroup1->ChannelsMaskRemaining[4] & CHANNELS_MASK_500KHZ_MASK ) & ( 1 << i ) ) == 0 ) { i++; } @@ -928,7 +886,7 @@ LoRaMacStatus_t RegionUS915NextChannel( NextChanParams_t* nextChanParams, uint8_ } // Disable the channel in the mask - RegionCommonChanDisable( NvmCtx.ChannelsMaskRemaining, *channel, US915_MAX_NB_CHANNELS ); + RegionCommonChanDisable( RegionNvmGroup1->ChannelsMaskRemaining, *channel, US915_MAX_NB_CHANNELS ); } return status; } @@ -945,9 +903,9 @@ bool RegionUS915ChannelsRemove( ChannelRemoveParams_t* channelRemove ) void RegionUS915SetContinuousWave( ContinuousWaveParams_t* continuousWave ) { - int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, NvmCtx.Bands[NvmCtx.Channels[continuousWave->Channel].Band].TxMaxPower, continuousWave->Datarate, NvmCtx.ChannelsMask ); + int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[continuousWave->Channel].Band].TxMaxPower, continuousWave->Datarate, RegionNvmGroup2->ChannelsMask ); int8_t phyTxPower = 0; - uint32_t frequency = NvmCtx.Channels[continuousWave->Channel].Frequency; + uint32_t frequency = RegionNvmGroup2->Channels[continuousWave->Channel].Frequency; // Calculate physical TX power phyTxPower = RegionCommonComputeTxPower( txPowerLimited, US915_DEFAULT_MAX_ERP, 0 ); diff --git a/src/mac/region/RegionUS915.h b/src/mac/region/RegionUS915.h index 7bb7fea1c..25b61fe64 100644 --- a/src/mac/region/RegionUS915.h +++ b/src/mac/region/RegionUS915.h @@ -258,15 +258,6 @@ void RegionUS915SetBandTxDone( SetBandTxDoneParams_t* txDone ); */ void RegionUS915InitDefaults( InitDefaultsParams_t* params ); -/*! - * \brief Returns a pointer to the internal context and its size. - * - * \param [OUT] params Pointer to the function parameters. - * - * \retval Points to a structure where the module store its non-volatile context. - */ -void* RegionUS915GetNvmCtx( GetNvmCtxParams_t* params ); - /*! * \brief Verifies a parameter. * diff --git a/src/mac/secure-element-nvm.h b/src/mac/secure-element-nvm.h new file mode 100644 index 000000000..39e4d3c00 --- /dev/null +++ b/src/mac/secure-element-nvm.h @@ -0,0 +1,116 @@ +/*! + * \file secure-element-nvm.h + * + * \brief Secure Element non-volatile data. + * + * \copyright Revised BSD License, see section \ref LICENSE. + * + * \code + * ______ _ + * / _____) _ | | + * ( (____ _____ ____ _| |_ _____ ____| |__ + * \____ \| ___ | (_ _) ___ |/ ___) _ \ + * _____) ) ____| | | || |_| ____( (___| | | | + * (______/|_____)_|_|_| \__)_____)\____)_| |_| + * (C)2013 Semtech + * + * ___ _____ _ ___ _ _____ ___ ___ ___ ___ + * / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| + * \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| + * |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| + * embedded.connectivity.solutions=============== + * + * \endcode + * + * \author Miguel Luis ( Semtech ) + * + * \author Daniel Jaeckle ( STACKFORCE ) + * + * \addtogroup SECUREELEMENT + * + * \{ + * + */ +#ifndef __SECURE_ELEMENT_NVM_H__ +#define __SECURE_ELEMENT_NVM_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include "LoRaMacTypes.h" + +/*! + * Secure-element keys size in bytes + */ +#define SE_KEY_SIZE 16 + +/*! + * Secure-element EUI size in bytes + */ +#define SE_EUI_SIZE 8 + +/*! + * Secure-element pin size in bytes + */ +#define SE_PIN_SIZE 4 + +#ifdef SOFT_SE +/*! + * Number of supported crypto keys for the soft-se + */ +#define NUM_OF_KEYS 23 + +/*! + * Key structure definition for the soft-se + */ +typedef struct sKey +{ + /*! + * Key identifier + */ + KeyIdentifier_t KeyID; + /*! + * Key value + */ + uint8_t KeyValue[SE_KEY_SIZE]; +} Key_t; +#endif + +typedef struct sSecureElementNvCtx +{ + /*! + * DevEUI storage + */ + uint8_t DevEui[SE_EUI_SIZE]; + /*! + * Join EUI storage + */ + uint8_t JoinEui[SE_EUI_SIZE]; + /*! + * Pin storage + */ + uint8_t Pin[SE_PIN_SIZE]; +#ifdef SOFT_SE + /*! + * The key list is required for the soft-se only. All other secure-elements + * handle the storage on their own. + */ + Key_t KeyList[NUM_OF_KEYS]; +#endif + /*! + * CRC32 value of the SecureElement data structure. + */ + uint32_t Crc32; +} SecureElementNvmData_t; + + +/*! \} addtogroup SECUREELEMENT */ + +#ifdef __cplusplus +} +#endif + +#endif // __SECURE_ELEMENT_NVM_H__ diff --git a/src/mac/secure-element.h b/src/mac/secure-element.h index c5ec49315..1c169f1b8 100644 --- a/src/mac/secure-element.h +++ b/src/mac/secure-element.h @@ -45,21 +45,7 @@ extern "C" #include #include "LoRaMacCrypto.h" - -/*! - * Secure-element keys size in bytes - */ -#define SE_KEY_SIZE 16 - -/*! - * Secure-element EUI size in bytes - */ -#define SE_EUI_SIZE 8 - -/*! - * Secure-element pin size in bytes - */ -#define SE_PIN_SIZE 4 +#include "secure-element-nvm.h" /*! * Return values. @@ -100,37 +86,14 @@ typedef enum eSecureElementStatus SECURE_ELEMENT_FAIL_ENCRYPT, }SecureElementStatus_t; -/*! - * Signature of callback function to be called by the Secure Element driver when the - * non volatile context have to be stored. - * - */ -typedef void ( *SecureElementNvmEvent )( void ); - /*! * Initialization of Secure Element driver * - * \param[IN] seNvmCtxChanged - Callback function which will be called when the - * non-volatile context have to be stored. - * \retval - Status of the operation - */ -SecureElementStatus_t SecureElementInit( SecureElementNvmEvent seNvmCtxChanged ); - -/*! - * Restores the internal nvm context from passed pointer. - * - * \param[IN] seNvmCtx - Pointer to non-volatile module context to be restored. + * \param[IN] nvm - Pointer to the non-volatile memory data + * structure. * \retval - Status of the operation */ -SecureElementStatus_t SecureElementRestoreNvmCtx( void* seNvmCtx ); - -/*! - * Returns a pointer to the internal non-volatile context. - * - * \param[IN] seNvmCtxSize - Size of the module non volatile context - * \retval - Points to a structure where the module store its non volatile context - */ -void* SecureElementGetNvmCtx( size_t* seNvmCtxSize ); +SecureElementStatus_t SecureElementInit( SecureElementNvmData_t* nvm ); /*! * Sets a key diff --git a/src/peripherals/CMakeLists.txt b/src/peripherals/CMakeLists.txt index e9521a8b0..7ed0cf0cd 100644 --- a/src/peripherals/CMakeLists.txt +++ b/src/peripherals/CMakeLists.txt @@ -54,13 +54,14 @@ endif() if(${SECURE_ELEMENT} MATCHES SOFT_SE) target_include_directories( ${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/soft-se) + target_compile_definitions(${PROJECT_NAME} PRIVATE -DSOFT_SE) else() if(${SECURE_ELEMENT} MATCHES LR1110_SE) if(${RADIO} MATCHES lr1110) target_include_directories( ${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/lr1110-se) endif() elseif((${SECURE_ELEMENT} MATCHES ATECC608A_TNGLORA_SE)) - target_include_directories( ${PROJECT_NAME} PUBLIC + target_include_directories( ${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/atecc608a-tnglora-se ${CMAKE_CURRENT_SOURCE_DIR}/atecc608a-tnglora-se/cryptoauthlib/lib ${CMAKE_CURRENT_SOURCE_DIR}/atecc608a-tnglora-se/cryptoauthlib/lib/basic diff --git a/src/peripherals/atecc608a-tnglora-se/atecc608a-tnglora-se.c b/src/peripherals/atecc608a-tnglora-se/atecc608a-tnglora-se.c index 014a6bc0a..d0d66b39f 100644 --- a/src/peripherals/atecc608a-tnglora-se/atecc608a-tnglora-se.c +++ b/src/peripherals/atecc608a-tnglora-se/atecc608a-tnglora-se.c @@ -38,6 +38,7 @@ #include "atca_devtypes.h" #include "secure-element.h" +#include "secure-element-nvm.h" #include "se-identity.h" #include "atecc608a-tnglora-se-hal.h" @@ -67,52 +68,9 @@ typedef struct sKey uint8_t KeyBlockIndex; } Key_t; -/* - * Secure Element Non Volatile Context structure - */ -typedef struct sSecureElementNvCtx -{ - /*! - * DevEUI storage - */ - uint8_t DevEui[SE_EUI_SIZE]; - /*! - * Join EUI storage - */ - uint8_t JoinEui[SE_EUI_SIZE]; - /*! - * Pin storage - */ - uint8_t Pin[SE_PIN_SIZE]; - /*! - * LoRaWAN key list - */ - Key_t KeyList[NUM_OF_KEYS]; -} SecureElementNvCtx_t; +static SecureElementNvmData_t* SeNvm; -/*! - * Secure element context - */ -static SecureElementNvCtx_t SeNvmCtx = { - /*! - * end-device IEEE EUI (big endian) - */ - .DevEui = { 0 }, - /*! - * App/Join server IEEE EUI (big endian) - */ - .JoinEui = { 0 }, - /*! - * Secure-element pin (big endian) - */ - .Pin = SECURE_ELEMENT_PIN, - /*! - * LoRaWAN key list - */ - .KeyList = ATECC608A_SE_KEY_LIST -}; - -static SecureElementNvmEvent SeNvmCtxChanged; +static Key_t KeyList[NUM_OF_KEYS] = ATECC608A_SE_KEY_LIST; static ATCAIfaceCfg atecc608_i2c_config; @@ -225,23 +183,15 @@ SecureElementStatus_t GetKeyByID( KeyIdentifier_t keyID, Key_t** keyItem ) { for( uint8_t i = 0; i < NUM_OF_KEYS; i++ ) { - if( SeNvmCtx.KeyList[i].KeyID == keyID ) + if( KeyList[i].KeyID == keyID ) { - *keyItem = &( SeNvmCtx.KeyList[i] ); + *keyItem = &( KeyList[i] ); return SECURE_ELEMENT_SUCCESS; } } return SECURE_ELEMENT_ERROR_INVALID_KEY_ID; } -/* - * Dummy callback in case if the user provides NULL function pointer - */ -static void DummyCB( void ) -{ - return; -} - /* * Computes a CMAC of a message using provided initial Bx block * @@ -296,8 +246,35 @@ static SecureElementStatus_t ComputeCmac( uint8_t* micBxBuffer, uint8_t* buffer, } } -SecureElementStatus_t SecureElementInit( SecureElementNvmEvent seNvmCtxChanged ) +SecureElementStatus_t SecureElementInit( SecureElementNvmData_t* nvm ) { + SecureElementNvmData_t seNvmInit = + { + /*! + * end-device IEEE EUI (big endian) + */ + .DevEui = { 0 }, + /*! + * App/Join server IEEE EUI (big endian) + */ + .JoinEui = { 0 }, + /*! + * Secure-element pin (big endian) + */ + .Pin = SECURE_ELEMENT_PIN, + }; + + if( nvm == NULL ) + { + return SECURE_ELEMENT_ERROR_NPE; + } + + // Initialize nvm pointer + SeNvm = nvm; + + // Initialize data + memcpy1( ( uint8_t* )SeNvm, ( uint8_t* )&seNvmInit, sizeof( seNvmInit ) ); + #if !defined( SECURE_ELEMENT_PRE_PROVISIONED ) #error "ATECC608A is always pre-provisioned. Please set SECURE_ELEMENT_PRE_PROVISIONED to ON" #endif @@ -314,49 +291,18 @@ SecureElementStatus_t SecureElementInit( SecureElementNvmEvent seNvmCtxChanged ) return SECURE_ELEMENT_ERROR; } - if( atcab_read_devEUI( SeNvmCtx.DevEui ) != ATCA_SUCCESS ) + if( atcab_read_devEUI( SeNvm->DevEui ) != ATCA_SUCCESS ) { return SECURE_ELEMENT_ERROR; } - if( atcab_read_joinEUI( SeNvmCtx.JoinEui ) != ATCA_SUCCESS ) + if( atcab_read_joinEUI( SeNvm->JoinEui ) != ATCA_SUCCESS ) { return SECURE_ELEMENT_ERROR; } - - // Assign callback - if( seNvmCtxChanged != 0 ) - { - SeNvmCtxChanged = seNvmCtxChanged; - } - else - { - SeNvmCtxChanged = DummyCB; - } - return SECURE_ELEMENT_SUCCESS; } -SecureElementStatus_t SecureElementRestoreNvmCtx( void* seNvmCtx ) -{ - // Restore nvm context - if( seNvmCtx != 0 ) - { - memcpy1( ( uint8_t* ) &SeNvmCtx, ( uint8_t* ) seNvmCtx, sizeof( SeNvmCtx ) ); - return SECURE_ELEMENT_SUCCESS; - } - else - { - return SECURE_ELEMENT_ERROR_NPE; - } -} - -void* SecureElementGetNvmCtx( size_t* seNvmCtxSize ) -{ - *seNvmCtxSize = sizeof( SeNvmCtx ); - return &SeNvmCtx; -} - SecureElementStatus_t SecureElementSetKey( KeyIdentifier_t keyID, uint8_t* key ) { // No key setting for HW SE, can only derive keys @@ -600,14 +546,13 @@ SecureElementStatus_t SecureElementSetDevEui( uint8_t* devEui ) { return SECURE_ELEMENT_ERROR_NPE; } - memcpy1( SeNvmCtx.DevEui, devEui, SE_EUI_SIZE ); - SeNvmCtxChanged( ); + memcpy1( SeNvm->DevEui, devEui, SE_EUI_SIZE ); return SECURE_ELEMENT_SUCCESS; } uint8_t* SecureElementGetDevEui( void ) { - return SeNvmCtx.DevEui; + return SeNvm->DevEui; } SecureElementStatus_t SecureElementSetJoinEui( uint8_t* joinEui ) @@ -616,14 +561,13 @@ SecureElementStatus_t SecureElementSetJoinEui( uint8_t* joinEui ) { return SECURE_ELEMENT_ERROR_NPE; } - memcpy1( SeNvmCtx.JoinEui, joinEui, SE_EUI_SIZE ); - SeNvmCtxChanged( ); + memcpy1( SeNvm->JoinEui, joinEui, SE_EUI_SIZE ); return SECURE_ELEMENT_SUCCESS; } uint8_t* SecureElementGetJoinEui( void ) { - return SeNvmCtx.JoinEui; + return SeNvm->JoinEui; } SecureElementStatus_t SecureElementSetPin( uint8_t* pin ) @@ -633,12 +577,11 @@ SecureElementStatus_t SecureElementSetPin( uint8_t* pin ) return SECURE_ELEMENT_ERROR_NPE; } - memcpy1( SeNvmCtx.Pin, pin, SE_PIN_SIZE ); - SeNvmCtxChanged( ); + memcpy1( SeNvm->Pin, pin, SE_PIN_SIZE ); return SECURE_ELEMENT_SUCCESS; } uint8_t* SecureElementGetPin( void ) { - return SeNvmCtx.Pin; + return SeNvm->Pin; } diff --git a/src/peripherals/atecc608a-tnglora-se/se-identity.h b/src/peripherals/atecc608a-tnglora-se/se-identity.h index 70395d06b..53b97990c 100644 --- a/src/peripherals/atecc608a-tnglora-se/se-identity.h +++ b/src/peripherals/atecc608a-tnglora-se/se-identity.h @@ -241,7 +241,7 @@ extern "C" { .KeySlotNumber = 0, \ .KeyBlockIndex = 0, \ }, \ - }, + } #ifdef __cplusplus } diff --git a/src/peripherals/lr1110-se/lr1110-se.c b/src/peripherals/lr1110-se/lr1110-se.c index c73104744..7649a3a75 100644 --- a/src/peripherals/lr1110-se/lr1110-se.c +++ b/src/peripherals/lr1110-se/lr1110-se.c @@ -26,6 +26,7 @@ #include "lr1110_crypto_engine.h" #include "secure-element.h" +#include "secure-element-nvm.h" #include "se-identity.h" #include "lr1110-se-hal.h" @@ -49,44 +50,7 @@ */ #define CRYPTO_BUFFER_SIZE CRYPTO_MAXMESSAGE_SIZE + MIC_BLOCK_BX_SIZE -/*! - * Secure-element LoRaWAN identity local storage. - */ -typedef struct sSecureElementNvCtx -{ - /* - * DevEUI storage - */ - uint8_t DevEui[SE_EUI_SIZE]; - /* - * Join EUI storage - */ - uint8_t JoinEui[SE_EUI_SIZE]; - /* - * PIN of the LR1110 - */ - uint8_t Pin[SE_PIN_SIZE]; -} SecureElementNvCtx_t; - -static SecureElementNvCtx_t SeContext = { - /*! - * end-device IEEE EUI (big endian) - * - * \remark In this application the value is automatically generated by calling - * BoardGetUniqueId function - */ - .DevEui = LORAWAN_DEVICE_EUI, - /*! - * App/Join server IEEE EUI (big endian) - */ - .JoinEui = LORAWAN_JOIN_EUI, - /*! - * Secure-element pin (big endian) - */ - .Pin = SECURE_ELEMENT_PIN, -}; - -static SecureElementNvmEvent SeNvmCtxChanged; +static SecureElementNvmData_t* SeNvm; /*! * LR1110 radio context @@ -102,71 +66,51 @@ extern lr1110_t LR1110; */ static lr1110_crypto_keys_idx_t convert_key_id_from_se_to_lr1110( KeyIdentifier_t key_id ); -/*! - * Dummy callback in case if the user provides NULL function pointer - */ -static void DummyCB( void ) -{ - return; -} - -SecureElementStatus_t SecureElementInit( SecureElementNvmEvent seNvmCtxChanged ) +SecureElementStatus_t SecureElementInit( SecureElementNvmData_t* nvm ) { lr1110_crypto_status_t status = LR1110_CRYPTO_STATUS_ERROR; - - // Assign callback - if( seNvmCtxChanged != 0 ) - { - SeNvmCtxChanged = seNvmCtxChanged; - } - else + SecureElementNvmData_t seNvmInit = { - SeNvmCtxChanged = DummyCB; - } + /*! + * end-device IEEE EUI (big endian) + * + * \remark In this application the value is automatically generated by calling + * BoardGetUniqueId function + */ + .DevEui = LORAWAN_DEVICE_EUI, + /*! + * App/Join server IEEE EUI (big endian) + */ + .JoinEui = LORAWAN_JOIN_EUI, + /*! + * Secure-element pin (big endian) + */ + .Pin = SECURE_ELEMENT_PIN, + }; + + // Initialize nvm pointer + SeNvm = nvm; + + // Initialize data + memcpy1( ( uint8_t* )SeNvm, ( uint8_t* )&seNvmInit, sizeof( seNvmInit ) ); lr1110_crypto_restore_from_flash( &LR1110, &status ); #if defined( SECURE_ELEMENT_PRE_PROVISIONED ) // Read LR1110 pre-provisioned identity - lr1110_system_read_uid( &LR1110, SeContext.DevEui ); - lr1110_system_read_join_eui( &LR1110, SeContext.JoinEui ); - lr1110_system_read_pin( &LR1110, SeContext.Pin ); + lr1110_system_read_uid( &LR1110, SeNvm->DevEui ); + lr1110_system_read_join_eui( &LR1110, SeNvm->JoinEui ); + lr1110_system_read_pin( &LR1110, SeNvm->Pin ); #else #if( STATIC_DEVICE_EUI == 0 ) // Get a DevEUI from MCU unique ID - LR1110SeHalGetUniqueId( SeContext.DevEui ); + LR1110SeHalGetUniqueId( SeNvm->DevEui ); #endif #endif - SeNvmCtxChanged( ); - - return ( SecureElementStatus_t ) status; -} - -SecureElementStatus_t SecureElementRestoreNvmCtx( void* seNvmCtx ) -{ - lr1110_crypto_status_t status = LR1110_CRYPTO_STATUS_ERROR; - - if( seNvmCtx == NULL ) - { - return SECURE_ELEMENT_ERROR_NPE; - } - - // Restore lr1110 crypto context - lr1110_crypto_restore_from_flash( &LR1110, &status ); - - // Restore nvm context - memcpy1( ( uint8_t* ) &SeContext, ( uint8_t* ) seNvmCtx, sizeof( SeContext ) ); - return ( SecureElementStatus_t ) status; } -void* SecureElementGetNvmCtx( size_t* seNvmCtxSize ) -{ - *seNvmCtxSize = sizeof( SeContext ); - return &SeContext; -} - SecureElementStatus_t SecureElementSetKey( KeyIdentifier_t keyID, uint8_t* key ) { if( key == NULL ) @@ -380,14 +324,13 @@ SecureElementStatus_t SecureElementSetDevEui( uint8_t* devEui ) { return SECURE_ELEMENT_ERROR_NPE; } - memcpy1( SeContext.DevEui, devEui, SE_EUI_SIZE ); - SeNvmCtxChanged( ); + memcpy1( SeNvm->DevEui, devEui, SE_EUI_SIZE ); return SECURE_ELEMENT_SUCCESS; } uint8_t* SecureElementGetDevEui( void ) { - return SeContext.DevEui; + return SeNvm->DevEui; } SecureElementStatus_t SecureElementSetJoinEui( uint8_t* joinEui ) @@ -396,14 +339,13 @@ SecureElementStatus_t SecureElementSetJoinEui( uint8_t* joinEui ) { return SECURE_ELEMENT_ERROR_NPE; } - memcpy1( SeContext.JoinEui, joinEui, SE_EUI_SIZE ); - SeNvmCtxChanged( ); + memcpy1( SeNvm->JoinEui, joinEui, SE_EUI_SIZE ); return SECURE_ELEMENT_SUCCESS; } uint8_t* SecureElementGetJoinEui( void ) { - return SeContext.JoinEui; + return SeNvm->JoinEui; } SecureElementStatus_t SecureElementSetPin( uint8_t* pin ) @@ -413,14 +355,13 @@ SecureElementStatus_t SecureElementSetPin( uint8_t* pin ) return SECURE_ELEMENT_ERROR_NPE; } - memcpy1( SeContext.Pin, pin, SE_PIN_SIZE ); - SeNvmCtxChanged( ); + memcpy1( SeNvm->Pin, pin, SE_PIN_SIZE ); return SECURE_ELEMENT_SUCCESS; } uint8_t* SecureElementGetPin( void ) { - return SeContext.Pin; + return SeNvm->Pin; } static lr1110_crypto_keys_idx_t convert_key_id_from_se_to_lr1110( KeyIdentifier_t key_id ) diff --git a/src/peripherals/soft-se/soft-se.c b/src/peripherals/soft-se/soft-se.c index dede2af93..c34fda624 100644 --- a/src/peripherals/soft-se/soft-se.c +++ b/src/peripherals/soft-se/soft-se.c @@ -33,78 +33,11 @@ #include "LoRaMacHeaderTypes.h" #include "secure-element.h" +#include "secure-element-nvm.h" #include "se-identity.h" #include "soft-se-hal.h" -/*! - * Number of supported crypto keys - */ -#define NUM_OF_KEYS 23 - -/*! - * Identifier value pair type for Keys - */ -typedef struct sKey -{ - /* - * Key identifier - */ - KeyIdentifier_t KeyID; - /* - * Key value - */ - uint8_t KeyValue[SE_KEY_SIZE]; -} Key_t; - -/* - * Secure Element Non Volatile Context structure - */ -typedef struct sSecureElementNvCtx -{ - /* - * DevEUI storage - */ - uint8_t DevEui[SE_EUI_SIZE]; - /* - * Join EUI storage - */ - uint8_t JoinEui[SE_EUI_SIZE]; - /* - * Pin storage - */ - uint8_t Pin[SE_PIN_SIZE]; - /* - * Key List - */ - Key_t KeyList[NUM_OF_KEYS]; -} SecureElementNvCtx_t; - -/*! - * Secure element context - */ -static SecureElementNvCtx_t SeNvmCtx = { - /*! - * end-device IEEE EUI (big endian) - * - * \remark In this application the value is automatically generated by calling - * BoardGetUniqueId function - */ - .DevEui = LORAWAN_DEVICE_EUI, - /*! - * App/Join server IEEE EUI (big endian) - */ - .JoinEui = LORAWAN_JOIN_EUI, - /*! - * Secure-element pin (big endian) - */ - .Pin = SECURE_ELEMENT_PIN, - /*! - * LoRaWAN key list - */ - .KeyList = SOFT_SE_KEY_LIST -}; - -static SecureElementNvmEvent SeNvmCtxChanged; +static SecureElementNvmData_t* SeNvm; /* * Local functions @@ -121,23 +54,15 @@ static SecureElementStatus_t GetKeyByID( KeyIdentifier_t keyID, Key_t** keyItem { for( uint8_t i = 0; i < NUM_OF_KEYS; i++ ) { - if( SeNvmCtx.KeyList[i].KeyID == keyID ) + if( SeNvm->KeyList[i].KeyID == keyID ) { - *keyItem = &( SeNvmCtx.KeyList[i] ); + *keyItem = &( SeNvm->KeyList[i] ); return SECURE_ELEMENT_SUCCESS; } } return SECURE_ELEMENT_ERROR_INVALID_KEY_ID; } -/* - * Dummy callback in case if the user provides NULL function pointer - */ -static void DummyCB( void ) -{ - return; -} - /* * Computes a CMAC of a message using provided initial Bx block * @@ -191,50 +116,52 @@ static SecureElementStatus_t ComputeCmac( uint8_t* micBxBuffer, uint8_t* buffer, * API functions */ -SecureElementStatus_t SecureElementInit( SecureElementNvmEvent seNvmCtxChanged ) +SecureElementStatus_t SecureElementInit( SecureElementNvmData_t* nvm ) { - // Assign callback - if( seNvmCtxChanged != 0 ) + SecureElementNvmData_t seNvmInit = { - SeNvmCtxChanged = seNvmCtxChanged; - } - else + /*! + * end-device IEEE EUI (big endian) + * + * \remark In this application the value is automatically generated by + * calling BoardGetUniqueId function + */ + .DevEui = LORAWAN_DEVICE_EUI, + /*! + * App/Join server IEEE EUI (big endian) + */ + .JoinEui = LORAWAN_JOIN_EUI, + /*! + * Secure-element pin (big endian) + */ + .Pin = SECURE_ELEMENT_PIN, + /*! + * LoRaWAN key list + */ + .KeyList = SOFT_SE_KEY_LIST + }; + + + if( nvm == NULL ) { - SeNvmCtxChanged = DummyCB; + return SECURE_ELEMENT_ERROR_NPE; } + // Initialize nvm pointer + SeNvm = nvm; + + // Initialize data + memcpy1( ( uint8_t* )SeNvm, ( uint8_t* )&seNvmInit, sizeof( seNvmInit ) ); + #if !defined( SECURE_ELEMENT_PRE_PROVISIONED ) #if( STATIC_DEVICE_EUI == 0 ) // Get a DevEUI from MCU unique ID - SoftSeHalGetUniqueId( SeNvmCtx.DevEui ); + SoftSeHalGetUniqueId( SeNvm->DevEui ); #endif #endif - - SeNvmCtxChanged( ); - return SECURE_ELEMENT_SUCCESS; } -SecureElementStatus_t SecureElementRestoreNvmCtx( void* seNvmCtx ) -{ - // Restore nvm context - if( seNvmCtx != 0 ) - { - memcpy1( ( uint8_t* ) &SeNvmCtx, ( uint8_t* ) seNvmCtx, sizeof( SeNvmCtx ) ); - return SECURE_ELEMENT_SUCCESS; - } - else - { - return SECURE_ELEMENT_ERROR_NPE; - } -} - -void* SecureElementGetNvmCtx( size_t* seNvmCtxSize ) -{ - *seNvmCtxSize = sizeof( SeNvmCtx ); - return &SeNvmCtx; -} - SecureElementStatus_t SecureElementSetKey( KeyIdentifier_t keyID, uint8_t* key ) { if( key == NULL ) @@ -244,7 +171,7 @@ SecureElementStatus_t SecureElementSetKey( KeyIdentifier_t keyID, uint8_t* key ) for( uint8_t i = 0; i < NUM_OF_KEYS; i++ ) { - if( SeNvmCtx.KeyList[i].KeyID == keyID ) + if( SeNvm->KeyList[i].KeyID == keyID ) { if( ( keyID == MC_KEY_0 ) || ( keyID == MC_KEY_1 ) || ( keyID == MC_KEY_2 ) || ( keyID == MC_KEY_3 ) ) { // Decrypt the key if its a Mckey @@ -253,15 +180,12 @@ SecureElementStatus_t SecureElementSetKey( KeyIdentifier_t keyID, uint8_t* key ) retval = SecureElementAesEncrypt( key, 16, MC_KE_KEY, decryptedKey ); - memcpy1( SeNvmCtx.KeyList[i].KeyValue, decryptedKey, SE_KEY_SIZE ); - SeNvmCtxChanged( ); - + memcpy1( SeNvm->KeyList[i].KeyValue, decryptedKey, SE_KEY_SIZE ); return retval; } else { - memcpy1( SeNvmCtx.KeyList[i].KeyValue, key, SE_KEY_SIZE ); - SeNvmCtxChanged( ); + memcpy1( SeNvm->KeyList[i].KeyValue, key, SE_KEY_SIZE ); return SECURE_ELEMENT_SUCCESS; } } @@ -493,14 +417,13 @@ SecureElementStatus_t SecureElementSetDevEui( uint8_t* devEui ) { return SECURE_ELEMENT_ERROR_NPE; } - memcpy1( SeNvmCtx.DevEui, devEui, SE_EUI_SIZE ); - SeNvmCtxChanged( ); + memcpy1( SeNvm->DevEui, devEui, SE_EUI_SIZE ); return SECURE_ELEMENT_SUCCESS; } uint8_t* SecureElementGetDevEui( void ) { - return SeNvmCtx.DevEui; + return SeNvm->DevEui; } SecureElementStatus_t SecureElementSetJoinEui( uint8_t* joinEui ) @@ -509,14 +432,13 @@ SecureElementStatus_t SecureElementSetJoinEui( uint8_t* joinEui ) { return SECURE_ELEMENT_ERROR_NPE; } - memcpy1( SeNvmCtx.JoinEui, joinEui, SE_EUI_SIZE ); - SeNvmCtxChanged( ); + memcpy1( SeNvm->JoinEui, joinEui, SE_EUI_SIZE ); return SECURE_ELEMENT_SUCCESS; } uint8_t* SecureElementGetJoinEui( void ) { - return SeNvmCtx.JoinEui; + return SeNvm->JoinEui; } SecureElementStatus_t SecureElementSetPin( uint8_t* pin ) @@ -526,12 +448,11 @@ SecureElementStatus_t SecureElementSetPin( uint8_t* pin ) return SECURE_ELEMENT_ERROR_NPE; } - memcpy1( SeNvmCtx.Pin, pin, SE_PIN_SIZE ); - SeNvmCtxChanged( ); + memcpy1( SeNvm->Pin, pin, SE_PIN_SIZE ); return SECURE_ELEMENT_SUCCESS; } uint8_t* SecureElementGetPin( void ) { - return SeNvmCtx.Pin; + return SeNvm->Pin; } diff --git a/src/system/eeprom.c b/src/system/eeprom.c deleted file mode 100644 index c6e6d5ac4..000000000 --- a/src/system/eeprom.c +++ /dev/null @@ -1,54 +0,0 @@ -/*! - * \file eeprom.c - * - * \brief EEPROM driver implementation - * - * \copyright Revised BSD License, see section \ref LICENSE. - * - * \code - * ______ _ - * / _____) _ | | - * ( (____ _____ ____ _| |_ _____ ____| |__ - * \____ \| ___ | (_ _) ___ |/ ___) _ \ - * _____) ) ____| | | || |_| ____( (___| | | | - * (______/|_____)_|_|_| \__)_____)\____)_| |_| - * (C)2013-2017 Semtech - * - * \endcode - * - * \author Miguel Luis ( Semtech ) - * - * \author Gregory Cristian ( Semtech ) - */ -#include "eeprom-board.h" -#include "eeprom.h" - -uint8_t EepromWriteBuffer( uint16_t addr, uint8_t *buffer, uint16_t size ) -{ - // Boundary check - if( size > ( 0xFFFF - addr ) ) - { - return 0; - } - return EepromMcuWriteBuffer( addr, buffer, size ); -} - -uint8_t EepromReadBuffer( uint16_t addr, uint8_t *buffer, uint16_t size ) -{ - // Boundary check - if( size > ( 0xFFFF - addr ) ) - { - return 0; - } - return EepromMcuReadBuffer( addr, buffer, size ); -} - -void EepromSetDeviceAddr( uint8_t addr ) -{ - EepromMcuSetDeviceAddr( addr ); -} - -uint8_t EepromGetDeviceAddr( void ) -{ - return EepromMcuGetDeviceAddr( ); -} diff --git a/src/system/eeprom.h b/src/system/eeprom.h deleted file mode 100644 index e16560657..000000000 --- a/src/system/eeprom.h +++ /dev/null @@ -1,75 +0,0 @@ -/*! - * \file eeprom.h - * - * \brief EEPROM driver implementation - * - * \copyright Revised BSD License, see section \ref LICENSE. - * - * \code - * ______ _ - * / _____) _ | | - * ( (____ _____ ____ _| |_ _____ ____| |__ - * \____ \| ___ | (_ _) ___ |/ ___) _ \ - * _____) ) ____| | | || |_| ____( (___| | | | - * (______/|_____)_|_|_| \__)_____)\____)_| |_| - * (C)2013-2017 Semtech - * - * \endcode - * - * \author Miguel Luis ( Semtech ) - * - * \author Gregory Cristian ( Semtech ) - */ -#ifndef __EEPROM_H__ -#define __EEPROM_H__ - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include - -/*! - * Writes the given buffer to the EEPROM at the specified address. - * - * \param[IN] addr EEPROM address to write to - * \param[IN] buffer Pointer to the buffer to be written. - * \param[IN] size Size of the buffer to be written. - * \retval status [SUCCESS, FAIL] - */ -uint8_t EepromWriteBuffer( uint16_t addr, uint8_t *buffer, uint16_t size ); - -/*! - * Reads the EEPROM at the specified address to the given buffer. - * - * \param[IN] addr EEPROM address to read from - * \param[OUT] buffer Pointer to the buffer to be written with read data. - * \param[IN] size Size of the buffer to be read. - * \retval status [SUCCESS, FAIL] - */ -uint8_t EepromReadBuffer( uint16_t addr, uint8_t *buffer, uint16_t size ); - -/*! - * Sets the device address. - * - * \remark Useful for I2C external EEPROMS - * - * \param[IN] addr External EEPROM address - */ -void EepromSetDeviceAddr( uint8_t addr ); - -/*! - * Gets the current device address. - * - * \remark Useful for I2C external EEPROMS - * - * \retval addr External EEPROM address - */ -uint8_t EepromGetDeviceAddr( void ); - -#ifdef __cplusplus -} -#endif - -#endif // __EEPROM_H__ diff --git a/src/system/nvmm.c b/src/system/nvmm.c index d5c70d5b7..c832f192d 100644 --- a/src/system/nvmm.c +++ b/src/system/nvmm.c @@ -1,173 +1,89 @@ -/* - / _____) _ | | -( (____ _____ ____ _| |_ _____ ____| |__ - \____ \| ___ | (_ _) ___ |/ ___) _ \ - _____) ) ____| | | || |_| ____( (___| | | | -(______/|_____)_|_|_| \__)_____)\____)_| |_| - (C)2013 Semtech - ___ _____ _ ___ _ _____ ___ ___ ___ ___ -/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| -\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| -|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| -embedded.connectivity.solutions=============== - -Description: LoRa MAC layer cryptographic functionality implementation - -License: Revised BSD License, see LICENSE.TXT file include in the project - -Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ), - Daniel Jaeckle ( STACKFORCE ), Johannes Bruder ( STACKFORCE ) -*/ +/*! + * \file nvmm.c + * + * \brief None volatile memory management module + * + * \copyright Revised BSD License, see section \ref LICENSE. + * + * \code + * ______ _ + * / _____) _ | | + * ( (____ _____ ____ _| |_ _____ ____| |__ + * \____ \| ___ | (_ _) ___ |/ ___) _ \ + * _____) ) ____| | | || |_| ____( (___| | | | + * (______/|_____)_|_|_| \__)_____)\____)_| |_| + * (C)2013-2020 Semtech + * + * ___ _____ _ ___ _ _____ ___ ___ ___ ___ + * / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| + * \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| + * |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| + * embedded.connectivity.solutions=============== + * + * \endcode + */ #include #include "utilities.h" -#include "eeprom.h" +#include "eeprom-board.h" #include "nvmm.h" -#define NVMM_MAGIC_NUMBER 0xA23 - -typedef struct sDataBlockHeader -{ - /* - * Checksum - */ - size_t CSum; - /* - * Size of current data block - */ - size_t Num; -} DataBlockHeader_t; - -static uint16_t DataBlockAdrCnt = sizeof( DataBlockHeader_t ); - -static uint32_t ComputeChecksum( uint8_t* data, uint16_t size ) -{ - uint32_t checksum = NVMM_MAGIC_NUMBER; // Start with a magic number - - for( uint16_t i = 0; i < size; i++ ) - { - checksum += data[i]; - } - return checksum; -} - -static uint32_t ComputeChecksumNvm( uint16_t addr, uint16_t size ) +uint16_t NvmmWrite( uint8_t* src, uint16_t size, uint16_t offset ) { - uint32_t checksum = NVMM_MAGIC_NUMBER; // Start with a magic number - uint8_t data = 0; - - for( uint16_t i = 0; i < size; i++ ) - { - EepromReadBuffer( addr + i, &data, 1 ); - checksum += data; - } - return checksum; -} - -/* - * API functions - */ - -NvmmStatus_t NvmmDeclare( NvmmDataBlock_t* dataB, size_t num ) -{ - NvmmStatus_t retval = NVMM_ERROR; - - // Increment the internal data block address - dataB->virtualAddr = DataBlockAdrCnt; - - if( NvmmVerify( dataB, num ) == NVMM_SUCCESS ) - { - retval = NVMM_SUCCESS; - } - - // If it is the first time or memory was corrupted - else + if( EepromMcuWriteBuffer( offset, src, size ) == SUCCESS ) { - DataBlockHeader_t dataBHdr; - dataBHdr.CSum = 0; - dataBHdr.Num = num; - EepromWriteBuffer( ( dataB->virtualAddr - sizeof( DataBlockHeader_t ) ), ( uint8_t* ) &dataBHdr, sizeof( DataBlockHeader_t ) ); - - retval = NVMM_FAIL_CHECKSUM; + return size; } - - DataBlockAdrCnt = DataBlockAdrCnt + num + sizeof( DataBlockHeader_t ); - - return retval; + return 0; } -NvmmStatus_t NvmmVerify( NvmmDataBlock_t* dataB, size_t num ) +uint16_t NvmmRead( uint8_t* dest, uint16_t size, uint16_t offset ) { - DataBlockHeader_t dataBHdr; - - // Read the data block header to obtain the size of data block - EepromReadBuffer( ( dataB->virtualAddr - sizeof( DataBlockHeader_t ) ), ( uint8_t* ) &dataBHdr, sizeof( DataBlockHeader_t ) ); - - // Catch already a mismatch of sizes - if( num != dataBHdr.Num ) + if( EepromMcuReadBuffer( offset, dest, size ) == SUCCESS ) { - return NVMM_FAIL_CHECKSUM; - } - - if( ComputeChecksumNvm( dataB->virtualAddr, dataBHdr.Num ) == dataBHdr.CSum ) - { - return NVMM_SUCCESS; - } - else - { - return NVMM_FAIL_CHECKSUM; + return size; } + return 0; } - -NvmmStatus_t NvmmWrite( NvmmDataBlock_t* dataB, void* src, size_t num ) +bool NvmmCrc32Check( uint16_t size, uint16_t offset ) { - CRITICAL_SECTION_BEGIN( ); - - DataBlockHeader_t dataBHdr; - - // Read the data block header to obtain the maximum allowed size to write - EepromReadBuffer( ( dataB->virtualAddr - sizeof( DataBlockHeader_t ) ), ( uint8_t* ) &dataBHdr, sizeof( dataBHdr ) ); + uint8_t data = 0; + uint32_t calculatedCrc32 = 0; + uint32_t readCrc32 = 0; - if( num > dataBHdr.Num ) + if( NvmmRead( ( uint8_t* ) &readCrc32, sizeof( readCrc32 ), + ( offset + ( size - sizeof( readCrc32 ) ) ) ) == sizeof( readCrc32 ) ) { - CRITICAL_SECTION_END( ); - return NVMM_ERROR_SIZE; + // Calculate crc + calculatedCrc32 = Crc32Init( ); + for( uint16_t i = 0; i < ( size - sizeof( readCrc32 ) ); i++ ) + { + if( NvmmRead( &data, 1, offset + i ) != 1 ) + { + return false; + } + calculatedCrc32 = Crc32Update( calculatedCrc32, &data, 1 ); + } + calculatedCrc32 = Crc32Finalize( calculatedCrc32 ); + + if( calculatedCrc32 != readCrc32 ) + { + return false; + } } - - dataBHdr.CSum = ComputeChecksum( ( uint8_t* ) src, num ); - - // Update data block header - EepromWriteBuffer( ( dataB->virtualAddr - sizeof( DataBlockHeader_t ) ), ( uint8_t* ) &dataBHdr, sizeof( DataBlockHeader_t ) ); - - // Write data block - EepromWriteBuffer( dataB->virtualAddr, ( uint8_t* ) src, num ); - - CRITICAL_SECTION_END( ); - - return NVMM_SUCCESS; + return true; } -NvmmStatus_t NvmmRead( NvmmDataBlock_t* dataB, void* dst, size_t num ) +bool NvmmReset( uint16_t size, uint16_t offset ) { - CRITICAL_SECTION_BEGIN( ); - - DataBlockHeader_t dataBHdr; - - // Read the data block header to obtain the maximum allowed size to write - EepromReadBuffer( (dataB->virtualAddr - sizeof( DataBlockHeader_t ) ), ( uint8_t * ) &dataBHdr, sizeof( dataBHdr ) ); + uint32_t crc32 = 0; - if( num > dataBHdr.Num ) + if( EepromMcuWriteBuffer( offset + size - sizeof( crc32 ), + ( uint8_t* ) &crc32, sizeof( crc32 ) ) == SUCCESS ) { - CRITICAL_SECTION_END( ); - return NVMM_ERROR_SIZE; + return true; } - - // data block - EepromReadBuffer( dataB->virtualAddr, ( uint8_t* ) dst, num ); - - CRITICAL_SECTION_END( ); - - return NVMM_SUCCESS; + return false; } diff --git a/src/system/nvmm.h b/src/system/nvmm.h index 3c7f5c218..e9eef957a 100644 --- a/src/system/nvmm.h +++ b/src/system/nvmm.h @@ -40,82 +40,51 @@ extern "C" #include #include +#include /*! - * Nvmm Status - */ -typedef enum eNvmmStatus -{ - /*! - * No error occurred - */ - NVMM_SUCCESS = 0, - /*! - * Checksum of the data block does not match. - */ - NVMM_FAIL_CHECKSUM, - /*! - * Size does not fit - */ - NVMM_ERROR_SIZE, - /*! - * Null pointer exception - */ - NVMM_ERROR_NPE, - /*! - * Undefined Error occurred - */ - NVMM_ERROR, -}NvmmStatus_t; - -/*! - * Nvmm Data Block handle - */ -typedef struct -{ - /* - * Unique internal used virtual address for the data block. - */ - uint16_t virtualAddr; -}NvmmDataBlock_t; - -/*! - * Declares a data block + * \brief Writes data to given data block. + * + * \param[IN] src Pointer to the source of data to be copied. + * \param[IN] size Number of bytes to copy. + * \param[IN] offset Relative NVM offset. * - * \param[IN] num Size as number of bytes. * \retval Status of the operation */ - NvmmStatus_t NvmmDeclare( NvmmDataBlock_t* dataB, size_t num ); +uint16_t NvmmWrite( uint8_t* src, uint16_t size, uint16_t offset ); /*! - * Reads the data block header and verifies the checksum to determine - * if it ever has been written or the data is corrupted. + * \brief Reads from data block to destination pointer. + * + * \param[IN] dst Pointer to the destination array where the content is to be copied. + * \param[IN] size Number of bytes to copy. + * \param[IN] offset Relative NVM offset. * - * \param[IN] dataB Pointer to the data block. - * \param[IN] num Size as number of bytes. * \retval Status of the operation */ -NvmmStatus_t NvmmVerify( NvmmDataBlock_t* dataB, size_t num ); +uint16_t NvmmRead( uint8_t* dest, uint16_t size, uint16_t offset ); /*! - * Writes data to given data block. + * \brief Verfies the CRC 32 of a data block. The function assumes that the + * crc32 is at the end of the block with 4 bytes. + * + * \param[IN] size Length of the block. + * \param[IN] offset Address offset of the NVM. * - * \param[IN] dataB Pointer to the data block. - * \param[IN] src Pointer to the source of data to be copied. - * \param[IN] num Number of bytes to copy. * \retval Status of the operation */ -NvmmStatus_t NvmmWrite( NvmmDataBlock_t* dataB, void* src, size_t num ); +bool NvmmCrc32Check( uint16_t size, uint16_t offset ); /*! - * Reads from data block to destination pointer. + * \brief Invalidates the CRC 32 of a data block. The function assumes that the + * crc32 is at the end of the block with 4 bytes. + * + * \param[IN] size Length of the block. + * \param[IN] offset Address offset of the NVM. * - * \param[IN] dataB Pointer to the data block. - * \param[IN] dst Pointer to the destination array where the content is to be copied. - * \param[IN] num Number of bytes to copy. * \retval Status of the operation */ -NvmmStatus_t NvmmRead( NvmmDataBlock_t* dataB, void* dst, size_t num ); +bool NvmmReset( uint16_t size, uint16_t offset ); #ifdef __cplusplus } From da031ab7dfcade33cc45e2271c9948dafc917dfb Mon Sep 17 00:00:00 2001 From: Miguel Luis Date: Fri, 18 Dec 2020 17:01:38 +0100 Subject: [PATCH 3/3] Release 4.4.6 --- CHANGELOG.md | 26 +++++++++++++++++++++++--- README.md | 9 ++++----- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2bbc7db71..2d8ffffcb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,18 +11,37 @@ Please refer to [Releases pre-certification-results](https://github.com/Lora-net ## [Unreleased] +## [4.4.6] - 2020-12-18 + +### General + +- Release based on "LoRaWAN specification 1.0.3" and "LoRaWAN Regional Parameters v1.0.3revA" +- GitHub reported issues corrections. Please refer to [Release Version 4.4.6](https://github.com/Lora-net/LoRaMac-node/milestone/8) +- **Release 4.4.6 is the last one supporting "LoRaWAN specification 1.0.3"** + ### Changed -- Changed IMST boards default power source to USB_POWER +- Refactored MAC layer and examples Non Volatile Memory data handling +- Changed `NewChannelReq` amd `DlChannelReq` handling to ignore command for `AU915`, `CN470` and `US915` regions +- Updated behavior of `SX126xSetLoRaSymbNumTimeout` to round up the timeout to the nearest possible number of symbol. +- Changed radio drivers floating point to integer computations +- Improved `GetNextLowerTxDr` function implementation. +- Changed SX1272 and SX1276 FSK FIFO handling by using `FifoLevel` IRQ instead of `FifoEmpty` IRQ + **WARNING** *DIO1 IRQ MCU pin detection has changed from `RISING` to `RISING_FALLING` edge.* +- Changed IMST boards default power source to `USB_POWER` ### Fixed -- Fixed an issue where the Join back off algorithm wasn't being applied when the duty-cycle enforcement was OFF. +- Fixed certification test application handling +- Fixed `ping-pong` and `rx-sensi` examples to use the right `FSK_BANDWIDTH` and `FSK_AFC_BANDWIDTH` parameters +- Fixed one byte transmissions over I2C +- Fixed `RegionIN865RxParamSetupReq` `DrOffset` verification +- Fixed STM platforms IRQ handlers when using a C++ compiler +- Fixed an issue where the Join back off algorithm wasn't being applied when the duty-cycle enforcement was OFF - Fixed `AU915_MAX_RX1_DR_OFFSET` value to 5 instead of 6 ### Removed -- Removed NvmCtxCallback calls as they should only be done when a modification happens. - Removed ClassA, ClassB and ClassC examples. ## [4.4.5] - 2020-10-14 @@ -48,6 +67,7 @@ Please refer to [Releases pre-certification-results](https://github.com/Lora-net - Changed hard coded `JoinAccept` max payload size (33) by `LORAMAC_JOIN_ACCEPT_FRAME_MAX_SIZE` definition. - Moved radio operating mode management to specific board implementation - Changed radio `IsChannelFree API` in order to provide reception bandwidth +- AS923 default downlink dwell time setting changed to disabled - Back port 1.0.4 region implementation improvements - Changed `RegionCommonComputeSymbolTimeLoRa`, `RegionCommonComputeSymbolTimeFsk` and `RegionCommonComputeRxWindowParameters` API implementations to use integer divisions instead of double division. diff --git a/README.md b/README.md index 6db23b7f2..8921b5387 100644 --- a/README.md +++ b/README.md @@ -18,14 +18,13 @@ The aim of this project is to show an example of an end-device LoRaWAN stack implementation. -This project has 3 active branches in place. +This project has 2 active branches in place. | Branch | L2 spec | RP spec | Tag/Milestone | Class | Comments | | ------------- |:-------------:|:---------:|:---------:|:---------:|:--------------| -| | [1.0.3](https://lora-alliance.org/resource-hub/lorawanr-specification-v103) | [v1.0.3revA](https://www.lora-alliance.org/resource-hub/lorawanr-regional-parameters-v103reva) | [v4.4.5](https://github.com/Lora-net/LoRaMac-node/releases/tag/v4.4.5) | A/B/C | LoRaWAN L2 1.0.3 - **_Released_** | -| [master](https://github.com/Lora-net/LoRaMac-node/tree/master) | [1.0.3](https://lora-alliance.org/resource-hub/lorawanr-specification-v103) | [v1.0.3revA](https://www.lora-alliance.org/resource-hub/lorawanr-regional-parameters-v103reva) | [M 4.4.6](https://github.com/Lora-net/LoRaMac-node/milestone/8) | A/B/C | LoRaWAN L2 1.0.3 | -| [develop](https://github.com/Lora-net/LoRaMac-node/tree/develop) | [1.0.4](https://lora-alliance.org/resource-hub) | [2-1.0.1](https://lora-alliance.org/sites/default/files/2020-02/rp_2-1.0.1.pdf) | [v4.5.0-rc.1](https://github.com/Lora-net/LoRaMac-node/releases/tag/v4.5.0-rc.1)/[M 4.5.0](https://github.com/Lora-net/LoRaMac-node/milestone/5) | A/B/C | LoRaWAN L2 1.0.4 - **_Pre-Released_**| -| [feature/5.0.0](https://github.com/Lora-net/LoRaMac-node/tree/feature/5.0.0) | [1.0.4](https://lora-alliance.org/resource-hub) / [1.1.1](https://lora-alliance.org/resource-hub/lorawanr-specification-v11) | [2-1.0.1](https://lora-alliance.org/sites/default/files/2020-02/rp_2-1.0.1.pdf) | [M 5.0.0](https://github.com/Lora-net/LoRaMac-node/milestone/3) | A/B/C | LoRaWAN L2 1.0.4 / 1.1.1 | +| | [1.0.3](https://lora-alliance.org/resource-hub/lorawanr-specification-v103) | [v1.0.3revA](https://www.lora-alliance.org/resource-hub/lorawanr-regional-parameters-v103reva) | [v4.4.6](https://github.com/Lora-net/LoRaMac-node/releases/tag/v4.4.6) | A/B/C | LoRaWAN L2 1.0.3 - **_Released_ (last release based on 1.0.3)** | +| [master](https://github.com/Lora-net/LoRaMac-node/tree/master) | [1.0.4](https://lora-alliance.org/resource-hub/lorawan-104-specification-package) | [2-1.0.1](https://lora-alliance.org/sites/default/files/2020-02/rp_2-1.0.1.pdf) | [M 4.5.0](https://github.com/Lora-net/LoRaMac-node/milestone/5) | A/B/C | LoRaWAN L2 1.0.4 | +| [develop](https://github.com/Lora-net/LoRaMac-node/tree/develop) | [1.0.4](https://lora-alliance.org/resource-hub/lorawan-104-specification-package) / [1.1.1](https://lora-alliance.org/resource-hub/lorawanr-specification-v11) | [2-1.0.1](https://lora-alliance.org/sites/default/files/2020-02/rp_2-1.0.1.pdf) | [M 4.6.0](https://github.com/Lora-net/LoRaMac-node/milestone/3) | A/B/C | LoRaWAN L2 1.0.4 / 1.1.1 | This project fully implements ClassA, ClassB and ClassC end-device classes and it also provides SX1272/73, SX1276/77/78/79, SX1261/2 and LR1110 radio drivers.