Introducing LoRaWAN 1.1 support
Back in April we added a native LoRaWAN stack to Mbed OS 5.8, and today we're continuing our commitment by adding LoRaWAN 1.1 support. LoRaWAN 1.1 includes support for secure device provisioning through a Join Server, new security primitives, handover roaming, and optimizations for communication from the network to the device. In addition to LoRaWAN 1.1 this release also adds support for LoRaWAN 1.0.3.
LoRaWAN remains one of the most popular connectivity methods in the Mbed community, with 21% of users expecting to use it in an upcoming product. Since the initial release of our LoRaWAN stack, we have seen tremendous market adoption and we're expecting the first large-scale deployments using the stack in the first quarter of 2019. We hope that adding LoRaWAN 1.1 support will strengthen this position and drive the whole ecosystem forward.
The updated LoRaWAN 1.1 stack works with any Mbed OS 5-enabled development board, and any available LoRa radio. The stack integrates other features that are important for IoT devices, such as Mbed TLS, Mbed RTOS, tickless mode, and deep-sleep APIs. This allows device and module manufacturers to dramatically shorten their time to market, not having to develop their own networking stack. This is becoming more and more important, as the LoRaWAN standard is increasing in complexity with the addition of features such as multicast and firmware updates.
In this blog post we'll look at the upgrade path, how to build your application, and differences between LoRaWAN 1.0.x and LoRaWAN 1.1.
1. Getting the code
The current release is available in an Mbed OS feature branch, and we expect to release it as part of the next stable Mbed OS release. Because of this, you cannot use the Online Compiler at this point, but have to build through Mbed CLI.
To start, import the Mbed OS LoRaWAN example program, then switch to the feature branch:
$ mbed import https://os.mbed.com/teams/mbed-os-examples/code/mbed-os-example-lorawan/ $ cd mbed-os-example-lorawan $ cd mbed-os $ git checkout feature-lorawan-1-1
If you already have a copy of this application, you can update Mbed OS to the feature branch via:
$ cd mbed-os $ git fetch $ git checkout feature-lorawan-1-1
2. Configuring and building
The Mbed LoRaWAN stack is configured using the Mbed configuration system. The first item that we will be discussing here is how to configure the protocol version in the stack:
2.1 Selecting the protocol version
We can choose the LoRaWAN protocol version by modifying the ‘mbed_app.json’ file located in the root directory of the example application. Look for the ‘target_overrides’ section and add the following line to it:
"lora.version": 10,
This will configure the stack to use LoRaWAN v1.1. The default value is 0, which selects LoRaWAN v1.0.2. The table below displays various field values that you can use to configure the stack.
Protocol version | Field value |
---|---|
LoRaWAN v1.0.2 | 0 |
LoRaWAN v1.0.3 | 1 |
LoRaWAN v1.1 | 10 |
Field value corresponding to protocol version
2.2 Setting up crypto keys and Extended Unique Identifier (EUI)
There are a few points which we need to go through before configuring the security keys and EUIs for the network access. In specification v1.1:
- AppEUI has been replaced with JoinEUI
- Additional security keys
- Differentiation of session security context into two separate parts
AppEUI is treated as JoinEUI inside the Mbed LoRaWAN stack for joining purposes. The name remains the same, so for example, configuring JoinEUI to the stack:
"lora.application-eui": "{ Your JoinEUI in C-Hex format}" ,
For LoRaWAN v1.0.2, you only need AppKey, but for v1.1 you need both AppKey and NwkKey.
If the network server does not support v1.1 and asks the stack to downgrade its protocol version to v1.0.2, the stack will take AppKey in use and revert to v1.0.2 on the fly. We will discuss this situation later in the blog. Note that the NwkKey is not used for v1.0.2.
Setting up NwkKey and AppKey:
"lora.application-key": "{Your AppKey in C-Hex format}", "lora.network-key": "{Your NwkKey in C-Hex format}",
If you configure the stack to use v1.0.2, the stack cannot upgrade itself to v1.1 on the fly.
The session security context has been split in v1.1. Any network management traffic is secured by using session keys derived from the NwkKey (in OTAA case) and any data traffic between the device and application server is secured by using a session key derived from the AppKey. This is in contrast to v1.0.2, where you had only one session security context.
This is it for stack configuration. Now we can have a wholistic look at configuring v1.1 with network acquisition techniques. There are two such techniques described by the specification, ABP (Activation by personalization) and OTAA (Over the air activation). The following table lists various session keys derived from either the NwkKey or AppKey in case of OTAA.
Derived from | Session key list |
---|---|
Network Key (NwkKey ) | 1. Forwarding network session integrity key (FNwkSIntKey ), 2. Serving network session integrity key (SNwkSIntKey ), 3. Network session encryption key (NwkSEncKey ), 4. Join session integrity key (JSIntKey ), 5. Join session encryption key (JSEncKey ) |
Application Key (AppKey) | Application session key (AppSKey) |
Session Keys derivation for OTAA
The function of FNwkSIntKey is identical to NwkSKey, that’s why there is no configuration field for FNwkSIntKey. If you are using ABP as the activation method, NwkSKey is the field you should be looking for while adding FNwkSIntKey.
Example configuration for OTAA:
"lora.version": 10, "lora.over-the-air-activation": true, "lora.application-eui": "{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }" "lora.device-eui": "{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }", "lora.application-key": "{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F , 0x1F }", "lora.network-key": "{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E , 0x0F }",
Example configuration for ABP:
"lora.version": 10, "lora.over-the-air-activation": false, "lora.device-address": "0x0000001" "lora.nwkskey": "{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F , 0x1F }", "lora.snwksintkey": "{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E , 0x0F }", "lora.nwksenckey": "{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F , 0x1F }", "lora.appskey": "{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E , 0x0F }",
2.3 Building the application
If your application involves switching device class from A to C or vice versa, you may need to add 3 more events to your event handler. The events are listed below.
CLASS_CHANGED
SERVER_ACCEPTED_CLASS_IN_USE
SERVER_DOES_NOT_SUPPORT_CLASS_IN_USE
The events are defined in lorawan_type.h and they inform the application about a requested change in device class. The event handler in the application example where you need to add these events is on line 219 of main.cpp. Addition of these events is not critical for normal operation.
Witheverything in place, we can now build our application for LoRaWAN v1.1:
$ mbed compile -m target_name -t tool_chain
Flash the binary to your target and you are ready to connect to a v1.1 LoRaWAN network server.
3. Major differences between protocol version support
3.1 MAC commands
MAC commands are used to perform network management and optimization tasks and are exchanged between the device and network nerver. In the new v1.1 specification , MAC commands are always sent as encrypted. These commands can either be piggybacked with the application data in the FOpts field of frame header or they can be sent as Payload. If the MAC commands are being sent as Payload, they must be sent to port 0, which is the designated port for management traffic. As Payload, MAC commands follow the same size limits as a normal packet would do.
Version | Piggybacked in FOpts | As FRMPayload |
---|---|---|
1.0.X | Unencrypted, 15 octets max. | Encrypted |
1.1 | Encrypted, 15 octets max. | Encrypted |
MAC command encryption differences
3.1.1 New MAC commands in LoRaWAN v1.1 protocol
Several new MAC commands were added in the v1.1 of the specification. Below is asummary of such MAC commands:
CID | Direction | Command | Description |
---|---|---|---|
0x01 | Uplink | ResetInd | Only applicable to ABP. Used to indicate device reset and negotiate protocol version |
0x01 | Downlink | ResetConf | Acknowledgement of ResetInd |
0x0B | Uplink | RekeyInd | Only applicable to OTAA. Used to indicate updated security context (rekeying) |
0x0B | Downlink | RekeyConf | Acknowledgement of RekeyInd. |
0x0D | Uplink | DeviceTimeReq | Device queries the NS for current date and time |
0x0D | Downlink | DeviceTimeAns | Answer sent by NS in response to DeviceTimeReq |
0x0E | Downlink | ForceRejoinReq | NS asks the device to rejoin the network immediately with optional periodic retries |
0x0F | Downlink | RejoinParamSetupReq | NS asks the device to setup periodic device rejoin messages |
0x0F | Uplink | RejoinParamSetupAns | Answer sent by the device in response to RejoinParamSetupReq |
New MAC commands introduced in v1.1
3.1.2 Differing behavior of old MAC commands
Some of the MAC commands which are carried into the new specification from legacy protocol specifications have either changed their meanings or have been clarified. A sub-field of LinkADRReq MAC command has changed its meaning:
CID | Direction | Command | Field | Description 1.0.X | Description 1.1 |
---|---|---|---|---|---|
0x03 | Downlink | LinkADRReq | NbTrans | Provides QOS by repeating the same uplink NbTrans times. Applicable only to UNCONFIRMED messages. | Provides QOS. Applicable to both UNCONFIRMED and CONFIRMED messages. For CONFIRMED messages, it means the max. number of retries if the ack is not received. |
Differing behaviour of old MAC commands
3.2 Functional protocol level differences
3.2.1 End device address (DevAddr)
DevAddr is a 32-bit address that uniquely identifies a particular device on a particular network. For v1.0.X, the DevAddr had a fixed composition, in other words its constituents had defined lengths. DevAddr was composed of two fields, namely NwkID (32..25) and NwkAddr(24..0). However, in v1.1 NwkID and NwkAddr fields are variable. This is mainly because the Alliance has moved to take in use NetID allocation schemes which provide differing schemes of addresses for different network providers.
Version | DevAddr |
---|---|
v1.0.X | 32 bytes, NwkID(32..25), NwkAddr(24..0) |
v1.1 | 32 bytes, AddrPrefix(31..32-N), NwkAddr(31-N..0) |
DevAddr construction
3.2.2 Session contexts
For v1.0.X there was only one session context. However, in v1.1 there are two session contexts, Network session context & Application session context.
Network session context includes:
- FNwkSintKey
- SNwkSIntKey
- DevAddr
- FCntUp (uplink frame counter)
- NFCntDown (downlink frame counter for network context)
Whereas the Application session context includes:
- AppSkey
- FCntUp (uplink frame counter, same as network context)
- AFCntDown (application context downlink frame counter)
Network session context is maintained by the Network Server (NS) and Application session context is maintained by Application server (AS).
3.2.3 DLSettings field in Join Accept message
The DLSettings field in Join Accept message has the bit number 8 set to RFU, meaning it was reserved for future use, like
However. in v1.1 the bit number 8 represents OptNeg.
If the OptNeg bit is set:
- The protocol version is 1.1 or later, negotiation will take place between the device and network server using ReKeyInd/ReKeyConf MAC command exchange.
- The device derives FNwkSIntKey, SNwkSIntKey & NwkSEncKey using NwkKey.
- The device derives AppSkey from AppKey
If the OptNeg bit is not set:
- The device reverts to 1.0.x, no exchange of MAC commands
- The device derives FNwkSIntKey & AppSKey from the NwkKey
- The device sets SNwkSIntKey & NwkSEncKey equal to FNwkSIntKey
3.2.4 Type of Join Request message and its impact on encryption of Join Accept message
In v1.0.x had only one type of Join Request message. v1.1 introduces another type of Join Request message known as Rejoin Request. This new type of Join Request comes in three flavours:
- Rejoin Request Type 0
- Rejoin Request Type 1
- Rejoin Request Type 2
The Join Accept message will be encrypted as a function of what type of Join Request is being used as shown in table below.
Join Request type | Join Accept encryption key |
---|---|
Join Request | NwkKey |
Rejoin Request (0,1 and 2) | JSEncKey |
Join Request types and corresponding Key
3.2.5 Rejoin Request messages
It is important to discuss Rejoin request messages here as it is a new feature introduced in v1.1. An activated device may periodically transmit a Rejoin Request along with its normal application traffic. This gives the backend an opportunity to initialize a new session context for the end device. It also ensures that you never exhaust your frame counters as a Rejoin will freshen your session context along with your frame counters. The same mechanism can also be used to hand over traffic from one network to another.
Rejoin Request type | Content & Purpose |
---|---|
0 | Contains NetID+DevEUI. Used to reset a device context including all radio parameters (DevAddr, session keys, frame counters, radio parameters, ..). This message can only be routed to the device’s home Network Server by the receiving Network Server, not to the device’s JoinServer The MIC of this message can only be verified by the serving or home Network Server. |
1 | Contains NetID+DevEUI. Used to rekey a device or change its DevAddr (DevAddr, session keys, frame counters). Radio parameters are kept unchanged. This message can only be routed to the device’s home Network Server by visited networks, not to the device’s Join Server. The MIC of this message can only be verified by the serving or home Network Server. |
2 | Contains JoinEUI+DevEUI. Exactly equivalent to the initial Join-Request message but may be transmitted on top of normal application traffic without disconnecting the device. Can only be routed to the device’s JoinServer by the receiving Network Server. Used to restore a lost session context (Example, Network Server has lost the session keys and cannot associate the device to a JoinServer). Only the JoinServer is able to check the MIC of this message |
Rejoin Request Type 0 and Type 2 are the ones with a different frame structure as compared to Rejoin Request Type 1.
RJCount is a 16-bit counter that is incremented every time a Rejoin Request of Type 0 or Type 2 is transmitted and is set to 0 whenever a Join Accept message is received. Rejoin Request Type 1 is very similar to normal Join Request as it uses JoinEUI and DevEUI. It is different in construction compared to Rejoin Type 0 and Type 2 since it introduces yet another counter, RJCount1, which must be incremented for every Rejoin Request Type 1. Recommended frequency of the Rejoin Request Type 1 is about 1 month.
Some more differences among Rejoin Request types can be summarized as:
Type | Periodic/Autonomous | In response to ForceRejoinReq MAC command | Channel to be used | Data rate to use |
---|---|---|---|---|
0 | X | X | Default channels only | Should use DR defined in ForceRejoinReq MAC command. |
1 | X | Default channels only | If ADR is enabled, use the same DR as used by application traffic. If ADR is disabled use any of the allowed DR. | |
2 | X | Any enabled channel | Should use DR defined in ForceRejoinReq MAC command. |
3.2.6 Rejoin Request message processing
For all 3 Rejoin Request messages the network server may respond with:
- A Join Accept Message if the NS decides to change the session context for the device. In that case RJCount(0 or 1) replaces DevNonce in the key derivation process.
- A normal downlink frame, which may contain MAC commands. This downlink will be sent on the same channel with same DR, and RX1Delay will be equal to JoinAccept Delay.
- No response. This can be the usual case.
What’s next
Arm is heavily invested in advancing the LoRaWAN standard. We're an an active member of the LoRa Alliance, and we were the first company to demonstrate multicast firmware updates over LoRaWAN. An IoT device is more than just an MCU and a radio. A complete IoT product incorporates an RTOS, crypto libraries, an update client, a resilient file system, and more. Having a common set of well-integrated middleware modules is vital for a secure and scalable IoT solution.
We have a lot more planned for our LoRaWAN stack. We acquired two Redwood LoRa testers recently which we'll use to run nightly certification tests, are working on LoRaWAN device simulation, and will release an updated LoRaWAN firmware update solution soon. Keep an eye on this space!
Want to learn more about Mbed OS and LoRaWAN? We will be present at The Things Conference, the largest LoRaWAN gathering on the planet, 31 January - 1 February in Amsterdam. Register here with code FRIEND-OF-JAN
to get 10% off!
-
Hasnain Virk is one of the authors of the Mbed LoRaWAN stack and a member of the LoRa Alliance Technical Comittee.