[LoRaWAN] Revamp internal processing, key checking, new MAC commands, implement DutyCycle & DwellTime
This commit is contained in:
parent
797b7a4323
commit
574555ca09
11 changed files with 1258 additions and 554 deletions
|
@ -24,11 +24,12 @@
|
|||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1278 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 9
|
||||
// DIO1 pin: 3
|
||||
// SX1262 has the following pin order:
|
||||
// Module(NSS/CS, DIO1, RESET, BUSY)
|
||||
// SX1262 radio = new Module(8, 14, 12, 13);
|
||||
|
||||
// SX1278 has the following pin order:
|
||||
// Module(NSS/CS, DIO0, RESET, DIO1)
|
||||
SX1278 radio = new Module(10, 2, 9, 3);
|
||||
|
||||
// create the node instance on the EU-868 band
|
||||
|
@ -85,6 +86,11 @@ void setup() {
|
|||
node.selectSubband(8, 15);
|
||||
*/
|
||||
|
||||
// on EEPROM-enabled boards, after the device has been activated,
|
||||
// the session can be restored without rejoining after device power cycle
|
||||
// this is intrinsically done when calling `beginOTAA()` with the same keys
|
||||
// in that case, the function will not need to transmit a JoinRequest
|
||||
|
||||
// now we can start the activation
|
||||
// this can take up to 10 seconds, and requires a LoRaWAN gateway in range
|
||||
// a specific starting-datarate can be selected in dynamic bands (e.g. EU868):
|
||||
|
@ -147,7 +153,11 @@ void loop() {
|
|||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
|
||||
|
||||
// wait before sending another packet
|
||||
delay(30000);
|
||||
uint32_t minimumDelay = 60000; // try to send once every minute
|
||||
uint32_t interval = node.timeUntilUplink(); // calculate minimum duty cycle delay (per law!)
|
||||
uint32_t delayMs = max(interval, minimumDelay); // cannot send faster than duty cycle allows
|
||||
|
||||
delay(delayMs);
|
||||
}
|
||||
|
|
|
@ -25,11 +25,12 @@
|
|||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1278 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 9
|
||||
// DIO1 pin: 3
|
||||
// SX1262 has the following pin order:
|
||||
// Module(NSS/CS, DIO1, RESET, BUSY)
|
||||
// SX1262 radio = new Module(8, 14, 12, 13);
|
||||
|
||||
// SX1278 has the following pin order:
|
||||
// Module(NSS/CS, DIO0, RESET, DIO1)
|
||||
SX1278 radio = new Module(10, 2, 9, 3);
|
||||
|
||||
// create the node instance on the EU-868 band
|
||||
|
@ -69,6 +70,14 @@ void setup() {
|
|||
uint8_t appSKey[] = { 0x61, 0x44, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65,
|
||||
0x6E, 0x74, 0x4B, 0x65, 0x79, 0x41, 0x42, 0x43 };
|
||||
|
||||
// network key 2 is the ASCII string "topSecretKey5678"
|
||||
uint8_t fNwkSIntKey[] = { 0x61, 0x44, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65,
|
||||
0x6E, 0x74, 0x4B, 0x65, 0x35, 0x36, 0x37, 0x38 };
|
||||
|
||||
// network key 3 is the ASCII string "aDifferentKeyDEF"
|
||||
uint8_t sNwkSIntKey[] = { 0x61, 0x44, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65,
|
||||
0x6E, 0x74, 0x4B, 0x65, 0x79, 0x44, 0x45, 0x46 };
|
||||
|
||||
// prior to LoRaWAN 1.1.0, only a single "nwkKey" is used
|
||||
// when connecting to LoRaWAN 1.0 network, "appKey" will be disregarded
|
||||
// and can be set to NULL
|
||||
|
@ -86,15 +95,20 @@ void setup() {
|
|||
node.rx2.drMax = 3;
|
||||
*/
|
||||
|
||||
// to start a LoRaWAN v1.1 session, the user should also provide
|
||||
// fNwkSIntKey and sNwkSIntKey similar to nwkSKey and appSKey
|
||||
// on EEPROM-enabled boards, after the device has been activated,
|
||||
// the session can be restored without rejoining after device power cycle
|
||||
// this is intrinsically done when calling `beginABP()` with the same keys
|
||||
// in that case, the function will not need to transmit a JoinRequest
|
||||
|
||||
// to start a LoRaWAN v1.0 session,
|
||||
// the user can remove the fNwkSIntKey and sNwkSIntKey
|
||||
/*
|
||||
state = node.beginABP(devAddr, nwkSKey, appSKey, fNwkSIntKey, sNwkSIntKey);
|
||||
state = node.beginABP(devAddr, nwkSKey, appSKey);
|
||||
*/
|
||||
|
||||
// start the device by directly providing the encryption keys and device address
|
||||
Serial.print(F("[LoRaWAN] Attempting over-the-air activation ... "));
|
||||
state = node.beginABP(devAddr, nwkSKey, appSKey);
|
||||
state = node.beginABP(devAddr, nwkSKey, appSKey, fNwkSIntKey, sNwkSIntKey);
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
|
@ -149,5 +163,9 @@ void loop() {
|
|||
}
|
||||
|
||||
// wait before sending another packet
|
||||
delay(30000);
|
||||
uint32_t minimumDelay = 60000; // try to send once every minute
|
||||
uint32_t interval = node.timeUntilUplink(); // calculate minimum duty cycle delay (per law!)
|
||||
uint32_t delayMs = max(interval, minimumDelay); // cannot send faster than duty cycle allows
|
||||
|
||||
delay(delayMs);
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
NOTE: LoRaWAN requires storing some parameters persistently!
|
||||
RadioLib does this by using EEPROM, by default
|
||||
starting at address 0 and using 384 bytes.
|
||||
starting at address 0 and using 448 bytes.
|
||||
If you already use EEPROM in your application,
|
||||
you will have to either avoid this range, or change it
|
||||
by setting a different start address by changing the value of
|
||||
|
@ -29,11 +29,12 @@
|
|||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1278 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 9
|
||||
// DIO1 pin: 3
|
||||
// SX1262 has the following pin order:
|
||||
// Module(NSS/CS, DIO1, RESET, BUSY)
|
||||
// SX1262 radio = new Module(8, 14, 12, 13);
|
||||
|
||||
// SX1278 has the following pin order:
|
||||
// Module(NSS/CS, DIO0, RESET, DIO1)
|
||||
SX1278 radio = new Module(10, 2, 9, 3);
|
||||
|
||||
// create the node instance on the EU-868 band
|
||||
|
@ -56,33 +57,31 @@ void setup() {
|
|||
while(true);
|
||||
}
|
||||
|
||||
// first we need to initialize the device storage
|
||||
// this will reset all persistently stored parameters
|
||||
// NOTE: This should only be done once prior to first joining a network!
|
||||
// After wiping persistent storage, you will also have to reset
|
||||
// the end device in TTN and perform the join procedure again!
|
||||
// Here, a delay is added to make sure that during re-flashing
|
||||
// the .wipe() is not triggered and the session is lost
|
||||
//delay(5000);
|
||||
//node.wipe();
|
||||
|
||||
// now we can start the activation
|
||||
// start the activation
|
||||
// Serial.print(F("[LoRaWAN] Attempting over-the-air activation ... "));
|
||||
// uint64_t joinEUI = 0x12AD1011B0C0FFEE;
|
||||
// uint64_t devEUI = 0x70B3D57ED005E120;
|
||||
// uint64_t devEUI = 0x70B3D57ED005E120;
|
||||
// uint8_t nwkKey[] = { 0x74, 0x6F, 0x70, 0x53, 0x65, 0x63, 0x72, 0x65,
|
||||
// 0x74, 0x4B, 0x65, 0x79, 0x31, 0x32, 0x33, 0x34 };
|
||||
// uint8_t appKey[] = { 0x61, 0x44, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65,
|
||||
// 0x6E, 0x74, 0x4B, 0x65, 0x79, 0x41, 0x42, 0x43 };
|
||||
// state = node.beginOTAA(joinEUI, devEUI, nwkKey, appKey);
|
||||
|
||||
// after the device has been activated,
|
||||
// on EEPROM-enabled boards, after the device has been activated,
|
||||
// the session can be restored without rejoining after device power cycle
|
||||
// on EEPROM-enabled boards by calling "restore"
|
||||
// by calling the same `beginOTAA()` or `beginABP()` function with the same keys
|
||||
// or call `restore()` where it will restore any existing session
|
||||
// `restore()` returns the active mode if it succeeded (OTAA or ABP)
|
||||
Serial.print(F("[LoRaWAN] Resuming previous session ... "));
|
||||
state = node.restore();
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
if(state >= RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
Serial.print(F("Restored an "));
|
||||
if(state == RADIOLIB_LORAWAN_MODE_OTAA)
|
||||
Serial.println(F("OTAA session."));
|
||||
else {
|
||||
Serial.println(F("ABP session."));
|
||||
}
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
|
@ -141,5 +140,9 @@ void loop() {
|
|||
// wait before sending another packet
|
||||
// alternatively, call a deepsleep function here
|
||||
// make sure to send the radio to sleep as well using radio.sleep()
|
||||
delay(30000);
|
||||
uint32_t minimumDelay = 60000; // try to send once every minute
|
||||
uint32_t interval = node.timeUntilUplink(); // calculate minimum duty cycle delay (per law!)
|
||||
uint32_t delayMs = max(interval, minimumDelay); // cannot send faster than duty cycle allows
|
||||
|
||||
delay(delayMs);
|
||||
}
|
||||
|
|
|
@ -27,11 +27,12 @@
|
|||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1278 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 9
|
||||
// DIO1 pin: 3
|
||||
// SX1262 has the following pin order:
|
||||
// Module(NSS/CS, DIO1, RESET, BUSY)
|
||||
// SX1262 radio = new Module(8, 14, 12, 13);
|
||||
|
||||
// SX1278 has the following pin order:
|
||||
// Module(NSS/CS, DIO0, RESET, DIO1)
|
||||
SX1278 radio = new Module(10, 2, 9, 3);
|
||||
|
||||
// create the node instance on the EU-868 band
|
||||
|
@ -106,9 +107,11 @@ void setup() {
|
|||
while(true);
|
||||
}
|
||||
|
||||
// after the device has been activated,
|
||||
// on EEPROM-enabled boards, after the device has been activated,
|
||||
// the session can be restored without rejoining after device power cycle
|
||||
// on EEPROM-enabled boards by calling "restore"
|
||||
// this is intrinsically done when calling `beginOTAA()` with the same keys
|
||||
// or if you 'lost' the keys or don't want them included in your sketch
|
||||
// you can call `restore()`
|
||||
/*
|
||||
Serial.print(F("[LoRaWAN] Resuming previous session ... "));
|
||||
state = node.restore();
|
||||
|
@ -131,6 +134,19 @@ void setup() {
|
|||
// this tries to minimize packet loss by searching for a free channel
|
||||
// before actually sending an uplink
|
||||
node.setCSMA(6, 2, true);
|
||||
|
||||
// enable or disable the dutycycle
|
||||
// the second argument specific allowed airtime per hour in milliseconds
|
||||
// 1250 = TTN FUP (30 seconds / 24 hours)
|
||||
// if not called, this corresponds to setDutyCycle(true, 0)
|
||||
// setting this to 0 corresponds to the band's maximum allowed dutycycle by law
|
||||
node.setDutyCycle(true, 1250);
|
||||
|
||||
// enable or disable the dwell time limits
|
||||
// the second argument specific allowed airtime per uplink in milliseconds
|
||||
// if not called, this corresponds to setDwellTime(true, 0)
|
||||
// setting this to 0 corresponds to the band's maximum allowed dwell time by law
|
||||
node.setDwellTime(true, 1000);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
@ -152,8 +168,11 @@ void loop() {
|
|||
String strUp = "Hello World! #" + String(fcntUp);
|
||||
|
||||
// send a confirmed uplink to port 10 every 64th frame
|
||||
// and also request the LinkCheck and DeviceTime MAC commands
|
||||
if(fcntUp % 64 == 0) {
|
||||
state = node.uplink(strUp, 10, true);
|
||||
node.sendMacCommandReq(RADIOLIB_LORAWAN_MAC_LINK_CHECK);
|
||||
node.sendMacCommandReq(RADIOLIB_LORAWAN_MAC_DEVICE_TIME);
|
||||
} else {
|
||||
state = node.uplink(strUp, 10);
|
||||
}
|
||||
|
@ -228,6 +247,24 @@ void loop() {
|
|||
Serial.println(event.port);
|
||||
|
||||
Serial.print(radio.getFrequencyError());
|
||||
|
||||
uint8_t margin = 0;
|
||||
uint8_t gwCnt = 0;
|
||||
if(node.getMacLinkCheckAns(&margin, &gwCnt)) {
|
||||
Serial.print(F("[LoRaWAN] LinkCheck margin:\t"));
|
||||
Serial.println(margin);
|
||||
Serial.print(F("[LoRaWAN] LinkCheck count:\t"));
|
||||
Serial.println(gwCnt);
|
||||
}
|
||||
|
||||
uint32_t networkTime = 0;
|
||||
uint8_t fracSecond = 0;
|
||||
if(node.getMacDeviceTimeAns(&networkTime, &fracSecond, true)) {
|
||||
Serial.print(F("[LoRaWAN] DeviceTime Unix:\t"));
|
||||
Serial.println(networkTime);
|
||||
Serial.print(F("[LoRaWAN] LinkCheck second:\t1/"));
|
||||
Serial.println(fracSecond);
|
||||
}
|
||||
|
||||
} else if(state == RADIOLIB_ERR_RX_TIMEOUT) {
|
||||
Serial.println(F("timeout!"));
|
||||
|
@ -244,5 +281,9 @@ void loop() {
|
|||
*/
|
||||
|
||||
// wait before sending another packet
|
||||
delay(30000);
|
||||
uint32_t minimumDelay = 60000; // try to send once every minute
|
||||
uint32_t interval = node.timeUntilUplink(); // calculate minimum duty cycle delay (per law!)
|
||||
uint32_t delayMs = max(interval, minimumDelay); // cannot send faster than duty cycle allows
|
||||
|
||||
delay(delayMs);
|
||||
}
|
||||
|
|
|
@ -295,6 +295,7 @@ restore KEYWORD2
|
|||
beginOTAA KEYWORD2
|
||||
beginABP KEYWORD2
|
||||
saveSession KEYWORD2
|
||||
sendMacCommandReq KEYWORD2
|
||||
uplink KEYWORD2
|
||||
downlink KEYWORD2
|
||||
sendReceive KEYWORD2
|
||||
|
@ -302,11 +303,19 @@ setDeviceStatus KEYWORD2
|
|||
getFcntUp KEYWORD2
|
||||
getNFcntDown KEYWORD2
|
||||
getAFcntDown KEYWORD2
|
||||
resetFcntDown KEYWORD2
|
||||
setDatarate KEYWORD2
|
||||
setADR KEYWORD2
|
||||
setDutyCycle KEYWORD2
|
||||
dutyCycleInterval KEYWORD2
|
||||
timeUntilUplink KEYWORD2
|
||||
setDwellTime KEYWORD2
|
||||
maxPayloadDwellTime KEYWORD2
|
||||
setTxPower KEYWORD2
|
||||
selectSubband KEYWORD2
|
||||
setCSMA KEYWORD2
|
||||
getMacLinkCheckAns KEYWORD2
|
||||
getMacDeviceTimeAns KEYWORD2
|
||||
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
||||
|
|
|
@ -112,7 +112,7 @@
|
|||
|
||||
// the amount of space allocated to the persistent storage
|
||||
#if !defined(RADIOLIB_HAL_PERSISTENT_STORAGE_SIZE)
|
||||
#define RADIOLIB_HAL_PERSISTENT_STORAGE_SIZE (0x0180)
|
||||
#define RADIOLIB_HAL_PERSISTENT_STORAGE_SIZE (0x01C0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
128
src/Hal.h
128
src/Hal.h
|
@ -6,60 +6,86 @@
|
|||
|
||||
#include "BuildOpt.h"
|
||||
|
||||
#define RADIOLIB_EEPROM_TABLE_VERSION (0x0002)
|
||||
|
||||
// list of persistent parameters
|
||||
#define RADIOLIB_PERSISTENT_PARAM_LORAWAN_TABLE_VERSION_ID (0) // this is NOT the LoRaWAN version, but version of this table
|
||||
#define RADIOLIB_PERSISTENT_PARAM_LORAWAN_MAGIC_ID (1)
|
||||
#define RADIOLIB_PERSISTENT_PARAM_LORAWAN_VERSION_ID (2)
|
||||
#define RADIOLIB_PERSISTENT_PARAM_LORAWAN_TXDR_RX2DR_ID (3)
|
||||
#define RADIOLIB_PERSISTENT_PARAM_LORAWAN_TXPWR_CUR_ID (4)
|
||||
#define RADIOLIB_PERSISTENT_PARAM_LORAWAN_RX1_DROFF_DEL_ID (5)
|
||||
#define RADIOLIB_PERSISTENT_PARAM_LORAWAN_RX2FREQ_ID (6)
|
||||
#define RADIOLIB_PERSISTENT_PARAM_LORAWAN_ADR_LIM_DEL_ID (7)
|
||||
#define RADIOLIB_PERSISTENT_PARAM_LORAWAN_NBTRANS_ID (8)
|
||||
#define RADIOLIB_PERSISTENT_PARAM_LORAWAN_DEV_ADDR_ID (9)
|
||||
#define RADIOLIB_PERSISTENT_PARAM_LORAWAN_APP_S_KEY_ID (10)
|
||||
#define RADIOLIB_PERSISTENT_PARAM_LORAWAN_FNWK_SINT_KEY_ID (11)
|
||||
#define RADIOLIB_PERSISTENT_PARAM_LORAWAN_SNWK_SINT_KEY_ID (12)
|
||||
#define RADIOLIB_PERSISTENT_PARAM_LORAWAN_NWK_SENC_KEY_ID (13)
|
||||
#define RADIOLIB_PERSISTENT_PARAM_LORAWAN_HOME_NET_ID (14)
|
||||
#define RADIOLIB_PERSISTENT_PARAM_LORAWAN_DEV_NONCE_ID (15)
|
||||
#define RADIOLIB_PERSISTENT_PARAM_LORAWAN_JOIN_NONCE_ID (16)
|
||||
#define RADIOLIB_PERSISTENT_PARAM_LORAWAN_A_FCNT_DOWN_ID (17)
|
||||
#define RADIOLIB_PERSISTENT_PARAM_LORAWAN_N_FCNT_DOWN_ID (18)
|
||||
#define RADIOLIB_PERSISTENT_PARAM_LORAWAN_CONF_FCNT_UP_ID (19)
|
||||
#define RADIOLIB_PERSISTENT_PARAM_LORAWAN_CONF_FCNT_DOWN_ID (20)
|
||||
#define RADIOLIB_PERSISTENT_PARAM_LORAWAN_ADR_FCNT_ID (21)
|
||||
#define RADIOLIB_PERSISTENT_PARAM_LORAWAN_FCNT_UP_ID (22)
|
||||
#define RADIOLIB_PERSISTENT_PARAM_LORAWAN_FOPTS_ID (23)
|
||||
#define RADIOLIB_PERSISTENT_PARAM_LORAWAN_FREQS_ID (24)
|
||||
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_PERSISTENT_PARAM_LORAWAN_TABLE_VERSION_ID
|
||||
0x01, // RADIOLIB_PERSISTENT_PARAM_LORAWAN_MAGIC_ID
|
||||
0x03, // RADIOLIB_PERSISTENT_PARAM_LORAWAN_VERSION
|
||||
0x04, // RADIOLIB_PERSISTENT_PARAM_LORAWAN_TXDR_RX2DR_ID
|
||||
0x05, // RADIOLIB_PERSISTENT_PARAM_LORAWAN_TXPWR_CUR_ID
|
||||
0x06, // RADIOLIB_PERSISTENT_PARAM_LORAWAN_RX1_DROFF_DEL_ID
|
||||
0x07, // RADIOLIB_PERSISTENT_PARAM_LORAWAN_RX2FREQ_ID
|
||||
0x0A, // RADIOLIB_PERSISTENT_PARAM_LORAWAN_ADR_LIM_DEL_ID
|
||||
0x0B, // RADIOLIB_PERSISTENT_PARAM_LORAWAN_NBTRANS_ID
|
||||
0x0C, // RADIOLIB_PERSISTENT_PARAM_LORAWAN_DEV_ADDR_ID
|
||||
0x10, // RADIOLIB_PERSISTENT_PARAM_LORAWAN_APP_S_KEY_ID
|
||||
0x20, // RADIOLIB_PERSISTENT_PARAM_LORAWAN_FNWK_SINT_KEY_ID
|
||||
0x30, // RADIOLIB_PERSISTENT_PARAM_LORAWAN_SNWK_SINT_KEY_ID
|
||||
0x40, // RADIOLIB_PERSISTENT_PARAM_LORAWAN_NWK_SENC_KEY_ID
|
||||
0x50, // RADIOLIB_PERSISTENT_PARAM_LORAWAN_HOME_NET_ID
|
||||
0x54, // RADIOLIB_PERSISTENT_PARAM_LORAWAN_DEV_NONCE_ID
|
||||
0x58, // RADIOLIB_PERSISTENT_PARAM_LORAWAN_JOIN_NONCE_ID
|
||||
0x5C, // RADIOLIB_PERSISTENT_PARAM_LORAWAN_A_FCNT_DOWN_ID
|
||||
0x60, // RADIOLIB_PERSISTENT_PARAM_LORAWAN_N_FCNT_DOWN_ID
|
||||
0x64, // RADIOLIB_PERSISTENT_PARAM_LORAWAN_CONF_FCNT_UP_ID
|
||||
0x68, // RADIOLIB_PERSISTENT_PARAM_LORAWAN_CONF_FCNT_DOWN_ID
|
||||
0x6C, // RADIOLIB_PERSISTENT_PARAM_LORAWAN_ADR_FCNT_ID
|
||||
0x70, // RADIOLIB_PERSISTENT_PARAM_LORAWAN_FCNT_UP_ID
|
||||
0x8E, // RADIOLIB_PERSISTENT_PARAM_LORAWAN_FOPTS_ID
|
||||
0xD0, // RADIOLIB_PERSISTENT_PARAM_LORAWAN_FREQS_ID
|
||||
0x0180, // end
|
||||
0x00, // RADIOLIB_EEPROM_LORAWAN_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 - NOTE change upon ADR Ack Req
|
||||
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
|
||||
};
|
||||
|
||||
/*!
|
||||
|
|
|
@ -519,7 +519,7 @@
|
|||
#define RADIOLIB_ERR_INVALID_CID (-1107)
|
||||
|
||||
/*!
|
||||
\brief User requested to start uplink while still inside RX window.
|
||||
\brief User requested to start uplink while still inside RX window or under dutycycle.
|
||||
*/
|
||||
#define RADIOLIB_ERR_UPLINK_UNAVAILABLE (-1108)
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -5,8 +5,15 @@
|
|||
#include "../PhysicalLayer/PhysicalLayer.h"
|
||||
#include "../../utils/Cryptography.h"
|
||||
|
||||
// version of NVM table layout (NOT the LoRaWAN version)
|
||||
#define RADIOLIB_PERSISTENT_PARAM_LORAWAN_TABLE_VERSION (0x01)
|
||||
// activation mode
|
||||
#define RADIOLIB_LORAWAN_MODE_OTAA (0x01AA)
|
||||
#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)
|
||||
|
||||
// preamble format
|
||||
#define RADIOLIB_LORAWAN_LORA_SYNC_WORD (0x34)
|
||||
|
@ -77,7 +84,6 @@
|
|||
// recommended default settings
|
||||
#define RADIOLIB_LORAWAN_RECEIVE_DELAY_1_MS (1000)
|
||||
#define RADIOLIB_LORAWAN_RECEIVE_DELAY_2_MS ((RADIOLIB_LORAWAN_RECEIVE_DELAY_1_MS) + 1000)
|
||||
#define RADIOLIB_LORAWAN_RX_WINDOW_LEN_MS (500)
|
||||
#define RADIOLIB_LORAWAN_RX1_DR_OFFSET (0)
|
||||
#define RADIOLIB_LORAWAN_JOIN_ACCEPT_DELAY_1_MS (5000)
|
||||
#define RADIOLIB_LORAWAN_JOIN_ACCEPT_DELAY_2_MS (6000)
|
||||
|
@ -87,6 +93,8 @@
|
|||
#define RADIOLIB_LORAWAN_RETRANSMIT_TIMEOUT_MIN_MS (1000)
|
||||
#define RADIOLIB_LORAWAN_RETRANSMIT_TIMEOUT_MAX_MS (3000)
|
||||
#define RADIOLIB_LORAWAN_POWER_STEP_SIZE_DBM (-2)
|
||||
#define RADIOLIB_LORAWAN_REJOIN_MAX_COUNT_N (10) // send rejoin request 16384 uplinks
|
||||
#define RADIOLIB_LORAWAN_REJOIN_MAX_TIME_N (15) // once every year, not actually implemented
|
||||
|
||||
// join request message layout
|
||||
#define RADIOLIB_LORAWAN_JOIN_REQUEST_LEN (23)
|
||||
|
@ -155,32 +163,61 @@
|
|||
#define RADIOLIB_LORAWAN_MAGIC (0x39EA)
|
||||
|
||||
// MAC commands
|
||||
#define RADIOLIB_LORAWAN_MAC_CMD_RESET (0x01)
|
||||
#define RADIOLIB_LORAWAN_MAC_CMD_LINK_CHECK (0x02)
|
||||
#define RADIOLIB_LORAWAN_MAC_CMD_LINK_ADR (0x03)
|
||||
#define RADIOLIB_LORAWAN_MAC_CMD_DUTY_CYCLE (0x04)
|
||||
#define RADIOLIB_LORAWAN_MAC_CMD_RX_PARAM_SETUP (0x05)
|
||||
#define RADIOLIB_LORAWAN_MAC_CMD_DEV_STATUS (0x06)
|
||||
#define RADIOLIB_LORAWAN_MAC_CMD_NEW_CHANNEL (0x07)
|
||||
#define RADIOLIB_LORAWAN_MAC_CMD_RX_TIMING_SETUP (0x08)
|
||||
#define RADIOLIB_LORAWAN_MAC_CMD_TX_PARAM_SETUP (0x09)
|
||||
#define RADIOLIB_LORAWAN_MAC_CMD_DL_CHANNEL (0x0A)
|
||||
#define RADIOLIB_LORAWAN_MAC_CMD_REKEY (0x0B)
|
||||
#define RADIOLIB_LORAWAN_MAC_CMD_ADR_PARAM_SETUP (0x0C)
|
||||
#define RADIOLIB_LORAWAN_MAC_CMD_DEVICE_TIME (0x0D)
|
||||
#define RADIOLIB_LORAWAN_MAC_CMD_FORCE_REJOIN (0x0E)
|
||||
#define RADIOLIB_LORAWAN_MAC_CMD_REJOIN_PARAM_SETUP (0x0F)
|
||||
#define RADIOLIB_LORAWAN_MAC_CMD_PROPRIETARY (0x80)
|
||||
#define RADIOLIB_LORAWAN_NUM_MAC_COMMANDS (16)
|
||||
|
||||
#define RADIOLIB_LORAWAN_MAC_RESET (0x01)
|
||||
#define RADIOLIB_LORAWAN_MAC_LINK_CHECK (0x02)
|
||||
#define RADIOLIB_LORAWAN_MAC_LINK_ADR (0x03)
|
||||
#define RADIOLIB_LORAWAN_MAC_DUTY_CYCLE (0x04)
|
||||
#define RADIOLIB_LORAWAN_MAC_RX_PARAM_SETUP (0x05)
|
||||
#define RADIOLIB_LORAWAN_MAC_DEV_STATUS (0x06)
|
||||
#define RADIOLIB_LORAWAN_MAC_NEW_CHANNEL (0x07)
|
||||
#define RADIOLIB_LORAWAN_MAC_RX_TIMING_SETUP (0x08)
|
||||
#define RADIOLIB_LORAWAN_MAC_TX_PARAM_SETUP (0x09)
|
||||
#define RADIOLIB_LORAWAN_MAC_DL_CHANNEL (0x0A)
|
||||
#define RADIOLIB_LORAWAN_MAC_REKEY (0x0B)
|
||||
#define RADIOLIB_LORAWAN_MAC_ADR_PARAM_SETUP (0x0C)
|
||||
#define RADIOLIB_LORAWAN_MAC_DEVICE_TIME (0x0D)
|
||||
#define RADIOLIB_LORAWAN_MAC_FORCE_REJOIN (0x0E)
|
||||
#define RADIOLIB_LORAWAN_MAC_REJOIN_PARAM_SETUP (0x0F)
|
||||
#define RADIOLIB_LORAWAN_MAC_PROPRIETARY (0x80)
|
||||
|
||||
// unused frame counter value
|
||||
#define RADIOLIB_LORAWAN_FCNT_NONE (0xFFFFFFFF)
|
||||
|
||||
// the length of internal MAC command queue - hopefully this is enough for most use cases
|
||||
#define RADIOLIB_LORAWAN_MAC_COMMAND_QUEUE_SIZE (8)
|
||||
#define RADIOLIB_LORAWAN_MAC_COMMAND_QUEUE_SIZE (9)
|
||||
|
||||
// the maximum number of simultaneously available channels
|
||||
#define RADIOLIB_LORAWAN_NUM_AVAILABLE_CHANNELS (16)
|
||||
|
||||
struct LoRaWANMacSpec_t {
|
||||
const uint8_t cid;
|
||||
const uint8_t lenDn;
|
||||
const uint8_t lenUp;
|
||||
const bool user; // whether this MAC command can be issued by a user or not
|
||||
};
|
||||
|
||||
const LoRaWANMacSpec_t MacTable[RADIOLIB_LORAWAN_NUM_MAC_COMMANDS + 1] = {
|
||||
{ 0x00, 0, 0, false }, // not an actual MAC command, exists for offsetting
|
||||
{ 0x01, 1, 1, false }, // RADIOLIB_LORAWAN_MAC_RESET
|
||||
{ 0x02, 2, 0, true }, // RADIOLIB_LORAWAN_MAC_LINK_CHECK
|
||||
{ 0x03, 4, 1, false }, // RADIOLIB_LORAWAN_MAC_LINK_ADR
|
||||
{ 0x04, 1, 0, false }, // RADIOLIB_LORAWAN_MAC_DUTY_CYCLE
|
||||
{ 0x05, 4, 1, false }, // RADIOLIB_LORAWAN_MAC_RX_PARAM_SETUP
|
||||
{ 0x06, 0, 2, false }, // RADIOLIB_LORAWAN_MAC_DEV_STATUS
|
||||
{ 0x07, 5, 1, false }, // RADIOLIB_LORAWAN_MAC_NEW_CHANNEL
|
||||
{ 0x08, 1, 0, false }, // RADIOLIB_LORAWAN_MAC_RX_TIMING_SETUP
|
||||
{ 0x09, 1, 0, false }, // RADIOLIB_LORAWAN_MAC_TX_PARAM_SETUP
|
||||
{ 0x0A, 4, 1, false }, // RADIOLIB_LORAWAN_MAC_DL_CHANNEL
|
||||
{ 0x0B, 1, 1, false }, // RADIOLIB_LORAWAN_MAC_REKEY
|
||||
{ 0x0C, 1, 0, false }, // RADIOLIB_LORAWAN_MAC_ADR_PARAM_SETUP
|
||||
{ 0x0D, 5, 0, true }, // RADIOLIB_LORAWAN_MAC_DEVICE_TIME
|
||||
{ 0x0E, 2, 0, false }, // RADIOLIB_LORAWAN_MAC_FORCE_REJOIN
|
||||
{ 0x0F, 1, 1, false }, // RADIOLIB_LORAWAN_MAC_REJOIN_PARAM_SETUP
|
||||
{ 0x80, 5, 0, true } // RADIOLIB_LORAWAN_MAC_PROPRIETARY
|
||||
};
|
||||
|
||||
/*!
|
||||
\struct LoRaWANChannelSpan_t
|
||||
\brief Structure to save information about LoRaWAN channels.
|
||||
|
@ -251,6 +288,13 @@ struct LoRaWANBand_t {
|
|||
/*! \brief Number of power steps in this band */
|
||||
int8_t powerNumSteps;
|
||||
|
||||
/*! \brief Number of milliseconds per hour of allowed Time-on-Air */
|
||||
uint32_t dutyCycle;
|
||||
|
||||
/*! \brief Maximum dwell time per message in milliseconds */
|
||||
uint32_t dwellTimeUp;
|
||||
uint32_t dwellTimeDn;
|
||||
|
||||
/*! \brief A set of default uplink (TX) channels for frequency-type bands */
|
||||
LoRaWANChannel_t txFreqs[3];
|
||||
|
||||
|
@ -371,7 +415,8 @@ class LoRaWANNode {
|
|||
|
||||
/*!
|
||||
\brief Restore session by loading information from persistent storage.
|
||||
\returns \ref status_codes
|
||||
\returns \ref status_codes in case of error,
|
||||
else LoRaWAN session mode (0 = no active session, 0xAA / 170 = OTAA, 0xAB / 171 = ABP)
|
||||
*/
|
||||
int16_t restore();
|
||||
#endif
|
||||
|
@ -413,6 +458,15 @@ class LoRaWANNode {
|
|||
*/
|
||||
int16_t saveSession();
|
||||
|
||||
/*!
|
||||
\brief Add a MAC command to the uplink queue.
|
||||
Only LinkCheck and DeviceTime are available to the user.
|
||||
Other commands are ignored; duplicate MAC commands are discarded.
|
||||
\param cid ID of the MAC command
|
||||
\returns Whether or not the MAC command was added to the queue.
|
||||
*/
|
||||
bool sendMacCommandReq(uint8_t cid);
|
||||
|
||||
#if defined(RADIOLIB_BUILD_ARDUINO)
|
||||
/*!
|
||||
\brief Send a message to the server.
|
||||
|
@ -533,6 +587,12 @@ class LoRaWANNode {
|
|||
/*! \brief Returns the last application downlink's frame counter */
|
||||
uint32_t getAFcntDown();
|
||||
|
||||
/*! \brief Reset the downlink frame counters (application and network)
|
||||
This is unsafe and can possibly allow replay attacks using downlinks.
|
||||
It mainly exists as part of the TS008 Specification Verification protocol.
|
||||
*/
|
||||
void resetFcntDown();
|
||||
|
||||
/*!
|
||||
\brief Set uplink datarate. This should not be used when ADR is enabled.
|
||||
\param dr Datarate to use for uplinks.
|
||||
|
@ -546,6 +606,41 @@ class LoRaWANNode {
|
|||
*/
|
||||
void setADR(bool enable = true);
|
||||
|
||||
/*!
|
||||
\brief Toggle adherence to dutyCycle limits to on or off.
|
||||
\param enable Whether to adhere to dutyCycle limits or not (default true).
|
||||
\param msPerHour The maximum allowed Time-on-Air per hour in milliseconds
|
||||
(default 0 = maximum allowed for configured band).
|
||||
*/
|
||||
void setDutyCycle(bool enable = true, uint32_t msPerHour = 0);
|
||||
|
||||
/*!
|
||||
\brief Calculate the minimum interval to adhere to a certain dutyCycle.
|
||||
This interval is based on the ToA of one uplink and does not actually keep track of total airtime.
|
||||
\param msPerHour The maximum allowed dutycyle (in milliseconds per hour).
|
||||
\param airtime The airtime of the uplink.
|
||||
\returns Required interval (delay) in milliseconds between consecutive uplinks.
|
||||
*/
|
||||
uint32_t dutyCycleInterval(uint32_t msPerHour, uint32_t airtime);
|
||||
|
||||
/*! \brief Returns time in milliseconds until next uplink is available under dutyCycle limits */
|
||||
uint32_t timeUntilUplink();
|
||||
|
||||
/*!
|
||||
\brief Toggle adherence to dwellTime limits to on or off.
|
||||
\param enable Whether to adhere to dwellTime limits or not (default true).
|
||||
\param msPerHour The maximum allowed Time-on-Air per uplink in milliseconds
|
||||
(default 0 = maximum allowed for configured band).
|
||||
*/
|
||||
void setDwellTime(bool enable, uint32_t msPerUplink = 0);
|
||||
|
||||
/*!
|
||||
\brief Returns the maximum payload given the currently present dwelltime limits.
|
||||
WARNING: the addition of MAC commands may cause uplink errors;
|
||||
if you want to be sure that your payload fits within dwelltime limits, subtract 16 from the result!
|
||||
*/
|
||||
uint8_t maxPayloadDwellTime();
|
||||
|
||||
/*!
|
||||
\brief Configure TX power of the radio module.
|
||||
\param txPower Output power during TX mode to be set in dBm.
|
||||
|
@ -578,12 +673,35 @@ class LoRaWANNode {
|
|||
*/
|
||||
void setCSMA(uint8_t backoffMax, uint8_t difsSlots, bool enableCSMA = false);
|
||||
|
||||
/*!
|
||||
\brief Returns the quality of connectivity after requesting a LinkCheck MAC command.
|
||||
Returns 'true' if a network response was succesfully parsed.
|
||||
Returns 'false' if there was no network response / parsing failed.
|
||||
\param margin Link margin in dB of LinkCheckReq demodulation at gateway side.
|
||||
\param gwCnt Number of gateways that received the LinkCheckReq.
|
||||
\returns Whether the parameters where succesfully parsed.
|
||||
*/
|
||||
bool getMacLinkCheckAns(uint8_t* margin, uint8_t* gwCnt);
|
||||
|
||||
/*!
|
||||
\brief Returns the network time after requesting a DeviceTime MAC command.
|
||||
Returns 'true' if a network response was succesfully parsed.
|
||||
Returns 'false' if there was no network response / parsing failed.
|
||||
\param gpsEpoch Number of seconds since GPS epoch (Jan. 6th 1980)
|
||||
\param fraction Fractional-second, in 1/256-second steps
|
||||
\param returnUnix If true, returns Unix timestamp instead of GPS (default true)
|
||||
\returns Whether the parameters where succesfully parsed.
|
||||
*/
|
||||
bool getMacDeviceTimeAns(uint32_t* gpsEpoch, uint8_t* fraction, bool returnUnix = true);
|
||||
|
||||
#if !RADIOLIB_GODMODE
|
||||
private:
|
||||
#endif
|
||||
PhysicalLayer* phyLayer = NULL;
|
||||
const LoRaWANBand_t* band = NULL;
|
||||
|
||||
void beginCommon();
|
||||
|
||||
LoRaWANMacCommandQueue_t commandsUp = {
|
||||
.numCommands = 0,
|
||||
.len = 0,
|
||||
|
@ -613,7 +731,8 @@ class LoRaWANNode {
|
|||
uint8_t adrLimitExp = RADIOLIB_LORAWAN_ADR_ACK_LIMIT_EXP;
|
||||
uint8_t adrDelayExp = RADIOLIB_LORAWAN_ADR_ACK_DELAY_EXP;
|
||||
uint8_t nbTrans = 1; // Number of allowed frame retransmissions
|
||||
uint8_t txPwrCur = 0;
|
||||
uint8_t txPowerCur = 0;
|
||||
uint8_t txPowerMax = 0;
|
||||
uint32_t fcntUp = 0;
|
||||
uint32_t aFcntDown = 0;
|
||||
uint32_t nFcntDown = 0;
|
||||
|
@ -624,11 +743,21 @@ class LoRaWANNode {
|
|||
// whether the current configured channel is in FSK mode
|
||||
bool FSK = false;
|
||||
|
||||
// flag that shows whether the device is joined and there is an ongoing session
|
||||
bool isJoinedFlag = false;
|
||||
// flag that shows whether the device is joined and there is an ongoing session (none, ABP or OTAA)
|
||||
uint16_t activeMode = 0;
|
||||
|
||||
// ADR is enabled by default
|
||||
bool adrEnabled = true;
|
||||
|
||||
// duty cycle is set upon initialization and activated in regions that impose this
|
||||
bool dutyCycleEnabled = false;
|
||||
uint32_t dutyCycle = 0;
|
||||
|
||||
// dwell time is set upon initialization and activated in regions that impose this
|
||||
bool dwellTimeEnabledUp = false;
|
||||
uint16_t dwellTimeUp = 0;
|
||||
bool dwellTimeEnabledDn = false;
|
||||
uint16_t dwellTimeDn = 0;
|
||||
|
||||
// enable/disable CSMA for LoRaWAN
|
||||
bool enableCSMA;
|
||||
|
@ -653,6 +782,9 @@ class LoRaWANNode {
|
|||
// LoRaWAN revision (1.0 vs 1.1)
|
||||
uint8_t rev = 0;
|
||||
|
||||
// Time on Air of last uplink
|
||||
uint32_t lastToA = 0;
|
||||
|
||||
// timestamp to measure the RX1/2 delay (from uplink end)
|
||||
uint32_t rxDelayStart = 0;
|
||||
|
||||
|
@ -714,9 +846,6 @@ class LoRaWANNode {
|
|||
// configure channel based on cached data rate ID and frequency
|
||||
int16_t configureChannel(uint8_t dir);
|
||||
|
||||
// save all available channels to persistent storage
|
||||
int16_t saveChannels();
|
||||
|
||||
// restore all available channels from persistent storage
|
||||
int16_t restoreChannels();
|
||||
|
||||
|
@ -724,10 +853,14 @@ class LoRaWANNode {
|
|||
int16_t pushMacCommand(LoRaWANMacCommand_t* cmd, LoRaWANMacCommandQueue_t* queue);
|
||||
|
||||
// delete a specific MAC command from queue, indicated by the command ID
|
||||
int16_t deleteMacCommand(uint8_t cid, LoRaWANMacCommandQueue_t* queue);
|
||||
// if a payload pointer is supplied, this returns the payload of the MAC command
|
||||
int16_t deleteMacCommand(uint8_t cid, LoRaWANMacCommandQueue_t* queue, uint8_t payload[5] = NULL);
|
||||
|
||||
// execute mac command, return the number of processed bytes for sequential processing
|
||||
size_t execMacCommand(LoRaWANMacCommand_t* cmd);
|
||||
bool execMacCommand(LoRaWANMacCommand_t* cmd, bool saveToEeprom = true);
|
||||
|
||||
// get the payload length for a specific MAC command
|
||||
uint8_t getMacPayloadLength(uint8_t cid);
|
||||
|
||||
// Performs CSMA as per LoRa Alliance Technical Reccomendation 13 (TR-013).
|
||||
void performCSMA();
|
||||
|
|
|
@ -7,6 +7,9 @@ const LoRaWANBand_t EU868 = {
|
|||
.payloadLenMax = { 59, 59, 59, 123, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0 },
|
||||
.powerMax = 16,
|
||||
.powerNumSteps = 7,
|
||||
.dutyCycle = 36000,
|
||||
.dwellTimeUp = 0,
|
||||
.dwellTimeDn = 0,
|
||||
.txFreqs = {
|
||||
{ .enabled = true, .idx = 0, .freq = 868.100, .drMin = 0, .drMax = 5},
|
||||
{ .enabled = true, .idx = 1, .freq = 868.300, .drMin = 0, .drMax = 5},
|
||||
|
@ -49,6 +52,9 @@ const LoRaWANBand_t US915 = {
|
|||
.payloadLenMax = { 19, 61, 133, 250, 250, 0, 0, 0, 41, 117, 230, 230, 230, 230, 0 },
|
||||
.powerMax = 30,
|
||||
.powerNumSteps = 10,
|
||||
.dutyCycle = 0,
|
||||
.dwellTimeUp = 400,
|
||||
.dwellTimeDn = 0,
|
||||
.txFreqs = {
|
||||
RADIOLIB_LORAWAN_CHANNEL_NONE,
|
||||
RADIOLIB_LORAWAN_CHANNEL_NONE,
|
||||
|
@ -112,6 +118,9 @@ const LoRaWANBand_t CN780 = {
|
|||
.payloadLenMax = { 59, 59, 59, 123, 230, 230, 250, 230, 0, 0, 0, 0, 0, 0, 0 },
|
||||
.powerMax = 12,
|
||||
.powerNumSteps = 5,
|
||||
.dutyCycle = 3600,
|
||||
.dwellTimeUp = 0,
|
||||
.dwellTimeDn = 0,
|
||||
.txFreqs = {
|
||||
{ .enabled = true, .idx = 0, .freq = 779.500, .drMin = 0, .drMax = 5},
|
||||
{ .enabled = true, .idx = 1, .freq = 779.700, .drMin = 0, .drMax = 5},
|
||||
|
@ -154,6 +163,9 @@ const LoRaWANBand_t EU433 = {
|
|||
.payloadLenMax = { 59, 59, 59, 123, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0 },
|
||||
.powerMax = 12,
|
||||
.powerNumSteps = 5,
|
||||
.dutyCycle = 36000,
|
||||
.dwellTimeUp = 0,
|
||||
.dwellTimeDn = 0,
|
||||
.txFreqs = {
|
||||
{ .enabled = true, .idx = 0, .freq = 433.175, .drMin = 0, .drMax = 5},
|
||||
{ .enabled = true, .idx = 1, .freq = 433.375, .drMin = 0, .drMax = 5},
|
||||
|
@ -196,6 +208,9 @@ const LoRaWANBand_t AU915 = {
|
|||
.payloadLenMax = { 59, 59, 59, 123, 230, 230, 230, 0, 41, 117, 230, 230, 230, 230, 0 },
|
||||
.powerMax = 30,
|
||||
.powerNumSteps = 10,
|
||||
.dutyCycle = 0,
|
||||
.dwellTimeUp = 0,
|
||||
.dwellTimeDn = 0,
|
||||
.txFreqs = {
|
||||
RADIOLIB_LORAWAN_CHANNEL_NONE,
|
||||
RADIOLIB_LORAWAN_CHANNEL_NONE,
|
||||
|
@ -259,6 +274,9 @@ const LoRaWANBand_t CN500 = {
|
|||
.payloadLenMax = { 59, 59, 59, 123, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
.powerMax = 19,
|
||||
.powerNumSteps = 7,
|
||||
.dutyCycle = 0,
|
||||
.dwellTimeUp = 0,
|
||||
.dwellTimeDn = 0,
|
||||
.txFreqs = {
|
||||
RADIOLIB_LORAWAN_CHANNEL_NONE,
|
||||
RADIOLIB_LORAWAN_CHANNEL_NONE,
|
||||
|
@ -315,6 +333,9 @@ const LoRaWANBand_t AS923 = {
|
|||
.payloadLenMax = { 59, 59, 59, 123, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0 },
|
||||
.powerMax = 16,
|
||||
.powerNumSteps = 7,
|
||||
.dutyCycle = 36000,
|
||||
.dwellTimeUp = 400,
|
||||
.dwellTimeDn = 400,
|
||||
.txFreqs = {
|
||||
{ .enabled = true, .idx = 0, .freq = 923.200, .drMin = 0, .drMax = 5},
|
||||
{ .enabled = true, .idx = 1, .freq = 923.400, .drMin = 0, .drMax = 5},
|
||||
|
@ -357,6 +378,9 @@ const LoRaWANBand_t KR920 = {
|
|||
.payloadLenMax = { 59, 59, 59, 123, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
.powerMax = 14,
|
||||
.powerNumSteps = 7,
|
||||
.dutyCycle = 0,
|
||||
.dwellTimeUp = 0,
|
||||
.dwellTimeDn = 0,
|
||||
.txFreqs = {
|
||||
{ .enabled = true, .idx = 0, .freq = 922.100, .drMin = 0, .drMax = 5},
|
||||
{ .enabled = true, .idx = 1, .freq = 922.300, .drMin = 0, .drMax = 5},
|
||||
|
@ -399,6 +423,9 @@ const LoRaWANBand_t IN865 = {
|
|||
.payloadLenMax = { 59, 59, 59, 123, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0 },
|
||||
.powerMax = 30,
|
||||
.powerNumSteps = 10,
|
||||
.dutyCycle = 0,
|
||||
.dwellTimeUp = 0,
|
||||
.dwellTimeDn = 0,
|
||||
.txFreqs = {
|
||||
{ .enabled = true, .idx = 0, .freq = 865.0625, .drMin = 0, .drMax = 5},
|
||||
{ .enabled = true, .idx = 1, .freq = 865.4025, .drMin = 0, .drMax = 5},
|
||||
|
|
Loading…
Add table
Reference in a new issue