[LoRaWAN] Return Rx window number, fix casing

This commit is contained in:
StevenCellist 2024-09-04 13:31:15 +02:00
parent 1ca988db44
commit f2e26dd92d
3 changed files with 77 additions and 62 deletions

View file

@ -142,29 +142,33 @@ int16_t LoRaWANNode::sendReceive(uint8_t* dataUp, size_t lenUp, uint8_t fPort, u
RADIOLIB_ASSERT(state);
}
// handle Rx1 and Rx2 windows - returns RADIOLIB_ERR_NONE if a downlink is received
// handle Rx1 and Rx2 windows - returns window > 0 if a downlink is received
state = receiveCommon(RADIOLIB_LORAWAN_DOWNLINK, this->channels, this->rxDelays, 2, this->rxDelayStart);
// RETRANSMIT_TIMEOUT is 2s +/- 1s
// RETRANSMIT_TIMEOUT is 2s +/- 1s (RP v1.0.4)
// must be present after any confirmed frame, so we force this here
if(isConfirmed) {
mod->hal->delay(this->phyLayer->random(1000, 3000));
}
// if a downlink was received, stop retransmission
if(state == RADIOLIB_ERR_NONE) {
// if an error occured or a downlink was received, stop retransmission
if(state != RADIOLIB_ERR_NONE) {
break;
}
// if a hardware error occurred, return
if(state != RADIOLIB_LORAWAN_NO_DOWNLINK) {
#if !RADIOLIB_STATIC_ONLY
delete[] uplinkMsg;
#endif
RADIOLIB_ASSERT(state);
}
// if no downlink was received, go on
} // end of transmission & reception
// note: if an error occured, it may still be the case that a transmission occured
// therefore, we act as if a transmission occured before throwing the actual error
// this feels to be the best way to comply to spec
// increase frame counter by one for the next uplink
this->fCntUp += 1;
// the downlink confirmation was acknowledged, so clear the counter value
this->confFCntDown = RADIOLIB_LORAWAN_FCNT_NONE;
} // end of transmission
// pass the uplink info if requested
if(eventUp) {
eventUp->dir = RADIOLIB_LORAWAN_UPLINK;
@ -178,17 +182,21 @@ int16_t LoRaWANNode::sendReceive(uint8_t* dataUp, size_t lenUp, uint8_t fPort, u
eventUp->nbTrans = trans;
}
// the downlink confirmation was acknowledged, so clear the counter value
this->confFCntDown = RADIOLIB_LORAWAN_FCNT_NONE;
// if a hardware error occurred, return
if(state < RADIOLIB_ERR_NONE) {
#if !RADIOLIB_STATIC_ONLY
delete[] uplinkMsg;
#endif
RADIOLIB_ASSERT(state);
}
// increase frame counter by one for the next uplink
this->fCntUp += 1;
uint8_t rxWindow = state;
// if no downlink was received, remove only non-persistent MAC commands
// the other commands should be re-sent until downlink is received
if(state == RADIOLIB_LORAWAN_NO_DOWNLINK) {
if(rxWindow == 0) {
LoRaWANNode::clearMacCommands(this->fOptsUp, &this->fOptsUpLen, RADIOLIB_LORAWAN_UPLINK);
return(state);
return(rxWindow);
}
// a downlink was received, so we can clear the whole MAC uplink buffer
@ -196,7 +204,10 @@ int16_t LoRaWANNode::sendReceive(uint8_t* dataUp, size_t lenUp, uint8_t fPort, u
this->fOptsUpLen = 0;
state = this->parseDownlink(dataDown, lenDown, eventDown);
return(state);
// return an error code, if any, otherwise return Rx window (which is > 0)
RADIOLIB_ASSERT(state);
return(rxWindow);
}
void LoRaWANNode::clearNonces() {
@ -1321,22 +1332,20 @@ int16_t LoRaWANNode::receiveCommon(uint8_t dir, LoRaWANChannel_t* dlChannels, Ra
return(RADIOLIB_ERR_NO_RX_WINDOW);
}
// create the masks that are required for receiving downlinks
RadioLibIrqFlags_t irqFlags = (1UL << RADIOLIB_IRQ_RX_DONE) | (1UL << RADIOLIB_IRQ_TIMEOUT);
RadioLibIrqFlags_t irqMask = RADIOLIB_IRQ_RX_DEFAULT_MASK;
// setup interrupt
this->phyLayer->setPacketReceivedAction(LoRaWANNodeOnDownlinkAction);
RadioLibTime_t tOpen = 0;
int16_t timedOut = 0;
// listen during the specified windows
for(uint8_t i = 1; i <= numWindows; i++) {
uint8_t window = 1;
for(; window <= numWindows; window++) {
downlinkAction = false;
// set the physical layer configuration for downlink
this->phyLayer->standby();
state = this->setPhyProperties(&dlChannels[i], dir, this->txPowerMax - 2*this->txPowerSteps);
state = this->setPhyProperties(&dlChannels[window], dir, this->txPowerMax - 2*this->txPowerSteps);
RADIOLIB_ASSERT(state);
// calculate the Rx timeout
@ -1344,10 +1353,10 @@ int16_t LoRaWANNode::receiveCommon(uint8_t dir, LoRaWANChannel_t* dlChannels, Ra
RadioLibTime_t timeoutMod = this->phyLayer->calculateRxTimeout(timeoutHost);
// wait for the start of the Rx window
RadioLibTime_t waitLen = tReference + dlDelays[i] - mod->hal->millis();
RadioLibTime_t waitLen = tReference + dlDelays[window] - mod->hal->millis();
// make sure that no underflow occured; if so, clip the delay (although this will likely miss any downlink)
if(waitLen > dlDelays[i]) {
waitLen = dlDelays[i];
if(waitLen > dlDelays[window]) {
waitLen = dlDelays[window];
}
// the waiting duration is shortened a bit to cover any possible timing errors
if(waitLen > this->scanGuard) {
@ -1356,14 +1365,15 @@ int16_t LoRaWANNode::receiveCommon(uint8_t dir, LoRaWANChannel_t* dlChannels, Ra
mod->hal->delay(waitLen);
// open Rx window by starting receive with specified timeout
state = this->phyLayer->startReceive(timeoutMod, irqFlags, irqMask, 0);
// TODO remove default arguments
state = this->phyLayer->startReceive(timeoutMod, RADIOLIB_IRQ_RX_DEFAULT_FLAGS, RADIOLIB_IRQ_RX_DEFAULT_MASK, 0);
tOpen = mod->hal->millis();
RADIOLIB_ASSERT(state);
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("Opening Rx%d window (%d ms timeout)... <-- Rx Delay end ", i, (int)(timeoutHost / 1000 + scanGuard / 2));
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("Opening Rx%d window (%d ms timeout)... <-- Rx Delay end ", window, (int)(timeoutHost / 1000 + scanGuard / 2));
// wait for the timeout to complete (and a small additional delay)
mod->hal->delay(timeoutHost / 1000 + this->scanGuard / 2);
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("Closing Rx%d window", i);
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("Closing Rx%d window", window);
// if the IRQ bit for Rx Timeout is not set, something is received, so stop the windows
timedOut = this->phyLayer->checkIrq(RADIOLIB_IRQ_TIMEOUT);
@ -1380,7 +1390,7 @@ int16_t LoRaWANNode::receiveCommon(uint8_t dir, LoRaWANChannel_t* dlChannels, Ra
// if we got here due to a timeout, stop ongoing activities
if(timedOut) {
this->phyLayer->standby();
return(RADIOLIB_LORAWAN_NO_DOWNLINK);
return(RADIOLIB_ERR_NONE);
}
// get the maximum allowed Time-on-Air of a packet given the current datarate
@ -1411,8 +1421,13 @@ int16_t LoRaWANNode::receiveCommon(uint8_t dir, LoRaWANChannel_t* dlChannels, Ra
this->phyLayer->clearPacketReceivedAction();
this->phyLayer->standby();
// if all windows passed without receiving anything, return so
if(!downlinkComplete) {
state = RADIOLIB_LORAWAN_NO_DOWNLINK;
state = RADIOLIB_ERR_NONE;
// if we received something during a window, return the window number
} else {
state = window;
}
return(state);
@ -1595,7 +1610,7 @@ int16_t LoRaWANNode::parseDownlink(uint8_t* data, size_t* len, LoRaWANEvent_t* e
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("Downlink (%sFCntDown = %lu) encoded:",
isAppDownlink ? "A" : "N",
isAppDownlink ? (uint32_t)this->aFCntDown : (uint32_t)this->nFCntDown);
(unsigned long)(isAppDownlink ? this->aFCntDown : this->nFCntDown));
RADIOLIB_DEBUG_PROTOCOL_HEXDUMP(downlinkMsg, RADIOLIB_AES128_BLOCK_SIZE + downlinkMsgLen);
// if this is a confirmed frame, save the downlink number (only app frames can be confirmed)

View file

@ -420,7 +420,7 @@ struct LoRaWANBand_t {
LoRaWANChannel_t rx2;
/*! \brief Relay channels for WoR uplink */
LoRaWANChannel_t txWor[2];
LoRaWANChannel_t txWoR[2];
/*! \brief Relay channels for ACK downlink */
LoRaWANChannel_t txAck[2];
@ -612,7 +612,7 @@ class LoRaWANNode {
(fPort, frame counter, etc.). If set to NULL, no extra information will be passed to the user.
\param eventDown Pointer to a structure to store extra information about the downlink event
(fPort, frame counter, etc.). If set to NULL, no extra information will be passed to the user.
\returns \ref status_codes
\returns Window number > 0 if downlink was received, 0 is no downlink was received, otherwise \ref status_codes
*/
virtual int16_t sendReceive(String& strUp, uint8_t fPort, String& strDown, bool isConfirmed = false, LoRaWANEvent_t* eventUp = NULL, LoRaWANEvent_t* eventDown = NULL);
#endif
@ -628,7 +628,7 @@ class LoRaWANNode {
(fPort, frame counter, etc.). If set to NULL, no extra information will be passed to the user.
\param eventDown Pointer to a structure to store extra information about the downlink event
(fPort, frame counter, etc.). If set to NULL, no extra information will be passed to the user.
\returns \ref status_codes
\returns Window number > 0 if downlink was received, 0 is no downlink was received, otherwise \ref status_codes
*/
virtual int16_t sendReceive(const char* strUp, uint8_t fPort, uint8_t* dataDown, size_t* lenDown, bool isConfirmed = false, LoRaWANEvent_t* eventUp = NULL, LoRaWANEvent_t* eventDown = NULL);
@ -644,7 +644,7 @@ class LoRaWANNode {
(fPort, frame counter, etc.). If set to NULL, no extra information will be passed to the user.
\param eventDown Pointer to a structure to store extra information about the downlink event
(fPort, frame counter, etc.). If set to NULL, no extra information will be passed to the user.
\returns \ref status_codes
\returns Window number > 0 if downlink was received, 0 is no downlink was received, otherwise \ref status_codes
*/
virtual int16_t sendReceive(uint8_t* dataUp, size_t lenUp, uint8_t fPort, uint8_t* dataDown, size_t* lenDown, bool isConfirmed = false, LoRaWANEvent_t* eventUp = NULL, LoRaWANEvent_t* eventDown = NULL);
@ -658,7 +658,7 @@ class LoRaWANNode {
(fPort, frame counter, etc.). If set to NULL, no extra information will be passed to the user.
\param eventDown Pointer to a structure to store extra information about the downlink event
(fPort, frame counter, etc.). If set to NULL, no extra information will be passed to the user.
\returns \ref status_codes
\returns Window number > 0 if downlink was received, 0 is no downlink was received, otherwise \ref status_codes
*/
virtual int16_t sendReceive(uint8_t* dataUp, size_t lenUp, uint8_t fPort = 1, bool isConfirmed = false, LoRaWANEvent_t* eventUp = NULL, LoRaWANEvent_t* eventDown = NULL);
@ -838,7 +838,7 @@ class LoRaWANNode {
RadioLibTime_t scanGuard = 10;
#if !RADIOLIB_GODMODE
private:
protected:
#endif
PhysicalLayer* phyLayer = NULL;
const LoRaWANBand_t* band = NULL;

View file

@ -61,13 +61,13 @@ const LoRaWANBand_t EU868 = {
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
},
.rx2 = { .enabled = true, .idx = 0, .freq = 8695250, .drMin = 0, .drMax = 0, .dr = 0, .available = true },
.txWor = {
.txWoR = {
{ .enabled = true, .idx = 0, .freq = 8651000, .drMin = 2, .drMax = 2, .dr = 2, .available = true },
{ .enabled = false, .idx = 1, .freq = 8655000, .drMin = 2, .drMax = 2, .dr = 2, .available = true }
{ .enabled = true, .idx = 1, .freq = 8655000, .drMin = 2, .drMax = 2, .dr = 2, .available = true }
},
.txAck = {
{ .enabled = true, .idx = 0, .freq = 8653000, .drMin = 2, .drMax = 2, .dr = 2, .available = true },
{ .enabled = false, .idx = 1, .freq = 8659000, .drMin = 2, .drMax = 2, .dr = 2, .available = true }
{ .enabled = true, .idx = 1, .freq = 8659000, .drMin = 2, .drMax = 2, .dr = 2, .available = true }
},
.dataRates = {
RADIOLIB_LORAWAN_DATA_RATE_LORA | RADIOLIB_LORAWAN_DATA_RATE_SF_12 | RADIOLIB_LORAWAN_DATA_RATE_BW_125_KHZ,
@ -153,13 +153,13 @@ const LoRaWANBand_t US915 = {
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
},
.rx2 = { .enabled = true, .idx = 0, .freq = 9233000, .drMin = 8, .drMax = 8, .dr = 8, .available = true },
.txWor = {
.txWoR = {
{ .enabled = true, .idx = 0, .freq = 9167000, .drMin = 10, .drMax = 10, .dr = 10, .available = true },
{ .enabled = false, .idx = 1, .freq = 9199000, .drMin = 10, .drMax = 10, .dr = 10, .available = true }
{ .enabled = true, .idx = 1, .freq = 9199000, .drMin = 10, .drMax = 10, .dr = 10, .available = true }
},
.txAck = {
{ .enabled = true, .idx = 0, .freq = 9183000, .drMin = 10, .drMax = 10, .dr = 10, .available = true },
{ .enabled = false, .idx = 1, .freq = 9215000, .drMin = 10, .drMax = 10, .dr = 10, .available = true }
{ .enabled = true, .idx = 1, .freq = 9215000, .drMin = 10, .drMax = 10, .dr = 10, .available = true }
},
.dataRates = {
RADIOLIB_LORAWAN_DATA_RATE_LORA | RADIOLIB_LORAWAN_DATA_RATE_SF_10 | RADIOLIB_LORAWAN_DATA_RATE_BW_125_KHZ,
@ -224,7 +224,7 @@ const LoRaWANBand_t EU433 = {
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
},
.rx2 = { .enabled = true, .idx = 0, .freq = 4346650, .drMin = 0, .drMax = 0, .dr = 0, .available = true },
.txWor = {
.txWoR = {
RADIOLIB_LORAWAN_CHANNEL_NONE,
RADIOLIB_LORAWAN_CHANNEL_NONE
},
@ -316,13 +316,13 @@ const LoRaWANBand_t AU915 = {
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
},
.rx2 = { .enabled = true, .idx = 0, .freq = 9233000, .drMin = 8, .drMax = 8, .dr = 8, .available = true },
.txWor = {
.txWoR = {
{ .enabled = true, .idx = 0, .freq = 9167000, .drMin = 10, .drMax = 10, .dr = 10, .available = true },
{ .enabled = false, .idx = 1, .freq = 9199000, .drMin = 10, .drMax = 10, .dr = 10, .available = true }
{ .enabled = true, .idx = 1, .freq = 9199000, .drMin = 10, .drMax = 10, .dr = 10, .available = true }
},
.txAck = {
{ .enabled = true, .idx = 0, .freq = 9183000, .drMin = 10, .drMax = 10, .dr = 10, .available = true },
{ .enabled = false, .idx = 1, .freq = 9215000, .drMin = 10, .drMax = 10, .dr = 10, .available = true }
{ .enabled = true, .idx = 1, .freq = 9215000, .drMin = 10, .drMax = 10, .dr = 10, .available = true }
},
.dataRates = {
RADIOLIB_LORAWAN_DATA_RATE_LORA | RADIOLIB_LORAWAN_DATA_RATE_SF_12 | RADIOLIB_LORAWAN_DATA_RATE_BW_125_KHZ,
@ -401,7 +401,7 @@ const LoRaWANBand_t CN500 = {
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
},
.rx2 = { .enabled = true, .idx = 0, .freq = 5053000, .drMin = 0, .drMax = 0, .dr = 0, .available = true },
.txWor = {
.txWoR = {
RADIOLIB_LORAWAN_CHANNEL_NONE,
RADIOLIB_LORAWAN_CHANNEL_NONE
},
@ -472,7 +472,7 @@ const LoRaWANBand_t AS923 = {
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
},
.rx2 = { .enabled = true, .idx = 0, .freq = 9232000, .drMin = 2, .drMax = 2, .dr = 2, .available = true },
.txWor = {
.txWoR = {
{ .enabled = true, .idx = 0, .freq = 9236000, .drMin = 3, .drMax = 3, .dr = 3, .available = true },
RADIOLIB_LORAWAN_CHANNEL_NONE
},
@ -543,7 +543,7 @@ const LoRaWANBand_t AS923_2 = {
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
},
.rx2 = { .enabled = true, .idx = 0, .freq = 9214000, .drMin = 2, .drMax = 2, .dr = 2, .available = true },
.txWor = {
.txWoR = {
{ .enabled = true, .idx = 0, .freq = 9218000, .drMin = 3, .drMax = 3, .dr = 3, .available = true },
RADIOLIB_LORAWAN_CHANNEL_NONE
},
@ -614,7 +614,7 @@ const LoRaWANBand_t AS923_3 = {
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
},
.rx2 = { .enabled = true, .idx = 0, .freq = 9166000, .drMin = 2, .drMax = 2, .dr = 2, .available = true },
.txWor = {
.txWoR = {
{ .enabled = true, .idx = 0, .freq = 9170000, .drMin = 3, .drMax = 3, .dr = 3, .available = true },
RADIOLIB_LORAWAN_CHANNEL_NONE
},
@ -685,7 +685,7 @@ const LoRaWANBand_t AS923_4 = {
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
},
.rx2 = { .enabled = true, .idx = 0, .freq = 9173000, .drMin = 2, .drMax = 2, .dr = 2, .available = true },
.txWor = {
.txWoR = {
{ .enabled = true, .idx = 0, .freq = 9177000, .drMin = 3, .drMax = 3, .dr = 3, .available = true },
RADIOLIB_LORAWAN_CHANNEL_NONE
},
@ -756,13 +756,13 @@ const LoRaWANBand_t KR920 = {
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
},
.rx2 = { .enabled = true, .idx = 0, .freq = 9219000, .drMin = 0, .drMax = 0, .dr = 0, .available = true },
.txWor = {
.txWoR = {
{ .enabled = true, .idx = 0, .freq = 9227000, .drMin = 3, .drMax = 3, .dr = 3, .available = true },
{ .enabled = false, .idx = 1, .freq = 9231000, .drMin = 3, .drMax = 3, .dr = 3, .available = true }
{ .enabled = true, .idx = 1, .freq = 9231000, .drMin = 3, .drMax = 3, .dr = 3, .available = true }
},
.txAck = {
{ .enabled = true, .idx = 0, .freq = 9229000, .drMin = 3, .drMax = 3, .dr = 3, .available = true },
{ .enabled = false, .idx = 1, .freq = 9231000, .drMin = 3, .drMax = 3, .dr = 3, .available = true }
{ .enabled = true, .idx = 1, .freq = 9231000, .drMin = 3, .drMax = 3, .dr = 3, .available = true }
},
.dataRates = {
RADIOLIB_LORAWAN_DATA_RATE_LORA | RADIOLIB_LORAWAN_DATA_RATE_SF_12 | RADIOLIB_LORAWAN_DATA_RATE_BW_125_KHZ,
@ -827,13 +827,13 @@ const LoRaWANBand_t IN865 = {
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
},
.rx2 = { .enabled = true, .idx = 0, .freq = 8665500, .drMin = 2, .drMax = 2, .dr = 2, .available = true },
.txWor = {
.txWoR = {
{ .enabled = true, .idx = 0, .freq = 8660000, .drMin = 3, .drMax = 3, .dr = 3, .available = true },
{ .enabled = false, .idx = 1, .freq = 8667000, .drMin = 3, .drMax = 3, .dr = 3, .available = true }
{ .enabled = true, .idx = 1, .freq = 8667000, .drMin = 3, .drMax = 3, .dr = 3, .available = true }
},
.txAck = {
{ .enabled = true, .idx = 0, .freq = 8662000, .drMin = 3, .drMax = 3, .dr = 3, .available = true },
{ .enabled = false, .idx = 1, .freq = 8669000, .drMin = 3, .drMax = 3, .dr = 3, .available = true }
{ .enabled = true, .idx = 1, .freq = 8669000, .drMin = 3, .drMax = 3, .dr = 3, .available = true }
},
.dataRates = {
RADIOLIB_LORAWAN_DATA_RATE_LORA | RADIOLIB_LORAWAN_DATA_RATE_SF_12 | RADIOLIB_LORAWAN_DATA_RATE_BW_125_KHZ,