ArduinoCore-stm32l0 icon indicating copy to clipboard operation
ArduinoCore-stm32l0 copied to clipboard

LoRaWAN.setSaveSession(true); Downlinks no longer received after reset or power cycle

Open NetSensors opened this issue 6 years ago • 9 comments

I'm getting some strange behaviour with downlinks not being received when LoRaWAN.setSaveSession(true);

The first downlink seems to be received after a new session is created then after a reset and continuation of session it doesn't accept downlinks.

I'm using the example code with a receive callback added. See below

#include "LoRaWAN.h"

const char *appEui = "70B3D57ED00144C8";
const char *appKey = "2B7E151628AED2A6ABF7158809CF4F3C";
const char *devEui = "0101010101010101";

volatile bool onRecieve = false;

void setup( void )
{
    Serial.begin(9600);
    //while (!Serial) { }
    LoRaWAN.begin(EU868);
    // LoRaWAN.setSubBand(2);
    LoRaWAN.setDutyCycle(false);
    // LoRaWAN.setAntennaGain(2.0);
    LoRaWAN.onReceive(callback_onReceive);
    LoRaWAN.setSaveSession(true);
    LoRaWAN.joinOTAA(appEui, appKey, devEui);
    Serial.println("JOIN( )");
}

void loop( void )
{
    if (!LoRaWAN.busy())
    {
        if (!LoRaWAN.linkGateways())
        {
            Serial.println("REJOIN( )"); 
            LoRaWAN.rejoinOTAA();
        }
        
        if (LoRaWAN.joined())
        {
            Serial.print("TRANSMIT( ");
            Serial.print("TimeOnAir: ");
            Serial.print(LoRaWAN.getTimeOnAir());
            Serial.print(", NextTxTime: ");
            Serial.print(LoRaWAN.getNextTxTime());
            Serial.print(", MaxPayloadSize: ");
            Serial.print(LoRaWAN.getMaxPayloadSize());
            Serial.print(", DR: ");
            Serial.print(LoRaWAN.getDataRate());
            Serial.print(", TxPower: ");
            Serial.print(LoRaWAN.getTxPower(), 1);
            Serial.print("dbm, UpLinkCounter: ");
            Serial.print(LoRaWAN.getUpLinkCounter());
            Serial.print(", DownLinkCounter: ");
            Serial.print(LoRaWAN.getDownLinkCounter());
            Serial.println(" )");
                
            LoRaWAN.beginPacket();
            LoRaWAN.write(0xef);
            LoRaWAN.write(0xbe);
            LoRaWAN.write(0xad);
            LoRaWAN.write(0xde);
            LoRaWAN.endPacket();
        }
    }

   if (onRecieve){
     onRecieve = false;
     Serial.print("RECIEVE( )");
     if (LoRaWAN.parsePacket())
    {
        
        uint32_t size;
        uint8_t data[50];
        size = LoRaWAN.read(&data[0], sizeof(data));
        if (size){
          Serial.print("Outputting data array ");
          for(int i=0;i<size;i++){
              Serial.print(data[i],HEX);
          }
          Serial.println();
        }
         delay(1000);
         STM32L0.reset();  
    }
    
    
    
    }
    delay(10000);
}

void callback_onReceive(){
   onRecieve = true;
}

_Originally posted by @NetSensors in https://github.com/GrumpyOldPizza/ArduinoCore-stm32l0/issues/64#issuecomment-458538286_

NetSensors avatar Feb 04 '19 13:02 NetSensors

Same issue here. Have you been able to solve it @NetSensors ?

aessig avatar Nov 12 '19 19:11 aessig

I am also experiencing the same issue, has anyone solved the problem ?

lollopes avatar Feb 18 '20 01:02 lollopes

Can confirm, the issue still stands, and even without saved sessions, downlink works only a fraction of the time.

pe-varga avatar Apr 02 '20 03:04 pe-varga

I have not been able to confirm missing downlinks in any case. Remember that there is always packet loss over the air. Perhaps this is what you are seeing. In my local testing the gateway is always close by ...

GrumpyOldPizza avatar Apr 02 '20 12:04 GrumpyOldPizza

