Over-the-air-activation OTAA with LMIC


I'm trying to do OTAA with the LMIC code on a RaspberryPi.

My gateway knows about the "new" servers.

The LMIC code needs a DEVEUI, that I derive from the PI's MAC address.
The APPEUI is the EUI I created with ttnctl applications.

Then the LMIC code wants a definition for a device-specific 128 bit AES key.I tried the APPSKEY I used earlier with PERSONALIZED activation, but that doesn't work. What should I specify here?

Denied Over-the-air-activation with LoraWan Libelium
(Arjan) #2

Did you follow Device Management in the wiki?

ttnctl devices register [DevEUI] [AppKey]

Or, to create or update OTAA registrations on the Handler that have not been explicitly registered using the above:

ttnctl devices register default [AppKey]

I don't know when to use the above default option, as the AppKey should be unique for each device:

6.2.2 Application key (AppKey)

The AppKey is an AES-128 application key specific for the end-device that is assigned by the application owner to the end-device and most likely derived from an application-specific root key exclusively known to and under the control of the application provider.
Since all end-devices end up with unrelated application keys specific for each end-device, extracting the AppKey from an end-device only compromises this one end-device.

(Thomas Telkamp) #3

Keep in mind that in LMiC APPEUI and DEVEUI are LSBF, DEVKEY (AppKey) is MSBF. To make life easier :smile:

New backend. How to connect?
New backend. How to connect?

Aha. Is that most significant BYTE first or most significant BIT first (do I swap bytes or bits). [Another example of IBM creating bit/byte order confusion.]


I already found out:I had to reverse the BYTE sequences for APPEUI and DEVEUI (I guess is the Raspberry's ARM is big-endian then).

And OTAA now works on the Raspberry LMIC port.


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?



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
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.

Adafruit LoRa Feather -> Gateway

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

Packet queued

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



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).

Packet queued
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

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


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.)


(Arjan) #20

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.