[LoRaWAN] Add methods to allow user-provided sleep function

This commit is contained in:
jgromes 2025-02-01 10:40:59 +01:00
parent 4deec953e8
commit 27eece8f8a
3 changed files with 39 additions and 2 deletions

View file

@ -377,6 +377,7 @@ getLastToA KEYWORD2
dutyCycleInterval KEYWORD2
timeUntilUplink KEYWORD2
getMaxPayloadLen KEYWORD2
setSleepFunction KEYWORD2
#######################################
# Constants (LITERAL1)

View file

@ -1377,7 +1377,7 @@ int16_t LoRaWANNode::receiveCommon(uint8_t dir, const LoRaWANChannel_t* dlChanne
if(waitLen > this->scanGuard) {
waitLen -= this->scanGuard;
}
mod->hal->delay(waitLen);
this->sleepDelay(waitLen);
// open Rx window by starting receive with specified timeout
// TODO remove default arguments
@ -1387,7 +1387,7 @@ int16_t LoRaWANNode::receiveCommon(uint8_t dir, const LoRaWANChannel_t* dlChanne
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);
this->sleepDelay(timeoutHost / 1000 + this->scanGuard / 2);
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
@ -3310,6 +3310,10 @@ uint8_t LoRaWANNode::getMaxPayloadLen() {
return(curLen - 13 - this->fOptsUpLen);
}
void LoRaWANNode::setSleepFunction(SleepCb_t cb) {
this->sleepCb = cb;
}
int16_t LoRaWANNode::findDataRate(uint8_t dr, DataRate_t* dataRate) {
int16_t state = this->phyLayer->standby();
if(state != RADIOLIB_ERR_NONE) {
@ -3434,6 +3438,18 @@ void LoRaWANNode::processAES(const uint8_t* in, size_t len, uint8_t* key, uint8_
}
}
void LoRaWANNode::sleepDelay(RadioLibTime_t ms) {
// if the user did not provide sleep callback, or the duration is short, just call delay
if((this->sleepCb == nullptr) || (ms <= RADIOLIB_LORAWAN_DELAY_SLEEP_THRESHOLD)) {
Module* mod = this->phyLayer->getMod();
mod->hal->delay(ms);
return;
}
// otherwise, call the user-provided callback
this->sleepCb(ms);
}
int16_t LoRaWANNode::checkBufferCommon(const uint8_t *buffer, uint16_t size) {
// check if there are actually values in the buffer
size_t i = 0;

View file

@ -210,6 +210,9 @@
#define RADIOLIB_LORAWAN_MAX_DOWNLINK_SIZE (250)
// threshold at which sleeping via user callback enabled, in ms
#define RADIOLIB_LORAWAN_DELAY_SLEEP_THRESHOLD (50)
/*!
\struct LoRaWANMacCommand_t
\brief MAC command specification structure.
@ -832,6 +835,18 @@ class LoRaWANNode {
*/
uint8_t getMaxPayloadLen();
/*! \brief Callback to a user-provided sleep function. */
typedef void (*SleepCb_t)(RadioLibTime_t ms);
/*!
\brief Set custom delay/sleep function callback. If set, LoRaWAN node will call
this function to wait for periods of time longer than RADIOLIB_LORAWAN_DELAY_SLEEP_THRESHOLD.
This can be used to lower the power consumption by putting the host microcontroller to sleep.
NOTE: Since this method will call a user-provided function, it is up to the user to ensure
that the time duration spent in that sleep function is accurate to at least 1 ms!
*/
void setSleepFunction(SleepCb_t cb);
/*!
\brief TS009 Protocol Specification Verification switch
(allows FPort 224 and cuts off uplink payload instead of rejecting if maximum length exceeded).
@ -973,6 +988,8 @@ class LoRaWANNode {
// allow port 226 for devices implementing TS011
bool TS011 = false;
SleepCb_t sleepCb = nullptr;
// this will reset the device credentials, so the device starts completely new
void clearNonces();
@ -1102,6 +1119,9 @@ class LoRaWANNode {
// function to encrypt and decrypt payloads (regular uplink/downlink)
void processAES(const uint8_t* in, size_t len, uint8_t* key, uint8_t* out, uint32_t fCnt, uint8_t dir, uint8_t ctrId, bool counter);
// function that allows sleeping via user-provided callback
void sleepDelay(RadioLibTime_t ms);
// 16-bit checksum method that takes a uint8_t array of even length and calculates the checksum
static uint16_t checkSum16(const uint8_t *key, uint16_t keyLen);