Over-the-air-activation OTAA with LMIC

Nice! I think this is valuable to share this with the community. Can you please add this to the new wiki? This page: http://staging.thethingsnetwork.org/wiki/Hardware/Nodes/Overview (raise PR on https://github.com/TheThingsNetwork/wiki/tree/rewrite). Thanks!

Thanks!. And what did you use for the APPKEY in LMIC?

Maarten

For the APPKEY is used a 16 byte code, that I also registered with the command ttnctl devices register DEVEUI APPKEY

Whether or not this APPKEY should be unique for the hardware device and/or the application does not become clear from the various inforamtion sources (the Lorawan spec does not fully agree with the RN2483 model command reference for example)

I also tried it with a default APPKEY I had registered with.ttnctl devices register default APPKEY; this also works
This ttnctl register default command installs a default key in TTN. Devices using that APPKEY and the corresponding APPEUI will get activated on first contact. (At least I believe that’s how it works)

That’s how it works indeed; you can specify a default AppKey per application, or a specific AppKey per device.

You can generate your own AppKey and it can be anything as long as it is 16 bytes. If you run your own application handler, which will be possible soon, you can keep these keys physically private to enable end-to-end encryption. Then, you use ttnctl to talk to your own handler.

It is recommended to configure a specific AppKey per device and use a strong random key generator to generate the keys.

This refers to “activate” a NODE based on ATMEGA and RFM95W with LMIC1.5x
I’m a little lost in TTN:
ok, I could follow the procedure with ttnctl-windows-amd64 up to step 8. Get info about a specific device
There I get
AppEUI: which I already know from step 3./4.
DevEUI: created 8 bytes of true random (RFM95W does in contrast to RN2483 not give a unique hardware-ID)
AppKey: also known from step 6.

my confusion is: LMIC needs also the following (also confused about “session”)

  • LoRaWAN NwkSKey, network session key DEVKEY[16]
  • LoRaWAN AppSKey, application session key ARTKEY[16]
  • DEVADDR which I’ve choosen out of “tth-zh address space”
  1. is AppKey one of DEVKEY or ARTKEY. how to find the other?
  2. could I use them as given from ttnctl or do I need to shuffle the bytes around as mentioned above LSBF/MSBF
    please give me dummy a clear example for DF FD 57 53 B0 57 3D CA F1 6A CE CD D1 BD A2 8A
  3. how do I register DEVADDR or will it registered at first usage?

thanks for your kind help, urs

I struggle quite a bit about this and found out the following:

APPEUI is provided by the EUI field of the ttnctl applications
DEVEUI is provided by the DevEUI field of the ttnctl devices info
NwkSkey is provided by the AppKey field of the ttnctl devices info

Then APPEUI and DEVEUI need to be reversed in the LMIC retrieve functions. Either, you store them in the reverse order or you do it in the os_getArtEui and os_getDevEui functions.

For example, if the DEVEUI returned by ttnctl devices info is 01 02 03 04 05 06 07 08, the the function need to return a buffer holding 08 07 06 05 04 03 02 01. Same for APPEUI. NwkSkey remain the same as ttnctl output.

hi mirmit
thanks for your explanation, but did I read correctly between the lines
ttnctl___=__thethingsnetwork-send-v1.ino
APPEUI = // LoRaWAN Application identifier (AppEUI) perfectly clear
DEVEUI = // LoRaWAN DevEUI, unique device ID (LSBF) ok, must be reversed
APPKEY = // LoRaWAN NwkSKey, network session key
??? = // LoRaWAN AppSKey, application session key <----- still unclear

thanks for spending another minute to clarify

Hi ursm,

For me OTAA with LMIC works if I do the following:

static const u1_t APPEUI[]={reversed 8 bytes of AppEUI registered with ttnctl}
void os_getArtEui (u1_t* buf) { memcpy(buf, APPEUI, 8);}
static const u1_t DEVEUI[]={reversed 8 bytes of DevEUI reistered with ttnctl}
void os_getDevEui (u1_t* buf) { memcpy(buf, DEVEUI, 8);}
static const unsigned char APPKEY[16] = {<non-reversed 16 bytes of the APPKEY used when registering a device with ttnctl register DevEUI AppKey>}
void os_getDevKey (u1_t* buf) {  memcpy(buf, APPKEY, 16);}

You do not need to fill in NWKSKEY and APPSKEY in the LMIC code. The DEVADDR is filled in automatically by the OTAA activation. You can remove the call(s) to LMIC_setSession(), which is the personalized activation call (“old style”)

With the RFM95W you have to come up with a (unique) devEUI; I used the Ethernet MAC code of my Raspberry for that and added 2 bytes (assuming MAC addresses are unique).

The APPKEY is a 16 byte code you make up for your application; this could be shared among multiple nodes,

Once your device is registered and activated you can get all it’s info from ttnctl devices info YourDevEUI
This command will show: APPEUI, DevEUI and AppKey. If the device has been activated correctly it will also show a DevAddr, NwkSKey and an AppSKey.

