LoRaWAN end device MAC layer for SX1272 and SX1276. Supports LoRaWAN-1.0 and LoRaWAN-1.1

Dependencies:   sx12xx_hal

Dependents:   LoRaWAN-SanJose_Bootcamp LoRaWAN-grove-cayenne LoRaWAN-classC-demo LoRaWAN-grove-cayenne ... more

radio chip selection

Radio chip driver is not included, because two options are available.
If you're using SX1272 or SX1276, then import sx127x driver into your program.
if you're using SX1261 or SX1262, then import sx126x driver into your program.
If you're using NAmote72 or Murata discovery, then you must import only sx127x driver.

application project requirements

This library requires mbed TLS to be enabled.
The file mbed_app.json must be present in the project using this library:

{
    "macros": [ "MBEDTLS_CMAC_C" ]
}

regional PHY selection

All end device configuration is done in Commissioning.h, define desired radio frequency band of operation in this header file.
Commissioning.h is located in the application using this library.

end device provisioning

End device is provisioned by editing Commissioning.h in the application which is using this library
To use LoRaWAN-1.0 OTA: make sure LORAWAN_ROOT_APPKEY is undefined.
To use LoRaWAN-1.1 OTA, define LORAWAN_ROOT_APPKEY.
To select OTA operation, define LORAWAN_JOIN_EUI, then LORAWAN_DEVICE_EUI must be defined, along with root key(s).
To select ABP operation, undefine LORAWAN_JOIN_EUI: then define session keys

LoRaWAN 1.0 nameLoRaWAN 1.1 nameComissioning.h defnedescription
OTADevEUIDevEUILORAWAN_DEVICE_EUIuniquely identifies end device
OTAAppEUIJoinEUILORAWAN_JOIN_EUI
OTAAppKeyNwkKeyLORAWAN_ROOT_NWKKEYroot key for network server
OTA(note 1)AppKeyLORAWAN_ROOT_APPKEYroot key for application server
ABPNwkSKey(note 3)LORAWAN_FNwkSIntKeynetwork session key
ABP(note 2)SNwkSIntKeyLORAWAN_SNwkSIntKeymac layer network integrity key
ABP(note 2)NwkSEncKeyLORAWAN_NwkSEncKeynetwork session encryption key
ABP(note 2)FNwkSIntKeyLORAWAN_FNwkSIntKeyforwarding network session integrity key
ABPAppSKeyAppSKeyLORAWAN_APPSKEYapplication session encryption key

(note 1): LoRaWAN-1.0 OTA uses a single root key for both network server and application server.

In LoRaWAN-1.0 OTA: the single root AppKey is used to generate NwkSkey and AppSKey.
(note 2): In LoRaWAN-1.0 (both OTA and ABP) SNwkSIntKey, NwkSEncKey. FNwkSIntKey are of same value and are collectively known as NwkSKey.
(note 3): LoRaWAN-1.0 uses single network session key, LoRaWAN-1.1 uses 3 network session keys. Both use a unique application session key.


In LoRaWAN-1.1 OTA: the root NwkKey is used to generate SNwkSIntKey, NwkSEncKey, FNwkSIntKey
In LoRaWAN-1.1 OTA: the root AppKey is used to generate AppSKey


in ABP mode, the DevAddr, and session keys are fixed (never change), and frame counters never reset to zero.
ABP operation has no concept of: root keys, or DevEUI or JoinEUI/AppEUI.
in OTA mode, the DevAddr and session keys are assigned at join procedure, and frame counters reset at join.

eeprom

This library includes eeprom driver to support non-volatile storage required by LoRaWAN specification.
Currently eeprom is implemented for STM32L1 family and STM32L0 family.
Writing of values are wear-leveled to increase endurance; each write operation circulates across several memory locations. A read operation returns the highest value found. This simple method is used for sequence numbers which only increase.

value nameused in
DevNonceOTAfor Join request (note 1)
RJcount1OTAfor ReJoin Type 1 request
FCntUpABPuplink frame counter
NFCntDownABPdownlink frame counter
AFCntDownABPdownlink frame counter

AFCntDown is only used in LoRaWAN-1.1 when application payload is present in downlink and FPort > 0.
NFCntDown is used in LoRaWAN-1.1 when FPort is zero in downlink or application payload not present.
NFCntDown is the only downlink frame counter used in LoRaWAN-1.0
(note 1) OTA DevNonce is random number in LoRaWAN-1.0, therefore not stored in eeprom. DevNonce in LoRaWAN-1.1 is forever increasing (non-volatile) number upon each join request,.
RJcount0 is only stored in RAM because the value resets upon new session from JoinAccept, therefore not stored in eeprom.
Frame counters in OTA mode reset upon new session in join request, therefore are stored in RAM instead of eeprom for OTA.