Same issue here (Europe/Netherlands/KPN), are other using same region/provider? Gateway close by or at longer distance does not seem to matter. Analysis suggests the Rx1DrOffset parameter is not persistent over resets. This causes downlink messages which are transmitted in RX1 to be not received after a reset....

Additionally I also regularly experience problems with network level messages causing OnTransmit callbacks. Below a screendump of a power analyzer showing currents of an IoT device indicating the ongoing LoRa radio communication. First a join is made. Then 3 'application' uplink messages are sent (back to back), each transmission having data in the RX2 window and each uplink correctly followed by an OnTransmit callback at the end of the RX2 window. Then two network level uplink messages are sent (not application initiated!). Then an additional/erroneous OnTransmit callback is called....

LoRaWANStackProblems

nelisse avatar Oct 15 '20 15:10 nelisse

I have one of those oki power analysers best piece of test kit I have bought.

Sent from my iPhone

On 15 Oct 2020, at 16:04, nelisse [email protected] wrote:

 Same issue here (Europe/Netherlands/KPN), are other using same region/provider? Gateway close by or at longer distance does not seem to matter. Analysis suggests the Rx1DrOffset parameter is not persistent over resets. This causes downlink messages which are transmitted in RX1 to be not received after a reset....

Additionally I also regularly experience problems with network level messages causing OnTransmit callbacks. Below a screendump of a power analyzer showing currents of an IoT device indicating the ongoing LoRa radio communication. First a join is made. Then 3 'application' uplink messages are sent (back to back), each transmission having data in the RX2 window and each uplink correctly followed by an OnTransmit callback at the end of the RX2 window. Then two network level uplink messages are sent (not application initiated!). Then an additional/erroneous OnTransmit callback is called....

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

NetSensors avatar Oct 15 '20 19:10 NetSensors

Further investigating into the RX1 downlink problem suggests the following:

  • TTN does not seem to be using these network changes, so reproducing the problem requires a different provider.
  • We notice similar problems with the frequencies being used after a reset (using default channels 1,2 and 3, in stead of other channels set earlier), which suggests these problems are related to persistancy.
  • The LoRaWAN class sits in between the application and the Semtech LoRa stack and takes (amongst others) care of making the various Semtech stack settings persistent by storing them in and retrieving them from EEPROM memory.
  • The LoRaWAN class uses two class variables (_session/_params of structures LoRaWANSession/LoRaWANParams) to do this.
  • The LoRaWANParams structure is used to store information like RX1DrOffset, RX2DataRate, RX2Frequency and also frequency information.
  • When the Semtach stack informs the LoRaWAN class to update these parameters, the settings are read from Semtech stack (_getParams) and saved into EEPROM (_saveParams).
  • However after a reset the OTAA join does retrieve the parameters from EEPROM (_restoreParams) but does NOT push them to the Semtech stack.
  • Therefore the Semtech stack does not use the previously pushed settings, but instead uses a default zero-ed set.
  • This makes the Semtech stack ignore downlink messages in RX1, but also proper frequencies etc.

Some initial trials with a fix from the application side, showed this could indeed be the cause of the problem. The fix is now recoded in (hopefully) the proper place in the LoRaWAN.cpp file, additional trials are now ongoing. Maybe others can do the same?

In function LoRaWANClass::_joinOTAA(LoRaWANCommissioning *commissioning) change lines 2625-2634 to:

        if ((_session.DevAddr == 0) || !_Save || !_restoreParams())
        {
            return _rejoinOTAA();
        }
        else
        {
            _restoreADR();
            // Push restored params to Semtech stack
            _setParams();

            return _rejoinABP();
        }

nelisse avatar Oct 22 '20 13:10 nelisse

Thanx for finding that. I checked throu the whole logic over and over again and did not see that.

GrumpyOldPizza avatar Oct 22 '20 14:10 GrumpyOldPizza

Great to be of any help! I assume the additional OnTransmit callbacks are not related to this param restore? But I think they are indeed triggered by the MAC information exchange between node and provider, any hints for me for code paths to look into?

nelisse avatar Oct 22 '20 16:10 nelisse