So after activation the node should have DevAddr, NwkSkey andd AppSkey set.

In the beginning it can beconfusing, with all these keys

Good luck.

3 Likes

THANKS @ernestopace now it’s clear. I’ll try it soon!

Hey Ernesto

thanks for these pointers! I’ve managed to activate the device via OTAA on my Arduino / Moteino - but am currently stuck at

Starting
Packet queued
181: EV_JOINING

I see that the device is activated, but the messages are not getting through. I’ve documented all here: https://github.com/lukastheiler/ttn_moteino#moteino-lmic-and-otaa-walkthrough-wip

do you have any idea why the messages are not getting through?

Thanks! Lukas

Hi Lukas,

My first thought was that your gateway might not handle messages TO your node correctly. However, I assume your RN2483 experiment uses the same gateway, and with that OTAA does seem to work.
Another possibility is that someone else has come up with DEEDDEEDDEED as DEVEUI. I think however this shouldn’t matter, because the DEVEUI should identify the node uniquely in combination with the APPEUI and/or the APPKEY. So this is probably not it.

I’m going to do some more testing with an Arduino and the RFM95W in the coming days.and see what I problems I run into then

Ernst

Hi Ernesto and @lukas,

I actually have the exact problem as Lukas. I registered the RFM95W + arudino pro mini succesfully via OTAA but it doesn’t send any messages (stuck at EV_JOINING). Furthermore the same setup does work if I use ABP. In addition I also have a working setup with OTAA and the RN2483. I am unsure what the problem is.

I just discovered that messages are actually being send, only after a (yet) inexpiable long time (approximately 15 min).

Starting
Packet queued
405: EV_JOINING
38257442: EV_JOINED
42179989: EV_TXCOMPLETE (includes waiting for RX windows)
Packet queued
44133708: EV_TXCOMPLETE (includes waiting for RX windows)
Packet queued
46215066: EV_TXCOMPLETE (includes waiting for RX windows)
Packet queued

325: EV_JOINING
55224904: EV_JOINED
60192041: EV_TXCOMPLETE (includes waiting for RX windows)
Packet queued
64292173: EV_TXCOMPLETE (includes waiting for RX windows)
Packet queued

1 Like

Hi Kibet,

The successfull access through OTAA with LMIC was on a RaspBerryPi.

I have now done some testing with an Arduino and the LMIC software from @matthijs (https://github.com/matthijskooijman/arduino-lmic).
This works with the original AES implementation. I do see very varying JOIN times, in the order of 1-3 minutes, which I find very slow.

(BTW I also tested OTAA with the alternative AES implementations @matthijs presented; With those AES versions OTAA does not seem to work at all. I’m still looking at that.)

Ernst

1 Like

Any idea if your nodes have a good connection? The duty cycle for join requests is less than 0.1% (at least for EU). So I guess retries, and falling back to lower data rates, will indeed imply a lot of waiting.

Awesome, I’ve just tested it, and patience is the key :smile:

Thanks a lot everyone!!

Yeah the node is 30 meters away from the gateway. With ABP it has always been a good connection, even at a distance of 1.5 km. Same goes for the RN2483 with OTAA, which instantly joins. Thus something different happens when I try the RFM95W with OTAA and this library. It could be that it fails to join and retries at a lower datarate, however this shouldn’t be necessary as the connection is good.

In the LoRaWAN 1.0 specification the duty cycle for joins in EU is indeed 0.1%. So if the initial joins fails for whatever reason, it will take a long time before it sends another attempt.

The LoRaWAN 1.0.1 update has relaxed this limitation to 1% join duty cycle in the first hour.

The reason for missing some join (accepts) is probably because the TTN backend can respond in the RX2 window and then uses data rate SF9. This is not compliant, and I just opened an issue for it. Before the join, the backend should respond with the LoRaWAN default values (=SF12 for RX2), and then it can change from the defaults by setting the new configuration parameters in the join accept message. After the join accept, it can then use the TTN values (=SF9 for RX2).

Also note that LMiC based end-node could miss a join accept because of incorrect RX slot timing, if your code does other stuff than just LMiC.

2 Likes

I guess you know, so just to be sure/for future readers: with ABP no join request is sent at all. Instead, all keys needed for the communication are already programmed into the node, hence no need for any join sequence.

1 Like

You are right, that was a poor choice of words. I changed it.

@Thomas

think you are (partially) right. When I changed the duty cycle form 0.1% to 1% the joining process was faster. However as expected, it still isn’t instantaneously. If the node retries to join at a lower data rate, is there anyway to see at which datarate it is trying or at which is successfully joined?

Furthemore changing RX2 window to SF9 or leaving it at SF12 (default) didn’t seem to make a difference.

LMIC.dn2Dr = SF9;

btw my code doesn’t do anything else then sending, it is pretty much the default example code.