Hi All, I would like to clarify something that I have read on the forum about node authentication:

Does OTAA generate keys for ABP authentication?

Example communication flow of the application in a common sleep/awake/send:

1: Join with OTAA then store the keys
2: Use stored keys to send data via ABP?

Is this correct?

this could probably help

Thanks @ursm, that’s where I read it. But I love to hear from others if this is the correct way to use OTAA.

Maybe my question should be: Should all node send one OTAA request to join (assuming its successful) then use ABP to send data unless otherwise told to OTAA join again?


No, not really:

  • OTAA activation gets the device the NwkSKey, AppSKey and DevAdr from the server, plus network settings such as additional frequencies and RX settings. (Join Request sent, Join Accept received.)

  • ABP “activation” sets the NwkSKey, AppSKey and DevAdr into the device while programming, and also requires one to program the network settings. (No network traffic for the “activation” at all.)

  • While transmitting uplinks or while decrypting downlinks, your LoRaWAN library does not care how the device got all these settings.

  • Only when the device somehow loses its configuration one can avoid having to do an OTAA activation again by storing the OTAA responses in non-volatile memory and then mimic an ABP “activation”. If this only happens when the device is restarted or the battery is empty: don’t worry, just do OTAA again. (Also nice to allow for simply joining a different network.) If it happens for every (deep) sleep, then store and re-use the settings and frame counters, and much more.

Some libraries or devices might support this without doing anything special in code, or with a single line of code to save the settings.

  • For RN2483 and RN2903, mac join abp after an earlier mac join otaa and frequent usage of mac save (to save a long but possibly incomplete list of settings) should do the trick, though one might first need to set dummy values for DevAddr, AppSKey and NwkSKey to make that work.

  • For LMiC, one needs to store and retrieve settings manually: after deep sleep, configure your node as an ABP node using LMIC_setSession(...), and set the frame counters to their last stored values, using LMIC.seqnoUp = ... and LMIC.seqnoDn = .... The session secrets have different names (which originate from the early days where LoRaWAN was still called LoRaMAC). The documentation shows:

    2.5.4 void LMIC_setSession (u4_t netid, devaddr_t devaddr, u1_t* nwkKey, u1_t* artKey)

    Set static session parameters. Instead of dynamically establishing a session by joining the network, precomputed session parameters can be provided. To resume a session with precomputed parameters, the frame sequence counters (LMIC.seqnoUp and LMIC.seqnoDn) must be restored to their latest values.

    And so does the code:

    void LMIC_setSession (u4_t netid, devaddr_t devaddr, xref2u1_t nwkKey, xref2u1_t artKey);

    Indeed, the global LMIC variable provides access to properties such as LMIC.nwkKey for NwkSKey, LMIC.artKey for AppSkey and LMIC.devaddr for DevAddr, which you should be able to retrieve and persist in case EV_JOINED.

Be careful where to save such details:

And if one happens to use an ESP32:


Does that mean that ABP is always technically on the network when you start a node with it?
As in: ABP is “connected” without a GW, but OTAA needs a GW to connect. (i know this means the ABP can’t send data, but theoretically speaking.


If the keys in your device match the keys in the network server (TTN Console), then: technically, maybe, yes; as soon as it transmits a packet using those secrets, the network knows how to handle it. However, it’s not like WiFi where a device is really “connected”. A device just transmits some data, and hopefully one or more gateways will receive that, and then forward to TTN, which hopefully knows how to handle it. Such gateways will also receive messages for other operators, and even messages that just use the LoRa radio modulation but without using the LoRaWAN network protocol, and will forward all of those. Typically, gateways don’t know what they’re receiving and forwarding.

So, by using ABP you really just skip OTAA by programming the “session” secrets into the device, rather than asking for those secrets* by using OTAA (which uses another secret, the application key).

*) and the non-standard network settings!

Thank you that makes a lot of sense, and should explain why some of my template code for Arduino WAN 1300 claims to be properly sending messages, even though i see nothing on TTN (whilst using ABP).
So it’s simply firing it into the atmosphere (or whatever analogy works), and hoping that a GW is close enough and actually picks it up?

Yes. But also: if the keys are wrong, then even when some gateway(s) receive the message, the message might be discarded by the operator (TTN).

If you do not have a gateway yourself (so: if you cannot access any gateway’s log files, or see its traffic in TTN Console), then to maximise the chances that your test message is received, try using SF12 for some tests.

Also beware that your node might reset its frame counters to zero when restarting, which for ABP either needs you to reset the counters in TTN Console too, or (for testing) needs you to disable the frame counter security altogether, for otherwise TTN will silently ignore the messages until it gets one that has a counter exceeding the last known value. For OTAA, the counters are reset on each join, so no problems there.

1 Like