From 616fff15c39b0b2029d82f9e2fc33d8ad837bcc1 Mon Sep 17 00:00:00 2001 From: StevenCellist Date: Sat, 18 May 2024 13:10:37 +0200 Subject: [PATCH] [LoRaWAN] Fix rejoining during active session --- keywords.txt | 1 - src/protocols/LoRaWAN/LoRaWAN.cpp | 21 ++++++++++++++++----- src/protocols/LoRaWAN/LoRaWAN.h | 12 ++++++------ 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/keywords.txt b/keywords.txt index 9f5c89b3..13755586 100644 --- a/keywords.txt +++ b/keywords.txt @@ -313,7 +313,6 @@ checkDataRate KEYWORD2 setModem KEYWORD2 # LoRaWAN -wipe KEYWORD2 getBufferNonces KEYWORD2 setBufferNonces KEYWORD2 getBufferSession KEYWORD2 diff --git a/src/protocols/LoRaWAN/LoRaWAN.cpp b/src/protocols/LoRaWAN/LoRaWAN.cpp index 0aa3aba1..e2d75130 100644 --- a/src/protocols/LoRaWAN/LoRaWAN.cpp +++ b/src/protocols/LoRaWAN/LoRaWAN.cpp @@ -44,13 +44,19 @@ void LoRaWANNode::setCSMA(uint8_t backoffMax, uint8_t difsSlots, bool enableCSMA this->enableCSMA = enableCSMA; } -void LoRaWANNode::wipe() { +void LoRaWANNode::clearNonces() { + // clear & set all the device credentials memset(this->bufferNonces, 0, RADIOLIB_LW_NONCES_BUF_SIZE); + this->keyCheckSum = 0; + this->devNonce = 0; + this->joinNonce = 0; + this->isActive = false; +} + +void LoRaWANNode::clearSession() { memset(this->bufferSession, 0, RADIOLIB_LW_SESSION_BUF_SIZE); memset(&(this->commandsUp), 0, sizeof(LoRaWANMacCommandQueue_t)); memset(&(this->commandsDown), 0, sizeof(LoRaWANMacCommandQueue_t)); - this->devNonce = 0; - this->joinNonce = 0; } uint8_t* LoRaWANNode::getBufferNonces() { @@ -445,6 +451,7 @@ void LoRaWANNode::beginOTAA(uint64_t joinEUI, uint64_t devEUI, uint8_t* nwkKey, this->keyCheckSum ^= LoRaWANNode::checkSum16(nwkKey, 16); this->keyCheckSum ^= LoRaWANNode::checkSum16(appKey, 16); + this->clearNonces(); this->lwMode = RADIOLIB_LW_MODE_OTAA; this->lwClass = RADIOLIB_LW_CLASS_A; } @@ -465,7 +472,8 @@ int16_t LoRaWANNode::activateOTAA(bool force, uint8_t joinDr, LoRaWANJoinEvent_t int16_t state = RADIOLIB_ERR_UNKNOWN; - // either no valid session was found or user forced a new session, so set active-bit to false + // either no valid session was found or user forced a new session, so clear all activity + this->clearSession(); this->bufferNonces[RADIOLIB_LW_NONCES_ACTIVE] = (uint8_t)false; this->isActive = false; @@ -764,6 +772,8 @@ void LoRaWANNode::beginABP(uint32_t addr, uint8_t* fNwkSIntKey, uint8_t* sNwkSIn if(fNwkSIntKey) { this->keyCheckSum ^= LoRaWANNode::checkSum16(fNwkSIntKey, 16); } if(sNwkSIntKey) { this->keyCheckSum ^= LoRaWANNode::checkSum16(sNwkSIntKey, 16); } + // clear & set all the device credentials + this->clearNonces(); this->lwMode = RADIOLIB_LW_MODE_ABP; this->lwClass = RADIOLIB_LW_CLASS_A; } @@ -782,7 +792,8 @@ int16_t LoRaWANNode::activateABP(bool force, uint8_t initialDr) { } } - // either no valid session was found or user forced a new session, so set active-bit to false + // either no valid session was found or user forced a new session, so clear all activity + this->clearSession(); this->bufferNonces[RADIOLIB_LW_NONCES_ACTIVE] = (uint8_t)false; this->isActive = false; diff --git a/src/protocols/LoRaWAN/LoRaWAN.h b/src/protocols/LoRaWAN/LoRaWAN.h index 025a58ec..18f42367 100644 --- a/src/protocols/LoRaWAN/LoRaWAN.h +++ b/src/protocols/LoRaWAN/LoRaWAN.h @@ -527,12 +527,6 @@ class LoRaWANNode { */ LoRaWANNode(PhysicalLayer* phy, const LoRaWANBand_t* band, uint8_t subBand = 0); - /*! - \brief Wipe internal persistent parameters. - This will reset all counters and saved variables, so the device will have to rejoin the network. - */ - void wipe(); - /*! \brief Returns the pointer to the internal buffer that holds the LW base parameters \returns Pointer to uint8_t array of size RADIOLIB_LW_NONCES_BUF_SIZE @@ -981,6 +975,12 @@ class LoRaWANNode { // save the selected sub-band in case this must be restored in ADR control uint8_t subBand = 0; + // this will reset the device credentials, so the device starts completely new + void clearNonces(); + + // this will reset all counters and saved variables, so the device will have to rejoin the network. + void clearSession(); + // wait for, open and listen during Rx1 and Rx2 windows; only performs listening int16_t downlinkCommon();