radio driver support

When SX127x driver is used, both SX1272 and SX1276 are supported without defining at compile time. The chip is detected at start-up.
Supported radio platforms:


Alternately, when SX126x driver is imported, the SX126xDVK1xAS board is used.

low-speed clock oscillator selection

LoRaWAN uses 32768Hz crystal to permit low-power operation.
However, some mbed targets might revert to low-speed internal oscillator, which is not accurate enough for LoRaWAN operation.
An oscillator check is performed at initialization; program will not start if internal oscillator is used.
To force LSE watch crystal, add to mbed_app.json

{
    "macros": [ "MBEDTLS_CMAC_C" ],
    "target_overrides": {
        "<your-target>": {
            "target.lse_available": true
        }
    }
}
Committer:
Wayne Roberts
Date:
Wed Feb 28 10:48:11 2018 -0800
Revision:
0:6b3ac9c5a042
Child:
2:c9c736b3e4eb
initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Wayne Roberts 0:6b3ac9c5a042 1 #ifndef _LORAMAC_H_
Wayne Roberts 0:6b3ac9c5a042 2 #define _LORAMAC_H_
Wayne Roberts 0:6b3ac9c5a042 3
Wayne Roberts 0:6b3ac9c5a042 4 #include "Commissioning.h"
Wayne Roberts 0:6b3ac9c5a042 5
Wayne Roberts 0:6b3ac9c5a042 6
Wayne Roberts 0:6b3ac9c5a042 7 typedef enum {
Wayne Roberts 0:6b3ac9c5a042 8 LORAMAC_STATUS_OK,
Wayne Roberts 0:6b3ac9c5a042 9 LORAMAC_STATUS_IN_PROGRESS,
Wayne Roberts 0:6b3ac9c5a042 10 LORAMAC_STATUS_BUSY_UPCONF,
Wayne Roberts 0:6b3ac9c5a042 11 LORAMAC_STATUS_SERVICE_UNKNOWN,
Wayne Roberts 0:6b3ac9c5a042 12 LORAMAC_STATUS_PARAMETER_INVALID,
Wayne Roberts 0:6b3ac9c5a042 13 LORAMAC_STATUS_DATARATE_INVALID,
Wayne Roberts 0:6b3ac9c5a042 14 LORAMAC_STATUS_FREQUENCY_INVALID,
Wayne Roberts 0:6b3ac9c5a042 15 LORAMAC_STATUS_LENGTH_ERROR,
Wayne Roberts 0:6b3ac9c5a042 16 LORAMAC_STATUS_DEVICE_OFF,
Wayne Roberts 0:6b3ac9c5a042 17 LORAMAC_STATUS_FREQ_AND_DR_INVALID,
Wayne Roberts 0:6b3ac9c5a042 18 LORAMAC_STATUS_EEPROM_FAIL,
Wayne Roberts 0:6b3ac9c5a042 19 LORAMAC_STATUS_MAC_CMD_LENGTH_ERROR,
Wayne Roberts 0:6b3ac9c5a042 20 #ifdef LORAWAN_JOIN_EUI
Wayne Roberts 0:6b3ac9c5a042 21 LORAMAC_STATUS_NO_NETWORK_JOINED
Wayne Roberts 0:6b3ac9c5a042 22 #endif
Wayne Roberts 0:6b3ac9c5a042 23 } LoRaMacStatus_t;
Wayne Roberts 0:6b3ac9c5a042 24
Wayne Roberts 0:6b3ac9c5a042 25 typedef enum {
Wayne Roberts 0:6b3ac9c5a042 26 LORAMAC_EVENT_INFO_STATUS_OK,
Wayne Roberts 0:6b3ac9c5a042 27 LORAMAC_EVENT_INFO_STATUS_INCR_FAIL,
Wayne Roberts 0:6b3ac9c5a042 28 LORAMAC_EVENT_INFO_STATUS_MLMEREQ,
Wayne Roberts 0:6b3ac9c5a042 29 LORAMAC_EVENT_INFO_STATUS_UNKNOWN_MTYPE,
Wayne Roberts 0:6b3ac9c5a042 30 LORAMAC_EVENT_INFO_STATUS_SENDING,
Wayne Roberts 0:6b3ac9c5a042 31 LORAMAC_EVENT_INFO_STATUS_MCPSREQ,
Wayne Roberts 0:6b3ac9c5a042 32 LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT,
Wayne Roberts 0:6b3ac9c5a042 33 LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT,
Wayne Roberts 0:6b3ac9c5a042 34 LORAMAC_EVENT_INFO_STATUS_RX2_ERROR,
Wayne Roberts 0:6b3ac9c5a042 35 LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED,
Wayne Roberts 0:6b3ac9c5a042 36 LORAMAC_EVENT_INFO_STATUS_TX_DR_PAYLOAD_SIZE_ERROR,
Wayne Roberts 0:6b3ac9c5a042 37 LORAMAC_EVENT_INFO_STATUS_DOWNLINK_TOO_MANY_FRAMES_LOSS,
Wayne Roberts 0:6b3ac9c5a042 38 LORAMAC_EVENT_INFO_STATUS_ADDRESS_FAIL,
Wayne Roberts 0:6b3ac9c5a042 39 LORAMAC_EVENT_INFO_STATUS_MIC_FAIL,
Wayne Roberts 0:6b3ac9c5a042 40 LORAMAC_EVENT_INFO_STATUS_MULTICAST_FAIL,
Wayne Roberts 0:6b3ac9c5a042 41 LORAMAC_EVENT_INFO_STATUS_BEACON_LOCKED,
Wayne Roberts 0:6b3ac9c5a042 42 LORAMAC_EVENT_INFO_STATUS_BEACON_LOST,
Wayne Roberts 0:6b3ac9c5a042 43 LORAMAC_EVENT_INFO_STATUS_BEACON_NOT_FOUND,
Wayne Roberts 0:6b3ac9c5a042 44 LORAMAC_EVENT_INFO_STATUS_NO_APPKEY,
Wayne Roberts 0:6b3ac9c5a042 45 LORAMAC_EVENT_INFO_BAD_RX_DELAY,
Wayne Roberts 0:6b3ac9c5a042 46 #ifdef LORAWAN_JOIN_EUI
Wayne Roberts 0:6b3ac9c5a042 47 LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL,
Wayne Roberts 0:6b3ac9c5a042 48 LORAMAC_EVENT_INFO_STATUS_JOINNONCE
Wayne Roberts 0:6b3ac9c5a042 49 #endif
Wayne Roberts 0:6b3ac9c5a042 50 } LoRaMacEventInfoStatus_t;
Wayne Roberts 0:6b3ac9c5a042 51
Wayne Roberts 0:6b3ac9c5a042 52 typedef enum {
Wayne Roberts 0:6b3ac9c5a042 53 MCPS_NONE,
Wayne Roberts 0:6b3ac9c5a042 54 MCPS_UNCONFIRMED,
Wayne Roberts 0:6b3ac9c5a042 55 MCPS_CONFIRMED,
Wayne Roberts 0:6b3ac9c5a042 56 MCPS_MULTICAST,
Wayne Roberts 0:6b3ac9c5a042 57 MCPS_PROPRIETARY
Wayne Roberts 0:6b3ac9c5a042 58 } Mcps_t;
Wayne Roberts 0:6b3ac9c5a042 59
Wayne Roberts 0:6b3ac9c5a042 60 #include <stdint.h>
Wayne Roberts 0:6b3ac9c5a042 61 typedef struct {
Wayne Roberts 0:6b3ac9c5a042 62 LoRaMacEventInfoStatus_t Status;
Wayne Roberts 0:6b3ac9c5a042 63 Mcps_t McpsRequest;
Wayne Roberts 0:6b3ac9c5a042 64 uint8_t NbRetries;
Wayne Roberts 0:6b3ac9c5a042 65 bool AckReceived;
Wayne Roberts 0:6b3ac9c5a042 66 uint32_t UpLinkCounter;
Wayne Roberts 0:6b3ac9c5a042 67 uint8_t Datarate;
Wayne Roberts 0:6b3ac9c5a042 68 int8_t TxPower;
Wayne Roberts 0:6b3ac9c5a042 69 uint32_t UpLinkFreqHz;
Wayne Roberts 0:6b3ac9c5a042 70 //us_timestamp_t TxTimeOnAir;
Wayne Roberts 0:6b3ac9c5a042 71 } McpsConfirm_t;
Wayne Roberts 0:6b3ac9c5a042 72
Wayne Roberts 0:6b3ac9c5a042 73 typedef struct {
Wayne Roberts 0:6b3ac9c5a042 74 uint8_t attempt;
Wayne Roberts 0:6b3ac9c5a042 75 uint8_t Snr;
Wayne Roberts 0:6b3ac9c5a042 76 int16_t Rssi;
Wayne Roberts 0:6b3ac9c5a042 77 int8_t RxSlot;
Wayne Roberts 0:6b3ac9c5a042 78 LoRaMacEventInfoStatus_t Status;
Wayne Roberts 0:6b3ac9c5a042 79 Mcps_t McpsIndication;
Wayne Roberts 0:6b3ac9c5a042 80 bool RxData;
Wayne Roberts 0:6b3ac9c5a042 81 uint8_t RxDatarate;
Wayne Roberts 0:6b3ac9c5a042 82 uint8_t Port;
Wayne Roberts 0:6b3ac9c5a042 83 uint8_t BufferSize;
Wayne Roberts 0:6b3ac9c5a042 84 uint8_t *Buffer;
Wayne Roberts 0:6b3ac9c5a042 85 uint8_t FramePending;
Wayne Roberts 0:6b3ac9c5a042 86 bool AckReceived;
Wayne Roberts 0:6b3ac9c5a042 87 uint32_t expectedFCntDown;
Wayne Roberts 0:6b3ac9c5a042 88 uint16_t receivedFCntDown;
Wayne Roberts 0:6b3ac9c5a042 89 } McpsIndication_t;
Wayne Roberts 0:6b3ac9c5a042 90
Wayne Roberts 0:6b3ac9c5a042 91 typedef enum {
Wayne Roberts 0:6b3ac9c5a042 92 MLME_NONE = 0,
Wayne Roberts 0:6b3ac9c5a042 93 MLME_LINK_CHECK,
Wayne Roberts 0:6b3ac9c5a042 94 MLME_SWITCH_CLASS,
Wayne Roberts 0:6b3ac9c5a042 95 MLME_PING_SLOT_INFO,
Wayne Roberts 0:6b3ac9c5a042 96 MLME_BEACON_TIMING,
Wayne Roberts 0:6b3ac9c5a042 97 MLME_BEACON_ACQUISITION,
Wayne Roberts 0:6b3ac9c5a042 98 MLME_TIME_REQ,
Wayne Roberts 0:6b3ac9c5a042 99 MLME_BEACON,
Wayne Roberts 0:6b3ac9c5a042 100 MLME_TXCW,
Wayne Roberts 0:6b3ac9c5a042 101 #ifdef LORAWAN_JOIN_EUI
Wayne Roberts 0:6b3ac9c5a042 102 MLME_JOIN,
Wayne Roberts 0:6b3ac9c5a042 103 MLME_REJOIN_0,
Wayne Roberts 0:6b3ac9c5a042 104 MLME_REJOIN_1,
Wayne Roberts 0:6b3ac9c5a042 105 MLME_REJOIN_2
Wayne Roberts 0:6b3ac9c5a042 106 #endif
Wayne Roberts 0:6b3ac9c5a042 107 } Mlme_t;
Wayne Roberts 0:6b3ac9c5a042 108
Wayne Roberts 0:6b3ac9c5a042 109 #include "board.h"
Wayne Roberts 0:6b3ac9c5a042 110
Wayne Roberts 0:6b3ac9c5a042 111 #define DR_0 0
Wayne Roberts 0:6b3ac9c5a042 112 #define DR_1 1
Wayne Roberts 0:6b3ac9c5a042 113 #define DR_2 2
Wayne Roberts 0:6b3ac9c5a042 114 #define DR_3 3
Wayne Roberts 0:6b3ac9c5a042 115 #define DR_4 4
Wayne Roberts 0:6b3ac9c5a042 116 #define DR_5 5
Wayne Roberts 0:6b3ac9c5a042 117 #define DR_6 6
Wayne Roberts 0:6b3ac9c5a042 118 #define DR_7 7
Wayne Roberts 0:6b3ac9c5a042 119 #define DR_8 8
Wayne Roberts 0:6b3ac9c5a042 120 #define DR_9 9
Wayne Roberts 0:6b3ac9c5a042 121 #define DR_10 10
Wayne Roberts 0:6b3ac9c5a042 122 #define DR_11 11
Wayne Roberts 0:6b3ac9c5a042 123 #define DR_12 12
Wayne Roberts 0:6b3ac9c5a042 124 #define DR_13 13
Wayne Roberts 0:6b3ac9c5a042 125 #define DR_14 14
Wayne Roberts 0:6b3ac9c5a042 126 #define DR_15 15
Wayne Roberts 0:6b3ac9c5a042 127
Wayne Roberts 0:6b3ac9c5a042 128
Wayne Roberts 0:6b3ac9c5a042 129 typedef union {
Wayne Roberts 0:6b3ac9c5a042 130 uint8_t Value;
Wayne Roberts 0:6b3ac9c5a042 131
Wayne Roberts 0:6b3ac9c5a042 132 struct {
Wayne Roberts 0:6b3ac9c5a042 133 int8_t Min : 4;
Wayne Roberts 0:6b3ac9c5a042 134 int8_t Max : 4;
Wayne Roberts 0:6b3ac9c5a042 135 } Fields;
Wayne Roberts 0:6b3ac9c5a042 136 } DrRange_t;
Wayne Roberts 0:6b3ac9c5a042 137
Wayne Roberts 0:6b3ac9c5a042 138 typedef struct {
Wayne Roberts 0:6b3ac9c5a042 139 uint32_t FreqHz;
Wayne Roberts 0:6b3ac9c5a042 140 DrRange_t DrRange;
Wayne Roberts 0:6b3ac9c5a042 141 uint8_t Band;
Wayne Roberts 0:6b3ac9c5a042 142 } ChannelParams_t;
Wayne Roberts 0:6b3ac9c5a042 143
Wayne Roberts 0:6b3ac9c5a042 144
Wayne Roberts 0:6b3ac9c5a042 145 typedef struct {
Wayne Roberts 0:6b3ac9c5a042 146 Mcps_t Type;
Wayne Roberts 0:6b3ac9c5a042 147 struct {
Wayne Roberts 0:6b3ac9c5a042 148 void *fBuffer;
Wayne Roberts 0:6b3ac9c5a042 149 uint16_t fBufferSize;
Wayne Roberts 0:6b3ac9c5a042 150 uint8_t Datarate;
Wayne Roberts 0:6b3ac9c5a042 151 uint8_t fPort;
Wayne Roberts 0:6b3ac9c5a042 152 uint8_t NbTrials; // only for confirmed
Wayne Roberts 0:6b3ac9c5a042 153 } Req;
Wayne Roberts 0:6b3ac9c5a042 154 } McpsReq_t;
Wayne Roberts 0:6b3ac9c5a042 155
Wayne Roberts 0:6b3ac9c5a042 156 typedef struct {
Wayne Roberts 0:6b3ac9c5a042 157 uint8_t MaxPossiblePayload;
Wayne Roberts 0:6b3ac9c5a042 158 uint8_t CurrentPayloadSize;
Wayne Roberts 0:6b3ac9c5a042 159 } LoRaMacTxInfo_t;
Wayne Roberts 0:6b3ac9c5a042 160
Wayne Roberts 0:6b3ac9c5a042 161
Wayne Roberts 0:6b3ac9c5a042 162
Wayne Roberts 0:6b3ac9c5a042 163 typedef enum {
Wayne Roberts 0:6b3ac9c5a042 164 MIB_DEV_ADDR,
Wayne Roberts 0:6b3ac9c5a042 165 MIB_DEVICE_CLASS,
Wayne Roberts 0:6b3ac9c5a042 166 MIB_ADR,
Wayne Roberts 0:6b3ac9c5a042 167 MIB_PUBLIC_NETWORK,
Wayne Roberts 0:6b3ac9c5a042 168 MIB_RX2_CHANNEL,
Wayne Roberts 0:6b3ac9c5a042 169 MIB_CHANNELS_MASK,
Wayne Roberts 0:6b3ac9c5a042 170 MIB_FNwkSIntKey,
Wayne Roberts 0:6b3ac9c5a042 171 MIB_APP_SKEY,
Wayne Roberts 0:6b3ac9c5a042 172 MIB_SNwkSIntKey,
Wayne Roberts 0:6b3ac9c5a042 173 MIB_NwkSEncKey,
Wayne Roberts 0:6b3ac9c5a042 174 MIB_NwkSKey, /* lorawan 1.0 */
Wayne Roberts 0:6b3ac9c5a042 175 #ifdef LORAWAN_JOIN_EUI
Wayne Roberts 0:6b3ac9c5a042 176 MIB_NETWORK_JOINED
Wayne Roberts 0:6b3ac9c5a042 177 #endif
Wayne Roberts 0:6b3ac9c5a042 178 } Mib_t;
Wayne Roberts 0:6b3ac9c5a042 179
Wayne Roberts 0:6b3ac9c5a042 180 typedef enum {
Wayne Roberts 0:6b3ac9c5a042 181 CLASS_A,
Wayne Roberts 0:6b3ac9c5a042 182 CLASS_B,
Wayne Roberts 0:6b3ac9c5a042 183 CLASS_C
Wayne Roberts 0:6b3ac9c5a042 184 } DeviceClass_t;
Wayne Roberts 0:6b3ac9c5a042 185
Wayne Roberts 0:6b3ac9c5a042 186 typedef struct {
Wayne Roberts 0:6b3ac9c5a042 187 uint32_t FrequencyHz;
Wayne Roberts 0:6b3ac9c5a042 188 uint8_t Datarate;
Wayne Roberts 0:6b3ac9c5a042 189 } Rx2ChannelParams_t;
Wayne Roberts 0:6b3ac9c5a042 190
Wayne Roberts 0:6b3ac9c5a042 191 typedef union {
Wayne Roberts 0:6b3ac9c5a042 192 uint32_t DevAddr;
Wayne Roberts 0:6b3ac9c5a042 193 bool AdrEnable;
Wayne Roberts 0:6b3ac9c5a042 194 DeviceClass_t Class;
Wayne Roberts 0:6b3ac9c5a042 195 bool IsNetworkJoined;
Wayne Roberts 0:6b3ac9c5a042 196 bool EnablePublicNetwork;
Wayne Roberts 0:6b3ac9c5a042 197 uint16_t* ChannelsMask;
Wayne Roberts 0:6b3ac9c5a042 198 //const uint8_t* FNwkSIntKey;
Wayne Roberts 0:6b3ac9c5a042 199 //const uint8_t* SNwkSIntKey;
Wayne Roberts 0:6b3ac9c5a042 200 //const uint8_t* NwkSEncKey;
Wayne Roberts 0:6b3ac9c5a042 201 //const uint8_t* AppSKey;
Wayne Roberts 0:6b3ac9c5a042 202 const uint8_t* key;
Wayne Roberts 0:6b3ac9c5a042 203 Rx2ChannelParams_t Rx2Channel;
Wayne Roberts 0:6b3ac9c5a042 204 } MibParam_t;
Wayne Roberts 0:6b3ac9c5a042 205
Wayne Roberts 0:6b3ac9c5a042 206 typedef struct {
Wayne Roberts 0:6b3ac9c5a042 207 Mib_t Type;
Wayne Roberts 0:6b3ac9c5a042 208 MibParam_t Param;
Wayne Roberts 0:6b3ac9c5a042 209 } MibRequestConfirm_t;
Wayne Roberts 0:6b3ac9c5a042 210
Wayne Roberts 0:6b3ac9c5a042 211
Wayne Roberts 0:6b3ac9c5a042 212
Wayne Roberts 0:6b3ac9c5a042 213 typedef struct {
Wayne Roberts 0:6b3ac9c5a042 214 Mlme_t Type;
Wayne Roberts 0:6b3ac9c5a042 215
Wayne Roberts 0:6b3ac9c5a042 216 union {
Wayne Roberts 0:6b3ac9c5a042 217 struct {
Wayne Roberts 0:6b3ac9c5a042 218 DeviceClass_t Class;
Wayne Roberts 0:6b3ac9c5a042 219 } SwitchClass;
Wayne Roberts 0:6b3ac9c5a042 220
Wayne Roberts 0:6b3ac9c5a042 221 union {
Wayne Roberts 0:6b3ac9c5a042 222 uint8_t Value;
Wayne Roberts 0:6b3ac9c5a042 223 struct sInfoFields {
Wayne Roberts 0:6b3ac9c5a042 224 uint8_t Periodicity : 3;
Wayne Roberts 0:6b3ac9c5a042 225 uint8_t RFU : 5;
Wayne Roberts 0:6b3ac9c5a042 226 } Fields;
Wayne Roberts 0:6b3ac9c5a042 227 } PingSlotInfo;
Wayne Roberts 0:6b3ac9c5a042 228
Wayne Roberts 0:6b3ac9c5a042 229 #ifdef LORAWAN_JOIN_EUI
Wayne Roberts 0:6b3ac9c5a042 230 struct {
Wayne Roberts 0:6b3ac9c5a042 231 const uint8_t *DevEui;
Wayne Roberts 0:6b3ac9c5a042 232 const uint8_t *JoinEui;
Wayne Roberts 0:6b3ac9c5a042 233 const uint8_t *NwkKey;
Wayne Roberts 0:6b3ac9c5a042 234 const uint8_t *AppKey;
Wayne Roberts 0:6b3ac9c5a042 235 uint8_t NbTrials;
Wayne Roberts 0:6b3ac9c5a042 236 } Join;
Wayne Roberts 0:6b3ac9c5a042 237 #endif /* LORAWAN_JOIN_EUI */
Wayne Roberts 0:6b3ac9c5a042 238
Wayne Roberts 0:6b3ac9c5a042 239 struct {
Wayne Roberts 0:6b3ac9c5a042 240 uint16_t Timeout;
Wayne Roberts 0:6b3ac9c5a042 241 } TxCw;
Wayne Roberts 0:6b3ac9c5a042 242 } Req;
Wayne Roberts 0:6b3ac9c5a042 243 } MlmeReq_t;
Wayne Roberts 0:6b3ac9c5a042 244
Wayne Roberts 0:6b3ac9c5a042 245
Wayne Roberts 0:6b3ac9c5a042 246 typedef struct {
Wayne Roberts 0:6b3ac9c5a042 247 LoRaMacEventInfoStatus_t Status;
Wayne Roberts 0:6b3ac9c5a042 248 Mlme_t MlmeRequest;
Wayne Roberts 0:6b3ac9c5a042 249 union {
Wayne Roberts 0:6b3ac9c5a042 250 struct {
Wayne Roberts 0:6b3ac9c5a042 251 uint8_t DemodMargin;
Wayne Roberts 0:6b3ac9c5a042 252 uint8_t NbGateways;
Wayne Roberts 0:6b3ac9c5a042 253 } link;
Wayne Roberts 0:6b3ac9c5a042 254 struct {
Wayne Roberts 0:6b3ac9c5a042 255 uint32_t Seconds; // seconds since epoch
Wayne Roberts 0:6b3ac9c5a042 256 uint32_t uSeconds; // fractional part
Wayne Roberts 0:6b3ac9c5a042 257 } time;
Wayne Roberts 0:6b3ac9c5a042 258 struct {
Wayne Roberts 0:6b3ac9c5a042 259 uint32_t rxJoinNonce;
Wayne Roberts 0:6b3ac9c5a042 260 uint32_t myJoinNonce;
Wayne Roberts 0:6b3ac9c5a042 261 } join;
Wayne Roberts 0:6b3ac9c5a042 262 } fields;
Wayne Roberts 0:6b3ac9c5a042 263 //us_timestamp_t TxTimeOnAir;
Wayne Roberts 0:6b3ac9c5a042 264 } MlmeConfirm_t;
Wayne Roberts 0:6b3ac9c5a042 265
Wayne Roberts 0:6b3ac9c5a042 266
Wayne Roberts 0:6b3ac9c5a042 267 typedef struct {
Wayne Roberts 0:6b3ac9c5a042 268 Mlme_t MlmeIndication;
Wayne Roberts 0:6b3ac9c5a042 269 LoRaMacEventInfoStatus_t Status;
Wayne Roberts 0:6b3ac9c5a042 270 uint32_t freqHz;
Wayne Roberts 0:6b3ac9c5a042 271 #ifdef LORAWAN_JOIN_EUI
Wayne Roberts 0:6b3ac9c5a042 272 uint8_t JoinRequestTrials;
Wayne Roberts 0:6b3ac9c5a042 273 #endif /* LORAWAN_JOIN_EUI */
Wayne Roberts 0:6b3ac9c5a042 274 } MlmeIndication_t;
Wayne Roberts 0:6b3ac9c5a042 275
Wayne Roberts 0:6b3ac9c5a042 276
Wayne Roberts 0:6b3ac9c5a042 277 /*!
Wayne Roberts 0:6b3ac9c5a042 278 * LoRaMAC events structure
Wayne Roberts 0:6b3ac9c5a042 279 * Used to notify upper layers of MAC events
Wayne Roberts 0:6b3ac9c5a042 280 */
Wayne Roberts 0:6b3ac9c5a042 281 typedef struct sLoRaMacPrimitives
Wayne Roberts 0:6b3ac9c5a042 282 {
Wayne Roberts 0:6b3ac9c5a042 283 /*!
Wayne Roberts 0:6b3ac9c5a042 284 * \brief MCPS-Confirm primitive
Wayne Roberts 0:6b3ac9c5a042 285 *
Wayne Roberts 0:6b3ac9c5a042 286 * \param [OUT] MCPS-Confirm parameters
Wayne Roberts 0:6b3ac9c5a042 287 */
Wayne Roberts 0:6b3ac9c5a042 288 void (* const MacMcpsConfirm )( const McpsConfirm_t *McpsConfirm );
Wayne Roberts 0:6b3ac9c5a042 289 /*!
Wayne Roberts 0:6b3ac9c5a042 290 * \brief MCPS-Indication primitive
Wayne Roberts 0:6b3ac9c5a042 291 *
Wayne Roberts 0:6b3ac9c5a042 292 * \param [OUT] MCPS-Indication parameters
Wayne Roberts 0:6b3ac9c5a042 293 */
Wayne Roberts 0:6b3ac9c5a042 294 void (* const MacMcpsIndication )( const McpsIndication_t *McpsIndication );
Wayne Roberts 0:6b3ac9c5a042 295 /*!
Wayne Roberts 0:6b3ac9c5a042 296 * \brief MLME-Confirm primitive
Wayne Roberts 0:6b3ac9c5a042 297 *
Wayne Roberts 0:6b3ac9c5a042 298 * \param [OUT] MLME-Confirm parameters
Wayne Roberts 0:6b3ac9c5a042 299 */
Wayne Roberts 0:6b3ac9c5a042 300 void (* const MacMlmeConfirm )( const MlmeConfirm_t *MlmeConfirm );
Wayne Roberts 0:6b3ac9c5a042 301 /*!
Wayne Roberts 0:6b3ac9c5a042 302 * \brief MLME-Indication primitive
Wayne Roberts 0:6b3ac9c5a042 303 *
Wayne Roberts 0:6b3ac9c5a042 304 * \param [OUT] MLME-Indication parameters
Wayne Roberts 0:6b3ac9c5a042 305 */
Wayne Roberts 0:6b3ac9c5a042 306 void (* const MacMlmeIndication )( const MlmeIndication_t *MlmeIndication );
Wayne Roberts 0:6b3ac9c5a042 307 } LoRaMacPrimitives_t;
Wayne Roberts 0:6b3ac9c5a042 308
Wayne Roberts 0:6b3ac9c5a042 309 typedef struct sLoRaMacCallback
Wayne Roberts 0:6b3ac9c5a042 310 {
Wayne Roberts 0:6b3ac9c5a042 311 /*!
Wayne Roberts 0:6b3ac9c5a042 312 * \brief Measures the battery level
Wayne Roberts 0:6b3ac9c5a042 313 *
Wayne Roberts 0:6b3ac9c5a042 314 * \retval Battery level [0: node is connected to an external
Wayne Roberts 0:6b3ac9c5a042 315 * power source, 1..254: battery level, where 1 is the minimum
Wayne Roberts 0:6b3ac9c5a042 316 * and 254 is the maximum value, 255: the node was not able
Wayne Roberts 0:6b3ac9c5a042 317 * to measure the battery level]
Wayne Roberts 0:6b3ac9c5a042 318 */
Wayne Roberts 0:6b3ac9c5a042 319 uint8_t (* const GetBatteryLevel )( void );
Wayne Roberts 0:6b3ac9c5a042 320 /*!
Wayne Roberts 0:6b3ac9c5a042 321 * \brief Measures the temperature level
Wayne Roberts 0:6b3ac9c5a042 322 *
Wayne Roberts 0:6b3ac9c5a042 323 * \retval Temperature level
Wayne Roberts 0:6b3ac9c5a042 324 */
Wayne Roberts 0:6b3ac9c5a042 325 float (* const GetTemperatureLevel )( void );
Wayne Roberts 0:6b3ac9c5a042 326 } LoRaMacCallback_t;
Wayne Roberts 0:6b3ac9c5a042 327
Wayne Roberts 0:6b3ac9c5a042 328 LoRaMacStatus_t LoRaMacInitialization( const LoRaMacPrimitives_t *primitives, const LoRaMacCallback_t *callbacks );
Wayne Roberts 0:6b3ac9c5a042 329 us_timestamp_t LoRaMacReadTimer(void);
Wayne Roberts 0:6b3ac9c5a042 330 LoRaMacStatus_t LoRaMacQueryTxPossible(uint8_t size, LoRaMacTxInfo_t* txInfo);
Wayne Roberts 0:6b3ac9c5a042 331 LoRaMacStatus_t LoRaMacMcpsRequest( McpsReq_t *mcpsRequest );
Wayne Roberts 0:6b3ac9c5a042 332 LoRaMacStatus_t LoRaMacMibGetRequestConfirm( MibRequestConfirm_t *mibGet );
Wayne Roberts 0:6b3ac9c5a042 333 LoRaMacStatus_t LoRaMacMlmeRequest( const MlmeReq_t *mlmeRequest );
Wayne Roberts 0:6b3ac9c5a042 334 LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSet );
Wayne Roberts 0:6b3ac9c5a042 335 LoRaMacStatus_t LoRaMacChannelAdd( uint8_t id, ChannelParams_t params );
Wayne Roberts 0:6b3ac9c5a042 336 void LoRaMacPrintStatus(void);
Wayne Roberts 0:6b3ac9c5a042 337 uint32_t get_fcntdwn(bool);
Wayne Roberts 0:6b3ac9c5a042 338 int8_t LoRaMacGetRxSlot(void);
Wayne Roberts 0:6b3ac9c5a042 339
Wayne Roberts 0:6b3ac9c5a042 340 #endif /* _LORAMAC_H_ */