From 27653e1cf7292d643e996028c1a40931e7867143 Mon Sep 17 00:00:00 2001 From: StevenCellist <steven@boonstoppel.nu> Date: Thu, 30 Jan 2025 20:58:53 +0100 Subject: [PATCH] [LoRaWAN] Allow support for misc MAC commands --- src/protocols/LoRaWAN/LoRaWAN.cpp | 23 ++++++++++++++--------- src/protocols/LoRaWAN/LoRaWAN.h | 3 ++- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/protocols/LoRaWAN/LoRaWAN.cpp b/src/protocols/LoRaWAN/LoRaWAN.cpp index cc6ed3df..91cdf65d 100644 --- a/src/protocols/LoRaWAN/LoRaWAN.cpp +++ b/src/protocols/LoRaWAN/LoRaWAN.cpp @@ -1718,14 +1718,14 @@ int16_t LoRaWANNode::parseDownlink(uint8_t* data, size_t* len, LoRaWANEvent_t* e cid = *mPtr; // MAC id is the first byte // fetch length of MAC downlink payload - state = this->getMacLen(cid, &fLen, RADIOLIB_LORAWAN_DOWNLINK, true); + state = this->getMacLen(cid, &fLen, RADIOLIB_LORAWAN_DOWNLINK, true, mPtr + 1); if(state != RADIOLIB_ERR_NONE) { RADIOLIB_DEBUG_PROTOCOL_PRINTLN("WARNING: Unknown MAC CID %02x", cid); RADIOLIB_DEBUG_PROTOCOL_PRINTLN("WARNING: Skipping remaining MAC commands"); break; } - // already fetch length of MAC answer payload (if any) + // already fetch length of MAC answer payload (if any), include CID uint8_t fLenRe = 0; (void)this->getMacLen(cid, &fLenRe, RADIOLIB_LORAWAN_UPLINK, true); // don't care about return value: the previous getMacLen() would have failed anyway @@ -2484,17 +2484,21 @@ int16_t LoRaWANNode::getMacDeviceTimeAns(uint32_t* gpsEpoch, uint8_t* fraction, return(RADIOLIB_ERR_NONE); } -int16_t LoRaWANNode::getMacLen(uint8_t cid, uint8_t* len, uint8_t dir, bool inclusive) { +int16_t LoRaWANNode::getMacLen(uint8_t cid, uint8_t* len, uint8_t dir, bool inclusive, uint8_t* payload) { + (void)payload; + + *len = 0; + if(inclusive) { + *len += 1; // add one byte for CID + } + LoRaWANMacCommand_t cmd = RADIOLIB_LORAWAN_MAC_COMMAND_NONE; int16_t state = this->getMacCommand(cid, &cmd); RADIOLIB_ASSERT(state); if(dir == RADIOLIB_LORAWAN_UPLINK) { - *len = cmd.lenUp; + *len += cmd.lenUp; } else { - *len = cmd.lenDn; - } - if(inclusive) { - *len += 1; // add one byte for CID + *len += cmd.lenDn; } return(RADIOLIB_ERR_NONE); } @@ -2596,7 +2600,8 @@ void LoRaWANNode::clearMacCommands(uint8_t* inOut, uint8_t* lenInOut, uint8_t di uint8_t numDeleted = 0; while(i < *lenInOut) { uint8_t id = inOut[i]; - uint8_t fLen = 1; // if there is an incorrect MAC command, we should at least move forward by one byte + uint8_t fLen = 0; + // include CID byte, so if command fails, we still move one byte forward (void)this->getMacLen(id, &fLen, dir, true); // only clear MAC command if it should not persist until a downlink is received diff --git a/src/protocols/LoRaWAN/LoRaWAN.h b/src/protocols/LoRaWAN/LoRaWAN.h index 977db468..1bfa782c 100644 --- a/src/protocols/LoRaWAN/LoRaWAN.h +++ b/src/protocols/LoRaWAN/LoRaWAN.h @@ -1030,7 +1030,8 @@ class LoRaWANNode { // get the length of a certain MAC command in a specific direction (up/down) // if inclusive is true, add one for the CID byte - int16_t getMacLen(uint8_t cid, uint8_t* len, uint8_t dir, bool inclusive = false); + // include payload in case the MAC command has a dynamic length + virtual int16_t getMacLen(uint8_t cid, uint8_t* len, uint8_t dir, bool inclusive = false, uint8_t* payload = NULL); // find out of a MAC command should persist destruction // in uplink direction, some commands must persist if no downlink is received