Skip to content

Commit

Permalink
[LoRaWAN] Fix #1284 (max length) and channel struct for fixed bands
Browse files Browse the repository at this point in the history
  • Loading branch information
StevenCellist committed Oct 22, 2024
1 parent 33ab117 commit 61494b8
Showing 1 changed file with 30 additions and 20 deletions.
50 changes: 30 additions & 20 deletions src/protocols/LoRaWAN/LoRaWAN.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1398,9 +1398,9 @@ int16_t LoRaWANNode::receiveCommon(uint8_t dir, const LoRaWANChannel_t* dlChanne
}

// get the maximum allowed Time-on-Air of a packet given the current datarate
uint8_t maxPayLen = this->band->payloadLenMax[this->channels[RADIOLIB_LORAWAN_UPLINK].dr];
uint8_t maxPayLen = this->band->payloadLenMax[dlChannels[window].dr];
if(this->TS011) {
maxPayLen = RADIOLIB_MIN(maxPayLen, 230); // payload length is limited to 230 if under repeater
maxPayLen = RADIOLIB_MIN(maxPayLen, 222); // payload length is limited to 222 if under repeater
}
RadioLibTime_t tMax = this->phyLayer->getTimeOnAir(maxPayLen + 13) / 1000; // mandatory FHDR is 12/13 bytes
bool downlinkComplete = true;
Expand Down Expand Up @@ -1978,7 +1978,7 @@ bool LoRaWANNode::execMacCommand(uint8_t cid, uint8_t* optIn, uint8_t lenIn, uin
optIn[13] = this->nbTrans;
}
memcpy(&this->bufferSession[RADIOLIB_LORAWAN_SESSION_LINK_ADR], optIn, lenIn);

return(true);
} break;

Expand Down Expand Up @@ -2796,7 +2796,7 @@ int16_t LoRaWANNode::setPhyProperties(const LoRaWANChannel_t* chnl, uint8_t dir,
}

RADIOLIB_DEBUG_PROTOCOL_PRINTLN("");
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("PHY: Frequency %cL = %7.3f MHz", dir ? 'D' : 'U', chnl->freq / 10000.0);
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("PHY: Frequency = %7.3f MHz, TX = %d dBm", chnl->freq / 10000.0, pwr);
state = this->phyLayer->setFrequency(chnl->freq / 10000.0);
RADIOLIB_ASSERT(state);

