Skip to content

Commit

Permalink
UNTESTED join change, TESTED: downlink buffer overflow protection and…
Browse files Browse the repository at this point in the history
… an example with downlink.
  • Loading branch information
clavisound committed Dec 4, 2024
1 parent c79bd92 commit 5915f40
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 84 deletions.
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,9 @@ The majority of the work was done by Hendrik Hagendorn and Ideetron B.V. Thanks
- [x] ADR_ACK_LIMIT
- [x] NbTrans
- [x] Channel Mask
- [x] RxTimingSetup

# MAC commands added but untested
## MAC commands added but untested

- [ ] Added battery Level to DevStatusAns. Battery status is working, I think margin is wrong.

Expand All @@ -73,18 +74,18 @@ Solutions with avr style.

# TODO's (PR's welcome) - In order of importance.

- [ ] CFlist
- [ ] Join back-off
- [ ] Confirmed Uplink
- [ ] Confirmed Downlink
- [ ] Extern variable for Duty Cycle if the application can provide time.
- [ ] Make DevNonce random.
- [ ] More regions. Currently only EU868 is working.
- [ ] Add pin mappings infrastucture for other boards.
- [ ] Add compile options for battery status (unable to measure, connected to external power)
- [ ] Respect Dwell MAC command (only for US902?)
- [ ] Random delay for TX.
- [ ] Duty Cycle per channel.
- [ ] extern variable for Duty Cycle if the application can provide time.
- [ ] Respect Dwell MAC command (only for US902?)
- [ ] CFlist only for US and AS?

# Undoable on AVR and Deep Sleep

