diff --git a/keywords.txt b/keywords.txt index 41cda138..8c91e6f4 100644 --- a/keywords.txt +++ b/keywords.txt @@ -326,6 +326,7 @@ activateOTAA KEYWORD2 beginABP KEYWORD2 activateABP KEYWORD2 isActivated KEYWORD2 +setRx2Dr KEYWORD2 sendMacCommandReq KEYWORD2 uplink KEYWORD2 downlink KEYWORD2 diff --git a/src/TypeDef.h b/src/TypeDef.h index 30c78bd8..da3eccc8 100644 --- a/src/TypeDef.h +++ b/src/TypeDef.h @@ -509,9 +509,9 @@ #define RADIOLIB_ERR_NO_RX_WINDOW (-1105) /*! - \brief No valid channel for the currently active LoRaWAN band was found. + \brief There are no channels available for the requested datarate. */ -#define RADIOLIB_ERR_INVALID_CHANNEL (-1106) +#define RADIOLIB_ERR_NO_CHANNEL_AVAILABLE (-1106) /*! \brief Invalid LoRaWAN MAC command ID. @@ -583,6 +583,11 @@ */ #define RADIOLIB_LORAWAN_SESSION_DISCARDED (-1120) +/*! + \brief The requested command is unavailable under the current LoRaWAN mode. +*/ +#define RADIOLIB_LORAWAN_INVALID_MODE (-1121) + // LR11x0-specific status codes /*! diff --git a/src/protocols/LoRaWAN/LoRaWAN.cpp b/src/protocols/LoRaWAN/LoRaWAN.cpp index 9399814a..e61c0045 100644 --- a/src/protocols/LoRaWAN/LoRaWAN.cpp +++ b/src/protocols/LoRaWAN/LoRaWAN.cpp @@ -1920,8 +1920,7 @@ int16_t LoRaWANNode::selectChannels() { } } if(numChannels == 0) { - RADIOLIB_DEBUG_PROTOCOL_PRINTLN("There are no channels defined - are you in ABP mode with no defined subband?"); - return(RADIOLIB_ERR_INVALID_CHANNEL); + return(RADIOLIB_ERR_NO_CHANNEL_AVAILABLE); } // select a random ID & channel from the list of enabled and possible channels uint8_t channelID = channelsEnabled[this->phyLayer->random(numChannels)]; @@ -2117,6 +2116,33 @@ int16_t LoRaWANNode::findDataRate(uint8_t dr, DataRate_t* dataRate) { return(state); } +int16_t LoRaWANNode::setRx2Dr(uint8_t dr) { + // this can only be configured in ABP mode + if(this->lwMode != RADIOLIB_LORAWAN_MODE_ABP) { + return(RADIOLIB_LORAWAN_INVALID_MODE); + } + + // can only configure different datarate for dynamic bands + if(this->band->bandType == RADIOLIB_LORAWAN_BAND_FIXED) { + return(RADIOLIB_ERR_NO_CHANNEL_AVAILABLE); + } + + // check if datarate is available in the selected band + if(this->band->dataRates[dr] == RADIOLIB_LORAWAN_DATA_RATE_UNUSED) { + return(RADIOLIB_ERR_INVALID_DATA_RATE); + } + + // find and check if the datarate is available for this radio module + DataRate_t dataRate; + int16_t state = findDataRate(dr, &dataRate); + RADIOLIB_ASSERT(state); + + // passed all checks, so configure the datarate + this->rx2.drMax = dr; + + return(state); +} + int16_t LoRaWANNode::sendMacCommandReq(uint8_t cid) { bool valid = false; for(size_t i = 0; i < RADIOLIB_LORAWAN_NUM_MAC_COMMANDS; i++) { diff --git a/src/protocols/LoRaWAN/LoRaWAN.h b/src/protocols/LoRaWAN/LoRaWAN.h index 1e8c7315..674b0189 100644 --- a/src/protocols/LoRaWAN/LoRaWAN.h +++ b/src/protocols/LoRaWAN/LoRaWAN.h @@ -513,12 +513,6 @@ struct LoRaWANEvent_t { class LoRaWANNode { public: - /*! \brief Offset between TX and RX1 (such that RX1 has equal or lower DR) */ - uint8_t rx1DrOffset = 0; - - /*! \brief RX2 channel properties - may be changed by MAC command */ - LoRaWANChannel_t rx2; - /*! \brief Default constructor. \param phy Pointer to the PhysicalLayer radio module. @@ -589,7 +583,7 @@ class LoRaWANNode { /*! \brief Join network by restoring ABP session or performing over-the-air activation. In this procedure, all necessary configuration must be provided by the user. - \param initialDr The datarate at which to send the first uplink and any subsequent uplinks (unless ADR is enabled) + \param initialDr The datarate at which to send the first uplink and any subsequent uplinks (unless ADR is enabled). \returns \ref status_codes */ int16_t activateABP(uint8_t initialDr = RADIOLIB_LORAWAN_DATA_RATE_UNUSED); @@ -597,6 +591,14 @@ class LoRaWANNode { /*! \brief Whether there is an ongoing session active */ bool isActivated(); + /*! + \brief Configure the Rx2 datarate for ABP mode. + This should not be needed for LoRaWAN 1.1 as it is configured through the first downlink. + \param dr The datarate to be used for listening for downlinks in Rx2. + \returns \ref status_codes + */ + int16_t setRx2Dr(uint8_t dr); + /*! \brief Add a MAC command to the uplink queue. Only LinkCheck and DeviceTime are available to the user. @@ -953,6 +955,12 @@ class LoRaWANNode { // currently configured datarates for TX and RX1 uint8_t dataRates[2] = { RADIOLIB_LORAWAN_DATA_RATE_UNUSED, RADIOLIB_LORAWAN_DATA_RATE_UNUSED }; + // Rx2 channel properties - may be changed by MAC command + LoRaWANChannel_t rx2 = RADIOLIB_LORAWAN_CHANNEL_NONE; + + // offset between TX and RX1 (such that RX1 has equal or lower DR) + uint8_t rx1DrOffset = 0; + // LoRaWAN revision (1.0 vs 1.1) uint8_t rev = 0;