ElectronicCats / Beelan-LoRaWAN

A LoRaWAN library for compatible arduino board
https://www.beelan.mx
MIT License
187 stars 77 forks source link

[Question] Save OTAA credentials #130

Closed Parradan closed 1 year ago

Parradan commented 1 year ago

Hello, I am currently using a stm32f103 (bluepill) on an ultra low power system. I would like to know if there is any way to save the credentials after the Join. I am using the stm32 in shutdown mode, so every time it comes back on i have to join.

I would like to know what are the credentials that i should save in eeprom, to avoid joining every time i shut down

Stm32f103c8t6, AU915, RFM95, Class-A device Thanks and regards Parradan

ivanmorenoj commented 1 year ago

Hi @Parradan you can use ABP instead of OTTA as activation method, but you will need to store the frame counter every uplink or disable frame counter validation.

Parradan commented 1 year ago

Hello, yes it is one of the options analyzed, but i had left it as the last option. I knew that credentials could be saved, but i don't know how difficult it is. If possible, i would continue to use OTAA activation method.

IvanAmg commented 1 year ago

Hi! @Parradan The values you're looking for are stored in a struct on the Beelan library. These variables are unsigned char DevNonce[2]; unsigned char AppNonce[3]; unsigned char NetID[3]; This struct is defined as sLoRa_OTAA type. Please, give it a try and let me know if there's any issue.

LioBou commented 5 months ago

Hello, could you give some clues about how to use the credentials (OTAA mode)? I don't see how to use the DevNonce, AppNonce and NetID once the join() has been performed... Thanks for your help !

Eric286 commented 5 months ago

Hello @LioBou!

Here's how to use them:

DevNonce, short for Device Nonce, is a unique and unpredictable number generated by the device for each join attempt or transmission. It prevents replay attacks and ensures fresh communication. In the file LoRaMAC.cpp in the src directory you can see how it is generated and loaded.

AppNonce, short for Application Nonce, is another unpredictable number generated by the application (in this case, your Arduino code) and included in the uplink frame. NetID, short for Network ID, is a unique identifier for the LoRaWAN network your device operates on.

For these you can also see them in the LoRaMAC.cpp file

Once the join() function successfully joins the network, the library stores the obtained NetID internally.

Have a Nice Day!

Support Team!

LioBou commented 5 months ago

Thank you @Eric286 !

What I need is to save (in Flash or EEPROM mem) NetID, DevNonce and AppNonce in order to re-use them after a power off and power on and avoiding doing a Join Request each time (this is consuming a lot of power, especially when Signal/Noise ratio a not very good (far gateways) with trial with SF8, then SF9, then SF10, then SF11 then SF12.

So I would like, for a low power IoT project (Hive monitoring), using LoRa in OTAA mode:

  1. After a successfull Join Request, store NetID, DevNonce and AppNonce in Flash memory (I'm using a Pico µcontroller)
  2. Send LoRa data
  3. Power off for XX minutes (not a sleep mode, real power off)
  4. Wakeup (using an external chip like TP5110) and power on
  5. Load previously stored NetID, DevNonce and AppNonce
  6. Send LoRa data (without redoing a Join Request)
  7. back to 3

So I'm looking for understanding the library to see how I can save NetID, DevNonce and AppNonce and re-use then in the SendUpLink function. And I'm having a hard time understanding the library unfortunately...

Any help ?

Thanks!

Eric286 commented 5 months ago

Hello @LioBou

Since DevNonce is a counter incremented with each Join Request, saving the last used value wouldn't be helpful. Instead, store a timestamp of the last successful Join Request. You can save the current AppNonce and reuse it for subsequent transmissions within a reasonable time frame (e.g., 24 hours). After that, generate a new AppNonce for security purposes. NetID is typically assigned by the LoRaWAN network and remains fixed for the device. You only need to store it once.

Before sending data, check if the stored timestamp for the last successful Join Request is within the validity period (e.g., 24 hours). If yes, retrieve the stored NetID, AppNonce, and DevNonce (increment the counter by 1) and use them in the send() or sendConfirmed() function of the Beelan-LoRaWAN library.

Consider using LoRaWAN Class C if possible, as it offers lower power consumption compared to Class A through scheduled uplinks and downlinks.

Support Team!