Ivano Calabrese / LoRaWAN-lib-st-murata

Dependents:   DISCO-L072CZ-LRWAN1-base

Fork of LoRaWAN-lib by Semtech

Committer:
alphaemmeo
Date:
Mon Dec 04 14:21:26 2017 +0000
Revision:
11:5b3e495baefb
Parent:
10:1ac668ce2b15
base test

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mluis 0:91d1a7783bb9 1 /*
mluis 0:91d1a7783bb9 2 / _____) _ | |
mluis 0:91d1a7783bb9 3 ( (____ _____ ____ _| |_ _____ ____| |__
mluis 0:91d1a7783bb9 4 \____ \| ___ | (_ _) ___ |/ ___) _ \
mluis 0:91d1a7783bb9 5 _____) ) ____| | | || |_| ____( (___| | | |
mluis 0:91d1a7783bb9 6 (______/|_____)_|_|_| \__)_____)\____)_| |_|
mluis 0:91d1a7783bb9 7 (C)2013 Semtech
mluis 2:14a5d6ad92d5 8 ___ _____ _ ___ _ _____ ___ ___ ___ ___
mluis 2:14a5d6ad92d5 9 / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
mluis 2:14a5d6ad92d5 10 \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
mluis 2:14a5d6ad92d5 11 |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
mluis 2:14a5d6ad92d5 12 embedded.connectivity.solutions===============
mluis 0:91d1a7783bb9 13
mluis 0:91d1a7783bb9 14 Description: LoRa MAC layer implementation
mluis 0:91d1a7783bb9 15
mluis 0:91d1a7783bb9 16 License: Revised BSD License, see LICENSE.TXT file include in the project
mluis 0:91d1a7783bb9 17
mluis 2:14a5d6ad92d5 18 Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jäckle ( STACKFORCE )
mluis 0:91d1a7783bb9 19 */
mluis 8:26002607de9c 20 #include <math.h>
mluis 0:91d1a7783bb9 21 #include "board.h"
mluis 0:91d1a7783bb9 22
alphaemmeo 11:5b3e495baefb 23 #include "main.h"
alphaemmeo 11:5b3e495baefb 24
mluis 0:91d1a7783bb9 25 #include "LoRaMacCrypto.h"
mluis 0:91d1a7783bb9 26 #include "LoRaMac.h"
mluis 2:14a5d6ad92d5 27 #include "LoRaMacTest.h"
mluis 0:91d1a7783bb9 28
alphaemmeo 11:5b3e495baefb 29
alphaemmeo 11:5b3e495baefb 30
mluis 0:91d1a7783bb9 31 /*!
mluis 0:91d1a7783bb9 32 * Maximum PHY layer payload size
mluis 0:91d1a7783bb9 33 */
mluis 1:91e4e6c60d1e 34 #define LORAMAC_PHY_MAXPAYLOAD 255
mluis 1:91e4e6c60d1e 35
mluis 1:91e4e6c60d1e 36 /*!
mluis 1:91e4e6c60d1e 37 * Maximum MAC commands buffer size
mluis 1:91e4e6c60d1e 38 */
mluis 1:91e4e6c60d1e 39 #define LORA_MAC_COMMAND_MAX_LENGTH 15
mluis 0:91d1a7783bb9 40
mluis 0:91d1a7783bb9 41 /*!
mluis 4:37c12dbc8dc7 42 * FRMPayload overhead to be used when setting the Radio.SetMaxPayloadLength
mluis 4:37c12dbc8dc7 43 * in RxWindowSetup function.
mluis 4:37c12dbc8dc7 44 * Maximum PHYPayload = MaxPayloadOfDatarate/MaxPayloadOfDatarateRepeater + LORA_MAC_FRMPAYLOAD_OVERHEAD
mluis 4:37c12dbc8dc7 45 */
mluis 4:37c12dbc8dc7 46 #define LORA_MAC_FRMPAYLOAD_OVERHEAD 13 // MHDR(1) + FHDR(7) + Port(1) + MIC(4)
mluis 4:37c12dbc8dc7 47
mluis 4:37c12dbc8dc7 48 /*!
mluis 8:26002607de9c 49 * LoRaMac duty cycle for the back-off procedure during the first hour.
mluis 8:26002607de9c 50 */
mluis 8:26002607de9c 51 #define BACKOFF_DC_1_HOUR 100
mluis 8:26002607de9c 52
mluis 8:26002607de9c 53 /*!
mluis 8:26002607de9c 54 * LoRaMac duty cycle for the back-off procedure during the next 10 hours.
mluis 8:26002607de9c 55 */
mluis 8:26002607de9c 56 #define BACKOFF_DC_10_HOURS 1000
mluis 8:26002607de9c 57
mluis 8:26002607de9c 58 /*!
mluis 8:26002607de9c 59 * LoRaMac duty cycle for the back-off procedure during the next 24 hours.
mluis 8:26002607de9c 60 */
mluis 8:26002607de9c 61 #define BACKOFF_DC_24_HOURS 10000
mluis 8:26002607de9c 62
mluis 8:26002607de9c 63 /*!
mluis 0:91d1a7783bb9 64 * Device IEEE EUI
mluis 0:91d1a7783bb9 65 */
mluis 0:91d1a7783bb9 66 static uint8_t *LoRaMacDevEui;
mluis 0:91d1a7783bb9 67
mluis 0:91d1a7783bb9 68 /*!
mluis 0:91d1a7783bb9 69 * Application IEEE EUI
mluis 0:91d1a7783bb9 70 */
mluis 0:91d1a7783bb9 71 static uint8_t *LoRaMacAppEui;
mluis 0:91d1a7783bb9 72
mluis 0:91d1a7783bb9 73 /*!
mluis 0:91d1a7783bb9 74 * AES encryption/decryption cipher application key
mluis 0:91d1a7783bb9 75 */
mluis 0:91d1a7783bb9 76 static uint8_t *LoRaMacAppKey;
mluis 0:91d1a7783bb9 77
mluis 0:91d1a7783bb9 78 /*!
mluis 0:91d1a7783bb9 79 * AES encryption/decryption cipher network session key
mluis 0:91d1a7783bb9 80 */
mluis 0:91d1a7783bb9 81 static uint8_t LoRaMacNwkSKey[] =
mluis 0:91d1a7783bb9 82 {
mluis 0:91d1a7783bb9 83 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
mluis 0:91d1a7783bb9 84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
mluis 0:91d1a7783bb9 85 };
mluis 0:91d1a7783bb9 86
mluis 0:91d1a7783bb9 87 /*!
mluis 0:91d1a7783bb9 88 * AES encryption/decryption cipher application session key
mluis 0:91d1a7783bb9 89 */
mluis 0:91d1a7783bb9 90 static uint8_t LoRaMacAppSKey[] =
mluis 0:91d1a7783bb9 91 {
mluis 0:91d1a7783bb9 92 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
mluis 0:91d1a7783bb9 93 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
mluis 0:91d1a7783bb9 94 };
mluis 0:91d1a7783bb9 95
mluis 0:91d1a7783bb9 96 /*!
mluis 0:91d1a7783bb9 97 * Device nonce is a random value extracted by issuing a sequence of RSSI
mluis 0:91d1a7783bb9 98 * measurements
mluis 0:91d1a7783bb9 99 */
mluis 0:91d1a7783bb9 100 static uint16_t LoRaMacDevNonce;
mluis 0:91d1a7783bb9 101
mluis 0:91d1a7783bb9 102 /*!
mluis 0:91d1a7783bb9 103 * Network ID ( 3 bytes )
mluis 0:91d1a7783bb9 104 */
mluis 0:91d1a7783bb9 105 static uint32_t LoRaMacNetID;
mluis 0:91d1a7783bb9 106
mluis 0:91d1a7783bb9 107 /*!
mluis 0:91d1a7783bb9 108 * Mote Address
mluis 0:91d1a7783bb9 109 */
mluis 0:91d1a7783bb9 110 static uint32_t LoRaMacDevAddr;
mluis 0:91d1a7783bb9 111
mluis 0:91d1a7783bb9 112 /*!
mluis 2:14a5d6ad92d5 113 * Multicast channels linked list
mluis 0:91d1a7783bb9 114 */
mluis 0:91d1a7783bb9 115 static MulticastParams_t *MulticastChannels = NULL;
mluis 0:91d1a7783bb9 116
mluis 0:91d1a7783bb9 117 /*!
mluis 0:91d1a7783bb9 118 * Actual device class
mluis 0:91d1a7783bb9 119 */
mluis 0:91d1a7783bb9 120 static DeviceClass_t LoRaMacDeviceClass;
mluis 0:91d1a7783bb9 121
mluis 0:91d1a7783bb9 122 /*!
mluis 0:91d1a7783bb9 123 * Indicates if the node is connected to a private or public network
mluis 0:91d1a7783bb9 124 */
mluis 0:91d1a7783bb9 125 static bool PublicNetwork;
mluis 0:91d1a7783bb9 126
mluis 0:91d1a7783bb9 127 /*!
mluis 0:91d1a7783bb9 128 * Indicates if the node supports repeaters
mluis 0:91d1a7783bb9 129 */
mluis 0:91d1a7783bb9 130 static bool RepeaterSupport;
mluis 0:91d1a7783bb9 131
mluis 0:91d1a7783bb9 132 /*!
mluis 0:91d1a7783bb9 133 * Buffer containing the data to be sent or received.
mluis 0:91d1a7783bb9 134 */
mluis 0:91d1a7783bb9 135 static uint8_t LoRaMacBuffer[LORAMAC_PHY_MAXPAYLOAD];
mluis 0:91d1a7783bb9 136
mluis 0:91d1a7783bb9 137 /*!
mluis 0:91d1a7783bb9 138 * Length of packet in LoRaMacBuffer
mluis 0:91d1a7783bb9 139 */
mluis 0:91d1a7783bb9 140 static uint16_t LoRaMacBufferPktLen = 0;
mluis 0:91d1a7783bb9 141
mluis 0:91d1a7783bb9 142 /*!
mluis 8:26002607de9c 143 * Length of the payload in LoRaMacBuffer
mluis 8:26002607de9c 144 */
mluis 8:26002607de9c 145 static uint8_t LoRaMacTxPayloadLen = 0;
mluis 8:26002607de9c 146
mluis 8:26002607de9c 147 /*!
mluis 0:91d1a7783bb9 148 * Buffer containing the upper layer data.
mluis 0:91d1a7783bb9 149 */
mluis 0:91d1a7783bb9 150 static uint8_t LoRaMacRxPayload[LORAMAC_PHY_MAXPAYLOAD];
mluis 0:91d1a7783bb9 151
mluis 0:91d1a7783bb9 152 /*!
mluis 0:91d1a7783bb9 153 * LoRaMAC frame counter. Each time a packet is sent the counter is incremented.
mluis 0:91d1a7783bb9 154 * Only the 16 LSB bits are sent
mluis 0:91d1a7783bb9 155 */
mluis 8:26002607de9c 156 static uint32_t UpLinkCounter = 0;
mluis 0:91d1a7783bb9 157
mluis 0:91d1a7783bb9 158 /*!
mluis 0:91d1a7783bb9 159 * LoRaMAC frame counter. Each time a packet is received the counter is incremented.
mluis 0:91d1a7783bb9 160 * Only the 16 LSB bits are received
mluis 0:91d1a7783bb9 161 */
mluis 0:91d1a7783bb9 162 static uint32_t DownLinkCounter = 0;
mluis 0:91d1a7783bb9 163
mluis 0:91d1a7783bb9 164 /*!
mluis 0:91d1a7783bb9 165 * IsPacketCounterFixed enables the MIC field tests by fixing the
mluis 0:91d1a7783bb9 166 * UpLinkCounter value
mluis 0:91d1a7783bb9 167 */
mluis 0:91d1a7783bb9 168 static bool IsUpLinkCounterFixed = false;
mluis 0:91d1a7783bb9 169
mluis 0:91d1a7783bb9 170 /*!
mluis 0:91d1a7783bb9 171 * Used for test purposes. Disables the opening of the reception windows.
mluis 0:91d1a7783bb9 172 */
mluis 0:91d1a7783bb9 173 static bool IsRxWindowsEnabled = true;
mluis 0:91d1a7783bb9 174
mluis 0:91d1a7783bb9 175 /*!
mluis 0:91d1a7783bb9 176 * Indicates if the MAC layer has already joined a network.
mluis 0:91d1a7783bb9 177 */
mluis 0:91d1a7783bb9 178 static bool IsLoRaMacNetworkJoined = false;
mluis 0:91d1a7783bb9 179
mluis 0:91d1a7783bb9 180 /*!
mluis 0:91d1a7783bb9 181 * LoRaMac ADR control status
mluis 0:91d1a7783bb9 182 */
mluis 0:91d1a7783bb9 183 static bool AdrCtrlOn = false;
mluis 0:91d1a7783bb9 184
mluis 0:91d1a7783bb9 185 /*!
mluis 0:91d1a7783bb9 186 * Counts the number of missed ADR acknowledgements
mluis 0:91d1a7783bb9 187 */
mluis 0:91d1a7783bb9 188 static uint32_t AdrAckCounter = 0;
mluis 0:91d1a7783bb9 189
mluis 0:91d1a7783bb9 190 /*!
mluis 0:91d1a7783bb9 191 * If the node has sent a FRAME_TYPE_DATA_CONFIRMED_UP this variable indicates
mluis 0:91d1a7783bb9 192 * if the nodes needs to manage the server acknowledgement.
mluis 0:91d1a7783bb9 193 */
mluis 0:91d1a7783bb9 194 static bool NodeAckRequested = false;
mluis 0:91d1a7783bb9 195
mluis 0:91d1a7783bb9 196 /*!
mluis 0:91d1a7783bb9 197 * If the server has sent a FRAME_TYPE_DATA_CONFIRMED_DOWN this variable indicates
mluis 0:91d1a7783bb9 198 * if the ACK bit must be set for the next transmission
mluis 0:91d1a7783bb9 199 */
mluis 0:91d1a7783bb9 200 static bool SrvAckRequested = false;
mluis 0:91d1a7783bb9 201
mluis 0:91d1a7783bb9 202 /*!
mluis 0:91d1a7783bb9 203 * Indicates if the MAC layer wants to send MAC commands
mluis 0:91d1a7783bb9 204 */
mluis 0:91d1a7783bb9 205 static bool MacCommandsInNextTx = false;
mluis 0:91d1a7783bb9 206
mluis 0:91d1a7783bb9 207 /*!
mluis 0:91d1a7783bb9 208 * Contains the current MacCommandsBuffer index
mluis 0:91d1a7783bb9 209 */
mluis 0:91d1a7783bb9 210 static uint8_t MacCommandsBufferIndex = 0;
mluis 0:91d1a7783bb9 211
mluis 0:91d1a7783bb9 212 /*!
mluis 7:c16969e0f70f 213 * Contains the current MacCommandsBuffer index for MAC commands to repeat
mluis 7:c16969e0f70f 214 */
mluis 7:c16969e0f70f 215 static uint8_t MacCommandsBufferToRepeatIndex = 0;
mluis 7:c16969e0f70f 216
mluis 7:c16969e0f70f 217 /*!
mluis 0:91d1a7783bb9 218 * Buffer containing the MAC layer commands
mluis 0:91d1a7783bb9 219 */
mluis 1:91e4e6c60d1e 220 static uint8_t MacCommandsBuffer[LORA_MAC_COMMAND_MAX_LENGTH];
mluis 0:91d1a7783bb9 221
mluis 7:c16969e0f70f 222 /*!
mluis 7:c16969e0f70f 223 * Buffer containing the MAC layer commands which must be repeated
mluis 7:c16969e0f70f 224 */
mluis 7:c16969e0f70f 225 static uint8_t MacCommandsBufferToRepeat[LORA_MAC_COMMAND_MAX_LENGTH];
mluis 7:c16969e0f70f 226
mluis 0:91d1a7783bb9 227 #if defined( USE_BAND_433 )
mluis 0:91d1a7783bb9 228 /*!
mluis 0:91d1a7783bb9 229 * Data rates table definition
mluis 0:91d1a7783bb9 230 */
mluis 0:91d1a7783bb9 231 const uint8_t Datarates[] = { 12, 11, 10, 9, 8, 7, 7, 50 };
mluis 0:91d1a7783bb9 232
mluis 0:91d1a7783bb9 233 /*!
mluis 8:26002607de9c 234 * Bandwidths table definition in Hz
mluis 8:26002607de9c 235 */
mluis 8:26002607de9c 236 const uint32_t Bandwidths[] = { 125e3, 125e3, 125e3, 125e3, 125e3, 125e3, 250e3, 0 };
mluis 8:26002607de9c 237
mluis 8:26002607de9c 238 /*!
mluis 0:91d1a7783bb9 239 * Maximum payload with respect to the datarate index. Cannot operate with repeater.
mluis 0:91d1a7783bb9 240 */
mluis 8:26002607de9c 241 const uint8_t MaxPayloadOfDatarate[] = { 51, 51, 51, 115, 242, 242, 242, 242 };
mluis 0:91d1a7783bb9 242
mluis 0:91d1a7783bb9 243 /*!
mluis 0:91d1a7783bb9 244 * Maximum payload with respect to the datarate index. Can operate with repeater.
mluis 0:91d1a7783bb9 245 */
mluis 8:26002607de9c 246 const uint8_t MaxPayloadOfDatarateRepeater[] = { 51, 51, 51, 115, 222, 222, 222, 222 };
mluis 0:91d1a7783bb9 247
mluis 0:91d1a7783bb9 248 /*!
mluis 0:91d1a7783bb9 249 * Tx output powers table definition
mluis 0:91d1a7783bb9 250 */
mluis 8:26002607de9c 251 const int8_t TxPowers[] = { 10, 7, 4, 1, -2, -5 };
mluis 0:91d1a7783bb9 252
mluis 0:91d1a7783bb9 253 /*!
mluis 0:91d1a7783bb9 254 * LoRaMac bands
mluis 0:91d1a7783bb9 255 */
mluis 0:91d1a7783bb9 256 static Band_t Bands[LORA_MAX_NB_BANDS] =
mluis 0:91d1a7783bb9 257 {
mluis 0:91d1a7783bb9 258 BAND0,
mluis 0:91d1a7783bb9 259 };
mluis 0:91d1a7783bb9 260
mluis 0:91d1a7783bb9 261 /*!
mluis 0:91d1a7783bb9 262 * LoRaMAC channels
mluis 0:91d1a7783bb9 263 */
mluis 0:91d1a7783bb9 264 static ChannelParams_t Channels[LORA_MAX_NB_CHANNELS] =
mluis 0:91d1a7783bb9 265 {
mluis 0:91d1a7783bb9 266 LC1,
mluis 0:91d1a7783bb9 267 LC2,
mluis 0:91d1a7783bb9 268 LC3,
mluis 0:91d1a7783bb9 269 };
mluis 8:26002607de9c 270 #elif defined( USE_BAND_470 )
mluis 8:26002607de9c 271
mluis 8:26002607de9c 272 /*!
mluis 8:26002607de9c 273 * Data rates table definition
mluis 8:26002607de9c 274 */
mluis 8:26002607de9c 275 const uint8_t Datarates[] = { 12, 11, 10, 9, 8, 7 };
mluis 8:26002607de9c 276
mluis 8:26002607de9c 277 /*!
mluis 8:26002607de9c 278 * Bandwidths table definition in Hz
mluis 8:26002607de9c 279 */
mluis 8:26002607de9c 280 const uint32_t Bandwidths[] = { 125e3, 125e3, 125e3, 125e3, 125e3, 125e3 };
mluis 8:26002607de9c 281
mluis 8:26002607de9c 282 /*!
mluis 8:26002607de9c 283 * Maximum payload with respect to the datarate index. Cannot operate with repeater.
mluis 8:26002607de9c 284 */
mluis 8:26002607de9c 285 const uint8_t MaxPayloadOfDatarate[] = { 51, 51, 51, 115, 222, 222 };
mluis 8:26002607de9c 286
mluis 8:26002607de9c 287 /*!
mluis 8:26002607de9c 288 * Maximum payload with respect to the datarate index. Can operate with repeater.
mluis 8:26002607de9c 289 */
mluis 8:26002607de9c 290 const uint8_t MaxPayloadOfDatarateRepeater[] = { 51, 51, 51, 115, 222, 222 };
mluis 8:26002607de9c 291
mluis 8:26002607de9c 292 /*!
mluis 8:26002607de9c 293 * Tx output powers table definition
mluis 8:26002607de9c 294 */
mluis 8:26002607de9c 295 const int8_t TxPowers[] = { 17, 16, 14, 12, 10, 7, 5, 2 };
mluis 8:26002607de9c 296
mluis 8:26002607de9c 297 /*!
mluis 8:26002607de9c 298 * LoRaMac bands
mluis 8:26002607de9c 299 */
mluis 8:26002607de9c 300 static Band_t Bands[LORA_MAX_NB_BANDS] =
mluis 8:26002607de9c 301 {
mluis 8:26002607de9c 302 BAND0,
mluis 8:26002607de9c 303 };
mluis 8:26002607de9c 304
mluis 8:26002607de9c 305 /*!
mluis 8:26002607de9c 306 * LoRaMAC channels
mluis 8:26002607de9c 307 */
mluis 8:26002607de9c 308 static ChannelParams_t Channels[LORA_MAX_NB_CHANNELS];
mluis 8:26002607de9c 309
mluis 8:26002607de9c 310 /*!
mluis 8:26002607de9c 311 * Defines the first channel for RX window 1 for CN470 band
mluis 8:26002607de9c 312 */
mluis 8:26002607de9c 313 #define LORAMAC_FIRST_RX1_CHANNEL ( (uint32_t) 500.3e6 )
mluis 8:26002607de9c 314
mluis 8:26002607de9c 315 /*!
mluis 8:26002607de9c 316 * Defines the last channel for RX window 1 for CN470 band
mluis 8:26002607de9c 317 */
mluis 8:26002607de9c 318 #define LORAMAC_LAST_RX1_CHANNEL ( (uint32_t) 509.7e6 )
mluis 8:26002607de9c 319
mluis 8:26002607de9c 320 /*!
mluis 8:26002607de9c 321 * Defines the step width of the channels for RX window 1
mluis 8:26002607de9c 322 */
mluis 8:26002607de9c 323 #define LORAMAC_STEPWIDTH_RX1_CHANNEL ( (uint32_t) 200e3 )
mluis 8:26002607de9c 324
mluis 0:91d1a7783bb9 325 #elif defined( USE_BAND_780 )
mluis 0:91d1a7783bb9 326 /*!
mluis 0:91d1a7783bb9 327 * Data rates table definition
mluis 0:91d1a7783bb9 328 */
mluis 0:91d1a7783bb9 329 const uint8_t Datarates[] = { 12, 11, 10, 9, 8, 7, 7, 50 };
mluis 0:91d1a7783bb9 330
mluis 0:91d1a7783bb9 331 /*!
mluis 8:26002607de9c 332 * Bandwidths table definition in Hz
mluis 8:26002607de9c 333 */
mluis 8:26002607de9c 334 const uint32_t Bandwidths[] = { 125e3, 125e3, 125e3, 125e3, 125e3, 125e3, 250e3, 0 };
mluis 8:26002607de9c 335
mluis 8:26002607de9c 336 /*!
mluis 0:91d1a7783bb9 337 * Maximum payload with respect to the datarate index. Cannot operate with repeater.
mluis 0:91d1a7783bb9 338 */
mluis 8:26002607de9c 339 const uint8_t MaxPayloadOfDatarate[] = { 51, 51, 51, 115, 242, 242, 242, 242 };
mluis 0:91d1a7783bb9 340
mluis 0:91d1a7783bb9 341 /*!
mluis 0:91d1a7783bb9 342 * Maximum payload with respect to the datarate index. Can operate with repeater.
mluis 0:91d1a7783bb9 343 */
mluis 8:26002607de9c 344 const uint8_t MaxPayloadOfDatarateRepeater[] = { 51, 51, 51, 115, 222, 222, 222, 222 };
mluis 0:91d1a7783bb9 345
mluis 0:91d1a7783bb9 346 /*!
mluis 0:91d1a7783bb9 347 * Tx output powers table definition
mluis 0:91d1a7783bb9 348 */
mluis 8:26002607de9c 349 const int8_t TxPowers[] = { 10, 7, 4, 1, -2, -5 };
mluis 0:91d1a7783bb9 350
mluis 0:91d1a7783bb9 351 /*!
mluis 0:91d1a7783bb9 352 * LoRaMac bands
mluis 0:91d1a7783bb9 353 */
mluis 0:91d1a7783bb9 354 static Band_t Bands[LORA_MAX_NB_BANDS] =
mluis 0:91d1a7783bb9 355 {
mluis 0:91d1a7783bb9 356 BAND0,
mluis 0:91d1a7783bb9 357 };
mluis 0:91d1a7783bb9 358
mluis 0:91d1a7783bb9 359 /*!
mluis 0:91d1a7783bb9 360 * LoRaMAC channels
mluis 0:91d1a7783bb9 361 */
mluis 0:91d1a7783bb9 362 static ChannelParams_t Channels[LORA_MAX_NB_CHANNELS] =
mluis 0:91d1a7783bb9 363 {
mluis 0:91d1a7783bb9 364 LC1,
mluis 0:91d1a7783bb9 365 LC2,
mluis 0:91d1a7783bb9 366 LC3,
mluis 0:91d1a7783bb9 367 };
mluis 0:91d1a7783bb9 368 #elif defined( USE_BAND_868 )
mluis 0:91d1a7783bb9 369 /*!
mluis 0:91d1a7783bb9 370 * Data rates table definition
mluis 0:91d1a7783bb9 371 */
mluis 0:91d1a7783bb9 372 const uint8_t Datarates[] = { 12, 11, 10, 9, 8, 7, 7, 50 };
mluis 0:91d1a7783bb9 373
mluis 0:91d1a7783bb9 374 /*!
mluis 8:26002607de9c 375 * Bandwidths table definition in Hz
mluis 8:26002607de9c 376 */
mluis 8:26002607de9c 377 const uint32_t Bandwidths[] = { 125e3, 125e3, 125e3, 125e3, 125e3, 125e3, 250e3, 0 };
mluis 8:26002607de9c 378
mluis 8:26002607de9c 379 /*!
mluis 0:91d1a7783bb9 380 * Maximum payload with respect to the datarate index. Cannot operate with repeater.
mluis 0:91d1a7783bb9 381 */
mluis 0:91d1a7783bb9 382 const uint8_t MaxPayloadOfDatarate[] = { 51, 51, 51, 115, 242, 242, 242, 242 };
mluis 0:91d1a7783bb9 383
mluis 0:91d1a7783bb9 384 /*!
mluis 0:91d1a7783bb9 385 * Maximum payload with respect to the datarate index. Can operate with repeater.
mluis 0:91d1a7783bb9 386 */
mluis 0:91d1a7783bb9 387 const uint8_t MaxPayloadOfDatarateRepeater[] = { 51, 51, 51, 115, 222, 222, 222, 222 };
mluis 0:91d1a7783bb9 388
mluis 0:91d1a7783bb9 389 /*!
mluis 0:91d1a7783bb9 390 * Tx output powers table definition
mluis 0:91d1a7783bb9 391 */
mluis 0:91d1a7783bb9 392 const int8_t TxPowers[] = { 20, 14, 11, 8, 5, 2 };
mluis 0:91d1a7783bb9 393
mluis 0:91d1a7783bb9 394 /*!
mluis 0:91d1a7783bb9 395 * LoRaMac bands
mluis 0:91d1a7783bb9 396 */
mluis 0:91d1a7783bb9 397 static Band_t Bands[LORA_MAX_NB_BANDS] =
mluis 0:91d1a7783bb9 398 {
mluis 0:91d1a7783bb9 399 BAND0,
mluis 0:91d1a7783bb9 400 BAND1,
mluis 0:91d1a7783bb9 401 BAND2,
mluis 0:91d1a7783bb9 402 BAND3,
mluis 0:91d1a7783bb9 403 BAND4,
mluis 0:91d1a7783bb9 404 };
mluis 0:91d1a7783bb9 405
mluis 0:91d1a7783bb9 406 /*!
mluis 0:91d1a7783bb9 407 * LoRaMAC channels
mluis 0:91d1a7783bb9 408 */
mluis 0:91d1a7783bb9 409 static ChannelParams_t Channels[LORA_MAX_NB_CHANNELS] =
mluis 0:91d1a7783bb9 410 {
mluis 0:91d1a7783bb9 411 LC1,
mluis 0:91d1a7783bb9 412 LC2,
mluis 0:91d1a7783bb9 413 LC3,
mluis 0:91d1a7783bb9 414 };
mluis 0:91d1a7783bb9 415 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 0:91d1a7783bb9 416 /*!
mluis 0:91d1a7783bb9 417 * Data rates table definition
mluis 0:91d1a7783bb9 418 */
mluis 0:91d1a7783bb9 419 const uint8_t Datarates[] = { 10, 9, 8, 7, 8, 0, 0, 0, 12, 11, 10, 9, 8, 7, 0, 0 };
mluis 0:91d1a7783bb9 420
mluis 0:91d1a7783bb9 421 /*!
mluis 8:26002607de9c 422 * Bandwidths table definition in Hz
mluis 8:26002607de9c 423 */
mluis 8:26002607de9c 424 const uint32_t Bandwidths[] = { 125e3, 125e3, 125e3, 125e3, 500e3, 0, 0, 0, 500e3, 500e3, 500e3, 500e3, 500e3, 500e3, 0, 0 };
mluis 8:26002607de9c 425
mluis 8:26002607de9c 426 /*!
mluis 0:91d1a7783bb9 427 * Up/Down link data rates offset definition
mluis 0:91d1a7783bb9 428 */
mluis 8:26002607de9c 429 const int8_t DatarateOffsets[5][4] =
mluis 0:91d1a7783bb9 430 {
mluis 0:91d1a7783bb9 431 { DR_10, DR_9 , DR_8 , DR_8 }, // DR_0
mluis 0:91d1a7783bb9 432 { DR_11, DR_10, DR_9 , DR_8 }, // DR_1
mluis 0:91d1a7783bb9 433 { DR_12, DR_11, DR_10, DR_9 }, // DR_2
mluis 0:91d1a7783bb9 434 { DR_13, DR_12, DR_11, DR_10 }, // DR_3
mluis 0:91d1a7783bb9 435 { DR_13, DR_13, DR_12, DR_11 }, // DR_4
mluis 0:91d1a7783bb9 436 };
mluis 0:91d1a7783bb9 437
mluis 0:91d1a7783bb9 438 /*!
mluis 0:91d1a7783bb9 439 * Maximum payload with respect to the datarate index. Cannot operate with repeater.
mluis 0:91d1a7783bb9 440 */
mluis 7:c16969e0f70f 441 const uint8_t MaxPayloadOfDatarate[] = { 11, 53, 125, 242, 242, 0, 0, 0, 53, 129, 242, 242, 242, 242, 0, 0 };
mluis 0:91d1a7783bb9 442
mluis 0:91d1a7783bb9 443 /*!
mluis 0:91d1a7783bb9 444 * Maximum payload with respect to the datarate index. Can operate with repeater.
mluis 0:91d1a7783bb9 445 */
mluis 7:c16969e0f70f 446 const uint8_t MaxPayloadOfDatarateRepeater[] = { 11, 53, 125, 242, 242, 0, 0, 0, 33, 109, 222, 222, 222, 222, 0, 0 };
mluis 0:91d1a7783bb9 447
mluis 0:91d1a7783bb9 448 /*!
mluis 0:91d1a7783bb9 449 * Tx output powers table definition
mluis 0:91d1a7783bb9 450 */
mluis 0:91d1a7783bb9 451 const int8_t TxPowers[] = { 30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10 };
mluis 0:91d1a7783bb9 452
mluis 0:91d1a7783bb9 453 /*!
mluis 0:91d1a7783bb9 454 * LoRaMac bands
mluis 0:91d1a7783bb9 455 */
mluis 0:91d1a7783bb9 456 static Band_t Bands[LORA_MAX_NB_BANDS] =
mluis 0:91d1a7783bb9 457 {
mluis 0:91d1a7783bb9 458 BAND0,
mluis 0:91d1a7783bb9 459 };
mluis 0:91d1a7783bb9 460
mluis 0:91d1a7783bb9 461 /*!
mluis 0:91d1a7783bb9 462 * LoRaMAC channels
mluis 0:91d1a7783bb9 463 */
mluis 0:91d1a7783bb9 464 static ChannelParams_t Channels[LORA_MAX_NB_CHANNELS];
mluis 0:91d1a7783bb9 465
mluis 2:14a5d6ad92d5 466 /*!
mluis 2:14a5d6ad92d5 467 * Contains the channels which remain to be applied.
mluis 2:14a5d6ad92d5 468 */
mluis 2:14a5d6ad92d5 469 static uint16_t ChannelsMaskRemaining[6];
mluis 7:c16969e0f70f 470
mluis 7:c16969e0f70f 471 /*!
mluis 8:26002607de9c 472 * Defines the first channel for RX window 1 for US band
mluis 7:c16969e0f70f 473 */
mluis 8:26002607de9c 474 #define LORAMAC_FIRST_RX1_CHANNEL ( (uint32_t) 923.3e6 )
mluis 7:c16969e0f70f 475
mluis 7:c16969e0f70f 476 /*!
mluis 8:26002607de9c 477 * Defines the last channel for RX window 1 for US band
mluis 7:c16969e0f70f 478 */
mluis 8:26002607de9c 479 #define LORAMAC_LAST_RX1_CHANNEL ( (uint32_t) 927.5e6 )
mluis 7:c16969e0f70f 480
mluis 7:c16969e0f70f 481 /*!
mluis 8:26002607de9c 482 * Defines the step width of the channels for RX window 1
mluis 7:c16969e0f70f 483 */
mluis 8:26002607de9c 484 #define LORAMAC_STEPWIDTH_RX1_CHANNEL ( (uint32_t) 600e3 )
mluis 7:c16969e0f70f 485
mluis 0:91d1a7783bb9 486 #else
mluis 0:91d1a7783bb9 487 #error "Please define a frequency band in the compiler options."
mluis 0:91d1a7783bb9 488 #endif
mluis 0:91d1a7783bb9 489
mluis 0:91d1a7783bb9 490 /*!
mluis 7:c16969e0f70f 491 * LoRaMac parameters
mluis 0:91d1a7783bb9 492 */
mluis 7:c16969e0f70f 493 LoRaMacParams_t LoRaMacParams;
mluis 0:91d1a7783bb9 494
mluis 0:91d1a7783bb9 495 /*!
mluis 7:c16969e0f70f 496 * LoRaMac default parameters
mluis 0:91d1a7783bb9 497 */
mluis 7:c16969e0f70f 498 LoRaMacParams_t LoRaMacParamsDefaults;
mluis 0:91d1a7783bb9 499
mluis 0:91d1a7783bb9 500 /*!
mluis 0:91d1a7783bb9 501 * Uplink messages repetitions counter
mluis 0:91d1a7783bb9 502 */
mluis 0:91d1a7783bb9 503 static uint8_t ChannelsNbRepCounter = 0;
mluis 0:91d1a7783bb9 504
mluis 0:91d1a7783bb9 505 /*!
mluis 0:91d1a7783bb9 506 * Maximum duty cycle
mluis 0:91d1a7783bb9 507 * \remark Possibility to shutdown the device.
mluis 0:91d1a7783bb9 508 */
mluis 0:91d1a7783bb9 509 static uint8_t MaxDCycle = 0;
mluis 0:91d1a7783bb9 510
mluis 0:91d1a7783bb9 511 /*!
mluis 2:14a5d6ad92d5 512 * Aggregated duty cycle management
mluis 0:91d1a7783bb9 513 */
mluis 0:91d1a7783bb9 514 static uint16_t AggregatedDCycle;
mluis 0:91d1a7783bb9 515 static TimerTime_t AggregatedLastTxDoneTime;
mluis 0:91d1a7783bb9 516 static TimerTime_t AggregatedTimeOff;
mluis 0:91d1a7783bb9 517
mluis 0:91d1a7783bb9 518 /*!
mluis 0:91d1a7783bb9 519 * Enables/Disables duty cycle management (Test only)
mluis 0:91d1a7783bb9 520 */
mluis 0:91d1a7783bb9 521 static bool DutyCycleOn;
mluis 0:91d1a7783bb9 522
mluis 0:91d1a7783bb9 523 /*!
mluis 0:91d1a7783bb9 524 * Current channel index
mluis 0:91d1a7783bb9 525 */
mluis 0:91d1a7783bb9 526 static uint8_t Channel;
mluis 0:91d1a7783bb9 527
mluis 7:c16969e0f70f 528 /*!
mluis 8:26002607de9c 529 * Stores the time at LoRaMac initialization.
mluis 8:26002607de9c 530 *
mluis 8:26002607de9c 531 * \remark Used for the BACKOFF_DC computation.
mluis 7:c16969e0f70f 532 */
mluis 8:26002607de9c 533 static TimerTime_t LoRaMacInitializationTime = 0;
mluis 4:37c12dbc8dc7 534
mluis 0:91d1a7783bb9 535 /*!
mluis 0:91d1a7783bb9 536 * LoRaMac internal states
mluis 0:91d1a7783bb9 537 */
mluis 2:14a5d6ad92d5 538 enum eLoRaMacState
mluis 0:91d1a7783bb9 539 {
mluis 8:26002607de9c 540 LORAMAC_IDLE = 0x00000000,
mluis 8:26002607de9c 541 LORAMAC_TX_RUNNING = 0x00000001,
mluis 8:26002607de9c 542 LORAMAC_RX = 0x00000002,
mluis 8:26002607de9c 543 LORAMAC_ACK_REQ = 0x00000004,
mluis 8:26002607de9c 544 LORAMAC_ACK_RETRY = 0x00000008,
mluis 8:26002607de9c 545 LORAMAC_TX_DELAYED = 0x00000010,
mluis 8:26002607de9c 546 LORAMAC_TX_CONFIG = 0x00000020,
mluis 8:26002607de9c 547 LORAMAC_RX_ABORT = 0x00000040,
mluis 0:91d1a7783bb9 548 };
mluis 0:91d1a7783bb9 549
mluis 0:91d1a7783bb9 550 /*!
mluis 0:91d1a7783bb9 551 * LoRaMac internal state
mluis 0:91d1a7783bb9 552 */
mluis 8:26002607de9c 553 uint32_t LoRaMacState = LORAMAC_IDLE;
mluis 0:91d1a7783bb9 554
mluis 0:91d1a7783bb9 555 /*!
mluis 0:91d1a7783bb9 556 * LoRaMac timer used to check the LoRaMacState (runs every second)
mluis 0:91d1a7783bb9 557 */
mluis 0:91d1a7783bb9 558 static TimerEvent_t MacStateCheckTimer;
mluis 0:91d1a7783bb9 559
mluis 0:91d1a7783bb9 560 /*!
mluis 0:91d1a7783bb9 561 * LoRaMac upper layer event functions
mluis 0:91d1a7783bb9 562 */
mluis 2:14a5d6ad92d5 563 static LoRaMacPrimitives_t *LoRaMacPrimitives;
mluis 0:91d1a7783bb9 564
mluis 0:91d1a7783bb9 565 /*!
mluis 2:14a5d6ad92d5 566 * LoRaMac upper layer callback functions
mluis 0:91d1a7783bb9 567 */
mluis 2:14a5d6ad92d5 568 static LoRaMacCallback_t *LoRaMacCallbacks;
mluis 0:91d1a7783bb9 569
mluis 0:91d1a7783bb9 570 /*!
mluis 2:14a5d6ad92d5 571 * Radio events function pointer
mluis 0:91d1a7783bb9 572 */
mluis 2:14a5d6ad92d5 573 static RadioEvents_t RadioEvents;
mluis 0:91d1a7783bb9 574
mluis 0:91d1a7783bb9 575 /*!
mluis 0:91d1a7783bb9 576 * LoRaMac duty cycle delayed Tx timer
mluis 0:91d1a7783bb9 577 */
mluis 0:91d1a7783bb9 578 static TimerEvent_t TxDelayedTimer;
mluis 0:91d1a7783bb9 579
mluis 0:91d1a7783bb9 580 /*!
mluis 0:91d1a7783bb9 581 * LoRaMac reception windows timers
mluis 0:91d1a7783bb9 582 */
mluis 0:91d1a7783bb9 583 static TimerEvent_t RxWindowTimer1;
mluis 0:91d1a7783bb9 584 static TimerEvent_t RxWindowTimer2;
mluis 0:91d1a7783bb9 585
mluis 0:91d1a7783bb9 586 /*!
mluis 0:91d1a7783bb9 587 * LoRaMac reception windows delay
mluis 0:91d1a7783bb9 588 * \remark normal frame: RxWindowXDelay = ReceiveDelayX - RADIO_WAKEUP_TIME
mluis 0:91d1a7783bb9 589 * join frame : RxWindowXDelay = JoinAcceptDelayX - RADIO_WAKEUP_TIME
mluis 0:91d1a7783bb9 590 */
mluis 0:91d1a7783bb9 591 static uint32_t RxWindow1Delay;
mluis 0:91d1a7783bb9 592 static uint32_t RxWindow2Delay;
mluis 0:91d1a7783bb9 593
mluis 0:91d1a7783bb9 594 /*!
mluis 8:26002607de9c 595 * Rx window parameters
mluis 8:26002607de9c 596 */
mluis 8:26002607de9c 597 typedef struct
mluis 8:26002607de9c 598 {
mluis 8:26002607de9c 599 int8_t Datarate;
mluis 8:26002607de9c 600 uint8_t Bandwidth;
mluis 8:26002607de9c 601 uint32_t RxWindowTimeout;
mluis 8:26002607de9c 602 int32_t RxOffset;
mluis 8:26002607de9c 603 }RxConfigParams_t;
mluis 8:26002607de9c 604
mluis 8:26002607de9c 605 /*!
mluis 8:26002607de9c 606 * Rx windows params
mluis 8:26002607de9c 607 */
mluis 8:26002607de9c 608 static RxConfigParams_t RxWindowsParams[2];
mluis 8:26002607de9c 609
mluis 8:26002607de9c 610 /*!
mluis 0:91d1a7783bb9 611 * Acknowledge timeout timer. Used for packet retransmissions.
mluis 0:91d1a7783bb9 612 */
mluis 0:91d1a7783bb9 613 static TimerEvent_t AckTimeoutTimer;
mluis 0:91d1a7783bb9 614
mluis 0:91d1a7783bb9 615 /*!
mluis 0:91d1a7783bb9 616 * Number of trials to get a frame acknowledged
mluis 0:91d1a7783bb9 617 */
mluis 0:91d1a7783bb9 618 static uint8_t AckTimeoutRetries = 1;
mluis 0:91d1a7783bb9 619
mluis 0:91d1a7783bb9 620 /*!
mluis 0:91d1a7783bb9 621 * Number of trials to get a frame acknowledged
mluis 0:91d1a7783bb9 622 */
mluis 0:91d1a7783bb9 623 static uint8_t AckTimeoutRetriesCounter = 1;
mluis 0:91d1a7783bb9 624
mluis 0:91d1a7783bb9 625 /*!
mluis 0:91d1a7783bb9 626 * Indicates if the AckTimeout timer has expired or not
mluis 0:91d1a7783bb9 627 */
mluis 0:91d1a7783bb9 628 static bool AckTimeoutRetry = false;
mluis 0:91d1a7783bb9 629
mluis 0:91d1a7783bb9 630 /*!
mluis 0:91d1a7783bb9 631 * Last transmission time on air
mluis 0:91d1a7783bb9 632 */
mluis 0:91d1a7783bb9 633 TimerTime_t TxTimeOnAir = 0;
mluis 0:91d1a7783bb9 634
mluis 0:91d1a7783bb9 635 /*!
mluis 7:c16969e0f70f 636 * Number of trials for the Join Request
mluis 7:c16969e0f70f 637 */
mluis 8:26002607de9c 638 static uint8_t JoinRequestTrials;
mluis 8:26002607de9c 639
mluis 8:26002607de9c 640 /*!
mluis 8:26002607de9c 641 * Maximum number of trials for the Join Request
mluis 8:26002607de9c 642 */
mluis 8:26002607de9c 643 static uint8_t MaxJoinRequestTrials;
mluis 7:c16969e0f70f 644
mluis 7:c16969e0f70f 645 /*!
mluis 2:14a5d6ad92d5 646 * Structure to hold an MCPS indication data.
mluis 2:14a5d6ad92d5 647 */
mluis 2:14a5d6ad92d5 648 static McpsIndication_t McpsIndication;
mluis 2:14a5d6ad92d5 649
mluis 2:14a5d6ad92d5 650 /*!
mluis 2:14a5d6ad92d5 651 * Structure to hold MCPS confirm data.
mluis 2:14a5d6ad92d5 652 */
mluis 2:14a5d6ad92d5 653 static McpsConfirm_t McpsConfirm;
mluis 2:14a5d6ad92d5 654
mluis 2:14a5d6ad92d5 655 /*!
mluis 2:14a5d6ad92d5 656 * Structure to hold MLME confirm data.
mluis 2:14a5d6ad92d5 657 */
mluis 2:14a5d6ad92d5 658 static MlmeConfirm_t MlmeConfirm;
mluis 2:14a5d6ad92d5 659
mluis 2:14a5d6ad92d5 660 /*!
mluis 2:14a5d6ad92d5 661 * Holds the current rx window slot
mluis 2:14a5d6ad92d5 662 */
mluis 2:14a5d6ad92d5 663 static uint8_t RxSlot = 0;
mluis 2:14a5d6ad92d5 664
mluis 2:14a5d6ad92d5 665 /*!
mluis 2:14a5d6ad92d5 666 * LoRaMac tx/rx operation state
mluis 2:14a5d6ad92d5 667 */
mluis 2:14a5d6ad92d5 668 LoRaMacFlags_t LoRaMacFlags;
mluis 2:14a5d6ad92d5 669
mluis 2:14a5d6ad92d5 670 /*!
mluis 2:14a5d6ad92d5 671 * \brief Function to be executed on Radio Tx Done event
mluis 0:91d1a7783bb9 672 */
alphaemmeo 11:5b3e495baefb 673 static void OnRadioTxDone( void *radio, void *userThisPtr, void *userData );
mluis 0:91d1a7783bb9 674
mluis 0:91d1a7783bb9 675 /*!
mluis 3:b9d87593a8ae 676 * \brief This function prepares the MAC to abort the execution of function
mluis 3:b9d87593a8ae 677 * OnRadioRxDone in case of a reception error.
mluis 3:b9d87593a8ae 678 */
mluis 3:b9d87593a8ae 679 static void PrepareRxDoneAbort( void );
mluis 3:b9d87593a8ae 680
mluis 3:b9d87593a8ae 681 /*!
mluis 2:14a5d6ad92d5 682 * \brief Function to be executed on Radio Rx Done event
mluis 0:91d1a7783bb9 683 */
alphaemmeo 11:5b3e495baefb 684 static void OnRadioRxDone( void *radio, void *userThisPtr, void *userData, uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr );
mluis 0:91d1a7783bb9 685
mluis 0:91d1a7783bb9 686 /*!
mluis 2:14a5d6ad92d5 687 * \brief Function executed on Radio Tx Timeout event
mluis 0:91d1a7783bb9 688 */
alphaemmeo 11:5b3e495baefb 689 static void OnRadioTxTimeout( void *radio, void *userThisPtr, void *userData );
mluis 0:91d1a7783bb9 690
mluis 0:91d1a7783bb9 691 /*!
mluis 2:14a5d6ad92d5 692 * \brief Function executed on Radio Rx error event
mluis 0:91d1a7783bb9 693 */
alphaemmeo 11:5b3e495baefb 694 static void OnRadioRxError( void *radio, void *userThisPtr, void *userData );
mluis 0:91d1a7783bb9 695
mluis 0:91d1a7783bb9 696 /*!
mluis 2:14a5d6ad92d5 697 * \brief Function executed on Radio Rx Timeout event
mluis 0:91d1a7783bb9 698 */
alphaemmeo 11:5b3e495baefb 699 static void OnRadioRxTimeout( void *radio, void *userThisPtr, void *userData );
mluis 0:91d1a7783bb9 700
mluis 0:91d1a7783bb9 701 /*!
mluis 2:14a5d6ad92d5 702 * \brief Function executed on Resend Frame timer event.
mluis 0:91d1a7783bb9 703 */
mluis 0:91d1a7783bb9 704 static void OnMacStateCheckTimerEvent( void );
mluis 0:91d1a7783bb9 705
mluis 0:91d1a7783bb9 706 /*!
mluis 2:14a5d6ad92d5 707 * \brief Function executed on duty cycle delayed Tx timer event
mluis 0:91d1a7783bb9 708 */
mluis 0:91d1a7783bb9 709 static void OnTxDelayedTimerEvent( void );
mluis 0:91d1a7783bb9 710
mluis 0:91d1a7783bb9 711 /*!
mluis 2:14a5d6ad92d5 712 * \brief Function executed on first Rx window timer event
mluis 0:91d1a7783bb9 713 */
mluis 0:91d1a7783bb9 714 static void OnRxWindow1TimerEvent( void );
mluis 0:91d1a7783bb9 715
mluis 0:91d1a7783bb9 716 /*!
mluis 2:14a5d6ad92d5 717 * \brief Function executed on second Rx window timer event
mluis 0:91d1a7783bb9 718 */
mluis 0:91d1a7783bb9 719 static void OnRxWindow2TimerEvent( void );
mluis 0:91d1a7783bb9 720
mluis 0:91d1a7783bb9 721 /*!
mluis 2:14a5d6ad92d5 722 * \brief Function executed on AckTimeout timer event
mluis 0:91d1a7783bb9 723 */
mluis 0:91d1a7783bb9 724 static void OnAckTimeoutTimerEvent( void );
mluis 0:91d1a7783bb9 725
mluis 0:91d1a7783bb9 726 /*!
mluis 2:14a5d6ad92d5 727 * \brief Searches and set the next random available channel
mluis 2:14a5d6ad92d5 728 *
mluis 3:b9d87593a8ae 729 * \param [OUT] Time to wait for the next transmission according to the duty
mluis 3:b9d87593a8ae 730 * cycle.
mluis 3:b9d87593a8ae 731 *
mluis 3:b9d87593a8ae 732 * \retval status Function status [1: OK, 0: Unable to find a channel on the
mluis 3:b9d87593a8ae 733 * current datarate]
mluis 2:14a5d6ad92d5 734 */
mluis 3:b9d87593a8ae 735 static bool SetNextChannel( TimerTime_t* time );
mluis 2:14a5d6ad92d5 736
mluis 2:14a5d6ad92d5 737 /*!
mluis 2:14a5d6ad92d5 738 * \brief Initializes and opens the reception window
mluis 2:14a5d6ad92d5 739 *
mluis 2:14a5d6ad92d5 740 * \param [IN] freq window channel frequency
mluis 2:14a5d6ad92d5 741 * \param [IN] datarate window channel datarate
mluis 2:14a5d6ad92d5 742 * \param [IN] bandwidth window channel bandwidth
mluis 2:14a5d6ad92d5 743 * \param [IN] timeout window channel timeout
mluis 8:26002607de9c 744 *
mluis 8:26002607de9c 745 * \retval status Operation status [true: Success, false: Fail]
mluis 0:91d1a7783bb9 746 */
mluis 8:26002607de9c 747 static bool RxWindowSetup( uint32_t freq, int8_t datarate, uint32_t bandwidth, uint16_t timeout, bool rxContinuous );
mluis 2:14a5d6ad92d5 748
mluis 2:14a5d6ad92d5 749 /*!
mluis 7:c16969e0f70f 750 * \brief Verifies if the RX window 2 frequency is in range
mluis 7:c16969e0f70f 751 *
mluis 7:c16969e0f70f 752 * \param [IN] freq window channel frequency
mluis 7:c16969e0f70f 753 *
mluis 7:c16969e0f70f 754 * \retval status Function status [1: OK, 0: Frequency not applicable]
mluis 7:c16969e0f70f 755 */
mluis 7:c16969e0f70f 756 static bool Rx2FreqInRange( uint32_t freq );
mluis 7:c16969e0f70f 757
mluis 7:c16969e0f70f 758 /*!
mluis 2:14a5d6ad92d5 759 * \brief Adds a new MAC command to be sent.
mluis 2:14a5d6ad92d5 760 *
mluis 2:14a5d6ad92d5 761 * \Remark MAC layer internal function
mluis 2:14a5d6ad92d5 762 *
mluis 2:14a5d6ad92d5 763 * \param [in] cmd MAC command to be added
mluis 2:14a5d6ad92d5 764 * [MOTE_MAC_LINK_CHECK_REQ,
mluis 2:14a5d6ad92d5 765 * MOTE_MAC_LINK_ADR_ANS,
mluis 2:14a5d6ad92d5 766 * MOTE_MAC_DUTY_CYCLE_ANS,
mluis 2:14a5d6ad92d5 767 * MOTE_MAC_RX2_PARAM_SET_ANS,
mluis 2:14a5d6ad92d5 768 * MOTE_MAC_DEV_STATUS_ANS
mluis 2:14a5d6ad92d5 769 * MOTE_MAC_NEW_CHANNEL_ANS]
mluis 2:14a5d6ad92d5 770 * \param [in] p1 1st parameter ( optional depends on the command )
mluis 2:14a5d6ad92d5 771 * \param [in] p2 2nd parameter ( optional depends on the command )
mluis 2:14a5d6ad92d5 772 *
mluis 2:14a5d6ad92d5 773 * \retval status Function status [0: OK, 1: Unknown command, 2: Buffer full]
mluis 2:14a5d6ad92d5 774 */
mluis 2:14a5d6ad92d5 775 static LoRaMacStatus_t AddMacCommand( uint8_t cmd, uint8_t p1, uint8_t p2 );
mluis 0:91d1a7783bb9 776
mluis 0:91d1a7783bb9 777 /*!
mluis 7:c16969e0f70f 778 * \brief Parses the MAC commands which must be repeated.
mluis 7:c16969e0f70f 779 *
mluis 7:c16969e0f70f 780 * \Remark MAC layer internal function
mluis 7:c16969e0f70f 781 *
mluis 7:c16969e0f70f 782 * \param [IN] cmdBufIn Buffer which stores the MAC commands to send
mluis 7:c16969e0f70f 783 * \param [IN] length Length of the input buffer to parse
mluis 7:c16969e0f70f 784 * \param [OUT] cmdBufOut Buffer which stores the MAC commands which must be
mluis 7:c16969e0f70f 785 * repeated.
mluis 7:c16969e0f70f 786 *
mluis 7:c16969e0f70f 787 * \retval Size of the MAC commands to repeat.
mluis 7:c16969e0f70f 788 */
mluis 7:c16969e0f70f 789 static uint8_t ParseMacCommandsToRepeat( uint8_t* cmdBufIn, uint8_t length, uint8_t* cmdBufOut );
mluis 7:c16969e0f70f 790
mluis 7:c16969e0f70f 791 /*!
mluis 0:91d1a7783bb9 792 * \brief Validates if the payload fits into the frame, taking the datarate
mluis 0:91d1a7783bb9 793 * into account.
mluis 0:91d1a7783bb9 794 *
mluis 0:91d1a7783bb9 795 * \details Refer to chapter 4.3.2 of the LoRaWAN specification, v1.0
mluis 0:91d1a7783bb9 796 *
mluis 0:91d1a7783bb9 797 * \param lenN Length of the application payload. The length depends on the
mluis 0:91d1a7783bb9 798 * datarate and is region specific
mluis 0:91d1a7783bb9 799 *
mluis 0:91d1a7783bb9 800 * \param datarate Current datarate
mluis 0:91d1a7783bb9 801 *
mluis 2:14a5d6ad92d5 802 * \param fOptsLen Length of the fOpts field
mluis 2:14a5d6ad92d5 803 *
mluis 0:91d1a7783bb9 804 * \retval [false: payload does not fit into the frame, true: payload fits into
mluis 0:91d1a7783bb9 805 * the frame]
mluis 0:91d1a7783bb9 806 */
mluis 2:14a5d6ad92d5 807 static bool ValidatePayloadLength( uint8_t lenN, int8_t datarate, uint8_t fOptsLen );
mluis 0:91d1a7783bb9 808
mluis 4:37c12dbc8dc7 809 /*!
mluis 4:37c12dbc8dc7 810 * \brief Counts the number of bits in a mask.
mluis 4:37c12dbc8dc7 811 *
mluis 4:37c12dbc8dc7 812 * \param [IN] mask A mask from which the function counts the active bits.
mluis 4:37c12dbc8dc7 813 * \param [IN] nbBits The number of bits to check.
mluis 4:37c12dbc8dc7 814 *
mluis 4:37c12dbc8dc7 815 * \retval Number of enabled bits in the mask.
mluis 4:37c12dbc8dc7 816 */
mluis 4:37c12dbc8dc7 817 static uint8_t CountBits( uint16_t mask, uint8_t nbBits );
mluis 4:37c12dbc8dc7 818
mluis 0:91d1a7783bb9 819 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 0:91d1a7783bb9 820 /*!
mluis 0:91d1a7783bb9 821 * \brief Counts the number of enabled 125 kHz channels in the channel mask.
mluis 0:91d1a7783bb9 822 * This function can only be applied to US915 band.
mluis 0:91d1a7783bb9 823 *
mluis 4:37c12dbc8dc7 824 * \param [IN] channelsMask Pointer to the first element of the channel mask
mluis 0:91d1a7783bb9 825 *
mluis 0:91d1a7783bb9 826 * \retval Number of enabled channels in the channel mask
mluis 0:91d1a7783bb9 827 */
mluis 0:91d1a7783bb9 828 static uint8_t CountNbEnabled125kHzChannels( uint16_t *channelsMask );
mluis 4:37c12dbc8dc7 829
mluis 4:37c12dbc8dc7 830 #if defined( USE_BAND_915_HYBRID )
mluis 4:37c12dbc8dc7 831 /*!
mluis 4:37c12dbc8dc7 832 * \brief Validates the correctness of the channel mask for US915, hybrid mode.
mluis 4:37c12dbc8dc7 833 *
mluis 4:37c12dbc8dc7 834 * \param [IN] mask Block definition to set.
mluis 4:37c12dbc8dc7 835 * \param [OUT] channelsMask Pointer to the first element of the channel mask
mluis 4:37c12dbc8dc7 836 */
mluis 8:26002607de9c 837 static void ReenableChannels( uint16_t mask, uint16_t* channelsMask );
mluis 4:37c12dbc8dc7 838
mluis 4:37c12dbc8dc7 839 /*!
mluis 4:37c12dbc8dc7 840 * \brief Validates the correctness of the channel mask for US915, hybrid mode.
mluis 4:37c12dbc8dc7 841 *
mluis 4:37c12dbc8dc7 842 * \param [IN] channelsMask Pointer to the first element of the channel mask
mluis 4:37c12dbc8dc7 843 *
mluis 4:37c12dbc8dc7 844 * \retval [true: channel mask correct, false: channel mask not correct]
mluis 4:37c12dbc8dc7 845 */
mluis 8:26002607de9c 846 static bool ValidateChannelMask( uint16_t* channelsMask );
mluis 4:37c12dbc8dc7 847 #endif
mluis 4:37c12dbc8dc7 848
mluis 0:91d1a7783bb9 849 #endif
mluis 0:91d1a7783bb9 850
mluis 0:91d1a7783bb9 851 /*!
mluis 8:26002607de9c 852 * \brief Validates the correctness of the datarate against the enable channels.
mluis 8:26002607de9c 853 *
mluis 8:26002607de9c 854 * \param [IN] datarate Datarate to be check
mluis 8:26002607de9c 855 * \param [IN] channelsMask Pointer to the first element of the channel mask
mluis 8:26002607de9c 856 *
mluis 8:26002607de9c 857 * \retval [true: datarate can be used, false: datarate can not be used]
mluis 8:26002607de9c 858 */
mluis 8:26002607de9c 859 static bool ValidateDatarate( int8_t datarate, uint16_t* channelsMask );
mluis 8:26002607de9c 860
mluis 8:26002607de9c 861 /*!
mluis 0:91d1a7783bb9 862 * \brief Limits the Tx power according to the number of enabled channels
mluis 0:91d1a7783bb9 863 *
mluis 8:26002607de9c 864 * \param [IN] txPower txPower to limit
mluis 8:26002607de9c 865 * \param [IN] maxBandTxPower Maximum band allowed TxPower
mluis 8:26002607de9c 866 *
mluis 0:91d1a7783bb9 867 * \retval Returns the maximum valid tx power
mluis 0:91d1a7783bb9 868 */
mluis 8:26002607de9c 869 static int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower );
mluis 0:91d1a7783bb9 870
mluis 0:91d1a7783bb9 871 /*!
mluis 2:14a5d6ad92d5 872 * \brief Verifies, if a value is in a given range.
mluis 2:14a5d6ad92d5 873 *
mluis 2:14a5d6ad92d5 874 * \param value Value to verify, if it is in range
mluis 2:14a5d6ad92d5 875 *
mluis 2:14a5d6ad92d5 876 * \param min Minimum possible value
mluis 2:14a5d6ad92d5 877 *
mluis 2:14a5d6ad92d5 878 * \param max Maximum possible value
mluis 2:14a5d6ad92d5 879 *
mluis 2:14a5d6ad92d5 880 * \retval Returns the maximum valid tx power
mluis 2:14a5d6ad92d5 881 */
mluis 2:14a5d6ad92d5 882 static bool ValueInRange( int8_t value, int8_t min, int8_t max );
mluis 2:14a5d6ad92d5 883
mluis 2:14a5d6ad92d5 884 /*!
mluis 2:14a5d6ad92d5 885 * \brief Calculates the next datarate to set, when ADR is on or off
mluis 2:14a5d6ad92d5 886 *
mluis 2:14a5d6ad92d5 887 * \param [IN] adrEnabled Specify whether ADR is on or off
mluis 2:14a5d6ad92d5 888 *
mluis 2:14a5d6ad92d5 889 * \param [IN] updateChannelMask Set to true, if the channel masks shall be updated
mluis 2:14a5d6ad92d5 890 *
mluis 2:14a5d6ad92d5 891 * \param [OUT] datarateOut Reports the datarate which will be used next
mluis 2:14a5d6ad92d5 892 *
mluis 2:14a5d6ad92d5 893 * \retval Returns the state of ADR ack request
mluis 2:14a5d6ad92d5 894 */
mluis 2:14a5d6ad92d5 895 static bool AdrNextDr( bool adrEnabled, bool updateChannelMask, int8_t* datarateOut );
mluis 2:14a5d6ad92d5 896
mluis 2:14a5d6ad92d5 897 /*!
mluis 2:14a5d6ad92d5 898 * \brief Disables channel in a specified channel mask
mluis 2:14a5d6ad92d5 899 *
mluis 2:14a5d6ad92d5 900 * \param [IN] id - Id of the channel
mluis 2:14a5d6ad92d5 901 *
mluis 2:14a5d6ad92d5 902 * \param [IN] mask - Pointer to the channel mask to edit
mluis 0:91d1a7783bb9 903 *
mluis 2:14a5d6ad92d5 904 * \retval [true, if disable was successful, false if not]
mluis 2:14a5d6ad92d5 905 */
mluis 2:14a5d6ad92d5 906 static bool DisableChannelInMask( uint8_t id, uint16_t* mask );
mluis 2:14a5d6ad92d5 907
mluis 2:14a5d6ad92d5 908 /*!
mluis 2:14a5d6ad92d5 909 * \brief Decodes MAC commands in the fOpts field and in the payload
mluis 2:14a5d6ad92d5 910 */
mluis 2:14a5d6ad92d5 911 static void ProcessMacCommands( uint8_t *payload, uint8_t macIndex, uint8_t commandsSize, uint8_t snr );
mluis 2:14a5d6ad92d5 912
mluis 2:14a5d6ad92d5 913 /*!
mluis 2:14a5d6ad92d5 914 * \brief LoRaMAC layer generic send frame
mluis 2:14a5d6ad92d5 915 *
mluis 2:14a5d6ad92d5 916 * \param [IN] macHdr MAC header field
mluis 2:14a5d6ad92d5 917 * \param [IN] fPort MAC payload port
mluis 2:14a5d6ad92d5 918 * \param [IN] fBuffer MAC data buffer to be sent
mluis 2:14a5d6ad92d5 919 * \param [IN] fBufferSize MAC data buffer size
mluis 2:14a5d6ad92d5 920 * \retval status Status of the operation.
mluis 2:14a5d6ad92d5 921 */
mluis 2:14a5d6ad92d5 922 LoRaMacStatus_t Send( LoRaMacHeader_t *macHdr, uint8_t fPort, void *fBuffer, uint16_t fBufferSize );
mluis 2:14a5d6ad92d5 923
mluis 2:14a5d6ad92d5 924 /*!
mluis 2:14a5d6ad92d5 925 * \brief LoRaMAC layer frame buffer initialization
mluis 2:14a5d6ad92d5 926 *
mluis 2:14a5d6ad92d5 927 * \param [IN] macHdr MAC header field
mluis 2:14a5d6ad92d5 928 * \param [IN] fCtrl MAC frame control field
mluis 2:14a5d6ad92d5 929 * \param [IN] fOpts MAC commands buffer
mluis 2:14a5d6ad92d5 930 * \param [IN] fPort MAC payload port
mluis 2:14a5d6ad92d5 931 * \param [IN] fBuffer MAC data buffer to be sent
mluis 2:14a5d6ad92d5 932 * \param [IN] fBufferSize MAC data buffer size
mluis 2:14a5d6ad92d5 933 * \retval status Status of the operation.
mluis 2:14a5d6ad92d5 934 */
mluis 2:14a5d6ad92d5 935 LoRaMacStatus_t PrepareFrame( LoRaMacHeader_t *macHdr, LoRaMacFrameCtrl_t *fCtrl, uint8_t fPort, void *fBuffer, uint16_t fBufferSize );
mluis 2:14a5d6ad92d5 936
mluis 2:14a5d6ad92d5 937 /*
mluis 2:14a5d6ad92d5 938 * \brief Schedules the frame according to the duty cycle
mluis 2:14a5d6ad92d5 939 *
mluis 2:14a5d6ad92d5 940 * \retval Status of the operation
mluis 2:14a5d6ad92d5 941 */
mluis 2:14a5d6ad92d5 942 static LoRaMacStatus_t ScheduleTx( void );
mluis 2:14a5d6ad92d5 943
mluis 4:37c12dbc8dc7 944 /*
mluis 8:26002607de9c 945 * \brief Sets the duty cycle for the join procedure.
mluis 7:c16969e0f70f 946 *
mluis 7:c16969e0f70f 947 * \retval Duty cycle
mluis 7:c16969e0f70f 948 */
mluis 8:26002607de9c 949 static uint16_t JoinDutyCycle( void );
mluis 7:c16969e0f70f 950
mluis 7:c16969e0f70f 951 /*
mluis 4:37c12dbc8dc7 952 * \brief Calculates the back-off time for the band of a channel.
mluis 4:37c12dbc8dc7 953 *
mluis 4:37c12dbc8dc7 954 * \param [IN] channel The last Tx channel index
mluis 4:37c12dbc8dc7 955 */
mluis 4:37c12dbc8dc7 956 static void CalculateBackOff( uint8_t channel );
mluis 4:37c12dbc8dc7 957
mluis 7:c16969e0f70f 958 /*
mluis 7:c16969e0f70f 959 * \brief Alternates the datarate of the channel for the join request.
mluis 7:c16969e0f70f 960 *
mluis 7:c16969e0f70f 961 * \param [IN] nbTrials Number of performed join requests.
mluis 7:c16969e0f70f 962 * \retval Datarate to apply
mluis 7:c16969e0f70f 963 */
mluis 7:c16969e0f70f 964 static int8_t AlternateDatarate( uint16_t nbTrials );
mluis 7:c16969e0f70f 965
mluis 2:14a5d6ad92d5 966 /*!
mluis 2:14a5d6ad92d5 967 * \brief LoRaMAC layer prepared frame buffer transmission with channel specification
mluis 2:14a5d6ad92d5 968 *
mluis 2:14a5d6ad92d5 969 * \remark PrepareFrame must be called at least once before calling this
mluis 2:14a5d6ad92d5 970 * function.
mluis 2:14a5d6ad92d5 971 *
mluis 2:14a5d6ad92d5 972 * \param [IN] channel Channel parameters
mluis 2:14a5d6ad92d5 973 * \retval status Status of the operation.
mluis 0:91d1a7783bb9 974 */
mluis 2:14a5d6ad92d5 975 LoRaMacStatus_t SendFrameOnChannel( ChannelParams_t channel );
mluis 2:14a5d6ad92d5 976
mluis 7:c16969e0f70f 977 /*!
mluis 8:26002607de9c 978 * \brief Sets the radio in continuous transmission mode
mluis 8:26002607de9c 979 *
mluis 8:26002607de9c 980 * \remark Uses the radio parameters set on the previous transmission.
mluis 8:26002607de9c 981 *
mluis 8:26002607de9c 982 * \param [IN] timeout Time in seconds while the radio is kept in continuous wave mode
mluis 8:26002607de9c 983 * \retval status Status of the operation.
mluis 8:26002607de9c 984 */
mluis 8:26002607de9c 985 LoRaMacStatus_t SetTxContinuousWave( uint16_t timeout );
mluis 8:26002607de9c 986
mluis 8:26002607de9c 987 /*!
mluis 8:26002607de9c 988 * \brief Sets the radio in continuous transmission mode
mluis 8:26002607de9c 989 *
mluis 8:26002607de9c 990 * \remark Uses the radio parameters set on the previous transmission.
mluis 8:26002607de9c 991 *
mluis 8:26002607de9c 992 * \param [IN] timeout Time in seconds while the radio is kept in continuous wave mode
mluis 8:26002607de9c 993 * \param [IN] frequency RF frequency to be set.
mluis 8:26002607de9c 994 * \param [IN] power RF ouptput power to be set.
mluis 8:26002607de9c 995 * \retval status Status of the operation.
mluis 8:26002607de9c 996 */
mluis 8:26002607de9c 997 LoRaMacStatus_t SetTxContinuousWave1( uint16_t timeout, uint32_t frequency, uint8_t power );
mluis 8:26002607de9c 998
mluis 8:26002607de9c 999 /*!
mluis 7:c16969e0f70f 1000 * \brief Resets MAC specific parameters to default
mluis 7:c16969e0f70f 1001 */
mluis 7:c16969e0f70f 1002 static void ResetMacParameters( void );
mluis 2:14a5d6ad92d5 1003
mluis 8:26002607de9c 1004 /*
mluis 8:26002607de9c 1005 * Rx window precise timing
mluis 8:26002607de9c 1006 *
mluis 8:26002607de9c 1007 * For more details please consult the following document, chapter 3.1.2.
mluis 8:26002607de9c 1008 * http://www.semtech.com/images/datasheet/SX1272_settings_for_LoRaWAN_v2.0.pdf
mluis 8:26002607de9c 1009 * or
mluis 8:26002607de9c 1010 * http://www.semtech.com/images/datasheet/SX1276_settings_for_LoRaWAN_v2.0.pdf
mluis 8:26002607de9c 1011 *
mluis 8:26002607de9c 1012 * Downlink start: T = Tx + 1s (+/- 20 us)
mluis 8:26002607de9c 1013 * |
mluis 8:26002607de9c 1014 * TRxEarly | TRxLate
mluis 8:26002607de9c 1015 * | | |
mluis 8:26002607de9c 1016 * | | +---+---+---+---+---+---+---+---+
mluis 8:26002607de9c 1017 * | | | Latest Rx window |
mluis 8:26002607de9c 1018 * | | +---+---+---+---+---+---+---+---+
mluis 8:26002607de9c 1019 * | | |
mluis 8:26002607de9c 1020 * +---+---+---+---+---+---+---+---+
mluis 8:26002607de9c 1021 * | Earliest Rx window |
mluis 8:26002607de9c 1022 * +---+---+---+---+---+---+---+---+
mluis 8:26002607de9c 1023 * |
mluis 8:26002607de9c 1024 * +---+---+---+---+---+---+---+---+
mluis 8:26002607de9c 1025 *Downlink preamble 8 symbols | | | | | | | | |
mluis 8:26002607de9c 1026 * +---+---+---+---+---+---+---+---+
mluis 8:26002607de9c 1027 *
mluis 8:26002607de9c 1028 * Worst case Rx window timings
mluis 8:26002607de9c 1029 *
mluis 8:26002607de9c 1030 * TRxLate = DEFAULT_MIN_RX_SYMBOLS * tSymbol - RADIO_WAKEUP_TIME
mluis 8:26002607de9c 1031 * TRxEarly = 8 - DEFAULT_MIN_RX_SYMBOLS * tSymbol - RxWindowTimeout - RADIO_WAKEUP_TIME
mluis 8:26002607de9c 1032 *
mluis 8:26002607de9c 1033 * TRxLate - TRxEarly = 2 * DEFAULT_SYSTEM_MAX_RX_ERROR
mluis 8:26002607de9c 1034 *
mluis 8:26002607de9c 1035 * RxOffset = ( TRxLate + TRxEarly ) / 2
mluis 8:26002607de9c 1036 *
mluis 8:26002607de9c 1037 * RxWindowTimeout = ( 2 * DEFAULT_MIN_RX_SYMBOLS - 8 ) * tSymbol + 2 * DEFAULT_SYSTEM_MAX_RX_ERROR
mluis 8:26002607de9c 1038 * RxOffset = 4 * tSymbol - RxWindowTimeout / 2 - RADIO_WAKE_UP_TIME
mluis 8:26002607de9c 1039 *
mluis 8:26002607de9c 1040 * Minimal value of RxWindowTimeout must be 5 symbols which implies that the system always tolerates at least an error of 1.5 * tSymbol
mluis 8:26002607de9c 1041 */
mluis 8:26002607de9c 1042 /*!
mluis 8:26002607de9c 1043 * Computes the Rx window parameters.
mluis 8:26002607de9c 1044 *
mluis 8:26002607de9c 1045 * \param [IN] datarate Rx window datarate to be used
mluis 8:26002607de9c 1046 * \param [IN] rxError Maximum timing error of the receiver. in milliseconds
mluis 8:26002607de9c 1047 * The receiver will turn on in a [-rxError : +rxError] ms
mluis 8:26002607de9c 1048 * interval around RxOffset
mluis 8:26002607de9c 1049 *
mluis 8:26002607de9c 1050 * \retval rxConfigParams Returns a RxConfigParams_t structure.
mluis 8:26002607de9c 1051 */
mluis 8:26002607de9c 1052 static RxConfigParams_t ComputeRxWindowParameters( int8_t datarate, uint32_t rxError );
mluis 8:26002607de9c 1053
alphaemmeo 11:5b3e495baefb 1054 static void OnRadioTxDone( void *radio, void *userThisPtr, void *userData )
mluis 2:14a5d6ad92d5 1055 {
mluis 2:14a5d6ad92d5 1056 TimerTime_t curTime = TimerGetCurrentTime( );
mluis 8:26002607de9c 1057
mluis 2:14a5d6ad92d5 1058 if( LoRaMacDeviceClass != CLASS_C )
mluis 2:14a5d6ad92d5 1059 {
mluis 2:14a5d6ad92d5 1060 Radio.Sleep( );
mluis 2:14a5d6ad92d5 1061 }
mluis 2:14a5d6ad92d5 1062 else
mluis 2:14a5d6ad92d5 1063 {
mluis 2:14a5d6ad92d5 1064 OnRxWindow2TimerEvent( );
mluis 2:14a5d6ad92d5 1065 }
mluis 2:14a5d6ad92d5 1066
mluis 8:26002607de9c 1067 // Setup timers
mluis 2:14a5d6ad92d5 1068 if( IsRxWindowsEnabled == true )
mluis 2:14a5d6ad92d5 1069 {
mluis 2:14a5d6ad92d5 1070 TimerSetValue( &RxWindowTimer1, RxWindow1Delay );
mluis 2:14a5d6ad92d5 1071 TimerStart( &RxWindowTimer1 );
mluis 2:14a5d6ad92d5 1072 if( LoRaMacDeviceClass != CLASS_C )
mluis 2:14a5d6ad92d5 1073 {
mluis 2:14a5d6ad92d5 1074 TimerSetValue( &RxWindowTimer2, RxWindow2Delay );
mluis 2:14a5d6ad92d5 1075 TimerStart( &RxWindowTimer2 );
mluis 2:14a5d6ad92d5 1076 }
mluis 2:14a5d6ad92d5 1077 if( ( LoRaMacDeviceClass == CLASS_C ) || ( NodeAckRequested == true ) )
mluis 2:14a5d6ad92d5 1078 {
mluis 2:14a5d6ad92d5 1079 TimerSetValue( &AckTimeoutTimer, RxWindow2Delay + ACK_TIMEOUT +
mluis 2:14a5d6ad92d5 1080 randr( -ACK_TIMEOUT_RND, ACK_TIMEOUT_RND ) );
mluis 2:14a5d6ad92d5 1081 TimerStart( &AckTimeoutTimer );
mluis 2:14a5d6ad92d5 1082 }
mluis 2:14a5d6ad92d5 1083 }
mluis 2:14a5d6ad92d5 1084 else
mluis 2:14a5d6ad92d5 1085 {
mluis 2:14a5d6ad92d5 1086 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK;
mluis 2:14a5d6ad92d5 1087 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT;
mluis 2:14a5d6ad92d5 1088
mluis 2:14a5d6ad92d5 1089 if( LoRaMacFlags.Value == 0 )
mluis 2:14a5d6ad92d5 1090 {
mluis 2:14a5d6ad92d5 1091 LoRaMacFlags.Bits.McpsReq = 1;
mluis 2:14a5d6ad92d5 1092 }
mluis 2:14a5d6ad92d5 1093 LoRaMacFlags.Bits.MacDone = 1;
mluis 2:14a5d6ad92d5 1094 }
mluis 2:14a5d6ad92d5 1095
mluis 8:26002607de9c 1096 // Update last tx done time for the current channel
mluis 8:26002607de9c 1097 Bands[Channels[Channel].Band].LastTxDoneTime = curTime;
mluis 8:26002607de9c 1098 // Update Aggregated last tx done time
mluis 8:26002607de9c 1099 AggregatedLastTxDoneTime = curTime;
mluis 8:26002607de9c 1100 // Update Backoff
mluis 8:26002607de9c 1101 CalculateBackOff( Channel );
mluis 8:26002607de9c 1102
mluis 2:14a5d6ad92d5 1103 if( NodeAckRequested == false )
mluis 2:14a5d6ad92d5 1104 {
mluis 2:14a5d6ad92d5 1105 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK;
mluis 2:14a5d6ad92d5 1106 ChannelsNbRepCounter++;
mluis 2:14a5d6ad92d5 1107 }
mluis 2:14a5d6ad92d5 1108 }
mluis 2:14a5d6ad92d5 1109
mluis 3:b9d87593a8ae 1110 static void PrepareRxDoneAbort( void )
mluis 3:b9d87593a8ae 1111 {
mluis 8:26002607de9c 1112 LoRaMacState |= LORAMAC_RX_ABORT;
mluis 3:b9d87593a8ae 1113
mluis 3:b9d87593a8ae 1114 if( NodeAckRequested )
mluis 3:b9d87593a8ae 1115 {
mluis 3:b9d87593a8ae 1116 OnAckTimeoutTimerEvent( );
mluis 3:b9d87593a8ae 1117 }
mluis 3:b9d87593a8ae 1118
mluis 3:b9d87593a8ae 1119 LoRaMacFlags.Bits.McpsInd = 1;
mluis 3:b9d87593a8ae 1120 LoRaMacFlags.Bits.MacDone = 1;
mluis 3:b9d87593a8ae 1121
mluis 3:b9d87593a8ae 1122 // Trig OnMacCheckTimerEvent call as soon as possible
mluis 8:26002607de9c 1123 TimerSetValue( &MacStateCheckTimer, 1 );
mluis 3:b9d87593a8ae 1124 TimerStart( &MacStateCheckTimer );
mluis 3:b9d87593a8ae 1125 }
mluis 3:b9d87593a8ae 1126
alphaemmeo 11:5b3e495baefb 1127 static void OnRadioRxDone( void *radio, void *userThisPtr, void *userData, uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr )
mluis 0:91d1a7783bb9 1128 {
mluis 2:14a5d6ad92d5 1129 LoRaMacHeader_t macHdr;
mluis 2:14a5d6ad92d5 1130 LoRaMacFrameCtrl_t fCtrl;
mluis 4:37c12dbc8dc7 1131 bool skipIndication = false;
mluis 2:14a5d6ad92d5 1132
mluis 2:14a5d6ad92d5 1133 uint8_t pktHeaderLen = 0;
mluis 2:14a5d6ad92d5 1134 uint32_t address = 0;
mluis 2:14a5d6ad92d5 1135 uint8_t appPayloadStartIndex = 0;
mluis 2:14a5d6ad92d5 1136 uint8_t port = 0xFF;
mluis 2:14a5d6ad92d5 1137 uint8_t frameLen = 0;
mluis 2:14a5d6ad92d5 1138 uint32_t mic = 0;
mluis 2:14a5d6ad92d5 1139 uint32_t micRx = 0;
mluis 2:14a5d6ad92d5 1140
mluis 2:14a5d6ad92d5 1141 uint16_t sequenceCounter = 0;
mluis 2:14a5d6ad92d5 1142 uint16_t sequenceCounterPrev = 0;
mluis 2:14a5d6ad92d5 1143 uint16_t sequenceCounterDiff = 0;
mluis 2:14a5d6ad92d5 1144 uint32_t downLinkCounter = 0;
mluis 2:14a5d6ad92d5 1145
mluis 2:14a5d6ad92d5 1146 MulticastParams_t *curMulticastParams = NULL;
mluis 2:14a5d6ad92d5 1147 uint8_t *nwkSKey = LoRaMacNwkSKey;
mluis 2:14a5d6ad92d5 1148 uint8_t *appSKey = LoRaMacAppSKey;
mluis 2:14a5d6ad92d5 1149
mluis 2:14a5d6ad92d5 1150 uint8_t multicast = 0;
mluis 2:14a5d6ad92d5 1151
mluis 2:14a5d6ad92d5 1152 bool isMicOk = false;
mluis 2:14a5d6ad92d5 1153
mluis 2:14a5d6ad92d5 1154 McpsConfirm.AckReceived = false;
mluis 2:14a5d6ad92d5 1155 McpsIndication.Rssi = rssi;
mluis 2:14a5d6ad92d5 1156 McpsIndication.Snr = snr;
mluis 2:14a5d6ad92d5 1157 McpsIndication.RxSlot = RxSlot;
mluis 2:14a5d6ad92d5 1158 McpsIndication.Port = 0;
mluis 2:14a5d6ad92d5 1159 McpsIndication.Multicast = 0;
mluis 2:14a5d6ad92d5 1160 McpsIndication.FramePending = 0;
mluis 2:14a5d6ad92d5 1161 McpsIndication.Buffer = NULL;
mluis 2:14a5d6ad92d5 1162 McpsIndication.BufferSize = 0;
mluis 2:14a5d6ad92d5 1163 McpsIndication.RxData = false;
mluis 2:14a5d6ad92d5 1164 McpsIndication.AckReceived = false;
mluis 2:14a5d6ad92d5 1165 McpsIndication.DownLinkCounter = 0;
mluis 2:14a5d6ad92d5 1166 McpsIndication.McpsIndication = MCPS_UNCONFIRMED;
mluis 2:14a5d6ad92d5 1167
mluis 8:26002607de9c 1168 Radio.Sleep( );
mluis 2:14a5d6ad92d5 1169 TimerStop( &RxWindowTimer2 );
mluis 2:14a5d6ad92d5 1170
mluis 2:14a5d6ad92d5 1171 macHdr.Value = payload[pktHeaderLen++];
mluis 2:14a5d6ad92d5 1172
mluis 2:14a5d6ad92d5 1173 switch( macHdr.Bits.MType )
mluis 2:14a5d6ad92d5 1174 {
mluis 2:14a5d6ad92d5 1175 case FRAME_TYPE_JOIN_ACCEPT:
mluis 2:14a5d6ad92d5 1176 if( IsLoRaMacNetworkJoined == true )
mluis 2:14a5d6ad92d5 1177 {
mluis 8:26002607de9c 1178 McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_ERROR;
mluis 8:26002607de9c 1179 PrepareRxDoneAbort( );
mluis 8:26002607de9c 1180 return;
mluis 2:14a5d6ad92d5 1181 }
mluis 2:14a5d6ad92d5 1182 LoRaMacJoinDecrypt( payload + 1, size - 1, LoRaMacAppKey, LoRaMacRxPayload + 1 );
mluis 2:14a5d6ad92d5 1183
mluis 2:14a5d6ad92d5 1184 LoRaMacRxPayload[0] = macHdr.Value;
mluis 2:14a5d6ad92d5 1185
mluis 2:14a5d6ad92d5 1186 LoRaMacJoinComputeMic( LoRaMacRxPayload, size - LORAMAC_MFR_LEN, LoRaMacAppKey, &mic );
mluis 2:14a5d6ad92d5 1187
mluis 2:14a5d6ad92d5 1188 micRx |= ( uint32_t )LoRaMacRxPayload[size - LORAMAC_MFR_LEN];
mluis 2:14a5d6ad92d5 1189 micRx |= ( ( uint32_t )LoRaMacRxPayload[size - LORAMAC_MFR_LEN + 1] << 8 );
mluis 2:14a5d6ad92d5 1190 micRx |= ( ( uint32_t )LoRaMacRxPayload[size - LORAMAC_MFR_LEN + 2] << 16 );
mluis 2:14a5d6ad92d5 1191 micRx |= ( ( uint32_t )LoRaMacRxPayload[size - LORAMAC_MFR_LEN + 3] << 24 );
mluis 2:14a5d6ad92d5 1192
mluis 2:14a5d6ad92d5 1193 if( micRx == mic )
mluis 2:14a5d6ad92d5 1194 {
mluis 2:14a5d6ad92d5 1195 LoRaMacJoinComputeSKeys( LoRaMacAppKey, LoRaMacRxPayload + 1, LoRaMacDevNonce, LoRaMacNwkSKey, LoRaMacAppSKey );
mluis 2:14a5d6ad92d5 1196
mluis 2:14a5d6ad92d5 1197 LoRaMacNetID = ( uint32_t )LoRaMacRxPayload[4];
mluis 2:14a5d6ad92d5 1198 LoRaMacNetID |= ( ( uint32_t )LoRaMacRxPayload[5] << 8 );
mluis 2:14a5d6ad92d5 1199 LoRaMacNetID |= ( ( uint32_t )LoRaMacRxPayload[6] << 16 );
mluis 2:14a5d6ad92d5 1200
mluis 2:14a5d6ad92d5 1201 LoRaMacDevAddr = ( uint32_t )LoRaMacRxPayload[7];
mluis 2:14a5d6ad92d5 1202 LoRaMacDevAddr |= ( ( uint32_t )LoRaMacRxPayload[8] << 8 );
mluis 2:14a5d6ad92d5 1203 LoRaMacDevAddr |= ( ( uint32_t )LoRaMacRxPayload[9] << 16 );
mluis 2:14a5d6ad92d5 1204 LoRaMacDevAddr |= ( ( uint32_t )LoRaMacRxPayload[10] << 24 );
mluis 2:14a5d6ad92d5 1205
mluis 2:14a5d6ad92d5 1206 // DLSettings
mluis 7:c16969e0f70f 1207 LoRaMacParams.Rx1DrOffset = ( LoRaMacRxPayload[11] >> 4 ) & 0x07;
mluis 7:c16969e0f70f 1208 LoRaMacParams.Rx2Channel.Datarate = LoRaMacRxPayload[11] & 0x0F;
mluis 8:26002607de9c 1209
mluis 2:14a5d6ad92d5 1210 // RxDelay
mluis 7:c16969e0f70f 1211 LoRaMacParams.ReceiveDelay1 = ( LoRaMacRxPayload[12] & 0x0F );
mluis 7:c16969e0f70f 1212 if( LoRaMacParams.ReceiveDelay1 == 0 )
mluis 2:14a5d6ad92d5 1213 {
mluis 7:c16969e0f70f 1214 LoRaMacParams.ReceiveDelay1 = 1;
mluis 2:14a5d6ad92d5 1215 }
mluis 8:26002607de9c 1216 LoRaMacParams.ReceiveDelay1 *= 1e3;
mluis 8:26002607de9c 1217 LoRaMacParams.ReceiveDelay2 = LoRaMacParams.ReceiveDelay1 + 1e3;
mluis 2:14a5d6ad92d5 1218
mluis 2:14a5d6ad92d5 1219 #if !( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) )
mluis 2:14a5d6ad92d5 1220 //CFList
mluis 2:14a5d6ad92d5 1221 if( ( size - 1 ) > 16 )
mluis 2:14a5d6ad92d5 1222 {
mluis 2:14a5d6ad92d5 1223 ChannelParams_t param;
mluis 2:14a5d6ad92d5 1224 param.DrRange.Value = ( DR_5 << 4 ) | DR_0;
mluis 2:14a5d6ad92d5 1225
mluis 8:26002607de9c 1226 LoRaMacState |= LORAMAC_TX_CONFIG;
mluis 2:14a5d6ad92d5 1227 for( uint8_t i = 3, j = 0; i < ( 5 + 3 ); i++, j += 3 )
mluis 2:14a5d6ad92d5 1228 {
mluis 2:14a5d6ad92d5 1229 param.Frequency = ( ( uint32_t )LoRaMacRxPayload[13 + j] | ( ( uint32_t )LoRaMacRxPayload[14 + j] << 8 ) | ( ( uint32_t )LoRaMacRxPayload[15 + j] << 16 ) ) * 100;
mluis 8:26002607de9c 1230 if( param.Frequency != 0 )
mluis 8:26002607de9c 1231 {
mluis 8:26002607de9c 1232 LoRaMacChannelAdd( i, param );
mluis 8:26002607de9c 1233 }
mluis 8:26002607de9c 1234 else
mluis 8:26002607de9c 1235 {
mluis 8:26002607de9c 1236 LoRaMacChannelRemove( i );
mluis 8:26002607de9c 1237 }
mluis 2:14a5d6ad92d5 1238 }
mluis 8:26002607de9c 1239 LoRaMacState &= ~LORAMAC_TX_CONFIG;
mluis 2:14a5d6ad92d5 1240 }
mluis 2:14a5d6ad92d5 1241 #endif
mluis 2:14a5d6ad92d5 1242 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK;
mluis 2:14a5d6ad92d5 1243 IsLoRaMacNetworkJoined = true;
mluis 7:c16969e0f70f 1244 LoRaMacParams.ChannelsDatarate = LoRaMacParamsDefaults.ChannelsDatarate;
mluis 2:14a5d6ad92d5 1245 }
mluis 2:14a5d6ad92d5 1246 else
mluis 2:14a5d6ad92d5 1247 {
mluis 2:14a5d6ad92d5 1248 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL;
mluis 2:14a5d6ad92d5 1249 }
mluis 2:14a5d6ad92d5 1250 break;
mluis 2:14a5d6ad92d5 1251 case FRAME_TYPE_DATA_CONFIRMED_DOWN:
mluis 2:14a5d6ad92d5 1252 case FRAME_TYPE_DATA_UNCONFIRMED_DOWN:
mluis 2:14a5d6ad92d5 1253 {
mluis 2:14a5d6ad92d5 1254 address = payload[pktHeaderLen++];
mluis 2:14a5d6ad92d5 1255 address |= ( (uint32_t)payload[pktHeaderLen++] << 8 );
mluis 2:14a5d6ad92d5 1256 address |= ( (uint32_t)payload[pktHeaderLen++] << 16 );
mluis 2:14a5d6ad92d5 1257 address |= ( (uint32_t)payload[pktHeaderLen++] << 24 );
mluis 2:14a5d6ad92d5 1258
mluis 2:14a5d6ad92d5 1259 if( address != LoRaMacDevAddr )
mluis 2:14a5d6ad92d5 1260 {
mluis 2:14a5d6ad92d5 1261 curMulticastParams = MulticastChannels;
mluis 2:14a5d6ad92d5 1262 while( curMulticastParams != NULL )
mluis 2:14a5d6ad92d5 1263 {
mluis 2:14a5d6ad92d5 1264 if( address == curMulticastParams->Address )
mluis 2:14a5d6ad92d5 1265 {
mluis 2:14a5d6ad92d5 1266 multicast = 1;
mluis 2:14a5d6ad92d5 1267 nwkSKey = curMulticastParams->NwkSKey;
mluis 2:14a5d6ad92d5 1268 appSKey = curMulticastParams->AppSKey;
mluis 2:14a5d6ad92d5 1269 downLinkCounter = curMulticastParams->DownLinkCounter;
mluis 2:14a5d6ad92d5 1270 break;
mluis 2:14a5d6ad92d5 1271 }
mluis 2:14a5d6ad92d5 1272 curMulticastParams = curMulticastParams->Next;
mluis 2:14a5d6ad92d5 1273 }
mluis 2:14a5d6ad92d5 1274 if( multicast == 0 )
mluis 2:14a5d6ad92d5 1275 {
mluis 2:14a5d6ad92d5 1276 // We are not the destination of this frame.
mluis 2:14a5d6ad92d5 1277 McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_ADDRESS_FAIL;
mluis 3:b9d87593a8ae 1278 PrepareRxDoneAbort( );
mluis 2:14a5d6ad92d5 1279 return;
mluis 2:14a5d6ad92d5 1280 }
mluis 2:14a5d6ad92d5 1281 }
mluis 2:14a5d6ad92d5 1282 else
mluis 2:14a5d6ad92d5 1283 {
mluis 2:14a5d6ad92d5 1284 multicast = 0;
mluis 2:14a5d6ad92d5 1285 nwkSKey = LoRaMacNwkSKey;
mluis 2:14a5d6ad92d5 1286 appSKey = LoRaMacAppSKey;
mluis 2:14a5d6ad92d5 1287 downLinkCounter = DownLinkCounter;
mluis 2:14a5d6ad92d5 1288 }
mluis 2:14a5d6ad92d5 1289
mluis 2:14a5d6ad92d5 1290 fCtrl.Value = payload[pktHeaderLen++];
mluis 2:14a5d6ad92d5 1291
mluis 2:14a5d6ad92d5 1292 sequenceCounter = ( uint16_t )payload[pktHeaderLen++];
mluis 2:14a5d6ad92d5 1293 sequenceCounter |= ( uint16_t )payload[pktHeaderLen++] << 8;
mluis 2:14a5d6ad92d5 1294
mluis 2:14a5d6ad92d5 1295 appPayloadStartIndex = 8 + fCtrl.Bits.FOptsLen;
mluis 2:14a5d6ad92d5 1296
mluis 2:14a5d6ad92d5 1297 micRx |= ( uint32_t )payload[size - LORAMAC_MFR_LEN];
mluis 2:14a5d6ad92d5 1298 micRx |= ( ( uint32_t )payload[size - LORAMAC_MFR_LEN + 1] << 8 );
mluis 2:14a5d6ad92d5 1299 micRx |= ( ( uint32_t )payload[size - LORAMAC_MFR_LEN + 2] << 16 );
mluis 2:14a5d6ad92d5 1300 micRx |= ( ( uint32_t )payload[size - LORAMAC_MFR_LEN + 3] << 24 );
mluis 2:14a5d6ad92d5 1301
mluis 2:14a5d6ad92d5 1302 sequenceCounterPrev = ( uint16_t )downLinkCounter;
mluis 2:14a5d6ad92d5 1303 sequenceCounterDiff = ( sequenceCounter - sequenceCounterPrev );
mluis 2:14a5d6ad92d5 1304
mluis 2:14a5d6ad92d5 1305 if( sequenceCounterDiff < ( 1 << 15 ) )
mluis 2:14a5d6ad92d5 1306 {
mluis 2:14a5d6ad92d5 1307 downLinkCounter += sequenceCounterDiff;
mluis 2:14a5d6ad92d5 1308 LoRaMacComputeMic( payload, size - LORAMAC_MFR_LEN, nwkSKey, address, DOWN_LINK, downLinkCounter, &mic );
mluis 2:14a5d6ad92d5 1309 if( micRx == mic )
mluis 2:14a5d6ad92d5 1310 {
mluis 2:14a5d6ad92d5 1311 isMicOk = true;
mluis 2:14a5d6ad92d5 1312 }
mluis 2:14a5d6ad92d5 1313 }
mluis 2:14a5d6ad92d5 1314 else
mluis 2:14a5d6ad92d5 1315 {
mluis 2:14a5d6ad92d5 1316 // check for sequence roll-over
mluis 2:14a5d6ad92d5 1317 uint32_t downLinkCounterTmp = downLinkCounter + 0x10000 + ( int16_t )sequenceCounterDiff;
mluis 2:14a5d6ad92d5 1318 LoRaMacComputeMic( payload, size - LORAMAC_MFR_LEN, nwkSKey, address, DOWN_LINK, downLinkCounterTmp, &mic );
mluis 2:14a5d6ad92d5 1319 if( micRx == mic )
mluis 2:14a5d6ad92d5 1320 {
mluis 2:14a5d6ad92d5 1321 isMicOk = true;
mluis 2:14a5d6ad92d5 1322 downLinkCounter = downLinkCounterTmp;
mluis 2:14a5d6ad92d5 1323 }
mluis 2:14a5d6ad92d5 1324 }
mluis 2:14a5d6ad92d5 1325
mluis 4:37c12dbc8dc7 1326 // Check for a the maximum allowed counter difference
mluis 4:37c12dbc8dc7 1327 if( sequenceCounterDiff >= MAX_FCNT_GAP )
mluis 4:37c12dbc8dc7 1328 {
mluis 4:37c12dbc8dc7 1329 McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_TOO_MANY_FRAMES_LOSS;
mluis 4:37c12dbc8dc7 1330 McpsIndication.DownLinkCounter = downLinkCounter;
mluis 4:37c12dbc8dc7 1331 PrepareRxDoneAbort( );
mluis 4:37c12dbc8dc7 1332 return;
mluis 4:37c12dbc8dc7 1333 }
mluis 4:37c12dbc8dc7 1334
mluis 2:14a5d6ad92d5 1335 if( isMicOk == true )
mluis 2:14a5d6ad92d5 1336 {
mluis 2:14a5d6ad92d5 1337 McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_OK;
mluis 2:14a5d6ad92d5 1338 McpsIndication.Multicast = multicast;
mluis 2:14a5d6ad92d5 1339 McpsIndication.FramePending = fCtrl.Bits.FPending;
mluis 2:14a5d6ad92d5 1340 McpsIndication.Buffer = NULL;
mluis 2:14a5d6ad92d5 1341 McpsIndication.BufferSize = 0;
mluis 2:14a5d6ad92d5 1342 McpsIndication.DownLinkCounter = downLinkCounter;
mluis 2:14a5d6ad92d5 1343
mluis 2:14a5d6ad92d5 1344 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK;
mluis 2:14a5d6ad92d5 1345
mluis 2:14a5d6ad92d5 1346 AdrAckCounter = 0;
mluis 7:c16969e0f70f 1347 MacCommandsBufferToRepeatIndex = 0;
mluis 2:14a5d6ad92d5 1348
mluis 2:14a5d6ad92d5 1349 // Update 32 bits downlink counter
mluis 2:14a5d6ad92d5 1350 if( multicast == 1 )
mluis 2:14a5d6ad92d5 1351 {
mluis 2:14a5d6ad92d5 1352 McpsIndication.McpsIndication = MCPS_MULTICAST;
mluis 2:14a5d6ad92d5 1353
mluis 2:14a5d6ad92d5 1354 if( ( curMulticastParams->DownLinkCounter == downLinkCounter ) &&
mluis 2:14a5d6ad92d5 1355 ( curMulticastParams->DownLinkCounter != 0 ) )
mluis 2:14a5d6ad92d5 1356 {
mluis 2:14a5d6ad92d5 1357 McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED;
mluis 2:14a5d6ad92d5 1358 McpsIndication.DownLinkCounter = downLinkCounter;
mluis 3:b9d87593a8ae 1359 PrepareRxDoneAbort( );
mluis 2:14a5d6ad92d5 1360 return;
mluis 2:14a5d6ad92d5 1361 }
mluis 2:14a5d6ad92d5 1362 curMulticastParams->DownLinkCounter = downLinkCounter;
mluis 2:14a5d6ad92d5 1363 }
mluis 2:14a5d6ad92d5 1364 else
mluis 2:14a5d6ad92d5 1365 {
mluis 2:14a5d6ad92d5 1366 if( macHdr.Bits.MType == FRAME_TYPE_DATA_CONFIRMED_DOWN )
mluis 2:14a5d6ad92d5 1367 {
mluis 3:b9d87593a8ae 1368 SrvAckRequested = true;
mluis 2:14a5d6ad92d5 1369 McpsIndication.McpsIndication = MCPS_CONFIRMED;
mluis 4:37c12dbc8dc7 1370
mluis 4:37c12dbc8dc7 1371 if( ( DownLinkCounter == downLinkCounter ) &&
mluis 4:37c12dbc8dc7 1372 ( DownLinkCounter != 0 ) )
mluis 4:37c12dbc8dc7 1373 {
mluis 4:37c12dbc8dc7 1374 // Duplicated confirmed downlink. Skip indication.
mluis 8:26002607de9c 1375 // In this case, the MAC layer shall accept the MAC commands
mluis 8:26002607de9c 1376 // which are included in the downlink retransmission.
mluis 8:26002607de9c 1377 // It should not provide the same frame to the application
mluis 8:26002607de9c 1378 // layer again.
mluis 4:37c12dbc8dc7 1379 skipIndication = true;
mluis 4:37c12dbc8dc7 1380 }
mluis 2:14a5d6ad92d5 1381 }
mluis 2:14a5d6ad92d5 1382 else
mluis 2:14a5d6ad92d5 1383 {
mluis 3:b9d87593a8ae 1384 SrvAckRequested = false;
mluis 2:14a5d6ad92d5 1385 McpsIndication.McpsIndication = MCPS_UNCONFIRMED;
mluis 4:37c12dbc8dc7 1386
mluis 4:37c12dbc8dc7 1387 if( ( DownLinkCounter == downLinkCounter ) &&
mluis 4:37c12dbc8dc7 1388 ( DownLinkCounter != 0 ) )
mluis 4:37c12dbc8dc7 1389 {
mluis 4:37c12dbc8dc7 1390 McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED;
mluis 4:37c12dbc8dc7 1391 McpsIndication.DownLinkCounter = downLinkCounter;
mluis 4:37c12dbc8dc7 1392 PrepareRxDoneAbort( );
mluis 4:37c12dbc8dc7 1393 return;
mluis 4:37c12dbc8dc7 1394 }
mluis 2:14a5d6ad92d5 1395 }
mluis 2:14a5d6ad92d5 1396 DownLinkCounter = downLinkCounter;
mluis 2:14a5d6ad92d5 1397 }
mluis 2:14a5d6ad92d5 1398
mluis 8:26002607de9c 1399 // This must be done before parsing the payload and the MAC commands.
mluis 8:26002607de9c 1400 // We need to reset the MacCommandsBufferIndex here, since we need
mluis 8:26002607de9c 1401 // to take retransmissions and repititions into account. Error cases
mluis 8:26002607de9c 1402 // will be handled in function OnMacStateCheckTimerEvent.
mluis 8:26002607de9c 1403 if( McpsConfirm.McpsRequest == MCPS_CONFIRMED )
mluis 2:14a5d6ad92d5 1404 {
mluis 8:26002607de9c 1405 if( fCtrl.Bits.Ack == 1 )
mluis 8:26002607de9c 1406 {// Reset MacCommandsBufferIndex when we have received an ACK.
mluis 8:26002607de9c 1407 MacCommandsBufferIndex = 0;
mluis 8:26002607de9c 1408 }
mluis 2:14a5d6ad92d5 1409 }
mluis 2:14a5d6ad92d5 1410 else
mluis 8:26002607de9c 1411 {// Reset the variable if we have received any valid frame.
mluis 8:26002607de9c 1412 MacCommandsBufferIndex = 0;
mluis 2:14a5d6ad92d5 1413 }
mluis 2:14a5d6ad92d5 1414
mluis 8:26002607de9c 1415 // Process payload and MAC commands
mluis 2:14a5d6ad92d5 1416 if( ( ( size - 4 ) - appPayloadStartIndex ) > 0 )
mluis 2:14a5d6ad92d5 1417 {
mluis 2:14a5d6ad92d5 1418 port = payload[appPayloadStartIndex++];
mluis 2:14a5d6ad92d5 1419 frameLen = ( size - 4 ) - appPayloadStartIndex;
mluis 2:14a5d6ad92d5 1420
mluis 2:14a5d6ad92d5 1421 McpsIndication.Port = port;
mluis 2:14a5d6ad92d5 1422
mluis 2:14a5d6ad92d5 1423 if( port == 0 )
mluis 2:14a5d6ad92d5 1424 {
mluis 8:26002607de9c 1425 // Only allow frames which do not have fOpts
mluis 7:c16969e0f70f 1426 if( fCtrl.Bits.FOptsLen == 0 )
mluis 7:c16969e0f70f 1427 {
mluis 7:c16969e0f70f 1428 LoRaMacPayloadDecrypt( payload + appPayloadStartIndex,
mluis 7:c16969e0f70f 1429 frameLen,
mluis 7:c16969e0f70f 1430 nwkSKey,
mluis 7:c16969e0f70f 1431 address,
mluis 7:c16969e0f70f 1432 DOWN_LINK,
mluis 7:c16969e0f70f 1433 downLinkCounter,
mluis 7:c16969e0f70f 1434 LoRaMacRxPayload );
mluis 7:c16969e0f70f 1435
mluis 7:c16969e0f70f 1436 // Decode frame payload MAC commands
mluis 7:c16969e0f70f 1437 ProcessMacCommands( LoRaMacRxPayload, 0, frameLen, snr );
mluis 7:c16969e0f70f 1438 }
mluis 7:c16969e0f70f 1439 else
mluis 7:c16969e0f70f 1440 {
mluis 7:c16969e0f70f 1441 skipIndication = true;
mluis 7:c16969e0f70f 1442 }
mluis 2:14a5d6ad92d5 1443 }
mluis 2:14a5d6ad92d5 1444 else
mluis 2:14a5d6ad92d5 1445 {
mluis 7:c16969e0f70f 1446 if( fCtrl.Bits.FOptsLen > 0 )
mluis 7:c16969e0f70f 1447 {
mluis 7:c16969e0f70f 1448 // Decode Options field MAC commands. Omit the fPort.
mluis 7:c16969e0f70f 1449 ProcessMacCommands( payload, 8, appPayloadStartIndex - 1, snr );
mluis 7:c16969e0f70f 1450 }
mluis 7:c16969e0f70f 1451
mluis 2:14a5d6ad92d5 1452 LoRaMacPayloadDecrypt( payload + appPayloadStartIndex,
mluis 2:14a5d6ad92d5 1453 frameLen,
mluis 2:14a5d6ad92d5 1454 appSKey,
mluis 2:14a5d6ad92d5 1455 address,
mluis 2:14a5d6ad92d5 1456 DOWN_LINK,
mluis 2:14a5d6ad92d5 1457 downLinkCounter,
mluis 2:14a5d6ad92d5 1458 LoRaMacRxPayload );
mluis 2:14a5d6ad92d5 1459
mluis 4:37c12dbc8dc7 1460 if( skipIndication == false )
mluis 4:37c12dbc8dc7 1461 {
mluis 4:37c12dbc8dc7 1462 McpsIndication.Buffer = LoRaMacRxPayload;
mluis 4:37c12dbc8dc7 1463 McpsIndication.BufferSize = frameLen;
mluis 4:37c12dbc8dc7 1464 McpsIndication.RxData = true;
mluis 4:37c12dbc8dc7 1465 }
mluis 2:14a5d6ad92d5 1466 }
mluis 2:14a5d6ad92d5 1467 }
mluis 7:c16969e0f70f 1468 else
mluis 7:c16969e0f70f 1469 {
mluis 7:c16969e0f70f 1470 if( fCtrl.Bits.FOptsLen > 0 )
mluis 7:c16969e0f70f 1471 {
mluis 7:c16969e0f70f 1472 // Decode Options field MAC commands
mluis 7:c16969e0f70f 1473 ProcessMacCommands( payload, 8, appPayloadStartIndex, snr );
mluis 7:c16969e0f70f 1474 }
mluis 7:c16969e0f70f 1475 }
mluis 7:c16969e0f70f 1476
mluis 4:37c12dbc8dc7 1477 if( skipIndication == false )
mluis 4:37c12dbc8dc7 1478 {
mluis 8:26002607de9c 1479 // Check if the frame is an acknowledgement
mluis 8:26002607de9c 1480 if( fCtrl.Bits.Ack == 1 )
mluis 8:26002607de9c 1481 {
mluis 8:26002607de9c 1482 McpsConfirm.AckReceived = true;
mluis 8:26002607de9c 1483 McpsIndication.AckReceived = true;
mluis 8:26002607de9c 1484
mluis 8:26002607de9c 1485 // Stop the AckTimeout timer as no more retransmissions
mluis 8:26002607de9c 1486 // are needed.
mluis 8:26002607de9c 1487 TimerStop( &AckTimeoutTimer );
mluis 8:26002607de9c 1488 }
mluis 8:26002607de9c 1489 else
mluis 8:26002607de9c 1490 {
mluis 8:26002607de9c 1491 McpsConfirm.AckReceived = false;
mluis 8:26002607de9c 1492
mluis 8:26002607de9c 1493 if( AckTimeoutRetriesCounter > AckTimeoutRetries )
mluis 8:26002607de9c 1494 {
mluis 8:26002607de9c 1495 // Stop the AckTimeout timer as no more retransmissions
mluis 8:26002607de9c 1496 // are needed.
mluis 8:26002607de9c 1497 TimerStop( &AckTimeoutTimer );
mluis 8:26002607de9c 1498 }
mluis 8:26002607de9c 1499 }
mluis 4:37c12dbc8dc7 1500 }
mluis 8:26002607de9c 1501 // Provide always an indication, skip the callback to the user application,
mluis 8:26002607de9c 1502 // in case of a confirmed downlink retransmission.
mluis 8:26002607de9c 1503 LoRaMacFlags.Bits.McpsInd = 1;
mluis 8:26002607de9c 1504 LoRaMacFlags.Bits.McpsIndSkip = skipIndication;
mluis 2:14a5d6ad92d5 1505 }
mluis 2:14a5d6ad92d5 1506 else
mluis 2:14a5d6ad92d5 1507 {
mluis 2:14a5d6ad92d5 1508 McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_MIC_FAIL;
mluis 3:b9d87593a8ae 1509
mluis 3:b9d87593a8ae 1510 PrepareRxDoneAbort( );
mluis 3:b9d87593a8ae 1511 return;
mluis 2:14a5d6ad92d5 1512 }
mluis 2:14a5d6ad92d5 1513 }
mluis 2:14a5d6ad92d5 1514 break;
mluis 2:14a5d6ad92d5 1515 case FRAME_TYPE_PROPRIETARY:
mluis 2:14a5d6ad92d5 1516 {
mluis 2:14a5d6ad92d5 1517 memcpy1( LoRaMacRxPayload, &payload[pktHeaderLen], size );
mluis 2:14a5d6ad92d5 1518
mluis 2:14a5d6ad92d5 1519 McpsIndication.McpsIndication = MCPS_PROPRIETARY;
mluis 2:14a5d6ad92d5 1520 McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_OK;
mluis 2:14a5d6ad92d5 1521 McpsIndication.Buffer = LoRaMacRxPayload;
mluis 2:14a5d6ad92d5 1522 McpsIndication.BufferSize = size - pktHeaderLen;
mluis 3:b9d87593a8ae 1523
mluis 3:b9d87593a8ae 1524 LoRaMacFlags.Bits.McpsInd = 1;
mluis 2:14a5d6ad92d5 1525 break;
mluis 2:14a5d6ad92d5 1526 }
mluis 2:14a5d6ad92d5 1527 default:
mluis 2:14a5d6ad92d5 1528 McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_ERROR;
mluis 3:b9d87593a8ae 1529 PrepareRxDoneAbort( );
mluis 2:14a5d6ad92d5 1530 break;
mluis 2:14a5d6ad92d5 1531 }
mluis 2:14a5d6ad92d5 1532 LoRaMacFlags.Bits.MacDone = 1;
mluis 3:b9d87593a8ae 1533
mluis 3:b9d87593a8ae 1534 // Trig OnMacCheckTimerEvent call as soon as possible
mluis 8:26002607de9c 1535 TimerSetValue( &MacStateCheckTimer, 1 );
mluis 3:b9d87593a8ae 1536 TimerStart( &MacStateCheckTimer );
mluis 2:14a5d6ad92d5 1537 }
mluis 2:14a5d6ad92d5 1538
alphaemmeo 11:5b3e495baefb 1539 static void OnRadioTxTimeout( void *radio, void *userThisPtr, void *userData )
mluis 2:14a5d6ad92d5 1540 {
mluis 2:14a5d6ad92d5 1541 if( LoRaMacDeviceClass != CLASS_C )
mluis 2:14a5d6ad92d5 1542 {
mluis 2:14a5d6ad92d5 1543 Radio.Sleep( );
mluis 2:14a5d6ad92d5 1544 }
mluis 2:14a5d6ad92d5 1545 else
mluis 2:14a5d6ad92d5 1546 {
mluis 2:14a5d6ad92d5 1547 OnRxWindow2TimerEvent( );
mluis 2:14a5d6ad92d5 1548 }
mluis 2:14a5d6ad92d5 1549
mluis 2:14a5d6ad92d5 1550 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT;
mluis 2:14a5d6ad92d5 1551 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT;
mluis 2:14a5d6ad92d5 1552 LoRaMacFlags.Bits.MacDone = 1;
mluis 2:14a5d6ad92d5 1553 }
mluis 2:14a5d6ad92d5 1554
alphaemmeo 11:5b3e495baefb 1555 static void OnRadioRxError( void *radio, void *userThisPtr, void *userData )
mluis 2:14a5d6ad92d5 1556 {
mluis 2:14a5d6ad92d5 1557 if( LoRaMacDeviceClass != CLASS_C )
mluis 2:14a5d6ad92d5 1558 {
mluis 2:14a5d6ad92d5 1559 Radio.Sleep( );
mluis 2:14a5d6ad92d5 1560 }
mluis 2:14a5d6ad92d5 1561 else
mluis 2:14a5d6ad92d5 1562 {
mluis 2:14a5d6ad92d5 1563 OnRxWindow2TimerEvent( );
mluis 2:14a5d6ad92d5 1564 }
mluis 2:14a5d6ad92d5 1565
mluis 8:26002607de9c 1566 if( RxSlot == 0 )
mluis 8:26002607de9c 1567 {
mluis 8:26002607de9c 1568 if( NodeAckRequested == true )
mluis 8:26002607de9c 1569 {
mluis 8:26002607de9c 1570 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX1_ERROR;
mluis 8:26002607de9c 1571 }
mluis 8:26002607de9c 1572 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX1_ERROR;
mluis 8:26002607de9c 1573
mluis 8:26002607de9c 1574 if( TimerGetElapsedTime( AggregatedLastTxDoneTime ) >= RxWindow2Delay )
mluis 8:26002607de9c 1575 {
mluis 8:26002607de9c 1576 LoRaMacFlags.Bits.MacDone = 1;
mluis 8:26002607de9c 1577 }
mluis 8:26002607de9c 1578 }
mluis 8:26002607de9c 1579 else
mluis 2:14a5d6ad92d5 1580 {
mluis 2:14a5d6ad92d5 1581 if( NodeAckRequested == true )
mluis 2:14a5d6ad92d5 1582 {
mluis 2:14a5d6ad92d5 1583 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX2_ERROR;
mluis 2:14a5d6ad92d5 1584 }
mluis 2:14a5d6ad92d5 1585 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX2_ERROR;
mluis 2:14a5d6ad92d5 1586 LoRaMacFlags.Bits.MacDone = 1;
mluis 2:14a5d6ad92d5 1587 }
mluis 2:14a5d6ad92d5 1588 }
mluis 2:14a5d6ad92d5 1589
alphaemmeo 11:5b3e495baefb 1590 static void OnRadioRxTimeout( void *radio, void *userThisPtr, void *userData )
mluis 2:14a5d6ad92d5 1591 {
mluis 2:14a5d6ad92d5 1592 if( LoRaMacDeviceClass != CLASS_C )
mluis 2:14a5d6ad92d5 1593 {
mluis 2:14a5d6ad92d5 1594 Radio.Sleep( );
mluis 2:14a5d6ad92d5 1595 }
mluis 2:14a5d6ad92d5 1596 else
mluis 2:14a5d6ad92d5 1597 {
mluis 2:14a5d6ad92d5 1598 OnRxWindow2TimerEvent( );
mluis 2:14a5d6ad92d5 1599 }
mluis 2:14a5d6ad92d5 1600
mluis 2:14a5d6ad92d5 1601 if( RxSlot == 1 )
mluis 2:14a5d6ad92d5 1602 {
mluis 2:14a5d6ad92d5 1603 if( NodeAckRequested == true )
mluis 2:14a5d6ad92d5 1604 {
mluis 2:14a5d6ad92d5 1605 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT;
mluis 2:14a5d6ad92d5 1606 }
mluis 2:14a5d6ad92d5 1607 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT;
mluis 2:14a5d6ad92d5 1608 LoRaMacFlags.Bits.MacDone = 1;
mluis 2:14a5d6ad92d5 1609 }
mluis 2:14a5d6ad92d5 1610 }
mluis 2:14a5d6ad92d5 1611
mluis 2:14a5d6ad92d5 1612 static void OnMacStateCheckTimerEvent( void )
mluis 2:14a5d6ad92d5 1613 {
mluis 2:14a5d6ad92d5 1614 TimerStop( &MacStateCheckTimer );
mluis 2:14a5d6ad92d5 1615 bool txTimeout = false;
mluis 2:14a5d6ad92d5 1616
mluis 2:14a5d6ad92d5 1617 if( LoRaMacFlags.Bits.MacDone == 1 )
mluis 2:14a5d6ad92d5 1618 {
mluis 8:26002607de9c 1619 if( ( LoRaMacState & LORAMAC_RX_ABORT ) == LORAMAC_RX_ABORT )
mluis 4:37c12dbc8dc7 1620 {
mluis 8:26002607de9c 1621 LoRaMacState &= ~LORAMAC_RX_ABORT;
mluis 8:26002607de9c 1622 LoRaMacState &= ~LORAMAC_TX_RUNNING;
mluis 4:37c12dbc8dc7 1623 }
mluis 4:37c12dbc8dc7 1624
mluis 2:14a5d6ad92d5 1625 if( ( LoRaMacFlags.Bits.MlmeReq == 1 ) || ( ( LoRaMacFlags.Bits.McpsReq == 1 ) ) )
mluis 2:14a5d6ad92d5 1626 {
mluis 2:14a5d6ad92d5 1627 if( ( McpsConfirm.Status == LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT ) ||
mluis 2:14a5d6ad92d5 1628 ( MlmeConfirm.Status == LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT ) )
mluis 2:14a5d6ad92d5 1629 {
mluis 2:14a5d6ad92d5 1630 // Stop transmit cycle due to tx timeout.
mluis 8:26002607de9c 1631 LoRaMacState &= ~LORAMAC_TX_RUNNING;
mluis 8:26002607de9c 1632 MacCommandsBufferIndex = 0;
mluis 2:14a5d6ad92d5 1633 McpsConfirm.NbRetries = AckTimeoutRetriesCounter;
mluis 2:14a5d6ad92d5 1634 McpsConfirm.AckReceived = false;
mluis 2:14a5d6ad92d5 1635 McpsConfirm.TxTimeOnAir = 0;
mluis 2:14a5d6ad92d5 1636 txTimeout = true;
mluis 2:14a5d6ad92d5 1637 }
mluis 2:14a5d6ad92d5 1638 }
mluis 2:14a5d6ad92d5 1639
mluis 2:14a5d6ad92d5 1640 if( ( NodeAckRequested == false ) && ( txTimeout == false ) )
mluis 2:14a5d6ad92d5 1641 {
mluis 2:14a5d6ad92d5 1642 if( ( LoRaMacFlags.Bits.MlmeReq == 1 ) || ( ( LoRaMacFlags.Bits.McpsReq == 1 ) ) )
mluis 2:14a5d6ad92d5 1643 {
mluis 8:26002607de9c 1644 if( ( LoRaMacFlags.Bits.MlmeReq == 1 ) && ( MlmeConfirm.MlmeRequest == MLME_JOIN ) )
mluis 8:26002607de9c 1645 {// Procedure for the join request
mluis 8:26002607de9c 1646 MlmeConfirm.NbRetries = JoinRequestTrials;
mluis 8:26002607de9c 1647
mluis 8:26002607de9c 1648 if( MlmeConfirm.Status == LORAMAC_EVENT_INFO_STATUS_OK )
mluis 8:26002607de9c 1649 {// Node joined successfully
mluis 8:26002607de9c 1650 UpLinkCounter = 0;
mluis 8:26002607de9c 1651 ChannelsNbRepCounter = 0;
mluis 8:26002607de9c 1652 LoRaMacState &= ~LORAMAC_TX_RUNNING;
mluis 8:26002607de9c 1653 }
mluis 8:26002607de9c 1654 else
mluis 2:14a5d6ad92d5 1655 {
mluis 8:26002607de9c 1656 if( JoinRequestTrials >= MaxJoinRequestTrials )
mluis 8:26002607de9c 1657 {
mluis 8:26002607de9c 1658 LoRaMacState &= ~LORAMAC_TX_RUNNING;
mluis 8:26002607de9c 1659 }
mluis 8:26002607de9c 1660 else
mluis 8:26002607de9c 1661 {
mluis 8:26002607de9c 1662 LoRaMacFlags.Bits.MacDone = 0;
mluis 8:26002607de9c 1663 // Sends the same frame again
mluis 8:26002607de9c 1664 OnTxDelayedTimerEvent( );
mluis 8:26002607de9c 1665 }
mluis 2:14a5d6ad92d5 1666 }
mluis 2:14a5d6ad92d5 1667 }
mluis 2:14a5d6ad92d5 1668 else
mluis 8:26002607de9c 1669 {// Procedure for all other frames
mluis 8:26002607de9c 1670 if( ( ChannelsNbRepCounter >= LoRaMacParams.ChannelsNbRep ) || ( LoRaMacFlags.Bits.McpsInd == 1 ) )
mluis 8:26002607de9c 1671 {
mluis 8:26002607de9c 1672 if( LoRaMacFlags.Bits.McpsInd == 0 )
mluis 8:26002607de9c 1673 { // Maximum repititions without downlink. Reset MacCommandsBufferIndex. Increase ADR Ack counter.
mluis 8:26002607de9c 1674 // Only process the case when the MAC did not receive a downlink.
mluis 8:26002607de9c 1675 MacCommandsBufferIndex = 0;
mluis 8:26002607de9c 1676 AdrAckCounter++;
mluis 8:26002607de9c 1677 }
mluis 8:26002607de9c 1678
mluis 8:26002607de9c 1679 ChannelsNbRepCounter = 0;
mluis 8:26002607de9c 1680
mluis 8:26002607de9c 1681 if( IsUpLinkCounterFixed == false )
mluis 8:26002607de9c 1682 {
mluis 8:26002607de9c 1683 UpLinkCounter++;
mluis 8:26002607de9c 1684 }
mluis 8:26002607de9c 1685
mluis 8:26002607de9c 1686 LoRaMacState &= ~LORAMAC_TX_RUNNING;
mluis 8:26002607de9c 1687 }
mluis 8:26002607de9c 1688 else
mluis 8:26002607de9c 1689 {
mluis 8:26002607de9c 1690 LoRaMacFlags.Bits.MacDone = 0;
mluis 8:26002607de9c 1691 // Sends the same frame again
mluis 8:26002607de9c 1692 OnTxDelayedTimerEvent( );
mluis 8:26002607de9c 1693 }
mluis 2:14a5d6ad92d5 1694 }
mluis 2:14a5d6ad92d5 1695 }
mluis 2:14a5d6ad92d5 1696 }
mluis 2:14a5d6ad92d5 1697
mluis 2:14a5d6ad92d5 1698 if( LoRaMacFlags.Bits.McpsInd == 1 )
mluis 8:26002607de9c 1699 {// Procedure if we received a frame
mluis 2:14a5d6ad92d5 1700 if( ( McpsConfirm.AckReceived == true ) || ( AckTimeoutRetriesCounter > AckTimeoutRetries ) )
mluis 2:14a5d6ad92d5 1701 {
mluis 2:14a5d6ad92d5 1702 AckTimeoutRetry = false;
mluis 3:b9d87593a8ae 1703 NodeAckRequested = false;
mluis 2:14a5d6ad92d5 1704 if( IsUpLinkCounterFixed == false )
mluis 2:14a5d6ad92d5 1705 {
mluis 2:14a5d6ad92d5 1706 UpLinkCounter++;
mluis 2:14a5d6ad92d5 1707 }
mluis 2:14a5d6ad92d5 1708 McpsConfirm.NbRetries = AckTimeoutRetriesCounter;
mluis 2:14a5d6ad92d5 1709
mluis 8:26002607de9c 1710 LoRaMacState &= ~LORAMAC_TX_RUNNING;
mluis 2:14a5d6ad92d5 1711 }
mluis 2:14a5d6ad92d5 1712 }
mluis 2:14a5d6ad92d5 1713
mluis 8:26002607de9c 1714 if( ( AckTimeoutRetry == true ) && ( ( LoRaMacState & LORAMAC_TX_DELAYED ) == 0 ) )
mluis 8:26002607de9c 1715 {// Retransmissions procedure for confirmed uplinks
mluis 2:14a5d6ad92d5 1716 AckTimeoutRetry = false;
mluis 2:14a5d6ad92d5 1717 if( ( AckTimeoutRetriesCounter < AckTimeoutRetries ) && ( AckTimeoutRetriesCounter <= MAX_ACK_RETRIES ) )
mluis 2:14a5d6ad92d5 1718 {
mluis 2:14a5d6ad92d5 1719 AckTimeoutRetriesCounter++;
mluis 2:14a5d6ad92d5 1720
mluis 2:14a5d6ad92d5 1721 if( ( AckTimeoutRetriesCounter % 2 ) == 1 )
mluis 2:14a5d6ad92d5 1722 {
mluis 7:c16969e0f70f 1723 LoRaMacParams.ChannelsDatarate = MAX( LoRaMacParams.ChannelsDatarate - 1, LORAMAC_TX_MIN_DATARATE );
mluis 2:14a5d6ad92d5 1724 }
mluis 8:26002607de9c 1725 // Try to send the frame again
mluis 8:26002607de9c 1726 if( ScheduleTx( ) == LORAMAC_STATUS_OK )
mluis 8:26002607de9c 1727 {
mluis 8:26002607de9c 1728 LoRaMacFlags.Bits.MacDone = 0;
mluis 8:26002607de9c 1729 }
mluis 8:26002607de9c 1730 else
mluis 8:26002607de9c 1731 {
mluis 8:26002607de9c 1732 // The DR is not applicable for the payload size
mluis 8:26002607de9c 1733 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_TX_DR_PAYLOAD_SIZE_ERROR;
mluis 8:26002607de9c 1734
mluis 8:26002607de9c 1735 MacCommandsBufferIndex = 0;
mluis 8:26002607de9c 1736 LoRaMacState &= ~LORAMAC_TX_RUNNING;
mluis 8:26002607de9c 1737 NodeAckRequested = false;
mluis 8:26002607de9c 1738 McpsConfirm.AckReceived = false;
mluis 8:26002607de9c 1739 McpsConfirm.NbRetries = AckTimeoutRetriesCounter;
mluis 8:26002607de9c 1740 McpsConfirm.Datarate = LoRaMacParams.ChannelsDatarate;
mluis 8:26002607de9c 1741 if( IsUpLinkCounterFixed == false )
mluis 8:26002607de9c 1742 {
mluis 8:26002607de9c 1743 UpLinkCounter++;
mluis 8:26002607de9c 1744 }
mluis 8:26002607de9c 1745 }
mluis 2:14a5d6ad92d5 1746 }
mluis 2:14a5d6ad92d5 1747 else
mluis 2:14a5d6ad92d5 1748 {
mluis 2:14a5d6ad92d5 1749 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
mluis 2:14a5d6ad92d5 1750 // Re-enable default channels LC1, LC2, LC3
mluis 7:c16969e0f70f 1751 LoRaMacParams.ChannelsMask[0] = LoRaMacParams.ChannelsMask[0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) );
mluis 8:26002607de9c 1752 #elif defined( USE_BAND_470 )
mluis 8:26002607de9c 1753 // Re-enable default channels
mluis 8:26002607de9c 1754 memcpy1( ( uint8_t* )LoRaMacParams.ChannelsMask, ( uint8_t* )LoRaMacParamsDefaults.ChannelsMask, sizeof( LoRaMacParams.ChannelsMask ) );
mluis 2:14a5d6ad92d5 1755 #elif defined( USE_BAND_915 )
mluis 2:14a5d6ad92d5 1756 // Re-enable default channels
mluis 8:26002607de9c 1757 memcpy1( ( uint8_t* )LoRaMacParams.ChannelsMask, ( uint8_t* )LoRaMacParamsDefaults.ChannelsMask, sizeof( LoRaMacParams.ChannelsMask ) );
mluis 2:14a5d6ad92d5 1758 #elif defined( USE_BAND_915_HYBRID )
mluis 2:14a5d6ad92d5 1759 // Re-enable default channels
mluis 8:26002607de9c 1760 ReenableChannels( LoRaMacParamsDefaults.ChannelsMask[4], LoRaMacParams.ChannelsMask );
mluis 2:14a5d6ad92d5 1761 #else
mluis 2:14a5d6ad92d5 1762 #error "Please define a frequency band in the compiler options."
mluis 2:14a5d6ad92d5 1763 #endif
mluis 8:26002607de9c 1764 LoRaMacState &= ~LORAMAC_TX_RUNNING;
mluis 8:26002607de9c 1765
mluis 8:26002607de9c 1766 MacCommandsBufferIndex = 0;
mluis 3:b9d87593a8ae 1767 NodeAckRequested = false;
mluis 2:14a5d6ad92d5 1768 McpsConfirm.AckReceived = false;
mluis 2:14a5d6ad92d5 1769 McpsConfirm.NbRetries = AckTimeoutRetriesCounter;
mluis 2:14a5d6ad92d5 1770 if( IsUpLinkCounterFixed == false )
mluis 2:14a5d6ad92d5 1771 {
mluis 2:14a5d6ad92d5 1772 UpLinkCounter++;
mluis 2:14a5d6ad92d5 1773 }
mluis 2:14a5d6ad92d5 1774 }
mluis 2:14a5d6ad92d5 1775 }
mluis 2:14a5d6ad92d5 1776 }
mluis 2:14a5d6ad92d5 1777 // Handle reception for Class B and Class C
mluis 8:26002607de9c 1778 if( ( LoRaMacState & LORAMAC_RX ) == LORAMAC_RX )
mluis 2:14a5d6ad92d5 1779 {
mluis 8:26002607de9c 1780 LoRaMacState &= ~LORAMAC_RX;
mluis 2:14a5d6ad92d5 1781 }
mluis 8:26002607de9c 1782 if( LoRaMacState == LORAMAC_IDLE )
mluis 2:14a5d6ad92d5 1783 {
mluis 2:14a5d6ad92d5 1784 if( LoRaMacFlags.Bits.McpsReq == 1 )
mluis 2:14a5d6ad92d5 1785 {
mluis 2:14a5d6ad92d5 1786 LoRaMacPrimitives->MacMcpsConfirm( &McpsConfirm );
mluis 2:14a5d6ad92d5 1787 LoRaMacFlags.Bits.McpsReq = 0;
mluis 2:14a5d6ad92d5 1788 }
mluis 2:14a5d6ad92d5 1789
mluis 2:14a5d6ad92d5 1790 if( LoRaMacFlags.Bits.MlmeReq == 1 )
mluis 2:14a5d6ad92d5 1791 {
mluis 2:14a5d6ad92d5 1792 LoRaMacPrimitives->MacMlmeConfirm( &MlmeConfirm );
mluis 2:14a5d6ad92d5 1793 LoRaMacFlags.Bits.MlmeReq = 0;
mluis 2:14a5d6ad92d5 1794 }
mluis 2:14a5d6ad92d5 1795
mluis 8:26002607de9c 1796 // Procedure done. Reset variables.
mluis 2:14a5d6ad92d5 1797 LoRaMacFlags.Bits.MacDone = 0;
mluis 2:14a5d6ad92d5 1798 }
mluis 2:14a5d6ad92d5 1799 else
mluis 2:14a5d6ad92d5 1800 {
mluis 2:14a5d6ad92d5 1801 // Operation not finished restart timer
mluis 3:b9d87593a8ae 1802 TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT );
mluis 2:14a5d6ad92d5 1803 TimerStart( &MacStateCheckTimer );
mluis 2:14a5d6ad92d5 1804 }
mluis 2:14a5d6ad92d5 1805
mluis 2:14a5d6ad92d5 1806 if( LoRaMacFlags.Bits.McpsInd == 1 )
mluis 2:14a5d6ad92d5 1807 {
mluis 8:26002607de9c 1808 if( LoRaMacDeviceClass == CLASS_C )
mluis 8:26002607de9c 1809 {// Activate RX2 window for Class C
mluis 8:26002607de9c 1810 OnRxWindow2TimerEvent( );
mluis 8:26002607de9c 1811 }
mluis 8:26002607de9c 1812 if( LoRaMacFlags.Bits.McpsIndSkip == 0 )
mluis 8:26002607de9c 1813 {
mluis 8:26002607de9c 1814 LoRaMacPrimitives->MacMcpsIndication( &McpsIndication );
mluis 8:26002607de9c 1815 }
mluis 8:26002607de9c 1816 LoRaMacFlags.Bits.McpsIndSkip = 0;
mluis 2:14a5d6ad92d5 1817 LoRaMacFlags.Bits.McpsInd = 0;
mluis 2:14a5d6ad92d5 1818 }
mluis 2:14a5d6ad92d5 1819 }
mluis 2:14a5d6ad92d5 1820
mluis 2:14a5d6ad92d5 1821 static void OnTxDelayedTimerEvent( void )
mluis 2:14a5d6ad92d5 1822 {
mluis 7:c16969e0f70f 1823 LoRaMacHeader_t macHdr;
mluis 7:c16969e0f70f 1824 LoRaMacFrameCtrl_t fCtrl;
mluis 7:c16969e0f70f 1825
mluis 2:14a5d6ad92d5 1826 TimerStop( &TxDelayedTimer );
mluis 8:26002607de9c 1827 LoRaMacState &= ~LORAMAC_TX_DELAYED;
mluis 2:14a5d6ad92d5 1828
mluis 7:c16969e0f70f 1829 if( ( LoRaMacFlags.Bits.MlmeReq == 1 ) && ( MlmeConfirm.MlmeRequest == MLME_JOIN ) )
mluis 7:c16969e0f70f 1830 {
mluis 8:26002607de9c 1831 ResetMacParameters( );
mluis 8:26002607de9c 1832 // Add a +1, since we start to count from 0
mluis 8:26002607de9c 1833 LoRaMacParams.ChannelsDatarate = AlternateDatarate( JoinRequestTrials + 1 );
mluis 8:26002607de9c 1834
mluis 7:c16969e0f70f 1835 macHdr.Value = 0;
mluis 7:c16969e0f70f 1836 macHdr.Bits.MType = FRAME_TYPE_JOIN_REQ;
mluis 7:c16969e0f70f 1837
mluis 7:c16969e0f70f 1838 fCtrl.Value = 0;
mluis 7:c16969e0f70f 1839 fCtrl.Bits.Adr = AdrCtrlOn;
mluis 7:c16969e0f70f 1840
mluis 8:26002607de9c 1841 /* In case of join request retransmissions, the stack must prepare
mluis 7:c16969e0f70f 1842 * the frame again, because the network server keeps track of the random
mluis 7:c16969e0f70f 1843 * LoRaMacDevNonce values to prevent reply attacks. */
mluis 7:c16969e0f70f 1844 PrepareFrame( &macHdr, &fCtrl, 0, NULL, 0 );
mluis 7:c16969e0f70f 1845 }
mluis 7:c16969e0f70f 1846
mluis 2:14a5d6ad92d5 1847 ScheduleTx( );
mluis 2:14a5d6ad92d5 1848 }
mluis 2:14a5d6ad92d5 1849
mluis 2:14a5d6ad92d5 1850 static void OnRxWindow1TimerEvent( void )
mluis 2:14a5d6ad92d5 1851 {
mluis 2:14a5d6ad92d5 1852 TimerStop( &RxWindowTimer1 );
mluis 2:14a5d6ad92d5 1853 RxSlot = 0;
mluis 2:14a5d6ad92d5 1854
mluis 2:14a5d6ad92d5 1855 if( LoRaMacDeviceClass == CLASS_C )
mluis 2:14a5d6ad92d5 1856 {
mluis 2:14a5d6ad92d5 1857 Radio.Standby( );
mluis 2:14a5d6ad92d5 1858 }
mluis 2:14a5d6ad92d5 1859
mluis 2:14a5d6ad92d5 1860 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
mluis 8:26002607de9c 1861 RxWindowSetup( Channels[Channel].Frequency, RxWindowsParams[0].Datarate, RxWindowsParams[0].Bandwidth, RxWindowsParams[0].RxWindowTimeout, false );
mluis 8:26002607de9c 1862 #elif defined( USE_BAND_470 )
mluis 8:26002607de9c 1863 RxWindowSetup( LORAMAC_FIRST_RX1_CHANNEL + ( Channel % 48 ) * LORAMAC_STEPWIDTH_RX1_CHANNEL, RxWindowsParams[0].Datarate, RxWindowsParams[0].Bandwidth, RxWindowsParams[0].RxWindowTimeout, false );
mluis 2:14a5d6ad92d5 1864 #elif ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) )
mluis 8:26002607de9c 1865 RxWindowSetup( LORAMAC_FIRST_RX1_CHANNEL + ( Channel % 8 ) * LORAMAC_STEPWIDTH_RX1_CHANNEL, RxWindowsParams[0].Datarate, RxWindowsParams[0].Bandwidth, RxWindowsParams[0].RxWindowTimeout, false );
mluis 2:14a5d6ad92d5 1866 #else
mluis 2:14a5d6ad92d5 1867 #error "Please define a frequency band in the compiler options."
mluis 2:14a5d6ad92d5 1868 #endif
mluis 2:14a5d6ad92d5 1869 }
mluis 2:14a5d6ad92d5 1870
mluis 2:14a5d6ad92d5 1871 static void OnRxWindow2TimerEvent( void )
mluis 2:14a5d6ad92d5 1872 {
mluis 8:26002607de9c 1873 bool rxContinuousMode = false;
mluis 2:14a5d6ad92d5 1874
mluis 2:14a5d6ad92d5 1875 TimerStop( &RxWindowTimer2 );
mluis 8:26002607de9c 1876
mluis 8:26002607de9c 1877 if( LoRaMacDeviceClass == CLASS_C )
mluis 4:37c12dbc8dc7 1878 {
mluis 8:26002607de9c 1879 rxContinuousMode = true;
mluis 2:14a5d6ad92d5 1880 }
mluis 8:26002607de9c 1881 if( RxWindowSetup( LoRaMacParams.Rx2Channel.Frequency, RxWindowsParams[1].Datarate, RxWindowsParams[1].Bandwidth, RxWindowsParams[1].RxWindowTimeout, rxContinuousMode ) == true )
mluis 2:14a5d6ad92d5 1882 {
mluis 8:26002607de9c 1883 RxSlot = 1;
mluis 2:14a5d6ad92d5 1884 }
mluis 2:14a5d6ad92d5 1885 }
mluis 2:14a5d6ad92d5 1886
mluis 2:14a5d6ad92d5 1887 static void OnAckTimeoutTimerEvent( void )
mluis 2:14a5d6ad92d5 1888 {
mluis 2:14a5d6ad92d5 1889 TimerStop( &AckTimeoutTimer );
mluis 2:14a5d6ad92d5 1890
mluis 2:14a5d6ad92d5 1891 if( NodeAckRequested == true )
mluis 2:14a5d6ad92d5 1892 {
mluis 2:14a5d6ad92d5 1893 AckTimeoutRetry = true;
mluis 8:26002607de9c 1894 LoRaMacState &= ~LORAMAC_ACK_REQ;
mluis 2:14a5d6ad92d5 1895 }
mluis 2:14a5d6ad92d5 1896 if( LoRaMacDeviceClass == CLASS_C )
mluis 2:14a5d6ad92d5 1897 {
mluis 2:14a5d6ad92d5 1898 LoRaMacFlags.Bits.MacDone = 1;
mluis 2:14a5d6ad92d5 1899 }
mluis 2:14a5d6ad92d5 1900 }
mluis 2:14a5d6ad92d5 1901
mluis 3:b9d87593a8ae 1902 static bool SetNextChannel( TimerTime_t* time )
mluis 2:14a5d6ad92d5 1903 {
mluis 0:91d1a7783bb9 1904 uint8_t nbEnabledChannels = 0;
mluis 3:b9d87593a8ae 1905 uint8_t delayTx = 0;
mluis 0:91d1a7783bb9 1906 uint8_t enabledChannels[LORA_MAX_NB_CHANNELS];
mluis 2:14a5d6ad92d5 1907 TimerTime_t nextTxDelay = ( TimerTime_t )( -1 );
mluis 0:91d1a7783bb9 1908
mluis 1:91e4e6c60d1e 1909 memset1( enabledChannels, 0, LORA_MAX_NB_CHANNELS );
mluis 0:91d1a7783bb9 1910
mluis 2:14a5d6ad92d5 1911 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 3:b9d87593a8ae 1912 if( CountNbEnabled125kHzChannels( ChannelsMaskRemaining ) == 0 )
mluis 3:b9d87593a8ae 1913 { // Restore default channels
mluis 7:c16969e0f70f 1914 memcpy1( ( uint8_t* ) ChannelsMaskRemaining, ( uint8_t* ) LoRaMacParams.ChannelsMask, 8 );
mluis 3:b9d87593a8ae 1915 }
mluis 7:c16969e0f70f 1916 if( ( LoRaMacParams.ChannelsDatarate >= DR_4 ) && ( ( ChannelsMaskRemaining[4] & 0x00FF ) == 0 ) )
mluis 3:b9d87593a8ae 1917 { // Make sure, that the channels are activated
mluis 7:c16969e0f70f 1918 ChannelsMaskRemaining[4] = LoRaMacParams.ChannelsMask[4];
mluis 3:b9d87593a8ae 1919 }
mluis 8:26002607de9c 1920 #elif defined( USE_BAND_470 )
mluis 8:26002607de9c 1921 if( ( CountBits( LoRaMacParams.ChannelsMask[0], 16 ) == 0 ) &&
mluis 8:26002607de9c 1922 ( CountBits( LoRaMacParams.ChannelsMask[1], 16 ) == 0 ) &&
mluis 8:26002607de9c 1923 ( CountBits( LoRaMacParams.ChannelsMask[2], 16 ) == 0 ) &&
mluis 8:26002607de9c 1924 ( CountBits( LoRaMacParams.ChannelsMask[3], 16 ) == 0 ) &&
mluis 8:26002607de9c 1925 ( CountBits( LoRaMacParams.ChannelsMask[4], 16 ) == 0 ) &&
mluis 8:26002607de9c 1926 ( CountBits( LoRaMacParams.ChannelsMask[5], 16 ) == 0 ) )
mluis 8:26002607de9c 1927 {
mluis 8:26002607de9c 1928 memcpy1( ( uint8_t* )LoRaMacParams.ChannelsMask, ( uint8_t* )LoRaMacParamsDefaults.ChannelsMask, sizeof( LoRaMacParams.ChannelsMask ) );
mluis 8:26002607de9c 1929 }
mluis 3:b9d87593a8ae 1930 #else
mluis 7:c16969e0f70f 1931 if( CountBits( LoRaMacParams.ChannelsMask[0], 16 ) == 0 )
mluis 3:b9d87593a8ae 1932 {
mluis 3:b9d87593a8ae 1933 // Re-enable default channels, if no channel is enabled
mluis 7:c16969e0f70f 1934 LoRaMacParams.ChannelsMask[0] = LoRaMacParams.ChannelsMask[0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) );
mluis 2:14a5d6ad92d5 1935 }
mluis 2:14a5d6ad92d5 1936 #endif
mluis 2:14a5d6ad92d5 1937
mluis 0:91d1a7783bb9 1938 // Update Aggregated duty cycle
mluis 4:37c12dbc8dc7 1939 if( AggregatedTimeOff <= TimerGetElapsedTime( AggregatedLastTxDoneTime ) )
mluis 0:91d1a7783bb9 1940 {
mluis 0:91d1a7783bb9 1941 AggregatedTimeOff = 0;
mluis 2:14a5d6ad92d5 1942
mluis 2:14a5d6ad92d5 1943 // Update bands Time OFF
mluis 2:14a5d6ad92d5 1944 for( uint8_t i = 0; i < LORA_MAX_NB_BANDS; i++ )
mluis 0:91d1a7783bb9 1945 {
mluis 8:26002607de9c 1946 if( ( IsLoRaMacNetworkJoined == false ) || ( DutyCycleOn == true ) )
mluis 0:91d1a7783bb9 1947 {
mluis 4:37c12dbc8dc7 1948 if( Bands[i].TimeOff <= TimerGetElapsedTime( Bands[i].LastTxDoneTime ) )
mluis 2:14a5d6ad92d5 1949 {
mluis 2:14a5d6ad92d5 1950 Bands[i].TimeOff = 0;
mluis 2:14a5d6ad92d5 1951 }
mluis 2:14a5d6ad92d5 1952 if( Bands[i].TimeOff != 0 )
mluis 2:14a5d6ad92d5 1953 {
mluis 8:26002607de9c 1954 nextTxDelay = MIN( Bands[i].TimeOff - TimerGetElapsedTime( Bands[i].LastTxDoneTime ), nextTxDelay );
mluis 2:14a5d6ad92d5 1955 }
mluis 2:14a5d6ad92d5 1956 }
mluis 2:14a5d6ad92d5 1957 else
mluis 2:14a5d6ad92d5 1958 {
mluis 8:26002607de9c 1959 if( DutyCycleOn == false )
mluis 8:26002607de9c 1960 {
mluis 8:26002607de9c 1961 Bands[i].TimeOff = 0;
mluis 8:26002607de9c 1962 }
mluis 0:91d1a7783bb9 1963 }
mluis 2:14a5d6ad92d5 1964 }
mluis 2:14a5d6ad92d5 1965
mluis 2:14a5d6ad92d5 1966 // Search how many channels are enabled
mluis 2:14a5d6ad92d5 1967 for( uint8_t i = 0, k = 0; i < LORA_MAX_NB_CHANNELS; i += 16, k++ )
mluis 2:14a5d6ad92d5 1968 {
mluis 2:14a5d6ad92d5 1969 for( uint8_t j = 0; j < 16; j++ )
mluis 0:91d1a7783bb9 1970 {
mluis 2:14a5d6ad92d5 1971 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 2:14a5d6ad92d5 1972 if( ( ChannelsMaskRemaining[k] & ( 1 << j ) ) != 0 )
mluis 2:14a5d6ad92d5 1973 #else
mluis 7:c16969e0f70f 1974 if( ( LoRaMacParams.ChannelsMask[k] & ( 1 << j ) ) != 0 )
mluis 2:14a5d6ad92d5 1975 #endif
mluis 2:14a5d6ad92d5 1976 {
mluis 2:14a5d6ad92d5 1977 if( Channels[i + j].Frequency == 0 )
mluis 2:14a5d6ad92d5 1978 { // Check if the channel is enabled
mluis 2:14a5d6ad92d5 1979 continue;
mluis 2:14a5d6ad92d5 1980 }
mluis 4:37c12dbc8dc7 1981 #if defined( USE_BAND_868 ) || defined( USE_BAND_433 ) || defined( USE_BAND_780 )
mluis 4:37c12dbc8dc7 1982 if( IsLoRaMacNetworkJoined == false )
mluis 4:37c12dbc8dc7 1983 {
mluis 4:37c12dbc8dc7 1984 if( ( JOIN_CHANNELS & ( 1 << j ) ) == 0 )
mluis 4:37c12dbc8dc7 1985 {
mluis 4:37c12dbc8dc7 1986 continue;
mluis 4:37c12dbc8dc7 1987 }
mluis 4:37c12dbc8dc7 1988 }
mluis 4:37c12dbc8dc7 1989 #endif
mluis 7:c16969e0f70f 1990 if( ( ( Channels[i + j].DrRange.Fields.Min <= LoRaMacParams.ChannelsDatarate ) &&
mluis 7:c16969e0f70f 1991 ( LoRaMacParams.ChannelsDatarate <= Channels[i + j].DrRange.Fields.Max ) ) == false )
mluis 2:14a5d6ad92d5 1992 { // Check if the current channel selection supports the given datarate
mluis 2:14a5d6ad92d5 1993 continue;
mluis 2:14a5d6ad92d5 1994 }
mluis 2:14a5d6ad92d5 1995 if( Bands[Channels[i + j].Band].TimeOff > 0 )
mluis 2:14a5d6ad92d5 1996 { // Check if the band is available for transmission
mluis 3:b9d87593a8ae 1997 delayTx++;
mluis 2:14a5d6ad92d5 1998 continue;
mluis 2:14a5d6ad92d5 1999 }
mluis 2:14a5d6ad92d5 2000 enabledChannels[nbEnabledChannels++] = i + j;
mluis 2:14a5d6ad92d5 2001 }
mluis 2:14a5d6ad92d5 2002 }
mluis 2:14a5d6ad92d5 2003 }
mluis 2:14a5d6ad92d5 2004 }
mluis 2:14a5d6ad92d5 2005 else
mluis 2:14a5d6ad92d5 2006 {
mluis 3:b9d87593a8ae 2007 delayTx++;
mluis 4:37c12dbc8dc7 2008 nextTxDelay = AggregatedTimeOff - TimerGetElapsedTime( AggregatedLastTxDoneTime );
mluis 2:14a5d6ad92d5 2009 }
mluis 2:14a5d6ad92d5 2010
mluis 2:14a5d6ad92d5 2011 if( nbEnabledChannels > 0 )
mluis 2:14a5d6ad92d5 2012 {
mluis 2:14a5d6ad92d5 2013 Channel = enabledChannels[randr( 0, nbEnabledChannels - 1 )];
mluis 2:14a5d6ad92d5 2014 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 3:b9d87593a8ae 2015 if( Channel < ( LORA_MAX_NB_CHANNELS - 8 ) )
mluis 3:b9d87593a8ae 2016 {
mluis 3:b9d87593a8ae 2017 DisableChannelInMask( Channel, ChannelsMaskRemaining );
mluis 3:b9d87593a8ae 2018 }
mluis 2:14a5d6ad92d5 2019 #endif
mluis 3:b9d87593a8ae 2020 *time = 0;
mluis 3:b9d87593a8ae 2021 return true;
mluis 2:14a5d6ad92d5 2022 }
mluis 2:14a5d6ad92d5 2023 else
mluis 2:14a5d6ad92d5 2024 {
mluis 3:b9d87593a8ae 2025 if( delayTx > 0 )
mluis 3:b9d87593a8ae 2026 {
mluis 3:b9d87593a8ae 2027 // Delay transmission due to AggregatedTimeOff or to a band time off
mluis 3:b9d87593a8ae 2028 *time = nextTxDelay;
mluis 3:b9d87593a8ae 2029 return true;
mluis 3:b9d87593a8ae 2030 }
mluis 3:b9d87593a8ae 2031 // Datarate not supported by any channel
mluis 3:b9d87593a8ae 2032 *time = 0;
mluis 3:b9d87593a8ae 2033 return false;
mluis 2:14a5d6ad92d5 2034 }
mluis 2:14a5d6ad92d5 2035 }
mluis 2:14a5d6ad92d5 2036
mluis 8:26002607de9c 2037 static bool RxWindowSetup( uint32_t freq, int8_t datarate, uint32_t bandwidth, uint16_t timeout, bool rxContinuous )
mluis 2:14a5d6ad92d5 2038 {
mluis 2:14a5d6ad92d5 2039 uint8_t downlinkDatarate = Datarates[datarate];
mluis 2:14a5d6ad92d5 2040 RadioModems_t modem;
mluis 2:14a5d6ad92d5 2041
mluis 2:14a5d6ad92d5 2042 if( Radio.GetStatus( ) == RF_IDLE )
mluis 2:14a5d6ad92d5 2043 {
mluis 2:14a5d6ad92d5 2044 Radio.SetChannel( freq );
mluis 2:14a5d6ad92d5 2045
mluis 2:14a5d6ad92d5 2046 // Store downlink datarate
mluis 2:14a5d6ad92d5 2047 McpsIndication.RxDatarate = ( uint8_t ) datarate;
mluis 2:14a5d6ad92d5 2048
mluis 2:14a5d6ad92d5 2049 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
mluis 2:14a5d6ad92d5 2050 if( datarate == DR_7 )
mluis 2:14a5d6ad92d5 2051 {
mluis 2:14a5d6ad92d5 2052 modem = MODEM_FSK;
mluis 8:26002607de9c 2053 Radio.SetRxConfig( modem, 50e3, downlinkDatarate * 1e3, 0, 83.333e3, 5, timeout, false, 0, true, 0, 0, false, rxContinuous );
mluis 2:14a5d6ad92d5 2054 }
mluis 2:14a5d6ad92d5 2055 else
mluis 2:14a5d6ad92d5 2056 {
mluis 2:14a5d6ad92d5 2057 modem = MODEM_LORA;
mluis 2:14a5d6ad92d5 2058 Radio.SetRxConfig( modem, bandwidth, downlinkDatarate, 1, 0, 8, timeout, false, 0, false, 0, 0, true, rxContinuous );
mluis 2:14a5d6ad92d5 2059 }
mluis 8:26002607de9c 2060 #elif defined( USE_BAND_470 ) || defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 2:14a5d6ad92d5 2061 modem = MODEM_LORA;
mluis 2:14a5d6ad92d5 2062 Radio.SetRxConfig( modem, bandwidth, downlinkDatarate, 1, 0, 8, timeout, false, 0, false, 0, 0, true, rxContinuous );
mluis 2:14a5d6ad92d5 2063 #endif
mluis 2:14a5d6ad92d5 2064
mluis 2:14a5d6ad92d5 2065 if( RepeaterSupport == true )
mluis 2:14a5d6ad92d5 2066 {
mluis 4:37c12dbc8dc7 2067 Radio.SetMaxPayloadLength( modem, MaxPayloadOfDatarateRepeater[datarate] + LORA_MAC_FRMPAYLOAD_OVERHEAD );
mluis 2:14a5d6ad92d5 2068 }
mluis 2:14a5d6ad92d5 2069 else
mluis 2:14a5d6ad92d5 2070 {
mluis 4:37c12dbc8dc7 2071 Radio.SetMaxPayloadLength( modem, MaxPayloadOfDatarate[datarate] + LORA_MAC_FRMPAYLOAD_OVERHEAD );
mluis 2:14a5d6ad92d5 2072 }
mluis 2:14a5d6ad92d5 2073
mluis 2:14a5d6ad92d5 2074 if( rxContinuous == false )
mluis 2:14a5d6ad92d5 2075 {
mluis 7:c16969e0f70f 2076 Radio.Rx( LoRaMacParams.MaxRxWindow );
mluis 2:14a5d6ad92d5 2077 }
mluis 2:14a5d6ad92d5 2078 else
mluis 2:14a5d6ad92d5 2079 {
mluis 2:14a5d6ad92d5 2080 Radio.Rx( 0 ); // Continuous mode
mluis 2:14a5d6ad92d5 2081 }
mluis 8:26002607de9c 2082 return true;
mluis 2:14a5d6ad92d5 2083 }
mluis 8:26002607de9c 2084 return false;
mluis 2:14a5d6ad92d5 2085 }
mluis 2:14a5d6ad92d5 2086
mluis 7:c16969e0f70f 2087 static bool Rx2FreqInRange( uint32_t freq )
mluis 7:c16969e0f70f 2088 {
mluis 7:c16969e0f70f 2089 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
mluis 7:c16969e0f70f 2090 if( Radio.CheckRfFrequency( freq ) == true )
mluis 8:26002607de9c 2091 #elif defined( USE_BAND_470 ) || defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 7:c16969e0f70f 2092 if( ( Radio.CheckRfFrequency( freq ) == true ) &&
mluis 8:26002607de9c 2093 ( freq >= LORAMAC_FIRST_RX1_CHANNEL ) &&
mluis 8:26002607de9c 2094 ( freq <= LORAMAC_LAST_RX1_CHANNEL ) &&
mluis 8:26002607de9c 2095 ( ( ( freq - ( uint32_t ) LORAMAC_FIRST_RX1_CHANNEL ) % ( uint32_t ) LORAMAC_STEPWIDTH_RX1_CHANNEL ) == 0 ) )
mluis 7:c16969e0f70f 2096 #endif
mluis 7:c16969e0f70f 2097 {
mluis 7:c16969e0f70f 2098 return true;
mluis 7:c16969e0f70f 2099 }
mluis 7:c16969e0f70f 2100 return false;
mluis 7:c16969e0f70f 2101 }
mluis 7:c16969e0f70f 2102
mluis 2:14a5d6ad92d5 2103 static bool ValidatePayloadLength( uint8_t lenN, int8_t datarate, uint8_t fOptsLen )
mluis 2:14a5d6ad92d5 2104 {
mluis 2:14a5d6ad92d5 2105 uint16_t maxN = 0;
mluis 2:14a5d6ad92d5 2106 uint16_t payloadSize = 0;
mluis 2:14a5d6ad92d5 2107
mluis 2:14a5d6ad92d5 2108 // Get the maximum payload length
mluis 2:14a5d6ad92d5 2109 if( RepeaterSupport == true )
mluis 2:14a5d6ad92d5 2110 {
mluis 2:14a5d6ad92d5 2111 maxN = MaxPayloadOfDatarateRepeater[datarate];
mluis 2:14a5d6ad92d5 2112 }
mluis 2:14a5d6ad92d5 2113 else
mluis 2:14a5d6ad92d5 2114 {
mluis 2:14a5d6ad92d5 2115 maxN = MaxPayloadOfDatarate[datarate];
mluis 2:14a5d6ad92d5 2116 }
mluis 2:14a5d6ad92d5 2117
mluis 2:14a5d6ad92d5 2118 // Calculate the resulting payload size
mluis 2:14a5d6ad92d5 2119 payloadSize = ( lenN + fOptsLen );
mluis 2:14a5d6ad92d5 2120
mluis 2:14a5d6ad92d5 2121 // Validation of the application payload size
mluis 2:14a5d6ad92d5 2122 if( ( payloadSize <= maxN ) && ( payloadSize <= LORAMAC_PHY_MAXPAYLOAD ) )
mluis 2:14a5d6ad92d5 2123 {
mluis 2:14a5d6ad92d5 2124 return true;
mluis 2:14a5d6ad92d5 2125 }
mluis 2:14a5d6ad92d5 2126 return false;
mluis 2:14a5d6ad92d5 2127 }
mluis 2:14a5d6ad92d5 2128
mluis 4:37c12dbc8dc7 2129 static uint8_t CountBits( uint16_t mask, uint8_t nbBits )
mluis 4:37c12dbc8dc7 2130 {
mluis 4:37c12dbc8dc7 2131 uint8_t nbActiveBits = 0;
mluis 4:37c12dbc8dc7 2132
mluis 4:37c12dbc8dc7 2133 for( uint8_t j = 0; j < nbBits; j++ )
mluis 4:37c12dbc8dc7 2134 {
mluis 4:37c12dbc8dc7 2135 if( ( mask & ( 1 << j ) ) == ( 1 << j ) )
mluis 4:37c12dbc8dc7 2136 {
mluis 4:37c12dbc8dc7 2137 nbActiveBits++;
mluis 4:37c12dbc8dc7 2138 }
mluis 4:37c12dbc8dc7 2139 }
mluis 4:37c12dbc8dc7 2140 return nbActiveBits;
mluis 4:37c12dbc8dc7 2141 }
mluis 4:37c12dbc8dc7 2142
mluis 2:14a5d6ad92d5 2143 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 2:14a5d6ad92d5 2144 static uint8_t CountNbEnabled125kHzChannels( uint16_t *channelsMask )
mluis 2:14a5d6ad92d5 2145 {
mluis 2:14a5d6ad92d5 2146 uint8_t nb125kHzChannels = 0;
mluis 2:14a5d6ad92d5 2147
mluis 2:14a5d6ad92d5 2148 for( uint8_t i = 0, k = 0; i < LORA_MAX_NB_CHANNELS - 8; i += 16, k++ )
mluis 2:14a5d6ad92d5 2149 {
mluis 4:37c12dbc8dc7 2150 nb125kHzChannels += CountBits( channelsMask[k], 16 );
mluis 2:14a5d6ad92d5 2151 }
mluis 2:14a5d6ad92d5 2152
mluis 2:14a5d6ad92d5 2153 return nb125kHzChannels;
mluis 2:14a5d6ad92d5 2154 }
mluis 4:37c12dbc8dc7 2155
mluis 4:37c12dbc8dc7 2156 #if defined( USE_BAND_915_HYBRID )
mluis 8:26002607de9c 2157 static void ReenableChannels( uint16_t mask, uint16_t* channelsMask )
mluis 4:37c12dbc8dc7 2158 {
mluis 4:37c12dbc8dc7 2159 uint16_t blockMask = mask;
mluis 4:37c12dbc8dc7 2160
mluis 4:37c12dbc8dc7 2161 for( uint8_t i = 0, j = 0; i < 4; i++, j += 2 )
mluis 4:37c12dbc8dc7 2162 {
mluis 8:26002607de9c 2163 channelsMask[i] = 0;
mluis 4:37c12dbc8dc7 2164 if( ( blockMask & ( 1 << j ) ) != 0 )
mluis 4:37c12dbc8dc7 2165 {
mluis 8:26002607de9c 2166 channelsMask[i] |= 0x00FF;
mluis 4:37c12dbc8dc7 2167 }
mluis 4:37c12dbc8dc7 2168 if( ( blockMask & ( 1 << ( j + 1 ) ) ) != 0 )
mluis 4:37c12dbc8dc7 2169 {
mluis 8:26002607de9c 2170 channelsMask[i] |= 0xFF00;
mluis 4:37c12dbc8dc7 2171 }
mluis 4:37c12dbc8dc7 2172 }
mluis 8:26002607de9c 2173 channelsMask[4] = blockMask;
mluis 8:26002607de9c 2174 channelsMask[5] = 0x0000;
mluis 4:37c12dbc8dc7 2175 }
mluis 4:37c12dbc8dc7 2176
mluis 8:26002607de9c 2177 static bool ValidateChannelMask( uint16_t* channelsMask )
mluis 4:37c12dbc8dc7 2178 {
mluis 4:37c12dbc8dc7 2179 bool chanMaskState = false;
mluis 4:37c12dbc8dc7 2180 uint16_t block1 = 0;
mluis 4:37c12dbc8dc7 2181 uint16_t block2 = 0;
mluis 4:37c12dbc8dc7 2182 uint8_t index = 0;
mluis 4:37c12dbc8dc7 2183
mluis 4:37c12dbc8dc7 2184 for( uint8_t i = 0; i < 4; i++ )
mluis 4:37c12dbc8dc7 2185 {
mluis 8:26002607de9c 2186 block1 = channelsMask[i] & 0x00FF;
mluis 8:26002607de9c 2187 block2 = channelsMask[i] & 0xFF00;
mluis 4:37c12dbc8dc7 2188
mluis 4:37c12dbc8dc7 2189 if( ( CountBits( block1, 16 ) > 5 ) && ( chanMaskState == false ) )
mluis 4:37c12dbc8dc7 2190 {
mluis 8:26002607de9c 2191 channelsMask[i] &= block1;
mluis 8:26002607de9c 2192 channelsMask[4] = 1 << ( i * 2 );
mluis 4:37c12dbc8dc7 2193 chanMaskState = true;
mluis 4:37c12dbc8dc7 2194 index = i;
mluis 4:37c12dbc8dc7 2195 }
mluis 4:37c12dbc8dc7 2196 else if( ( CountBits( block2, 16 ) > 5 ) && ( chanMaskState == false ) )
mluis 4:37c12dbc8dc7 2197 {
mluis 8:26002607de9c 2198 channelsMask[i] &= block2;
mluis 8:26002607de9c 2199 channelsMask[4] = 1 << ( i * 2 + 1 );
mluis 4:37c12dbc8dc7 2200 chanMaskState = true;
mluis 4:37c12dbc8dc7 2201 index = i;
mluis 4:37c12dbc8dc7 2202 }
mluis 4:37c12dbc8dc7 2203 }
mluis 4:37c12dbc8dc7 2204
mluis 4:37c12dbc8dc7 2205 // Do only change the channel mask, if we have found a valid block.
mluis 4:37c12dbc8dc7 2206 if( chanMaskState == true )
mluis 4:37c12dbc8dc7 2207 {
mluis 4:37c12dbc8dc7 2208 for( uint8_t i = 0; i < 4; i++ )
mluis 4:37c12dbc8dc7 2209 {
mluis 4:37c12dbc8dc7 2210 if( i != index )
mluis 4:37c12dbc8dc7 2211 {
mluis 8:26002607de9c 2212 channelsMask[i] = 0;
mluis 4:37c12dbc8dc7 2213 }
mluis 4:37c12dbc8dc7 2214 }
mluis 4:37c12dbc8dc7 2215 }
mluis 4:37c12dbc8dc7 2216 return chanMaskState;
mluis 4:37c12dbc8dc7 2217 }
mluis 4:37c12dbc8dc7 2218 #endif
mluis 2:14a5d6ad92d5 2219 #endif
mluis 2:14a5d6ad92d5 2220
mluis 8:26002607de9c 2221 static bool ValidateDatarate( int8_t datarate, uint16_t* channelsMask )
mluis 8:26002607de9c 2222 {
mluis 8:26002607de9c 2223 if( ValueInRange( datarate, LORAMAC_TX_MIN_DATARATE, LORAMAC_TX_MAX_DATARATE ) == false )
mluis 8:26002607de9c 2224 {
mluis 8:26002607de9c 2225 return false;
mluis 8:26002607de9c 2226 }
mluis 8:26002607de9c 2227 for( uint8_t i = 0, k = 0; i < LORA_MAX_NB_CHANNELS; i += 16, k++ )
mluis 8:26002607de9c 2228 {
mluis 8:26002607de9c 2229 for( uint8_t j = 0; j < 16; j++ )
mluis 8:26002607de9c 2230 {
mluis 8:26002607de9c 2231 if( ( ( channelsMask[k] & ( 1 << j ) ) != 0 ) )
mluis 8:26002607de9c 2232 {// Check datarate validity for enabled channels
mluis 8:26002607de9c 2233 if( ValueInRange( datarate, Channels[i + j].DrRange.Fields.Min, Channels[i + j].DrRange.Fields.Max ) == true )
mluis 8:26002607de9c 2234 {
mluis 8:26002607de9c 2235 // At least 1 channel has been found we can return OK.
mluis 8:26002607de9c 2236 return true;
mluis 8:26002607de9c 2237 }
mluis 8:26002607de9c 2238 }
mluis 8:26002607de9c 2239 }
mluis 8:26002607de9c 2240 }
mluis 8:26002607de9c 2241 return false;
mluis 8:26002607de9c 2242 }
mluis 8:26002607de9c 2243
mluis 8:26002607de9c 2244 static int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower )
mluis 2:14a5d6ad92d5 2245 {
mluis 2:14a5d6ad92d5 2246 int8_t resultTxPower = txPower;
mluis 8:26002607de9c 2247
mluis 8:26002607de9c 2248 // Limit tx power to the band max
mluis 8:26002607de9c 2249 resultTxPower = MAX( txPower, maxBandTxPower );
mluis 8:26002607de9c 2250
mluis 2:14a5d6ad92d5 2251 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 7:c16969e0f70f 2252 if( ( LoRaMacParams.ChannelsDatarate == DR_4 ) ||
mluis 7:c16969e0f70f 2253 ( ( LoRaMacParams.ChannelsDatarate >= DR_8 ) && ( LoRaMacParams.ChannelsDatarate <= DR_13 ) ) )
mluis 2:14a5d6ad92d5 2254 {// Limit tx power to max 26dBm
mluis 2:14a5d6ad92d5 2255 resultTxPower = MAX( txPower, TX_POWER_26_DBM );
mluis 2:14a5d6ad92d5 2256 }
mluis 2:14a5d6ad92d5 2257 else
mluis 2:14a5d6ad92d5 2258 {
mluis 7:c16969e0f70f 2259 if( CountNbEnabled125kHzChannels( LoRaMacParams.ChannelsMask ) < 50 )
mluis 2:14a5d6ad92d5 2260 {// Limit tx power to max 21dBm
mluis 2:14a5d6ad92d5 2261 resultTxPower = MAX( txPower, TX_POWER_20_DBM );
mluis 2:14a5d6ad92d5 2262 }
mluis 2:14a5d6ad92d5 2263 }
mluis 2:14a5d6ad92d5 2264 #endif
mluis 2:14a5d6ad92d5 2265 return resultTxPower;
mluis 2:14a5d6ad92d5 2266 }
mluis 2:14a5d6ad92d5 2267
mluis 2:14a5d6ad92d5 2268 static bool ValueInRange( int8_t value, int8_t min, int8_t max )
mluis 2:14a5d6ad92d5 2269 {
mluis 2:14a5d6ad92d5 2270 if( ( value >= min ) && ( value <= max ) )
mluis 2:14a5d6ad92d5 2271 {
mluis 2:14a5d6ad92d5 2272 return true;
mluis 2:14a5d6ad92d5 2273 }
mluis 2:14a5d6ad92d5 2274 return false;
mluis 2:14a5d6ad92d5 2275 }
mluis 2:14a5d6ad92d5 2276
mluis 2:14a5d6ad92d5 2277 static bool DisableChannelInMask( uint8_t id, uint16_t* mask )
mluis 2:14a5d6ad92d5 2278 {
mluis 2:14a5d6ad92d5 2279 uint8_t index = 0;
mluis 2:14a5d6ad92d5 2280 index = id / 16;
mluis 2:14a5d6ad92d5 2281
mluis 2:14a5d6ad92d5 2282 if( ( index > 4 ) || ( id >= LORA_MAX_NB_CHANNELS ) )
mluis 2:14a5d6ad92d5 2283 {
mluis 2:14a5d6ad92d5 2284 return false;
mluis 2:14a5d6ad92d5 2285 }
mluis 2:14a5d6ad92d5 2286
mluis 2:14a5d6ad92d5 2287 // Deactivate channel
mluis 2:14a5d6ad92d5 2288 mask[index] &= ~( 1 << ( id % 16 ) );
mluis 2:14a5d6ad92d5 2289
mluis 2:14a5d6ad92d5 2290 return true;
mluis 2:14a5d6ad92d5 2291 }
mluis 2:14a5d6ad92d5 2292
mluis 2:14a5d6ad92d5 2293 static bool AdrNextDr( bool adrEnabled, bool updateChannelMask, int8_t* datarateOut )
mluis 2:14a5d6ad92d5 2294 {
mluis 2:14a5d6ad92d5 2295 bool adrAckReq = false;
mluis 7:c16969e0f70f 2296 int8_t datarate = LoRaMacParams.ChannelsDatarate;
mluis 2:14a5d6ad92d5 2297
mluis 2:14a5d6ad92d5 2298 if( adrEnabled == true )
mluis 2:14a5d6ad92d5 2299 {
mluis 4:37c12dbc8dc7 2300 if( datarate == LORAMAC_TX_MIN_DATARATE )
mluis 2:14a5d6ad92d5 2301 {
mluis 2:14a5d6ad92d5 2302 AdrAckCounter = 0;
mluis 2:14a5d6ad92d5 2303 adrAckReq = false;
mluis 0:91d1a7783bb9 2304 }
mluis 0:91d1a7783bb9 2305 else
mluis 0:91d1a7783bb9 2306 {
mluis 3:b9d87593a8ae 2307 if( AdrAckCounter >= ADR_ACK_LIMIT )
mluis 2:14a5d6ad92d5 2308 {
mluis 2:14a5d6ad92d5 2309 adrAckReq = true;
mluis 8:26002607de9c 2310 LoRaMacParams.ChannelsTxPower = LORAMAC_MAX_TX_POWER;
mluis 2:14a5d6ad92d5 2311 }
mluis 2:14a5d6ad92d5 2312 else
mluis 2:14a5d6ad92d5 2313 {
mluis 2:14a5d6ad92d5 2314 adrAckReq = false;
mluis 2:14a5d6ad92d5 2315 }
mluis 3:b9d87593a8ae 2316 if( AdrAckCounter >= ( ADR_ACK_LIMIT + ADR_ACK_DELAY ) )
mluis 0:91d1a7783bb9 2317 {
mluis 8:26002607de9c 2318 if( ( AdrAckCounter % ADR_ACK_DELAY ) == 1 )
mluis 3:b9d87593a8ae 2319 {
mluis 2:14a5d6ad92d5 2320 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
mluis 4:37c12dbc8dc7 2321 if( datarate > LORAMAC_TX_MIN_DATARATE )
mluis 3:b9d87593a8ae 2322 {
mluis 3:b9d87593a8ae 2323 datarate--;
mluis 3:b9d87593a8ae 2324 }
mluis 4:37c12dbc8dc7 2325 if( datarate == LORAMAC_TX_MIN_DATARATE )
mluis 3:b9d87593a8ae 2326 {
mluis 3:b9d87593a8ae 2327 if( updateChannelMask == true )
mluis 3:b9d87593a8ae 2328 {
mluis 3:b9d87593a8ae 2329 // Re-enable default channels LC1, LC2, LC3
mluis 7:c16969e0f70f 2330 LoRaMacParams.ChannelsMask[0] = LoRaMacParams.ChannelsMask[0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) );
mluis 3:b9d87593a8ae 2331 }
mluis 3:b9d87593a8ae 2332 }
mluis 8:26002607de9c 2333 #elif defined( USE_BAND_470 )
mluis 8:26002607de9c 2334 if( datarate > LORAMAC_TX_MIN_DATARATE )
mluis 8:26002607de9c 2335 {
mluis 8:26002607de9c 2336 datarate--;
mluis 8:26002607de9c 2337 }
mluis 8:26002607de9c 2338 if( datarate == LORAMAC_TX_MIN_DATARATE )
mluis 8:26002607de9c 2339 {
mluis 8:26002607de9c 2340 if( updateChannelMask == true )
mluis 8:26002607de9c 2341 {
mluis 8:26002607de9c 2342 // Re-enable default channels
mluis 8:26002607de9c 2343 memcpy1( ( uint8_t* )LoRaMacParams.ChannelsMask, ( uint8_t* )LoRaMacParamsDefaults.ChannelsMask, sizeof( LoRaMacParams.ChannelsMask ) );
mluis 8:26002607de9c 2344 }
mluis 8:26002607de9c 2345 }
mluis 2:14a5d6ad92d5 2346 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 4:37c12dbc8dc7 2347 if( ( datarate > LORAMAC_TX_MIN_DATARATE ) && ( datarate == DR_8 ) )
mluis 3:b9d87593a8ae 2348 {
mluis 3:b9d87593a8ae 2349 datarate = DR_4;
mluis 3:b9d87593a8ae 2350 }
mluis 4:37c12dbc8dc7 2351 else if( datarate > LORAMAC_TX_MIN_DATARATE )
mluis 3:b9d87593a8ae 2352 {
mluis 3:b9d87593a8ae 2353 datarate--;
mluis 3:b9d87593a8ae 2354 }
mluis 4:37c12dbc8dc7 2355 if( datarate == LORAMAC_TX_MIN_DATARATE )
mluis 3:b9d87593a8ae 2356 {
mluis 3:b9d87593a8ae 2357 if( updateChannelMask == true )
mluis 3:b9d87593a8ae 2358 {
mluis 3:b9d87593a8ae 2359 #if defined( USE_BAND_915 )
mluis 3:b9d87593a8ae 2360 // Re-enable default channels
mluis 8:26002607de9c 2361 memcpy1( ( uint8_t* )LoRaMacParams.ChannelsMask, ( uint8_t* )LoRaMacParamsDefaults.ChannelsMask, sizeof( LoRaMacParams.ChannelsMask ) );
mluis 3:b9d87593a8ae 2362 #else // defined( USE_BAND_915_HYBRID )
mluis 3:b9d87593a8ae 2363 // Re-enable default channels
mluis 8:26002607de9c 2364 ReenableChannels( LoRaMacParamsDefaults.ChannelsMask[4], LoRaMacParams.ChannelsMask );
mluis 3:b9d87593a8ae 2365 #endif
mluis 3:b9d87593a8ae 2366 }
mluis 3:b9d87593a8ae 2367 }
mluis 2:14a5d6ad92d5 2368 #else
mluis 2:14a5d6ad92d5 2369 #error "Please define a frequency band in the compiler options."
mluis 2:14a5d6ad92d5 2370 #endif
mluis 3:b9d87593a8ae 2371 }
mluis 0:91d1a7783bb9 2372 }
mluis 0:91d1a7783bb9 2373 }
mluis 0:91d1a7783bb9 2374 }
mluis 2:14a5d6ad92d5 2375
mluis 2:14a5d6ad92d5 2376 *datarateOut = datarate;
mluis 2:14a5d6ad92d5 2377
mluis 2:14a5d6ad92d5 2378 return adrAckReq;
mluis 0:91d1a7783bb9 2379 }
mluis 0:91d1a7783bb9 2380
mluis 2:14a5d6ad92d5 2381 static LoRaMacStatus_t AddMacCommand( uint8_t cmd, uint8_t p1, uint8_t p2 )
mluis 0:91d1a7783bb9 2382 {
mluis 2:14a5d6ad92d5 2383 LoRaMacStatus_t status = LORAMAC_STATUS_BUSY;
mluis 7:c16969e0f70f 2384 // The maximum buffer length must take MAC commands to re-send into account.
mluis 7:c16969e0f70f 2385 uint8_t bufLen = LORA_MAC_COMMAND_MAX_LENGTH - MacCommandsBufferToRepeatIndex;
mluis 1:91e4e6c60d1e 2386
mluis 0:91d1a7783bb9 2387 switch( cmd )
mluis 0:91d1a7783bb9 2388 {
mluis 0:91d1a7783bb9 2389 case MOTE_MAC_LINK_CHECK_REQ:
mluis 7:c16969e0f70f 2390 if( MacCommandsBufferIndex < bufLen )
mluis 1:91e4e6c60d1e 2391 {
mluis 1:91e4e6c60d1e 2392 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
mluis 1:91e4e6c60d1e 2393 // No payload for this command
mluis 2:14a5d6ad92d5 2394 status = LORAMAC_STATUS_OK;
mluis 1:91e4e6c60d1e 2395 }
mluis 0:91d1a7783bb9 2396 break;
mluis 0:91d1a7783bb9 2397 case MOTE_MAC_LINK_ADR_ANS:
mluis 7:c16969e0f70f 2398 if( MacCommandsBufferIndex < ( bufLen - 1 ) )
mluis 1:91e4e6c60d1e 2399 {
mluis 1:91e4e6c60d1e 2400 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
mluis 1:91e4e6c60d1e 2401 // Margin
mluis 1:91e4e6c60d1e 2402 MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
mluis 2:14a5d6ad92d5 2403 status = LORAMAC_STATUS_OK;
mluis 1:91e4e6c60d1e 2404 }
mluis 0:91d1a7783bb9 2405 break;
mluis 0:91d1a7783bb9 2406 case MOTE_MAC_DUTY_CYCLE_ANS:
mluis 7:c16969e0f70f 2407 if( MacCommandsBufferIndex < bufLen )
mluis 1:91e4e6c60d1e 2408 {
mluis 1:91e4e6c60d1e 2409 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
mluis 1:91e4e6c60d1e 2410 // No payload for this answer
mluis 2:14a5d6ad92d5 2411 status = LORAMAC_STATUS_OK;
mluis 1:91e4e6c60d1e 2412 }
mluis 0:91d1a7783bb9 2413 break;
mluis 0:91d1a7783bb9 2414 case MOTE_MAC_RX_PARAM_SETUP_ANS:
mluis 7:c16969e0f70f 2415 if( MacCommandsBufferIndex < ( bufLen - 1 ) )
mluis 1:91e4e6c60d1e 2416 {
mluis 1:91e4e6c60d1e 2417 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
mluis 1:91e4e6c60d1e 2418 // Status: Datarate ACK, Channel ACK
mluis 1:91e4e6c60d1e 2419 MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
mluis 2:14a5d6ad92d5 2420 status = LORAMAC_STATUS_OK;
mluis 1:91e4e6c60d1e 2421 }
mluis 0:91d1a7783bb9 2422 break;
mluis 0:91d1a7783bb9 2423 case MOTE_MAC_DEV_STATUS_ANS:
mluis 7:c16969e0f70f 2424 if( MacCommandsBufferIndex < ( bufLen - 2 ) )
mluis 1:91e4e6c60d1e 2425 {
mluis 1:91e4e6c60d1e 2426 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
mluis 1:91e4e6c60d1e 2427 // 1st byte Battery
mluis 1:91e4e6c60d1e 2428 // 2nd byte Margin
mluis 1:91e4e6c60d1e 2429 MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
mluis 1:91e4e6c60d1e 2430 MacCommandsBuffer[MacCommandsBufferIndex++] = p2;
mluis 2:14a5d6ad92d5 2431 status = LORAMAC_STATUS_OK;
mluis 1:91e4e6c60d1e 2432 }
mluis 0:91d1a7783bb9 2433 break;
mluis 0:91d1a7783bb9 2434 case MOTE_MAC_NEW_CHANNEL_ANS:
mluis 7:c16969e0f70f 2435 if( MacCommandsBufferIndex < ( bufLen - 1 ) )
mluis 1:91e4e6c60d1e 2436 {
mluis 1:91e4e6c60d1e 2437 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
mluis 1:91e4e6c60d1e 2438 // Status: Datarate range OK, Channel frequency OK
mluis 1:91e4e6c60d1e 2439 MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
mluis 2:14a5d6ad92d5 2440 status = LORAMAC_STATUS_OK;
mluis 1:91e4e6c60d1e 2441 }
mluis 0:91d1a7783bb9 2442 break;
mluis 0:91d1a7783bb9 2443 case MOTE_MAC_RX_TIMING_SETUP_ANS:
mluis 7:c16969e0f70f 2444 if( MacCommandsBufferIndex < bufLen )
mluis 1:91e4e6c60d1e 2445 {
mluis 1:91e4e6c60d1e 2446 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
mluis 1:91e4e6c60d1e 2447 // No payload for this answer
mluis 2:14a5d6ad92d5 2448 status = LORAMAC_STATUS_OK;
mluis 1:91e4e6c60d1e 2449 }
mluis 0:91d1a7783bb9 2450 break;
mluis 0:91d1a7783bb9 2451 default:
mluis 2:14a5d6ad92d5 2452 return LORAMAC_STATUS_SERVICE_UNKNOWN;
mluis 0:91d1a7783bb9 2453 }
mluis 2:14a5d6ad92d5 2454 if( status == LORAMAC_STATUS_OK )
mluis 0:91d1a7783bb9 2455 {
mluis 0:91d1a7783bb9 2456 MacCommandsInNextTx = true;
mluis 0:91d1a7783bb9 2457 }
mluis 1:91e4e6c60d1e 2458 return status;
mluis 0:91d1a7783bb9 2459 }
mluis 0:91d1a7783bb9 2460
mluis 7:c16969e0f70f 2461 static uint8_t ParseMacCommandsToRepeat( uint8_t* cmdBufIn, uint8_t length, uint8_t* cmdBufOut )
mluis 7:c16969e0f70f 2462 {
mluis 7:c16969e0f70f 2463 uint8_t i = 0;
mluis 7:c16969e0f70f 2464 uint8_t cmdCount = 0;
mluis 7:c16969e0f70f 2465
mluis 7:c16969e0f70f 2466 if( ( cmdBufIn == NULL ) || ( cmdBufOut == NULL ) )
mluis 7:c16969e0f70f 2467 {
mluis 7:c16969e0f70f 2468 return 0;
mluis 7:c16969e0f70f 2469 }
mluis 7:c16969e0f70f 2470
mluis 7:c16969e0f70f 2471 for( i = 0; i < length; i++ )
mluis 7:c16969e0f70f 2472 {
mluis 7:c16969e0f70f 2473 switch( cmdBufIn[i] )
mluis 7:c16969e0f70f 2474 {
mluis 8:26002607de9c 2475 // STICKY
mluis 7:c16969e0f70f 2476 case MOTE_MAC_RX_PARAM_SETUP_ANS:
mluis 7:c16969e0f70f 2477 {
mluis 7:c16969e0f70f 2478 cmdBufOut[cmdCount++] = cmdBufIn[i++];
mluis 7:c16969e0f70f 2479 cmdBufOut[cmdCount++] = cmdBufIn[i];
mluis 7:c16969e0f70f 2480 break;
mluis 7:c16969e0f70f 2481 }
mluis 7:c16969e0f70f 2482 case MOTE_MAC_RX_TIMING_SETUP_ANS:
mluis 7:c16969e0f70f 2483 {
mluis 7:c16969e0f70f 2484 cmdBufOut[cmdCount++] = cmdBufIn[i];
mluis 7:c16969e0f70f 2485 break;
mluis 7:c16969e0f70f 2486 }
mluis 8:26002607de9c 2487 // NON-STICKY
mluis 8:26002607de9c 2488 case MOTE_MAC_DEV_STATUS_ANS:
mluis 8:26002607de9c 2489 { // 2 bytes payload
mluis 8:26002607de9c 2490 i += 2;
mluis 8:26002607de9c 2491 break;
mluis 8:26002607de9c 2492 }
mluis 8:26002607de9c 2493 case MOTE_MAC_LINK_ADR_ANS:
mluis 8:26002607de9c 2494 case MOTE_MAC_NEW_CHANNEL_ANS:
mluis 8:26002607de9c 2495 { // 1 byte payload
mluis 8:26002607de9c 2496 i++;
mluis 8:26002607de9c 2497 break;
mluis 8:26002607de9c 2498 }
mluis 8:26002607de9c 2499 case MOTE_MAC_DUTY_CYCLE_ANS:
mluis 8:26002607de9c 2500 case MOTE_MAC_LINK_CHECK_REQ:
mluis 8:26002607de9c 2501 { // 0 byte payload
mluis 8:26002607de9c 2502 break;
mluis 8:26002607de9c 2503 }
mluis 7:c16969e0f70f 2504 default:
mluis 7:c16969e0f70f 2505 break;
mluis 7:c16969e0f70f 2506 }
mluis 7:c16969e0f70f 2507 }
mluis 7:c16969e0f70f 2508
mluis 7:c16969e0f70f 2509 return cmdCount;
mluis 7:c16969e0f70f 2510 }
mluis 7:c16969e0f70f 2511
mluis 2:14a5d6ad92d5 2512 static void ProcessMacCommands( uint8_t *payload, uint8_t macIndex, uint8_t commandsSize, uint8_t snr )
mluis 0:91d1a7783bb9 2513 {
mluis 0:91d1a7783bb9 2514 while( macIndex < commandsSize )
mluis 0:91d1a7783bb9 2515 {
mluis 0:91d1a7783bb9 2516 // Decode Frame MAC commands
mluis 0:91d1a7783bb9 2517 switch( payload[macIndex++] )
mluis 0:91d1a7783bb9 2518 {
mluis 0:91d1a7783bb9 2519 case SRV_MAC_LINK_CHECK_ANS:
mluis 2:14a5d6ad92d5 2520 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK;
mluis 2:14a5d6ad92d5 2521 MlmeConfirm.DemodMargin = payload[macIndex++];
mluis 2:14a5d6ad92d5 2522 MlmeConfirm.NbGateways = payload[macIndex++];
mluis 0:91d1a7783bb9 2523 break;
mluis 0:91d1a7783bb9 2524 case SRV_MAC_LINK_ADR_REQ:
mluis 0:91d1a7783bb9 2525 {
mluis 2:14a5d6ad92d5 2526 uint8_t i;
mluis 0:91d1a7783bb9 2527 uint8_t status = 0x07;
mluis 0:91d1a7783bb9 2528 uint16_t chMask;
mluis 0:91d1a7783bb9 2529 int8_t txPower = 0;
mluis 0:91d1a7783bb9 2530 int8_t datarate = 0;
mluis 0:91d1a7783bb9 2531 uint8_t nbRep = 0;
mluis 0:91d1a7783bb9 2532 uint8_t chMaskCntl = 0;
mluis 0:91d1a7783bb9 2533 uint16_t channelsMask[6] = { 0, 0, 0, 0, 0, 0 };
mluis 2:14a5d6ad92d5 2534
mluis 0:91d1a7783bb9 2535 // Initialize local copy of the channels mask array
mluis 2:14a5d6ad92d5 2536 for( i = 0; i < 6; i++ )
mluis 0:91d1a7783bb9 2537 {
mluis 7:c16969e0f70f 2538 channelsMask[i] = LoRaMacParams.ChannelsMask[i];
mluis 0:91d1a7783bb9 2539 }
mluis 0:91d1a7783bb9 2540 datarate = payload[macIndex++];
mluis 0:91d1a7783bb9 2541 txPower = datarate & 0x0F;
mluis 0:91d1a7783bb9 2542 datarate = ( datarate >> 4 ) & 0x0F;
mluis 0:91d1a7783bb9 2543
mluis 2:14a5d6ad92d5 2544 if( ( AdrCtrlOn == false ) &&
mluis 7:c16969e0f70f 2545 ( ( LoRaMacParams.ChannelsDatarate != datarate ) || ( LoRaMacParams.ChannelsTxPower != txPower ) ) )
mluis 0:91d1a7783bb9 2546 { // ADR disabled don't handle ADR requests if server tries to change datarate or txpower
mluis 0:91d1a7783bb9 2547 // Answer the server with fail status
mluis 0:91d1a7783bb9 2548 // Power ACK = 0
mluis 0:91d1a7783bb9 2549 // Data rate ACK = 0
mluis 0:91d1a7783bb9 2550 // Channel mask = 0
mluis 0:91d1a7783bb9 2551 AddMacCommand( MOTE_MAC_LINK_ADR_ANS, 0, 0 );
mluis 1:91e4e6c60d1e 2552 macIndex += 3; // Skip over the remaining bytes of the request
mluis 0:91d1a7783bb9 2553 break;
mluis 0:91d1a7783bb9 2554 }
mluis 1:91e4e6c60d1e 2555 chMask = ( uint16_t )payload[macIndex++];
mluis 1:91e4e6c60d1e 2556 chMask |= ( uint16_t )payload[macIndex++] << 8;
mluis 0:91d1a7783bb9 2557
mluis 0:91d1a7783bb9 2558 nbRep = payload[macIndex++];
mluis 0:91d1a7783bb9 2559 chMaskCntl = ( nbRep >> 4 ) & 0x07;
mluis 0:91d1a7783bb9 2560 nbRep &= 0x0F;
mluis 0:91d1a7783bb9 2561 if( nbRep == 0 )
mluis 0:91d1a7783bb9 2562 {
mluis 0:91d1a7783bb9 2563 nbRep = 1;
mluis 0:91d1a7783bb9 2564 }
mluis 0:91d1a7783bb9 2565 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
mluis 0:91d1a7783bb9 2566 if( ( chMaskCntl == 0 ) && ( chMask == 0 ) )
mluis 0:91d1a7783bb9 2567 {
mluis 0:91d1a7783bb9 2568 status &= 0xFE; // Channel mask KO
mluis 0:91d1a7783bb9 2569 }
mluis 2:14a5d6ad92d5 2570 else if( ( ( chMaskCntl >= 1 ) && ( chMaskCntl <= 5 )) ||
mluis 2:14a5d6ad92d5 2571 ( chMaskCntl >= 7 ) )
mluis 0:91d1a7783bb9 2572 {
mluis 0:91d1a7783bb9 2573 // RFU
mluis 0:91d1a7783bb9 2574 status &= 0xFE; // Channel mask KO
mluis 0:91d1a7783bb9 2575 }
mluis 0:91d1a7783bb9 2576 else
mluis 0:91d1a7783bb9 2577 {
mluis 2:14a5d6ad92d5 2578 for( i = 0; i < LORA_MAX_NB_CHANNELS; i++ )
mluis 0:91d1a7783bb9 2579 {
mluis 0:91d1a7783bb9 2580 if( chMaskCntl == 6 )
mluis 0:91d1a7783bb9 2581 {
mluis 0:91d1a7783bb9 2582 if( Channels[i].Frequency != 0 )
mluis 0:91d1a7783bb9 2583 {
mluis 0:91d1a7783bb9 2584 chMask |= 1 << i;
mluis 0:91d1a7783bb9 2585 }
mluis 0:91d1a7783bb9 2586 }
mluis 0:91d1a7783bb9 2587 else
mluis 0:91d1a7783bb9 2588 {
mluis 0:91d1a7783bb9 2589 if( ( ( chMask & ( 1 << i ) ) != 0 ) &&
mluis 0:91d1a7783bb9 2590 ( Channels[i].Frequency == 0 ) )
mluis 0:91d1a7783bb9 2591 {// Trying to enable an undefined channel
mluis 0:91d1a7783bb9 2592 status &= 0xFE; // Channel mask KO
mluis 0:91d1a7783bb9 2593 }
mluis 0:91d1a7783bb9 2594 }
mluis 0:91d1a7783bb9 2595 }
mluis 0:91d1a7783bb9 2596 channelsMask[0] = chMask;
mluis 0:91d1a7783bb9 2597 }
mluis 8:26002607de9c 2598 #elif defined( USE_BAND_470 )
mluis 0:91d1a7783bb9 2599 if( chMaskCntl == 6 )
mluis 0:91d1a7783bb9 2600 {
mluis 0:91d1a7783bb9 2601 // Enable all 125 kHz channels
mluis 8:26002607de9c 2602 for( uint8_t i = 0, k = 0; i < LORA_MAX_NB_CHANNELS; i += 16, k++ )
mluis 0:91d1a7783bb9 2603 {
mluis 0:91d1a7783bb9 2604 for( uint8_t j = 0; j < 16; j++ )
mluis 0:91d1a7783bb9 2605 {
mluis 0:91d1a7783bb9 2606 if( Channels[i + j].Frequency != 0 )
mluis 0:91d1a7783bb9 2607 {
mluis 0:91d1a7783bb9 2608 channelsMask[k] |= 1 << j;
mluis 0:91d1a7783bb9 2609 }
mluis 0:91d1a7783bb9 2610 }
mluis 0:91d1a7783bb9 2611 }
mluis 0:91d1a7783bb9 2612 }
mluis 0:91d1a7783bb9 2613 else if( chMaskCntl == 7 )
mluis 0:91d1a7783bb9 2614 {
mluis 0:91d1a7783bb9 2615 status &= 0xFE; // Channel mask KO
mluis 0:91d1a7783bb9 2616 }
mluis 0:91d1a7783bb9 2617 else
mluis 0:91d1a7783bb9 2618 {
mluis 0:91d1a7783bb9 2619 for( uint8_t i = 0; i < 16; i++ )
mluis 0:91d1a7783bb9 2620 {
mluis 0:91d1a7783bb9 2621 if( ( ( chMask & ( 1 << i ) ) != 0 ) &&
mluis 0:91d1a7783bb9 2622 ( Channels[chMaskCntl * 16 + i].Frequency == 0 ) )
mluis 0:91d1a7783bb9 2623 {// Trying to enable an undefined channel
mluis 0:91d1a7783bb9 2624 status &= 0xFE; // Channel mask KO
mluis 0:91d1a7783bb9 2625 }
mluis 0:91d1a7783bb9 2626 }
mluis 0:91d1a7783bb9 2627 channelsMask[chMaskCntl] = chMask;
mluis 8:26002607de9c 2628 }
mluis 8:26002607de9c 2629 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 8:26002607de9c 2630 if( chMaskCntl == 6 )
mluis 8:26002607de9c 2631 {
mluis 8:26002607de9c 2632 // Enable all 125 kHz channels
mluis 8:26002607de9c 2633 channelsMask[0] = 0xFFFF;
mluis 8:26002607de9c 2634 channelsMask[1] = 0xFFFF;
mluis 8:26002607de9c 2635 channelsMask[2] = 0xFFFF;
mluis 8:26002607de9c 2636 channelsMask[3] = 0xFFFF;
mluis 8:26002607de9c 2637 // Apply chMask to channels 64 to 71
mluis 8:26002607de9c 2638 channelsMask[4] = chMask;
mluis 8:26002607de9c 2639 }
mluis 8:26002607de9c 2640 else if( chMaskCntl == 7 )
mluis 8:26002607de9c 2641 {
mluis 8:26002607de9c 2642 // Disable all 125 kHz channels
mluis 8:26002607de9c 2643 channelsMask[0] = 0x0000;
mluis 8:26002607de9c 2644 channelsMask[1] = 0x0000;
mluis 8:26002607de9c 2645 channelsMask[2] = 0x0000;
mluis 8:26002607de9c 2646 channelsMask[3] = 0x0000;
mluis 8:26002607de9c 2647 // Apply chMask to channels 64 to 71
mluis 8:26002607de9c 2648 channelsMask[4] = chMask;
mluis 8:26002607de9c 2649 }
mluis 8:26002607de9c 2650 else if( chMaskCntl == 5 )
mluis 8:26002607de9c 2651 {
mluis 8:26002607de9c 2652 // RFU
mluis 8:26002607de9c 2653 status &= 0xFE; // Channel mask KO
mluis 8:26002607de9c 2654 }
mluis 8:26002607de9c 2655 else
mluis 8:26002607de9c 2656 {
mluis 8:26002607de9c 2657 channelsMask[chMaskCntl] = chMask;
mluis 8:26002607de9c 2658
mluis 8:26002607de9c 2659 // FCC 15.247 paragraph F mandates to hop on at least 2 125 kHz channels
mluis 8:26002607de9c 2660 if( ( datarate < DR_4 ) && ( CountNbEnabled125kHzChannels( channelsMask ) < 2 ) )
mluis 0:91d1a7783bb9 2661 {
mluis 0:91d1a7783bb9 2662 status &= 0xFE; // Channel mask KO
mluis 0:91d1a7783bb9 2663 }
mluis 4:37c12dbc8dc7 2664
mluis 4:37c12dbc8dc7 2665 #if defined( USE_BAND_915_HYBRID )
mluis 4:37c12dbc8dc7 2666 if( ValidateChannelMask( channelsMask ) == false )
mluis 4:37c12dbc8dc7 2667 {
mluis 4:37c12dbc8dc7 2668 status &= 0xFE; // Channel mask KO
mluis 4:37c12dbc8dc7 2669 }
mluis 4:37c12dbc8dc7 2670 #endif
mluis 0:91d1a7783bb9 2671 }
mluis 0:91d1a7783bb9 2672 #else
mluis 0:91d1a7783bb9 2673 #error "Please define a frequency band in the compiler options."
mluis 0:91d1a7783bb9 2674 #endif
mluis 8:26002607de9c 2675 if( ValidateDatarate( datarate, channelsMask ) == false )
mluis 0:91d1a7783bb9 2676 {
mluis 0:91d1a7783bb9 2677 status &= 0xFD; // Datarate KO
mluis 0:91d1a7783bb9 2678 }
mluis 0:91d1a7783bb9 2679
mluis 0:91d1a7783bb9 2680 //
mluis 0:91d1a7783bb9 2681 // Remark MaxTxPower = 0 and MinTxPower = 5
mluis 0:91d1a7783bb9 2682 //
mluis 2:14a5d6ad92d5 2683 if( ValueInRange( txPower, LORAMAC_MAX_TX_POWER, LORAMAC_MIN_TX_POWER ) == false )
mluis 0:91d1a7783bb9 2684 {
mluis 0:91d1a7783bb9 2685 status &= 0xFB; // TxPower KO
mluis 0:91d1a7783bb9 2686 }
mluis 0:91d1a7783bb9 2687 if( ( status & 0x07 ) == 0x07 )
mluis 0:91d1a7783bb9 2688 {
mluis 7:c16969e0f70f 2689 LoRaMacParams.ChannelsDatarate = datarate;
mluis 7:c16969e0f70f 2690 LoRaMacParams.ChannelsTxPower = txPower;
mluis 7:c16969e0f70f 2691
mluis 8:26002607de9c 2692 memcpy1( ( uint8_t* )LoRaMacParams.ChannelsMask, ( uint8_t* )channelsMask, sizeof( LoRaMacParams.ChannelsMask ) );
mluis 7:c16969e0f70f 2693
mluis 7:c16969e0f70f 2694 LoRaMacParams.ChannelsNbRep = nbRep;
mluis 8:26002607de9c 2695 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 8:26002607de9c 2696 // Reset ChannelsMaskRemaining to the new ChannelsMask
mluis 8:26002607de9c 2697 ChannelsMaskRemaining[0] &= channelsMask[0];
mluis 8:26002607de9c 2698 ChannelsMaskRemaining[1] &= channelsMask[1];
mluis 8:26002607de9c 2699 ChannelsMaskRemaining[2] &= channelsMask[2];
mluis 8:26002607de9c 2700 ChannelsMaskRemaining[3] &= channelsMask[3];
mluis 8:26002607de9c 2701 ChannelsMaskRemaining[4] = channelsMask[4];
mluis 8:26002607de9c 2702 ChannelsMaskRemaining[5] = channelsMask[5];
mluis 8:26002607de9c 2703 #endif
mluis 0:91d1a7783bb9 2704 }
mluis 0:91d1a7783bb9 2705 AddMacCommand( MOTE_MAC_LINK_ADR_ANS, status, 0 );
mluis 0:91d1a7783bb9 2706 }
mluis 0:91d1a7783bb9 2707 break;
mluis 0:91d1a7783bb9 2708 case SRV_MAC_DUTY_CYCLE_REQ:
mluis 0:91d1a7783bb9 2709 MaxDCycle = payload[macIndex++];
mluis 0:91d1a7783bb9 2710 AggregatedDCycle = 1 << MaxDCycle;
mluis 0:91d1a7783bb9 2711 AddMacCommand( MOTE_MAC_DUTY_CYCLE_ANS, 0, 0 );
mluis 0:91d1a7783bb9 2712 break;
mluis 0:91d1a7783bb9 2713 case SRV_MAC_RX_PARAM_SETUP_REQ:
mluis 0:91d1a7783bb9 2714 {
mluis 0:91d1a7783bb9 2715 uint8_t status = 0x07;
mluis 0:91d1a7783bb9 2716 int8_t datarate = 0;
mluis 0:91d1a7783bb9 2717 int8_t drOffset = 0;
mluis 0:91d1a7783bb9 2718 uint32_t freq = 0;
mluis 2:14a5d6ad92d5 2719
mluis 1:91e4e6c60d1e 2720 drOffset = ( payload[macIndex] >> 4 ) & 0x07;
mluis 1:91e4e6c60d1e 2721 datarate = payload[macIndex] & 0x0F;
mluis 1:91e4e6c60d1e 2722 macIndex++;
mluis 2:14a5d6ad92d5 2723
mluis 2:14a5d6ad92d5 2724 freq = ( uint32_t )payload[macIndex++];
mluis 0:91d1a7783bb9 2725 freq |= ( uint32_t )payload[macIndex++] << 8;
mluis 0:91d1a7783bb9 2726 freq |= ( uint32_t )payload[macIndex++] << 16;
mluis 0:91d1a7783bb9 2727 freq *= 100;
mluis 2:14a5d6ad92d5 2728
mluis 7:c16969e0f70f 2729 if( Rx2FreqInRange( freq ) == false )
mluis 0:91d1a7783bb9 2730 {
mluis 0:91d1a7783bb9 2731 status &= 0xFE; // Channel frequency KO
mluis 0:91d1a7783bb9 2732 }
mluis 2:14a5d6ad92d5 2733
mluis 4:37c12dbc8dc7 2734 if( ValueInRange( datarate, LORAMAC_RX_MIN_DATARATE, LORAMAC_RX_MAX_DATARATE ) == false )
mluis 0:91d1a7783bb9 2735 {
mluis 0:91d1a7783bb9 2736 status &= 0xFD; // Datarate KO
mluis 0:91d1a7783bb9 2737 }
mluis 2:14a5d6ad92d5 2738 #if ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) )
mluis 2:14a5d6ad92d5 2739 if( ( ValueInRange( datarate, DR_5, DR_7 ) == true ) ||
mluis 2:14a5d6ad92d5 2740 ( datarate > DR_13 ) )
mluis 2:14a5d6ad92d5 2741 {
mluis 2:14a5d6ad92d5 2742 status &= 0xFD; // Datarate KO
mluis 2:14a5d6ad92d5 2743 }
mluis 2:14a5d6ad92d5 2744 #endif
mluis 2:14a5d6ad92d5 2745 if( ValueInRange( drOffset, LORAMAC_MIN_RX1_DR_OFFSET, LORAMAC_MAX_RX1_DR_OFFSET ) == false )
mluis 0:91d1a7783bb9 2746 {
mluis 0:91d1a7783bb9 2747 status &= 0xFB; // Rx1DrOffset range KO
mluis 0:91d1a7783bb9 2748 }
mluis 2:14a5d6ad92d5 2749
mluis 0:91d1a7783bb9 2750 if( ( status & 0x07 ) == 0x07 )
mluis 0:91d1a7783bb9 2751 {
mluis 7:c16969e0f70f 2752 LoRaMacParams.Rx2Channel.Datarate = datarate;
mluis 7:c16969e0f70f 2753 LoRaMacParams.Rx2Channel.Frequency = freq;
mluis 7:c16969e0f70f 2754 LoRaMacParams.Rx1DrOffset = drOffset;
mluis 0:91d1a7783bb9 2755 }
mluis 0:91d1a7783bb9 2756 AddMacCommand( MOTE_MAC_RX_PARAM_SETUP_ANS, status, 0 );
mluis 0:91d1a7783bb9 2757 }
mluis 0:91d1a7783bb9 2758 break;
mluis 0:91d1a7783bb9 2759 case SRV_MAC_DEV_STATUS_REQ:
mluis 1:91e4e6c60d1e 2760 {
mluis 1:91e4e6c60d1e 2761 uint8_t batteryLevel = BAT_LEVEL_NO_MEASURE;
mluis 1:91e4e6c60d1e 2762 if( ( LoRaMacCallbacks != NULL ) && ( LoRaMacCallbacks->GetBatteryLevel != NULL ) )
mluis 1:91e4e6c60d1e 2763 {
mluis 1:91e4e6c60d1e 2764 batteryLevel = LoRaMacCallbacks->GetBatteryLevel( );
mluis 1:91e4e6c60d1e 2765 }
mluis 2:14a5d6ad92d5 2766 AddMacCommand( MOTE_MAC_DEV_STATUS_ANS, batteryLevel, snr );
mluis 2:14a5d6ad92d5 2767 break;
mluis 1:91e4e6c60d1e 2768 }
mluis 0:91d1a7783bb9 2769 case SRV_MAC_NEW_CHANNEL_REQ:
mluis 0:91d1a7783bb9 2770 {
mluis 0:91d1a7783bb9 2771 uint8_t status = 0x03;
mluis 3:b9d87593a8ae 2772
mluis 8:26002607de9c 2773 #if defined( USE_BAND_470 ) || defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 3:b9d87593a8ae 2774 status &= 0xFC; // Channel frequency and datarate KO
mluis 3:b9d87593a8ae 2775 macIndex += 5;
mluis 2:14a5d6ad92d5 2776 #else
mluis 0:91d1a7783bb9 2777 int8_t channelIndex = 0;
mluis 0:91d1a7783bb9 2778 ChannelParams_t chParam;
mluis 2:14a5d6ad92d5 2779
mluis 0:91d1a7783bb9 2780 channelIndex = payload[macIndex++];
mluis 0:91d1a7783bb9 2781 chParam.Frequency = ( uint32_t )payload[macIndex++];
mluis 0:91d1a7783bb9 2782 chParam.Frequency |= ( uint32_t )payload[macIndex++] << 8;
mluis 0:91d1a7783bb9 2783 chParam.Frequency |= ( uint32_t )payload[macIndex++] << 16;
mluis 0:91d1a7783bb9 2784 chParam.Frequency *= 100;
mluis 0:91d1a7783bb9 2785 chParam.DrRange.Value = payload[macIndex++];
mluis 2:14a5d6ad92d5 2786
mluis 8:26002607de9c 2787 LoRaMacState |= LORAMAC_TX_CONFIG;
mluis 3:b9d87593a8ae 2788 if( chParam.Frequency == 0 )
mluis 0:91d1a7783bb9 2789 {
mluis 3:b9d87593a8ae 2790 if( channelIndex < 3 )
mluis 3:b9d87593a8ae 2791 {
mluis 3:b9d87593a8ae 2792 status &= 0xFC;
mluis 3:b9d87593a8ae 2793 }
mluis 3:b9d87593a8ae 2794 else
mluis 3:b9d87593a8ae 2795 {
mluis 3:b9d87593a8ae 2796 if( LoRaMacChannelRemove( channelIndex ) != LORAMAC_STATUS_OK )
mluis 3:b9d87593a8ae 2797 {
mluis 3:b9d87593a8ae 2798 status &= 0xFC;
mluis 3:b9d87593a8ae 2799 }
mluis 3:b9d87593a8ae 2800 }
mluis 0:91d1a7783bb9 2801 }
mluis 3:b9d87593a8ae 2802 else
mluis 0:91d1a7783bb9 2803 {
mluis 3:b9d87593a8ae 2804 switch( LoRaMacChannelAdd( channelIndex, chParam ) )
mluis 3:b9d87593a8ae 2805 {
mluis 3:b9d87593a8ae 2806 case LORAMAC_STATUS_OK:
mluis 3:b9d87593a8ae 2807 {
mluis 3:b9d87593a8ae 2808 break;
mluis 3:b9d87593a8ae 2809 }
mluis 3:b9d87593a8ae 2810 case LORAMAC_STATUS_FREQUENCY_INVALID:
mluis 3:b9d87593a8ae 2811 {
mluis 3:b9d87593a8ae 2812 status &= 0xFE;
mluis 3:b9d87593a8ae 2813 break;
mluis 3:b9d87593a8ae 2814 }
mluis 3:b9d87593a8ae 2815 case LORAMAC_STATUS_DATARATE_INVALID:
mluis 3:b9d87593a8ae 2816 {
mluis 3:b9d87593a8ae 2817 status &= 0xFD;
mluis 3:b9d87593a8ae 2818 break;
mluis 3:b9d87593a8ae 2819 }
mluis 3:b9d87593a8ae 2820 case LORAMAC_STATUS_FREQ_AND_DR_INVALID:
mluis 3:b9d87593a8ae 2821 {
mluis 3:b9d87593a8ae 2822 status &= 0xFC;
mluis 3:b9d87593a8ae 2823 break;
mluis 3:b9d87593a8ae 2824 }
mluis 3:b9d87593a8ae 2825 default:
mluis 3:b9d87593a8ae 2826 {
mluis 3:b9d87593a8ae 2827 status &= 0xFC;
mluis 3:b9d87593a8ae 2828 break;
mluis 3:b9d87593a8ae 2829 }
mluis 3:b9d87593a8ae 2830 }
mluis 0:91d1a7783bb9 2831 }
mluis 8:26002607de9c 2832 LoRaMacState &= ~LORAMAC_TX_CONFIG;
mluis 2:14a5d6ad92d5 2833 #endif
mluis 0:91d1a7783bb9 2834 AddMacCommand( MOTE_MAC_NEW_CHANNEL_ANS, status, 0 );
mluis 0:91d1a7783bb9 2835 }
mluis 0:91d1a7783bb9 2836 break;
mluis 0:91d1a7783bb9 2837 case SRV_MAC_RX_TIMING_SETUP_REQ:
mluis 0:91d1a7783bb9 2838 {
mluis 0:91d1a7783bb9 2839 uint8_t delay = payload[macIndex++] & 0x0F;
mluis 2:14a5d6ad92d5 2840
mluis 0:91d1a7783bb9 2841 if( delay == 0 )
mluis 0:91d1a7783bb9 2842 {
mluis 0:91d1a7783bb9 2843 delay++;
mluis 0:91d1a7783bb9 2844 }
mluis 8:26002607de9c 2845 LoRaMacParams.ReceiveDelay1 = delay * 1e3;
mluis 8:26002607de9c 2846 LoRaMacParams.ReceiveDelay2 = LoRaMacParams.ReceiveDelay1 + 1e3;
mluis 0:91d1a7783bb9 2847 AddMacCommand( MOTE_MAC_RX_TIMING_SETUP_ANS, 0, 0 );
mluis 0:91d1a7783bb9 2848 }
mluis 0:91d1a7783bb9 2849 break;
mluis 0:91d1a7783bb9 2850 default:
mluis 0:91d1a7783bb9 2851 // Unknown command. ABORT MAC commands processing
mluis 0:91d1a7783bb9 2852 return;
mluis 0:91d1a7783bb9 2853 }
mluis 0:91d1a7783bb9 2854 }
mluis 0:91d1a7783bb9 2855 }
mluis 0:91d1a7783bb9 2856
mluis 2:14a5d6ad92d5 2857 LoRaMacStatus_t Send( LoRaMacHeader_t *macHdr, uint8_t fPort, void *fBuffer, uint16_t fBufferSize )
mluis 0:91d1a7783bb9 2858 {
alphaemmeo 11:5b3e495baefb 2859 ser->printf("[LRMAC] In to the LoRaMacStatus_t Send \n\r");
mluis 2:14a5d6ad92d5 2860 LoRaMacFrameCtrl_t fCtrl;
mluis 2:14a5d6ad92d5 2861 LoRaMacStatus_t status = LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 2862
mluis 2:14a5d6ad92d5 2863 fCtrl.Value = 0;
mluis 2:14a5d6ad92d5 2864 fCtrl.Bits.FOptsLen = 0;
mluis 2:14a5d6ad92d5 2865 fCtrl.Bits.FPending = 0;
mluis 2:14a5d6ad92d5 2866 fCtrl.Bits.Ack = false;
mluis 2:14a5d6ad92d5 2867 fCtrl.Bits.AdrAckReq = false;
mluis 2:14a5d6ad92d5 2868 fCtrl.Bits.Adr = AdrCtrlOn;
mluis 2:14a5d6ad92d5 2869
mluis 2:14a5d6ad92d5 2870 // Prepare the frame
mluis 2:14a5d6ad92d5 2871 status = PrepareFrame( macHdr, &fCtrl, fPort, fBuffer, fBufferSize );
mluis 2:14a5d6ad92d5 2872
mluis 2:14a5d6ad92d5 2873 // Validate status
mluis 2:14a5d6ad92d5 2874 if( status != LORAMAC_STATUS_OK )
mluis 0:91d1a7783bb9 2875 {
alphaemmeo 11:5b3e495baefb 2876 ser->printf("[LRMAC] LoRaMacStatus_t Send :: status %u \n\r", status);
mluis 2:14a5d6ad92d5 2877 return status;
mluis 0:91d1a7783bb9 2878 }
alphaemmeo 11:5b3e495baefb 2879 ser->printf("[LRMAC] LoRaMacStatus_t Send :: LORAMAC_STATUS_OK \n\r");
alphaemmeo 11:5b3e495baefb 2880
mluis 2:14a5d6ad92d5 2881 // Reset confirm parameters
mluis 2:14a5d6ad92d5 2882 McpsConfirm.NbRetries = 0;
mluis 2:14a5d6ad92d5 2883 McpsConfirm.AckReceived = false;
mluis 2:14a5d6ad92d5 2884 McpsConfirm.UpLinkCounter = UpLinkCounter;
mluis 2:14a5d6ad92d5 2885
mluis 2:14a5d6ad92d5 2886 status = ScheduleTx( );
alphaemmeo 11:5b3e495baefb 2887
alphaemmeo 11:5b3e495baefb 2888 ser->printf("[LRMAC] LoRaMacStatus_t Send :: status %u \n\r", status);
mluis 2:14a5d6ad92d5 2889
mluis 2:14a5d6ad92d5 2890 return status;
mluis 0:91d1a7783bb9 2891 }
mluis 0:91d1a7783bb9 2892
mluis 8:26002607de9c 2893 static LoRaMacStatus_t ScheduleTx( void )
mluis 0:91d1a7783bb9 2894 {
alphaemmeo 11:5b3e495baefb 2895 ser->printf("[LRMAC] LoRaMacStatus_t ScheduleTx \n\r");
mluis 2:14a5d6ad92d5 2896 TimerTime_t dutyCycleTimeOff = 0;
mluis 2:14a5d6ad92d5 2897
mluis 2:14a5d6ad92d5 2898 // Check if the device is off
mluis 2:14a5d6ad92d5 2899 if( MaxDCycle == 255 )
mluis 2:14a5d6ad92d5 2900 {
alphaemmeo 11:5b3e495baefb 2901 ser->printf("[LRMAC] LoRaMacStatus_t ScheduleTx :: LORAMAC_STATUS_DEVICE_OFF\n\r");
mluis 2:14a5d6ad92d5 2902 return LORAMAC_STATUS_DEVICE_OFF;
mluis 2:14a5d6ad92d5 2903 }
mluis 2:14a5d6ad92d5 2904 if( MaxDCycle == 0 )
mluis 0:91d1a7783bb9 2905 {
mluis 2:14a5d6ad92d5 2906 AggregatedTimeOff = 0;
mluis 2:14a5d6ad92d5 2907 }
mluis 2:14a5d6ad92d5 2908
mluis 2:14a5d6ad92d5 2909 // Select channel
mluis 3:b9d87593a8ae 2910 while( SetNextChannel( &dutyCycleTimeOff ) == false )
mluis 3:b9d87593a8ae 2911 {
mluis 3:b9d87593a8ae 2912 // Set the default datarate
mluis 7:c16969e0f70f 2913 LoRaMacParams.ChannelsDatarate = LoRaMacParamsDefaults.ChannelsDatarate;
mluis 3:b9d87593a8ae 2914
mluis 3:b9d87593a8ae 2915 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
mluis 3:b9d87593a8ae 2916 // Re-enable default channels LC1, LC2, LC3
mluis 7:c16969e0f70f 2917 LoRaMacParams.ChannelsMask[0] = LoRaMacParams.ChannelsMask[0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) );
mluis 3:b9d87593a8ae 2918 #endif
mluis 3:b9d87593a8ae 2919 }
mluis 2:14a5d6ad92d5 2920
mluis 8:26002607de9c 2921 // Compute Rx1 windows parameters
mluis 8:26002607de9c 2922 #if ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) )
mluis 8:26002607de9c 2923 RxWindowsParams[0] = ComputeRxWindowParameters( DatarateOffsets[LoRaMacParams.ChannelsDatarate][LoRaMacParams.Rx1DrOffset], LoRaMacParams.SystemMaxRxError );
mluis 8:26002607de9c 2924 #else
mluis 8:26002607de9c 2925 RxWindowsParams[0] = ComputeRxWindowParameters( MAX( DR_0, LoRaMacParams.ChannelsDatarate - LoRaMacParams.Rx1DrOffset ), LoRaMacParams.SystemMaxRxError );
mluis 8:26002607de9c 2926 #endif
mluis 8:26002607de9c 2927 // Compute Rx2 windows parameters
mluis 8:26002607de9c 2928 RxWindowsParams[1] = ComputeRxWindowParameters( LoRaMacParams.Rx2Channel.Datarate, LoRaMacParams.SystemMaxRxError );
mluis 8:26002607de9c 2929
mluis 8:26002607de9c 2930 if( IsLoRaMacNetworkJoined == false )
mluis 8:26002607de9c 2931 {
mluis 8:26002607de9c 2932 RxWindow1Delay = LoRaMacParams.JoinAcceptDelay1 + RxWindowsParams[0].RxOffset;
mluis 8:26002607de9c 2933 RxWindow2Delay = LoRaMacParams.JoinAcceptDelay2 + RxWindowsParams[1].RxOffset;
mluis 8:26002607de9c 2934 }
mluis 8:26002607de9c 2935 else
mluis 8:26002607de9c 2936 {
terence304 10:1ac668ce2b15 2937 if( ValidatePayloadLength( LoRaMacTxPayloadLen, LoRaMacParams.ChannelsDatarate, MacCommandsBufferIndex ) == false )
terence304 10:1ac668ce2b15 2938 {
alphaemmeo 11:5b3e495baefb 2939 ser->printf("[LRMAC] LoRaMacStatus_t ScheduleTx :: LORAMAC_STATUS_LENGTH_ERROR\n\r");
terence304 10:1ac668ce2b15 2940 return LORAMAC_STATUS_LENGTH_ERROR;
terence304 10:1ac668ce2b15 2941 }
mluis 8:26002607de9c 2942 RxWindow1Delay = LoRaMacParams.ReceiveDelay1 + RxWindowsParams[0].RxOffset;
mluis 8:26002607de9c 2943 RxWindow2Delay = LoRaMacParams.ReceiveDelay2 + RxWindowsParams[1].RxOffset;
mluis 8:26002607de9c 2944 }
mluis 8:26002607de9c 2945
mluis 2:14a5d6ad92d5 2946 // Schedule transmission of frame
mluis 2:14a5d6ad92d5 2947 if( dutyCycleTimeOff == 0 )
mluis 2:14a5d6ad92d5 2948 {
mluis 2:14a5d6ad92d5 2949 // Try to send now
mluis 2:14a5d6ad92d5 2950 return SendFrameOnChannel( Channels[Channel] );
mluis 0:91d1a7783bb9 2951 }
mluis 0:91d1a7783bb9 2952 else
mluis 0:91d1a7783bb9 2953 {
mluis 2:14a5d6ad92d5 2954 // Send later - prepare timer
mluis 8:26002607de9c 2955 LoRaMacState |= LORAMAC_TX_DELAYED;
mluis 2:14a5d6ad92d5 2956 TimerSetValue( &TxDelayedTimer, dutyCycleTimeOff );
mluis 2:14a5d6ad92d5 2957 TimerStart( &TxDelayedTimer );
mluis 2:14a5d6ad92d5 2958
alphaemmeo 11:5b3e495baefb 2959 ser->printf("[LRMAC] LoRaMacStatus_t ScheduleTx :: LORAMAC_STATUS_OK\n\r");
mluis 2:14a5d6ad92d5 2960 return LORAMAC_STATUS_OK;
mluis 0:91d1a7783bb9 2961 }
mluis 2:14a5d6ad92d5 2962 }
mluis 2:14a5d6ad92d5 2963
mluis 8:26002607de9c 2964 static uint16_t JoinDutyCycle( void )
mluis 7:c16969e0f70f 2965 {
mluis 7:c16969e0f70f 2966 uint16_t dutyCycle = 0;
mluis 8:26002607de9c 2967 TimerTime_t timeElapsed = TimerGetElapsedTime( LoRaMacInitializationTime );
mluis 8:26002607de9c 2968
mluis 8:26002607de9c 2969 if( timeElapsed < 3600e3 )
mluis 7:c16969e0f70f 2970 {
mluis 7:c16969e0f70f 2971 dutyCycle = BACKOFF_DC_1_HOUR;
mluis 7:c16969e0f70f 2972 }
mluis 8:26002607de9c 2973 else if( timeElapsed < ( 3600e3 + 36000e3 ) )
mluis 7:c16969e0f70f 2974 {
mluis 7:c16969e0f70f 2975 dutyCycle = BACKOFF_DC_10_HOURS;
mluis 7:c16969e0f70f 2976 }
mluis 7:c16969e0f70f 2977 else
mluis 7:c16969e0f70f 2978 {
mluis 7:c16969e0f70f 2979 dutyCycle = BACKOFF_DC_24_HOURS;
mluis 7:c16969e0f70f 2980 }
mluis 7:c16969e0f70f 2981 return dutyCycle;
mluis 7:c16969e0f70f 2982 }
mluis 7:c16969e0f70f 2983
mluis 4:37c12dbc8dc7 2984 static void CalculateBackOff( uint8_t channel )
mluis 4:37c12dbc8dc7 2985 {
mluis 4:37c12dbc8dc7 2986 uint16_t dutyCycle = Bands[Channels[channel].Band].DCycle;
mluis 7:c16969e0f70f 2987 uint16_t joinDutyCycle = 0;
mluis 8:26002607de9c 2988
mluis 8:26002607de9c 2989 // Reset time-off to initial value.
mluis 8:26002607de9c 2990 Bands[Channels[channel].Band].TimeOff = 0;
mluis 4:37c12dbc8dc7 2991
mluis 4:37c12dbc8dc7 2992 if( IsLoRaMacNetworkJoined == false )
mluis 4:37c12dbc8dc7 2993 {
mluis 8:26002607de9c 2994 // The node has not joined yet. Apply join duty cycle to all regions.
mluis 8:26002607de9c 2995 joinDutyCycle = JoinDutyCycle( );
mluis 7:c16969e0f70f 2996 dutyCycle = MAX( dutyCycle, joinDutyCycle );
mluis 7:c16969e0f70f 2997
mluis 8:26002607de9c 2998 // Update Band time-off.
mluis 4:37c12dbc8dc7 2999 Bands[Channels[channel].Band].TimeOff = TxTimeOnAir * dutyCycle - TxTimeOnAir;
mluis 4:37c12dbc8dc7 3000 }
mluis 4:37c12dbc8dc7 3001 else
mluis 4:37c12dbc8dc7 3002 {
mluis 8:26002607de9c 3003 if( DutyCycleOn == true )
mluis 8:26002607de9c 3004 {
mluis 8:26002607de9c 3005 Bands[Channels[channel].Band].TimeOff = TxTimeOnAir * dutyCycle - TxTimeOnAir;
mluis 8:26002607de9c 3006 }
mluis 7:c16969e0f70f 3007 }
mluis 7:c16969e0f70f 3008
mluis 4:37c12dbc8dc7 3009 // Update Aggregated Time OFF
mluis 4:37c12dbc8dc7 3010 AggregatedTimeOff = AggregatedTimeOff + ( TxTimeOnAir * AggregatedDCycle - TxTimeOnAir );
mluis 4:37c12dbc8dc7 3011 }
mluis 4:37c12dbc8dc7 3012
mluis 7:c16969e0f70f 3013 static int8_t AlternateDatarate( uint16_t nbTrials )
mluis 7:c16969e0f70f 3014 {
mluis 7:c16969e0f70f 3015 int8_t datarate = LORAMAC_TX_MIN_DATARATE;
mluis 7:c16969e0f70f 3016 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 7:c16969e0f70f 3017 #if defined( USE_BAND_915 )
mluis 7:c16969e0f70f 3018 // Re-enable 500 kHz default channels
mluis 7:c16969e0f70f 3019 LoRaMacParams.ChannelsMask[4] = 0x00FF;
mluis 7:c16969e0f70f 3020 #else // defined( USE_BAND_915_HYBRID )
mluis 7:c16969e0f70f 3021 // Re-enable 500 kHz default channels
mluis 8:26002607de9c 3022 ReenableChannels( LoRaMacParamsDefaults.ChannelsMask[4], LoRaMacParams.ChannelsMask );
mluis 7:c16969e0f70f 3023 #endif
mluis 7:c16969e0f70f 3024
mluis 7:c16969e0f70f 3025 if( ( nbTrials & 0x01 ) == 0x01 )
mluis 7:c16969e0f70f 3026 {
mluis 7:c16969e0f70f 3027 datarate = DR_4;
mluis 7:c16969e0f70f 3028 }
mluis 7:c16969e0f70f 3029 else
mluis 7:c16969e0f70f 3030 {
mluis 8:26002607de9c 3031 datarate = DR_0;
mluis 7:c16969e0f70f 3032 }
mluis 7:c16969e0f70f 3033 #else
mluis 7:c16969e0f70f 3034 if( ( nbTrials % 48 ) == 0 )
mluis 7:c16969e0f70f 3035 {
mluis 7:c16969e0f70f 3036 datarate = DR_0;
mluis 7:c16969e0f70f 3037 }
mluis 7:c16969e0f70f 3038 else if( ( nbTrials % 32 ) == 0 )
mluis 7:c16969e0f70f 3039 {
mluis 7:c16969e0f70f 3040 datarate = DR_1;
mluis 7:c16969e0f70f 3041 }
mluis 7:c16969e0f70f 3042 else if( ( nbTrials % 24 ) == 0 )
mluis 7:c16969e0f70f 3043 {
mluis 7:c16969e0f70f 3044 datarate = DR_2;
mluis 7:c16969e0f70f 3045 }
mluis 7:c16969e0f70f 3046 else if( ( nbTrials % 16 ) == 0 )
mluis 7:c16969e0f70f 3047 {
mluis 7:c16969e0f70f 3048 datarate = DR_3;
mluis 7:c16969e0f70f 3049 }
mluis 7:c16969e0f70f 3050 else if( ( nbTrials % 8 ) == 0 )
mluis 7:c16969e0f70f 3051 {
mluis 7:c16969e0f70f 3052 datarate = DR_4;
mluis 7:c16969e0f70f 3053 }
mluis 7:c16969e0f70f 3054 else
mluis 7:c16969e0f70f 3055 {
mluis 7:c16969e0f70f 3056 datarate = DR_5;
mluis 7:c16969e0f70f 3057 }
mluis 7:c16969e0f70f 3058 #endif
mluis 7:c16969e0f70f 3059 return datarate;
mluis 7:c16969e0f70f 3060 }
mluis 7:c16969e0f70f 3061
mluis 7:c16969e0f70f 3062 static void ResetMacParameters( void )
mluis 7:c16969e0f70f 3063 {
mluis 7:c16969e0f70f 3064 IsLoRaMacNetworkJoined = false;
mluis 7:c16969e0f70f 3065
mluis 7:c16969e0f70f 3066 // Counters
mluis 8:26002607de9c 3067 UpLinkCounter = 0;
mluis 7:c16969e0f70f 3068 DownLinkCounter = 0;
mluis 7:c16969e0f70f 3069 AdrAckCounter = 0;
mluis 7:c16969e0f70f 3070
mluis 7:c16969e0f70f 3071 ChannelsNbRepCounter = 0;
mluis 7:c16969e0f70f 3072
mluis 7:c16969e0f70f 3073 AckTimeoutRetries = 1;
mluis 7:c16969e0f70f 3074 AckTimeoutRetriesCounter = 1;
mluis 7:c16969e0f70f 3075 AckTimeoutRetry = false;
mluis 7:c16969e0f70f 3076
mluis 7:c16969e0f70f 3077 MaxDCycle = 0;
mluis 7:c16969e0f70f 3078 AggregatedDCycle = 1;
mluis 7:c16969e0f70f 3079
mluis 7:c16969e0f70f 3080 MacCommandsBufferIndex = 0;
mluis 7:c16969e0f70f 3081 MacCommandsBufferToRepeatIndex = 0;
mluis 7:c16969e0f70f 3082
mluis 7:c16969e0f70f 3083 IsRxWindowsEnabled = true;
mluis 7:c16969e0f70f 3084
mluis 7:c16969e0f70f 3085 LoRaMacParams.ChannelsTxPower = LoRaMacParamsDefaults.ChannelsTxPower;
mluis 7:c16969e0f70f 3086 LoRaMacParams.ChannelsDatarate = LoRaMacParamsDefaults.ChannelsDatarate;
mluis 7:c16969e0f70f 3087
mluis 7:c16969e0f70f 3088 LoRaMacParams.Rx1DrOffset = LoRaMacParamsDefaults.Rx1DrOffset;
mluis 7:c16969e0f70f 3089 LoRaMacParams.Rx2Channel = LoRaMacParamsDefaults.Rx2Channel;
mluis 7:c16969e0f70f 3090
mluis 7:c16969e0f70f 3091 memcpy1( ( uint8_t* ) LoRaMacParams.ChannelsMask, ( uint8_t* ) LoRaMacParamsDefaults.ChannelsMask, sizeof( LoRaMacParams.ChannelsMask ) );
mluis 7:c16969e0f70f 3092
mluis 7:c16969e0f70f 3093 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 7:c16969e0f70f 3094 memcpy1( ( uint8_t* ) ChannelsMaskRemaining, ( uint8_t* ) LoRaMacParamsDefaults.ChannelsMask, sizeof( LoRaMacParams.ChannelsMask ) );
mluis 7:c16969e0f70f 3095 #endif
mluis 7:c16969e0f70f 3096
mluis 7:c16969e0f70f 3097
mluis 7:c16969e0f70f 3098 NodeAckRequested = false;
mluis 7:c16969e0f70f 3099 SrvAckRequested = false;
mluis 7:c16969e0f70f 3100 MacCommandsInNextTx = false;
mluis 7:c16969e0f70f 3101
mluis 7:c16969e0f70f 3102 // Reset Multicast downlink counters
mluis 7:c16969e0f70f 3103 MulticastParams_t *cur = MulticastChannels;
mluis 7:c16969e0f70f 3104 while( cur != NULL )
mluis 7:c16969e0f70f 3105 {
mluis 7:c16969e0f70f 3106 cur->DownLinkCounter = 0;
mluis 7:c16969e0f70f 3107 cur = cur->Next;
mluis 7:c16969e0f70f 3108 }
mluis 7:c16969e0f70f 3109
mluis 7:c16969e0f70f 3110 // Initialize channel index.
mluis 7:c16969e0f70f 3111 Channel = LORA_MAX_NB_CHANNELS;
mluis 7:c16969e0f70f 3112 }
mluis 7:c16969e0f70f 3113
mluis 2:14a5d6ad92d5 3114 LoRaMacStatus_t PrepareFrame( LoRaMacHeader_t *macHdr, LoRaMacFrameCtrl_t *fCtrl, uint8_t fPort, void *fBuffer, uint16_t fBufferSize )
mluis 2:14a5d6ad92d5 3115 {
alphaemmeo 11:5b3e495baefb 3116 ser->printf("[LRMAC] LoRaMacStatus_t PrepareFrame \n\r");
mluis 2:14a5d6ad92d5 3117 uint16_t i;
mluis 2:14a5d6ad92d5 3118 uint8_t pktHeaderLen = 0;
mluis 2:14a5d6ad92d5 3119 uint32_t mic = 0;
mluis 2:14a5d6ad92d5 3120 const void* payload = fBuffer;
mluis 2:14a5d6ad92d5 3121 uint8_t framePort = fPort;
mluis 2:14a5d6ad92d5 3122
mluis 2:14a5d6ad92d5 3123 LoRaMacBufferPktLen = 0;
mluis 2:14a5d6ad92d5 3124
mluis 2:14a5d6ad92d5 3125 NodeAckRequested = false;
mluis 2:14a5d6ad92d5 3126
mluis 2:14a5d6ad92d5 3127 if( fBuffer == NULL )
mluis 0:91d1a7783bb9 3128 {
mluis 2:14a5d6ad92d5 3129 fBufferSize = 0;
mluis 2:14a5d6ad92d5 3130 }
mluis 2:14a5d6ad92d5 3131
mluis 8:26002607de9c 3132 LoRaMacTxPayloadLen = fBufferSize;
mluis 8:26002607de9c 3133
mluis 2:14a5d6ad92d5 3134 LoRaMacBuffer[pktHeaderLen++] = macHdr->Value;
mluis 2:14a5d6ad92d5 3135
mluis 2:14a5d6ad92d5 3136 switch( macHdr->Bits.MType )
mluis 2:14a5d6ad92d5 3137 {
mluis 2:14a5d6ad92d5 3138 case FRAME_TYPE_JOIN_REQ:
mluis 2:14a5d6ad92d5 3139 LoRaMacBufferPktLen = pktHeaderLen;
mluis 2:14a5d6ad92d5 3140
mluis 2:14a5d6ad92d5 3141 memcpyr( LoRaMacBuffer + LoRaMacBufferPktLen, LoRaMacAppEui, 8 );
mluis 2:14a5d6ad92d5 3142 LoRaMacBufferPktLen += 8;
mluis 2:14a5d6ad92d5 3143 memcpyr( LoRaMacBuffer + LoRaMacBufferPktLen, LoRaMacDevEui, 8 );
mluis 2:14a5d6ad92d5 3144 LoRaMacBufferPktLen += 8;
mluis 2:14a5d6ad92d5 3145
mluis 2:14a5d6ad92d5 3146 LoRaMacDevNonce = Radio.Random( );
mluis 2:14a5d6ad92d5 3147
mluis 2:14a5d6ad92d5 3148 LoRaMacBuffer[LoRaMacBufferPktLen++] = LoRaMacDevNonce & 0xFF;
mluis 2:14a5d6ad92d5 3149 LoRaMacBuffer[LoRaMacBufferPktLen++] = ( LoRaMacDevNonce >> 8 ) & 0xFF;
mluis 2:14a5d6ad92d5 3150
mluis 2:14a5d6ad92d5 3151 LoRaMacJoinComputeMic( LoRaMacBuffer, LoRaMacBufferPktLen & 0xFF, LoRaMacAppKey, &mic );
mluis 2:14a5d6ad92d5 3152
mluis 2:14a5d6ad92d5 3153 LoRaMacBuffer[LoRaMacBufferPktLen++] = mic & 0xFF;
mluis 2:14a5d6ad92d5 3154 LoRaMacBuffer[LoRaMacBufferPktLen++] = ( mic >> 8 ) & 0xFF;
mluis 2:14a5d6ad92d5 3155 LoRaMacBuffer[LoRaMacBufferPktLen++] = ( mic >> 16 ) & 0xFF;
mluis 2:14a5d6ad92d5 3156 LoRaMacBuffer[LoRaMacBufferPktLen++] = ( mic >> 24 ) & 0xFF;
mluis 2:14a5d6ad92d5 3157
mluis 2:14a5d6ad92d5 3158 break;
mluis 2:14a5d6ad92d5 3159 case FRAME_TYPE_DATA_CONFIRMED_UP:
mluis 2:14a5d6ad92d5 3160 NodeAckRequested = true;
mluis 8:26002607de9c 3161 //Intentional fallthrough
mluis 2:14a5d6ad92d5 3162 case FRAME_TYPE_DATA_UNCONFIRMED_UP:
alphaemmeo 11:5b3e495baefb 3163 ser->printf("[LRMAC] LoRaMacStatus_t PrepareFrame :: FRAME_TYPE_DATA_UNCONFIRMED_UP \n\r");
mluis 2:14a5d6ad92d5 3164 if( IsLoRaMacNetworkJoined == false )
mluis 0:91d1a7783bb9 3165 {
alphaemmeo 11:5b3e495baefb 3166 ser->printf("[LRMAC] LoRaMacStatus_t PrepareFrame :: LORAMAC_STATUS_NO_NETWORK_JOINED \n\r");
mluis 2:14a5d6ad92d5 3167 return LORAMAC_STATUS_NO_NETWORK_JOINED; // No network has been joined yet
mluis 2:14a5d6ad92d5 3168 }
mluis 2:14a5d6ad92d5 3169
mluis 7:c16969e0f70f 3170 fCtrl->Bits.AdrAckReq = AdrNextDr( fCtrl->Bits.Adr, true, &LoRaMacParams.ChannelsDatarate );
terence304 9:db4900d60c37 3171
mluis 2:14a5d6ad92d5 3172 if( SrvAckRequested == true )
mluis 2:14a5d6ad92d5 3173 {
mluis 2:14a5d6ad92d5 3174 SrvAckRequested = false;
mluis 2:14a5d6ad92d5 3175 fCtrl->Bits.Ack = 1;
mluis 2:14a5d6ad92d5 3176 }
mluis 2:14a5d6ad92d5 3177
mluis 2:14a5d6ad92d5 3178 LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr ) & 0xFF;
mluis 2:14a5d6ad92d5 3179 LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr >> 8 ) & 0xFF;
mluis 2:14a5d6ad92d5 3180 LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr >> 16 ) & 0xFF;
mluis 2:14a5d6ad92d5 3181 LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr >> 24 ) & 0xFF;
mluis 2:14a5d6ad92d5 3182
mluis 2:14a5d6ad92d5 3183 LoRaMacBuffer[pktHeaderLen++] = fCtrl->Value;
mluis 2:14a5d6ad92d5 3184
mluis 2:14a5d6ad92d5 3185 LoRaMacBuffer[pktHeaderLen++] = UpLinkCounter & 0xFF;
mluis 2:14a5d6ad92d5 3186 LoRaMacBuffer[pktHeaderLen++] = ( UpLinkCounter >> 8 ) & 0xFF;
mluis 2:14a5d6ad92d5 3187
mluis 7:c16969e0f70f 3188 // Copy the MAC commands which must be re-send into the MAC command buffer
mluis 7:c16969e0f70f 3189 memcpy1( &MacCommandsBuffer[MacCommandsBufferIndex], MacCommandsBufferToRepeat, MacCommandsBufferToRepeatIndex );
mluis 7:c16969e0f70f 3190 MacCommandsBufferIndex += MacCommandsBufferToRepeatIndex;
mluis 7:c16969e0f70f 3191
mluis 8:26002607de9c 3192 if( ( payload != NULL ) && ( LoRaMacTxPayloadLen > 0 ) )
mluis 2:14a5d6ad92d5 3193 {
mluis 2:14a5d6ad92d5 3194 if( ( MacCommandsBufferIndex <= LORA_MAC_COMMAND_MAX_LENGTH ) && ( MacCommandsInNextTx == true ) )
mluis 1:91e4e6c60d1e 3195 {
mluis 2:14a5d6ad92d5 3196 fCtrl->Bits.FOptsLen += MacCommandsBufferIndex;
mluis 2:14a5d6ad92d5 3197
mluis 2:14a5d6ad92d5 3198 // Update FCtrl field with new value of OptionsLength
mluis 2:14a5d6ad92d5 3199 LoRaMacBuffer[0x05] = fCtrl->Value;
mluis 2:14a5d6ad92d5 3200 for( i = 0; i < MacCommandsBufferIndex; i++ )
mluis 0:91d1a7783bb9 3201 {
mluis 2:14a5d6ad92d5 3202 LoRaMacBuffer[pktHeaderLen++] = MacCommandsBuffer[i];
mluis 0:91d1a7783bb9 3203 }
mluis 0:91d1a7783bb9 3204 }
mluis 0:91d1a7783bb9 3205 }
mluis 0:91d1a7783bb9 3206 else
mluis 0:91d1a7783bb9 3207 {
mluis 2:14a5d6ad92d5 3208 if( ( MacCommandsBufferIndex > 0 ) && ( MacCommandsInNextTx ) )
mluis 0:91d1a7783bb9 3209 {
mluis 8:26002607de9c 3210 LoRaMacTxPayloadLen = MacCommandsBufferIndex;
mluis 2:14a5d6ad92d5 3211 payload = MacCommandsBuffer;
mluis 2:14a5d6ad92d5 3212 framePort = 0;
mluis 0:91d1a7783bb9 3213 }
mluis 2:14a5d6ad92d5 3214 }
mluis 2:14a5d6ad92d5 3215 MacCommandsInNextTx = false;
mluis 7:c16969e0f70f 3216 // Store MAC commands which must be re-send in case the device does not receive a downlink anymore
mluis 7:c16969e0f70f 3217 MacCommandsBufferToRepeatIndex = ParseMacCommandsToRepeat( MacCommandsBuffer, MacCommandsBufferIndex, MacCommandsBufferToRepeat );
mluis 7:c16969e0f70f 3218 if( MacCommandsBufferToRepeatIndex > 0 )
mluis 7:c16969e0f70f 3219 {
mluis 7:c16969e0f70f 3220 MacCommandsInNextTx = true;
mluis 7:c16969e0f70f 3221 }
mluis 8:26002607de9c 3222
mluis 8:26002607de9c 3223 if( ( payload != NULL ) && ( LoRaMacTxPayloadLen > 0 ) )
mluis 2:14a5d6ad92d5 3224 {
mluis 2:14a5d6ad92d5 3225 LoRaMacBuffer[pktHeaderLen++] = framePort;
mluis 2:14a5d6ad92d5 3226
mluis 2:14a5d6ad92d5 3227 if( framePort == 0 )
mluis 0:91d1a7783bb9 3228 {
mluis 8:26002607de9c 3229 LoRaMacPayloadEncrypt( (uint8_t* ) payload, LoRaMacTxPayloadLen, LoRaMacNwkSKey, LoRaMacDevAddr, UP_LINK, UpLinkCounter, &LoRaMacBuffer[pktHeaderLen] );
mluis 0:91d1a7783bb9 3230 }
mluis 0:91d1a7783bb9 3231 else
mluis 0:91d1a7783bb9 3232 {
mluis 8:26002607de9c 3233 LoRaMacPayloadEncrypt( (uint8_t* ) payload, LoRaMacTxPayloadLen, LoRaMacAppSKey, LoRaMacDevAddr, UP_LINK, UpLinkCounter, &LoRaMacBuffer[pktHeaderLen] );
mluis 0:91d1a7783bb9 3234 }
mluis 2:14a5d6ad92d5 3235 }
mluis 8:26002607de9c 3236 LoRaMacBufferPktLen = pktHeaderLen + LoRaMacTxPayloadLen;
mluis 2:14a5d6ad92d5 3237
mluis 2:14a5d6ad92d5 3238 LoRaMacComputeMic( LoRaMacBuffer, LoRaMacBufferPktLen, LoRaMacNwkSKey, LoRaMacDevAddr, UP_LINK, UpLinkCounter, &mic );
mluis 2:14a5d6ad92d5 3239
mluis 2:14a5d6ad92d5 3240 LoRaMacBuffer[LoRaMacBufferPktLen + 0] = mic & 0xFF;
mluis 2:14a5d6ad92d5 3241 LoRaMacBuffer[LoRaMacBufferPktLen + 1] = ( mic >> 8 ) & 0xFF;
mluis 2:14a5d6ad92d5 3242 LoRaMacBuffer[LoRaMacBufferPktLen + 2] = ( mic >> 16 ) & 0xFF;
mluis 2:14a5d6ad92d5 3243 LoRaMacBuffer[LoRaMacBufferPktLen + 3] = ( mic >> 24 ) & 0xFF;
mluis 2:14a5d6ad92d5 3244
mluis 2:14a5d6ad92d5 3245 LoRaMacBufferPktLen += LORAMAC_MFR_LEN;
mluis 2:14a5d6ad92d5 3246
mluis 2:14a5d6ad92d5 3247 break;
mluis 2:14a5d6ad92d5 3248 case FRAME_TYPE_PROPRIETARY:
mluis 8:26002607de9c 3249 if( ( fBuffer != NULL ) && ( LoRaMacTxPayloadLen > 0 ) )
mluis 2:14a5d6ad92d5 3250 {
mluis 8:26002607de9c 3251 memcpy1( LoRaMacBuffer + pktHeaderLen, ( uint8_t* ) fBuffer, LoRaMacTxPayloadLen );
mluis 8:26002607de9c 3252 LoRaMacBufferPktLen = pktHeaderLen + LoRaMacTxPayloadLen;
mluis 0:91d1a7783bb9 3253 }
mluis 0:91d1a7783bb9 3254 break;
mluis 0:91d1a7783bb9 3255 default:
mluis 2:14a5d6ad92d5 3256 return LORAMAC_STATUS_SERVICE_UNKNOWN;
mluis 0:91d1a7783bb9 3257 }
mluis 2:14a5d6ad92d5 3258
alphaemmeo 11:5b3e495baefb 3259 ser->printf("[LRMAC] LoRaMacStatus_t PrepareFrame :: LORAMAC_STATUS_OK \n\r");
mluis 2:14a5d6ad92d5 3260 return LORAMAC_STATUS_OK;
mluis 0:91d1a7783bb9 3261 }
mluis 0:91d1a7783bb9 3262
mluis 2:14a5d6ad92d5 3263 LoRaMacStatus_t SendFrameOnChannel( ChannelParams_t channel )
mluis 0:91d1a7783bb9 3264 {
alphaemmeo 11:5b3e495baefb 3265 ser->printf("[LRMAC] LoRaMacStatus_t SendFrameOnChannel\n\r");
mluis 7:c16969e0f70f 3266 int8_t datarate = Datarates[LoRaMacParams.ChannelsDatarate];
mluis 4:37c12dbc8dc7 3267 int8_t txPowerIndex = 0;
mluis 2:14a5d6ad92d5 3268 int8_t txPower = 0;
mluis 2:14a5d6ad92d5 3269
mluis 8:26002607de9c 3270 txPowerIndex = LimitTxPower( LoRaMacParams.ChannelsTxPower, Bands[channel.Band].TxMaxPower );
mluis 4:37c12dbc8dc7 3271 txPower = TxPowers[txPowerIndex];
mluis 2:14a5d6ad92d5 3272
mluis 2:14a5d6ad92d5 3273 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR;
mluis 2:14a5d6ad92d5 3274 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR;
mluis 7:c16969e0f70f 3275 McpsConfirm.Datarate = LoRaMacParams.ChannelsDatarate;
mluis 4:37c12dbc8dc7 3276 McpsConfirm.TxPower = txPowerIndex;
mluis 8:26002607de9c 3277 McpsConfirm.UpLinkFrequency = channel.Frequency;
mluis 2:14a5d6ad92d5 3278
mluis 2:14a5d6ad92d5 3279 Radio.SetChannel( channel.Frequency );
mluis 2:14a5d6ad92d5 3280
mluis 2:14a5d6ad92d5 3281 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
mluis 7:c16969e0f70f 3282 if( LoRaMacParams.ChannelsDatarate == DR_7 )
mluis 2:14a5d6ad92d5 3283 { // High Speed FSK channel
mluis 2:14a5d6ad92d5 3284 Radio.SetMaxPayloadLength( MODEM_FSK, LoRaMacBufferPktLen );
mluis 8:26002607de9c 3285 Radio.SetTxConfig( MODEM_FSK, txPower, 25e3, 0, datarate * 1e3, 0, 5, false, true, 0, 0, false, 3e3 );
mluis 2:14a5d6ad92d5 3286 TxTimeOnAir = Radio.TimeOnAir( MODEM_FSK, LoRaMacBufferPktLen );
mluis 2:14a5d6ad92d5 3287
mluis 0:91d1a7783bb9 3288 }
mluis 7:c16969e0f70f 3289 else if( LoRaMacParams.ChannelsDatarate == DR_6 )
mluis 2:14a5d6ad92d5 3290 { // High speed LoRa channel
mluis 2:14a5d6ad92d5 3291 Radio.SetMaxPayloadLength( MODEM_LORA, LoRaMacBufferPktLen );
mluis 8:26002607de9c 3292 Radio.SetTxConfig( MODEM_LORA, txPower, 0, 1, datarate, 1, 8, false, true, 0, 0, false, 3e3 );
mluis 2:14a5d6ad92d5 3293 TxTimeOnAir = Radio.TimeOnAir( MODEM_LORA, LoRaMacBufferPktLen );
mluis 0:91d1a7783bb9 3294 }
mluis 1:91e4e6c60d1e 3295 else
mluis 2:14a5d6ad92d5 3296 { // Normal LoRa channel
alphaemmeo 11:5b3e495baefb 3297 ser->printf("[LRMAC] LoRaMacStatus_t SendFrameOnChannel :: Normal LoRa channel \n\r");
alphaemmeo 11:5b3e495baefb 3298
mluis 2:14a5d6ad92d5 3299 Radio.SetMaxPayloadLength( MODEM_LORA, LoRaMacBufferPktLen );
mluis 8:26002607de9c 3300 Radio.SetTxConfig( MODEM_LORA, txPower, 0, 0, datarate, 1, 8, false, true, 0, 0, false, 3e3 );
mluis 2:14a5d6ad92d5 3301 TxTimeOnAir = Radio.TimeOnAir( MODEM_LORA, LoRaMacBufferPktLen );
mluis 0:91d1a7783bb9 3302 }
mluis 2:14a5d6ad92d5 3303 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 2:14a5d6ad92d5 3304 Radio.SetMaxPayloadLength( MODEM_LORA, LoRaMacBufferPktLen );
mluis 7:c16969e0f70f 3305 if( LoRaMacParams.ChannelsDatarate >= DR_4 )
mluis 2:14a5d6ad92d5 3306 { // High speed LoRa channel BW500 kHz
mluis 8:26002607de9c 3307 Radio.SetTxConfig( MODEM_LORA, txPower, 0, 2, datarate, 1, 8, false, true, 0, 0, false, 3e3 );
mluis 2:14a5d6ad92d5 3308 TxTimeOnAir = Radio.TimeOnAir( MODEM_LORA, LoRaMacBufferPktLen );
mluis 0:91d1a7783bb9 3309 }
mluis 1:91e4e6c60d1e 3310 else
mluis 2:14a5d6ad92d5 3311 { // Normal LoRa channel
mluis 8:26002607de9c 3312 Radio.SetTxConfig( MODEM_LORA, txPower, 0, 0, datarate, 1, 8, false, true, 0, 0, false, 3e3 );
mluis 2:14a5d6ad92d5 3313 TxTimeOnAir = Radio.TimeOnAir( MODEM_LORA, LoRaMacBufferPktLen );
mluis 0:91d1a7783bb9 3314 }
mluis 8:26002607de9c 3315 #elif defined( USE_BAND_470 )
mluis 8:26002607de9c 3316 Radio.SetMaxPayloadLength( MODEM_LORA, LoRaMacBufferPktLen );
mluis 8:26002607de9c 3317 Radio.SetTxConfig( MODEM_LORA, txPower, 0, 0, datarate, 1, 8, false, true, 0, 0, false, 3e3 );
mluis 8:26002607de9c 3318 TxTimeOnAir = Radio.TimeOnAir( MODEM_LORA, LoRaMacBufferPktLen );
mluis 0:91d1a7783bb9 3319 #else
mluis 0:91d1a7783bb9 3320 #error "Please define a frequency band in the compiler options."
mluis 0:91d1a7783bb9 3321 #endif
mluis 2:14a5d6ad92d5 3322
mluis 2:14a5d6ad92d5 3323 // Store the time on air
mluis 2:14a5d6ad92d5 3324 McpsConfirm.TxTimeOnAir = TxTimeOnAir;
mluis 2:14a5d6ad92d5 3325 MlmeConfirm.TxTimeOnAir = TxTimeOnAir;
mluis 2:14a5d6ad92d5 3326
mluis 2:14a5d6ad92d5 3327 // Starts the MAC layer status check timer
mluis 3:b9d87593a8ae 3328 TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT );
mluis 2:14a5d6ad92d5 3329 TimerStart( &MacStateCheckTimer );
mluis 2:14a5d6ad92d5 3330
mluis 8:26002607de9c 3331 if( IsLoRaMacNetworkJoined == false )
mluis 8:26002607de9c 3332 {
mluis 8:26002607de9c 3333 JoinRequestTrials++;
alphaemmeo 11:5b3e495baefb 3334 ser->printf("[LRMAC] [LRMAC] LoRaMacStatus_t SendFrameOnChannel :: JoinRequestTrials++\n\r");
mluis 8:26002607de9c 3335 }
mluis 8:26002607de9c 3336
mluis 2:14a5d6ad92d5 3337 // Send now
mluis 2:14a5d6ad92d5 3338 Radio.Send( LoRaMacBuffer, LoRaMacBufferPktLen );
mluis 2:14a5d6ad92d5 3339
mluis 8:26002607de9c 3340 LoRaMacState |= LORAMAC_TX_RUNNING;
mluis 8:26002607de9c 3341
alphaemmeo 11:5b3e495baefb 3342 ser->printf("[LRMAC] LoRaMacStatus_t SendFrameOnChannel :: LORAMAC_STATUS_OK\n\r");
mluis 8:26002607de9c 3343 return LORAMAC_STATUS_OK;
mluis 8:26002607de9c 3344 }
mluis 8:26002607de9c 3345
mluis 8:26002607de9c 3346 LoRaMacStatus_t SetTxContinuousWave( uint16_t timeout )
mluis 8:26002607de9c 3347 {
mluis 8:26002607de9c 3348 int8_t txPowerIndex = 0;
mluis 8:26002607de9c 3349 int8_t txPower = 0;
mluis 8:26002607de9c 3350
mluis 8:26002607de9c 3351 txPowerIndex = LimitTxPower( LoRaMacParams.ChannelsTxPower, Bands[Channels[Channel].Band].TxMaxPower );
mluis 8:26002607de9c 3352 txPower = TxPowers[txPowerIndex];
mluis 8:26002607de9c 3353
mluis 8:26002607de9c 3354 // Starts the MAC layer status check timer
mluis 8:26002607de9c 3355 TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT );
mluis 8:26002607de9c 3356 TimerStart( &MacStateCheckTimer );
mluis 8:26002607de9c 3357
mluis 8:26002607de9c 3358 Radio.SetTxContinuousWave( Channels[Channel].Frequency, txPower, timeout );
mluis 8:26002607de9c 3359
mluis 8:26002607de9c 3360 LoRaMacState |= LORAMAC_TX_RUNNING;
mluis 8:26002607de9c 3361
mluis 8:26002607de9c 3362 return LORAMAC_STATUS_OK;
mluis 8:26002607de9c 3363 }
mluis 8:26002607de9c 3364
mluis 8:26002607de9c 3365 LoRaMacStatus_t SetTxContinuousWave1( uint16_t timeout, uint32_t frequency, uint8_t power )
mluis 8:26002607de9c 3366 {
mluis 8:26002607de9c 3367 Radio.SetTxContinuousWave( frequency, power, timeout );
mluis 8:26002607de9c 3368
mluis 8:26002607de9c 3369 // Starts the MAC layer status check timer
mluis 8:26002607de9c 3370 TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT );
mluis 8:26002607de9c 3371 TimerStart( &MacStateCheckTimer );
mluis 8:26002607de9c 3372
mluis 8:26002607de9c 3373 LoRaMacState |= LORAMAC_TX_RUNNING;
mluis 2:14a5d6ad92d5 3374
mluis 2:14a5d6ad92d5 3375 return LORAMAC_STATUS_OK;
mluis 2:14a5d6ad92d5 3376 }
mluis 2:14a5d6ad92d5 3377
mluis 2:14a5d6ad92d5 3378 LoRaMacStatus_t LoRaMacInitialization( LoRaMacPrimitives_t *primitives, LoRaMacCallback_t *callbacks )
mluis 2:14a5d6ad92d5 3379 {
mluis 2:14a5d6ad92d5 3380 if( primitives == NULL )
mluis 2:14a5d6ad92d5 3381 {
mluis 2:14a5d6ad92d5 3382 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 3383 }
mluis 2:14a5d6ad92d5 3384
mluis 2:14a5d6ad92d5 3385 if( ( primitives->MacMcpsConfirm == NULL ) ||
mluis 2:14a5d6ad92d5 3386 ( primitives->MacMcpsIndication == NULL ) ||
mluis 8:26002607de9c 3387 ( primitives->MacMlmeConfirm == NULL ) )
mluis 2:14a5d6ad92d5 3388 {
mluis 2:14a5d6ad92d5 3389 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 3390 }
mluis 2:14a5d6ad92d5 3391
mluis 2:14a5d6ad92d5 3392 LoRaMacPrimitives = primitives;
mluis 2:14a5d6ad92d5 3393 LoRaMacCallbacks = callbacks;
mluis 2:14a5d6ad92d5 3394
mluis 2:14a5d6ad92d5 3395 LoRaMacFlags.Value = 0;
mluis 2:14a5d6ad92d5 3396
mluis 2:14a5d6ad92d5 3397 LoRaMacDeviceClass = CLASS_A;
mluis 8:26002607de9c 3398 LoRaMacState = LORAMAC_IDLE;
mluis 7:c16969e0f70f 3399
mluis 7:c16969e0f70f 3400 JoinRequestTrials = 0;
mluis 8:26002607de9c 3401 MaxJoinRequestTrials = 1;
mluis 2:14a5d6ad92d5 3402 RepeaterSupport = false;
mluis 7:c16969e0f70f 3403
mluis 7:c16969e0f70f 3404 // Reset duty cycle times
mluis 7:c16969e0f70f 3405 AggregatedLastTxDoneTime = 0;
mluis 7:c16969e0f70f 3406 AggregatedTimeOff = 0;
mluis 7:c16969e0f70f 3407
mluis 7:c16969e0f70f 3408 // Duty cycle
mluis 2:14a5d6ad92d5 3409 #if defined( USE_BAND_433 )
mluis 8:26002607de9c 3410 DutyCycleOn = true;
mluis 8:26002607de9c 3411 #elif defined( USE_BAND_470 )
mluis 7:c16969e0f70f 3412 DutyCycleOn = false;
mluis 2:14a5d6ad92d5 3413 #elif defined( USE_BAND_780 )
mluis 8:26002607de9c 3414 DutyCycleOn = true;
mluis 2:14a5d6ad92d5 3415 #elif defined( USE_BAND_868 )
mluis 7:c16969e0f70f 3416 DutyCycleOn = true;
mluis 7:c16969e0f70f 3417 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 7:c16969e0f70f 3418 DutyCycleOn = false;
mluis 7:c16969e0f70f 3419 #else
mluis 7:c16969e0f70f 3420 #error "Please define a frequency band in the compiler options."
mluis 7:c16969e0f70f 3421 #endif
mluis 7:c16969e0f70f 3422
mluis 7:c16969e0f70f 3423 // Reset to defaults
mluis 7:c16969e0f70f 3424 LoRaMacParamsDefaults.ChannelsTxPower = LORAMAC_DEFAULT_TX_POWER;
mluis 7:c16969e0f70f 3425 LoRaMacParamsDefaults.ChannelsDatarate = LORAMAC_DEFAULT_DATARATE;
mluis 7:c16969e0f70f 3426
mluis 8:26002607de9c 3427 LoRaMacParamsDefaults.SystemMaxRxError = 10;
mluis 8:26002607de9c 3428 LoRaMacParamsDefaults.MinRxSymbols = 6;
mluis 7:c16969e0f70f 3429 LoRaMacParamsDefaults.MaxRxWindow = MAX_RX_WINDOW;
mluis 7:c16969e0f70f 3430 LoRaMacParamsDefaults.ReceiveDelay1 = RECEIVE_DELAY1;
mluis 7:c16969e0f70f 3431 LoRaMacParamsDefaults.ReceiveDelay2 = RECEIVE_DELAY2;
mluis 7:c16969e0f70f 3432 LoRaMacParamsDefaults.JoinAcceptDelay1 = JOIN_ACCEPT_DELAY1;
mluis 7:c16969e0f70f 3433 LoRaMacParamsDefaults.JoinAcceptDelay2 = JOIN_ACCEPT_DELAY2;
mluis 7:c16969e0f70f 3434
mluis 7:c16969e0f70f 3435 LoRaMacParamsDefaults.ChannelsNbRep = 1;
mluis 7:c16969e0f70f 3436 LoRaMacParamsDefaults.Rx1DrOffset = 0;
mluis 7:c16969e0f70f 3437
mluis 7:c16969e0f70f 3438 LoRaMacParamsDefaults.Rx2Channel = ( Rx2ChannelParams_t )RX_WND_2_CHANNEL;
mluis 7:c16969e0f70f 3439
mluis 7:c16969e0f70f 3440 // Channel mask
mluis 7:c16969e0f70f 3441 #if defined( USE_BAND_433 )
mluis 7:c16969e0f70f 3442 LoRaMacParamsDefaults.ChannelsMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 );
mluis 8:26002607de9c 3443 #elif defined ( USE_BAND_470 )
mluis 8:26002607de9c 3444 LoRaMacParamsDefaults.ChannelsMask[0] = 0xFFFF;
mluis 8:26002607de9c 3445 LoRaMacParamsDefaults.ChannelsMask[1] = 0xFFFF;
mluis 8:26002607de9c 3446 LoRaMacParamsDefaults.ChannelsMask[2] = 0xFFFF;
mluis 8:26002607de9c 3447 LoRaMacParamsDefaults.ChannelsMask[3] = 0xFFFF;
mluis 8:26002607de9c 3448 LoRaMacParamsDefaults.ChannelsMask[4] = 0xFFFF;
mluis 8:26002607de9c 3449 LoRaMacParamsDefaults.ChannelsMask[5] = 0xFFFF;
mluis 7:c16969e0f70f 3450 #elif defined( USE_BAND_780 )
mluis 7:c16969e0f70f 3451 LoRaMacParamsDefaults.ChannelsMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 );
mluis 7:c16969e0f70f 3452 #elif defined( USE_BAND_868 )
mluis 7:c16969e0f70f 3453 LoRaMacParamsDefaults.ChannelsMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 );
mluis 2:14a5d6ad92d5 3454 #elif defined( USE_BAND_915 )
mluis 7:c16969e0f70f 3455 LoRaMacParamsDefaults.ChannelsMask[0] = 0xFFFF;
mluis 7:c16969e0f70f 3456 LoRaMacParamsDefaults.ChannelsMask[1] = 0xFFFF;
mluis 7:c16969e0f70f 3457 LoRaMacParamsDefaults.ChannelsMask[2] = 0xFFFF;
mluis 7:c16969e0f70f 3458 LoRaMacParamsDefaults.ChannelsMask[3] = 0xFFFF;
mluis 7:c16969e0f70f 3459 LoRaMacParamsDefaults.ChannelsMask[4] = 0x00FF;
mluis 7:c16969e0f70f 3460 LoRaMacParamsDefaults.ChannelsMask[5] = 0x0000;
mluis 2:14a5d6ad92d5 3461 #elif defined( USE_BAND_915_HYBRID )
mluis 7:c16969e0f70f 3462 LoRaMacParamsDefaults.ChannelsMask[0] = 0x00FF;
mluis 7:c16969e0f70f 3463 LoRaMacParamsDefaults.ChannelsMask[1] = 0x0000;
mluis 7:c16969e0f70f 3464 LoRaMacParamsDefaults.ChannelsMask[2] = 0x0000;
mluis 7:c16969e0f70f 3465 LoRaMacParamsDefaults.ChannelsMask[3] = 0x0000;
mluis 7:c16969e0f70f 3466 LoRaMacParamsDefaults.ChannelsMask[4] = 0x0001;
mluis 7:c16969e0f70f 3467 LoRaMacParamsDefaults.ChannelsMask[5] = 0x0000;
mluis 2:14a5d6ad92d5 3468 #else
mluis 2:14a5d6ad92d5 3469 #error "Please define a frequency band in the compiler options."
mluis 2:14a5d6ad92d5 3470 #endif
mluis 2:14a5d6ad92d5 3471
mluis 2:14a5d6ad92d5 3472 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 2:14a5d6ad92d5 3473 // 125 kHz channels
mluis 2:14a5d6ad92d5 3474 for( uint8_t i = 0; i < LORA_MAX_NB_CHANNELS - 8; i++ )
mluis 0:91d1a7783bb9 3475 {
mluis 2:14a5d6ad92d5 3476 Channels[i].Frequency = 902.3e6 + i * 200e3;
mluis 2:14a5d6ad92d5 3477 Channels[i].DrRange.Value = ( DR_3 << 4 ) | DR_0;
mluis 2:14a5d6ad92d5 3478 Channels[i].Band = 0;
mluis 2:14a5d6ad92d5 3479 }
mluis 2:14a5d6ad92d5 3480 // 500 kHz channels
mluis 2:14a5d6ad92d5 3481 for( uint8_t i = LORA_MAX_NB_CHANNELS - 8; i < LORA_MAX_NB_CHANNELS; i++ )
mluis 2:14a5d6ad92d5 3482 {
mluis 2:14a5d6ad92d5 3483 Channels[i].Frequency = 903.0e6 + ( i - ( LORA_MAX_NB_CHANNELS - 8 ) ) * 1.6e6;
mluis 2:14a5d6ad92d5 3484 Channels[i].DrRange.Value = ( DR_4 << 4 ) | DR_4;
mluis 2:14a5d6ad92d5 3485 Channels[i].Band = 0;
mluis 2:14a5d6ad92d5 3486 }
mluis 8:26002607de9c 3487 #elif defined( USE_BAND_470 )
mluis 8:26002607de9c 3488 // 125 kHz channels
mluis 8:26002607de9c 3489 for( uint8_t i = 0; i < LORA_MAX_NB_CHANNELS; i++ )
mluis 8:26002607de9c 3490 {
mluis 8:26002607de9c 3491 Channels[i].Frequency = 470.3e6 + i * 200e3;
mluis 8:26002607de9c 3492 Channels[i].DrRange.Value = ( DR_5 << 4 ) | DR_0;
mluis 8:26002607de9c 3493 Channels[i].Band = 0;
mluis 8:26002607de9c 3494 }
mluis 2:14a5d6ad92d5 3495 #endif
mluis 2:14a5d6ad92d5 3496
mluis 8:26002607de9c 3497 // Init parameters which are not set in function ResetMacParameters
mluis 8:26002607de9c 3498 LoRaMacParams.SystemMaxRxError = LoRaMacParamsDefaults.SystemMaxRxError;
mluis 8:26002607de9c 3499 LoRaMacParams.MinRxSymbols = LoRaMacParamsDefaults.MinRxSymbols;
mluis 8:26002607de9c 3500 LoRaMacParams.MaxRxWindow = LoRaMacParamsDefaults.MaxRxWindow;
mluis 8:26002607de9c 3501 LoRaMacParams.ReceiveDelay1 = LoRaMacParamsDefaults.ReceiveDelay1;
mluis 8:26002607de9c 3502 LoRaMacParams.ReceiveDelay2 = LoRaMacParamsDefaults.ReceiveDelay2;
mluis 8:26002607de9c 3503 LoRaMacParams.JoinAcceptDelay1 = LoRaMacParamsDefaults.JoinAcceptDelay1;
mluis 8:26002607de9c 3504 LoRaMacParams.JoinAcceptDelay2 = LoRaMacParamsDefaults.JoinAcceptDelay2;
mluis 8:26002607de9c 3505 LoRaMacParams.ChannelsNbRep = LoRaMacParamsDefaults.ChannelsNbRep;
mluis 8:26002607de9c 3506
mluis 7:c16969e0f70f 3507 ResetMacParameters( );
mluis 7:c16969e0f70f 3508
mluis 7:c16969e0f70f 3509 // Initialize timers
mluis 2:14a5d6ad92d5 3510 TimerInit( &MacStateCheckTimer, OnMacStateCheckTimerEvent );
mluis 2:14a5d6ad92d5 3511 TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT );
mluis 2:14a5d6ad92d5 3512
mluis 2:14a5d6ad92d5 3513 TimerInit( &TxDelayedTimer, OnTxDelayedTimerEvent );
mluis 2:14a5d6ad92d5 3514 TimerInit( &RxWindowTimer1, OnRxWindow1TimerEvent );
mluis 2:14a5d6ad92d5 3515 TimerInit( &RxWindowTimer2, OnRxWindow2TimerEvent );
mluis 2:14a5d6ad92d5 3516 TimerInit( &AckTimeoutTimer, OnAckTimeoutTimerEvent );
mluis 2:14a5d6ad92d5 3517
mluis 8:26002607de9c 3518 // Store the current initialization time
mluis 8:26002607de9c 3519 LoRaMacInitializationTime = TimerGetCurrentTime( );
mluis 8:26002607de9c 3520
mluis 2:14a5d6ad92d5 3521 // Initialize Radio driver
mluis 2:14a5d6ad92d5 3522 RadioEvents.TxDone = OnRadioTxDone;
mluis 2:14a5d6ad92d5 3523 RadioEvents.RxDone = OnRadioRxDone;
mluis 2:14a5d6ad92d5 3524 RadioEvents.RxError = OnRadioRxError;
mluis 2:14a5d6ad92d5 3525 RadioEvents.TxTimeout = OnRadioTxTimeout;
mluis 2:14a5d6ad92d5 3526 RadioEvents.RxTimeout = OnRadioRxTimeout;
mluis 2:14a5d6ad92d5 3527 Radio.Init( &RadioEvents );
mluis 2:14a5d6ad92d5 3528
mluis 2:14a5d6ad92d5 3529 // Random seed initialization
mluis 2:14a5d6ad92d5 3530 srand1( Radio.Random( ) );
mluis 2:14a5d6ad92d5 3531
mluis 2:14a5d6ad92d5 3532 PublicNetwork = true;
mluis 8:26002607de9c 3533 Radio.SetPublicNetwork( PublicNetwork );
mluis 2:14a5d6ad92d5 3534 Radio.Sleep( );
mluis 2:14a5d6ad92d5 3535
mluis 2:14a5d6ad92d5 3536 return LORAMAC_STATUS_OK;
mluis 2:14a5d6ad92d5 3537 }
mluis 2:14a5d6ad92d5 3538
mluis 2:14a5d6ad92d5 3539 LoRaMacStatus_t LoRaMacQueryTxPossible( uint8_t size, LoRaMacTxInfo_t* txInfo )
mluis 2:14a5d6ad92d5 3540 {
mluis 7:c16969e0f70f 3541 int8_t datarate = LoRaMacParamsDefaults.ChannelsDatarate;
mluis 7:c16969e0f70f 3542 uint8_t fOptLen = MacCommandsBufferIndex + MacCommandsBufferToRepeatIndex;
mluis 2:14a5d6ad92d5 3543
mluis 2:14a5d6ad92d5 3544 if( txInfo == NULL )
mluis 2:14a5d6ad92d5 3545 {
mluis 2:14a5d6ad92d5 3546 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 3547 }
mluis 2:14a5d6ad92d5 3548
mluis 2:14a5d6ad92d5 3549 AdrNextDr( AdrCtrlOn, false, &datarate );
mluis 2:14a5d6ad92d5 3550
mluis 2:14a5d6ad92d5 3551 if( RepeaterSupport == true )
mluis 2:14a5d6ad92d5 3552 {
mluis 2:14a5d6ad92d5 3553 txInfo->CurrentPayloadSize = MaxPayloadOfDatarateRepeater[datarate];
mluis 0:91d1a7783bb9 3554 }
mluis 0:91d1a7783bb9 3555 else
mluis 0:91d1a7783bb9 3556 {
mluis 2:14a5d6ad92d5 3557 txInfo->CurrentPayloadSize = MaxPayloadOfDatarate[datarate];
mluis 0:91d1a7783bb9 3558 }
mluis 2:14a5d6ad92d5 3559
mluis 7:c16969e0f70f 3560 if( txInfo->CurrentPayloadSize >= fOptLen )
mluis 0:91d1a7783bb9 3561 {
mluis 7:c16969e0f70f 3562 txInfo->MaxPossiblePayload = txInfo->CurrentPayloadSize - fOptLen;
mluis 0:91d1a7783bb9 3563 }
mluis 0:91d1a7783bb9 3564 else
mluis 0:91d1a7783bb9 3565 {
mluis 2:14a5d6ad92d5 3566 return LORAMAC_STATUS_MAC_CMD_LENGTH_ERROR;
mluis 2:14a5d6ad92d5 3567 }
mluis 2:14a5d6ad92d5 3568
mluis 2:14a5d6ad92d5 3569 if( ValidatePayloadLength( size, datarate, 0 ) == false )
mluis 2:14a5d6ad92d5 3570 {
mluis 2:14a5d6ad92d5 3571 return LORAMAC_STATUS_LENGTH_ERROR;
mluis 0:91d1a7783bb9 3572 }
mluis 2:14a5d6ad92d5 3573
mluis 7:c16969e0f70f 3574 if( ValidatePayloadLength( size, datarate, fOptLen ) == false )
mluis 0:91d1a7783bb9 3575 {
mluis 2:14a5d6ad92d5 3576 return LORAMAC_STATUS_MAC_CMD_LENGTH_ERROR;
mluis 0:91d1a7783bb9 3577 }
mluis 0:91d1a7783bb9 3578
mluis 2:14a5d6ad92d5 3579 return LORAMAC_STATUS_OK;
mluis 0:91d1a7783bb9 3580 }
mluis 0:91d1a7783bb9 3581
mluis 2:14a5d6ad92d5 3582 LoRaMacStatus_t LoRaMacMibGetRequestConfirm( MibRequestConfirm_t *mibGet )
mluis 0:91d1a7783bb9 3583 {
mluis 2:14a5d6ad92d5 3584 LoRaMacStatus_t status = LORAMAC_STATUS_OK;
mluis 2:14a5d6ad92d5 3585
mluis 2:14a5d6ad92d5 3586 if( mibGet == NULL )
mluis 2:14a5d6ad92d5 3587 {
mluis 2:14a5d6ad92d5 3588 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 3589 }
mluis 2:14a5d6ad92d5 3590
mluis 2:14a5d6ad92d5 3591 switch( mibGet->Type )
mluis 0:91d1a7783bb9 3592 {
mluis 2:14a5d6ad92d5 3593 case MIB_DEVICE_CLASS:
mluis 2:14a5d6ad92d5 3594 {
mluis 2:14a5d6ad92d5 3595 mibGet->Param.Class = LoRaMacDeviceClass;
mluis 2:14a5d6ad92d5 3596 break;
mluis 2:14a5d6ad92d5 3597 }
mluis 2:14a5d6ad92d5 3598 case MIB_NETWORK_JOINED:
mluis 2:14a5d6ad92d5 3599 {
mluis 2:14a5d6ad92d5 3600 mibGet->Param.IsNetworkJoined = IsLoRaMacNetworkJoined;
mluis 2:14a5d6ad92d5 3601 break;
mluis 2:14a5d6ad92d5 3602 }
mluis 2:14a5d6ad92d5 3603 case MIB_ADR:
mluis 2:14a5d6ad92d5 3604 {
mluis 2:14a5d6ad92d5 3605 mibGet->Param.AdrEnable = AdrCtrlOn;
mluis 2:14a5d6ad92d5 3606 break;
mluis 2:14a5d6ad92d5 3607 }
mluis 2:14a5d6ad92d5 3608 case MIB_NET_ID:
mluis 2:14a5d6ad92d5 3609 {
mluis 2:14a5d6ad92d5 3610 mibGet->Param.NetID = LoRaMacNetID;
mluis 2:14a5d6ad92d5 3611 break;
mluis 2:14a5d6ad92d5 3612 }
mluis 2:14a5d6ad92d5 3613 case MIB_DEV_ADDR:
mluis 2:14a5d6ad92d5 3614 {
mluis 2:14a5d6ad92d5 3615 mibGet->Param.DevAddr = LoRaMacDevAddr;
mluis 2:14a5d6ad92d5 3616 break;
mluis 2:14a5d6ad92d5 3617 }
mluis 2:14a5d6ad92d5 3618 case MIB_NWK_SKEY:
mluis 2:14a5d6ad92d5 3619 {
mluis 2:14a5d6ad92d5 3620 mibGet->Param.NwkSKey = LoRaMacNwkSKey;
mluis 2:14a5d6ad92d5 3621 break;
mluis 2:14a5d6ad92d5 3622 }
mluis 2:14a5d6ad92d5 3623 case MIB_APP_SKEY:
mluis 2:14a5d6ad92d5 3624 {
mluis 2:14a5d6ad92d5 3625 mibGet->Param.AppSKey = LoRaMacAppSKey;
mluis 2:14a5d6ad92d5 3626 break;
mluis 2:14a5d6ad92d5 3627 }
mluis 2:14a5d6ad92d5 3628 case MIB_PUBLIC_NETWORK:
mluis 2:14a5d6ad92d5 3629 {
mluis 2:14a5d6ad92d5 3630 mibGet->Param.EnablePublicNetwork = PublicNetwork;
mluis 2:14a5d6ad92d5 3631 break;
mluis 2:14a5d6ad92d5 3632 }
mluis 2:14a5d6ad92d5 3633 case MIB_REPEATER_SUPPORT:
mluis 2:14a5d6ad92d5 3634 {
mluis 2:14a5d6ad92d5 3635 mibGet->Param.EnableRepeaterSupport = RepeaterSupport;
mluis 2:14a5d6ad92d5 3636 break;
mluis 2:14a5d6ad92d5 3637 }
mluis 2:14a5d6ad92d5 3638 case MIB_CHANNELS:
mluis 2:14a5d6ad92d5 3639 {
mluis 2:14a5d6ad92d5 3640 mibGet->Param.ChannelList = Channels;
mluis 2:14a5d6ad92d5 3641 break;
mluis 2:14a5d6ad92d5 3642 }
mluis 2:14a5d6ad92d5 3643 case MIB_RX2_CHANNEL:
mluis 2:14a5d6ad92d5 3644 {
mluis 7:c16969e0f70f 3645 mibGet->Param.Rx2Channel = LoRaMacParams.Rx2Channel;
mluis 2:14a5d6ad92d5 3646 break;
mluis 2:14a5d6ad92d5 3647 }
mluis 8:26002607de9c 3648 case MIB_RX2_DEFAULT_CHANNEL:
mluis 8:26002607de9c 3649 {
mluis 8:26002607de9c 3650 mibGet->Param.Rx2Channel = LoRaMacParamsDefaults.Rx2Channel;
mluis 8:26002607de9c 3651 break;
mluis 8:26002607de9c 3652 }
mluis 8:26002607de9c 3653 case MIB_CHANNELS_DEFAULT_MASK:
mluis 8:26002607de9c 3654 {
mluis 8:26002607de9c 3655 mibGet->Param.ChannelsDefaultMask = LoRaMacParamsDefaults.ChannelsMask;
mluis 8:26002607de9c 3656 break;
mluis 8:26002607de9c 3657 }
mluis 2:14a5d6ad92d5 3658 case MIB_CHANNELS_MASK:
mluis 2:14a5d6ad92d5 3659 {
mluis 7:c16969e0f70f 3660 mibGet->Param.ChannelsMask = LoRaMacParams.ChannelsMask;
mluis 2:14a5d6ad92d5 3661 break;
mluis 0:91d1a7783bb9 3662 }
mluis 2:14a5d6ad92d5 3663 case MIB_CHANNELS_NB_REP:
mluis 2:14a5d6ad92d5 3664 {
mluis 7:c16969e0f70f 3665 mibGet->Param.ChannelNbRep = LoRaMacParams.ChannelsNbRep;
mluis 2:14a5d6ad92d5 3666 break;
mluis 2:14a5d6ad92d5 3667 }
mluis 2:14a5d6ad92d5 3668 case MIB_MAX_RX_WINDOW_DURATION:
mluis 2:14a5d6ad92d5 3669 {
mluis 7:c16969e0f70f 3670 mibGet->Param.MaxRxWindow = LoRaMacParams.MaxRxWindow;
mluis 2:14a5d6ad92d5 3671 break;
mluis 2:14a5d6ad92d5 3672 }
mluis 2:14a5d6ad92d5 3673 case MIB_RECEIVE_DELAY_1:
mluis 2:14a5d6ad92d5 3674 {
mluis 7:c16969e0f70f 3675 mibGet->Param.ReceiveDelay1 = LoRaMacParams.ReceiveDelay1;
mluis 2:14a5d6ad92d5 3676 break;
mluis 2:14a5d6ad92d5 3677 }
mluis 2:14a5d6ad92d5 3678 case MIB_RECEIVE_DELAY_2:
mluis 2:14a5d6ad92d5 3679 {
mluis 7:c16969e0f70f 3680 mibGet->Param.ReceiveDelay2 = LoRaMacParams.ReceiveDelay2;
mluis 2:14a5d6ad92d5 3681 break;
mluis 2:14a5d6ad92d5 3682 }
mluis 2:14a5d6ad92d5 3683 case MIB_JOIN_ACCEPT_DELAY_1:
mluis 2:14a5d6ad92d5 3684 {
mluis 7:c16969e0f70f 3685 mibGet->Param.JoinAcceptDelay1 = LoRaMacParams.JoinAcceptDelay1;
mluis 2:14a5d6ad92d5 3686 break;
mluis 2:14a5d6ad92d5 3687 }
mluis 2:14a5d6ad92d5 3688 case MIB_JOIN_ACCEPT_DELAY_2:
mluis 2:14a5d6ad92d5 3689 {
mluis 7:c16969e0f70f 3690 mibGet->Param.JoinAcceptDelay2 = LoRaMacParams.JoinAcceptDelay2;
mluis 2:14a5d6ad92d5 3691 break;
mluis 2:14a5d6ad92d5 3692 }
mluis 4:37c12dbc8dc7 3693 case MIB_CHANNELS_DEFAULT_DATARATE:
mluis 4:37c12dbc8dc7 3694 {
mluis 7:c16969e0f70f 3695 mibGet->Param.ChannelsDefaultDatarate = LoRaMacParamsDefaults.ChannelsDatarate;
mluis 4:37c12dbc8dc7 3696 break;
mluis 4:37c12dbc8dc7 3697 }
mluis 2:14a5d6ad92d5 3698 case MIB_CHANNELS_DATARATE:
mluis 2:14a5d6ad92d5 3699 {
mluis 7:c16969e0f70f 3700 mibGet->Param.ChannelsDatarate = LoRaMacParams.ChannelsDatarate;
mluis 2:14a5d6ad92d5 3701 break;
mluis 2:14a5d6ad92d5 3702 }
mluis 8:26002607de9c 3703 case MIB_CHANNELS_DEFAULT_TX_POWER:
mluis 8:26002607de9c 3704 {
mluis 8:26002607de9c 3705 mibGet->Param.ChannelsDefaultTxPower = LoRaMacParamsDefaults.ChannelsTxPower;
mluis 8:26002607de9c 3706 break;
mluis 8:26002607de9c 3707 }
mluis 2:14a5d6ad92d5 3708 case MIB_CHANNELS_TX_POWER:
mluis 2:14a5d6ad92d5 3709 {
mluis 7:c16969e0f70f 3710 mibGet->Param.ChannelsTxPower = LoRaMacParams.ChannelsTxPower;
mluis 2:14a5d6ad92d5 3711 break;
mluis 2:14a5d6ad92d5 3712 }
mluis 2:14a5d6ad92d5 3713 case MIB_UPLINK_COUNTER:
mluis 2:14a5d6ad92d5 3714 {
mluis 2:14a5d6ad92d5 3715 mibGet->Param.UpLinkCounter = UpLinkCounter;
mluis 2:14a5d6ad92d5 3716 break;
mluis 2:14a5d6ad92d5 3717 }
mluis 2:14a5d6ad92d5 3718 case MIB_DOWNLINK_COUNTER:
mluis 2:14a5d6ad92d5 3719 {
mluis 2:14a5d6ad92d5 3720 mibGet->Param.DownLinkCounter = DownLinkCounter;
mluis 2:14a5d6ad92d5 3721 break;
mluis 2:14a5d6ad92d5 3722 }
mluis 2:14a5d6ad92d5 3723 case MIB_MULTICAST_CHANNEL:
mluis 2:14a5d6ad92d5 3724 {
mluis 2:14a5d6ad92d5 3725 mibGet->Param.MulticastList = MulticastChannels;
mluis 2:14a5d6ad92d5 3726 break;
mluis 2:14a5d6ad92d5 3727 }
mluis 8:26002607de9c 3728 case MIB_SYSTEM_MAX_RX_ERROR:
mluis 8:26002607de9c 3729 {
mluis 8:26002607de9c 3730 mibGet->Param.SystemMaxRxError = LoRaMacParams.SystemMaxRxError;
mluis 8:26002607de9c 3731 break;
mluis 8:26002607de9c 3732 }
mluis 8:26002607de9c 3733 case MIB_MIN_RX_SYMBOLS:
mluis 8:26002607de9c 3734 {
mluis 8:26002607de9c 3735 mibGet->Param.MinRxSymbols = LoRaMacParams.MinRxSymbols;
mluis 8:26002607de9c 3736 break;
mluis 8:26002607de9c 3737 }
mluis 2:14a5d6ad92d5 3738 default:
mluis 2:14a5d6ad92d5 3739 status = LORAMAC_STATUS_SERVICE_UNKNOWN;
mluis 2:14a5d6ad92d5 3740 break;
mluis 0:91d1a7783bb9 3741 }
mluis 0:91d1a7783bb9 3742
mluis 2:14a5d6ad92d5 3743 return status;
mluis 0:91d1a7783bb9 3744 }
mluis 2:14a5d6ad92d5 3745
mluis 2:14a5d6ad92d5 3746 LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSet )
mluis 0:91d1a7783bb9 3747 {
mluis 2:14a5d6ad92d5 3748 LoRaMacStatus_t status = LORAMAC_STATUS_OK;
mluis 2:14a5d6ad92d5 3749
mluis 2:14a5d6ad92d5 3750 if( mibSet == NULL )
mluis 2:14a5d6ad92d5 3751 {
mluis 2:14a5d6ad92d5 3752 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 0:91d1a7783bb9 3753 }
mluis 8:26002607de9c 3754 if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING )
mluis 0:91d1a7783bb9 3755 {
mluis 2:14a5d6ad92d5 3756 return LORAMAC_STATUS_BUSY;
mluis 0:91d1a7783bb9 3757 }
mluis 2:14a5d6ad92d5 3758
mluis 2:14a5d6ad92d5 3759 switch( mibSet->Type )
mluis 0:91d1a7783bb9 3760 {
mluis 2:14a5d6ad92d5 3761 case MIB_DEVICE_CLASS:
mluis 2:14a5d6ad92d5 3762 {
mluis 2:14a5d6ad92d5 3763 LoRaMacDeviceClass = mibSet->Param.Class;
mluis 2:14a5d6ad92d5 3764 switch( LoRaMacDeviceClass )
mluis 2:14a5d6ad92d5 3765 {
mluis 2:14a5d6ad92d5 3766 case CLASS_A:
mluis 2:14a5d6ad92d5 3767 {
mluis 2:14a5d6ad92d5 3768 // Set the radio into sleep to setup a defined state
mluis 2:14a5d6ad92d5 3769 Radio.Sleep( );
mluis 2:14a5d6ad92d5 3770 break;
mluis 2:14a5d6ad92d5 3771 }
mluis 2:14a5d6ad92d5 3772 case CLASS_B:
mluis 2:14a5d6ad92d5 3773 {
mluis 2:14a5d6ad92d5 3774 break;
mluis 2:14a5d6ad92d5 3775 }
mluis 2:14a5d6ad92d5 3776 case CLASS_C:
mluis 2:14a5d6ad92d5 3777 {
mluis 2:14a5d6ad92d5 3778 // Set the NodeAckRequested indicator to default
mluis 2:14a5d6ad92d5 3779 NodeAckRequested = false;
mluis 2:14a5d6ad92d5 3780 OnRxWindow2TimerEvent( );
mluis 2:14a5d6ad92d5 3781 break;
mluis 2:14a5d6ad92d5 3782 }
mluis 2:14a5d6ad92d5 3783 }
mluis 2:14a5d6ad92d5 3784 break;
mluis 2:14a5d6ad92d5 3785 }
mluis 2:14a5d6ad92d5 3786 case MIB_NETWORK_JOINED:
mluis 2:14a5d6ad92d5 3787 {
mluis 2:14a5d6ad92d5 3788 IsLoRaMacNetworkJoined = mibSet->Param.IsNetworkJoined;
mluis 2:14a5d6ad92d5 3789 break;
mluis 2:14a5d6ad92d5 3790 }
mluis 2:14a5d6ad92d5 3791 case MIB_ADR:
mluis 2:14a5d6ad92d5 3792 {
mluis 2:14a5d6ad92d5 3793 AdrCtrlOn = mibSet->Param.AdrEnable;
mluis 2:14a5d6ad92d5 3794 break;
mluis 2:14a5d6ad92d5 3795 }
mluis 2:14a5d6ad92d5 3796 case MIB_NET_ID:
mluis 2:14a5d6ad92d5 3797 {
mluis 2:14a5d6ad92d5 3798 LoRaMacNetID = mibSet->Param.NetID;
mluis 2:14a5d6ad92d5 3799 break;
mluis 2:14a5d6ad92d5 3800 }
mluis 2:14a5d6ad92d5 3801 case MIB_DEV_ADDR:
mluis 2:14a5d6ad92d5 3802 {
mluis 2:14a5d6ad92d5 3803 LoRaMacDevAddr = mibSet->Param.DevAddr;
mluis 2:14a5d6ad92d5 3804 break;
mluis 2:14a5d6ad92d5 3805 }
mluis 2:14a5d6ad92d5 3806 case MIB_NWK_SKEY:
mluis 0:91d1a7783bb9 3807 {
mluis 2:14a5d6ad92d5 3808 if( mibSet->Param.NwkSKey != NULL )
mluis 2:14a5d6ad92d5 3809 {
mluis 2:14a5d6ad92d5 3810 memcpy1( LoRaMacNwkSKey, mibSet->Param.NwkSKey,
mluis 2:14a5d6ad92d5 3811 sizeof( LoRaMacNwkSKey ) );
mluis 2:14a5d6ad92d5 3812 }
mluis 2:14a5d6ad92d5 3813 else
mluis 2:14a5d6ad92d5 3814 {
mluis 2:14a5d6ad92d5 3815 status = LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 3816 }
mluis 2:14a5d6ad92d5 3817 break;
mluis 2:14a5d6ad92d5 3818 }
mluis 2:14a5d6ad92d5 3819 case MIB_APP_SKEY:
mluis 2:14a5d6ad92d5 3820 {
mluis 2:14a5d6ad92d5 3821 if( mibSet->Param.AppSKey != NULL )
mluis 2:14a5d6ad92d5 3822 {
mluis 2:14a5d6ad92d5 3823 memcpy1( LoRaMacAppSKey, mibSet->Param.AppSKey,
mluis 2:14a5d6ad92d5 3824 sizeof( LoRaMacAppSKey ) );
mluis 2:14a5d6ad92d5 3825 }
mluis 2:14a5d6ad92d5 3826 else
mluis 2:14a5d6ad92d5 3827 {
mluis 2:14a5d6ad92d5 3828 status = LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 3829 }
mluis 2:14a5d6ad92d5 3830 break;
mluis 2:14a5d6ad92d5 3831 }
mluis 2:14a5d6ad92d5 3832 case MIB_PUBLIC_NETWORK:
mluis 2:14a5d6ad92d5 3833 {
mluis 8:26002607de9c 3834 PublicNetwork = mibSet->Param.EnablePublicNetwork;
mluis 8:26002607de9c 3835 Radio.SetPublicNetwork( PublicNetwork );
mluis 2:14a5d6ad92d5 3836 break;
mluis 0:91d1a7783bb9 3837 }
mluis 2:14a5d6ad92d5 3838 case MIB_REPEATER_SUPPORT:
mluis 2:14a5d6ad92d5 3839 {
mluis 2:14a5d6ad92d5 3840 RepeaterSupport = mibSet->Param.EnableRepeaterSupport;
mluis 2:14a5d6ad92d5 3841 break;
mluis 2:14a5d6ad92d5 3842 }
mluis 2:14a5d6ad92d5 3843 case MIB_RX2_CHANNEL:
mluis 2:14a5d6ad92d5 3844 {
mluis 7:c16969e0f70f 3845 LoRaMacParams.Rx2Channel = mibSet->Param.Rx2Channel;
mluis 2:14a5d6ad92d5 3846 break;
mluis 2:14a5d6ad92d5 3847 }
mluis 8:26002607de9c 3848 case MIB_RX2_DEFAULT_CHANNEL:
mluis 8:26002607de9c 3849 {
mluis 8:26002607de9c 3850 LoRaMacParamsDefaults.Rx2Channel = mibSet->Param.Rx2DefaultChannel;
mluis 8:26002607de9c 3851 break;
mluis 8:26002607de9c 3852 }
mluis 8:26002607de9c 3853 case MIB_CHANNELS_DEFAULT_MASK:
mluis 8:26002607de9c 3854 {
mluis 8:26002607de9c 3855 if( mibSet->Param.ChannelsDefaultMask )
mluis 8:26002607de9c 3856 {
mluis 8:26002607de9c 3857 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 8:26002607de9c 3858 bool chanMaskState = true;
mluis 8:26002607de9c 3859
mluis 8:26002607de9c 3860 #if defined( USE_BAND_915_HYBRID )
mluis 8:26002607de9c 3861 chanMaskState = ValidateChannelMask( mibSet->Param.ChannelsDefaultMask );
mluis 8:26002607de9c 3862 #endif
mluis 8:26002607de9c 3863 if( chanMaskState == true )
mluis 8:26002607de9c 3864 {
mluis 8:26002607de9c 3865 if( ( CountNbEnabled125kHzChannels( mibSet->Param.ChannelsMask ) < 2 ) &&
mluis 8:26002607de9c 3866 ( CountNbEnabled125kHzChannels( mibSet->Param.ChannelsMask ) > 0 ) )
mluis 8:26002607de9c 3867 {
mluis 8:26002607de9c 3868 status = LORAMAC_STATUS_PARAMETER_INVALID;
mluis 8:26002607de9c 3869 }
mluis 8:26002607de9c 3870 else
mluis 8:26002607de9c 3871 {
mluis 8:26002607de9c 3872 memcpy1( ( uint8_t* ) LoRaMacParamsDefaults.ChannelsMask,
mluis 8:26002607de9c 3873 ( uint8_t* ) mibSet->Param.ChannelsDefaultMask, sizeof( LoRaMacParamsDefaults.ChannelsMask ) );
mluis 8:26002607de9c 3874 for ( uint8_t i = 0; i < sizeof( LoRaMacParamsDefaults.ChannelsMask ) / 2; i++ )
mluis 8:26002607de9c 3875 {
mluis 8:26002607de9c 3876 // Disable channels which are no longer available
mluis 8:26002607de9c 3877 ChannelsMaskRemaining[i] &= LoRaMacParamsDefaults.ChannelsMask[i];
mluis 8:26002607de9c 3878 }
mluis 8:26002607de9c 3879 }
mluis 8:26002607de9c 3880 }
mluis 8:26002607de9c 3881 else
mluis 8:26002607de9c 3882 {
mluis 8:26002607de9c 3883 status = LORAMAC_STATUS_PARAMETER_INVALID;
mluis 8:26002607de9c 3884 }
mluis 8:26002607de9c 3885 #elif defined( USE_BAND_470 )
mluis 8:26002607de9c 3886 memcpy1( ( uint8_t* ) LoRaMacParamsDefaults.ChannelsMask,
mluis 8:26002607de9c 3887 ( uint8_t* ) mibSet->Param.ChannelsDefaultMask, sizeof( LoRaMacParamsDefaults.ChannelsMask ) );
mluis 8:26002607de9c 3888 #else
mluis 8:26002607de9c 3889 memcpy1( ( uint8_t* ) LoRaMacParamsDefaults.ChannelsMask,
mluis 8:26002607de9c 3890 ( uint8_t* ) mibSet->Param.ChannelsDefaultMask, 2 );
mluis 8:26002607de9c 3891 #endif
mluis 8:26002607de9c 3892 }
mluis 8:26002607de9c 3893 else
mluis 8:26002607de9c 3894 {
mluis 8:26002607de9c 3895 status = LORAMAC_STATUS_PARAMETER_INVALID;
mluis 8:26002607de9c 3896 }
mluis 8:26002607de9c 3897 break;
mluis 8:26002607de9c 3898 }
mluis 2:14a5d6ad92d5 3899 case MIB_CHANNELS_MASK:
mluis 2:14a5d6ad92d5 3900 {
mluis 2:14a5d6ad92d5 3901 if( mibSet->Param.ChannelsMask )
mluis 2:14a5d6ad92d5 3902 {
mluis 2:14a5d6ad92d5 3903 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 4:37c12dbc8dc7 3904 bool chanMaskState = true;
mluis 4:37c12dbc8dc7 3905
mluis 4:37c12dbc8dc7 3906 #if defined( USE_BAND_915_HYBRID )
mluis 4:37c12dbc8dc7 3907 chanMaskState = ValidateChannelMask( mibSet->Param.ChannelsMask );
mluis 4:37c12dbc8dc7 3908 #endif
mluis 4:37c12dbc8dc7 3909 if( chanMaskState == true )
mluis 2:14a5d6ad92d5 3910 {
mluis 8:26002607de9c 3911 if( ( CountNbEnabled125kHzChannels( mibSet->Param.ChannelsMask ) < 2 ) &&
mluis 4:37c12dbc8dc7 3912 ( CountNbEnabled125kHzChannels( mibSet->Param.ChannelsMask ) > 0 ) )
mluis 4:37c12dbc8dc7 3913 {
mluis 4:37c12dbc8dc7 3914 status = LORAMAC_STATUS_PARAMETER_INVALID;
mluis 4:37c12dbc8dc7 3915 }
mluis 4:37c12dbc8dc7 3916 else
mluis 4:37c12dbc8dc7 3917 {
mluis 7:c16969e0f70f 3918 memcpy1( ( uint8_t* ) LoRaMacParams.ChannelsMask,
mluis 7:c16969e0f70f 3919 ( uint8_t* ) mibSet->Param.ChannelsMask, sizeof( LoRaMacParams.ChannelsMask ) );
mluis 7:c16969e0f70f 3920 for ( uint8_t i = 0; i < sizeof( LoRaMacParams.ChannelsMask ) / 2; i++ )
mluis 4:37c12dbc8dc7 3921 {
mluis 4:37c12dbc8dc7 3922 // Disable channels which are no longer available
mluis 7:c16969e0f70f 3923 ChannelsMaskRemaining[i] &= LoRaMacParams.ChannelsMask[i];
mluis 4:37c12dbc8dc7 3924 }
mluis 4:37c12dbc8dc7 3925 }
mluis 2:14a5d6ad92d5 3926 }
mluis 2:14a5d6ad92d5 3927 else
mluis 2:14a5d6ad92d5 3928 {
mluis 4:37c12dbc8dc7 3929 status = LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 3930 }
mluis 8:26002607de9c 3931 #elif defined( USE_BAND_470 )
mluis 8:26002607de9c 3932 memcpy1( ( uint8_t* ) LoRaMacParams.ChannelsMask,
mluis 8:26002607de9c 3933 ( uint8_t* ) mibSet->Param.ChannelsMask, sizeof( LoRaMacParams.ChannelsMask ) );
mluis 0:91d1a7783bb9 3934 #else
mluis 7:c16969e0f70f 3935 memcpy1( ( uint8_t* ) LoRaMacParams.ChannelsMask,
mluis 2:14a5d6ad92d5 3936 ( uint8_t* ) mibSet->Param.ChannelsMask, 2 );
mluis 0:91d1a7783bb9 3937 #endif
mluis 2:14a5d6ad92d5 3938 }
mluis 2:14a5d6ad92d5 3939 else
mluis 2:14a5d6ad92d5 3940 {
mluis 2:14a5d6ad92d5 3941 status = LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 3942 }
mluis 2:14a5d6ad92d5 3943 break;
mluis 2:14a5d6ad92d5 3944 }
mluis 2:14a5d6ad92d5 3945 case MIB_CHANNELS_NB_REP:
mluis 2:14a5d6ad92d5 3946 {
mluis 2:14a5d6ad92d5 3947 if( ( mibSet->Param.ChannelNbRep >= 1 ) &&
mluis 2:14a5d6ad92d5 3948 ( mibSet->Param.ChannelNbRep <= 15 ) )
mluis 2:14a5d6ad92d5 3949 {
mluis 7:c16969e0f70f 3950 LoRaMacParams.ChannelsNbRep = mibSet->Param.ChannelNbRep;
mluis 2:14a5d6ad92d5 3951 }
mluis 2:14a5d6ad92d5 3952 else
mluis 2:14a5d6ad92d5 3953 {
mluis 2:14a5d6ad92d5 3954 status = LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 3955 }
mluis 2:14a5d6ad92d5 3956 break;
mluis 2:14a5d6ad92d5 3957 }
mluis 2:14a5d6ad92d5 3958 case MIB_MAX_RX_WINDOW_DURATION:
mluis 2:14a5d6ad92d5 3959 {
mluis 7:c16969e0f70f 3960 LoRaMacParams.MaxRxWindow = mibSet->Param.MaxRxWindow;
mluis 2:14a5d6ad92d5 3961 break;
mluis 2:14a5d6ad92d5 3962 }
mluis 2:14a5d6ad92d5 3963 case MIB_RECEIVE_DELAY_1:
mluis 2:14a5d6ad92d5 3964 {
mluis 7:c16969e0f70f 3965 LoRaMacParams.ReceiveDelay1 = mibSet->Param.ReceiveDelay1;
mluis 2:14a5d6ad92d5 3966 break;
mluis 2:14a5d6ad92d5 3967 }
mluis 2:14a5d6ad92d5 3968 case MIB_RECEIVE_DELAY_2:
mluis 2:14a5d6ad92d5 3969 {
mluis 7:c16969e0f70f 3970 LoRaMacParams.ReceiveDelay2 = mibSet->Param.ReceiveDelay2;
mluis 2:14a5d6ad92d5 3971 break;
mluis 2:14a5d6ad92d5 3972 }
mluis 2:14a5d6ad92d5 3973 case MIB_JOIN_ACCEPT_DELAY_1:
mluis 2:14a5d6ad92d5 3974 {
mluis 7:c16969e0f70f 3975 LoRaMacParams.JoinAcceptDelay1 = mibSet->Param.JoinAcceptDelay1;
mluis 2:14a5d6ad92d5 3976 break;
mluis 2:14a5d6ad92d5 3977 }
mluis 2:14a5d6ad92d5 3978 case MIB_JOIN_ACCEPT_DELAY_2:
mluis 2:14a5d6ad92d5 3979 {
mluis 7:c16969e0f70f 3980 LoRaMacParams.JoinAcceptDelay2 = mibSet->Param.JoinAcceptDelay2;
mluis 2:14a5d6ad92d5 3981 break;
mluis 2:14a5d6ad92d5 3982 }
mluis 4:37c12dbc8dc7 3983 case MIB_CHANNELS_DEFAULT_DATARATE:
mluis 4:37c12dbc8dc7 3984 {
mluis 8:26002607de9c 3985 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
mluis 8:26002607de9c 3986 if( ValueInRange( mibSet->Param.ChannelsDefaultDatarate,
mluis 8:26002607de9c 3987 DR_0, DR_5 ) )
mluis 8:26002607de9c 3988 {
mluis 8:26002607de9c 3989 LoRaMacParamsDefaults.ChannelsDatarate = mibSet->Param.ChannelsDefaultDatarate;
mluis 8:26002607de9c 3990 }
mluis 8:26002607de9c 3991 #else
mluis 4:37c12dbc8dc7 3992 if( ValueInRange( mibSet->Param.ChannelsDefaultDatarate,
mluis 4:37c12dbc8dc7 3993 LORAMAC_TX_MIN_DATARATE, LORAMAC_TX_MAX_DATARATE ) )
mluis 4:37c12dbc8dc7 3994 {
mluis 7:c16969e0f70f 3995 LoRaMacParamsDefaults.ChannelsDatarate = mibSet->Param.ChannelsDefaultDatarate;
mluis 4:37c12dbc8dc7 3996 }
mluis 8:26002607de9c 3997 #endif
mluis 4:37c12dbc8dc7 3998 else
mluis 4:37c12dbc8dc7 3999 {
mluis 4:37c12dbc8dc7 4000 status = LORAMAC_STATUS_PARAMETER_INVALID;
mluis 4:37c12dbc8dc7 4001 }
mluis 4:37c12dbc8dc7 4002 break;
mluis 4:37c12dbc8dc7 4003 }
mluis 2:14a5d6ad92d5 4004 case MIB_CHANNELS_DATARATE:
mluis 2:14a5d6ad92d5 4005 {
mluis 2:14a5d6ad92d5 4006 if( ValueInRange( mibSet->Param.ChannelsDatarate,
mluis 4:37c12dbc8dc7 4007 LORAMAC_TX_MIN_DATARATE, LORAMAC_TX_MAX_DATARATE ) )
mluis 2:14a5d6ad92d5 4008 {
mluis 7:c16969e0f70f 4009 LoRaMacParams.ChannelsDatarate = mibSet->Param.ChannelsDatarate;
mluis 2:14a5d6ad92d5 4010 }
mluis 2:14a5d6ad92d5 4011 else
mluis 2:14a5d6ad92d5 4012 {
mluis 2:14a5d6ad92d5 4013 status = LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 4014 }
mluis 2:14a5d6ad92d5 4015 break;
mluis 2:14a5d6ad92d5 4016 }
mluis 8:26002607de9c 4017 case MIB_CHANNELS_DEFAULT_TX_POWER:
mluis 8:26002607de9c 4018 {
mluis 8:26002607de9c 4019 if( ValueInRange( mibSet->Param.ChannelsDefaultTxPower,
mluis 8:26002607de9c 4020 LORAMAC_MAX_TX_POWER, LORAMAC_MIN_TX_POWER ) )
mluis 8:26002607de9c 4021 {
mluis 8:26002607de9c 4022 LoRaMacParamsDefaults.ChannelsTxPower = mibSet->Param.ChannelsDefaultTxPower;
mluis 8:26002607de9c 4023 }
mluis 8:26002607de9c 4024 else
mluis 8:26002607de9c 4025 {
mluis 8:26002607de9c 4026 status = LORAMAC_STATUS_PARAMETER_INVALID;
mluis 8:26002607de9c 4027 }
mluis 8:26002607de9c 4028 break;
mluis 8:26002607de9c 4029 }
mluis 2:14a5d6ad92d5 4030 case MIB_CHANNELS_TX_POWER:
mluis 2:14a5d6ad92d5 4031 {
mluis 2:14a5d6ad92d5 4032 if( ValueInRange( mibSet->Param.ChannelsTxPower,
mluis 2:14a5d6ad92d5 4033 LORAMAC_MAX_TX_POWER, LORAMAC_MIN_TX_POWER ) )
mluis 2:14a5d6ad92d5 4034 {
mluis 7:c16969e0f70f 4035 LoRaMacParams.ChannelsTxPower = mibSet->Param.ChannelsTxPower;
mluis 2:14a5d6ad92d5 4036 }
mluis 2:14a5d6ad92d5 4037 else
mluis 2:14a5d6ad92d5 4038 {
mluis 2:14a5d6ad92d5 4039 status = LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 4040 }
mluis 2:14a5d6ad92d5 4041 break;
mluis 2:14a5d6ad92d5 4042 }
mluis 4:37c12dbc8dc7 4043 case MIB_UPLINK_COUNTER:
mluis 4:37c12dbc8dc7 4044 {
mluis 4:37c12dbc8dc7 4045 UpLinkCounter = mibSet->Param.UpLinkCounter;
mluis 4:37c12dbc8dc7 4046 break;
mluis 4:37c12dbc8dc7 4047 }
mluis 4:37c12dbc8dc7 4048 case MIB_DOWNLINK_COUNTER:
mluis 4:37c12dbc8dc7 4049 {
mluis 4:37c12dbc8dc7 4050 DownLinkCounter = mibSet->Param.DownLinkCounter;
mluis 4:37c12dbc8dc7 4051 break;
mluis 4:37c12dbc8dc7 4052 }
mluis 8:26002607de9c 4053 case MIB_SYSTEM_MAX_RX_ERROR:
mluis 8:26002607de9c 4054 {
mluis 8:26002607de9c 4055 LoRaMacParams.SystemMaxRxError = LoRaMacParamsDefaults.SystemMaxRxError = mibSet->Param.SystemMaxRxError;
mluis 8:26002607de9c 4056 break;
mluis 8:26002607de9c 4057 }
mluis 8:26002607de9c 4058 case MIB_MIN_RX_SYMBOLS:
mluis 8:26002607de9c 4059 {
mluis 8:26002607de9c 4060 LoRaMacParams.MinRxSymbols = LoRaMacParamsDefaults.MinRxSymbols = mibSet->Param.MinRxSymbols;
mluis 8:26002607de9c 4061 break;
mluis 8:26002607de9c 4062 }
mluis 2:14a5d6ad92d5 4063 default:
mluis 2:14a5d6ad92d5 4064 status = LORAMAC_STATUS_SERVICE_UNKNOWN;
mluis 2:14a5d6ad92d5 4065 break;
mluis 0:91d1a7783bb9 4066 }
mluis 0:91d1a7783bb9 4067
mluis 2:14a5d6ad92d5 4068 return status;
mluis 0:91d1a7783bb9 4069 }
mluis 0:91d1a7783bb9 4070
mluis 2:14a5d6ad92d5 4071 LoRaMacStatus_t LoRaMacChannelAdd( uint8_t id, ChannelParams_t params )
mluis 0:91d1a7783bb9 4072 {
mluis 8:26002607de9c 4073 #if defined( USE_BAND_470 ) || defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 3:b9d87593a8ae 4074 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 3:b9d87593a8ae 4075 #else
mluis 3:b9d87593a8ae 4076 bool datarateInvalid = false;
mluis 3:b9d87593a8ae 4077 bool frequencyInvalid = false;
mluis 3:b9d87593a8ae 4078 uint8_t band = 0;
mluis 3:b9d87593a8ae 4079
mluis 3:b9d87593a8ae 4080 // The id must not exceed LORA_MAX_NB_CHANNELS
mluis 2:14a5d6ad92d5 4081 if( id >= LORA_MAX_NB_CHANNELS )
mluis 0:91d1a7783bb9 4082 {
mluis 2:14a5d6ad92d5 4083 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 0:91d1a7783bb9 4084 }
mluis 3:b9d87593a8ae 4085 // Validate if the MAC is in a correct state
mluis 8:26002607de9c 4086 if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING )
mluis 0:91d1a7783bb9 4087 {
mluis 8:26002607de9c 4088 if( ( LoRaMacState & LORAMAC_TX_CONFIG ) != LORAMAC_TX_CONFIG )
mluis 3:b9d87593a8ae 4089 {
mluis 3:b9d87593a8ae 4090 return LORAMAC_STATUS_BUSY;
mluis 3:b9d87593a8ae 4091 }
mluis 0:91d1a7783bb9 4092 }
mluis 3:b9d87593a8ae 4093 // Validate the datarate
mluis 2:14a5d6ad92d5 4094 if( ( params.DrRange.Fields.Min > params.DrRange.Fields.Max ) ||
mluis 4:37c12dbc8dc7 4095 ( ValueInRange( params.DrRange.Fields.Min, LORAMAC_TX_MIN_DATARATE,
mluis 4:37c12dbc8dc7 4096 LORAMAC_TX_MAX_DATARATE ) == false ) ||
mluis 4:37c12dbc8dc7 4097 ( ValueInRange( params.DrRange.Fields.Max, LORAMAC_TX_MIN_DATARATE,
mluis 4:37c12dbc8dc7 4098 LORAMAC_TX_MAX_DATARATE ) == false ) )
mluis 0:91d1a7783bb9 4099 {
mluis 3:b9d87593a8ae 4100 datarateInvalid = true;
mluis 0:91d1a7783bb9 4101 }
mluis 2:14a5d6ad92d5 4102
mluis 3:b9d87593a8ae 4103 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
mluis 3:b9d87593a8ae 4104 if( id < 3 )
mluis 0:91d1a7783bb9 4105 {
mluis 3:b9d87593a8ae 4106 if( params.Frequency != Channels[id].Frequency )
mluis 0:91d1a7783bb9 4107 {
mluis 3:b9d87593a8ae 4108 frequencyInvalid = true;
mluis 3:b9d87593a8ae 4109 }
mluis 3:b9d87593a8ae 4110
mluis 8:26002607de9c 4111 if( params.DrRange.Fields.Min > DR_0 )
mluis 3:b9d87593a8ae 4112 {
mluis 3:b9d87593a8ae 4113 datarateInvalid = true;
mluis 3:b9d87593a8ae 4114 }
mluis 4:37c12dbc8dc7 4115 if( ValueInRange( params.DrRange.Fields.Max, DR_5, LORAMAC_TX_MAX_DATARATE ) == false )
mluis 3:b9d87593a8ae 4116 {
mluis 3:b9d87593a8ae 4117 datarateInvalid = true;
mluis 0:91d1a7783bb9 4118 }
mluis 0:91d1a7783bb9 4119 }
mluis 3:b9d87593a8ae 4120 #endif
mluis 3:b9d87593a8ae 4121
mluis 3:b9d87593a8ae 4122 // Validate the frequency
mluis 3:b9d87593a8ae 4123 if( ( Radio.CheckRfFrequency( params.Frequency ) == true ) && ( params.Frequency > 0 ) && ( frequencyInvalid == false ) )
mluis 0:91d1a7783bb9 4124 {
mluis 3:b9d87593a8ae 4125 #if defined( USE_BAND_868 )
mluis 8:26002607de9c 4126 if( ( params.Frequency >= 863000000 ) && ( params.Frequency < 865000000 ) )
mluis 8:26002607de9c 4127 {
mluis 8:26002607de9c 4128 band = BAND_G1_2;
mluis 8:26002607de9c 4129 }
mluis 8:26002607de9c 4130 else if( ( params.Frequency >= 865000000 ) && ( params.Frequency <= 868000000 ) )
mluis 0:91d1a7783bb9 4131 {
mluis 3:b9d87593a8ae 4132 band = BAND_G1_0;
mluis 0:91d1a7783bb9 4133 }
mluis 3:b9d87593a8ae 4134 else if( ( params.Frequency > 868000000 ) && ( params.Frequency <= 868600000 ) )
mluis 0:91d1a7783bb9 4135 {
mluis 3:b9d87593a8ae 4136 band = BAND_G1_1;
mluis 0:91d1a7783bb9 4137 }
mluis 3:b9d87593a8ae 4138 else if( ( params.Frequency >= 868700000 ) && ( params.Frequency <= 869200000 ) )
mluis 0:91d1a7783bb9 4139 {
mluis 3:b9d87593a8ae 4140 band = BAND_G1_2;
mluis 3:b9d87593a8ae 4141 }
mluis 3:b9d87593a8ae 4142 else if( ( params.Frequency >= 869400000 ) && ( params.Frequency <= 869650000 ) )
mluis 3:b9d87593a8ae 4143 {
mluis 3:b9d87593a8ae 4144 band = BAND_G1_3;
mluis 0:91d1a7783bb9 4145 }
mluis 3:b9d87593a8ae 4146 else if( ( params.Frequency >= 869700000 ) && ( params.Frequency <= 870000000 ) )
mluis 0:91d1a7783bb9 4147 {
mluis 3:b9d87593a8ae 4148 band = BAND_G1_4;
mluis 0:91d1a7783bb9 4149 }
mluis 3:b9d87593a8ae 4150 else
mluis 3:b9d87593a8ae 4151 {
mluis 3:b9d87593a8ae 4152 frequencyInvalid = true;
mluis 3:b9d87593a8ae 4153 }
mluis 3:b9d87593a8ae 4154 #endif
mluis 0:91d1a7783bb9 4155 }
mluis 0:91d1a7783bb9 4156 else
mluis 0:91d1a7783bb9 4157 {
mluis 3:b9d87593a8ae 4158 frequencyInvalid = true;
mluis 3:b9d87593a8ae 4159 }
mluis 3:b9d87593a8ae 4160
mluis 3:b9d87593a8ae 4161 if( ( datarateInvalid == true ) && ( frequencyInvalid == true ) )
mluis 3:b9d87593a8ae 4162 {
mluis 3:b9d87593a8ae 4163 return LORAMAC_STATUS_FREQ_AND_DR_INVALID;
mluis 0:91d1a7783bb9 4164 }
mluis 3:b9d87593a8ae 4165 if( datarateInvalid == true )
mluis 3:b9d87593a8ae 4166 {
mluis 3:b9d87593a8ae 4167 return LORAMAC_STATUS_DATARATE_INVALID;
mluis 3:b9d87593a8ae 4168 }
mluis 3:b9d87593a8ae 4169 if( frequencyInvalid == true )
mluis 0:91d1a7783bb9 4170 {
mluis 3:b9d87593a8ae 4171 return LORAMAC_STATUS_FREQUENCY_INVALID;
mluis 2:14a5d6ad92d5 4172 }
mluis 2:14a5d6ad92d5 4173
mluis 3:b9d87593a8ae 4174 // Every parameter is valid, activate the channel
mluis 3:b9d87593a8ae 4175 Channels[id] = params;
mluis 3:b9d87593a8ae 4176 Channels[id].Band = band;
mluis 7:c16969e0f70f 4177 LoRaMacParams.ChannelsMask[0] |= ( 1 << id );
mluis 3:b9d87593a8ae 4178
mluis 2:14a5d6ad92d5 4179 return LORAMAC_STATUS_OK;
mluis 0:91d1a7783bb9 4180 #endif
mluis 0:91d1a7783bb9 4181 }
mluis 0:91d1a7783bb9 4182
mluis 2:14a5d6ad92d5 4183 LoRaMacStatus_t LoRaMacChannelRemove( uint8_t id )
mluis 0:91d1a7783bb9 4184 {
mluis 3:b9d87593a8ae 4185 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
mluis 8:26002607de9c 4186 if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING )
mluis 0:91d1a7783bb9 4187 {
mluis 8:26002607de9c 4188 if( ( LoRaMacState & LORAMAC_TX_CONFIG ) != LORAMAC_TX_CONFIG )
mluis 3:b9d87593a8ae 4189 {
mluis 3:b9d87593a8ae 4190 return LORAMAC_STATUS_BUSY;
mluis 3:b9d87593a8ae 4191 }
mluis 0:91d1a7783bb9 4192 }
mluis 3:b9d87593a8ae 4193
mluis 4:37c12dbc8dc7 4194 if( ( id < 3 ) || ( id >= LORA_MAX_NB_CHANNELS ) )
mluis 0:91d1a7783bb9 4195 {
mluis 3:b9d87593a8ae 4196 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 3:b9d87593a8ae 4197 }
mluis 3:b9d87593a8ae 4198 else
mluis 3:b9d87593a8ae 4199 {
mluis 3:b9d87593a8ae 4200 // Remove the channel from the list of channels
mluis 3:b9d87593a8ae 4201 Channels[id] = ( ChannelParams_t ){ 0, { 0 }, 0 };
mluis 4:37c12dbc8dc7 4202
mluis 3:b9d87593a8ae 4203 // Disable the channel as it doesn't exist anymore
mluis 7:c16969e0f70f 4204 if( DisableChannelInMask( id, LoRaMacParams.ChannelsMask ) == false )
mluis 2:14a5d6ad92d5 4205 {
mluis 2:14a5d6ad92d5 4206 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 4207 }
mluis 0:91d1a7783bb9 4208 }
mluis 3:b9d87593a8ae 4209 return LORAMAC_STATUS_OK;
mluis 8:26002607de9c 4210 #elif ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) || defined( USE_BAND_470 ) )
mluis 3:b9d87593a8ae 4211 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 4212 #endif
mluis 2:14a5d6ad92d5 4213 }
mluis 2:14a5d6ad92d5 4214
mluis 2:14a5d6ad92d5 4215 LoRaMacStatus_t LoRaMacMulticastChannelLink( MulticastParams_t *channelParam )
mluis 2:14a5d6ad92d5 4216 {
mluis 2:14a5d6ad92d5 4217 if( channelParam == NULL )
mluis 2:14a5d6ad92d5 4218 {
mluis 2:14a5d6ad92d5 4219 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 4220 }
mluis 8:26002607de9c 4221 if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING )
mluis 2:14a5d6ad92d5 4222 {
mluis 2:14a5d6ad92d5 4223 return LORAMAC_STATUS_BUSY;
mluis 2:14a5d6ad92d5 4224 }
mluis 2:14a5d6ad92d5 4225
mluis 2:14a5d6ad92d5 4226 // Reset downlink counter
mluis 2:14a5d6ad92d5 4227 channelParam->DownLinkCounter = 0;
mluis 2:14a5d6ad92d5 4228
mluis 2:14a5d6ad92d5 4229 if( MulticastChannels == NULL )
mluis 2:14a5d6ad92d5 4230 {
mluis 2:14a5d6ad92d5 4231 // New node is the fist element
mluis 2:14a5d6ad92d5 4232 MulticastChannels = channelParam;
mluis 0:91d1a7783bb9 4233 }
mluis 0:91d1a7783bb9 4234 else
mluis 0:91d1a7783bb9 4235 {
mluis 2:14a5d6ad92d5 4236 MulticastParams_t *cur = MulticastChannels;
mluis 2:14a5d6ad92d5 4237
mluis 2:14a5d6ad92d5 4238 // Search the last node in the list
mluis 2:14a5d6ad92d5 4239 while( cur->Next != NULL )
mluis 2:14a5d6ad92d5 4240 {
mluis 2:14a5d6ad92d5 4241 cur = cur->Next;
mluis 2:14a5d6ad92d5 4242 }
mluis 2:14a5d6ad92d5 4243 // This function always finds the last node
mluis 2:14a5d6ad92d5 4244 cur->Next = channelParam;
mluis 0:91d1a7783bb9 4245 }
mluis 2:14a5d6ad92d5 4246
mluis 2:14a5d6ad92d5 4247 return LORAMAC_STATUS_OK;
mluis 0:91d1a7783bb9 4248 }
mluis 0:91d1a7783bb9 4249
mluis 2:14a5d6ad92d5 4250 LoRaMacStatus_t LoRaMacMulticastChannelUnlink( MulticastParams_t *channelParam )
mluis 0:91d1a7783bb9 4251 {
mluis 2:14a5d6ad92d5 4252 if( channelParam == NULL )
mluis 0:91d1a7783bb9 4253 {
mluis 2:14a5d6ad92d5 4254 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 0:91d1a7783bb9 4255 }
mluis 8:26002607de9c 4256 if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING )
mluis 2:14a5d6ad92d5 4257 {
mluis 2:14a5d6ad92d5 4258 return LORAMAC_STATUS_BUSY;
mluis 2:14a5d6ad92d5 4259 }
mluis 2:14a5d6ad92d5 4260
mluis 2:14a5d6ad92d5 4261 if( MulticastChannels != NULL )
mluis 0:91d1a7783bb9 4262 {
mluis 2:14a5d6ad92d5 4263 if( MulticastChannels == channelParam )
mluis 2:14a5d6ad92d5 4264 {
mluis 2:14a5d6ad92d5 4265 // First element
mluis 2:14a5d6ad92d5 4266 MulticastChannels = channelParam->Next;
mluis 2:14a5d6ad92d5 4267 }
mluis 2:14a5d6ad92d5 4268 else
mluis 2:14a5d6ad92d5 4269 {
mluis 2:14a5d6ad92d5 4270 MulticastParams_t *cur = MulticastChannels;
mluis 2:14a5d6ad92d5 4271
mluis 2:14a5d6ad92d5 4272 // Search the node in the list
mluis 2:14a5d6ad92d5 4273 while( cur->Next && cur->Next != channelParam )
mluis 2:14a5d6ad92d5 4274 {
mluis 2:14a5d6ad92d5 4275 cur = cur->Next;
mluis 2:14a5d6ad92d5 4276 }
mluis 2:14a5d6ad92d5 4277 // If we found the node, remove it
mluis 2:14a5d6ad92d5 4278 if( cur->Next )
mluis 2:14a5d6ad92d5 4279 {
mluis 2:14a5d6ad92d5 4280 cur->Next = channelParam->Next;
mluis 2:14a5d6ad92d5 4281 }
mluis 2:14a5d6ad92d5 4282 }
mluis 2:14a5d6ad92d5 4283 channelParam->Next = NULL;
mluis 0:91d1a7783bb9 4284 }
mluis 2:14a5d6ad92d5 4285
mluis 2:14a5d6ad92d5 4286 return LORAMAC_STATUS_OK;
mluis 0:91d1a7783bb9 4287 }
mluis 0:91d1a7783bb9 4288
mluis 2:14a5d6ad92d5 4289 LoRaMacStatus_t LoRaMacMlmeRequest( MlmeReq_t *mlmeRequest )
mluis 0:91d1a7783bb9 4290 {
mluis 2:14a5d6ad92d5 4291 LoRaMacStatus_t status = LORAMAC_STATUS_SERVICE_UNKNOWN;
mluis 2:14a5d6ad92d5 4292 LoRaMacHeader_t macHdr;
mluis 2:14a5d6ad92d5 4293
mluis 2:14a5d6ad92d5 4294 if( mlmeRequest == NULL )
mluis 2:14a5d6ad92d5 4295 {
mluis 2:14a5d6ad92d5 4296 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 4297 }
mluis 8:26002607de9c 4298 if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING )
mluis 2:14a5d6ad92d5 4299 {
mluis 2:14a5d6ad92d5 4300 return LORAMAC_STATUS_BUSY;
mluis 2:14a5d6ad92d5 4301 }
mluis 2:14a5d6ad92d5 4302
mluis 2:14a5d6ad92d5 4303 memset1( ( uint8_t* ) &MlmeConfirm, 0, sizeof( MlmeConfirm ) );
mluis 2:14a5d6ad92d5 4304
mluis 2:14a5d6ad92d5 4305 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR;
mluis 2:14a5d6ad92d5 4306
mluis 2:14a5d6ad92d5 4307 switch( mlmeRequest->Type )
mluis 2:14a5d6ad92d5 4308 {
mluis 2:14a5d6ad92d5 4309 case MLME_JOIN:
mluis 2:14a5d6ad92d5 4310 {
mluis 8:26002607de9c 4311 if( ( LoRaMacState & LORAMAC_TX_DELAYED ) == LORAMAC_TX_DELAYED )
mluis 2:14a5d6ad92d5 4312 {
mluis 6:d7a34ded7c87 4313 return LORAMAC_STATUS_BUSY;
mluis 2:14a5d6ad92d5 4314 }
mluis 2:14a5d6ad92d5 4315
mluis 2:14a5d6ad92d5 4316 if( ( mlmeRequest->Req.Join.DevEui == NULL ) ||
mluis 2:14a5d6ad92d5 4317 ( mlmeRequest->Req.Join.AppEui == NULL ) ||
mluis 8:26002607de9c 4318 ( mlmeRequest->Req.Join.AppKey == NULL ) ||
mluis 8:26002607de9c 4319 ( mlmeRequest->Req.Join.NbTrials == 0 ) )
mluis 2:14a5d6ad92d5 4320 {
mluis 2:14a5d6ad92d5 4321 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 4322 }
mluis 2:14a5d6ad92d5 4323
mluis 8:26002607de9c 4324 #if ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) )
mluis 8:26002607de9c 4325 // Enables at least the usage of the 2 datarates.
mluis 8:26002607de9c 4326 if( mlmeRequest->Req.Join.NbTrials < 2 )
mluis 8:26002607de9c 4327 {
mluis 8:26002607de9c 4328 mlmeRequest->Req.Join.NbTrials = 2;
mluis 8:26002607de9c 4329 }
mluis 8:26002607de9c 4330 #else
mluis 8:26002607de9c 4331 // Enables at least the usage of all datarates.
mluis 8:26002607de9c 4332 if( mlmeRequest->Req.Join.NbTrials < 48 )
mluis 8:26002607de9c 4333 {
mluis 8:26002607de9c 4334 mlmeRequest->Req.Join.NbTrials = 48;
mluis 8:26002607de9c 4335 }
mluis 8:26002607de9c 4336 #endif
mluis 8:26002607de9c 4337
mluis 2:14a5d6ad92d5 4338 LoRaMacFlags.Bits.MlmeReq = 1;
mluis 8:26002607de9c 4339 MlmeConfirm.MlmeRequest = mlmeRequest->Type;
mluis 2:14a5d6ad92d5 4340
mluis 2:14a5d6ad92d5 4341 LoRaMacDevEui = mlmeRequest->Req.Join.DevEui;
mluis 2:14a5d6ad92d5 4342 LoRaMacAppEui = mlmeRequest->Req.Join.AppEui;
mluis 2:14a5d6ad92d5 4343 LoRaMacAppKey = mlmeRequest->Req.Join.AppKey;
mluis 8:26002607de9c 4344 MaxJoinRequestTrials = mlmeRequest->Req.Join.NbTrials;
mluis 8:26002607de9c 4345
mluis 8:26002607de9c 4346 // Reset variable JoinRequestTrials
mluis 8:26002607de9c 4347 JoinRequestTrials = 0;
mluis 8:26002607de9c 4348
mluis 8:26002607de9c 4349 // Setup header information
mluis 2:14a5d6ad92d5 4350 macHdr.Value = 0;
mluis 2:14a5d6ad92d5 4351 macHdr.Bits.MType = FRAME_TYPE_JOIN_REQ;
mluis 2:14a5d6ad92d5 4352
mluis 7:c16969e0f70f 4353 ResetMacParameters( );
mluis 7:c16969e0f70f 4354
mluis 8:26002607de9c 4355 // Add a +1, since we start to count from 0
mluis 8:26002607de9c 4356 LoRaMacParams.ChannelsDatarate = AlternateDatarate( JoinRequestTrials + 1 );
mluis 2:14a5d6ad92d5 4357
mluis 2:14a5d6ad92d5 4358 status = Send( &macHdr, 0, NULL, 0 );
alphaemmeo 11:5b3e495baefb 4359
mluis 2:14a5d6ad92d5 4360 break;
mluis 2:14a5d6ad92d5 4361 }
mluis 2:14a5d6ad92d5 4362 case MLME_LINK_CHECK:
mluis 2:14a5d6ad92d5 4363 {
mluis 2:14a5d6ad92d5 4364 LoRaMacFlags.Bits.MlmeReq = 1;
mluis 2:14a5d6ad92d5 4365 // LoRaMac will send this command piggy-pack
mluis 2:14a5d6ad92d5 4366 MlmeConfirm.MlmeRequest = mlmeRequest->Type;
mluis 2:14a5d6ad92d5 4367
mluis 2:14a5d6ad92d5 4368 status = AddMacCommand( MOTE_MAC_LINK_CHECK_REQ, 0, 0 );
mluis 2:14a5d6ad92d5 4369 break;
mluis 2:14a5d6ad92d5 4370 }
mluis 8:26002607de9c 4371 case MLME_TXCW:
mluis 8:26002607de9c 4372 {
mluis 8:26002607de9c 4373 MlmeConfirm.MlmeRequest = mlmeRequest->Type;
mluis 8:26002607de9c 4374 LoRaMacFlags.Bits.MlmeReq = 1;
mluis 8:26002607de9c 4375 status = SetTxContinuousWave( mlmeRequest->Req.TxCw.Timeout );
mluis 8:26002607de9c 4376 break;
mluis 8:26002607de9c 4377 }
mluis 8:26002607de9c 4378 case MLME_TXCW_1:
mluis 8:26002607de9c 4379 {
mluis 8:26002607de9c 4380 MlmeConfirm.MlmeRequest = mlmeRequest->Type;
mluis 8:26002607de9c 4381 LoRaMacFlags.Bits.MlmeReq = 1;
mluis 8:26002607de9c 4382 status = SetTxContinuousWave1( mlmeRequest->Req.TxCw.Timeout, mlmeRequest->Req.TxCw.Frequency, mlmeRequest->Req.TxCw.Power );
mluis 8:26002607de9c 4383 break;
mluis 8:26002607de9c 4384 }
mluis 2:14a5d6ad92d5 4385 default:
mluis 2:14a5d6ad92d5 4386 break;
mluis 2:14a5d6ad92d5 4387 }
mluis 2:14a5d6ad92d5 4388
mluis 2:14a5d6ad92d5 4389 if( status != LORAMAC_STATUS_OK )
mluis 2:14a5d6ad92d5 4390 {
mluis 2:14a5d6ad92d5 4391 NodeAckRequested = false;
mluis 2:14a5d6ad92d5 4392 LoRaMacFlags.Bits.MlmeReq = 0;
mluis 2:14a5d6ad92d5 4393 }
mluis 2:14a5d6ad92d5 4394
mluis 2:14a5d6ad92d5 4395 return status;
mluis 0:91d1a7783bb9 4396 }
mluis 0:91d1a7783bb9 4397
mluis 2:14a5d6ad92d5 4398 LoRaMacStatus_t LoRaMacMcpsRequest( McpsReq_t *mcpsRequest )
mluis 0:91d1a7783bb9 4399 {
mluis 2:14a5d6ad92d5 4400 LoRaMacStatus_t status = LORAMAC_STATUS_SERVICE_UNKNOWN;
mluis 2:14a5d6ad92d5 4401 LoRaMacHeader_t macHdr;
mluis 2:14a5d6ad92d5 4402 uint8_t fPort = 0;
mluis 2:14a5d6ad92d5 4403 void *fBuffer;
mluis 2:14a5d6ad92d5 4404 uint16_t fBufferSize;
mluis 2:14a5d6ad92d5 4405 int8_t datarate;
mluis 2:14a5d6ad92d5 4406 bool readyToSend = false;
mluis 2:14a5d6ad92d5 4407
mluis 2:14a5d6ad92d5 4408 if( mcpsRequest == NULL )
mluis 2:14a5d6ad92d5 4409 {
alphaemmeo 11:5b3e495baefb 4410 ser->printf("[LRMAC] LORAMAC_STATUS_PARAMETER_INVALID 1\n\r");
mluis 2:14a5d6ad92d5 4411 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 4412 }
mluis 8:26002607de9c 4413 if( ( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) ||
mluis 8:26002607de9c 4414 ( ( LoRaMacState & LORAMAC_TX_DELAYED ) == LORAMAC_TX_DELAYED ) )
mluis 2:14a5d6ad92d5 4415 {
alphaemmeo 11:5b3e495baefb 4416 ser->printf("[LRMAC] LORAMAC_STATUS_BUSY\n\r");
mluis 2:14a5d6ad92d5 4417 return LORAMAC_STATUS_BUSY;
mluis 2:14a5d6ad92d5 4418 }
mluis 2:14a5d6ad92d5 4419
mluis 2:14a5d6ad92d5 4420 macHdr.Value = 0;
mluis 2:14a5d6ad92d5 4421 memset1 ( ( uint8_t* ) &McpsConfirm, 0, sizeof( McpsConfirm ) );
mluis 2:14a5d6ad92d5 4422 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR;
mluis 2:14a5d6ad92d5 4423
mluis 2:14a5d6ad92d5 4424 switch( mcpsRequest->Type )
mluis 2:14a5d6ad92d5 4425 {
mluis 2:14a5d6ad92d5 4426 case MCPS_UNCONFIRMED:
mluis 2:14a5d6ad92d5 4427 {
alphaemmeo 11:5b3e495baefb 4428 ser->printf("[LRMAC] MCPS_UNCONFIRMED\n\r");
mluis 2:14a5d6ad92d5 4429 readyToSend = true;
mluis 2:14a5d6ad92d5 4430 AckTimeoutRetries = 1;
mluis 2:14a5d6ad92d5 4431
mluis 2:14a5d6ad92d5 4432 macHdr.Bits.MType = FRAME_TYPE_DATA_UNCONFIRMED_UP;
mluis 2:14a5d6ad92d5 4433 fPort = mcpsRequest->Req.Unconfirmed.fPort;
mluis 2:14a5d6ad92d5 4434 fBuffer = mcpsRequest->Req.Unconfirmed.fBuffer;
mluis 2:14a5d6ad92d5 4435 fBufferSize = mcpsRequest->Req.Unconfirmed.fBufferSize;
mluis 2:14a5d6ad92d5 4436 datarate = mcpsRequest->Req.Unconfirmed.Datarate;
mluis 2:14a5d6ad92d5 4437 break;
mluis 2:14a5d6ad92d5 4438 }
mluis 2:14a5d6ad92d5 4439 case MCPS_CONFIRMED:
mluis 2:14a5d6ad92d5 4440 {
alphaemmeo 11:5b3e495baefb 4441 ser->printf("[LRMAC] MCPS_CONFIRMED\n\r");
mluis 2:14a5d6ad92d5 4442 readyToSend = true;
mluis 2:14a5d6ad92d5 4443 AckTimeoutRetriesCounter = 1;
mluis 3:b9d87593a8ae 4444 AckTimeoutRetries = mcpsRequest->Req.Confirmed.NbTrials;
mluis 2:14a5d6ad92d5 4445
mluis 2:14a5d6ad92d5 4446 macHdr.Bits.MType = FRAME_TYPE_DATA_CONFIRMED_UP;
mluis 2:14a5d6ad92d5 4447 fPort = mcpsRequest->Req.Confirmed.fPort;
mluis 2:14a5d6ad92d5 4448 fBuffer = mcpsRequest->Req.Confirmed.fBuffer;
mluis 2:14a5d6ad92d5 4449 fBufferSize = mcpsRequest->Req.Confirmed.fBufferSize;
mluis 2:14a5d6ad92d5 4450 datarate = mcpsRequest->Req.Confirmed.Datarate;
mluis 2:14a5d6ad92d5 4451 break;
mluis 2:14a5d6ad92d5 4452 }
mluis 2:14a5d6ad92d5 4453 case MCPS_PROPRIETARY:
mluis 2:14a5d6ad92d5 4454 {
alphaemmeo 11:5b3e495baefb 4455 ser->printf("[LRMAC] MCPS_PROPRIETARY\n\r");
mluis 2:14a5d6ad92d5 4456 readyToSend = true;
mluis 2:14a5d6ad92d5 4457 AckTimeoutRetries = 1;
mluis 2:14a5d6ad92d5 4458
mluis 2:14a5d6ad92d5 4459 macHdr.Bits.MType = FRAME_TYPE_PROPRIETARY;
mluis 2:14a5d6ad92d5 4460 fBuffer = mcpsRequest->Req.Proprietary.fBuffer;
mluis 2:14a5d6ad92d5 4461 fBufferSize = mcpsRequest->Req.Proprietary.fBufferSize;
mluis 2:14a5d6ad92d5 4462 datarate = mcpsRequest->Req.Proprietary.Datarate;
mluis 2:14a5d6ad92d5 4463 break;
mluis 2:14a5d6ad92d5 4464 }
mluis 2:14a5d6ad92d5 4465 default:
mluis 2:14a5d6ad92d5 4466 break;
mluis 2:14a5d6ad92d5 4467 }
mluis 2:14a5d6ad92d5 4468
mluis 2:14a5d6ad92d5 4469 if( readyToSend == true )
mluis 2:14a5d6ad92d5 4470 {
mluis 2:14a5d6ad92d5 4471 if( AdrCtrlOn == false )
mluis 2:14a5d6ad92d5 4472 {
mluis 4:37c12dbc8dc7 4473 if( ValueInRange( datarate, LORAMAC_TX_MIN_DATARATE, LORAMAC_TX_MAX_DATARATE ) == true )
mluis 2:14a5d6ad92d5 4474 {
mluis 7:c16969e0f70f 4475 LoRaMacParams.ChannelsDatarate = datarate;
mluis 2:14a5d6ad92d5 4476 }
mluis 2:14a5d6ad92d5 4477 else
mluis 2:14a5d6ad92d5 4478 {
alphaemmeo 11:5b3e495baefb 4479 ser->printf("[LRMAC] LORAMAC_STATUS_PARAMETER_INVALID 2 \n\r");
mluis 2:14a5d6ad92d5 4480 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 4481 }
mluis 2:14a5d6ad92d5 4482 }
mluis 2:14a5d6ad92d5 4483
mluis 2:14a5d6ad92d5 4484 status = Send( &macHdr, fPort, fBuffer, fBufferSize );
mluis 2:14a5d6ad92d5 4485 if( status == LORAMAC_STATUS_OK )
mluis 2:14a5d6ad92d5 4486 {
mluis 2:14a5d6ad92d5 4487 McpsConfirm.McpsRequest = mcpsRequest->Type;
mluis 2:14a5d6ad92d5 4488 LoRaMacFlags.Bits.McpsReq = 1;
mluis 2:14a5d6ad92d5 4489 }
mluis 2:14a5d6ad92d5 4490 else
mluis 2:14a5d6ad92d5 4491 {
mluis 2:14a5d6ad92d5 4492 NodeAckRequested = false;
mluis 2:14a5d6ad92d5 4493 }
mluis 2:14a5d6ad92d5 4494 }
alphaemmeo 11:5b3e495baefb 4495 ser->printf("[LRMAC] LoRaMacStatus_t LoRaMacMcpsRequest :: status %u \n\r", status);
mluis 2:14a5d6ad92d5 4496 return status;
mluis 0:91d1a7783bb9 4497 }
mluis 0:91d1a7783bb9 4498
mluis 0:91d1a7783bb9 4499 void LoRaMacTestRxWindowsOn( bool enable )
mluis 0:91d1a7783bb9 4500 {
mluis 0:91d1a7783bb9 4501 IsRxWindowsEnabled = enable;
mluis 0:91d1a7783bb9 4502 }
mluis 0:91d1a7783bb9 4503
mluis 2:14a5d6ad92d5 4504 void LoRaMacTestSetMic( uint16_t txPacketCounter )
mluis 0:91d1a7783bb9 4505 {
mluis 2:14a5d6ad92d5 4506 UpLinkCounter = txPacketCounter;
mluis 0:91d1a7783bb9 4507 IsUpLinkCounterFixed = true;
mluis 0:91d1a7783bb9 4508 }
mluis 2:14a5d6ad92d5 4509
mluis 2:14a5d6ad92d5 4510 void LoRaMacTestSetDutyCycleOn( bool enable )
mluis 2:14a5d6ad92d5 4511 {
mluis 8:26002607de9c 4512 #if ( defined( USE_BAND_868 ) || defined( USE_BAND_433 ) || defined( USE_BAND_780 ) )
mluis 2:14a5d6ad92d5 4513 DutyCycleOn = enable;
mluis 8:26002607de9c 4514 #else
mluis 8:26002607de9c 4515 DutyCycleOn = false;
mluis 8:26002607de9c 4516 #endif
mluis 2:14a5d6ad92d5 4517 }
mluis 8:26002607de9c 4518
mluis 8:26002607de9c 4519 void LoRaMacTestSetChannel( uint8_t channel )
mluis 8:26002607de9c 4520 {
mluis 8:26002607de9c 4521 Channel = channel;
mluis 8:26002607de9c 4522 }
mluis 8:26002607de9c 4523
mluis 8:26002607de9c 4524 static RxConfigParams_t ComputeRxWindowParameters( int8_t datarate, uint32_t rxError )
mluis 8:26002607de9c 4525 {
mluis 8:26002607de9c 4526 RxConfigParams_t rxConfigParams = { 0, 0, 0, 0 };
mluis 8:26002607de9c 4527 double tSymbol = 0.0;
mluis 8:26002607de9c 4528
mluis 8:26002607de9c 4529 rxConfigParams.Datarate = datarate;
mluis 8:26002607de9c 4530 switch( Bandwidths[datarate] )
mluis 8:26002607de9c 4531 {
mluis 8:26002607de9c 4532 default:
mluis 8:26002607de9c 4533 case 125000:
mluis 8:26002607de9c 4534 rxConfigParams.Bandwidth = 0;
mluis 8:26002607de9c 4535 break;
mluis 8:26002607de9c 4536 case 250000:
mluis 8:26002607de9c 4537 rxConfigParams.Bandwidth = 1;
mluis 8:26002607de9c 4538 break;
mluis 8:26002607de9c 4539 case 500000:
mluis 8:26002607de9c 4540 rxConfigParams.Bandwidth = 2;
mluis 8:26002607de9c 4541 break;
mluis 8:26002607de9c 4542 }
mluis 8:26002607de9c 4543
mluis 8:26002607de9c 4544 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
mluis 8:26002607de9c 4545 if( datarate == DR_7 )
mluis 8:26002607de9c 4546 { // FSK
mluis 8:26002607de9c 4547 tSymbol = ( 1.0 / ( double )Datarates[datarate] ) * 8.0; // 1 symbol equals 1 byte
mluis 8:26002607de9c 4548 }
mluis 8:26002607de9c 4549 else
mluis 8:26002607de9c 4550 #endif
mluis 8:26002607de9c 4551 { // LoRa
mluis 8:26002607de9c 4552 tSymbol = ( ( double )( 1 << Datarates[datarate] ) / ( double )Bandwidths[datarate] ) * 1e3;
mluis 8:26002607de9c 4553 }
mluis 8:26002607de9c 4554
mluis 8:26002607de9c 4555 rxConfigParams.RxWindowTimeout = MAX( ( uint32_t )ceil( ( ( 2 * LoRaMacParams.MinRxSymbols - 8 ) * tSymbol + 2 * rxError ) / tSymbol ), LoRaMacParams.MinRxSymbols ); // Computed number of symbols
mluis 8:26002607de9c 4556
mluis 8:26002607de9c 4557 rxConfigParams.RxOffset = ( int32_t )ceil( ( 4.0 * tSymbol ) - ( ( rxConfigParams.RxWindowTimeout * tSymbol ) / 2.0 ) - RADIO_WAKEUP_TIME );
mluis 8:26002607de9c 4558
mluis 8:26002607de9c 4559 return rxConfigParams;
mluis 8:26002607de9c 4560 }