[LoRaWAN] Change and upgrade persistence handling (#1017)
* [LoRaWAN] Change and upgrade persistence handling * [BuildOpt] Patch to upstream * [LoRaWAN] Fix #1018 * [LoRaWAN] Remove outdated parts * [LoRaWAN] Resolve feedback Warning: untested - am not at my desk * [LoRaWAN] Small bugfixes
This commit is contained in:
parent
3d5f05b963
commit
ca2a3073b9
10 changed files with 540 additions and 882 deletions
|
@ -293,6 +293,10 @@ setModem KEYWORD2
|
|||
|
||||
# LoRaWAN
|
||||
wipe KEYWORD2
|
||||
getBufferNonces KEYWORD2
|
||||
setBufferNonces KEYWORD2
|
||||
getBufferSession KEYWORD2
|
||||
setBufferSession KEYWORD2
|
||||
restore KEYWORD2
|
||||
beginOTAA KEYWORD2
|
||||
beginABP KEYWORD2
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
|
||||
#if defined(RADIOLIB_BUILD_ARDUINO)
|
||||
|
||||
#if !defined(RADIOLIB_EEPROM_UNSUPPORTED)
|
||||
#include <EEPROM.h>
|
||||
#endif
|
||||
|
||||
ArduinoHal::ArduinoHal(): RadioLibHal(INPUT, OUTPUT, LOW, HIGH, RISING, FALLING), spi(&RADIOLIB_DEFAULT_SPI), initInterface(true) {}
|
||||
|
||||
ArduinoHal::ArduinoHal(SPIClass& spi, SPISettings spiSettings): RadioLibHal(INPUT, OUTPUT, LOW, HIGH, RISING, FALLING), spi(&spi), spiSettings(spiSettings) {}
|
||||
|
@ -118,49 +114,6 @@ void inline ArduinoHal::spiEnd() {
|
|||
spi->end();
|
||||
}
|
||||
|
||||
void ArduinoHal::readPersistentStorage(uint32_t addr, uint8_t* buff, size_t len) {
|
||||
#if !defined(RADIOLIB_EEPROM_UNSUPPORTED)
|
||||
#if defined(RADIOLIB_ESP32) || defined(ARDUINO_ARCH_RP2040)
|
||||
EEPROM.begin(RADIOLIB_HAL_PERSISTENT_STORAGE_SIZE);
|
||||
#elif defined(ARDUINO_ARCH_APOLLO3)
|
||||
EEPROM.init();
|
||||
#endif
|
||||
for(size_t i = 0; i < len; i++) {
|
||||
buff[i] = EEPROM.read(addr + i);
|
||||
}
|
||||
#if defined(RADIOLIB_ESP32) || defined(ARDUINO_ARCH_RP2040)
|
||||
EEPROM.end();
|
||||
#endif
|
||||
#else
|
||||
(void)addr;
|
||||
(void)buff;
|
||||
(void)len;
|
||||
#endif
|
||||
}
|
||||
|
||||
void ArduinoHal::writePersistentStorage(uint32_t addr, uint8_t* buff, size_t len) {
|
||||
#if !defined(RADIOLIB_EEPROM_UNSUPPORTED)
|
||||
#if defined(RADIOLIB_ESP32) || defined(ARDUINO_ARCH_RP2040)
|
||||
EEPROM.begin(RADIOLIB_HAL_PERSISTENT_STORAGE_SIZE);
|
||||
#elif defined(ARDUINO_ARCH_APOLLO3)
|
||||
EEPROM.init();
|
||||
#endif
|
||||
for(size_t i = 0; i < len; i++) {
|
||||
if(EEPROM.read(addr + i) != buff[i]) { // only write if value is new
|
||||
EEPROM.write(addr + i, buff[i]);
|
||||
}
|
||||
}
|
||||
#if defined(RADIOLIB_ESP32) || defined(ARDUINO_ARCH_RP2040)
|
||||
EEPROM.commit();
|
||||
EEPROM.end();
|
||||
#endif
|
||||
#else
|
||||
(void)addr;
|
||||
(void)buff;
|
||||
(void)len;
|
||||
#endif
|
||||
}
|
||||
|
||||
void inline ArduinoHal::tone(uint32_t pin, unsigned int frequency, unsigned long duration) {
|
||||
#if !defined(RADIOLIB_TONE_UNSUPPORTED)
|
||||
if(pin == RADIOLIB_NC) {
|
||||
|
|
|
@ -51,9 +51,6 @@ class ArduinoHal : public RadioLibHal {
|
|||
void spiEndTransaction() override;
|
||||
void spiEnd() override;
|
||||
|
||||
void readPersistentStorage(uint32_t addr, uint8_t* buff, size_t len) override;
|
||||
void writePersistentStorage(uint32_t addr, uint8_t* buff, size_t len) override;
|
||||
|
||||
// implementations of virtual RadioLibHal methods
|
||||
void init() override;
|
||||
void term() override;
|
||||
|
|
|
@ -104,21 +104,6 @@
|
|||
#define RADIOLIB_STATIC_ARRAY_SIZE (256)
|
||||
#endif
|
||||
|
||||
// the base address for persistent storage
|
||||
// some protocols (e.g. LoRaWAN) require a method
|
||||
// to store some data persistently
|
||||
// on Arduino, this will use EEPROM, on non-Arduino platform,
|
||||
// it will use anything provided by the hardware abstraction layer
|
||||
// RadioLib will place these starting at this address
|
||||
#if !defined(RADIOLIB_HAL_PERSISTENT_STORAGE_BASE)
|
||||
#define RADIOLIB_HAL_PERSISTENT_STORAGE_BASE (0)
|
||||
#endif
|
||||
|
||||
// the amount of space allocated to the persistent storage
|
||||
#if !defined(RADIOLIB_HAL_PERSISTENT_STORAGE_SIZE)
|
||||
#define RADIOLIB_HAL_PERSISTENT_STORAGE_SIZE (0x01C0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Uncomment on boards whose clock runs too slow or too fast
|
||||
* Set the value according to the following scheme:
|
||||
|
@ -238,7 +223,6 @@
|
|||
#elif defined(SAMD_SERIES)
|
||||
// Adafruit SAMD boards (M0 and M4)
|
||||
#define RADIOLIB_PLATFORM "Adafruit SAMD"
|
||||
#define RADIOLIB_EEPROM_UNSUPPORTED
|
||||
|
||||
#elif defined(ARDUINO_ARCH_SAMD)
|
||||
// Arduino SAMD (Zero, MKR, etc.)
|
||||
|
@ -246,18 +230,15 @@
|
|||
#define RADIOLIB_ARDUINOHAL_PIN_MODE_CAST (PinMode)
|
||||
#define RADIOLIB_ARDUINOHAL_PIN_STATUS_CAST (PinStatus)
|
||||
#define RADIOLIB_ARDUINOHAL_INTERRUPT_MODE_CAST (PinStatus)
|
||||
#define RADIOLIB_EEPROM_UNSUPPORTED
|
||||
|
||||
#elif defined(__SAM3X8E__)
|
||||
// Arduino Due
|
||||
#define RADIOLIB_PLATFORM "Arduino Due"
|
||||
#define RADIOLIB_TONE_UNSUPPORTED
|
||||
#define RADIOLIB_EEPROM_UNSUPPORTED
|
||||
|
||||
#elif (defined(NRF52832_XXAA) || defined(NRF52840_XXAA)) && !defined(ARDUINO_ARDUINO_NANO33BLE)
|
||||
// Adafruit nRF52 boards
|
||||
#define RADIOLIB_PLATFORM "Adafruit nRF52"
|
||||
#define RADIOLIB_EEPROM_UNSUPPORTED
|
||||
|
||||
#elif defined(ARDUINO_ARC32_TOOLS)
|
||||
// Intel Curie
|
||||
|
@ -280,7 +261,6 @@
|
|||
#define RADIOLIB_ARDUINOHAL_PIN_MODE_CAST (PinMode)
|
||||
#define RADIOLIB_ARDUINOHAL_PIN_STATUS_CAST (PinStatus)
|
||||
#define RADIOLIB_ARDUINOHAL_INTERRUPT_MODE_CAST (PinStatus)
|
||||
#define RADIOLIB_EEPROM_UNSUPPORTED
|
||||
|
||||
// Arduino mbed OS boards have a really bad tone implementation which will crash after a couple seconds
|
||||
#define RADIOLIB_TONE_UNSUPPORTED
|
||||
|
@ -292,7 +272,6 @@
|
|||
#define RADIOLIB_ARDUINOHAL_PIN_MODE_CAST (PinMode)
|
||||
#define RADIOLIB_ARDUINOHAL_PIN_STATUS_CAST (PinStatus)
|
||||
#define RADIOLIB_ARDUINOHAL_INTERRUPT_MODE_CAST (PinStatus)
|
||||
#define RADIOLIB_EEPROM_UNSUPPORTED
|
||||
|
||||
// Arduino mbed OS boards have a really bad tone implementation which will crash after a couple seconds
|
||||
#define RADIOLIB_TONE_UNSUPPORTED
|
||||
|
@ -314,7 +293,6 @@
|
|||
#define RADIOLIB_ARDUINOHAL_PIN_MODE_CAST (PinMode)
|
||||
#define RADIOLIB_ARDUINOHAL_PIN_STATUS_CAST (PinStatus)
|
||||
#define RADIOLIB_ARDUINOHAL_INTERRUPT_MODE_CAST (PinStatus)
|
||||
#define RADIOLIB_EEPROM_UNSUPPORTED
|
||||
|
||||
// Arduino mbed OS boards have a really bad tone implementation which will crash after a couple seconds
|
||||
#define RADIOLIB_TONE_UNSUPPORTED
|
||||
|
@ -585,4 +563,4 @@
|
|||
|
||||
#define RADIOLIB_VERSION (((RADIOLIB_VERSION_MAJOR) << 24) | ((RADIOLIB_VERSION_MINOR) << 16) | ((RADIOLIB_VERSION_PATCH) << 8) | (RADIOLIB_VERSION_EXTRA))
|
||||
|
||||
#endif
|
||||
#endif
|
47
src/Hal.cpp
47
src/Hal.cpp
|
@ -33,50 +33,3 @@ void RadioLibHal::yield() {
|
|||
uint32_t RadioLibHal::pinToInterrupt(uint32_t pin) {
|
||||
return(pin);
|
||||
}
|
||||
|
||||
void RadioLibHal::readPersistentStorage(uint32_t addr, uint8_t* buff, size_t len) {
|
||||
// these are only needed for some protocols, so it's not needed to have them by default
|
||||
(void)addr;
|
||||
(void)buff;
|
||||
(void)len;
|
||||
}
|
||||
|
||||
void RadioLibHal::writePersistentStorage(uint32_t addr, uint8_t* buff, size_t len) {
|
||||
// these are only needed for some protocols, so it's not needed to have them by default
|
||||
(void)addr;
|
||||
(void)buff;
|
||||
(void)len;
|
||||
}
|
||||
|
||||
void RadioLibHal::wipePersistentStorage() {
|
||||
uint8_t dummy = 0;
|
||||
for(size_t i = 0; i < RADIOLIB_HAL_PERSISTENT_STORAGE_SIZE; i++) {
|
||||
this->writePersistentStorage(RADIOLIB_HAL_PERSISTENT_STORAGE_BASE + i, &dummy, sizeof(uint8_t));
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t RadioLibHal::getPersistentAddr(uint32_t id) {
|
||||
return(RadioLibPersistentParamTable[id]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void RadioLibHal::setPersistentParameter(uint32_t id, T val, uint32_t offset) {
|
||||
uint8_t *ptr = (uint8_t*)&val;
|
||||
this->writePersistentStorage(RADIOLIB_HAL_PERSISTENT_STORAGE_BASE + RadioLibPersistentParamTable[id] + offset, ptr, sizeof(T));
|
||||
}
|
||||
|
||||
template void RadioLibHal::setPersistentParameter(uint32_t id, uint8_t val, uint32_t offset);
|
||||
template void RadioLibHal::setPersistentParameter(uint32_t id, uint16_t val, uint32_t offset);
|
||||
template void RadioLibHal::setPersistentParameter(uint32_t id, uint32_t val, uint32_t offset);
|
||||
|
||||
template<typename T>
|
||||
T RadioLibHal::getPersistentParameter(uint32_t id) {
|
||||
T val = 0;
|
||||
uint8_t *ptr = (uint8_t*)&val;
|
||||
this->readPersistentStorage(RADIOLIB_HAL_PERSISTENT_STORAGE_BASE + RadioLibPersistentParamTable[id], ptr, sizeof(T));
|
||||
return(val);
|
||||
}
|
||||
|
||||
template uint8_t RadioLibHal::getPersistentParameter(uint32_t id);
|
||||
template uint16_t RadioLibHal::getPersistentParameter(uint32_t id);
|
||||
template uint32_t RadioLibHal::getPersistentParameter(uint32_t id);
|
||||
|
|
132
src/Hal.h
132
src/Hal.h
|
@ -6,88 +6,6 @@
|
|||
|
||||
#include "BuildOpt.h"
|
||||
|
||||
#define RADIOLIB_EEPROM_TABLE_VERSION (0x0002)
|
||||
|
||||
// list of persistent parameters
|
||||
enum RADIOLIB_EEPROM_PARAMS {
|
||||
RADIOLIB_EEPROM_TABLE_VERSION_ID, // table layout version
|
||||
RADIOLIB_EEPROM_LORAWAN_CLASS_ID, // class A, B or C
|
||||
RADIOLIB_EEPROM_LORAWAN_MODE_ID, // none, OTAA or ABP
|
||||
RADIOLIB_EEPROM_LORAWAN_CHECKSUM_ID, // checksum of keys used for device activation
|
||||
RADIOLIB_EEPROM_LORAWAN_VERSION_ID, // LoRaWAN version
|
||||
RADIOLIB_EEPROM_LORAWAN_LAST_TIME_ID, // last heard time through DeviceTimeReq or Beacon
|
||||
RADIOLIB_EEPROM_LORAWAN_DEV_ADDR_ID,
|
||||
RADIOLIB_EEPROM_LORAWAN_APP_S_KEY_ID,
|
||||
RADIOLIB_EEPROM_LORAWAN_FNWK_SINT_KEY_ID,
|
||||
RADIOLIB_EEPROM_LORAWAN_SNWK_SINT_KEY_ID,
|
||||
RADIOLIB_EEPROM_LORAWAN_NWK_SENC_KEY_ID,
|
||||
RADIOLIB_EEPROM_LORAWAN_DEV_NONCE_ID,
|
||||
RADIOLIB_EEPROM_LORAWAN_JOIN_NONCE_ID,
|
||||
RADIOLIB_EEPROM_LORAWAN_HOME_NET_ID,
|
||||
RADIOLIB_EEPROM_LORAWAN_A_FCNT_DOWN_ID,
|
||||
RADIOLIB_EEPROM_LORAWAN_N_FCNT_DOWN_ID,
|
||||
RADIOLIB_EEPROM_LORAWAN_CONF_FCNT_UP_ID,
|
||||
RADIOLIB_EEPROM_LORAWAN_CONF_FCNT_DOWN_ID,
|
||||
RADIOLIB_EEPROM_LORAWAN_ADR_FCNT_ID,
|
||||
RADIOLIB_EEPROM_LORAWAN_RJ_COUNT0_ID,
|
||||
RADIOLIB_EEPROM_LORAWAN_RJ_COUNT1_ID,
|
||||
RADIOLIB_EEPROM_LORAWAN_FCNT_UP_ID,
|
||||
RADIOLIB_EEPROM_LORAWAN_LINK_ADR_ID,
|
||||
RADIOLIB_EEPROM_LORAWAN_DUTY_CYCLE_ID,
|
||||
RADIOLIB_EEPROM_LORAWAN_RX_PARAM_SETUP_ID,
|
||||
RADIOLIB_EEPROM_LORAWAN_RX_TIMING_SETUP_ID,
|
||||
RADIOLIB_EEPROM_LORAWAN_TX_PARAM_SETUP_ID,
|
||||
RADIOLIB_EEPROM_LORAWAN_ADR_PARAM_SETUP_ID,
|
||||
RADIOLIB_EEPROM_LORAWAN_REJOIN_PARAM_SETUP_ID,
|
||||
RADIOLIB_EEPROM_LORAWAN_BEACON_FREQ_ID,
|
||||
RADIOLIB_EEPROM_LORAWAN_PING_SLOT_CHANNEL_ID,
|
||||
RADIOLIB_EEPROM_LORAWAN_PERIODICITY_ID,
|
||||
RADIOLIB_EEPROM_LORAWAN_NUM_ADR_MASKS_ID,
|
||||
RADIOLIB_EEPROM_LORAWAN_MAC_QUEUE_UL_ID,
|
||||
RADIOLIB_EEPROM_LORAWAN_UL_CHANNELS_ID,
|
||||
RADIOLIB_EEPROM_LORAWAN_DL_CHANNELS_ID
|
||||
};
|
||||
|
||||
static const uint32_t RadioLibPersistentParamTable[] = {
|
||||
0x00, // RADIOLIB_EEPROM_TABLE_VERSION_ID
|
||||
0x02, // RADIOLIB_EEPROM_LORAWAN_CLASS_ID
|
||||
0x03, // RADIOLIB_EEPROM_LORAWAN_MODE_ID
|
||||
0x05, // RADIOLIB_EEPROM_LORAWAN_CHECKSUM_ID
|
||||
0x07, // RADIOLIB_EEPROM_LORAWAN_VERSION_ID
|
||||
0x08, // RADIOLIB_EEPROM_LORAWAN_LAST_TIME_ID
|
||||
0x0C, // RADIOLIB_EEPROM_LORAWAN_DEV_ADDR_ID
|
||||
0x10, // RADIOLIB_EEPROM_LORAWAN_APP_S_KEY_ID
|
||||
0x20, // RADIOLIB_EEPROM_LORAWAN_FNWK_SINT_KEY_ID
|
||||
0x30, // RADIOLIB_EEPROM_LORAWAN_SNWK_SINT_KEY_ID
|
||||
0x40, // RADIOLIB_EEPROM_LORAWAN_NWK_SENC_KEY_ID
|
||||
0x50, // RADIOLIB_EEPROM_LORAWAN_DEV_NONCE_ID
|
||||
0x54, // RADIOLIB_EEPROM_LORAWAN_JOIN_NONCE_ID
|
||||
0x58, // RADIOLIB_EEPROM_LORAWAN_HOME_NET_ID
|
||||
0x5C, // RADIOLIB_EEPROM_LORAWAN_A_FCNT_DOWN_ID
|
||||
0x60, // RADIOLIB_EEPROM_LORAWAN_N_FCNT_DOWN_ID
|
||||
0x64, // RADIOLIB_EEPROM_LORAWAN_CONF_FCNT_UP_ID
|
||||
0x68, // RADIOLIB_EEPROM_LORAWAN_CONF_FCNT_DOWN_ID
|
||||
0x6C, // RADIOLIB_EEPROM_LORAWAN_ADR_FCNT_ID
|
||||
0x70, // RADIOLIB_EEPROM_LORAWAN_RJ_COUNT0_ID
|
||||
0x72, // RADIOLIB_EEPROM_LORAWAN_RJ_COUNT1_ID
|
||||
0x74, // RADIOLIB_EEPROM_LORAWAN_FCNT_UP_ID
|
||||
0xA0, // RADIOLIB_EEPROM_LORAWAN_LINK_ADR_ID
|
||||
0xA4, // RADIOLIB_EEPROM_LORAWAN_DUTY_CYCLE_ID
|
||||
0xA5, // RADIOLIB_EEPROM_LORAWAN_RX_PARAM_SETUP_ID
|
||||
0xA9, // RADIOLIB_EEPROM_LORAWAN_RX_TIMING_SETUP_ID
|
||||
0xAA, // RADIOLIB_EEPROM_LORAWAN_TX_PARAM_SETUP_ID
|
||||
0xAB, // RADIOLIB_EEPROM_LORAWAN_ADR_PARAM_SETUP_ID
|
||||
0xAC, // RADIOLIB_EEPROM_LORAWAN_REJOIN_PARAM_SETUP_ID
|
||||
0xAD, // RADIOLIB_EEPROM_LORAWAN_BEACON_FREQ_ID
|
||||
0xB0, // RADIOLIB_EEPROM_LORAWAN_PING_SLOT_CHANNEL_ID
|
||||
0xB4, // RADIOLIB_EEPROM_LORAWAN_PERIODICITY_ID
|
||||
0xB5, // RADIOLIB_EEPROM_LORAWAN_NUM_ADR_MASKS_ID
|
||||
0xB6, // RADIOLIB_EEPROM_LORAWAN_MAC_QUEUE_UL_ID
|
||||
0x0100, // RADIOLIB_EEPROM_LORAWAN_UL_CHANNELS_ID
|
||||
0x0180, // RADIOLIB_EEPROM_LORAWAN_DL_CHANNELS_ID
|
||||
0x01C0, // end
|
||||
};
|
||||
|
||||
/*!
|
||||
\class RadioLibHal
|
||||
\brief Hardware abstraction library base interface.
|
||||
|
@ -289,56 +207,6 @@ class RadioLibHal {
|
|||
\returns The interrupt number of a given pin.
|
||||
*/
|
||||
virtual uint32_t pinToInterrupt(uint32_t pin);
|
||||
|
||||
/*!
|
||||
\brief Method to read from persistent storage (e.g. EEPROM).
|
||||
\param addr Address to start reading at.
|
||||
\param buff Buffer to read into.
|
||||
\param len Number of bytes to read.
|
||||
*/
|
||||
virtual void readPersistentStorage(uint32_t addr, uint8_t* buff, size_t len);
|
||||
|
||||
/*!
|
||||
\brief Method to write to persistent storage (e.g. EEPROM).
|
||||
\param addr Address to start writing to.
|
||||
\param buff Buffer to write.
|
||||
\param len Number of bytes to write.
|
||||
*/
|
||||
virtual void writePersistentStorage(uint32_t addr, uint8_t* buff, size_t len);
|
||||
|
||||
/*!
|
||||
\brief Method to wipe the persistent storage by writing to 0.
|
||||
Will write at most RADIOLIB_HAL_PERSISTENT_STORAGE_SIZE bytes.
|
||||
*/
|
||||
void wipePersistentStorage();
|
||||
|
||||
/*!
|
||||
\brief Method to convert from persistent parameter ID to its physical address.
|
||||
\param id Parameter ID.
|
||||
\returns Parameter physical address.
|
||||
*/
|
||||
uint32_t getPersistentAddr(uint32_t id);
|
||||
|
||||
/*!
|
||||
\brief Method to set arbitrary parameter to persistent storage.
|
||||
This method DOES NOT perform any endianness conversion, so the value
|
||||
will be stored in the system endian!
|
||||
\param id Parameter ID to save at.
|
||||
\param val Value to set.
|
||||
\param offset An additional offset added to the address.
|
||||
*/
|
||||
template<typename T>
|
||||
void setPersistentParameter(uint32_t id, T val, uint32_t offset = 0);
|
||||
|
||||
/*!
|
||||
\brief Method to get arbitrary parameter from persistent storage.
|
||||
This method DOES NOT perform any endianness conversion, so the value
|
||||
will be retrieved in the system endian!
|
||||
\param id Parameter ID to load from.
|
||||
\returns The loaded value.
|
||||
*/
|
||||
template<typename T>
|
||||
T getPersistentParameter(uint32_t id);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -558,6 +558,11 @@
|
|||
*/
|
||||
#define RADIOLIB_ERR_DWELL_TIME_EXCEEDED (-1115)
|
||||
|
||||
/*!
|
||||
\brief The buffer integrity check did not match the supplied checksum value.
|
||||
*/
|
||||
#define RADIOLIB_ERR_CHECKSUM_MISMATCH (-1116)
|
||||
|
||||
/*!
|
||||
\}
|
||||
*/
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -6,14 +6,14 @@
|
|||
#include "../../utils/Cryptography.h"
|
||||
|
||||
// activation mode
|
||||
#define RADIOLIB_LORAWAN_MODE_OTAA (0x01AA)
|
||||
#define RADIOLIB_LORAWAN_MODE_OTAA (0x07AA)
|
||||
#define RADIOLIB_LORAWAN_MODE_ABP (0x0AB9)
|
||||
#define RADIOLIB_LORAWAN_MODE_NONE (0x0000)
|
||||
|
||||
// operation mode
|
||||
#define RADIOLIB_LORAWAN_CLASS_A (0x00)
|
||||
#define RADIOLIB_LORAWAN_CLASS_B (0x01)
|
||||
#define RADIOLIB_LORAWAN_CLASS_C (0x02)
|
||||
#define RADIOLIB_LORAWAN_CLASS_A (0x0A)
|
||||
#define RADIOLIB_LORAWAN_CLASS_B (0x0B)
|
||||
#define RADIOLIB_LORAWAN_CLASS_C (0x0C)
|
||||
|
||||
// preamble format
|
||||
#define RADIOLIB_LORAWAN_LORA_SYNC_WORD (0x34)
|
||||
|
@ -226,6 +226,56 @@ const LoRaWANMacSpec_t MacTable[RADIOLIB_LORAWAN_NUM_MAC_COMMANDS + 1] = {
|
|||
{ RADIOLIB_LORAWAN_MAC_PROPRIETARY, 5, 0, true }
|
||||
};
|
||||
|
||||
#define RADIOLIB_LORAWAN_NONCES_VERSION_VAL (0x0001)
|
||||
|
||||
enum LoRaWANSchemeBase_t {
|
||||
RADIOLIB_LORAWAN_NONCES_VERSION = 0x00, // 2 bytes
|
||||
RADIOLIB_LORAWAN_NONCES_MODE = 0x02, // 2 bytes
|
||||
RADIOLIB_LORAWAN_NONCES_CLASS = 0x04, // 1 byte
|
||||
RADIOLIB_LORAWAN_NONCES_PLAN = 0x05, // 1 byte
|
||||
RADIOLIB_LORAWAN_NONCES_CHECKSUM = 0x06, // 2 bytes
|
||||
RADIOLIB_LORAWAN_NONCES_DEV_NONCE = 0x08, // 2 bytes
|
||||
RADIOLIB_LORAWAN_NONCES_JOIN_NONCE = 0x0A, // 3 bytes
|
||||
RADIOLIB_LORAWAN_NONCES_ACTIVE = 0x0D, // 1 byte
|
||||
RADIOLIB_LORAWAN_NONCES_SIGNATURE = 0x0E, // 2 bytes
|
||||
RADIOLIB_LORAWAN_NONCES_BUF_SIZE = 0x10 // = 16 bytes
|
||||
};
|
||||
|
||||
enum LoRaWANSchemeSession_t {
|
||||
RADIOLIB_LORAWAN_SESSION_NWK_SENC_KEY = 0x00, // 16 bytes
|
||||
RADIOLIB_LORAWAN_SESSION_APP_SKEY = 0x10, // 16 bytes
|
||||
RADIOLIB_LORAWAN_SESSION_FNWK_SINT_KEY = 0x20, // 16 bytes
|
||||
RADIOLIB_LORAWAN_SESSION_SNWK_SINT_KEY = 0x30, // 16 bytes
|
||||
RADIOLIB_LORAWAN_SESSION_DEV_ADDR = 0x40, // 4 bytes
|
||||
RADIOLIB_LORAWAN_SESSION_NONCES_SIGNATURE = 0x44, // 2 bytes
|
||||
RADIOLIB_LORAWAN_SESSION_A_FCNT_DOWN = 0x46, // 4 bytes
|
||||
RADIOLIB_LORAWAN_SESSION_CONF_FCNT_UP = 0x4A, // 4 bytes
|
||||
RADIOLIB_LORAWAN_SESSION_CONF_FCNT_DOWN = 0x4E, // 4 bytes
|
||||
RADIOLIB_LORAWAN_SESSION_RJ_COUNT0 = 0x52, // 2 bytes
|
||||
RADIOLIB_LORAWAN_SESSION_RJ_COUNT1 = 0x54, // 2 bytes
|
||||
RADIOLIB_LORAWAN_SESSION_HOMENET_ID = 0x56, // 4 bytes
|
||||
RADIOLIB_LORAWAN_SESSION_VERSION = 0x5A, // 1 byte
|
||||
RADIOLIB_LORAWAN_SESSION_DUTY_CYCLE = 0x5B, // 1 byte
|
||||
RADIOLIB_LORAWAN_SESSION_RX_PARAM_SETUP = 0x5C, // 4 bytes
|
||||
RADIOLIB_LORAWAN_SESSION_RX_TIMING_SETUP = 0x60, // 1 byte
|
||||
RADIOLIB_LORAWAN_SESSION_TX_PARAM_SETUP = 0x61, // 1 byte
|
||||
RADIOLIB_LORAWAN_SESSION_ADR_PARAM_SETUP = 0x62, // 1 byte
|
||||
RADIOLIB_LORAWAN_SESSION_REJOIN_PARAM_SETUP = 0x63, // 1 byte
|
||||
RADIOLIB_LORAWAN_SESSION_BEACON_FREQ = 0x64, // 3 bytes
|
||||
RADIOLIB_LORAWAN_SESSION_PING_SLOT_CHANNEL = 0x67, // 4 bytes
|
||||
RADIOLIB_LORAWAN_SESSION_PERIODICITY = 0x6B, // 1 byte
|
||||
RADIOLIB_LORAWAN_SESSION_LAST_TIME = 0x6C, // 4 bytes
|
||||
RADIOLIB_LORAWAN_SESSION_UL_CHANNELS = 0x70, // 16*8 bytes
|
||||
RADIOLIB_LORAWAN_SESSION_DL_CHANNELS = 0xF0, // 16*4 bytes
|
||||
RADIOLIB_LORAWAN_SESSION_MAC_QUEUE_UL = 0x0130, // 9*8+2 bytes
|
||||
RADIOLIB_LORAWAN_SESSION_N_FCNT_DOWN = 0x017A, // 4 bytes
|
||||
RADIOLIB_LORAWAN_SESSION_ADR_FCNT = 0x017E, // 4 bytes
|
||||
RADIOLIB_LORAWAN_SESSION_LINK_ADR = 0x0182, // 4 bytes
|
||||
RADIOLIB_LORAWAN_SESSION_FCNT_UP = 0x0186, // 4 bytes
|
||||
RADIOLIB_LORAWAN_SESSION_SIGNATURE = 0x018A, // 2 bytes
|
||||
RADIOLIB_LORAWAN_SESSION_BUF_SIZE = 0x018C // 396 bytes
|
||||
};
|
||||
|
||||
/*!
|
||||
\struct LoRaWANChannelSpan_t
|
||||
\brief Structure to save information about LoRaWAN channels.
|
||||
|
@ -284,6 +334,9 @@ struct LoRaWANChannelSpan_t {
|
|||
\brief Structure to save information about LoRaWAN band
|
||||
*/
|
||||
struct LoRaWANBand_t {
|
||||
/*! \brief Identier for this band */
|
||||
uint8_t bandNum;
|
||||
|
||||
/*! \brief Whether the channels are fixed per specification, or dynamically allocated through the network (plus defaults) */
|
||||
uint8_t bandType;
|
||||
|
||||
|
@ -415,7 +468,6 @@ class LoRaWANNode {
|
|||
*/
|
||||
LoRaWANNode(PhysicalLayer* phy, const LoRaWANBand_t* band, uint8_t subBand = 0);
|
||||
|
||||
#if !defined(RADIOLIB_EEPROM_UNSUPPORTED)
|
||||
/*!
|
||||
\brief Wipe internal persistent parameters.
|
||||
This will reset all counters and saved variables, so the device will have to rejoin the network.
|
||||
|
@ -423,12 +475,36 @@ class LoRaWANNode {
|
|||
void wipe();
|
||||
|
||||
/*!
|
||||
\brief Restore session by loading information from persistent storage.
|
||||
\returns \ref status_codes in case of error,
|
||||
else LoRaWAN session mode (0 = no active session, 0xAA / 170 = OTAA, 0xAB / 171 = ABP)
|
||||
\brief Returns the pointer to the internal buffer that holds the LW base parameters
|
||||
\returns Pointer to uint8_t array of size RADIOLIB_LORAWAN_NONCES_BUF_SIZE
|
||||
*/
|
||||
int16_t restore();
|
||||
#endif
|
||||
uint8_t* getBufferNonces();
|
||||
|
||||
/*!
|
||||
\brief Fill the internal buffer that holds the LW base parameters with a supplied buffer
|
||||
\param persistentBuffer Buffer that should match the internal format (previously extracted using getBufferNonces)
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setBufferNonces(uint8_t* persistentBuffer);
|
||||
|
||||
/*!
|
||||
\brief Returns the pointer to the internal buffer that holds the LW session parameters
|
||||
\returns Pointer to uint8_t array of size RADIOLIB_LORAWAN_SESSION_BUF_SIZE
|
||||
*/
|
||||
uint8_t* getBufferSession();
|
||||
|
||||
/*!
|
||||
\brief Fill the internal buffer that holds the LW session parameters with a supplied buffer
|
||||
\param persistentBuffer Buffer that should match the internal format (previously extracted using getBufferSession)
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setBufferSession(uint8_t* persistentBuffer);
|
||||
|
||||
/*!
|
||||
\brief Restore session by loading information from persistent storage.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t restore(uint16_t checkSum, uint16_t lwMode, uint8_t lwClass, uint8_t freqPlan);
|
||||
|
||||
/*!
|
||||
\brief Join network by performing over-the-air activation. By this procedure,
|
||||
|
@ -437,12 +513,11 @@ class LoRaWANNode {
|
|||
\param devEUI 8-byte device identifier.
|
||||
\param nwkKey Pointer to the network AES-128 key.
|
||||
\param appKey Pointer to the application AES-128 key.
|
||||
\param joinDr (OTAA:) The datarate at which to send the join-request; (ABP:) ignored
|
||||
\param force Set to true to force joining even if previously joined.
|
||||
|
||||
\param joinDr The datarate at which to send the join-request and any subsequent uplinks (unless ADR is enabled)
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t beginOTAA(uint64_t joinEUI, uint64_t devEUI, uint8_t* nwkKey, uint8_t* appKey, uint8_t joinDr = RADIOLIB_LORAWAN_DATA_RATE_UNUSED, bool force = false);
|
||||
int16_t beginOTAA(uint64_t joinEUI, uint64_t devEUI, uint8_t* nwkKey, uint8_t* appKey, bool force = false, uint8_t joinDr = RADIOLIB_LORAWAN_DATA_RATE_UNUSED);
|
||||
|
||||
/*!
|
||||
\brief Join network by performing activation by personalization.
|
||||
|
@ -450,8 +525,8 @@ class LoRaWANNode {
|
|||
\param addr Device address.
|
||||
\param nwkSKey Pointer to the network session AES-128 key (LoRaWAN 1.0) or MAC command network session key (LoRaWAN 1.1).
|
||||
\param appSKey Pointer to the application session AES-128 key.
|
||||
\param fNwkSIntKey Pointer to the network session F key (LoRaWAN 1.1), unused for LoRaWAN 1.0.
|
||||
\param sNwkSIntKey Pointer to the network session S key (LoRaWAN 1.1), unused for LoRaWAN 1.0.
|
||||
\param fNwkSIntKey Pointer to the Forwarding network session (LoRaWAN 1.1), unused for LoRaWAN 1.0.
|
||||
\param sNwkSIntKey Pointer to the Serving network session (LoRaWAN 1.1), unused for LoRaWAN 1.0.
|
||||
\param force Set to true to force a new session, even if one exists.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
|
@ -461,8 +536,7 @@ class LoRaWANNode {
|
|||
bool isJoined();
|
||||
|
||||
/*!
|
||||
\brief Save the current state of the session.
|
||||
All variables are compared to what is saved and only the differences are rewritten.
|
||||
\brief Save the current state of the session to the session buffer.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t saveSession();
|
||||
|
@ -637,10 +711,9 @@ class LoRaWANNode {
|
|||
/*!
|
||||
\brief Set uplink datarate. This should not be used when ADR is enabled.
|
||||
\param dr Datarate to use for uplinks.
|
||||
\param saveToEeprom Whether to save this setting to EEPROM or not (default false).
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setDatarate(uint8_t drUp, bool saveToEeprom = false);
|
||||
int16_t setDatarate(uint8_t drUp);
|
||||
|
||||
/*!
|
||||
\brief Toggle ADR to on or off.
|
||||
|
@ -686,10 +759,9 @@ class LoRaWANNode {
|
|||
/*!
|
||||
\brief Configure TX power of the radio module.
|
||||
\param txPower Output power during TX mode to be set in dBm.
|
||||
\param saveToEeprom Whether to save this setting to EEPROM or not (default false).
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t setTxPower(int8_t txPower, bool saveToEeprom = false);
|
||||
int16_t setTxPower(int8_t txPower);
|
||||
|
||||
/*!
|
||||
\brief Configures CSMA for LoRaWAN as per TR-13, LoRa Alliance.
|
||||
|
@ -732,8 +804,16 @@ class LoRaWANNode {
|
|||
PhysicalLayer* phyLayer = NULL;
|
||||
const LoRaWANBand_t* band = NULL;
|
||||
|
||||
static int16_t checkBufferCommon(uint8_t *buffer, uint16_t size);
|
||||
|
||||
void beginCommon(uint8_t joinDr = RADIOLIB_LORAWAN_DATA_RATE_UNUSED);
|
||||
|
||||
// a buffer that holds all LW base parameters that should persist at all times!
|
||||
uint8_t bufferNonces[RADIOLIB_LORAWAN_NONCES_BUF_SIZE] = { 0 };
|
||||
|
||||
// a buffer that holds all LW session parameters that preferably persist, but can be afforded to get lost
|
||||
uint8_t bufferSession[RADIOLIB_LORAWAN_SESSION_BUF_SIZE] = { 0 };
|
||||
|
||||
LoRaWANMacCommandQueue_t commandsUp = {
|
||||
.numCommands = 0,
|
||||
.len = 0,
|
||||
|
@ -776,7 +856,7 @@ class LoRaWANNode {
|
|||
bool FSK = false;
|
||||
|
||||
// flag that shows whether the device is joined and there is an ongoing session (none, ABP or OTAA)
|
||||
uint16_t activeMode = 0;
|
||||
uint16_t activeMode = RADIOLIB_LORAWAN_MODE_NONE;
|
||||
|
||||
// ADR is enabled by default
|
||||
bool adrEnabled = true;
|
||||
|
@ -835,26 +915,6 @@ class LoRaWANNode {
|
|||
// save the selected sub-band in case this must be restored in ADR control
|
||||
uint8_t subBand = 0;
|
||||
|
||||
#if !defined(RADIOLIB_EEPROM_UNSUPPORTED)
|
||||
/*!
|
||||
\brief Save the current uplink frame counter.
|
||||
Note that the usable frame counter width is 'only' 30 bits for highly efficient wear-levelling.
|
||||
*/
|
||||
void saveFcntUp();
|
||||
|
||||
/*!
|
||||
\brief Restore frame counter for uplinks from persistent storage.
|
||||
Note that the usable frame counter width is 'only' 30 bits for highly efficient wear-levelling.
|
||||
*/
|
||||
void restoreFcntUp();
|
||||
|
||||
// set all keys to zero
|
||||
void clearSession();
|
||||
|
||||
// test if saved keys are non-zero
|
||||
bool isValidSession();
|
||||
#endif
|
||||
|
||||
// wait for, open and listen during Rx1 and Rx2 windows; only performs listening
|
||||
int16_t downlinkCommon();
|
||||
|
||||
|
@ -901,13 +961,13 @@ class LoRaWANNode {
|
|||
int16_t deleteMacCommand(uint8_t cid, LoRaWANMacCommandQueue_t* queue, uint8_t* payload = NULL);
|
||||
|
||||
// execute mac command, return the number of processed bytes for sequential processing
|
||||
bool execMacCommand(LoRaWANMacCommand_t* cmd, bool saveToEeprom = true);
|
||||
bool execMacCommand(LoRaWANMacCommand_t* cmd);
|
||||
|
||||
// apply a channel mask to a set of readily defined channels (dynamic bands only)
|
||||
bool applyChannelMaskDyn(uint8_t chMaskCntl, uint16_t chMask);
|
||||
|
||||
// define or delete channels from a fixed set of channels (fixed bands only)
|
||||
bool applyChannelMaskFix(uint8_t chMaskCntl, uint16_t chMask, bool clear);
|
||||
bool applyChannelMaskFix(uint8_t chMaskCntl, uint16_t chMask);
|
||||
|
||||
// get the payload length for a specific MAC command
|
||||
uint8_t getMacPayloadLength(uint8_t cid);
|
||||
|
@ -922,7 +982,7 @@ class LoRaWANNode {
|
|||
void processAES(uint8_t* in, size_t len, uint8_t* key, uint8_t* out, uint32_t fcnt, uint8_t dir, uint8_t ctrId, bool counter);
|
||||
|
||||
// 16-bit checksum method that takes a uint8_t array of even length and calculates the checksum
|
||||
static uint16_t checkSum16(uint8_t *key, uint8_t keyLen);
|
||||
static uint16_t checkSum16(uint8_t *key, uint16_t keyLen);
|
||||
|
||||
// network-to-host conversion method - takes data from network packet and converts it to the host endians
|
||||
template<typename T>
|
||||
|
|
|
@ -2,7 +2,21 @@
|
|||
|
||||
#if !RADIOLIB_EXCLUDE_LORAWAN
|
||||
|
||||
enum LoRaWANBandNum_t {
|
||||
BandNone,
|
||||
BandEU868,
|
||||
BandUS915,
|
||||
BandCN780,
|
||||
BandEU433,
|
||||
BandAU915,
|
||||
BandCN500,
|
||||
BandAS923,
|
||||
BandKR920,
|
||||
BandIN865
|
||||
};
|
||||
|
||||
const LoRaWANBand_t EU868 = {
|
||||
.bandNum = BandEU868,
|
||||
.bandType = RADIOLIB_LORAWAN_BAND_DYNAMIC,
|
||||
.payloadLenMax = { 59, 59, 59, 123, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0 },
|
||||
.powerMax = 16,
|
||||
|
@ -48,6 +62,7 @@ const LoRaWANBand_t EU868 = {
|
|||
};
|
||||
|
||||
const LoRaWANBand_t US915 = {
|
||||
.bandNum = BandUS915,
|
||||
.bandType = RADIOLIB_LORAWAN_BAND_FIXED,
|
||||
.payloadLenMax = { 19, 61, 133, 250, 250, 0, 0, 0, 41, 117, 230, 230, 230, 230, 0 },
|
||||
.powerMax = 30,
|
||||
|
@ -114,6 +129,7 @@ const LoRaWANBand_t US915 = {
|
|||
};
|
||||
|
||||
const LoRaWANBand_t CN780 = {
|
||||
.bandNum = BandCN780,
|
||||
.bandType = RADIOLIB_LORAWAN_BAND_DYNAMIC,
|
||||
.payloadLenMax = { 59, 59, 59, 123, 230, 230, 250, 230, 0, 0, 0, 0, 0, 0, 0 },
|
||||
.powerMax = 12,
|
||||
|
@ -159,6 +175,7 @@ const LoRaWANBand_t CN780 = {
|
|||
};
|
||||
|
||||
const LoRaWANBand_t EU433 = {
|
||||
.bandNum = BandEU433,
|
||||
.bandType = RADIOLIB_LORAWAN_BAND_DYNAMIC,
|
||||
.payloadLenMax = { 59, 59, 59, 123, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0 },
|
||||
.powerMax = 12,
|
||||
|
@ -204,6 +221,7 @@ const LoRaWANBand_t EU433 = {
|
|||
};
|
||||
|
||||
const LoRaWANBand_t AU915 = {
|
||||
.bandNum = BandAU915,
|
||||
.bandType = RADIOLIB_LORAWAN_BAND_FIXED,
|
||||
.payloadLenMax = { 59, 59, 59, 123, 230, 230, 230, 0, 41, 117, 230, 230, 230, 230, 0 },
|
||||
.powerMax = 30,
|
||||
|
@ -270,6 +288,7 @@ const LoRaWANBand_t AU915 = {
|
|||
};
|
||||
|
||||
const LoRaWANBand_t CN500 = {
|
||||
.bandNum = BandCN500,
|
||||
.bandType = RADIOLIB_LORAWAN_BAND_FIXED,
|
||||
.payloadLenMax = { 59, 59, 59, 123, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
.powerMax = 19,
|
||||
|
@ -329,6 +348,7 @@ const LoRaWANBand_t CN500 = {
|
|||
};
|
||||
|
||||
const LoRaWANBand_t AS923 = {
|
||||
.bandNum = BandAS923,
|
||||
.bandType = RADIOLIB_LORAWAN_BAND_DYNAMIC,
|
||||
.payloadLenMax = { 59, 59, 59, 123, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0 },
|
||||
.powerMax = 16,
|
||||
|
@ -374,6 +394,7 @@ const LoRaWANBand_t AS923 = {
|
|||
};
|
||||
|
||||
const LoRaWANBand_t KR920 = {
|
||||
.bandNum = BandKR920,
|
||||
.bandType = RADIOLIB_LORAWAN_BAND_DYNAMIC,
|
||||
.payloadLenMax = { 59, 59, 59, 123, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
.powerMax = 14,
|
||||
|
@ -419,6 +440,7 @@ const LoRaWANBand_t KR920 = {
|
|||
};
|
||||
|
||||
const LoRaWANBand_t IN865 = {
|
||||
.bandNum = BandIN865,
|
||||
.bandType = RADIOLIB_LORAWAN_BAND_DYNAMIC,
|
||||
.payloadLenMax = { 59, 59, 59, 123, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0 },
|
||||
.powerMax = 30,
|
||||
|
|
Loading…
Add table
Reference in a new issue