Expand All @@ -2813,12 +2813,12 @@ int16_t LoRaWANNode::setPhyProperties(const LoRaWANChannel_t* chnl, uint8_t dir,
RADIOLIB_ASSERT(state);

if(this->modulation == RADIOLIB_LORAWAN_MODULATION_GFSK) {
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("FSK: BR = %4.1f, TX = %d dBm, FD = %4.1f kHz",
dr.fsk.bitRate, pwr, dr.fsk.freqDev);
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("FSK: BR = %4.1f, FD = %4.1f kHz",
dr.fsk.bitRate, dr.fsk.freqDev);
}
if(this->modulation == RADIOLIB_LORAWAN_MODULATION_LORA) {
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("LoRa: SF = %d, TX = %d dBm, BW = %5.1f kHz, CR = 4/%d",
dr.lora.spreadingFactor, pwr, dr.lora.bandwidth, dr.lora.codingRate);
RADIOLIB_DEBUG_PROTOCOL_PRINTLN("LoRa: SF = %d, BW = %5.1f kHz, CR = 4/%d, IQ: %c",
dr.lora.spreadingFactor, dr.lora.bandwidth, dr.lora.codingRate, dir ? 'D' : 'U');
}

// this only needs to be done once-ish
Expand Down Expand Up @@ -2901,7 +2901,10 @@ void LoRaWANNode::getChannelPlanMask(uint64_t* chMaskGrp0123, uint32_t* chMaskGr
*chMaskGrp0123 = 0;
*chMaskGrp45 = 0;

if(this->band->bandType == RADIOLIB_LORAWAN_BAND_DYNAMIC) {
uint8_t numCh = this->getAvailableChannels(NULL);

// if there are any channels selected, create the mask from those channels
if(numCh > 0) {
for(int i = 0; i < RADIOLIB_LORAWAN_NUM_AVAILABLE_CHANNELS; i++) {
uint8_t idx = this->channelPlan[RADIOLIB_LORAWAN_UPLINK][i].idx;
if(idx != RADIOLIB_LORAWAN_CHANNEL_INDEX_NONE) {
Expand All @@ -2912,6 +2915,13 @@ void LoRaWANNode::getChannelPlanMask(uint64_t* chMaskGrp0123, uint32_t* chMaskGr
}
}
}
return;
}

// it should not happen that no channels are set for dynamic band
// but in that case, simply return
if(this->band->bandType == RADIOLIB_LORAWAN_BAND_DYNAMIC) {
return;

} else { // bandType == RADIOLIB_LORAWAN_BAND_FIXED
// if a subband is set, we can set the channel indices straight from subband
Expand All @@ -2923,9 +2933,9 @@ void LoRaWANNode::getChannelPlanMask(uint64_t* chMaskGrp0123, uint32_t* chMaskGr
// CN500 only: for sub band 9-12, set bank of 8 125kHz channels
*chMaskGrp45 |= 0xFF << ((this->subBand - 9) * 8);
} else {
// if subband is set to 0, all 125kHz channels are enabled
// however, we can 'only' store 16 channels, so we do not actually store these
// therefore, we select a random channel from each bank of 8 channels
// if subband is set to 0, all 125kHz channels are enabled.
// however, we can 'only' store 16 channels, so we don't use all channels at once.
// instead, we select a random channel from each bank of 8 channels + 1 from second plan.
uint8_t num125kHz = this->band->txSpans[0].numChannels;
uint8_t numBanks = num125kHz / 8;
for(uint8_t bank = 0; bank < numBanks; bank++) {
Expand Down Expand Up @@ -3009,10 +3019,6 @@ void LoRaWANNode::selectChannelPlanFix() {

// make all enabled channels available for uplink selection
this->setAvailableChannels(0xFFFF);

#if RADIOLIB_DEBUG_PROTOCOL
this->printChannels();
#endif
}

uint8_t LoRaWANNode::getAvailableChannels(uint16_t* chMask) {
Expand Down Expand Up @@ -3109,7 +3115,6 @@ int16_t LoRaWANNode::selectChannels() {
}

bool LoRaWANNode::applyChannelMask(uint64_t chMaskGrp0123, uint32_t chMaskGrp45) {
int num = 0;
if(this->band->bandType == RADIOLIB_LORAWAN_BAND_DYNAMIC) {
for(int i = 0; i < RADIOLIB_LORAWAN_NUM_AVAILABLE_CHANNELS; i++) {
if(chMaskGrp0123 & ((uint64_t)1 << i)) {
Expand All @@ -3123,7 +3128,12 @@ bool LoRaWANNode::applyChannelMask(uint64_t chMaskGrp0123, uint32_t chMaskGrp45)
}
}
} else { // bandType == RADIOLIB_LORAWAN_BAND_FIXED
// full channel mask received, so clear all existing channels
LoRaWANChannel_t chnl = RADIOLIB_LORAWAN_CHANNEL_NONE;
for(size_t i = 0; i < RADIOLIB_LORAWAN_NUM_AVAILABLE_CHANNELS; i++) {
this->channelPlan[RADIOLIB_LORAWAN_UPLINK][i] = chnl;
}
int num = 0;
uint8_t spanNum = 0;
int chNum = 0;
int chOfs = 0;
Expand Down Expand Up @@ -3240,12 +3250,12 @@ uint8_t LoRaWANNode::getMaxPayloadLen() {
RADIOLIB_LORAWAN_UPLINK,
this->txPowerMax - 2*this->txPowerSteps);

// mandatory FHDR is 12/13, so add & subtract 13 from calculations where necessary
uint8_t minLen = 0;
uint8_t maxLen = this->band->payloadLenMax[this->channels[RADIOLIB_LORAWAN_UPLINK].dr] + 13;
uint8_t maxLen = this->band->payloadLenMax[this->channels[RADIOLIB_LORAWAN_UPLINK].dr];
if(this->TS011) {
maxLen = RADIOLIB_MIN(maxLen, 230 + 13); // payload length is limited to 230 if under repeater
maxLen = RADIOLIB_MIN(maxLen, 222); // payload length is limited to N=222 if under repeater
}
maxLen += 13; // mandatory FHDR is 12/13 bytes

// if not limited by dwell-time, just return maximum
if(!this->dwellTimeEnabledUp) {
Expand Down

0 comments on commit 61494b8

Please sign in to comment.