Expand Down
61 changes: 30 additions & 31 deletions SlimLoRa.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1334,8 +1334,9 @@ void SlimLoRa::ProcessFrameOptions(uint8_t *options, uint8_t f_options_length) {
// Apply ChMask
// TODO US: Apply ChMask according to ChMaskCntl. p. 33 Regional parameters
if ( new_rx2_dr == 0 ) {
// BUG? Always zero?
ChMask = (uint16_t) options[i + 2] | options[i + 3] << 8;

// Store to EEPROM
SetChMask();

#if DEBUG_SLIM == 1
Expand Down Expand Up @@ -1507,6 +1508,8 @@ void SlimLoRa::ProcessFrameOptions(uint8_t *options, uint8_t f_options_length) {
new_rx2_dr = (options[i + 1] & 0xF);
// zero value = 1
if ( new_rx2_dr == 0 ) { new_rx2_dr = 1; }

// Save to EEPROM
SetRx1Delay(new_rx2_dr);
rx1_delay_micros_ = GetRx1Delay() * MICROS_PER_SECOND;

Expand Down Expand Up @@ -1547,6 +1550,10 @@ void SlimLoRa::ProcessFrameOptions(uint8_t *options, uint8_t f_options_length) {
* @return 0 if successful, else error code.
*/
int8_t SlimLoRa::ProcessDownlink(uint8_t window) {
// start fresh
downlinkSize = 0;
downPort = 0;

int8_t result;
uint8_t rx1_offset_dr;
uint8_t temp;
Expand Down Expand Up @@ -1663,18 +1670,6 @@ int8_t SlimLoRa::ProcessDownlink(uint8_t window) {
#endif

}
//
// This does not goes well with my procedure to read downlink application data.
// EEPROM corruption, hung and restart.
/* else {
#if DEBUG_SLIM == 1
Serial.print(F("\nMAC else downPort: "));Serial.println(downPort);Serial.flush();
#endif
// Process MAC commands
f_options_length = packet[5] & 0xF;
ProcessFrameOptions(&packet[8], f_options_length);
}
*/

// application downlink
if ( downPort > 0 && downPort < 224 ) { // downPort 0 and 224 are special case
Expand All @@ -1697,7 +1692,6 @@ int8_t SlimLoRa::ProcessDownlink(uint8_t window) {

// stollen from MAC command
payload_length = packet_length - LORAWAN_MAC_AND_FRAME_HEADER - f_options_length - LORAWAN_MIC_SIZE;
//payload_length = packet_length - 8 - f_options_length - 4;
#if DEBUG_SLIM == 1
Serial.print(F("\nPacket RAW HEX"));printHex(packet, packet_length);
printDownlink();
Expand All @@ -1707,14 +1701,29 @@ int8_t SlimLoRa::ProcessDownlink(uint8_t window) {
EncryptPayload(&packet[LORAWAN_MAC_AND_FRAME_HEADER + f_options_length + LORAWAN_PORT_SIZE], payload_length, frame_counter, LORAWAN_DIRECTION_DOWN);

// Store downlink payload to downlinkData. Skip MAC header and Device Address.
// Data starts at 10th byte and ends 4 bytes - before MIC;
downlinkSize = 0;
for ( temp = LORAWAN_START_OF_FRM_PAYLOAD - 1; temp < packet_length - LORAWAN_MIC_SIZE; temp++) {
temp = LORAWAN_START_OF_FRM_PAYLOAD; // Data starts at 10th byte and ends 4 bytes before MIC
for ( ; downlinkSize < payload_length - 1; downlinkSize++) { // BUG? payload_length is always plus 1. WHY?

if ( downlinkSize > DOWNLINK_PAYLOAD_SIZE ) { // Protection for buffer overflow.
// If downlinkSize > DOWNLINK_PAYLOAD_SIZE invalidate and abort income data.

#if DEBUG_SLIM == 1
Serial.print(F("\ndownlinkSize is larger than DOWNLINK_PAYLOAD_SIZE: "));Serial.print(DOWNLINK_PAYLOAD_SIZE);
Serial.print(F("\ndownlinkSize: "));Serial.print(downlinkSize);
#endif

downlinkSize = 0;

break;
}
downlinkData[downlinkSize] = packet[temp];
downlinkSize++;
temp++;
}

#if DEBUG_SLIM == 1
if ( downlinkSize > 0 ) {
Serial.print(F("\nDownlinkData"));printHex(downlinkData, downlinkSize);
}
#endif
}

Expand Down Expand Up @@ -2449,7 +2458,7 @@ uint16_t SlimLoRa::GetTxFrameCounter() {
void SlimLoRa::SetTxFrameCounter(uint16_t count) {
eeprom_write_word(&eeprom_lw_tx_frame_counter, count);
#if DEBUG_SLIM == 1
Serial.print(F("\nWRITE Tx#: "));Serial.print(count >> 8);Serial.print(count);
Serial.print(F("\nWRITE Tx#: "));Serial.print(count);
#endif
}

Expand Down Expand Up @@ -2491,20 +2500,10 @@ uint8_t SlimLoRa::GetRx2DataRate() {

if (value == 0xFF) {
#if LORAWAN_OTAA_ENABLED
return SF12BW125;
#if NETWORK == 'NET_TTN' // TTN
// return SF12BW125;
return RX_SECOND_WINDOW;
#endif // TTN
#if NETWORK == 'NET_HELIUM' // Helium
return RX_SECOND_WINDOW;
#endif // HELIUM
#else
#if NETWORK == 'NET_TTN' // TTN
return RX_SECOND_WINDOW;
#endif // TTN
#if NETWORK == 'NET_TTN' // TTN
return RX_SECOND_WINDOW;
#endif // Helium
#endif // LORAWAN_OTAA_ENABLED
}
return value;
Expand Down Expand Up @@ -2580,7 +2579,7 @@ void SlimLoRa::SetTxFrameCounter(uint16_t count) {
//EEPROM.update(EEPROM_TX_COUNTER, count);
EEPROM.put(EEPROM_TX_COUNTER, count);
#if DEBUG_SLIM == 1
Serial.print(F("\nWRITE Tx#: "));Serial.print(count >> 8);Serial.print(count);
Serial.print(F("\nWRITE Tx#: "));Serial.print(count);
#endif
}

Expand Down
18 changes: 11 additions & 7 deletions SlimLoRa.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#define NBTRANS 1

// TTN or Helium
#define NETWORK 'NET_HELIUM' // Two options: NET_HLM = helium, NET_TTN = TheThingsNetwork
#define NETWORK 'NET_TTN' // Two options: NET_HLM = helium, NET_TTN = TheThingsNetwork
// NET_TTN: RX2 SF9
// NET_HLM: RX2 SF12

Expand All @@ -28,12 +28,12 @@
// I think helium needs re-join. EVAL with chripstack

// I propose to you that you config your device on the console.helium.com to 5 seconds RX DELAY.
// By Default HELIUM uses 1 sec of delay
#define NET_HELIUM_RX_DELAY 5

// Make sure this value is the same with TTN console.
#define NET_TTN_RX_DELAY 5

// By Default HELIUM uses 1 sec of delay, but join is always at 5 seconds
#define NET_HELIUM_RX_DELAY 5

// Select Arduino style EEPROM handling.
#define ARDUINO_EEPROM 1 // Uses static storage, but it helps debugging.

Expand All @@ -49,6 +49,9 @@
#define EEPROM_WRITE_TX_COUNT 200 // SlimLoRa default: 10
#define EEPROM_WRITE_RX_COUNT 10 // SlimLoRa default: 3

// downlink size payload. You can gain some flash / RAM memory here
#define DOWNLINK_PAYLOAD_SIZE 12 // more than 51 bytes is impossible in SF12

// LoRaWAN ADR
// https://lora-developers.semtech.com/documentation/tech-papers-and-guides/implementing-adaptive-data-rate-adr/implementing-adaptive-data-rate/
#define LORAWAN_ADR_ACK_LIMIT 164 // Request downlink after XX uplinks to verify we have connection. Minimum sane value: 64
Expand Down Expand Up @@ -161,7 +164,8 @@
#define LORAWAN_DIRECTION_UP 0
#define LORAWAN_DIRECTION_DOWN 1

#define LORAWAN_UPLINK_CHANNEL_COUNT 8 // Valid Values 8 or 16. Used for ChMask
#define LORAWAN_UPLINK_CHANNEL_COUNT 8 // Valid Value only 8.
// In future downlink channel must move to another index - not 8 or in another variable.

// LoRaWAN frame options
#define LORAWAN_FOPT_LINK_CHECK_REQ 0x02
Expand Down Expand Up @@ -199,7 +203,7 @@
#define LORAWAN_PORT_SIZE 1
#define LORAWAN_MIC_SIZE 4
#define LORAWAN_MAC_AND_FRAME_HEADER 8 // MAC Header is 1 byte. Frame header is 7..22 bytes
#define LORAWAN_START_OF_FRM_PAYLOAD 10
#define LORAWAN_START_OF_FRM_PAYLOAD 9

// LoRaWAN Join packet sizes
#define LORAWAN_JOIN_REQUEST_SIZE 18
Expand Down Expand Up @@ -308,7 +312,7 @@ class SlimLoRa {
void setArrayEEPROM(uint16_t eepromAdr, uint8_t *arrayData, uint8_t size);
#endif

uint8_t downlinkData[12]; // hardcoded to 12 bytes
uint8_t downlinkData[DOWNLINK_PAYLOAD_SIZE];
uint8_t downlinkSize;
uint8_t downPort;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#define HLM // TTN or HLM (helium) MSB values

// JS DECODER for Helium or TTN
// JS DECODER for TTN or Helium.
/*
function Decoder(bytes, port) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#endif

void checkBatt(){
vbat = analogRead(VBATPIN) - 450; // convert to 8bit
vbat = analogRead(VBATPIN) - 450; // fit to 8bit. Will add 450 on decoder.
/*
vbat *= 2; // we divided by 2, so multiply back
vbat *= 3.3; // Multiply by 3.3V, our reference voltage
Expand Down Expand Up @@ -74,27 +74,4 @@ void blinkLed(uint16_t times, uint16_t duration, uint8_t pause) { // x, ms, seco
Serial.println();
}

void printMAC_EEPROM(){
Serial.println(F("MAC STATE from EEPROM"));
#if LORAWAN_OTAA_ENABLED // You define this on SlimLoRa.h file.
Serial.print(F("EEPROM join: "));Serial.println(lora.GetHasJoined());
#else
Serial.print(F("ABP DevAddr"));printHexB(DevAddr, 4);
#endif // LORAWAN_OTAA_ENABLED
lora.GetDevAddr(temp) ;Serial.print(F("DevAdd"));printHexB(temp, 4);
Serial.print(F("Tx_# : "));Serial.println(lora.GetTxFrameCounter()); // Serial.print(F("\tRAM: "));Serial.println(tx_frame_counter_);
Serial.print(F("Rx_# : "));Serial.println(lora.GetRxFrameCounter()); // Serial.print(F("\tRAM: "));Serial.println(rx_frame_counter_);
Serial.print(F("Rx1 delay : "));Serial.print(lora.GetRx1Delay());Serial.print(F(", System Setting: "));Serial.print(LORAWAN_JOIN_ACCEPT_DELAY1_MICROS / 1000000);Serial.print("s, RX2: ");Serial.print(LORAWAN_JOIN_ACCEPT_DELAY2_MICROS / 1000000);Serial.println("s, ");
Serial.print(F("Rx1 DR Offset: "));Serial.println(lora.GetRx1DataRateOffset());
Serial.print(F("DevNonce : "));Serial.print(lora.GetDevNonce() >> 8);Serial.println(lora.GetDevNonce());
Serial.print(F("JoinNonce : "));Serial.print(lora.GetJoinNonce() >> 24);Serial.print(lora.GetJoinNonce() >> 16);Serial.print(lora.GetJoinNonce() >> 8);Serial.println(lora.GetJoinNonce());
// Don't publish those values!
#if KEYS_EXPORT == 1
lora.GetAppSKey(temp) ;Serial.print(F("AppSKey NOWEB")) ;printHexB(temp, 16);
lora.GetFNwkSIntKey(temp) ;Serial.print(F("FNwkSIntKey NOWEB"));printHexB(temp, 16);
lora.GetSNwkSIntKey(temp) ;Serial.print(F("SNwkSIntKey NOWEB"));printHexB(temp, 16);
lora.GetNwkSEncKey(temp) ;Serial.print(F("NwkSEncKey NOWEB")) ;printHexB(temp, 16);
#endif
}

#endif // DEBUG_INO
Loading

0 comments on commit 5915f40

Please sign in to comment.