# LoRaWAN 1.0.2
###### tags: `LoRaWAN`
This is a note which is reordered and extracted from LoRaWAN 1.0.2.
Focus on Class A.
## Star Topology
End device#1 -┐
End device#2 -┼- Gateway
End device#n -┘
## LoRaWAN Classes
### Bi-directional end-devices (Class A)
* End-devices of Class A allow for bi-directional communications whereby each end-device‘s uplink transmission is followed by two short downlink receive windows.
* The transmission slot scheduled by the end-device is based on its own communication needs with a small variation based on a random time basis (**ALOHA**-type of protocol).
### Bi-directional end-devices with scheduled receive slots (Class B)
* End-devices of Class B allow for more receive slots.
* In addition to the Class A random receive windows, Class B devices open extra receive windows at scheduled times.
* In order for the End-device to open it receive window at the scheduled time it receives a time synchronized Beacon from the gateway. This allows the server to know when the end-device is listening.
### Bi-directional end-devices with maximal receive slots (Class C)
* End-devices of Class C have nearly continuously open receive windows, only closed when transmitting.
* Class C end-device will use more power to operate than Class A or Class B but they offer the lowest latency for server to end-device communication.
## End-device Receive Slot Timing
![End-device Receive Slot Timing](https://hackmd.io/_uploads/HkVXoOdU3.jpg)
* RX1 and RX2 are receive windows opened by the end device.
* If it is in activation process, the delay will be **JOIN_ACCPRT_DELAY1** and **JOIN_ACCEPT_DELAY2**.
* If it is in normal data transferring, the delay will be **RECEIVE_DELAY1** and **RECEIVE_DELAY2**.
* If a preamble is detected during one of the receive windows, the radio receiver stays active until the downlink frame is demodulated.
* The length of a receive window must be at least the time required by the end-device‘s radio transceiver to effectively detect a downlink preamble.
* If a frame was detected and subsequently demodulated during the first receive window and the frame was intended for this end-device after address and MIC (message integrity code) checks, the end-device does not open the second receive window.
* These values of the parameters should be refered to **LoRaWAN 1.0.2 Regional Parameters**
## MAC Frame Format
### Join Request Message Format (End-device -> Gateway)
![Join Request](https://hackmd.io/_uploads/BJ9EoOOL2.jpg)
### Join Accept Message Format (Gateway -> End-device)
![Join Accept](https://hackmd.io/_uploads/Hk78s_O83.jpg)
### MAC Data Message Format (End-device <-> Gateway)
![MAC Data Message](https://hackmd.io/_uploads/SytDiOOLn.jpg)
### MHDR - MAC Header
7..5 bits | 4..2 bits | 1..0 bits
----------|-----------|----------
MType | RFU | Major
* MType
MType | Description
------|----------------------
000 | Join Request
001 | Join Accept
010 | Unconfirmed Data Up
011 | Unconfirmed Data Down
100 | Confirmed Data Up
101 | Confirmed Data Down
110 | RFU
111 | Proprietary
* Major
Major bits | Description
-----------|------------
00 | LoRaWAN R1
### MIC - Message Integrity Code
The **MIC** will be defined by each message type.
## For MAC Data Message
### FHDR - Frame Header
* FCtrl - Frame Control
- For Uplink Frames
7 bit | 6 bit | 5 bit | 4 bit | 3..0 bits
------|-----------|-------|-------|----------
ADR | ADRACKReq | ACK | RFU | FOptsLen
- For Downlink Frames
7 bit | 6 bit | 5 bit | 4 bit | 3..0 bits
------|-------|-------|----------|----------
ADR | RFU | ACK | FPending | FOptsLen
- ADR
* If the **ADR** bit is set, the network will control the data rate of the end-device through the appropriate MAC commands. If the **ADR** bit is not set, the network will not attempt to control the data rate of the end-device regardless of the received signal quality.
* The **ADR** bit may be set and unset by the end-device or the Network on demand.
- ADRACKReq
In uplink transmissions the **ADRACKReq** bit is set if *ADR_ACK_CNT >= ADR_ACK_LIMIT* and the current data-rate is greater than the device defined minimum data rate, it is cleared in other conditions.
- ACK
When receiving a confirmed data message, the receiver shall respond with a data frame that has the acknowledgment bit **ACK** set.
- FPending
The frame pending bit **FPending** is only used in downlink communication, indicating that the gateway has more data pending to be sent and therefore asking the end-device to open another receive window as soon as possible by sending another uplink message.
- FOptsLen
The frame-options length field **FOptsLen** in FCtrl byte denotes the actual length of the frame options field **FOpts** included in the frame.
### Retransmission Procedure
The number of retransmissions (and their timing) for the same message where an acknowledgment is requested but not received is at the discretion of the end device and may be different for each end-device.
### FCnt - Frame counter
* Each end-device has two frame counters to keep track of the number of data frames sent uplink to the network server **FCntUp**, incremented by the end-device and received by the end-device downlink from the network server **FCntDown**, which is incremented by the network server.
* The network server tracks the uplink frame counter and generates the downlink counter for each end-device.
* After a JoinReq – JoinAccept message exchange or a reset for a personalized end-device, the frame counters on the end-device and the frame counters on the network server for that end-device are reset to 0.
* The FCnt is not incremented in case of multiple transmissions of an *unconfirmed frame*, or in the case of a confirmed frame that is *not acknowledged*.
* The end-device shall not reuse the same **FCntUp** value, except for retransmission, with the same application and network session keys.
### FPort - Port Field
* If the frame payload field is not empty, the port field must be present. If present, an FPort value of 0 indicates that the FRMPayload contains MAC commands only.
* FPort values 1..223 (0x01..0xDF) are application-specific.
* FPort value 224 is dedicated to LoRaWAN Mac layer test protocol.
* FPort values 225..255 (0xE1..0xFF) are reserved for future standardized application extensions.
### FOpts - Frame Options
* FOpts transport MAC commands of a maximum length of 15 octets that are piggybacked onto data frames.
* If FOptsLen is 0, the FOpts field is absent. If FOptsLen is different from 0, i.e. if MAC commands are present in the FOpts field, the port 0 cannot be used (FPort must be either not present or different from 0).
* MAC commands cannot be simultaneously present in the payload field and the frame options field.
### MAC Frame Payload Encryption
* If a data frame carries a payload, FRMPayload must be encrypted before the message integrity code (MIC) is calculated.
* The encryption scheme used is based on the generic algorithm described in *IEEE 802.15.4/2006 Annex B* [IEEE802154] using AES with a key length of 128 bits.
* The key K used depends on the FPort of the data message:
FPort | K
-------|--------
0 | NwkSkey
1..255 | AppSKey
* pld = **FRMPayload**
* sequence of Blocks *A_i* for i = 1..k with k = ceil(len(pld) / 16)
bytes | 1 | 4 | 1 | 4 | 4 | 1 | 1
------|------|----------|-----|---------|------|------|--
*A_i* | 0x01 | 4 X 0x00 | Dir | DevAddr | FCnt | 0x00 | i
- **Dir** is 0 for uplink frames and 1 for downlink frames
- blocks *A_i* are encrypted to get a sequence S of blocks *S_i*:
*S_i = aes128_encrypt(K, A_i) for i = 1..k*
*S = S_1 | S_2 | .. | S_k*
* Encryption and decryption of the payload is done by truncating
*(pld | pad_16 ) xor S*
to the first len(pld) octets.
* Use AES 128 bits CTR mode
* Padding by zeroes
https://www.thethingsnetwork.org/forum/t/questions-about-aes128-encryption-of-a-frmpayload-payload/4207
### MIC - Message Integrity Code
* The message integrity code *MIC* is calculated over all the fields in the message.
*msg = MHDR | FHDR | FPort | FRMPayload*
* The MIC is calculated as follows [RFC4493]:
*cmac = aes128_cmac(NwkSKey, *B_0* | msg)*
*MIC = cmac[0..3]*
bytes | 1 | 4 | 1 | 4 | 4 | 1 | 1
------|------|----------|-----|---------|------|------|---------
*B_0* | 0x49 | 4 X 0x00 | Dir | DevAddr | FCnt | 0x00 | len(msg)
### MAC Commands
A single data frame can contain any sequence of MAC commands in 2 ways:
1. Piggybacked in the FOpts field or
- Piggybacked MAC commands are always sent without encryption
- Must not exceed 15 octets
2. Sent as a separate data frame, in the FRMPayload field with the FPort field being set to 0
- MAC commands sent as FRMPayload are always encrypted
- Must not exceed the maximum FRMPayload length
1 byte | Some more bytes
-------|----------------
CID | Command's data
#### CID - Command identifier
CID | Command | Transmitted by | Short Description
-----|------------------|----------------|------------------
0x02 | LinkCheckReq | End-device | Used by an end-device to validate its connectivity to a network
0x02 | LinkCheckAns | Gateway | Answer to LinkCheckReq command
0x03 | LinkADRReq | Gateway | Requests the end-device to change data rate, transmit power, repetition rate or channel
0x03 | LinkADRAns | End-device | Acknowledges the LinkRateReq
0x04 | DutyCycleReq | Gateway | Sets the maximum aggregated transmit duty-cycle of a device
0x04 | DutyCycleAns | End-device | Acknowledges a DutyCycleReq command
0x05 | RXParamSetupReq | Gateway | Sets the reception slots parameters
0x05 | RXParamSetupAns | End-device | Acknowledges a RXSetupReq command
0x06 | DevStatusReq | Gateway | Requests the status of the end-device
0x06 | DevStatusAns | End-device | Returns the status of the end-device, namely its battery level and its demodulation margin
0x07 | NewChannelReq | Gateway | Creates or modifies the definition of a radio channel
0x07 | NewChannelAns | End-device | Acknowledges a NewChannelReq command
0x08 | RXTimingSetupReq | Gateway | Sets the timing of the of the reception slots
0x08 | RXTimingSetupAns | End-device | Acknowledges RXTimingSetupReq
0x09 | TxParamSetupReq | Gateway | Used by the network server to set the maximum allowed dwell time and Max EIRP of end-device, based on local regulations
0x09 | TxParamSetupAns | End-device | Acknowledges TxParamSetupReq command
0x0A | DlChannelReq | Gateway | Modifies the definition of a downlink RX1 radio channel by shifting the downlink frequency from the uplink frequencies
0x0A | DlChannelAns | End-device | Acknowledges DlChannelReq command
0x80..FF | Proprietary | Both | Reserved for proprietary network command extensions
The more detail and commands' data could be found in Chapter 5 of LoRaWAN 1.0.2 specification.
## Join Request-Accept Activation
### Over-the-Air Activation
The join procedure requires the end-device to be personalized with the following information before it starts the join procedure: a globally unique end-device identifier **DevEUI**, the application identifier **AppEUI**, and an AES-128 key **AppKey**.
#### AppEUI - Application identifier
* The AppEUI is a global application ID in IEEE EUI64 address space that uniquely identifies the entity able to process the JoinReq frame.
#### DevEUI - End-device identifier
* The DevEUI is a global end-device ID in IEEE EUI64 address space that uniquely identifies the end-device.
#### AppKey - Application key
* The AppKey is an AES-128 root key specific to the end-device.
* The AppKey is used to derive the session keys **NwkSKey** and **AppSKey** specific for that end-device to encrypt and verify network communication and application data.
### Join-Request Message
bytes | 8 | 8 | 4
-------------|--------|--------|---------
Join-Request | AppEUI | DevEUI | DevNonce
#### DevNonce
* DevNonce is a random value provided by the end-device.
* For each end-device, the network server keeps track of a certain number of DevNonce values used by the end-device in the past, and ignores join requests with any of these DevNonce values from that end-device.
#### MIC for Join Request
*cmac = aes128_cmac(AppKey, MHDR | AppEUI | DevEUI | DevNonce)*
*MIC = cmac[0..3]*
### Join-Accept Message
bytes | 3 | 3 | 4 | 1 | 1 | 0 or 16
-------------|----------|-------|---------|------------|---------|--------
Join-Request | AppNonce | NetID | DevAddr | DLSettings | RxDelay | CFList
#### AppNonce
* The AppNonce is a random value or some form of unique ID provided by the network server
* Used by the end-device to derive the two session keys **NwkSKey** and **AppSKey**
***NwkSKey** = aes128_encrypt(AppKey, 0x01 | AppNonce | NetID | DevNonce | pad_16 )*
***AppSKey** = aes128_encrypt(AppKey, 0x02 | AppNonce | NetID | DevNonce | pad_16 )*
#### NetID
* Assigned by the network manager
23..7 bits | 6..0 bits
-------------------------------|----------
Chosen by the network operator | NwkID
#### DevAddr - End-device address
* Assigned by the network manager
31..25 bits | 24..0 bits
------------|-----------
NwkID | NwkAddr
#### DLSettings
7 bit | 6..4 bits | 3..0 bits
------|-------------|--------------
RFU | RX1DRoffset | RX2 Data rate
* RX1DRoffset
- Sets the offset between the uplink data rate and the downlink data rate used to communicate with the end-device on the first reception slot (RX1).
- By default this offset is 0.
- The offset is used to take into account maximum power density constraints for base stations in some regions and to balance the uplink and downlink radio link margins.
- The actual relationship between the uplink and downlink data rate is region specific and detailed in the LoRaWAN Regional Parameters document [PARAMS].
#### MIC for Join Accept
*cmac = aes128_cmac(AppKey, MHDR | AppNonce | NetID | DevAddr | DLSettings | RxDelay | CFList)*
*MIC = cmac[0..3]*
#### Join-accept message itself is encrypted with the AppKey
*aes128_**decrypt**(AppKey, AppNonce | NetID | DevAddr | DLSettings | RxDelay | CFList | MIC)*
PS. The network server uses an AES decrypt operation in ECB mode to encrypt the join-accept message so that the end-device can use an AES encrypt operation to decrypt the message. This way **an end-device only has to implement AES encrypt but not AES decrypt**.