Adding support for India ISM Band.

Fork of LoRaWAN-lib by Semtech

Committer:
spcores
Date:
Thu Mar 31 16:05:20 2016 +0000
Revision:
4:06708c793508
Parent:
3:b9d87593a8ae
Child:
5:77f44e83b37d
WIP Support for India ISM Band

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 0:91d1a7783bb9 20 #include "board.h"
mluis 0:91d1a7783bb9 21
mluis 0:91d1a7783bb9 22 #include "LoRaMacCrypto.h"
mluis 0:91d1a7783bb9 23 #include "LoRaMac.h"
mluis 2:14a5d6ad92d5 24 #include "LoRaMacTest.h"
mluis 0:91d1a7783bb9 25
mluis 0:91d1a7783bb9 26 /*!
mluis 0:91d1a7783bb9 27 * Maximum PHY layer payload size
mluis 0:91d1a7783bb9 28 */
mluis 1:91e4e6c60d1e 29 #define LORAMAC_PHY_MAXPAYLOAD 255
mluis 1:91e4e6c60d1e 30
mluis 1:91e4e6c60d1e 31 /*!
mluis 1:91e4e6c60d1e 32 * Maximum MAC commands buffer size
mluis 1:91e4e6c60d1e 33 */
mluis 1:91e4e6c60d1e 34 #define LORA_MAC_COMMAND_MAX_LENGTH 15
mluis 0:91d1a7783bb9 35
mluis 0:91d1a7783bb9 36 /*!
mluis 0:91d1a7783bb9 37 * Device IEEE EUI
mluis 0:91d1a7783bb9 38 */
mluis 0:91d1a7783bb9 39 static uint8_t *LoRaMacDevEui;
mluis 0:91d1a7783bb9 40
mluis 0:91d1a7783bb9 41 /*!
mluis 0:91d1a7783bb9 42 * Application IEEE EUI
mluis 0:91d1a7783bb9 43 */
mluis 0:91d1a7783bb9 44 static uint8_t *LoRaMacAppEui;
mluis 0:91d1a7783bb9 45
mluis 0:91d1a7783bb9 46 /*!
mluis 0:91d1a7783bb9 47 * AES encryption/decryption cipher application key
mluis 0:91d1a7783bb9 48 */
mluis 0:91d1a7783bb9 49 static uint8_t *LoRaMacAppKey;
mluis 0:91d1a7783bb9 50
mluis 0:91d1a7783bb9 51 /*!
mluis 0:91d1a7783bb9 52 * AES encryption/decryption cipher network session key
mluis 0:91d1a7783bb9 53 */
mluis 0:91d1a7783bb9 54 static uint8_t LoRaMacNwkSKey[] =
mluis 0:91d1a7783bb9 55 {
mluis 0:91d1a7783bb9 56 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
mluis 0:91d1a7783bb9 57 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
mluis 0:91d1a7783bb9 58 };
mluis 0:91d1a7783bb9 59
mluis 0:91d1a7783bb9 60 /*!
mluis 0:91d1a7783bb9 61 * AES encryption/decryption cipher application session key
mluis 0:91d1a7783bb9 62 */
mluis 0:91d1a7783bb9 63 static uint8_t LoRaMacAppSKey[] =
mluis 0:91d1a7783bb9 64 {
mluis 0:91d1a7783bb9 65 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
mluis 0:91d1a7783bb9 66 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
mluis 0:91d1a7783bb9 67 };
mluis 0:91d1a7783bb9 68
mluis 0:91d1a7783bb9 69 /*!
mluis 0:91d1a7783bb9 70 * Device nonce is a random value extracted by issuing a sequence of RSSI
mluis 0:91d1a7783bb9 71 * measurements
mluis 0:91d1a7783bb9 72 */
mluis 0:91d1a7783bb9 73 static uint16_t LoRaMacDevNonce;
mluis 0:91d1a7783bb9 74
mluis 0:91d1a7783bb9 75 /*!
mluis 0:91d1a7783bb9 76 * Network ID ( 3 bytes )
mluis 0:91d1a7783bb9 77 */
mluis 0:91d1a7783bb9 78 static uint32_t LoRaMacNetID;
mluis 0:91d1a7783bb9 79
mluis 0:91d1a7783bb9 80 /*!
mluis 0:91d1a7783bb9 81 * Mote Address
mluis 0:91d1a7783bb9 82 */
mluis 0:91d1a7783bb9 83 static uint32_t LoRaMacDevAddr;
mluis 0:91d1a7783bb9 84
mluis 0:91d1a7783bb9 85 /*!
mluis 2:14a5d6ad92d5 86 * Multicast channels linked list
mluis 0:91d1a7783bb9 87 */
mluis 0:91d1a7783bb9 88 static MulticastParams_t *MulticastChannels = NULL;
mluis 0:91d1a7783bb9 89
mluis 0:91d1a7783bb9 90 /*!
mluis 0:91d1a7783bb9 91 * Actual device class
mluis 0:91d1a7783bb9 92 */
mluis 0:91d1a7783bb9 93 static DeviceClass_t LoRaMacDeviceClass;
mluis 0:91d1a7783bb9 94
mluis 0:91d1a7783bb9 95 /*!
mluis 0:91d1a7783bb9 96 * Indicates if the node is connected to a private or public network
mluis 0:91d1a7783bb9 97 */
mluis 0:91d1a7783bb9 98 static bool PublicNetwork;
mluis 0:91d1a7783bb9 99
mluis 0:91d1a7783bb9 100 /*!
mluis 0:91d1a7783bb9 101 * Indicates if the node supports repeaters
mluis 0:91d1a7783bb9 102 */
mluis 0:91d1a7783bb9 103 static bool RepeaterSupport;
mluis 0:91d1a7783bb9 104
mluis 0:91d1a7783bb9 105 /*!
mluis 0:91d1a7783bb9 106 * Buffer containing the data to be sent or received.
mluis 0:91d1a7783bb9 107 */
mluis 0:91d1a7783bb9 108 static uint8_t LoRaMacBuffer[LORAMAC_PHY_MAXPAYLOAD];
mluis 0:91d1a7783bb9 109
mluis 0:91d1a7783bb9 110 /*!
mluis 0:91d1a7783bb9 111 * Length of packet in LoRaMacBuffer
mluis 0:91d1a7783bb9 112 */
mluis 0:91d1a7783bb9 113 static uint16_t LoRaMacBufferPktLen = 0;
mluis 0:91d1a7783bb9 114
mluis 0:91d1a7783bb9 115 /*!
mluis 0:91d1a7783bb9 116 * Buffer containing the upper layer data.
mluis 0:91d1a7783bb9 117 */
mluis 0:91d1a7783bb9 118 static uint8_t LoRaMacPayload[LORAMAC_PHY_MAXPAYLOAD];
mluis 0:91d1a7783bb9 119 static uint8_t LoRaMacRxPayload[LORAMAC_PHY_MAXPAYLOAD];
mluis 0:91d1a7783bb9 120
mluis 0:91d1a7783bb9 121 /*!
mluis 0:91d1a7783bb9 122 * LoRaMAC frame counter. Each time a packet is sent the counter is incremented.
mluis 0:91d1a7783bb9 123 * Only the 16 LSB bits are sent
mluis 0:91d1a7783bb9 124 */
mluis 0:91d1a7783bb9 125 static uint32_t UpLinkCounter = 1;
mluis 0:91d1a7783bb9 126
mluis 0:91d1a7783bb9 127 /*!
mluis 0:91d1a7783bb9 128 * LoRaMAC frame counter. Each time a packet is received the counter is incremented.
mluis 0:91d1a7783bb9 129 * Only the 16 LSB bits are received
mluis 0:91d1a7783bb9 130 */
mluis 0:91d1a7783bb9 131 static uint32_t DownLinkCounter = 0;
mluis 0:91d1a7783bb9 132
mluis 0:91d1a7783bb9 133 /*!
mluis 0:91d1a7783bb9 134 * IsPacketCounterFixed enables the MIC field tests by fixing the
mluis 0:91d1a7783bb9 135 * UpLinkCounter value
mluis 0:91d1a7783bb9 136 */
mluis 0:91d1a7783bb9 137 static bool IsUpLinkCounterFixed = false;
mluis 0:91d1a7783bb9 138
mluis 0:91d1a7783bb9 139 /*!
mluis 0:91d1a7783bb9 140 * Used for test purposes. Disables the opening of the reception windows.
mluis 0:91d1a7783bb9 141 */
mluis 0:91d1a7783bb9 142 static bool IsRxWindowsEnabled = true;
mluis 0:91d1a7783bb9 143
mluis 0:91d1a7783bb9 144 /*!
mluis 0:91d1a7783bb9 145 * Indicates if the MAC layer has already joined a network.
mluis 0:91d1a7783bb9 146 */
mluis 0:91d1a7783bb9 147 static bool IsLoRaMacNetworkJoined = false;
mluis 0:91d1a7783bb9 148
mluis 0:91d1a7783bb9 149 /*!
mluis 0:91d1a7783bb9 150 * LoRaMac ADR control status
mluis 0:91d1a7783bb9 151 */
mluis 0:91d1a7783bb9 152 static bool AdrCtrlOn = false;
mluis 0:91d1a7783bb9 153
mluis 0:91d1a7783bb9 154 /*!
mluis 0:91d1a7783bb9 155 * Counts the number of missed ADR acknowledgements
mluis 0:91d1a7783bb9 156 */
mluis 0:91d1a7783bb9 157 static uint32_t AdrAckCounter = 0;
mluis 0:91d1a7783bb9 158
mluis 0:91d1a7783bb9 159 /*!
mluis 0:91d1a7783bb9 160 * If the node has sent a FRAME_TYPE_DATA_CONFIRMED_UP this variable indicates
mluis 0:91d1a7783bb9 161 * if the nodes needs to manage the server acknowledgement.
mluis 0:91d1a7783bb9 162 */
mluis 0:91d1a7783bb9 163 static bool NodeAckRequested = false;
mluis 0:91d1a7783bb9 164
mluis 0:91d1a7783bb9 165 /*!
mluis 0:91d1a7783bb9 166 * If the server has sent a FRAME_TYPE_DATA_CONFIRMED_DOWN this variable indicates
mluis 0:91d1a7783bb9 167 * if the ACK bit must be set for the next transmission
mluis 0:91d1a7783bb9 168 */
mluis 0:91d1a7783bb9 169 static bool SrvAckRequested = false;
mluis 0:91d1a7783bb9 170
mluis 0:91d1a7783bb9 171 /*!
mluis 0:91d1a7783bb9 172 * Indicates if the MAC layer wants to send MAC commands
mluis 0:91d1a7783bb9 173 */
mluis 0:91d1a7783bb9 174 static bool MacCommandsInNextTx = false;
mluis 0:91d1a7783bb9 175
mluis 0:91d1a7783bb9 176 /*!
mluis 0:91d1a7783bb9 177 * Contains the current MacCommandsBuffer index
mluis 0:91d1a7783bb9 178 */
mluis 0:91d1a7783bb9 179 static uint8_t MacCommandsBufferIndex = 0;
mluis 0:91d1a7783bb9 180
mluis 0:91d1a7783bb9 181 /*!
mluis 0:91d1a7783bb9 182 * Buffer containing the MAC layer commands
mluis 0:91d1a7783bb9 183 */
mluis 1:91e4e6c60d1e 184 static uint8_t MacCommandsBuffer[LORA_MAC_COMMAND_MAX_LENGTH];
mluis 0:91d1a7783bb9 185
mluis 0:91d1a7783bb9 186 #if defined( USE_BAND_433 )
mluis 0:91d1a7783bb9 187 /*!
mluis 0:91d1a7783bb9 188 * Data rates table definition
mluis 0:91d1a7783bb9 189 */
mluis 0:91d1a7783bb9 190 const uint8_t Datarates[] = { 12, 11, 10, 9, 8, 7, 7, 50 };
mluis 0:91d1a7783bb9 191
mluis 0:91d1a7783bb9 192 /*!
mluis 0:91d1a7783bb9 193 * Maximum payload with respect to the datarate index. Cannot operate with repeater.
mluis 0:91d1a7783bb9 194 */
mluis 0:91d1a7783bb9 195 const uint8_t MaxPayloadOfDatarate[] = { 59, 59, 59, 123, 250, 250, 250, 250 };
mluis 0:91d1a7783bb9 196
mluis 0:91d1a7783bb9 197 /*!
mluis 0:91d1a7783bb9 198 * Maximum payload with respect to the datarate index. Can operate with repeater.
mluis 0:91d1a7783bb9 199 */
mluis 0:91d1a7783bb9 200 const uint8_t MaxPayloadOfDatarateRepeater[] = { 59, 59, 59, 123, 230, 230, 230, 230 };
mluis 0:91d1a7783bb9 201
mluis 0:91d1a7783bb9 202 /*!
mluis 0:91d1a7783bb9 203 * Tx output powers table definition
mluis 0:91d1a7783bb9 204 */
mluis 0:91d1a7783bb9 205 const int8_t TxPowers[] = { 20, 14, 11, 8, 5, 2 };
mluis 0:91d1a7783bb9 206
mluis 0:91d1a7783bb9 207 /*!
mluis 0:91d1a7783bb9 208 * LoRaMac bands
mluis 0:91d1a7783bb9 209 */
mluis 0:91d1a7783bb9 210 static Band_t Bands[LORA_MAX_NB_BANDS] =
mluis 0:91d1a7783bb9 211 {
mluis 0:91d1a7783bb9 212 BAND0,
mluis 0:91d1a7783bb9 213 };
mluis 0:91d1a7783bb9 214
mluis 0:91d1a7783bb9 215 /*!
mluis 0:91d1a7783bb9 216 * LoRaMAC channels
mluis 0:91d1a7783bb9 217 */
mluis 0:91d1a7783bb9 218 static ChannelParams_t Channels[LORA_MAX_NB_CHANNELS] =
mluis 0:91d1a7783bb9 219 {
mluis 0:91d1a7783bb9 220 LC1,
mluis 0:91d1a7783bb9 221 LC2,
mluis 0:91d1a7783bb9 222 LC3,
mluis 0:91d1a7783bb9 223 };
mluis 0:91d1a7783bb9 224 #elif defined( USE_BAND_780 )
mluis 0:91d1a7783bb9 225 /*!
mluis 0:91d1a7783bb9 226 * Data rates table definition
mluis 0:91d1a7783bb9 227 */
mluis 0:91d1a7783bb9 228 const uint8_t Datarates[] = { 12, 11, 10, 9, 8, 7, 7, 50 };
mluis 0:91d1a7783bb9 229
mluis 0:91d1a7783bb9 230 /*!
mluis 0:91d1a7783bb9 231 * Maximum payload with respect to the datarate index. Cannot operate with repeater.
mluis 0:91d1a7783bb9 232 */
mluis 0:91d1a7783bb9 233 const uint8_t MaxPayloadOfDatarate[] = { 59, 59, 59, 123, 250, 250, 250, 250 };
mluis 0:91d1a7783bb9 234
mluis 0:91d1a7783bb9 235 /*!
mluis 0:91d1a7783bb9 236 * Maximum payload with respect to the datarate index. Can operate with repeater.
mluis 0:91d1a7783bb9 237 */
mluis 0:91d1a7783bb9 238 const uint8_t MaxPayloadOfDatarateRepeater[] = { 59, 59, 59, 123, 230, 230, 230, 230 };
mluis 0:91d1a7783bb9 239
mluis 0:91d1a7783bb9 240 /*!
mluis 0:91d1a7783bb9 241 * Tx output powers table definition
mluis 0:91d1a7783bb9 242 */
mluis 0:91d1a7783bb9 243 const int8_t TxPowers[] = { 20, 14, 11, 8, 5, 2 };
mluis 0:91d1a7783bb9 244
mluis 0:91d1a7783bb9 245 /*!
mluis 0:91d1a7783bb9 246 * LoRaMac bands
mluis 0:91d1a7783bb9 247 */
mluis 0:91d1a7783bb9 248 static Band_t Bands[LORA_MAX_NB_BANDS] =
mluis 0:91d1a7783bb9 249 {
mluis 0:91d1a7783bb9 250 BAND0,
mluis 0:91d1a7783bb9 251 };
mluis 0:91d1a7783bb9 252
mluis 0:91d1a7783bb9 253 /*!
mluis 0:91d1a7783bb9 254 * LoRaMAC channels
mluis 0:91d1a7783bb9 255 */
mluis 0:91d1a7783bb9 256 static ChannelParams_t Channels[LORA_MAX_NB_CHANNELS] =
mluis 0:91d1a7783bb9 257 {
mluis 0:91d1a7783bb9 258 LC1,
mluis 0:91d1a7783bb9 259 LC2,
mluis 0:91d1a7783bb9 260 LC3,
mluis 0:91d1a7783bb9 261 };
spcores 4:06708c793508 262 /************************************************************************************/
spcores 4:06708c793508 263 /******** India Frequency Declaration Start **********/
spcores 4:06708c793508 264 /******** Added by: Sachin Pukale | 31.03.2016 **********/
spcores 4:06708c793508 265 /************************************************************************************/
spcores 4:06708c793508 266 #elif defined( USE_BAND_865 )
spcores 4:06708c793508 267 /*!
spcores 4:06708c793508 268 * Data rates table definition
spcores 4:06708c793508 269 */
spcores 4:06708c793508 270 const uint8_t Datarates[] = { 12, 11, 10, 9, 8, 7, 7, 50 };
spcores 4:06708c793508 271
spcores 4:06708c793508 272 /*!
spcores 4:06708c793508 273 * Maximum payload with respect to the datarate index. Cannot operate with repeater.
spcores 4:06708c793508 274 */
spcores 4:06708c793508 275 const uint8_t MaxPayloadOfDatarate[] = { 51, 51, 51, 115, 242, 242, 242, 242 };
spcores 4:06708c793508 276
spcores 4:06708c793508 277 /*!
spcores 4:06708c793508 278 * Maximum payload with respect to the datarate index. Can operate with repeater.
spcores 4:06708c793508 279 */
spcores 4:06708c793508 280 const uint8_t MaxPayloadOfDatarateRepeater[] = { 51, 51, 51, 115, 222, 222, 222, 222 };
spcores 4:06708c793508 281
spcores 4:06708c793508 282 /*!
spcores 4:06708c793508 283 * Tx output powers table definition
spcores 4:06708c793508 284 */
spcores 4:06708c793508 285 const int8_t TxPowers[] = { 27, 20, 14, 11, 8, 5, 2 }; //Added by SP 31.03.2016
spcores 4:06708c793508 286
spcores 4:06708c793508 287 /*!
spcores 4:06708c793508 288 * LoRaMac bands
spcores 4:06708c793508 289 */
spcores 4:06708c793508 290 static Band_t Bands[LORA_MAX_NB_BANDS] =
spcores 4:06708c793508 291 {
spcores 4:06708c793508 292 BAND0,
spcores 4:06708c793508 293 /*
spcores 4:06708c793508 294 BAND1,
spcores 4:06708c793508 295 BAND2,
spcores 4:06708c793508 296 BAND3,
spcores 4:06708c793508 297 BAND4,
spcores 4:06708c793508 298 */
spcores 4:06708c793508 299 };
spcores 4:06708c793508 300
spcores 4:06708c793508 301 /*!
spcores 4:06708c793508 302 * LoRaMAC channels
spcores 4:06708c793508 303 */
spcores 4:06708c793508 304 static ChannelParams_t Channels[LORA_MAX_NB_CHANNELS] =
spcores 4:06708c793508 305 {
spcores 4:06708c793508 306 LC1,
spcores 4:06708c793508 307 LC2,
spcores 4:06708c793508 308 LC3,
spcores 4:06708c793508 309 };
spcores 4:06708c793508 310 /************************************************************************************/
spcores 4:06708c793508 311 /******** India Frequency Declaration End **********/
spcores 4:06708c793508 312 /************************************************************************************/
spcores 4:06708c793508 313
mluis 0:91d1a7783bb9 314 #elif defined( USE_BAND_868 )
mluis 0:91d1a7783bb9 315 /*!
mluis 0:91d1a7783bb9 316 * Data rates table definition
mluis 0:91d1a7783bb9 317 */
mluis 0:91d1a7783bb9 318 const uint8_t Datarates[] = { 12, 11, 10, 9, 8, 7, 7, 50 };
mluis 0:91d1a7783bb9 319
mluis 0:91d1a7783bb9 320 /*!
mluis 0:91d1a7783bb9 321 * Maximum payload with respect to the datarate index. Cannot operate with repeater.
mluis 0:91d1a7783bb9 322 */
mluis 0:91d1a7783bb9 323 const uint8_t MaxPayloadOfDatarate[] = { 51, 51, 51, 115, 242, 242, 242, 242 };
mluis 0:91d1a7783bb9 324
mluis 0:91d1a7783bb9 325 /*!
mluis 0:91d1a7783bb9 326 * Maximum payload with respect to the datarate index. Can operate with repeater.
mluis 0:91d1a7783bb9 327 */
mluis 0:91d1a7783bb9 328 const uint8_t MaxPayloadOfDatarateRepeater[] = { 51, 51, 51, 115, 222, 222, 222, 222 };
mluis 0:91d1a7783bb9 329
mluis 0:91d1a7783bb9 330 /*!
mluis 0:91d1a7783bb9 331 * Tx output powers table definition
mluis 0:91d1a7783bb9 332 */
mluis 0:91d1a7783bb9 333 const int8_t TxPowers[] = { 20, 14, 11, 8, 5, 2 };
mluis 0:91d1a7783bb9 334
mluis 0:91d1a7783bb9 335 /*!
mluis 0:91d1a7783bb9 336 * LoRaMac bands
mluis 0:91d1a7783bb9 337 */
mluis 0:91d1a7783bb9 338 static Band_t Bands[LORA_MAX_NB_BANDS] =
mluis 0:91d1a7783bb9 339 {
mluis 0:91d1a7783bb9 340 BAND0,
mluis 0:91d1a7783bb9 341 BAND1,
mluis 0:91d1a7783bb9 342 BAND2,
mluis 0:91d1a7783bb9 343 BAND3,
mluis 0:91d1a7783bb9 344 BAND4,
mluis 0:91d1a7783bb9 345 };
mluis 0:91d1a7783bb9 346
mluis 0:91d1a7783bb9 347 /*!
mluis 0:91d1a7783bb9 348 * LoRaMAC channels
mluis 0:91d1a7783bb9 349 */
mluis 0:91d1a7783bb9 350 static ChannelParams_t Channels[LORA_MAX_NB_CHANNELS] =
mluis 0:91d1a7783bb9 351 {
mluis 0:91d1a7783bb9 352 LC1,
mluis 0:91d1a7783bb9 353 LC2,
mluis 0:91d1a7783bb9 354 LC3,
mluis 0:91d1a7783bb9 355 };
mluis 0:91d1a7783bb9 356 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 0:91d1a7783bb9 357 /*!
mluis 0:91d1a7783bb9 358 * Data rates table definition
mluis 0:91d1a7783bb9 359 */
mluis 0:91d1a7783bb9 360 const uint8_t Datarates[] = { 10, 9, 8, 7, 8, 0, 0, 0, 12, 11, 10, 9, 8, 7, 0, 0 };
mluis 0:91d1a7783bb9 361
mluis 0:91d1a7783bb9 362 /*!
mluis 0:91d1a7783bb9 363 * Up/Down link data rates offset definition
mluis 0:91d1a7783bb9 364 */
mluis 2:14a5d6ad92d5 365 const int8_t datarateOffsets[16][4] =
mluis 0:91d1a7783bb9 366 {
mluis 0:91d1a7783bb9 367 { DR_10, DR_9 , DR_8 , DR_8 }, // DR_0
mluis 0:91d1a7783bb9 368 { DR_11, DR_10, DR_9 , DR_8 }, // DR_1
mluis 0:91d1a7783bb9 369 { DR_12, DR_11, DR_10, DR_9 }, // DR_2
mluis 0:91d1a7783bb9 370 { DR_13, DR_12, DR_11, DR_10 }, // DR_3
mluis 0:91d1a7783bb9 371 { DR_13, DR_13, DR_12, DR_11 }, // DR_4
mluis 0:91d1a7783bb9 372 { 0xFF , 0xFF , 0xFF , 0xFF },
mluis 0:91d1a7783bb9 373 { 0xFF , 0xFF , 0xFF , 0xFF },
mluis 0:91d1a7783bb9 374 { 0xFF , 0xFF , 0xFF , 0xFF },
mluis 0:91d1a7783bb9 375 { DR_8 , DR_8 , DR_8 , DR_8 },
mluis 0:91d1a7783bb9 376 { DR_9 , DR_8 , DR_8 , DR_8 },
mluis 0:91d1a7783bb9 377 { DR_10, DR_9 , DR_8 , DR_8 },
mluis 0:91d1a7783bb9 378 { DR_11, DR_10, DR_9 , DR_8 },
mluis 0:91d1a7783bb9 379 { DR_12, DR_11, DR_10, DR_9 },
mluis 0:91d1a7783bb9 380 { DR_13, DR_12, DR_11, DR_10 },
mluis 0:91d1a7783bb9 381 { 0xFF , 0xFF , 0xFF , 0xFF },
mluis 0:91d1a7783bb9 382 { 0xFF , 0xFF , 0xFF , 0xFF },
mluis 0:91d1a7783bb9 383 };
mluis 0:91d1a7783bb9 384
mluis 0:91d1a7783bb9 385 /*!
mluis 0:91d1a7783bb9 386 * Maximum payload with respect to the datarate index. Cannot operate with repeater.
mluis 0:91d1a7783bb9 387 */
mluis 0:91d1a7783bb9 388 const uint8_t MaxPayloadOfDatarate[] = { 11, 53, 129, 242, 242, 0, 0, 0, 53, 129, 242, 242, 242, 242, 0, 0 };
mluis 0:91d1a7783bb9 389
mluis 0:91d1a7783bb9 390 /*!
mluis 0:91d1a7783bb9 391 * Maximum payload with respect to the datarate index. Can operate with repeater.
mluis 0:91d1a7783bb9 392 */
mluis 0:91d1a7783bb9 393 const uint8_t MaxPayloadOfDatarateRepeater[] = { 11, 53, 129, 242, 242, 0, 0, 0, 33, 103, 222, 222, 222, 222, 0, 0 };
mluis 0:91d1a7783bb9 394
mluis 0:91d1a7783bb9 395 /*!
mluis 0:91d1a7783bb9 396 * Tx output powers table definition
mluis 0:91d1a7783bb9 397 */
mluis 0:91d1a7783bb9 398 const int8_t TxPowers[] = { 30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10 };
mluis 0:91d1a7783bb9 399
mluis 0:91d1a7783bb9 400 /*!
mluis 0:91d1a7783bb9 401 * LoRaMac bands
mluis 0:91d1a7783bb9 402 */
mluis 0:91d1a7783bb9 403 static Band_t Bands[LORA_MAX_NB_BANDS] =
mluis 0:91d1a7783bb9 404 {
mluis 0:91d1a7783bb9 405 BAND0,
mluis 0:91d1a7783bb9 406 };
mluis 0:91d1a7783bb9 407
mluis 0:91d1a7783bb9 408 /*!
mluis 0:91d1a7783bb9 409 * LoRaMAC channels
mluis 0:91d1a7783bb9 410 */
mluis 0:91d1a7783bb9 411 static ChannelParams_t Channels[LORA_MAX_NB_CHANNELS];
mluis 0:91d1a7783bb9 412
mluis 2:14a5d6ad92d5 413 /*!
mluis 2:14a5d6ad92d5 414 * Contains the channels which remain to be applied.
mluis 2:14a5d6ad92d5 415 */
mluis 2:14a5d6ad92d5 416 static uint16_t ChannelsMaskRemaining[6];
mluis 2:14a5d6ad92d5 417
mluis 0:91d1a7783bb9 418 #else
mluis 0:91d1a7783bb9 419 #error "Please define a frequency band in the compiler options."
mluis 0:91d1a7783bb9 420 #endif
mluis 0:91d1a7783bb9 421
mluis 0:91d1a7783bb9 422 /*!
mluis 0:91d1a7783bb9 423 * LoRaMAC 2nd reception window settings
mluis 0:91d1a7783bb9 424 */
mluis 0:91d1a7783bb9 425 static Rx2ChannelParams_t Rx2Channel = RX_WND_2_CHANNEL;
mluis 0:91d1a7783bb9 426
mluis 0:91d1a7783bb9 427 /*!
mluis 0:91d1a7783bb9 428 * Datarate offset between uplink and downlink on first window
mluis 0:91d1a7783bb9 429 */
mluis 0:91d1a7783bb9 430 static uint8_t Rx1DrOffset = 0;
mluis 0:91d1a7783bb9 431
mluis 0:91d1a7783bb9 432 /*!
mluis 0:91d1a7783bb9 433 * Mask indicating which channels are enabled
mluis 0:91d1a7783bb9 434 */
mluis 0:91d1a7783bb9 435 static uint16_t ChannelsMask[6];
mluis 0:91d1a7783bb9 436
mluis 0:91d1a7783bb9 437 /*!
mluis 0:91d1a7783bb9 438 * Channels Tx output power
mluis 0:91d1a7783bb9 439 */
mluis 0:91d1a7783bb9 440 static int8_t ChannelsTxPower = LORAMAC_DEFAULT_TX_POWER;
mluis 0:91d1a7783bb9 441
mluis 0:91d1a7783bb9 442 /*!
mluis 0:91d1a7783bb9 443 * Channels datarate
mluis 0:91d1a7783bb9 444 */
mluis 0:91d1a7783bb9 445 static int8_t ChannelsDatarate = LORAMAC_DEFAULT_DATARATE;
mluis 0:91d1a7783bb9 446
mluis 0:91d1a7783bb9 447 /*!
mluis 0:91d1a7783bb9 448 * Channels default datarate
mluis 0:91d1a7783bb9 449 */
mluis 0:91d1a7783bb9 450 static int8_t ChannelsDefaultDatarate = LORAMAC_DEFAULT_DATARATE;
mluis 0:91d1a7783bb9 451
mluis 0:91d1a7783bb9 452 /*!
mluis 0:91d1a7783bb9 453 * Number of uplink messages repetitions [1:15] (unconfirmed messages only)
mluis 0:91d1a7783bb9 454 */
mluis 0:91d1a7783bb9 455 static uint8_t ChannelsNbRep = 1;
mluis 0:91d1a7783bb9 456
mluis 0:91d1a7783bb9 457 /*!
mluis 0:91d1a7783bb9 458 * Uplink messages repetitions counter
mluis 0:91d1a7783bb9 459 */
mluis 0:91d1a7783bb9 460 static uint8_t ChannelsNbRepCounter = 0;
mluis 0:91d1a7783bb9 461
mluis 0:91d1a7783bb9 462 /*!
mluis 0:91d1a7783bb9 463 * Maximum duty cycle
mluis 0:91d1a7783bb9 464 * \remark Possibility to shutdown the device.
mluis 0:91d1a7783bb9 465 */
mluis 0:91d1a7783bb9 466 static uint8_t MaxDCycle = 0;
mluis 0:91d1a7783bb9 467
mluis 0:91d1a7783bb9 468 /*!
mluis 2:14a5d6ad92d5 469 * Aggregated duty cycle management
mluis 0:91d1a7783bb9 470 */
mluis 0:91d1a7783bb9 471 static uint16_t AggregatedDCycle;
mluis 0:91d1a7783bb9 472 static TimerTime_t AggregatedLastTxDoneTime;
mluis 0:91d1a7783bb9 473 static TimerTime_t AggregatedTimeOff;
mluis 0:91d1a7783bb9 474
mluis 0:91d1a7783bb9 475 /*!
mluis 0:91d1a7783bb9 476 * Enables/Disables duty cycle management (Test only)
mluis 0:91d1a7783bb9 477 */
mluis 0:91d1a7783bb9 478 static bool DutyCycleOn;
mluis 0:91d1a7783bb9 479
mluis 0:91d1a7783bb9 480 /*!
mluis 0:91d1a7783bb9 481 * Current channel index
mluis 0:91d1a7783bb9 482 */
mluis 0:91d1a7783bb9 483 static uint8_t Channel;
mluis 0:91d1a7783bb9 484
mluis 0:91d1a7783bb9 485 /*!
mluis 0:91d1a7783bb9 486 * LoRaMac internal states
mluis 0:91d1a7783bb9 487 */
mluis 2:14a5d6ad92d5 488 enum eLoRaMacState
mluis 0:91d1a7783bb9 489 {
mluis 0:91d1a7783bb9 490 MAC_IDLE = 0x00000000,
mluis 0:91d1a7783bb9 491 MAC_TX_RUNNING = 0x00000001,
mluis 0:91d1a7783bb9 492 MAC_RX = 0x00000002,
mluis 0:91d1a7783bb9 493 MAC_ACK_REQ = 0x00000004,
mluis 0:91d1a7783bb9 494 MAC_ACK_RETRY = 0x00000008,
mluis 2:14a5d6ad92d5 495 MAC_TX_DELAYED = 0x00000010,
mluis 3:b9d87593a8ae 496 MAC_TX_CONFIG = 0x00000020,
mluis 0:91d1a7783bb9 497 };
mluis 0:91d1a7783bb9 498
mluis 0:91d1a7783bb9 499 /*!
mluis 0:91d1a7783bb9 500 * LoRaMac internal state
mluis 0:91d1a7783bb9 501 */
mluis 0:91d1a7783bb9 502 uint32_t LoRaMacState = MAC_IDLE;
mluis 0:91d1a7783bb9 503
mluis 0:91d1a7783bb9 504 /*!
mluis 0:91d1a7783bb9 505 * LoRaMac timer used to check the LoRaMacState (runs every second)
mluis 0:91d1a7783bb9 506 */
mluis 0:91d1a7783bb9 507 static TimerEvent_t MacStateCheckTimer;
mluis 0:91d1a7783bb9 508
mluis 0:91d1a7783bb9 509 /*!
mluis 0:91d1a7783bb9 510 * LoRaMac upper layer event functions
mluis 0:91d1a7783bb9 511 */
mluis 2:14a5d6ad92d5 512 static LoRaMacPrimitives_t *LoRaMacPrimitives;
mluis 0:91d1a7783bb9 513
mluis 0:91d1a7783bb9 514 /*!
mluis 2:14a5d6ad92d5 515 * LoRaMac upper layer callback functions
mluis 0:91d1a7783bb9 516 */
mluis 2:14a5d6ad92d5 517 static LoRaMacCallback_t *LoRaMacCallbacks;
mluis 0:91d1a7783bb9 518
mluis 0:91d1a7783bb9 519 /*!
mluis 2:14a5d6ad92d5 520 * Radio events function pointer
mluis 0:91d1a7783bb9 521 */
mluis 2:14a5d6ad92d5 522 static RadioEvents_t RadioEvents;
mluis 0:91d1a7783bb9 523
mluis 0:91d1a7783bb9 524 /*!
mluis 0:91d1a7783bb9 525 * LoRaMac duty cycle delayed Tx timer
mluis 0:91d1a7783bb9 526 */
mluis 0:91d1a7783bb9 527 static TimerEvent_t TxDelayedTimer;
mluis 0:91d1a7783bb9 528
mluis 0:91d1a7783bb9 529 /*!
mluis 0:91d1a7783bb9 530 * LoRaMac reception windows timers
mluis 0:91d1a7783bb9 531 */
mluis 0:91d1a7783bb9 532 static TimerEvent_t RxWindowTimer1;
mluis 0:91d1a7783bb9 533 static TimerEvent_t RxWindowTimer2;
mluis 0:91d1a7783bb9 534
mluis 0:91d1a7783bb9 535 /*!
mluis 0:91d1a7783bb9 536 * LoRaMac reception windows delay from end of Tx
mluis 0:91d1a7783bb9 537 */
mluis 0:91d1a7783bb9 538 static uint32_t ReceiveDelay1;
mluis 0:91d1a7783bb9 539 static uint32_t ReceiveDelay2;
mluis 0:91d1a7783bb9 540 static uint32_t JoinAcceptDelay1;
mluis 0:91d1a7783bb9 541 static uint32_t JoinAcceptDelay2;
mluis 0:91d1a7783bb9 542
mluis 0:91d1a7783bb9 543 /*!
mluis 0:91d1a7783bb9 544 * LoRaMac reception windows delay
mluis 0:91d1a7783bb9 545 * \remark normal frame: RxWindowXDelay = ReceiveDelayX - RADIO_WAKEUP_TIME
mluis 0:91d1a7783bb9 546 * join frame : RxWindowXDelay = JoinAcceptDelayX - RADIO_WAKEUP_TIME
mluis 0:91d1a7783bb9 547 */
mluis 0:91d1a7783bb9 548 static uint32_t RxWindow1Delay;
mluis 0:91d1a7783bb9 549 static uint32_t RxWindow2Delay;
mluis 0:91d1a7783bb9 550
mluis 0:91d1a7783bb9 551 /*!
mluis 0:91d1a7783bb9 552 * LoRaMac maximum time a reception window stays open
mluis 0:91d1a7783bb9 553 */
mluis 0:91d1a7783bb9 554 static uint32_t MaxRxWindow;
mluis 0:91d1a7783bb9 555
mluis 0:91d1a7783bb9 556 /*!
mluis 0:91d1a7783bb9 557 * Acknowledge timeout timer. Used for packet retransmissions.
mluis 0:91d1a7783bb9 558 */
mluis 0:91d1a7783bb9 559 static TimerEvent_t AckTimeoutTimer;
mluis 0:91d1a7783bb9 560
mluis 0:91d1a7783bb9 561 /*!
mluis 0:91d1a7783bb9 562 * Number of trials to get a frame acknowledged
mluis 0:91d1a7783bb9 563 */
mluis 0:91d1a7783bb9 564 static uint8_t AckTimeoutRetries = 1;
mluis 0:91d1a7783bb9 565
mluis 0:91d1a7783bb9 566 /*!
mluis 0:91d1a7783bb9 567 * Number of trials to get a frame acknowledged
mluis 0:91d1a7783bb9 568 */
mluis 0:91d1a7783bb9 569 static uint8_t AckTimeoutRetriesCounter = 1;
mluis 0:91d1a7783bb9 570
mluis 0:91d1a7783bb9 571 /*!
mluis 0:91d1a7783bb9 572 * Indicates if the AckTimeout timer has expired or not
mluis 0:91d1a7783bb9 573 */
mluis 0:91d1a7783bb9 574 static bool AckTimeoutRetry = false;
mluis 0:91d1a7783bb9 575
mluis 0:91d1a7783bb9 576 /*!
mluis 0:91d1a7783bb9 577 * Last transmission time on air
mluis 0:91d1a7783bb9 578 */
mluis 0:91d1a7783bb9 579 TimerTime_t TxTimeOnAir = 0;
mluis 0:91d1a7783bb9 580
mluis 0:91d1a7783bb9 581 /*!
mluis 2:14a5d6ad92d5 582 * Structure to hold an MCPS indication data.
mluis 2:14a5d6ad92d5 583 */
mluis 2:14a5d6ad92d5 584 static McpsIndication_t McpsIndication;
mluis 2:14a5d6ad92d5 585
mluis 2:14a5d6ad92d5 586 /*!
mluis 2:14a5d6ad92d5 587 * Structure to hold MCPS confirm data.
mluis 2:14a5d6ad92d5 588 */
mluis 2:14a5d6ad92d5 589 static McpsConfirm_t McpsConfirm;
mluis 2:14a5d6ad92d5 590
mluis 2:14a5d6ad92d5 591 /*!
mluis 2:14a5d6ad92d5 592 * Structure to hold MLME confirm data.
mluis 2:14a5d6ad92d5 593 */
mluis 2:14a5d6ad92d5 594 static MlmeConfirm_t MlmeConfirm;
mluis 2:14a5d6ad92d5 595
mluis 2:14a5d6ad92d5 596 /*!
mluis 2:14a5d6ad92d5 597 * Holds the current rx window slot
mluis 2:14a5d6ad92d5 598 */
mluis 2:14a5d6ad92d5 599 static uint8_t RxSlot = 0;
mluis 2:14a5d6ad92d5 600
mluis 2:14a5d6ad92d5 601 /*!
mluis 2:14a5d6ad92d5 602 * LoRaMac tx/rx operation state
mluis 2:14a5d6ad92d5 603 */
mluis 2:14a5d6ad92d5 604 LoRaMacFlags_t LoRaMacFlags;
mluis 2:14a5d6ad92d5 605
mluis 2:14a5d6ad92d5 606 /*!
mluis 2:14a5d6ad92d5 607 * \brief Function to be executed on Radio Tx Done event
mluis 0:91d1a7783bb9 608 */
mluis 0:91d1a7783bb9 609 static void OnRadioTxDone( void );
mluis 0:91d1a7783bb9 610
mluis 0:91d1a7783bb9 611 /*!
mluis 3:b9d87593a8ae 612 * \brief This function prepares the MAC to abort the execution of function
mluis 3:b9d87593a8ae 613 * OnRadioRxDone in case of a reception error.
mluis 3:b9d87593a8ae 614 */
mluis 3:b9d87593a8ae 615 static void PrepareRxDoneAbort( void );
mluis 3:b9d87593a8ae 616
mluis 3:b9d87593a8ae 617 /*!
mluis 2:14a5d6ad92d5 618 * \brief Function to be executed on Radio Rx Done event
mluis 0:91d1a7783bb9 619 */
mluis 0:91d1a7783bb9 620 static void OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr );
mluis 0:91d1a7783bb9 621
mluis 0:91d1a7783bb9 622 /*!
mluis 2:14a5d6ad92d5 623 * \brief Function executed on Radio Tx Timeout event
mluis 0:91d1a7783bb9 624 */
mluis 0:91d1a7783bb9 625 static void OnRadioTxTimeout( void );
mluis 0:91d1a7783bb9 626
mluis 0:91d1a7783bb9 627 /*!
mluis 2:14a5d6ad92d5 628 * \brief Function executed on Radio Rx error event
mluis 0:91d1a7783bb9 629 */
mluis 0:91d1a7783bb9 630 static void OnRadioRxError( void );
mluis 0:91d1a7783bb9 631
mluis 0:91d1a7783bb9 632 /*!
mluis 2:14a5d6ad92d5 633 * \brief Function executed on Radio Rx Timeout event
mluis 0:91d1a7783bb9 634 */
mluis 0:91d1a7783bb9 635 static void OnRadioRxTimeout( void );
mluis 0:91d1a7783bb9 636
mluis 0:91d1a7783bb9 637 /*!
mluis 2:14a5d6ad92d5 638 * \brief Function executed on Resend Frame timer event.
mluis 0:91d1a7783bb9 639 */
mluis 0:91d1a7783bb9 640 static void OnMacStateCheckTimerEvent( void );
mluis 0:91d1a7783bb9 641
mluis 0:91d1a7783bb9 642 /*!
mluis 2:14a5d6ad92d5 643 * \brief Function executed on duty cycle delayed Tx timer event
mluis 0:91d1a7783bb9 644 */
mluis 0:91d1a7783bb9 645 static void OnTxDelayedTimerEvent( void );
mluis 0:91d1a7783bb9 646
mluis 0:91d1a7783bb9 647 /*!
mluis 2:14a5d6ad92d5 648 * \brief Function executed on first Rx window timer event
mluis 0:91d1a7783bb9 649 */
mluis 0:91d1a7783bb9 650 static void OnRxWindow1TimerEvent( void );
mluis 0:91d1a7783bb9 651
mluis 0:91d1a7783bb9 652 /*!
mluis 2:14a5d6ad92d5 653 * \brief Function executed on second Rx window timer event
mluis 0:91d1a7783bb9 654 */
mluis 0:91d1a7783bb9 655 static void OnRxWindow2TimerEvent( void );
mluis 0:91d1a7783bb9 656
mluis 0:91d1a7783bb9 657 /*!
mluis 2:14a5d6ad92d5 658 * \brief Function executed on AckTimeout timer event
mluis 0:91d1a7783bb9 659 */
mluis 0:91d1a7783bb9 660 static void OnAckTimeoutTimerEvent( void );
mluis 0:91d1a7783bb9 661
mluis 0:91d1a7783bb9 662 /*!
mluis 2:14a5d6ad92d5 663 * \brief Searches and set the next random available channel
mluis 2:14a5d6ad92d5 664 *
mluis 3:b9d87593a8ae 665 * \param [OUT] Time to wait for the next transmission according to the duty
mluis 3:b9d87593a8ae 666 * cycle.
mluis 3:b9d87593a8ae 667 *
mluis 3:b9d87593a8ae 668 * \retval status Function status [1: OK, 0: Unable to find a channel on the
mluis 3:b9d87593a8ae 669 * current datarate]
mluis 2:14a5d6ad92d5 670 */
mluis 3:b9d87593a8ae 671 static bool SetNextChannel( TimerTime_t* time );
mluis 2:14a5d6ad92d5 672
mluis 2:14a5d6ad92d5 673 /*!
mluis 2:14a5d6ad92d5 674 * \brief Sets the network to public or private. Updates the sync byte.
mluis 2:14a5d6ad92d5 675 *
mluis 2:14a5d6ad92d5 676 * \param [IN] enable if true, it enables a public network
mluis 2:14a5d6ad92d5 677 */
mluis 2:14a5d6ad92d5 678 static void SetPublicNetwork( bool enable );
mluis 2:14a5d6ad92d5 679
mluis 2:14a5d6ad92d5 680 /*!
mluis 2:14a5d6ad92d5 681 * \brief Initializes and opens the reception window
mluis 2:14a5d6ad92d5 682 *
mluis 2:14a5d6ad92d5 683 * \param [IN] freq window channel frequency
mluis 2:14a5d6ad92d5 684 * \param [IN] datarate window channel datarate
mluis 2:14a5d6ad92d5 685 * \param [IN] bandwidth window channel bandwidth
mluis 2:14a5d6ad92d5 686 * \param [IN] timeout window channel timeout
mluis 0:91d1a7783bb9 687 */
mluis 2:14a5d6ad92d5 688 static void RxWindowSetup( uint32_t freq, int8_t datarate, uint32_t bandwidth, uint16_t timeout, bool rxContinuous );
mluis 2:14a5d6ad92d5 689
mluis 2:14a5d6ad92d5 690 /*!
mluis 2:14a5d6ad92d5 691 * \brief Adds a new MAC command to be sent.
mluis 2:14a5d6ad92d5 692 *
mluis 2:14a5d6ad92d5 693 * \Remark MAC layer internal function
mluis 2:14a5d6ad92d5 694 *
mluis 2:14a5d6ad92d5 695 * \param [in] cmd MAC command to be added
mluis 2:14a5d6ad92d5 696 * [MOTE_MAC_LINK_CHECK_REQ,
mluis 2:14a5d6ad92d5 697 * MOTE_MAC_LINK_ADR_ANS,
mluis 2:14a5d6ad92d5 698 * MOTE_MAC_DUTY_CYCLE_ANS,
mluis 2:14a5d6ad92d5 699 * MOTE_MAC_RX2_PARAM_SET_ANS,
mluis 2:14a5d6ad92d5 700 * MOTE_MAC_DEV_STATUS_ANS
mluis 2:14a5d6ad92d5 701 * MOTE_MAC_NEW_CHANNEL_ANS]
mluis 2:14a5d6ad92d5 702 * \param [in] p1 1st parameter ( optional depends on the command )
mluis 2:14a5d6ad92d5 703 * \param [in] p2 2nd parameter ( optional depends on the command )
mluis 2:14a5d6ad92d5 704 *
mluis 2:14a5d6ad92d5 705 * \retval status Function status [0: OK, 1: Unknown command, 2: Buffer full]
mluis 2:14a5d6ad92d5 706 */
mluis 2:14a5d6ad92d5 707 static LoRaMacStatus_t AddMacCommand( uint8_t cmd, uint8_t p1, uint8_t p2 );
mluis 0:91d1a7783bb9 708
mluis 0:91d1a7783bb9 709 /*!
mluis 0:91d1a7783bb9 710 * \brief Validates if the payload fits into the frame, taking the datarate
mluis 0:91d1a7783bb9 711 * into account.
mluis 0:91d1a7783bb9 712 *
mluis 0:91d1a7783bb9 713 * \details Refer to chapter 4.3.2 of the LoRaWAN specification, v1.0
mluis 0:91d1a7783bb9 714 *
mluis 0:91d1a7783bb9 715 * \param lenN Length of the application payload. The length depends on the
mluis 0:91d1a7783bb9 716 * datarate and is region specific
mluis 0:91d1a7783bb9 717 *
mluis 0:91d1a7783bb9 718 * \param datarate Current datarate
mluis 0:91d1a7783bb9 719 *
mluis 2:14a5d6ad92d5 720 * \param fOptsLen Length of the fOpts field
mluis 2:14a5d6ad92d5 721 *
mluis 0:91d1a7783bb9 722 * \retval [false: payload does not fit into the frame, true: payload fits into
mluis 0:91d1a7783bb9 723 * the frame]
mluis 0:91d1a7783bb9 724 */
mluis 2:14a5d6ad92d5 725 static bool ValidatePayloadLength( uint8_t lenN, int8_t datarate, uint8_t fOptsLen );
mluis 0:91d1a7783bb9 726
mluis 0:91d1a7783bb9 727 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 0:91d1a7783bb9 728 /*!
mluis 0:91d1a7783bb9 729 * \brief Counts the number of enabled 125 kHz channels in the channel mask.
mluis 0:91d1a7783bb9 730 * This function can only be applied to US915 band.
mluis 0:91d1a7783bb9 731 *
mluis 0:91d1a7783bb9 732 * \param channelsMask Pointer to the first element of the channel mask
mluis 0:91d1a7783bb9 733 *
mluis 0:91d1a7783bb9 734 * \retval Number of enabled channels in the channel mask
mluis 0:91d1a7783bb9 735 */
mluis 0:91d1a7783bb9 736 static uint8_t CountNbEnabled125kHzChannels( uint16_t *channelsMask );
mluis 0:91d1a7783bb9 737 #endif
mluis 0:91d1a7783bb9 738
mluis 0:91d1a7783bb9 739 /*!
mluis 0:91d1a7783bb9 740 * \brief Limits the Tx power according to the number of enabled channels
mluis 0:91d1a7783bb9 741 *
mluis 0:91d1a7783bb9 742 * \retval Returns the maximum valid tx power
mluis 0:91d1a7783bb9 743 */
mluis 0:91d1a7783bb9 744 static int8_t LimitTxPower( int8_t txPower );
mluis 0:91d1a7783bb9 745
mluis 0:91d1a7783bb9 746 /*!
mluis 2:14a5d6ad92d5 747 * \brief Verifies, if a value is in a given range.
mluis 2:14a5d6ad92d5 748 *
mluis 2:14a5d6ad92d5 749 * \param value Value to verify, if it is in range
mluis 2:14a5d6ad92d5 750 *
mluis 2:14a5d6ad92d5 751 * \param min Minimum possible value
mluis 2:14a5d6ad92d5 752 *
mluis 2:14a5d6ad92d5 753 * \param max Maximum possible value
mluis 2:14a5d6ad92d5 754 *
mluis 2:14a5d6ad92d5 755 * \retval Returns the maximum valid tx power
mluis 2:14a5d6ad92d5 756 */
mluis 2:14a5d6ad92d5 757 static bool ValueInRange( int8_t value, int8_t min, int8_t max );
mluis 2:14a5d6ad92d5 758
mluis 2:14a5d6ad92d5 759 /*!
mluis 2:14a5d6ad92d5 760 * \brief Calculates the next datarate to set, when ADR is on or off
mluis 2:14a5d6ad92d5 761 *
mluis 2:14a5d6ad92d5 762 * \param [IN] adrEnabled Specify whether ADR is on or off
mluis 2:14a5d6ad92d5 763 *
mluis 2:14a5d6ad92d5 764 * \param [IN] updateChannelMask Set to true, if the channel masks shall be updated
mluis 2:14a5d6ad92d5 765 *
mluis 2:14a5d6ad92d5 766 * \param [OUT] datarateOut Reports the datarate which will be used next
mluis 2:14a5d6ad92d5 767 *
mluis 2:14a5d6ad92d5 768 * \retval Returns the state of ADR ack request
mluis 2:14a5d6ad92d5 769 */
mluis 2:14a5d6ad92d5 770 static bool AdrNextDr( bool adrEnabled, bool updateChannelMask, int8_t* datarateOut );
mluis 2:14a5d6ad92d5 771
mluis 2:14a5d6ad92d5 772 /*!
mluis 2:14a5d6ad92d5 773 * \brief Disables channel in a specified channel mask
mluis 2:14a5d6ad92d5 774 *
mluis 2:14a5d6ad92d5 775 * \param [IN] id - Id of the channel
mluis 2:14a5d6ad92d5 776 *
mluis 2:14a5d6ad92d5 777 * \param [IN] mask - Pointer to the channel mask to edit
mluis 0:91d1a7783bb9 778 *
mluis 2:14a5d6ad92d5 779 * \retval [true, if disable was successful, false if not]
mluis 2:14a5d6ad92d5 780 */
mluis 2:14a5d6ad92d5 781 static bool DisableChannelInMask( uint8_t id, uint16_t* mask );
mluis 2:14a5d6ad92d5 782
mluis 2:14a5d6ad92d5 783 /*!
mluis 2:14a5d6ad92d5 784 * \brief Decodes MAC commands in the fOpts field and in the payload
mluis 2:14a5d6ad92d5 785 */
mluis 2:14a5d6ad92d5 786 static void ProcessMacCommands( uint8_t *payload, uint8_t macIndex, uint8_t commandsSize, uint8_t snr );
mluis 2:14a5d6ad92d5 787
mluis 2:14a5d6ad92d5 788 /*!
mluis 2:14a5d6ad92d5 789 * \brief LoRaMAC layer generic send frame
mluis 2:14a5d6ad92d5 790 *
mluis 2:14a5d6ad92d5 791 * \param [IN] macHdr MAC header field
mluis 2:14a5d6ad92d5 792 * \param [IN] fPort MAC payload port
mluis 2:14a5d6ad92d5 793 * \param [IN] fBuffer MAC data buffer to be sent
mluis 2:14a5d6ad92d5 794 * \param [IN] fBufferSize MAC data buffer size
mluis 2:14a5d6ad92d5 795 * \retval status Status of the operation.
mluis 2:14a5d6ad92d5 796 */
mluis 2:14a5d6ad92d5 797 LoRaMacStatus_t Send( LoRaMacHeader_t *macHdr, uint8_t fPort, void *fBuffer, uint16_t fBufferSize );
mluis 2:14a5d6ad92d5 798
mluis 2:14a5d6ad92d5 799 /*!
mluis 2:14a5d6ad92d5 800 * \brief LoRaMAC layer frame buffer initialization
mluis 2:14a5d6ad92d5 801 *
mluis 2:14a5d6ad92d5 802 * \param [IN] macHdr MAC header field
mluis 2:14a5d6ad92d5 803 * \param [IN] fCtrl MAC frame control field
mluis 2:14a5d6ad92d5 804 * \param [IN] fOpts MAC commands buffer
mluis 2:14a5d6ad92d5 805 * \param [IN] fPort MAC payload port
mluis 2:14a5d6ad92d5 806 * \param [IN] fBuffer MAC data buffer to be sent
mluis 2:14a5d6ad92d5 807 * \param [IN] fBufferSize MAC data buffer size
mluis 2:14a5d6ad92d5 808 * \retval status Status of the operation.
mluis 2:14a5d6ad92d5 809 */
mluis 2:14a5d6ad92d5 810 LoRaMacStatus_t PrepareFrame( LoRaMacHeader_t *macHdr, LoRaMacFrameCtrl_t *fCtrl, uint8_t fPort, void *fBuffer, uint16_t fBufferSize );
mluis 2:14a5d6ad92d5 811
mluis 2:14a5d6ad92d5 812 /*
mluis 2:14a5d6ad92d5 813 * \brief Schedules the frame according to the duty cycle
mluis 2:14a5d6ad92d5 814 *
mluis 2:14a5d6ad92d5 815 * \retval Status of the operation
mluis 2:14a5d6ad92d5 816 */
mluis 2:14a5d6ad92d5 817 static LoRaMacStatus_t ScheduleTx( void );
mluis 2:14a5d6ad92d5 818
mluis 2:14a5d6ad92d5 819 /*!
mluis 2:14a5d6ad92d5 820 * \brief LoRaMAC layer prepared frame buffer transmission with channel specification
mluis 2:14a5d6ad92d5 821 *
mluis 2:14a5d6ad92d5 822 * \remark PrepareFrame must be called at least once before calling this
mluis 2:14a5d6ad92d5 823 * function.
mluis 2:14a5d6ad92d5 824 *
mluis 2:14a5d6ad92d5 825 * \param [IN] channel Channel parameters
mluis 2:14a5d6ad92d5 826 * \retval status Status of the operation.
mluis 0:91d1a7783bb9 827 */
mluis 2:14a5d6ad92d5 828 LoRaMacStatus_t SendFrameOnChannel( ChannelParams_t channel );
mluis 2:14a5d6ad92d5 829
mluis 2:14a5d6ad92d5 830
mluis 2:14a5d6ad92d5 831
mluis 2:14a5d6ad92d5 832 static void OnRadioTxDone( void )
mluis 2:14a5d6ad92d5 833 {
mluis 2:14a5d6ad92d5 834 TimerTime_t curTime = TimerGetCurrentTime( );
mluis 2:14a5d6ad92d5 835 if( LoRaMacDeviceClass != CLASS_C )
mluis 2:14a5d6ad92d5 836 {
mluis 2:14a5d6ad92d5 837 Radio.Sleep( );
mluis 2:14a5d6ad92d5 838 }
mluis 2:14a5d6ad92d5 839 else
mluis 2:14a5d6ad92d5 840 {
mluis 2:14a5d6ad92d5 841 OnRxWindow2TimerEvent( );
mluis 2:14a5d6ad92d5 842 }
mluis 2:14a5d6ad92d5 843
mluis 2:14a5d6ad92d5 844 // Update Band Time OFF
mluis 2:14a5d6ad92d5 845 Bands[Channels[Channel].Band].LastTxDoneTime = curTime;
mluis 2:14a5d6ad92d5 846 if( DutyCycleOn == true )
mluis 2:14a5d6ad92d5 847 {
mluis 2:14a5d6ad92d5 848 Bands[Channels[Channel].Band].TimeOff = TxTimeOnAir * Bands[Channels[Channel].Band].DCycle - TxTimeOnAir;
mluis 2:14a5d6ad92d5 849 }
mluis 2:14a5d6ad92d5 850 else
mluis 2:14a5d6ad92d5 851 {
mluis 2:14a5d6ad92d5 852 Bands[Channels[Channel].Band].TimeOff = 0;
mluis 2:14a5d6ad92d5 853 }
mluis 2:14a5d6ad92d5 854 // Update Aggregated Time OFF
mluis 2:14a5d6ad92d5 855 AggregatedLastTxDoneTime = curTime;
mluis 2:14a5d6ad92d5 856 AggregatedTimeOff = AggregatedTimeOff + ( TxTimeOnAir * AggregatedDCycle - TxTimeOnAir );
mluis 2:14a5d6ad92d5 857
mluis 2:14a5d6ad92d5 858 if( IsRxWindowsEnabled == true )
mluis 2:14a5d6ad92d5 859 {
mluis 2:14a5d6ad92d5 860 TimerSetValue( &RxWindowTimer1, RxWindow1Delay );
mluis 2:14a5d6ad92d5 861 TimerStart( &RxWindowTimer1 );
mluis 2:14a5d6ad92d5 862 if( LoRaMacDeviceClass != CLASS_C )
mluis 2:14a5d6ad92d5 863 {
mluis 2:14a5d6ad92d5 864 TimerSetValue( &RxWindowTimer2, RxWindow2Delay );
mluis 2:14a5d6ad92d5 865 TimerStart( &RxWindowTimer2 );
mluis 2:14a5d6ad92d5 866 }
mluis 2:14a5d6ad92d5 867 if( ( LoRaMacDeviceClass == CLASS_C ) || ( NodeAckRequested == true ) )
mluis 2:14a5d6ad92d5 868 {
mluis 2:14a5d6ad92d5 869 TimerSetValue( &AckTimeoutTimer, RxWindow2Delay + ACK_TIMEOUT +
mluis 2:14a5d6ad92d5 870 randr( -ACK_TIMEOUT_RND, ACK_TIMEOUT_RND ) );
mluis 2:14a5d6ad92d5 871 TimerStart( &AckTimeoutTimer );
mluis 2:14a5d6ad92d5 872 }
mluis 2:14a5d6ad92d5 873 }
mluis 2:14a5d6ad92d5 874 else
mluis 2:14a5d6ad92d5 875 {
mluis 2:14a5d6ad92d5 876 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK;
mluis 2:14a5d6ad92d5 877 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT;
mluis 2:14a5d6ad92d5 878
mluis 2:14a5d6ad92d5 879 if( LoRaMacFlags.Value == 0 )
mluis 2:14a5d6ad92d5 880 {
mluis 2:14a5d6ad92d5 881 LoRaMacFlags.Bits.McpsReq = 1;
mluis 2:14a5d6ad92d5 882 }
mluis 2:14a5d6ad92d5 883 LoRaMacFlags.Bits.MacDone = 1;
mluis 2:14a5d6ad92d5 884 }
mluis 2:14a5d6ad92d5 885
mluis 2:14a5d6ad92d5 886 if( NodeAckRequested == false )
mluis 2:14a5d6ad92d5 887 {
mluis 2:14a5d6ad92d5 888 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK;
mluis 2:14a5d6ad92d5 889 ChannelsNbRepCounter++;
mluis 2:14a5d6ad92d5 890 }
mluis 2:14a5d6ad92d5 891 }
mluis 2:14a5d6ad92d5 892
mluis 3:b9d87593a8ae 893 static void PrepareRxDoneAbort( void )
mluis 3:b9d87593a8ae 894 {
mluis 3:b9d87593a8ae 895 LoRaMacState &= ~MAC_TX_RUNNING;
mluis 3:b9d87593a8ae 896
mluis 3:b9d87593a8ae 897 if( NodeAckRequested )
mluis 3:b9d87593a8ae 898 {
mluis 3:b9d87593a8ae 899 OnAckTimeoutTimerEvent( );
mluis 3:b9d87593a8ae 900 }
mluis 3:b9d87593a8ae 901
mluis 3:b9d87593a8ae 902 if( ( RxSlot == 0 ) && ( LoRaMacDeviceClass == CLASS_C ) )
mluis 3:b9d87593a8ae 903 {
mluis 3:b9d87593a8ae 904 OnRxWindow2TimerEvent( );
mluis 3:b9d87593a8ae 905 }
mluis 3:b9d87593a8ae 906
mluis 3:b9d87593a8ae 907 LoRaMacFlags.Bits.McpsInd = 1;
mluis 3:b9d87593a8ae 908 LoRaMacFlags.Bits.MacDone = 1;
mluis 3:b9d87593a8ae 909
mluis 3:b9d87593a8ae 910 // Trig OnMacCheckTimerEvent call as soon as possible
mluis 3:b9d87593a8ae 911 TimerSetValue( &MacStateCheckTimer, 1000 );
mluis 3:b9d87593a8ae 912 TimerStart( &MacStateCheckTimer );
mluis 3:b9d87593a8ae 913 }
mluis 3:b9d87593a8ae 914
mluis 2:14a5d6ad92d5 915 static void OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr )
mluis 0:91d1a7783bb9 916 {
mluis 2:14a5d6ad92d5 917 LoRaMacHeader_t macHdr;
mluis 2:14a5d6ad92d5 918 LoRaMacFrameCtrl_t fCtrl;
mluis 2:14a5d6ad92d5 919
mluis 2:14a5d6ad92d5 920 uint8_t pktHeaderLen = 0;
mluis 2:14a5d6ad92d5 921 uint32_t address = 0;
mluis 2:14a5d6ad92d5 922 uint8_t appPayloadStartIndex = 0;
mluis 2:14a5d6ad92d5 923 uint8_t port = 0xFF;
mluis 2:14a5d6ad92d5 924 uint8_t frameLen = 0;
mluis 2:14a5d6ad92d5 925 uint32_t mic = 0;
mluis 2:14a5d6ad92d5 926 uint32_t micRx = 0;
mluis 2:14a5d6ad92d5 927
mluis 2:14a5d6ad92d5 928 uint16_t sequenceCounter = 0;
mluis 2:14a5d6ad92d5 929 uint16_t sequenceCounterPrev = 0;
mluis 2:14a5d6ad92d5 930 uint16_t sequenceCounterDiff = 0;
mluis 2:14a5d6ad92d5 931 uint32_t downLinkCounter = 0;
mluis 2:14a5d6ad92d5 932
mluis 2:14a5d6ad92d5 933 MulticastParams_t *curMulticastParams = NULL;
mluis 2:14a5d6ad92d5 934 uint8_t *nwkSKey = LoRaMacNwkSKey;
mluis 2:14a5d6ad92d5 935 uint8_t *appSKey = LoRaMacAppSKey;
mluis 2:14a5d6ad92d5 936
mluis 2:14a5d6ad92d5 937 uint8_t multicast = 0;
mluis 2:14a5d6ad92d5 938
mluis 2:14a5d6ad92d5 939 bool isMicOk = false;
mluis 2:14a5d6ad92d5 940
mluis 2:14a5d6ad92d5 941 McpsConfirm.AckReceived = false;
mluis 2:14a5d6ad92d5 942 McpsIndication.Rssi = rssi;
mluis 2:14a5d6ad92d5 943 McpsIndication.Snr = snr;
mluis 2:14a5d6ad92d5 944 McpsIndication.RxSlot = RxSlot;
mluis 2:14a5d6ad92d5 945 McpsIndication.Port = 0;
mluis 2:14a5d6ad92d5 946 McpsIndication.Multicast = 0;
mluis 2:14a5d6ad92d5 947 McpsIndication.FramePending = 0;
mluis 2:14a5d6ad92d5 948 McpsIndication.Buffer = NULL;
mluis 2:14a5d6ad92d5 949 McpsIndication.BufferSize = 0;
mluis 2:14a5d6ad92d5 950 McpsIndication.RxData = false;
mluis 2:14a5d6ad92d5 951 McpsIndication.AckReceived = false;
mluis 2:14a5d6ad92d5 952 McpsIndication.DownLinkCounter = 0;
mluis 2:14a5d6ad92d5 953 McpsIndication.McpsIndication = MCPS_UNCONFIRMED;
mluis 2:14a5d6ad92d5 954
mluis 2:14a5d6ad92d5 955 if( LoRaMacDeviceClass != CLASS_C )
mluis 2:14a5d6ad92d5 956 {
mluis 2:14a5d6ad92d5 957 Radio.Sleep( );
mluis 2:14a5d6ad92d5 958 }
mluis 2:14a5d6ad92d5 959 TimerStop( &RxWindowTimer2 );
mluis 2:14a5d6ad92d5 960
mluis 2:14a5d6ad92d5 961 macHdr.Value = payload[pktHeaderLen++];
mluis 2:14a5d6ad92d5 962
mluis 2:14a5d6ad92d5 963 switch( macHdr.Bits.MType )
mluis 2:14a5d6ad92d5 964 {
mluis 2:14a5d6ad92d5 965 case FRAME_TYPE_JOIN_ACCEPT:
mluis 2:14a5d6ad92d5 966 if( IsLoRaMacNetworkJoined == true )
mluis 2:14a5d6ad92d5 967 {
mluis 2:14a5d6ad92d5 968 break;
mluis 2:14a5d6ad92d5 969 }
mluis 2:14a5d6ad92d5 970 LoRaMacJoinDecrypt( payload + 1, size - 1, LoRaMacAppKey, LoRaMacRxPayload + 1 );
mluis 2:14a5d6ad92d5 971
mluis 2:14a5d6ad92d5 972 LoRaMacRxPayload[0] = macHdr.Value;
mluis 2:14a5d6ad92d5 973
mluis 2:14a5d6ad92d5 974 LoRaMacJoinComputeMic( LoRaMacRxPayload, size - LORAMAC_MFR_LEN, LoRaMacAppKey, &mic );
mluis 2:14a5d6ad92d5 975
mluis 2:14a5d6ad92d5 976 micRx |= ( uint32_t )LoRaMacRxPayload[size - LORAMAC_MFR_LEN];
mluis 2:14a5d6ad92d5 977 micRx |= ( ( uint32_t )LoRaMacRxPayload[size - LORAMAC_MFR_LEN + 1] << 8 );
mluis 2:14a5d6ad92d5 978 micRx |= ( ( uint32_t )LoRaMacRxPayload[size - LORAMAC_MFR_LEN + 2] << 16 );
mluis 2:14a5d6ad92d5 979 micRx |= ( ( uint32_t )LoRaMacRxPayload[size - LORAMAC_MFR_LEN + 3] << 24 );
mluis 2:14a5d6ad92d5 980
mluis 2:14a5d6ad92d5 981 if( micRx == mic )
mluis 2:14a5d6ad92d5 982 {
mluis 2:14a5d6ad92d5 983 LoRaMacJoinComputeSKeys( LoRaMacAppKey, LoRaMacRxPayload + 1, LoRaMacDevNonce, LoRaMacNwkSKey, LoRaMacAppSKey );
mluis 2:14a5d6ad92d5 984
mluis 2:14a5d6ad92d5 985 LoRaMacNetID = ( uint32_t )LoRaMacRxPayload[4];
mluis 2:14a5d6ad92d5 986 LoRaMacNetID |= ( ( uint32_t )LoRaMacRxPayload[5] << 8 );
mluis 2:14a5d6ad92d5 987 LoRaMacNetID |= ( ( uint32_t )LoRaMacRxPayload[6] << 16 );
mluis 2:14a5d6ad92d5 988
mluis 2:14a5d6ad92d5 989 LoRaMacDevAddr = ( uint32_t )LoRaMacRxPayload[7];
mluis 2:14a5d6ad92d5 990 LoRaMacDevAddr |= ( ( uint32_t )LoRaMacRxPayload[8] << 8 );
mluis 2:14a5d6ad92d5 991 LoRaMacDevAddr |= ( ( uint32_t )LoRaMacRxPayload[9] << 16 );
mluis 2:14a5d6ad92d5 992 LoRaMacDevAddr |= ( ( uint32_t )LoRaMacRxPayload[10] << 24 );
mluis 2:14a5d6ad92d5 993
mluis 2:14a5d6ad92d5 994 // DLSettings
mluis 2:14a5d6ad92d5 995 Rx1DrOffset = ( LoRaMacRxPayload[11] >> 4 ) & 0x07;
mluis 2:14a5d6ad92d5 996 Rx2Channel.Datarate = LoRaMacRxPayload[11] & 0x0F;
mluis 2:14a5d6ad92d5 997 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 2:14a5d6ad92d5 998 /*
mluis 2:14a5d6ad92d5 999 * WARNING: To be removed once Semtech server implementation
mluis 2:14a5d6ad92d5 1000 * is corrected.
mluis 2:14a5d6ad92d5 1001 */
mluis 2:14a5d6ad92d5 1002 if( Rx2Channel.Datarate == DR_3 )
mluis 2:14a5d6ad92d5 1003 {
mluis 2:14a5d6ad92d5 1004 Rx2Channel.Datarate = DR_8;
mluis 2:14a5d6ad92d5 1005 }
mluis 2:14a5d6ad92d5 1006 #endif
mluis 2:14a5d6ad92d5 1007 // RxDelay
mluis 2:14a5d6ad92d5 1008 ReceiveDelay1 = ( LoRaMacRxPayload[12] & 0x0F );
mluis 2:14a5d6ad92d5 1009 if( ReceiveDelay1 == 0 )
mluis 2:14a5d6ad92d5 1010 {
mluis 2:14a5d6ad92d5 1011 ReceiveDelay1 = 1;
mluis 2:14a5d6ad92d5 1012 }
mluis 2:14a5d6ad92d5 1013 ReceiveDelay1 *= 1e6;
mluis 2:14a5d6ad92d5 1014 ReceiveDelay2 = ReceiveDelay1 + 1e6;
mluis 2:14a5d6ad92d5 1015
mluis 2:14a5d6ad92d5 1016 #if !( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) )
mluis 2:14a5d6ad92d5 1017 //CFList
mluis 2:14a5d6ad92d5 1018 if( ( size - 1 ) > 16 )
mluis 2:14a5d6ad92d5 1019 {
mluis 2:14a5d6ad92d5 1020 ChannelParams_t param;
mluis 2:14a5d6ad92d5 1021 param.DrRange.Value = ( DR_5 << 4 ) | DR_0;
mluis 2:14a5d6ad92d5 1022
mluis 3:b9d87593a8ae 1023 LoRaMacState |= MAC_TX_CONFIG;
mluis 2:14a5d6ad92d5 1024 for( uint8_t i = 3, j = 0; i < ( 5 + 3 ); i++, j += 3 )
mluis 2:14a5d6ad92d5 1025 {
mluis 2:14a5d6ad92d5 1026 param.Frequency = ( ( uint32_t )LoRaMacRxPayload[13 + j] | ( ( uint32_t )LoRaMacRxPayload[14 + j] << 8 ) | ( ( uint32_t )LoRaMacRxPayload[15 + j] << 16 ) ) * 100;
mluis 2:14a5d6ad92d5 1027 LoRaMacChannelAdd( i, param );
mluis 2:14a5d6ad92d5 1028 }
mluis 3:b9d87593a8ae 1029 LoRaMacState &= ~MAC_TX_CONFIG;
mluis 2:14a5d6ad92d5 1030 }
mluis 2:14a5d6ad92d5 1031 #endif
mluis 2:14a5d6ad92d5 1032 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK;
mluis 2:14a5d6ad92d5 1033 IsLoRaMacNetworkJoined = true;
mluis 2:14a5d6ad92d5 1034 ChannelsDatarate = ChannelsDefaultDatarate;
mluis 2:14a5d6ad92d5 1035 }
mluis 2:14a5d6ad92d5 1036 else
mluis 2:14a5d6ad92d5 1037 {
mluis 2:14a5d6ad92d5 1038 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL;
mluis 2:14a5d6ad92d5 1039 }
mluis 2:14a5d6ad92d5 1040 break;
mluis 2:14a5d6ad92d5 1041 case FRAME_TYPE_DATA_CONFIRMED_DOWN:
mluis 2:14a5d6ad92d5 1042 case FRAME_TYPE_DATA_UNCONFIRMED_DOWN:
mluis 2:14a5d6ad92d5 1043 {
mluis 2:14a5d6ad92d5 1044 address = payload[pktHeaderLen++];
mluis 2:14a5d6ad92d5 1045 address |= ( (uint32_t)payload[pktHeaderLen++] << 8 );
mluis 2:14a5d6ad92d5 1046 address |= ( (uint32_t)payload[pktHeaderLen++] << 16 );
mluis 2:14a5d6ad92d5 1047 address |= ( (uint32_t)payload[pktHeaderLen++] << 24 );
mluis 2:14a5d6ad92d5 1048
mluis 2:14a5d6ad92d5 1049 if( address != LoRaMacDevAddr )
mluis 2:14a5d6ad92d5 1050 {
mluis 2:14a5d6ad92d5 1051 curMulticastParams = MulticastChannels;
mluis 2:14a5d6ad92d5 1052 while( curMulticastParams != NULL )
mluis 2:14a5d6ad92d5 1053 {
mluis 2:14a5d6ad92d5 1054 if( address == curMulticastParams->Address )
mluis 2:14a5d6ad92d5 1055 {
mluis 2:14a5d6ad92d5 1056 multicast = 1;
mluis 2:14a5d6ad92d5 1057 nwkSKey = curMulticastParams->NwkSKey;
mluis 2:14a5d6ad92d5 1058 appSKey = curMulticastParams->AppSKey;
mluis 2:14a5d6ad92d5 1059 downLinkCounter = curMulticastParams->DownLinkCounter;
mluis 2:14a5d6ad92d5 1060 break;
mluis 2:14a5d6ad92d5 1061 }
mluis 2:14a5d6ad92d5 1062 curMulticastParams = curMulticastParams->Next;
mluis 2:14a5d6ad92d5 1063 }
mluis 2:14a5d6ad92d5 1064 if( multicast == 0 )
mluis 2:14a5d6ad92d5 1065 {
mluis 2:14a5d6ad92d5 1066 // We are not the destination of this frame.
mluis 2:14a5d6ad92d5 1067 McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_ADDRESS_FAIL;
mluis 3:b9d87593a8ae 1068 PrepareRxDoneAbort( );
mluis 2:14a5d6ad92d5 1069 return;
mluis 2:14a5d6ad92d5 1070 }
mluis 2:14a5d6ad92d5 1071 }
mluis 2:14a5d6ad92d5 1072 else
mluis 2:14a5d6ad92d5 1073 {
mluis 2:14a5d6ad92d5 1074 multicast = 0;
mluis 2:14a5d6ad92d5 1075 nwkSKey = LoRaMacNwkSKey;
mluis 2:14a5d6ad92d5 1076 appSKey = LoRaMacAppSKey;
mluis 2:14a5d6ad92d5 1077 downLinkCounter = DownLinkCounter;
mluis 2:14a5d6ad92d5 1078 }
mluis 2:14a5d6ad92d5 1079
mluis 2:14a5d6ad92d5 1080 fCtrl.Value = payload[pktHeaderLen++];
mluis 2:14a5d6ad92d5 1081
mluis 2:14a5d6ad92d5 1082 sequenceCounter = ( uint16_t )payload[pktHeaderLen++];
mluis 2:14a5d6ad92d5 1083 sequenceCounter |= ( uint16_t )payload[pktHeaderLen++] << 8;
mluis 2:14a5d6ad92d5 1084
mluis 2:14a5d6ad92d5 1085 appPayloadStartIndex = 8 + fCtrl.Bits.FOptsLen;
mluis 2:14a5d6ad92d5 1086
mluis 2:14a5d6ad92d5 1087 micRx |= ( uint32_t )payload[size - LORAMAC_MFR_LEN];
mluis 2:14a5d6ad92d5 1088 micRx |= ( ( uint32_t )payload[size - LORAMAC_MFR_LEN + 1] << 8 );
mluis 2:14a5d6ad92d5 1089 micRx |= ( ( uint32_t )payload[size - LORAMAC_MFR_LEN + 2] << 16 );
mluis 2:14a5d6ad92d5 1090 micRx |= ( ( uint32_t )payload[size - LORAMAC_MFR_LEN + 3] << 24 );
mluis 2:14a5d6ad92d5 1091
mluis 2:14a5d6ad92d5 1092 sequenceCounterPrev = ( uint16_t )downLinkCounter;
mluis 2:14a5d6ad92d5 1093 sequenceCounterDiff = ( sequenceCounter - sequenceCounterPrev );
mluis 2:14a5d6ad92d5 1094
mluis 2:14a5d6ad92d5 1095 if( sequenceCounterDiff < ( 1 << 15 ) )
mluis 2:14a5d6ad92d5 1096 {
mluis 2:14a5d6ad92d5 1097 downLinkCounter += sequenceCounterDiff;
mluis 2:14a5d6ad92d5 1098 LoRaMacComputeMic( payload, size - LORAMAC_MFR_LEN, nwkSKey, address, DOWN_LINK, downLinkCounter, &mic );
mluis 2:14a5d6ad92d5 1099 if( micRx == mic )
mluis 2:14a5d6ad92d5 1100 {
mluis 2:14a5d6ad92d5 1101 isMicOk = true;
mluis 2:14a5d6ad92d5 1102 }
mluis 2:14a5d6ad92d5 1103 }
mluis 2:14a5d6ad92d5 1104 else
mluis 2:14a5d6ad92d5 1105 {
mluis 2:14a5d6ad92d5 1106 // check for sequence roll-over
mluis 2:14a5d6ad92d5 1107 uint32_t downLinkCounterTmp = downLinkCounter + 0x10000 + ( int16_t )sequenceCounterDiff;
mluis 2:14a5d6ad92d5 1108 LoRaMacComputeMic( payload, size - LORAMAC_MFR_LEN, nwkSKey, address, DOWN_LINK, downLinkCounterTmp, &mic );
mluis 2:14a5d6ad92d5 1109 if( micRx == mic )
mluis 2:14a5d6ad92d5 1110 {
mluis 2:14a5d6ad92d5 1111 isMicOk = true;
mluis 2:14a5d6ad92d5 1112 downLinkCounter = downLinkCounterTmp;
mluis 2:14a5d6ad92d5 1113 }
mluis 2:14a5d6ad92d5 1114 }
mluis 2:14a5d6ad92d5 1115
mluis 2:14a5d6ad92d5 1116 if( isMicOk == true )
mluis 2:14a5d6ad92d5 1117 {
mluis 2:14a5d6ad92d5 1118 McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_OK;
mluis 2:14a5d6ad92d5 1119 McpsIndication.Multicast = multicast;
mluis 2:14a5d6ad92d5 1120 McpsIndication.FramePending = fCtrl.Bits.FPending;
mluis 2:14a5d6ad92d5 1121 McpsIndication.Buffer = NULL;
mluis 2:14a5d6ad92d5 1122 McpsIndication.BufferSize = 0;
mluis 2:14a5d6ad92d5 1123 McpsIndication.DownLinkCounter = downLinkCounter;
mluis 2:14a5d6ad92d5 1124
mluis 2:14a5d6ad92d5 1125 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK;
mluis 2:14a5d6ad92d5 1126
mluis 2:14a5d6ad92d5 1127 AdrAckCounter = 0;
mluis 2:14a5d6ad92d5 1128
mluis 2:14a5d6ad92d5 1129 // Update 32 bits downlink counter
mluis 2:14a5d6ad92d5 1130 if( multicast == 1 )
mluis 2:14a5d6ad92d5 1131 {
mluis 2:14a5d6ad92d5 1132 McpsIndication.McpsIndication = MCPS_MULTICAST;
mluis 2:14a5d6ad92d5 1133
mluis 2:14a5d6ad92d5 1134 if( ( curMulticastParams->DownLinkCounter == downLinkCounter ) &&
mluis 2:14a5d6ad92d5 1135 ( curMulticastParams->DownLinkCounter != 0 ) )
mluis 2:14a5d6ad92d5 1136 {
mluis 2:14a5d6ad92d5 1137 McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED;
mluis 2:14a5d6ad92d5 1138 McpsIndication.DownLinkCounter = downLinkCounter;
mluis 3:b9d87593a8ae 1139 PrepareRxDoneAbort( );
mluis 2:14a5d6ad92d5 1140 return;
mluis 2:14a5d6ad92d5 1141 }
mluis 2:14a5d6ad92d5 1142 curMulticastParams->DownLinkCounter = downLinkCounter;
mluis 2:14a5d6ad92d5 1143 }
mluis 2:14a5d6ad92d5 1144 else
mluis 2:14a5d6ad92d5 1145 {
mluis 2:14a5d6ad92d5 1146 if( macHdr.Bits.MType == FRAME_TYPE_DATA_CONFIRMED_DOWN )
mluis 2:14a5d6ad92d5 1147 {
mluis 3:b9d87593a8ae 1148 SrvAckRequested = true;
mluis 2:14a5d6ad92d5 1149 McpsIndication.McpsIndication = MCPS_CONFIRMED;
mluis 2:14a5d6ad92d5 1150 }
mluis 2:14a5d6ad92d5 1151 else
mluis 2:14a5d6ad92d5 1152 {
mluis 3:b9d87593a8ae 1153 SrvAckRequested = false;
mluis 2:14a5d6ad92d5 1154 McpsIndication.McpsIndication = MCPS_UNCONFIRMED;
mluis 2:14a5d6ad92d5 1155 }
mluis 2:14a5d6ad92d5 1156 if( ( DownLinkCounter == downLinkCounter ) &&
mluis 2:14a5d6ad92d5 1157 ( DownLinkCounter != 0 ) )
mluis 2:14a5d6ad92d5 1158 {
mluis 2:14a5d6ad92d5 1159 McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED;
mluis 2:14a5d6ad92d5 1160 McpsIndication.DownLinkCounter = downLinkCounter;
mluis 3:b9d87593a8ae 1161 PrepareRxDoneAbort( );
mluis 2:14a5d6ad92d5 1162 return;
mluis 2:14a5d6ad92d5 1163 }
mluis 2:14a5d6ad92d5 1164 DownLinkCounter = downLinkCounter;
mluis 2:14a5d6ad92d5 1165 }
mluis 2:14a5d6ad92d5 1166
mluis 2:14a5d6ad92d5 1167 // Check if the frame is an acknowledgement
mluis 2:14a5d6ad92d5 1168 if( fCtrl.Bits.Ack == 1 )
mluis 2:14a5d6ad92d5 1169 {
mluis 2:14a5d6ad92d5 1170 McpsConfirm.AckReceived = true;
mluis 2:14a5d6ad92d5 1171 McpsIndication.AckReceived = true;
mluis 2:14a5d6ad92d5 1172
mluis 2:14a5d6ad92d5 1173 // Stop the AckTimeout timer as no more retransmissions
mluis 2:14a5d6ad92d5 1174 // are needed.
mluis 2:14a5d6ad92d5 1175 TimerStop( &AckTimeoutTimer );
mluis 2:14a5d6ad92d5 1176 }
mluis 2:14a5d6ad92d5 1177 else
mluis 2:14a5d6ad92d5 1178 {
mluis 2:14a5d6ad92d5 1179 McpsConfirm.AckReceived = false;
mluis 2:14a5d6ad92d5 1180
mluis 2:14a5d6ad92d5 1181 if( AckTimeoutRetriesCounter > AckTimeoutRetries )
mluis 2:14a5d6ad92d5 1182 {
mluis 2:14a5d6ad92d5 1183 // Stop the AckTimeout timer as no more retransmissions
mluis 2:14a5d6ad92d5 1184 // are needed.
mluis 2:14a5d6ad92d5 1185 TimerStop( &AckTimeoutTimer );
mluis 2:14a5d6ad92d5 1186 }
mluis 2:14a5d6ad92d5 1187 }
mluis 2:14a5d6ad92d5 1188
mluis 2:14a5d6ad92d5 1189 if( fCtrl.Bits.FOptsLen > 0 )
mluis 2:14a5d6ad92d5 1190 {
mluis 2:14a5d6ad92d5 1191 // Decode Options field MAC commands
mluis 2:14a5d6ad92d5 1192 ProcessMacCommands( payload, 8, appPayloadStartIndex, snr );
mluis 2:14a5d6ad92d5 1193 }
mluis 2:14a5d6ad92d5 1194 if( ( ( size - 4 ) - appPayloadStartIndex ) > 0 )
mluis 2:14a5d6ad92d5 1195 {
mluis 2:14a5d6ad92d5 1196 port = payload[appPayloadStartIndex++];
mluis 2:14a5d6ad92d5 1197 frameLen = ( size - 4 ) - appPayloadStartIndex;
mluis 2:14a5d6ad92d5 1198
mluis 2:14a5d6ad92d5 1199 McpsIndication.Port = port;
mluis 2:14a5d6ad92d5 1200
mluis 2:14a5d6ad92d5 1201 if( port == 0 )
mluis 2:14a5d6ad92d5 1202 {
mluis 2:14a5d6ad92d5 1203 LoRaMacPayloadDecrypt( payload + appPayloadStartIndex,
mluis 2:14a5d6ad92d5 1204 frameLen,
mluis 2:14a5d6ad92d5 1205 nwkSKey,
mluis 2:14a5d6ad92d5 1206 address,
mluis 2:14a5d6ad92d5 1207 DOWN_LINK,
mluis 2:14a5d6ad92d5 1208 downLinkCounter,
mluis 2:14a5d6ad92d5 1209 LoRaMacRxPayload );
mluis 2:14a5d6ad92d5 1210
mluis 2:14a5d6ad92d5 1211 // Decode frame payload MAC commands
mluis 2:14a5d6ad92d5 1212 ProcessMacCommands( LoRaMacRxPayload, 0, frameLen, snr );
mluis 2:14a5d6ad92d5 1213 }
mluis 2:14a5d6ad92d5 1214 else
mluis 2:14a5d6ad92d5 1215 {
mluis 2:14a5d6ad92d5 1216 LoRaMacPayloadDecrypt( payload + appPayloadStartIndex,
mluis 2:14a5d6ad92d5 1217 frameLen,
mluis 2:14a5d6ad92d5 1218 appSKey,
mluis 2:14a5d6ad92d5 1219 address,
mluis 2:14a5d6ad92d5 1220 DOWN_LINK,
mluis 2:14a5d6ad92d5 1221 downLinkCounter,
mluis 2:14a5d6ad92d5 1222 LoRaMacRxPayload );
mluis 2:14a5d6ad92d5 1223
mluis 2:14a5d6ad92d5 1224 McpsIndication.Buffer = LoRaMacRxPayload;
mluis 2:14a5d6ad92d5 1225 McpsIndication.BufferSize = frameLen;
mluis 2:14a5d6ad92d5 1226 McpsIndication.RxData = true;
mluis 2:14a5d6ad92d5 1227 }
mluis 2:14a5d6ad92d5 1228 }
mluis 3:b9d87593a8ae 1229 LoRaMacFlags.Bits.McpsInd = 1;
mluis 2:14a5d6ad92d5 1230 }
mluis 2:14a5d6ad92d5 1231 else
mluis 2:14a5d6ad92d5 1232 {
mluis 2:14a5d6ad92d5 1233 McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_MIC_FAIL;
mluis 3:b9d87593a8ae 1234
mluis 3:b9d87593a8ae 1235 PrepareRxDoneAbort( );
mluis 3:b9d87593a8ae 1236 return;
mluis 2:14a5d6ad92d5 1237 }
mluis 2:14a5d6ad92d5 1238 }
mluis 2:14a5d6ad92d5 1239 break;
mluis 2:14a5d6ad92d5 1240 case FRAME_TYPE_PROPRIETARY:
mluis 2:14a5d6ad92d5 1241 {
mluis 2:14a5d6ad92d5 1242 memcpy1( LoRaMacRxPayload, &payload[pktHeaderLen], size );
mluis 2:14a5d6ad92d5 1243
mluis 2:14a5d6ad92d5 1244 McpsIndication.McpsIndication = MCPS_PROPRIETARY;
mluis 2:14a5d6ad92d5 1245 McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_OK;
mluis 2:14a5d6ad92d5 1246 McpsIndication.Buffer = LoRaMacRxPayload;
mluis 2:14a5d6ad92d5 1247 McpsIndication.BufferSize = size - pktHeaderLen;
mluis 3:b9d87593a8ae 1248
mluis 3:b9d87593a8ae 1249 LoRaMacFlags.Bits.McpsInd = 1;
mluis 2:14a5d6ad92d5 1250 break;
mluis 2:14a5d6ad92d5 1251 }
mluis 2:14a5d6ad92d5 1252 default:
mluis 2:14a5d6ad92d5 1253 McpsIndication.Status = LORAMAC_EVENT_INFO_STATUS_ERROR;
mluis 3:b9d87593a8ae 1254 PrepareRxDoneAbort( );
mluis 2:14a5d6ad92d5 1255 break;
mluis 2:14a5d6ad92d5 1256 }
mluis 2:14a5d6ad92d5 1257
mluis 2:14a5d6ad92d5 1258 if( ( RxSlot == 0 ) && ( LoRaMacDeviceClass == CLASS_C ) )
mluis 2:14a5d6ad92d5 1259 {
mluis 2:14a5d6ad92d5 1260 OnRxWindow2TimerEvent( );
mluis 2:14a5d6ad92d5 1261 }
mluis 2:14a5d6ad92d5 1262 LoRaMacFlags.Bits.MacDone = 1;
mluis 3:b9d87593a8ae 1263
mluis 3:b9d87593a8ae 1264 // Trig OnMacCheckTimerEvent call as soon as possible
mluis 3:b9d87593a8ae 1265 TimerSetValue( &MacStateCheckTimer, 1000 );
mluis 3:b9d87593a8ae 1266 TimerStart( &MacStateCheckTimer );
mluis 2:14a5d6ad92d5 1267 }
mluis 2:14a5d6ad92d5 1268
mluis 2:14a5d6ad92d5 1269 static void OnRadioTxTimeout( void )
mluis 2:14a5d6ad92d5 1270 {
mluis 2:14a5d6ad92d5 1271 if( LoRaMacDeviceClass != CLASS_C )
mluis 2:14a5d6ad92d5 1272 {
mluis 2:14a5d6ad92d5 1273 Radio.Sleep( );
mluis 2:14a5d6ad92d5 1274 }
mluis 2:14a5d6ad92d5 1275 else
mluis 2:14a5d6ad92d5 1276 {
mluis 2:14a5d6ad92d5 1277 OnRxWindow2TimerEvent( );
mluis 2:14a5d6ad92d5 1278 }
mluis 2:14a5d6ad92d5 1279
mluis 2:14a5d6ad92d5 1280 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT;
mluis 2:14a5d6ad92d5 1281 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT;
mluis 2:14a5d6ad92d5 1282 LoRaMacFlags.Bits.MacDone = 1;
mluis 2:14a5d6ad92d5 1283 }
mluis 2:14a5d6ad92d5 1284
mluis 2:14a5d6ad92d5 1285 static void OnRadioRxError( void )
mluis 2:14a5d6ad92d5 1286 {
mluis 2:14a5d6ad92d5 1287 if( LoRaMacDeviceClass != CLASS_C )
mluis 2:14a5d6ad92d5 1288 {
mluis 2:14a5d6ad92d5 1289 Radio.Sleep( );
mluis 2:14a5d6ad92d5 1290 }
mluis 2:14a5d6ad92d5 1291 else
mluis 2:14a5d6ad92d5 1292 {
mluis 2:14a5d6ad92d5 1293 OnRxWindow2TimerEvent( );
mluis 2:14a5d6ad92d5 1294 }
mluis 2:14a5d6ad92d5 1295
mluis 2:14a5d6ad92d5 1296 if( RxSlot == 1 )
mluis 2:14a5d6ad92d5 1297 {
mluis 2:14a5d6ad92d5 1298 if( NodeAckRequested == true )
mluis 2:14a5d6ad92d5 1299 {
mluis 2:14a5d6ad92d5 1300 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX2_ERROR;
mluis 2:14a5d6ad92d5 1301 }
mluis 2:14a5d6ad92d5 1302 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX2_ERROR;
mluis 2:14a5d6ad92d5 1303 LoRaMacFlags.Bits.MacDone = 1;
mluis 2:14a5d6ad92d5 1304 }
mluis 2:14a5d6ad92d5 1305 }
mluis 2:14a5d6ad92d5 1306
mluis 2:14a5d6ad92d5 1307 static void OnRadioRxTimeout( void )
mluis 2:14a5d6ad92d5 1308 {
mluis 2:14a5d6ad92d5 1309 if( LoRaMacDeviceClass != CLASS_C )
mluis 2:14a5d6ad92d5 1310 {
mluis 2:14a5d6ad92d5 1311 Radio.Sleep( );
mluis 2:14a5d6ad92d5 1312 }
mluis 2:14a5d6ad92d5 1313 else
mluis 2:14a5d6ad92d5 1314 {
mluis 2:14a5d6ad92d5 1315 OnRxWindow2TimerEvent( );
mluis 2:14a5d6ad92d5 1316 }
mluis 2:14a5d6ad92d5 1317
mluis 2:14a5d6ad92d5 1318 if( RxSlot == 1 )
mluis 2:14a5d6ad92d5 1319 {
mluis 2:14a5d6ad92d5 1320 if( NodeAckRequested == true )
mluis 2:14a5d6ad92d5 1321 {
mluis 2:14a5d6ad92d5 1322 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT;
mluis 2:14a5d6ad92d5 1323 }
mluis 2:14a5d6ad92d5 1324 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT;
mluis 2:14a5d6ad92d5 1325 LoRaMacFlags.Bits.MacDone = 1;
mluis 2:14a5d6ad92d5 1326 }
mluis 2:14a5d6ad92d5 1327 }
mluis 2:14a5d6ad92d5 1328
mluis 2:14a5d6ad92d5 1329 static void OnMacStateCheckTimerEvent( void )
mluis 2:14a5d6ad92d5 1330 {
mluis 2:14a5d6ad92d5 1331 TimerStop( &MacStateCheckTimer );
mluis 2:14a5d6ad92d5 1332 bool txTimeout = false;
mluis 2:14a5d6ad92d5 1333
mluis 2:14a5d6ad92d5 1334 if( LoRaMacFlags.Bits.MacDone == 1 )
mluis 2:14a5d6ad92d5 1335 {
mluis 2:14a5d6ad92d5 1336 if( ( LoRaMacFlags.Bits.MlmeReq == 1 ) || ( ( LoRaMacFlags.Bits.McpsReq == 1 ) ) )
mluis 2:14a5d6ad92d5 1337 {
mluis 2:14a5d6ad92d5 1338 if( ( McpsConfirm.Status == LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT ) ||
mluis 2:14a5d6ad92d5 1339 ( MlmeConfirm.Status == LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT ) )
mluis 2:14a5d6ad92d5 1340 {
mluis 2:14a5d6ad92d5 1341 // Stop transmit cycle due to tx timeout.
mluis 2:14a5d6ad92d5 1342 LoRaMacState &= ~MAC_TX_RUNNING;
mluis 2:14a5d6ad92d5 1343 McpsConfirm.NbRetries = AckTimeoutRetriesCounter;
mluis 2:14a5d6ad92d5 1344 McpsConfirm.AckReceived = false;
mluis 2:14a5d6ad92d5 1345 McpsConfirm.TxTimeOnAir = 0;
mluis 2:14a5d6ad92d5 1346 txTimeout = true;
mluis 2:14a5d6ad92d5 1347 }
mluis 2:14a5d6ad92d5 1348 }
mluis 2:14a5d6ad92d5 1349
mluis 2:14a5d6ad92d5 1350 if( ( NodeAckRequested == false ) && ( txTimeout == false ) )
mluis 2:14a5d6ad92d5 1351 {
mluis 2:14a5d6ad92d5 1352 if( LoRaMacFlags.Bits.MlmeReq == 1 )
mluis 2:14a5d6ad92d5 1353 {
mluis 2:14a5d6ad92d5 1354 if( MlmeConfirm.MlmeRequest == MLME_JOIN )
mluis 2:14a5d6ad92d5 1355 {
mluis 2:14a5d6ad92d5 1356 if( MlmeConfirm.Status == LORAMAC_EVENT_INFO_STATUS_OK )
mluis 2:14a5d6ad92d5 1357 {
mluis 2:14a5d6ad92d5 1358 UpLinkCounter = 0;
mluis 2:14a5d6ad92d5 1359 }
mluis 2:14a5d6ad92d5 1360 // Join messages aren't repeated automatically
mluis 2:14a5d6ad92d5 1361 ChannelsNbRepCounter = ChannelsNbRep;
mluis 2:14a5d6ad92d5 1362 }
mluis 2:14a5d6ad92d5 1363 }
mluis 2:14a5d6ad92d5 1364 if( ( LoRaMacFlags.Bits.MlmeReq == 1 ) || ( ( LoRaMacFlags.Bits.McpsReq == 1 ) ) )
mluis 2:14a5d6ad92d5 1365 {
mluis 2:14a5d6ad92d5 1366 if( ( ChannelsNbRepCounter >= ChannelsNbRep ) || ( LoRaMacFlags.Bits.McpsInd == 1 ) )
mluis 2:14a5d6ad92d5 1367 {
mluis 2:14a5d6ad92d5 1368 ChannelsNbRepCounter = 0;
mluis 2:14a5d6ad92d5 1369
mluis 2:14a5d6ad92d5 1370 AdrAckCounter++;
mluis 2:14a5d6ad92d5 1371 if( IsUpLinkCounterFixed == false )
mluis 2:14a5d6ad92d5 1372 {
mluis 2:14a5d6ad92d5 1373 UpLinkCounter++;
mluis 2:14a5d6ad92d5 1374 }
mluis 2:14a5d6ad92d5 1375
mluis 2:14a5d6ad92d5 1376 LoRaMacState &= ~MAC_TX_RUNNING;
mluis 2:14a5d6ad92d5 1377 }
mluis 2:14a5d6ad92d5 1378 else
mluis 2:14a5d6ad92d5 1379 {
mluis 2:14a5d6ad92d5 1380 LoRaMacFlags.Bits.MacDone = 0;
mluis 2:14a5d6ad92d5 1381 // Sends the same frame again
mluis 2:14a5d6ad92d5 1382 ScheduleTx( );
mluis 2:14a5d6ad92d5 1383 }
mluis 2:14a5d6ad92d5 1384 }
mluis 2:14a5d6ad92d5 1385 }
mluis 2:14a5d6ad92d5 1386
mluis 2:14a5d6ad92d5 1387 if( LoRaMacFlags.Bits.McpsInd == 1 )
mluis 2:14a5d6ad92d5 1388 {
mluis 2:14a5d6ad92d5 1389 if( ( McpsConfirm.AckReceived == true ) || ( AckTimeoutRetriesCounter > AckTimeoutRetries ) )
mluis 2:14a5d6ad92d5 1390 {
mluis 2:14a5d6ad92d5 1391 AckTimeoutRetry = false;
mluis 3:b9d87593a8ae 1392 NodeAckRequested = false;
mluis 2:14a5d6ad92d5 1393 if( IsUpLinkCounterFixed == false )
mluis 2:14a5d6ad92d5 1394 {
mluis 2:14a5d6ad92d5 1395 UpLinkCounter++;
mluis 2:14a5d6ad92d5 1396 }
mluis 2:14a5d6ad92d5 1397 McpsConfirm.NbRetries = AckTimeoutRetriesCounter;
mluis 2:14a5d6ad92d5 1398
mluis 2:14a5d6ad92d5 1399 LoRaMacState &= ~MAC_TX_RUNNING;
mluis 2:14a5d6ad92d5 1400 }
mluis 2:14a5d6ad92d5 1401 }
mluis 2:14a5d6ad92d5 1402
mluis 2:14a5d6ad92d5 1403 if( ( AckTimeoutRetry == true ) && ( ( LoRaMacState & MAC_TX_DELAYED ) == 0 ) )
mluis 2:14a5d6ad92d5 1404 {
mluis 2:14a5d6ad92d5 1405 AckTimeoutRetry = false;
mluis 2:14a5d6ad92d5 1406 if( ( AckTimeoutRetriesCounter < AckTimeoutRetries ) && ( AckTimeoutRetriesCounter <= MAX_ACK_RETRIES ) )
mluis 2:14a5d6ad92d5 1407 {
mluis 2:14a5d6ad92d5 1408 AckTimeoutRetriesCounter++;
mluis 2:14a5d6ad92d5 1409
mluis 2:14a5d6ad92d5 1410 if( ( AckTimeoutRetriesCounter % 2 ) == 1 )
mluis 2:14a5d6ad92d5 1411 {
mluis 2:14a5d6ad92d5 1412 ChannelsDatarate = MAX( ChannelsDatarate - 1, LORAMAC_MIN_DATARATE );
mluis 2:14a5d6ad92d5 1413 }
mluis 2:14a5d6ad92d5 1414 LoRaMacFlags.Bits.MacDone = 0;
mluis 2:14a5d6ad92d5 1415 // Sends the same frame again
mluis 2:14a5d6ad92d5 1416 ScheduleTx( );
mluis 2:14a5d6ad92d5 1417 }
mluis 2:14a5d6ad92d5 1418 else
mluis 2:14a5d6ad92d5 1419 {
mluis 2:14a5d6ad92d5 1420 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
mluis 2:14a5d6ad92d5 1421 // Re-enable default channels LC1, LC2, LC3
mluis 2:14a5d6ad92d5 1422 ChannelsMask[0] = ChannelsMask[0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) );
mluis 2:14a5d6ad92d5 1423 #elif defined( USE_BAND_915 )
mluis 2:14a5d6ad92d5 1424 // Re-enable default channels
mluis 2:14a5d6ad92d5 1425 ChannelsMask[0] = 0xFFFF;
mluis 2:14a5d6ad92d5 1426 ChannelsMask[1] = 0xFFFF;
mluis 2:14a5d6ad92d5 1427 ChannelsMask[2] = 0xFFFF;
mluis 2:14a5d6ad92d5 1428 ChannelsMask[3] = 0xFFFF;
mluis 2:14a5d6ad92d5 1429 ChannelsMask[4] = 0x00FF;
mluis 2:14a5d6ad92d5 1430 ChannelsMask[5] = 0x0000;
mluis 2:14a5d6ad92d5 1431 #elif defined( USE_BAND_915_HYBRID )
mluis 2:14a5d6ad92d5 1432 // Re-enable default channels
mluis 2:14a5d6ad92d5 1433 ChannelsMask[0] = 0x00FF;
mluis 2:14a5d6ad92d5 1434 ChannelsMask[1] = 0x0000;
mluis 2:14a5d6ad92d5 1435 ChannelsMask[2] = 0x0000;
mluis 2:14a5d6ad92d5 1436 ChannelsMask[3] = 0x0000;
mluis 2:14a5d6ad92d5 1437 ChannelsMask[4] = 0x0001;
mluis 2:14a5d6ad92d5 1438 ChannelsMask[5] = 0x0000;
mluis 2:14a5d6ad92d5 1439 #else
mluis 2:14a5d6ad92d5 1440 #error "Please define a frequency band in the compiler options."
mluis 2:14a5d6ad92d5 1441 #endif
mluis 2:14a5d6ad92d5 1442 LoRaMacState &= ~MAC_TX_RUNNING;
mluis 2:14a5d6ad92d5 1443
mluis 3:b9d87593a8ae 1444 NodeAckRequested = false;
mluis 2:14a5d6ad92d5 1445 McpsConfirm.AckReceived = false;
mluis 2:14a5d6ad92d5 1446 McpsConfirm.NbRetries = AckTimeoutRetriesCounter;
mluis 2:14a5d6ad92d5 1447 if( IsUpLinkCounterFixed == false )
mluis 2:14a5d6ad92d5 1448 {
mluis 2:14a5d6ad92d5 1449 UpLinkCounter++;
mluis 2:14a5d6ad92d5 1450 }
mluis 2:14a5d6ad92d5 1451 }
mluis 2:14a5d6ad92d5 1452 }
mluis 2:14a5d6ad92d5 1453 }
mluis 2:14a5d6ad92d5 1454 // Handle reception for Class B and Class C
mluis 2:14a5d6ad92d5 1455 if( ( LoRaMacState & MAC_RX ) == MAC_RX )
mluis 2:14a5d6ad92d5 1456 {
mluis 2:14a5d6ad92d5 1457 LoRaMacState &= ~MAC_RX;
mluis 2:14a5d6ad92d5 1458 }
mluis 2:14a5d6ad92d5 1459 if( LoRaMacState == MAC_IDLE )
mluis 2:14a5d6ad92d5 1460 {
mluis 2:14a5d6ad92d5 1461 if( LoRaMacFlags.Bits.McpsReq == 1 )
mluis 2:14a5d6ad92d5 1462 {
mluis 2:14a5d6ad92d5 1463 LoRaMacPrimitives->MacMcpsConfirm( &McpsConfirm );
mluis 2:14a5d6ad92d5 1464 LoRaMacFlags.Bits.McpsReq = 0;
mluis 2:14a5d6ad92d5 1465 }
mluis 2:14a5d6ad92d5 1466
mluis 2:14a5d6ad92d5 1467 if( LoRaMacFlags.Bits.MlmeReq == 1 )
mluis 2:14a5d6ad92d5 1468 {
mluis 2:14a5d6ad92d5 1469 LoRaMacPrimitives->MacMlmeConfirm( &MlmeConfirm );
mluis 2:14a5d6ad92d5 1470 LoRaMacFlags.Bits.MlmeReq = 0;
mluis 2:14a5d6ad92d5 1471 }
mluis 2:14a5d6ad92d5 1472
mluis 2:14a5d6ad92d5 1473 LoRaMacFlags.Bits.MacDone = 0;
mluis 2:14a5d6ad92d5 1474 }
mluis 2:14a5d6ad92d5 1475 else
mluis 2:14a5d6ad92d5 1476 {
mluis 2:14a5d6ad92d5 1477 // Operation not finished restart timer
mluis 3:b9d87593a8ae 1478 TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT );
mluis 2:14a5d6ad92d5 1479 TimerStart( &MacStateCheckTimer );
mluis 2:14a5d6ad92d5 1480 }
mluis 2:14a5d6ad92d5 1481
mluis 2:14a5d6ad92d5 1482 if( LoRaMacFlags.Bits.McpsInd == 1 )
mluis 2:14a5d6ad92d5 1483 {
mluis 2:14a5d6ad92d5 1484 LoRaMacPrimitives->MacMcpsIndication( &McpsIndication );
mluis 2:14a5d6ad92d5 1485 LoRaMacFlags.Bits.McpsInd = 0;
mluis 2:14a5d6ad92d5 1486 }
mluis 2:14a5d6ad92d5 1487 }
mluis 2:14a5d6ad92d5 1488
mluis 2:14a5d6ad92d5 1489 static void OnTxDelayedTimerEvent( void )
mluis 2:14a5d6ad92d5 1490 {
mluis 2:14a5d6ad92d5 1491 TimerStop( &TxDelayedTimer );
mluis 2:14a5d6ad92d5 1492 LoRaMacState &= ~MAC_TX_DELAYED;
mluis 2:14a5d6ad92d5 1493
mluis 2:14a5d6ad92d5 1494 ScheduleTx( );
mluis 2:14a5d6ad92d5 1495 }
mluis 2:14a5d6ad92d5 1496
mluis 2:14a5d6ad92d5 1497 static void OnRxWindow1TimerEvent( void )
mluis 2:14a5d6ad92d5 1498 {
mluis 2:14a5d6ad92d5 1499 uint16_t symbTimeout = 5; // DR_2, DR_1, DR_0
mluis 2:14a5d6ad92d5 1500 int8_t datarate = 0;
mluis 2:14a5d6ad92d5 1501 uint32_t bandwidth = 0; // LoRa 125 kHz
mluis 2:14a5d6ad92d5 1502
mluis 2:14a5d6ad92d5 1503 TimerStop( &RxWindowTimer1 );
mluis 2:14a5d6ad92d5 1504 RxSlot = 0;
mluis 2:14a5d6ad92d5 1505
mluis 2:14a5d6ad92d5 1506 if( LoRaMacDeviceClass == CLASS_C )
mluis 2:14a5d6ad92d5 1507 {
mluis 2:14a5d6ad92d5 1508 Radio.Standby( );
mluis 2:14a5d6ad92d5 1509 }
mluis 2:14a5d6ad92d5 1510
mluis 2:14a5d6ad92d5 1511 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
mluis 2:14a5d6ad92d5 1512 datarate = ChannelsDatarate - Rx1DrOffset;
mluis 2:14a5d6ad92d5 1513 if( datarate < 0 )
mluis 2:14a5d6ad92d5 1514 {
mluis 2:14a5d6ad92d5 1515 datarate = DR_0;
mluis 2:14a5d6ad92d5 1516 }
mluis 2:14a5d6ad92d5 1517
mluis 2:14a5d6ad92d5 1518 // For higher datarates, we increase the number of symbols generating a Rx Timeout
mluis 2:14a5d6ad92d5 1519 if( datarate >= DR_3 )
mluis 2:14a5d6ad92d5 1520 { // DR_6, DR_5, DR_4, DR_3
mluis 2:14a5d6ad92d5 1521 symbTimeout = 8;
mluis 2:14a5d6ad92d5 1522 }
mluis 2:14a5d6ad92d5 1523 if( datarate == DR_6 )
mluis 2:14a5d6ad92d5 1524 {// LoRa 250 kHz
mluis 2:14a5d6ad92d5 1525 bandwidth = 1;
mluis 2:14a5d6ad92d5 1526 }
mluis 2:14a5d6ad92d5 1527 RxWindowSetup( Channels[Channel].Frequency, datarate, bandwidth, symbTimeout, false );
mluis 2:14a5d6ad92d5 1528 #elif ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) )
mluis 2:14a5d6ad92d5 1529 datarate = datarateOffsets[ChannelsDatarate][Rx1DrOffset];
mluis 2:14a5d6ad92d5 1530 if( datarate < 0 )
mluis 2:14a5d6ad92d5 1531 {
mluis 2:14a5d6ad92d5 1532 datarate = DR_0;
mluis 2:14a5d6ad92d5 1533 }
mluis 2:14a5d6ad92d5 1534 // For higher datarates, we increase the number of symbols generating a Rx Timeout
mluis 2:14a5d6ad92d5 1535 if( datarate > DR_0 )
mluis 2:14a5d6ad92d5 1536 { // DR_1, DR_2, DR_3, DR_4, DR_8, DR_9, DR_10, DR_11, DR_12, DR_13
mluis 2:14a5d6ad92d5 1537 symbTimeout = 8;
mluis 2:14a5d6ad92d5 1538 }
mluis 2:14a5d6ad92d5 1539 if( datarate >= DR_4 )
mluis 2:14a5d6ad92d5 1540 {// LoRa 500 kHz
mluis 2:14a5d6ad92d5 1541 bandwidth = 2;
mluis 2:14a5d6ad92d5 1542 }
mluis 2:14a5d6ad92d5 1543 RxWindowSetup( 923.3e6 + ( Channel % 8 ) * 600e3, datarate, bandwidth, symbTimeout, false );
mluis 2:14a5d6ad92d5 1544 #else
mluis 2:14a5d6ad92d5 1545 #error "Please define a frequency band in the compiler options."
mluis 2:14a5d6ad92d5 1546 #endif
mluis 2:14a5d6ad92d5 1547 }
mluis 2:14a5d6ad92d5 1548
mluis 2:14a5d6ad92d5 1549 static void OnRxWindow2TimerEvent( void )
mluis 2:14a5d6ad92d5 1550 {
mluis 2:14a5d6ad92d5 1551 uint16_t symbTimeout = 5; // DR_2, DR_1, DR_0
mluis 2:14a5d6ad92d5 1552 uint32_t bandwidth = 0; // LoRa 125 kHz
mluis 2:14a5d6ad92d5 1553
mluis 2:14a5d6ad92d5 1554 TimerStop( &RxWindowTimer2 );
mluis 2:14a5d6ad92d5 1555 RxSlot = 1;
mluis 2:14a5d6ad92d5 1556
mluis 2:14a5d6ad92d5 1557 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
mluis 2:14a5d6ad92d5 1558 // For higher datarates, we increase the number of symbols generating a Rx Timeout
mluis 2:14a5d6ad92d5 1559 if( Rx2Channel.Datarate >= DR_3 )
mluis 2:14a5d6ad92d5 1560 { // DR_6, DR_5, DR_4, DR_3
mluis 2:14a5d6ad92d5 1561 symbTimeout = 8;
mluis 2:14a5d6ad92d5 1562 }
mluis 2:14a5d6ad92d5 1563 if( Rx2Channel.Datarate == DR_6 )
mluis 2:14a5d6ad92d5 1564 {// LoRa 250 kHz
mluis 2:14a5d6ad92d5 1565 bandwidth = 1;
mluis 2:14a5d6ad92d5 1566 }
mluis 2:14a5d6ad92d5 1567 #elif ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) )
mluis 2:14a5d6ad92d5 1568 // For higher datarates, we increase the number of symbols generating a Rx Timeout
mluis 2:14a5d6ad92d5 1569 if( Rx2Channel.Datarate > DR_0 )
mluis 2:14a5d6ad92d5 1570 { // DR_1, DR_2, DR_3, DR_4, DR_8, DR_9, DR_10, DR_11, DR_12, DR_13
mluis 2:14a5d6ad92d5 1571 symbTimeout = 8;
mluis 2:14a5d6ad92d5 1572 }
mluis 2:14a5d6ad92d5 1573 if( Rx2Channel.Datarate >= DR_4 )
mluis 2:14a5d6ad92d5 1574 {// LoRa 500 kHz
mluis 2:14a5d6ad92d5 1575 bandwidth = 2;
mluis 2:14a5d6ad92d5 1576 }
mluis 2:14a5d6ad92d5 1577 #else
mluis 2:14a5d6ad92d5 1578 #error "Please define a frequency band in the compiler options."
mluis 2:14a5d6ad92d5 1579 #endif
mluis 2:14a5d6ad92d5 1580 if( LoRaMacDeviceClass != CLASS_C )
mluis 2:14a5d6ad92d5 1581 {
mluis 2:14a5d6ad92d5 1582 RxWindowSetup( Rx2Channel.Frequency, Rx2Channel.Datarate, bandwidth, symbTimeout, false );
mluis 2:14a5d6ad92d5 1583 }
mluis 2:14a5d6ad92d5 1584 else
mluis 2:14a5d6ad92d5 1585 {
mluis 2:14a5d6ad92d5 1586 RxWindowSetup( Rx2Channel.Frequency, Rx2Channel.Datarate, bandwidth, symbTimeout, true );
mluis 2:14a5d6ad92d5 1587 }
mluis 2:14a5d6ad92d5 1588 }
mluis 2:14a5d6ad92d5 1589
mluis 2:14a5d6ad92d5 1590 static void OnAckTimeoutTimerEvent( void )
mluis 2:14a5d6ad92d5 1591 {
mluis 2:14a5d6ad92d5 1592 TimerStop( &AckTimeoutTimer );
mluis 2:14a5d6ad92d5 1593
mluis 2:14a5d6ad92d5 1594 if( NodeAckRequested == true )
mluis 2:14a5d6ad92d5 1595 {
mluis 2:14a5d6ad92d5 1596 AckTimeoutRetry = true;
mluis 2:14a5d6ad92d5 1597 LoRaMacState &= ~MAC_ACK_REQ;
mluis 2:14a5d6ad92d5 1598 }
mluis 2:14a5d6ad92d5 1599 if( LoRaMacDeviceClass == CLASS_C )
mluis 2:14a5d6ad92d5 1600 {
mluis 2:14a5d6ad92d5 1601 LoRaMacFlags.Bits.MacDone = 1;
mluis 2:14a5d6ad92d5 1602 }
mluis 2:14a5d6ad92d5 1603 }
mluis 2:14a5d6ad92d5 1604
mluis 3:b9d87593a8ae 1605 static bool SetNextChannel( TimerTime_t* time )
mluis 2:14a5d6ad92d5 1606 {
mluis 0:91d1a7783bb9 1607 uint8_t nbEnabledChannels = 0;
mluis 3:b9d87593a8ae 1608 uint8_t delayTx = 0;
mluis 0:91d1a7783bb9 1609 uint8_t enabledChannels[LORA_MAX_NB_CHANNELS];
mluis 0:91d1a7783bb9 1610 TimerTime_t curTime = TimerGetCurrentTime( );
mluis 2:14a5d6ad92d5 1611 TimerTime_t nextTxDelay = ( TimerTime_t )( -1 );
mluis 0:91d1a7783bb9 1612
mluis 1:91e4e6c60d1e 1613 memset1( enabledChannels, 0, LORA_MAX_NB_CHANNELS );
mluis 0:91d1a7783bb9 1614
mluis 2:14a5d6ad92d5 1615 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 3:b9d87593a8ae 1616 if( CountNbEnabled125kHzChannels( ChannelsMaskRemaining ) == 0 )
mluis 3:b9d87593a8ae 1617 { // Restore default channels
mluis 3:b9d87593a8ae 1618 memcpy1( ( uint8_t* ) ChannelsMaskRemaining, ( uint8_t* ) ChannelsMask, 8 );
mluis 3:b9d87593a8ae 1619 }
mluis 3:b9d87593a8ae 1620 if( ( ChannelsDatarate >= DR_4 ) && ( ( ChannelsMaskRemaining[4] & 0x00FF ) == 0 ) )
mluis 3:b9d87593a8ae 1621 { // Make sure, that the channels are activated
mluis 3:b9d87593a8ae 1622 ChannelsMaskRemaining[4] = ChannelsMask[4];
mluis 3:b9d87593a8ae 1623 }
mluis 3:b9d87593a8ae 1624 #else
mluis 3:b9d87593a8ae 1625 uint8_t chanCnt = 0;
mluis 3:b9d87593a8ae 1626 for( uint8_t i = 0, k = 0; i < LORA_MAX_NB_CHANNELS; i += 16, k++ )
mluis 2:14a5d6ad92d5 1627 {
mluis 3:b9d87593a8ae 1628 if( ChannelsMask[k] != 0 )
mluis 3:b9d87593a8ae 1629 {
mluis 3:b9d87593a8ae 1630 chanCnt++;
mluis 3:b9d87593a8ae 1631 break;
mluis 3:b9d87593a8ae 1632 }
mluis 3:b9d87593a8ae 1633 }
mluis 3:b9d87593a8ae 1634 if( chanCnt == 0 )
mluis 3:b9d87593a8ae 1635 {
mluis 3:b9d87593a8ae 1636 // Re-enable default channels, if no channel is enabled
mluis 3:b9d87593a8ae 1637 ChannelsMask[0] = ChannelsMask[0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) );
mluis 2:14a5d6ad92d5 1638 }
mluis 2:14a5d6ad92d5 1639 #endif
mluis 2:14a5d6ad92d5 1640
mluis 0:91d1a7783bb9 1641 // Update Aggregated duty cycle
mluis 0:91d1a7783bb9 1642 if( AggregatedTimeOff < ( curTime - AggregatedLastTxDoneTime ) )
mluis 0:91d1a7783bb9 1643 {
mluis 0:91d1a7783bb9 1644 AggregatedTimeOff = 0;
mluis 2:14a5d6ad92d5 1645
mluis 2:14a5d6ad92d5 1646 // Update bands Time OFF
mluis 2:14a5d6ad92d5 1647 for( uint8_t i = 0; i < LORA_MAX_NB_BANDS; i++ )
mluis 0:91d1a7783bb9 1648 {
mluis 2:14a5d6ad92d5 1649 if( DutyCycleOn == true )
mluis 0:91d1a7783bb9 1650 {
mluis 2:14a5d6ad92d5 1651 if( Bands[i].TimeOff < ( curTime - Bands[i].LastTxDoneTime ) )
mluis 2:14a5d6ad92d5 1652 {
mluis 2:14a5d6ad92d5 1653 Bands[i].TimeOff = 0;
mluis 2:14a5d6ad92d5 1654 }
mluis 2:14a5d6ad92d5 1655 if( Bands[i].TimeOff != 0 )
mluis 2:14a5d6ad92d5 1656 {
mluis 2:14a5d6ad92d5 1657 nextTxDelay = MIN( Bands[i].TimeOff -
mluis 2:14a5d6ad92d5 1658 ( curTime - Bands[i].LastTxDoneTime ),
mluis 2:14a5d6ad92d5 1659 nextTxDelay );
mluis 2:14a5d6ad92d5 1660 }
mluis 2:14a5d6ad92d5 1661 }
mluis 2:14a5d6ad92d5 1662 else
mluis 2:14a5d6ad92d5 1663 {
mluis 2:14a5d6ad92d5 1664 nextTxDelay = 0;
mluis 0:91d1a7783bb9 1665 Bands[i].TimeOff = 0;
mluis 0:91d1a7783bb9 1666 }
mluis 2:14a5d6ad92d5 1667 }
mluis 2:14a5d6ad92d5 1668
mluis 2:14a5d6ad92d5 1669 // Search how many channels are enabled
mluis 2:14a5d6ad92d5 1670 for( uint8_t i = 0, k = 0; i < LORA_MAX_NB_CHANNELS; i += 16, k++ )
mluis 2:14a5d6ad92d5 1671 {
mluis 2:14a5d6ad92d5 1672 for( uint8_t j = 0; j < 16; j++ )
mluis 0:91d1a7783bb9 1673 {
mluis 2:14a5d6ad92d5 1674 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 2:14a5d6ad92d5 1675 if( ( ChannelsMaskRemaining[k] & ( 1 << j ) ) != 0 )
mluis 2:14a5d6ad92d5 1676 #else
mluis 2:14a5d6ad92d5 1677 if( ( ChannelsMask[k] & ( 1 << j ) ) != 0 )
mluis 2:14a5d6ad92d5 1678 #endif
mluis 2:14a5d6ad92d5 1679 {
mluis 2:14a5d6ad92d5 1680 if( Channels[i + j].Frequency == 0 )
mluis 2:14a5d6ad92d5 1681 { // Check if the channel is enabled
mluis 2:14a5d6ad92d5 1682 continue;
mluis 2:14a5d6ad92d5 1683 }
mluis 2:14a5d6ad92d5 1684 if( ( ( Channels[i + j].DrRange.Fields.Min <= ChannelsDatarate ) &&
mluis 2:14a5d6ad92d5 1685 ( ChannelsDatarate <= Channels[i + j].DrRange.Fields.Max ) ) == false )
mluis 2:14a5d6ad92d5 1686 { // Check if the current channel selection supports the given datarate
mluis 2:14a5d6ad92d5 1687 continue;
mluis 2:14a5d6ad92d5 1688 }
mluis 2:14a5d6ad92d5 1689 if( Bands[Channels[i + j].Band].TimeOff > 0 )
mluis 2:14a5d6ad92d5 1690 { // Check if the band is available for transmission
mluis 3:b9d87593a8ae 1691 delayTx++;
mluis 2:14a5d6ad92d5 1692 continue;
mluis 2:14a5d6ad92d5 1693 }
mluis 2:14a5d6ad92d5 1694 enabledChannels[nbEnabledChannels++] = i + j;
mluis 2:14a5d6ad92d5 1695 }
mluis 2:14a5d6ad92d5 1696 }
mluis 2:14a5d6ad92d5 1697 }
mluis 2:14a5d6ad92d5 1698 }
mluis 2:14a5d6ad92d5 1699 else
mluis 2:14a5d6ad92d5 1700 {
mluis 3:b9d87593a8ae 1701 delayTx++;
mluis 2:14a5d6ad92d5 1702 nextTxDelay = AggregatedTimeOff - ( curTime - AggregatedLastTxDoneTime );
mluis 2:14a5d6ad92d5 1703 }
mluis 2:14a5d6ad92d5 1704
mluis 2:14a5d6ad92d5 1705 if( nbEnabledChannels > 0 )
mluis 2:14a5d6ad92d5 1706 {
mluis 2:14a5d6ad92d5 1707 Channel = enabledChannels[randr( 0, nbEnabledChannels - 1 )];
mluis 2:14a5d6ad92d5 1708 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 3:b9d87593a8ae 1709 if( Channel < ( LORA_MAX_NB_CHANNELS - 8 ) )
mluis 3:b9d87593a8ae 1710 {
mluis 3:b9d87593a8ae 1711 DisableChannelInMask( Channel, ChannelsMaskRemaining );
mluis 3:b9d87593a8ae 1712 }
mluis 2:14a5d6ad92d5 1713 #endif
mluis 3:b9d87593a8ae 1714 *time = 0;
mluis 3:b9d87593a8ae 1715 return true;
mluis 2:14a5d6ad92d5 1716 }
mluis 2:14a5d6ad92d5 1717 else
mluis 2:14a5d6ad92d5 1718 {
mluis 3:b9d87593a8ae 1719 if( delayTx > 0 )
mluis 3:b9d87593a8ae 1720 {
mluis 3:b9d87593a8ae 1721 // Delay transmission due to AggregatedTimeOff or to a band time off
mluis 3:b9d87593a8ae 1722 *time = nextTxDelay;
mluis 3:b9d87593a8ae 1723 return true;
mluis 3:b9d87593a8ae 1724 }
mluis 3:b9d87593a8ae 1725 // Datarate not supported by any channel
mluis 3:b9d87593a8ae 1726 *time = 0;
mluis 3:b9d87593a8ae 1727 return false;
mluis 2:14a5d6ad92d5 1728 }
mluis 2:14a5d6ad92d5 1729 }
mluis 2:14a5d6ad92d5 1730
mluis 2:14a5d6ad92d5 1731 static void SetPublicNetwork( bool enable )
mluis 2:14a5d6ad92d5 1732 {
mluis 2:14a5d6ad92d5 1733 PublicNetwork = enable;
mluis 2:14a5d6ad92d5 1734 Radio.SetModem( MODEM_LORA );
mluis 2:14a5d6ad92d5 1735 if( PublicNetwork == true )
mluis 2:14a5d6ad92d5 1736 {
mluis 2:14a5d6ad92d5 1737 // Change LoRa modem SyncWord
mluis 2:14a5d6ad92d5 1738 Radio.Write( REG_LR_SYNCWORD, LORA_MAC_PUBLIC_SYNCWORD );
mluis 2:14a5d6ad92d5 1739 }
mluis 2:14a5d6ad92d5 1740 else
mluis 2:14a5d6ad92d5 1741 {
mluis 2:14a5d6ad92d5 1742 // Change LoRa modem SyncWord
mluis 2:14a5d6ad92d5 1743 Radio.Write( REG_LR_SYNCWORD, LORA_MAC_PRIVATE_SYNCWORD );
mluis 2:14a5d6ad92d5 1744 }
mluis 2:14a5d6ad92d5 1745 }
mluis 2:14a5d6ad92d5 1746
mluis 2:14a5d6ad92d5 1747 static void RxWindowSetup( uint32_t freq, int8_t datarate, uint32_t bandwidth, uint16_t timeout, bool rxContinuous )
mluis 2:14a5d6ad92d5 1748 {
mluis 2:14a5d6ad92d5 1749 uint8_t downlinkDatarate = Datarates[datarate];
mluis 2:14a5d6ad92d5 1750 RadioModems_t modem;
mluis 2:14a5d6ad92d5 1751
mluis 2:14a5d6ad92d5 1752 if( Radio.GetStatus( ) == RF_IDLE )
mluis 2:14a5d6ad92d5 1753 {
mluis 2:14a5d6ad92d5 1754 Radio.SetChannel( freq );
mluis 2:14a5d6ad92d5 1755
mluis 2:14a5d6ad92d5 1756 // Store downlink datarate
mluis 2:14a5d6ad92d5 1757 McpsIndication.RxDatarate = ( uint8_t ) datarate;
mluis 2:14a5d6ad92d5 1758
mluis 2:14a5d6ad92d5 1759 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
mluis 2:14a5d6ad92d5 1760 if( datarate == DR_7 )
mluis 2:14a5d6ad92d5 1761 {
mluis 2:14a5d6ad92d5 1762 modem = MODEM_FSK;
mluis 2:14a5d6ad92d5 1763 Radio.SetRxConfig( modem, 50e3, downlinkDatarate * 1e3, 0, 83.333e3, 5, 0, false, 0, true, 0, 0, false, rxContinuous );
mluis 2:14a5d6ad92d5 1764 }
mluis 2:14a5d6ad92d5 1765 else
mluis 2:14a5d6ad92d5 1766 {
mluis 2:14a5d6ad92d5 1767 modem = MODEM_LORA;
mluis 2:14a5d6ad92d5 1768 Radio.SetRxConfig( modem, bandwidth, downlinkDatarate, 1, 0, 8, timeout, false, 0, false, 0, 0, true, rxContinuous );
mluis 2:14a5d6ad92d5 1769 }
mluis 2:14a5d6ad92d5 1770 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 2:14a5d6ad92d5 1771 modem = MODEM_LORA;
mluis 2:14a5d6ad92d5 1772 Radio.SetRxConfig( modem, bandwidth, downlinkDatarate, 1, 0, 8, timeout, false, 0, false, 0, 0, true, rxContinuous );
mluis 2:14a5d6ad92d5 1773 #endif
mluis 2:14a5d6ad92d5 1774
mluis 2:14a5d6ad92d5 1775 if( RepeaterSupport == true )
mluis 2:14a5d6ad92d5 1776 {
mluis 2:14a5d6ad92d5 1777 Radio.SetMaxPayloadLength( modem, MaxPayloadOfDatarateRepeater[datarate] );
mluis 2:14a5d6ad92d5 1778 }
mluis 2:14a5d6ad92d5 1779 else
mluis 2:14a5d6ad92d5 1780 {
mluis 2:14a5d6ad92d5 1781 Radio.SetMaxPayloadLength( modem, MaxPayloadOfDatarate[datarate] );
mluis 2:14a5d6ad92d5 1782 }
mluis 2:14a5d6ad92d5 1783
mluis 2:14a5d6ad92d5 1784 if( rxContinuous == false )
mluis 2:14a5d6ad92d5 1785 {
mluis 2:14a5d6ad92d5 1786 Radio.Rx( MaxRxWindow );
mluis 2:14a5d6ad92d5 1787 }
mluis 2:14a5d6ad92d5 1788 else
mluis 2:14a5d6ad92d5 1789 {
mluis 2:14a5d6ad92d5 1790 Radio.Rx( 0 ); // Continuous mode
mluis 2:14a5d6ad92d5 1791 }
mluis 2:14a5d6ad92d5 1792 }
mluis 2:14a5d6ad92d5 1793 }
mluis 2:14a5d6ad92d5 1794
mluis 2:14a5d6ad92d5 1795 static bool ValidatePayloadLength( uint8_t lenN, int8_t datarate, uint8_t fOptsLen )
mluis 2:14a5d6ad92d5 1796 {
mluis 2:14a5d6ad92d5 1797 uint16_t maxN = 0;
mluis 2:14a5d6ad92d5 1798 uint16_t payloadSize = 0;
mluis 2:14a5d6ad92d5 1799
mluis 2:14a5d6ad92d5 1800 // Get the maximum payload length
mluis 2:14a5d6ad92d5 1801 if( RepeaterSupport == true )
mluis 2:14a5d6ad92d5 1802 {
mluis 2:14a5d6ad92d5 1803 maxN = MaxPayloadOfDatarateRepeater[datarate];
mluis 2:14a5d6ad92d5 1804 }
mluis 2:14a5d6ad92d5 1805 else
mluis 2:14a5d6ad92d5 1806 {
mluis 2:14a5d6ad92d5 1807 maxN = MaxPayloadOfDatarate[datarate];
mluis 2:14a5d6ad92d5 1808 }
mluis 2:14a5d6ad92d5 1809
mluis 2:14a5d6ad92d5 1810 // Calculate the resulting payload size
mluis 2:14a5d6ad92d5 1811 payloadSize = ( lenN + fOptsLen );
mluis 2:14a5d6ad92d5 1812
mluis 2:14a5d6ad92d5 1813 // Validation of the application payload size
mluis 2:14a5d6ad92d5 1814 if( ( payloadSize <= maxN ) && ( payloadSize <= LORAMAC_PHY_MAXPAYLOAD ) )
mluis 2:14a5d6ad92d5 1815 {
mluis 2:14a5d6ad92d5 1816 return true;
mluis 2:14a5d6ad92d5 1817 }
mluis 2:14a5d6ad92d5 1818 return false;
mluis 2:14a5d6ad92d5 1819 }
mluis 2:14a5d6ad92d5 1820
mluis 2:14a5d6ad92d5 1821 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 2:14a5d6ad92d5 1822 static uint8_t CountNbEnabled125kHzChannels( uint16_t *channelsMask )
mluis 2:14a5d6ad92d5 1823 {
mluis 2:14a5d6ad92d5 1824 uint8_t nb125kHzChannels = 0;
mluis 2:14a5d6ad92d5 1825
mluis 2:14a5d6ad92d5 1826 for( uint8_t i = 0, k = 0; i < LORA_MAX_NB_CHANNELS - 8; i += 16, k++ )
mluis 2:14a5d6ad92d5 1827 {
mluis 2:14a5d6ad92d5 1828 for( uint8_t j = 0; j < 16; j++ )
mluis 2:14a5d6ad92d5 1829 {// Verify if the channel is active
mluis 2:14a5d6ad92d5 1830 if( ( channelsMask[k] & ( 1 << j ) ) == ( 1 << j ) )
mluis 2:14a5d6ad92d5 1831 {
mluis 2:14a5d6ad92d5 1832 nb125kHzChannels++;
mluis 2:14a5d6ad92d5 1833 }
mluis 2:14a5d6ad92d5 1834 }
mluis 2:14a5d6ad92d5 1835 }
mluis 2:14a5d6ad92d5 1836
mluis 2:14a5d6ad92d5 1837 return nb125kHzChannels;
mluis 2:14a5d6ad92d5 1838 }
mluis 2:14a5d6ad92d5 1839 #endif
mluis 2:14a5d6ad92d5 1840
mluis 2:14a5d6ad92d5 1841 static int8_t LimitTxPower( int8_t txPower )
mluis 2:14a5d6ad92d5 1842 {
mluis 2:14a5d6ad92d5 1843 int8_t resultTxPower = txPower;
mluis 2:14a5d6ad92d5 1844 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 2:14a5d6ad92d5 1845 if( ( ChannelsDatarate == DR_4 ) ||
mluis 2:14a5d6ad92d5 1846 ( ( ChannelsDatarate >= DR_8 ) && ( ChannelsDatarate <= DR_13 ) ) )
mluis 2:14a5d6ad92d5 1847 {// Limit tx power to max 26dBm
mluis 2:14a5d6ad92d5 1848 resultTxPower = MAX( txPower, TX_POWER_26_DBM );
mluis 2:14a5d6ad92d5 1849 }
mluis 2:14a5d6ad92d5 1850 else
mluis 2:14a5d6ad92d5 1851 {
mluis 2:14a5d6ad92d5 1852 if( CountNbEnabled125kHzChannels( ChannelsMask ) < 50 )
mluis 2:14a5d6ad92d5 1853 {// Limit tx power to max 21dBm
mluis 2:14a5d6ad92d5 1854 resultTxPower = MAX( txPower, TX_POWER_20_DBM );
mluis 2:14a5d6ad92d5 1855 }
mluis 2:14a5d6ad92d5 1856 }
mluis 2:14a5d6ad92d5 1857 #endif
mluis 2:14a5d6ad92d5 1858 return resultTxPower;
mluis 2:14a5d6ad92d5 1859 }
mluis 2:14a5d6ad92d5 1860
mluis 2:14a5d6ad92d5 1861 static bool ValueInRange( int8_t value, int8_t min, int8_t max )
mluis 2:14a5d6ad92d5 1862 {
mluis 2:14a5d6ad92d5 1863 if( ( value >= min ) && ( value <= max ) )
mluis 2:14a5d6ad92d5 1864 {
mluis 2:14a5d6ad92d5 1865 return true;
mluis 2:14a5d6ad92d5 1866 }
mluis 2:14a5d6ad92d5 1867 return false;
mluis 2:14a5d6ad92d5 1868 }
mluis 2:14a5d6ad92d5 1869
mluis 2:14a5d6ad92d5 1870 static bool DisableChannelInMask( uint8_t id, uint16_t* mask )
mluis 2:14a5d6ad92d5 1871 {
mluis 2:14a5d6ad92d5 1872 uint8_t index = 0;
mluis 2:14a5d6ad92d5 1873 index = id / 16;
mluis 2:14a5d6ad92d5 1874
mluis 2:14a5d6ad92d5 1875 if( ( index > 4 ) || ( id >= LORA_MAX_NB_CHANNELS ) )
mluis 2:14a5d6ad92d5 1876 {
mluis 2:14a5d6ad92d5 1877 return false;
mluis 2:14a5d6ad92d5 1878 }
mluis 2:14a5d6ad92d5 1879
mluis 2:14a5d6ad92d5 1880 // Deactivate channel
mluis 2:14a5d6ad92d5 1881 mask[index] &= ~( 1 << ( id % 16 ) );
mluis 2:14a5d6ad92d5 1882
mluis 2:14a5d6ad92d5 1883 return true;
mluis 2:14a5d6ad92d5 1884 }
mluis 2:14a5d6ad92d5 1885
mluis 2:14a5d6ad92d5 1886 static bool AdrNextDr( bool adrEnabled, bool updateChannelMask, int8_t* datarateOut )
mluis 2:14a5d6ad92d5 1887 {
mluis 2:14a5d6ad92d5 1888 bool adrAckReq = false;
mluis 2:14a5d6ad92d5 1889 int8_t datarate = ChannelsDatarate;
mluis 2:14a5d6ad92d5 1890
mluis 2:14a5d6ad92d5 1891 if( adrEnabled == true )
mluis 2:14a5d6ad92d5 1892 {
mluis 2:14a5d6ad92d5 1893 if( datarate == LORAMAC_MIN_DATARATE )
mluis 2:14a5d6ad92d5 1894 {
mluis 2:14a5d6ad92d5 1895 AdrAckCounter = 0;
mluis 2:14a5d6ad92d5 1896 adrAckReq = false;
mluis 0:91d1a7783bb9 1897 }
mluis 0:91d1a7783bb9 1898 else
mluis 0:91d1a7783bb9 1899 {
mluis 3:b9d87593a8ae 1900 if( AdrAckCounter >= ADR_ACK_LIMIT )
mluis 2:14a5d6ad92d5 1901 {
mluis 2:14a5d6ad92d5 1902 adrAckReq = true;
mluis 2:14a5d6ad92d5 1903 }
mluis 2:14a5d6ad92d5 1904 else
mluis 2:14a5d6ad92d5 1905 {
mluis 2:14a5d6ad92d5 1906 adrAckReq = false;
mluis 2:14a5d6ad92d5 1907 }
mluis 3:b9d87593a8ae 1908 if( AdrAckCounter >= ( ADR_ACK_LIMIT + ADR_ACK_DELAY ) )
mluis 0:91d1a7783bb9 1909 {
mluis 3:b9d87593a8ae 1910 if( ( ( AdrAckCounter - ADR_ACK_DELAY ) % ADR_ACK_LIMIT ) == 0 )
mluis 3:b9d87593a8ae 1911 {
mluis 2:14a5d6ad92d5 1912 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
mluis 3:b9d87593a8ae 1913 if( datarate > LORAMAC_MIN_DATARATE )
mluis 3:b9d87593a8ae 1914 {
mluis 3:b9d87593a8ae 1915 datarate--;
mluis 3:b9d87593a8ae 1916 }
mluis 3:b9d87593a8ae 1917 if( datarate == LORAMAC_MIN_DATARATE )
mluis 3:b9d87593a8ae 1918 {
mluis 3:b9d87593a8ae 1919 if( updateChannelMask == true )
mluis 3:b9d87593a8ae 1920 {
mluis 3:b9d87593a8ae 1921
mluis 3:b9d87593a8ae 1922 // Re-enable default channels LC1, LC2, LC3
mluis 3:b9d87593a8ae 1923 ChannelsMask[0] = ChannelsMask[0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) );
mluis 3:b9d87593a8ae 1924 }
mluis 3:b9d87593a8ae 1925 }
mluis 2:14a5d6ad92d5 1926 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 3:b9d87593a8ae 1927 if( ( datarate > LORAMAC_MIN_DATARATE ) && ( datarate == DR_8 ) )
mluis 3:b9d87593a8ae 1928 {
mluis 3:b9d87593a8ae 1929 datarate = DR_4;
mluis 3:b9d87593a8ae 1930 }
mluis 3:b9d87593a8ae 1931 else if( datarate > LORAMAC_MIN_DATARATE )
mluis 3:b9d87593a8ae 1932 {
mluis 3:b9d87593a8ae 1933 datarate--;
mluis 3:b9d87593a8ae 1934 }
mluis 3:b9d87593a8ae 1935 if( datarate == LORAMAC_MIN_DATARATE )
mluis 3:b9d87593a8ae 1936 {
mluis 3:b9d87593a8ae 1937 if( updateChannelMask == true )
mluis 3:b9d87593a8ae 1938 {
mluis 3:b9d87593a8ae 1939 #if defined( USE_BAND_915 )
mluis 3:b9d87593a8ae 1940 // Re-enable default channels
mluis 3:b9d87593a8ae 1941 ChannelsMask[0] = 0xFFFF;
mluis 3:b9d87593a8ae 1942 ChannelsMask[1] = 0xFFFF;
mluis 3:b9d87593a8ae 1943 ChannelsMask[2] = 0xFFFF;
mluis 3:b9d87593a8ae 1944 ChannelsMask[3] = 0xFFFF;
mluis 3:b9d87593a8ae 1945 ChannelsMask[4] = 0x00FF;
mluis 3:b9d87593a8ae 1946 ChannelsMask[5] = 0x0000;
mluis 3:b9d87593a8ae 1947 #else // defined( USE_BAND_915_HYBRID )
mluis 3:b9d87593a8ae 1948 // Re-enable default channels
mluis 3:b9d87593a8ae 1949 ChannelsMask[0] = 0x00FF;
mluis 3:b9d87593a8ae 1950 ChannelsMask[1] = 0x0000;
mluis 3:b9d87593a8ae 1951 ChannelsMask[2] = 0x0000;
mluis 3:b9d87593a8ae 1952 ChannelsMask[3] = 0x0000;
mluis 3:b9d87593a8ae 1953 ChannelsMask[4] = 0x0001;
mluis 3:b9d87593a8ae 1954 ChannelsMask[5] = 0x0000;
mluis 3:b9d87593a8ae 1955 #endif
mluis 3:b9d87593a8ae 1956 }
mluis 3:b9d87593a8ae 1957 }
mluis 2:14a5d6ad92d5 1958 #else
mluis 2:14a5d6ad92d5 1959 #error "Please define a frequency band in the compiler options."
mluis 2:14a5d6ad92d5 1960 #endif
mluis 3:b9d87593a8ae 1961 }
mluis 0:91d1a7783bb9 1962 }
mluis 0:91d1a7783bb9 1963 }
mluis 0:91d1a7783bb9 1964 }
mluis 2:14a5d6ad92d5 1965
mluis 2:14a5d6ad92d5 1966 *datarateOut = datarate;
mluis 2:14a5d6ad92d5 1967
mluis 2:14a5d6ad92d5 1968 return adrAckReq;
mluis 0:91d1a7783bb9 1969 }
mluis 0:91d1a7783bb9 1970
mluis 2:14a5d6ad92d5 1971 static LoRaMacStatus_t AddMacCommand( uint8_t cmd, uint8_t p1, uint8_t p2 )
mluis 0:91d1a7783bb9 1972 {
mluis 2:14a5d6ad92d5 1973 LoRaMacStatus_t status = LORAMAC_STATUS_BUSY;
mluis 1:91e4e6c60d1e 1974
mluis 0:91d1a7783bb9 1975 switch( cmd )
mluis 0:91d1a7783bb9 1976 {
mluis 0:91d1a7783bb9 1977 case MOTE_MAC_LINK_CHECK_REQ:
mluis 1:91e4e6c60d1e 1978 if( MacCommandsBufferIndex < LORA_MAC_COMMAND_MAX_LENGTH )
mluis 1:91e4e6c60d1e 1979 {
mluis 1:91e4e6c60d1e 1980 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
mluis 1:91e4e6c60d1e 1981 // No payload for this command
mluis 2:14a5d6ad92d5 1982 status = LORAMAC_STATUS_OK;
mluis 1:91e4e6c60d1e 1983 }
mluis 0:91d1a7783bb9 1984 break;
mluis 0:91d1a7783bb9 1985 case MOTE_MAC_LINK_ADR_ANS:
mluis 1:91e4e6c60d1e 1986 if( MacCommandsBufferIndex < ( LORA_MAC_COMMAND_MAX_LENGTH - 1 ) )
mluis 1:91e4e6c60d1e 1987 {
mluis 1:91e4e6c60d1e 1988 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
mluis 1:91e4e6c60d1e 1989 // Margin
mluis 1:91e4e6c60d1e 1990 MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
mluis 2:14a5d6ad92d5 1991 status = LORAMAC_STATUS_OK;
mluis 1:91e4e6c60d1e 1992 }
mluis 0:91d1a7783bb9 1993 break;
mluis 0:91d1a7783bb9 1994 case MOTE_MAC_DUTY_CYCLE_ANS:
mluis 1:91e4e6c60d1e 1995 if( MacCommandsBufferIndex < LORA_MAC_COMMAND_MAX_LENGTH )
mluis 1:91e4e6c60d1e 1996 {
mluis 1:91e4e6c60d1e 1997 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
mluis 1:91e4e6c60d1e 1998 // No payload for this answer
mluis 2:14a5d6ad92d5 1999 status = LORAMAC_STATUS_OK;
mluis 1:91e4e6c60d1e 2000 }
mluis 0:91d1a7783bb9 2001 break;
mluis 0:91d1a7783bb9 2002 case MOTE_MAC_RX_PARAM_SETUP_ANS:
mluis 1:91e4e6c60d1e 2003 if( MacCommandsBufferIndex < ( LORA_MAC_COMMAND_MAX_LENGTH - 1 ) )
mluis 1:91e4e6c60d1e 2004 {
mluis 1:91e4e6c60d1e 2005 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
mluis 1:91e4e6c60d1e 2006 // Status: Datarate ACK, Channel ACK
mluis 1:91e4e6c60d1e 2007 MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
mluis 2:14a5d6ad92d5 2008 status = LORAMAC_STATUS_OK;
mluis 1:91e4e6c60d1e 2009 }
mluis 0:91d1a7783bb9 2010 break;
mluis 0:91d1a7783bb9 2011 case MOTE_MAC_DEV_STATUS_ANS:
mluis 1:91e4e6c60d1e 2012 if( MacCommandsBufferIndex < ( LORA_MAC_COMMAND_MAX_LENGTH - 2 ) )
mluis 1:91e4e6c60d1e 2013 {
mluis 1:91e4e6c60d1e 2014 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
mluis 1:91e4e6c60d1e 2015 // 1st byte Battery
mluis 1:91e4e6c60d1e 2016 // 2nd byte Margin
mluis 1:91e4e6c60d1e 2017 MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
mluis 1:91e4e6c60d1e 2018 MacCommandsBuffer[MacCommandsBufferIndex++] = p2;
mluis 2:14a5d6ad92d5 2019 status = LORAMAC_STATUS_OK;
mluis 1:91e4e6c60d1e 2020 }
mluis 0:91d1a7783bb9 2021 break;
mluis 0:91d1a7783bb9 2022 case MOTE_MAC_NEW_CHANNEL_ANS:
mluis 1:91e4e6c60d1e 2023 if( MacCommandsBufferIndex < ( LORA_MAC_COMMAND_MAX_LENGTH - 1 ) )
mluis 1:91e4e6c60d1e 2024 {
mluis 1:91e4e6c60d1e 2025 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
mluis 1:91e4e6c60d1e 2026 // Status: Datarate range OK, Channel frequency OK
mluis 1:91e4e6c60d1e 2027 MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
mluis 2:14a5d6ad92d5 2028 status = LORAMAC_STATUS_OK;
mluis 1:91e4e6c60d1e 2029 }
mluis 0:91d1a7783bb9 2030 break;
mluis 0:91d1a7783bb9 2031 case MOTE_MAC_RX_TIMING_SETUP_ANS:
mluis 1:91e4e6c60d1e 2032 if( MacCommandsBufferIndex < LORA_MAC_COMMAND_MAX_LENGTH )
mluis 1:91e4e6c60d1e 2033 {
mluis 1:91e4e6c60d1e 2034 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
mluis 1:91e4e6c60d1e 2035 // No payload for this answer
mluis 2:14a5d6ad92d5 2036 status = LORAMAC_STATUS_OK;
mluis 1:91e4e6c60d1e 2037 }
mluis 0:91d1a7783bb9 2038 break;
mluis 0:91d1a7783bb9 2039 default:
mluis 2:14a5d6ad92d5 2040 return LORAMAC_STATUS_SERVICE_UNKNOWN;
mluis 0:91d1a7783bb9 2041 }
mluis 2:14a5d6ad92d5 2042 if( status == LORAMAC_STATUS_OK )
mluis 0:91d1a7783bb9 2043 {
mluis 0:91d1a7783bb9 2044 MacCommandsInNextTx = true;
mluis 0:91d1a7783bb9 2045 }
mluis 1:91e4e6c60d1e 2046 return status;
mluis 0:91d1a7783bb9 2047 }
mluis 0:91d1a7783bb9 2048
mluis 2:14a5d6ad92d5 2049 static void ProcessMacCommands( uint8_t *payload, uint8_t macIndex, uint8_t commandsSize, uint8_t snr )
mluis 0:91d1a7783bb9 2050 {
mluis 0:91d1a7783bb9 2051 while( macIndex < commandsSize )
mluis 0:91d1a7783bb9 2052 {
mluis 0:91d1a7783bb9 2053 // Decode Frame MAC commands
mluis 0:91d1a7783bb9 2054 switch( payload[macIndex++] )
mluis 0:91d1a7783bb9 2055 {
mluis 0:91d1a7783bb9 2056 case SRV_MAC_LINK_CHECK_ANS:
mluis 2:14a5d6ad92d5 2057 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_OK;
mluis 2:14a5d6ad92d5 2058 MlmeConfirm.DemodMargin = payload[macIndex++];
mluis 2:14a5d6ad92d5 2059 MlmeConfirm.NbGateways = payload[macIndex++];
mluis 0:91d1a7783bb9 2060 break;
mluis 0:91d1a7783bb9 2061 case SRV_MAC_LINK_ADR_REQ:
mluis 0:91d1a7783bb9 2062 {
mluis 2:14a5d6ad92d5 2063 uint8_t i;
mluis 0:91d1a7783bb9 2064 uint8_t status = 0x07;
mluis 0:91d1a7783bb9 2065 uint16_t chMask;
mluis 0:91d1a7783bb9 2066 int8_t txPower = 0;
mluis 0:91d1a7783bb9 2067 int8_t datarate = 0;
mluis 0:91d1a7783bb9 2068 uint8_t nbRep = 0;
mluis 0:91d1a7783bb9 2069 uint8_t chMaskCntl = 0;
mluis 0:91d1a7783bb9 2070 uint16_t channelsMask[6] = { 0, 0, 0, 0, 0, 0 };
mluis 2:14a5d6ad92d5 2071
mluis 0:91d1a7783bb9 2072 // Initialize local copy of the channels mask array
mluis 2:14a5d6ad92d5 2073 for( i = 0; i < 6; i++ )
mluis 0:91d1a7783bb9 2074 {
mluis 0:91d1a7783bb9 2075 channelsMask[i] = ChannelsMask[i];
mluis 0:91d1a7783bb9 2076 }
mluis 0:91d1a7783bb9 2077 datarate = payload[macIndex++];
mluis 0:91d1a7783bb9 2078 txPower = datarate & 0x0F;
mluis 0:91d1a7783bb9 2079 datarate = ( datarate >> 4 ) & 0x0F;
mluis 0:91d1a7783bb9 2080
mluis 2:14a5d6ad92d5 2081 if( ( AdrCtrlOn == false ) &&
mluis 0:91d1a7783bb9 2082 ( ( ChannelsDatarate != datarate ) || ( ChannelsTxPower != txPower ) ) )
mluis 0:91d1a7783bb9 2083 { // ADR disabled don't handle ADR requests if server tries to change datarate or txpower
mluis 0:91d1a7783bb9 2084 // Answer the server with fail status
mluis 0:91d1a7783bb9 2085 // Power ACK = 0
mluis 0:91d1a7783bb9 2086 // Data rate ACK = 0
mluis 0:91d1a7783bb9 2087 // Channel mask = 0
mluis 0:91d1a7783bb9 2088 AddMacCommand( MOTE_MAC_LINK_ADR_ANS, 0, 0 );
mluis 1:91e4e6c60d1e 2089 macIndex += 3; // Skip over the remaining bytes of the request
mluis 0:91d1a7783bb9 2090 break;
mluis 0:91d1a7783bb9 2091 }
mluis 1:91e4e6c60d1e 2092 chMask = ( uint16_t )payload[macIndex++];
mluis 1:91e4e6c60d1e 2093 chMask |= ( uint16_t )payload[macIndex++] << 8;
mluis 0:91d1a7783bb9 2094
mluis 0:91d1a7783bb9 2095 nbRep = payload[macIndex++];
mluis 0:91d1a7783bb9 2096 chMaskCntl = ( nbRep >> 4 ) & 0x07;
mluis 0:91d1a7783bb9 2097 nbRep &= 0x0F;
mluis 0:91d1a7783bb9 2098 if( nbRep == 0 )
mluis 0:91d1a7783bb9 2099 {
mluis 0:91d1a7783bb9 2100 nbRep = 1;
mluis 0:91d1a7783bb9 2101 }
mluis 0:91d1a7783bb9 2102 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
mluis 0:91d1a7783bb9 2103 if( ( chMaskCntl == 0 ) && ( chMask == 0 ) )
mluis 0:91d1a7783bb9 2104 {
mluis 0:91d1a7783bb9 2105 status &= 0xFE; // Channel mask KO
mluis 0:91d1a7783bb9 2106 }
mluis 2:14a5d6ad92d5 2107 else if( ( ( chMaskCntl >= 1 ) && ( chMaskCntl <= 5 )) ||
mluis 2:14a5d6ad92d5 2108 ( chMaskCntl >= 7 ) )
mluis 0:91d1a7783bb9 2109 {
mluis 0:91d1a7783bb9 2110 // RFU
mluis 0:91d1a7783bb9 2111 status &= 0xFE; // Channel mask KO
mluis 0:91d1a7783bb9 2112 }
mluis 0:91d1a7783bb9 2113 else
mluis 0:91d1a7783bb9 2114 {
mluis 2:14a5d6ad92d5 2115 for( i = 0; i < LORA_MAX_NB_CHANNELS; i++ )
mluis 0:91d1a7783bb9 2116 {
mluis 0:91d1a7783bb9 2117 if( chMaskCntl == 6 )
mluis 0:91d1a7783bb9 2118 {
mluis 0:91d1a7783bb9 2119 if( Channels[i].Frequency != 0 )
mluis 0:91d1a7783bb9 2120 {
mluis 0:91d1a7783bb9 2121 chMask |= 1 << i;
mluis 0:91d1a7783bb9 2122 }
mluis 0:91d1a7783bb9 2123 }
mluis 0:91d1a7783bb9 2124 else
mluis 0:91d1a7783bb9 2125 {
mluis 0:91d1a7783bb9 2126 if( ( ( chMask & ( 1 << i ) ) != 0 ) &&
mluis 0:91d1a7783bb9 2127 ( Channels[i].Frequency == 0 ) )
mluis 0:91d1a7783bb9 2128 {// Trying to enable an undefined channel
mluis 0:91d1a7783bb9 2129 status &= 0xFE; // Channel mask KO
mluis 0:91d1a7783bb9 2130 }
mluis 0:91d1a7783bb9 2131 }
mluis 0:91d1a7783bb9 2132 }
mluis 0:91d1a7783bb9 2133 channelsMask[0] = chMask;
mluis 0:91d1a7783bb9 2134 }
mluis 0:91d1a7783bb9 2135 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 0:91d1a7783bb9 2136 if( chMaskCntl == 6 )
mluis 0:91d1a7783bb9 2137 {
mluis 0:91d1a7783bb9 2138 // Enable all 125 kHz channels
mluis 0:91d1a7783bb9 2139 for( uint8_t i = 0, k = 0; i < LORA_MAX_NB_CHANNELS - 8; i += 16, k++ )
mluis 0:91d1a7783bb9 2140 {
mluis 0:91d1a7783bb9 2141 for( uint8_t j = 0; j < 16; j++ )
mluis 0:91d1a7783bb9 2142 {
mluis 0:91d1a7783bb9 2143 if( Channels[i + j].Frequency != 0 )
mluis 0:91d1a7783bb9 2144 {
mluis 0:91d1a7783bb9 2145 channelsMask[k] |= 1 << j;
mluis 0:91d1a7783bb9 2146 }
mluis 0:91d1a7783bb9 2147 }
mluis 0:91d1a7783bb9 2148 }
mluis 0:91d1a7783bb9 2149 }
mluis 0:91d1a7783bb9 2150 else if( chMaskCntl == 7 )
mluis 0:91d1a7783bb9 2151 {
mluis 0:91d1a7783bb9 2152 // Disable all 125 kHz channels
mluis 0:91d1a7783bb9 2153 channelsMask[0] = 0x0000;
mluis 0:91d1a7783bb9 2154 channelsMask[1] = 0x0000;
mluis 0:91d1a7783bb9 2155 channelsMask[2] = 0x0000;
mluis 0:91d1a7783bb9 2156 channelsMask[3] = 0x0000;
mluis 0:91d1a7783bb9 2157 }
mluis 0:91d1a7783bb9 2158 else if( chMaskCntl == 5 )
mluis 0:91d1a7783bb9 2159 {
mluis 0:91d1a7783bb9 2160 // RFU
mluis 0:91d1a7783bb9 2161 status &= 0xFE; // Channel mask KO
mluis 0:91d1a7783bb9 2162 }
mluis 0:91d1a7783bb9 2163 else
mluis 0:91d1a7783bb9 2164 {
mluis 0:91d1a7783bb9 2165 for( uint8_t i = 0; i < 16; i++ )
mluis 0:91d1a7783bb9 2166 {
mluis 0:91d1a7783bb9 2167 if( ( ( chMask & ( 1 << i ) ) != 0 ) &&
mluis 0:91d1a7783bb9 2168 ( Channels[chMaskCntl * 16 + i].Frequency == 0 ) )
mluis 0:91d1a7783bb9 2169 {// Trying to enable an undefined channel
mluis 0:91d1a7783bb9 2170 status &= 0xFE; // Channel mask KO
mluis 0:91d1a7783bb9 2171 }
mluis 0:91d1a7783bb9 2172 }
mluis 0:91d1a7783bb9 2173 channelsMask[chMaskCntl] = chMask;
mluis 2:14a5d6ad92d5 2174
mluis 0:91d1a7783bb9 2175 if( CountNbEnabled125kHzChannels( channelsMask ) < 6 )
mluis 0:91d1a7783bb9 2176 {
mluis 0:91d1a7783bb9 2177 status &= 0xFE; // Channel mask KO
mluis 0:91d1a7783bb9 2178 }
mluis 0:91d1a7783bb9 2179 }
mluis 0:91d1a7783bb9 2180 #else
mluis 0:91d1a7783bb9 2181 #error "Please define a frequency band in the compiler options."
mluis 0:91d1a7783bb9 2182 #endif
mluis 2:14a5d6ad92d5 2183 if( ValueInRange( datarate, LORAMAC_MIN_DATARATE, LORAMAC_MAX_DATARATE ) == false )
mluis 0:91d1a7783bb9 2184 {
mluis 0:91d1a7783bb9 2185 status &= 0xFD; // Datarate KO
mluis 0:91d1a7783bb9 2186 }
mluis 0:91d1a7783bb9 2187
mluis 0:91d1a7783bb9 2188 //
mluis 0:91d1a7783bb9 2189 // Remark MaxTxPower = 0 and MinTxPower = 5
mluis 0:91d1a7783bb9 2190 //
mluis 2:14a5d6ad92d5 2191 if( ValueInRange( txPower, LORAMAC_MAX_TX_POWER, LORAMAC_MIN_TX_POWER ) == false )
mluis 0:91d1a7783bb9 2192 {
mluis 0:91d1a7783bb9 2193 status &= 0xFB; // TxPower KO
mluis 0:91d1a7783bb9 2194 }
mluis 0:91d1a7783bb9 2195 if( ( status & 0x07 ) == 0x07 )
mluis 0:91d1a7783bb9 2196 {
mluis 0:91d1a7783bb9 2197 ChannelsDatarate = datarate;
mluis 0:91d1a7783bb9 2198 ChannelsTxPower = txPower;
mluis 0:91d1a7783bb9 2199 #if defined( USE_BAND_915_HYBRID )
mluis 0:91d1a7783bb9 2200 ChannelsMask[0] = channelsMask[0] & 0x00FF;
mluis 0:91d1a7783bb9 2201 ChannelsMask[1] = channelsMask[1] & 0x0000;
mluis 0:91d1a7783bb9 2202 ChannelsMask[2] = channelsMask[2] & 0x0000;
mluis 0:91d1a7783bb9 2203 ChannelsMask[3] = channelsMask[3] & 0x0000;
mluis 0:91d1a7783bb9 2204 ChannelsMask[4] = channelsMask[4] & 0x0001;
mluis 0:91d1a7783bb9 2205 ChannelsMask[5] = channelsMask[5] & 0x0000;
mluis 0:91d1a7783bb9 2206 #else
mluis 0:91d1a7783bb9 2207 ChannelsMask[0] = channelsMask[0];
mluis 0:91d1a7783bb9 2208 ChannelsMask[1] = channelsMask[1];
mluis 0:91d1a7783bb9 2209 ChannelsMask[2] = channelsMask[2];
mluis 0:91d1a7783bb9 2210 ChannelsMask[3] = channelsMask[3];
mluis 0:91d1a7783bb9 2211 ChannelsMask[4] = channelsMask[4];
mluis 0:91d1a7783bb9 2212 ChannelsMask[5] = channelsMask[5];
mluis 0:91d1a7783bb9 2213 #endif
mluis 0:91d1a7783bb9 2214 ChannelsNbRep = nbRep;
mluis 0:91d1a7783bb9 2215 }
mluis 0:91d1a7783bb9 2216 AddMacCommand( MOTE_MAC_LINK_ADR_ANS, status, 0 );
mluis 0:91d1a7783bb9 2217 }
mluis 0:91d1a7783bb9 2218 break;
mluis 0:91d1a7783bb9 2219 case SRV_MAC_DUTY_CYCLE_REQ:
mluis 0:91d1a7783bb9 2220 MaxDCycle = payload[macIndex++];
mluis 0:91d1a7783bb9 2221 AggregatedDCycle = 1 << MaxDCycle;
mluis 0:91d1a7783bb9 2222 AddMacCommand( MOTE_MAC_DUTY_CYCLE_ANS, 0, 0 );
mluis 0:91d1a7783bb9 2223 break;
mluis 0:91d1a7783bb9 2224 case SRV_MAC_RX_PARAM_SETUP_REQ:
mluis 0:91d1a7783bb9 2225 {
mluis 0:91d1a7783bb9 2226 uint8_t status = 0x07;
mluis 0:91d1a7783bb9 2227 int8_t datarate = 0;
mluis 0:91d1a7783bb9 2228 int8_t drOffset = 0;
mluis 0:91d1a7783bb9 2229 uint32_t freq = 0;
mluis 2:14a5d6ad92d5 2230
mluis 1:91e4e6c60d1e 2231 drOffset = ( payload[macIndex] >> 4 ) & 0x07;
mluis 1:91e4e6c60d1e 2232 datarate = payload[macIndex] & 0x0F;
mluis 1:91e4e6c60d1e 2233 macIndex++;
mluis 2:14a5d6ad92d5 2234
mluis 2:14a5d6ad92d5 2235 freq = ( uint32_t )payload[macIndex++];
mluis 0:91d1a7783bb9 2236 freq |= ( uint32_t )payload[macIndex++] << 8;
mluis 0:91d1a7783bb9 2237 freq |= ( uint32_t )payload[macIndex++] << 16;
mluis 0:91d1a7783bb9 2238 freq *= 100;
mluis 2:14a5d6ad92d5 2239
mluis 0:91d1a7783bb9 2240 if( Radio.CheckRfFrequency( freq ) == false )
mluis 0:91d1a7783bb9 2241 {
mluis 0:91d1a7783bb9 2242 status &= 0xFE; // Channel frequency KO
mluis 0:91d1a7783bb9 2243 }
mluis 2:14a5d6ad92d5 2244
mluis 2:14a5d6ad92d5 2245 if( ValueInRange( datarate, LORAMAC_MIN_DATARATE, LORAMAC_MAX_DATARATE ) == false )
mluis 0:91d1a7783bb9 2246 {
mluis 0:91d1a7783bb9 2247 status &= 0xFD; // Datarate KO
mluis 0:91d1a7783bb9 2248 }
mluis 2:14a5d6ad92d5 2249 #if ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) )
mluis 2:14a5d6ad92d5 2250 if( ( ValueInRange( datarate, DR_5, DR_7 ) == true ) ||
mluis 2:14a5d6ad92d5 2251 ( datarate > DR_13 ) )
mluis 2:14a5d6ad92d5 2252 {
mluis 2:14a5d6ad92d5 2253 status &= 0xFD; // Datarate KO
mluis 2:14a5d6ad92d5 2254 }
mluis 2:14a5d6ad92d5 2255 #endif
mluis 2:14a5d6ad92d5 2256 if( ValueInRange( drOffset, LORAMAC_MIN_RX1_DR_OFFSET, LORAMAC_MAX_RX1_DR_OFFSET ) == false )
mluis 0:91d1a7783bb9 2257 {
mluis 0:91d1a7783bb9 2258 status &= 0xFB; // Rx1DrOffset range KO
mluis 0:91d1a7783bb9 2259 }
mluis 2:14a5d6ad92d5 2260
mluis 0:91d1a7783bb9 2261 if( ( status & 0x07 ) == 0x07 )
mluis 0:91d1a7783bb9 2262 {
mluis 0:91d1a7783bb9 2263 Rx2Channel.Datarate = datarate;
mluis 0:91d1a7783bb9 2264 Rx2Channel.Frequency = freq;
mluis 0:91d1a7783bb9 2265 Rx1DrOffset = drOffset;
mluis 0:91d1a7783bb9 2266 }
mluis 0:91d1a7783bb9 2267 AddMacCommand( MOTE_MAC_RX_PARAM_SETUP_ANS, status, 0 );
mluis 0:91d1a7783bb9 2268 }
mluis 0:91d1a7783bb9 2269 break;
mluis 0:91d1a7783bb9 2270 case SRV_MAC_DEV_STATUS_REQ:
mluis 1:91e4e6c60d1e 2271 {
mluis 1:91e4e6c60d1e 2272 uint8_t batteryLevel = BAT_LEVEL_NO_MEASURE;
mluis 1:91e4e6c60d1e 2273 if( ( LoRaMacCallbacks != NULL ) && ( LoRaMacCallbacks->GetBatteryLevel != NULL ) )
mluis 1:91e4e6c60d1e 2274 {
mluis 1:91e4e6c60d1e 2275 batteryLevel = LoRaMacCallbacks->GetBatteryLevel( );
mluis 1:91e4e6c60d1e 2276 }
mluis 2:14a5d6ad92d5 2277 AddMacCommand( MOTE_MAC_DEV_STATUS_ANS, batteryLevel, snr );
mluis 2:14a5d6ad92d5 2278 break;
mluis 1:91e4e6c60d1e 2279 }
mluis 0:91d1a7783bb9 2280 case SRV_MAC_NEW_CHANNEL_REQ:
mluis 0:91d1a7783bb9 2281 {
mluis 0:91d1a7783bb9 2282 uint8_t status = 0x03;
mluis 3:b9d87593a8ae 2283
mluis 2:14a5d6ad92d5 2284 #if ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) )
mluis 3:b9d87593a8ae 2285 status &= 0xFC; // Channel frequency and datarate KO
mluis 3:b9d87593a8ae 2286 macIndex += 5;
mluis 2:14a5d6ad92d5 2287 #else
mluis 0:91d1a7783bb9 2288 int8_t channelIndex = 0;
mluis 0:91d1a7783bb9 2289 ChannelParams_t chParam;
mluis 2:14a5d6ad92d5 2290
mluis 0:91d1a7783bb9 2291 channelIndex = payload[macIndex++];
mluis 0:91d1a7783bb9 2292 chParam.Frequency = ( uint32_t )payload[macIndex++];
mluis 0:91d1a7783bb9 2293 chParam.Frequency |= ( uint32_t )payload[macIndex++] << 8;
mluis 0:91d1a7783bb9 2294 chParam.Frequency |= ( uint32_t )payload[macIndex++] << 16;
mluis 0:91d1a7783bb9 2295 chParam.Frequency *= 100;
mluis 0:91d1a7783bb9 2296 chParam.DrRange.Value = payload[macIndex++];
mluis 2:14a5d6ad92d5 2297
mluis 3:b9d87593a8ae 2298 LoRaMacState |= MAC_TX_CONFIG;
mluis 3:b9d87593a8ae 2299 if( chParam.Frequency == 0 )
mluis 0:91d1a7783bb9 2300 {
mluis 3:b9d87593a8ae 2301 if( channelIndex < 3 )
mluis 3:b9d87593a8ae 2302 {
mluis 3:b9d87593a8ae 2303 status &= 0xFC;
mluis 3:b9d87593a8ae 2304 }
mluis 3:b9d87593a8ae 2305 else
mluis 3:b9d87593a8ae 2306 {
mluis 3:b9d87593a8ae 2307 if( LoRaMacChannelRemove( channelIndex ) != LORAMAC_STATUS_OK )
mluis 3:b9d87593a8ae 2308 {
mluis 3:b9d87593a8ae 2309 status &= 0xFC;
mluis 3:b9d87593a8ae 2310 }
mluis 3:b9d87593a8ae 2311 }
mluis 0:91d1a7783bb9 2312 }
mluis 3:b9d87593a8ae 2313 else
mluis 0:91d1a7783bb9 2314 {
mluis 3:b9d87593a8ae 2315 switch( LoRaMacChannelAdd( channelIndex, chParam ) )
mluis 3:b9d87593a8ae 2316 {
mluis 3:b9d87593a8ae 2317 case LORAMAC_STATUS_OK:
mluis 3:b9d87593a8ae 2318 {
mluis 3:b9d87593a8ae 2319 break;
mluis 3:b9d87593a8ae 2320 }
mluis 3:b9d87593a8ae 2321 case LORAMAC_STATUS_FREQUENCY_INVALID:
mluis 3:b9d87593a8ae 2322 {
mluis 3:b9d87593a8ae 2323 status &= 0xFE;
mluis 3:b9d87593a8ae 2324 break;
mluis 3:b9d87593a8ae 2325 }
mluis 3:b9d87593a8ae 2326 case LORAMAC_STATUS_DATARATE_INVALID:
mluis 3:b9d87593a8ae 2327 {
mluis 3:b9d87593a8ae 2328 status &= 0xFD;
mluis 3:b9d87593a8ae 2329 break;
mluis 3:b9d87593a8ae 2330 }
mluis 3:b9d87593a8ae 2331 case LORAMAC_STATUS_FREQ_AND_DR_INVALID:
mluis 3:b9d87593a8ae 2332 {
mluis 3:b9d87593a8ae 2333 status &= 0xFC;
mluis 3:b9d87593a8ae 2334 break;
mluis 3:b9d87593a8ae 2335 }
mluis 3:b9d87593a8ae 2336 default:
mluis 3:b9d87593a8ae 2337 {
mluis 3:b9d87593a8ae 2338 status &= 0xFC;
mluis 3:b9d87593a8ae 2339 break;
mluis 3:b9d87593a8ae 2340 }
mluis 3:b9d87593a8ae 2341 }
mluis 0:91d1a7783bb9 2342 }
mluis 3:b9d87593a8ae 2343 LoRaMacState &= ~MAC_TX_CONFIG;
mluis 2:14a5d6ad92d5 2344 #endif
mluis 0:91d1a7783bb9 2345 AddMacCommand( MOTE_MAC_NEW_CHANNEL_ANS, status, 0 );
mluis 0:91d1a7783bb9 2346 }
mluis 0:91d1a7783bb9 2347 break;
mluis 0:91d1a7783bb9 2348 case SRV_MAC_RX_TIMING_SETUP_REQ:
mluis 0:91d1a7783bb9 2349 {
mluis 0:91d1a7783bb9 2350 uint8_t delay = payload[macIndex++] & 0x0F;
mluis 2:14a5d6ad92d5 2351
mluis 0:91d1a7783bb9 2352 if( delay == 0 )
mluis 0:91d1a7783bb9 2353 {
mluis 0:91d1a7783bb9 2354 delay++;
mluis 0:91d1a7783bb9 2355 }
mluis 0:91d1a7783bb9 2356 ReceiveDelay1 = delay * 1e6;
mluis 0:91d1a7783bb9 2357 ReceiveDelay2 = ReceiveDelay1 + 1e6;
mluis 0:91d1a7783bb9 2358 AddMacCommand( MOTE_MAC_RX_TIMING_SETUP_ANS, 0, 0 );
mluis 0:91d1a7783bb9 2359 }
mluis 0:91d1a7783bb9 2360 break;
mluis 0:91d1a7783bb9 2361 default:
mluis 0:91d1a7783bb9 2362 // Unknown command. ABORT MAC commands processing
mluis 0:91d1a7783bb9 2363 return;
mluis 0:91d1a7783bb9 2364 }
mluis 0:91d1a7783bb9 2365 }
mluis 0:91d1a7783bb9 2366 }
mluis 0:91d1a7783bb9 2367
mluis 2:14a5d6ad92d5 2368 LoRaMacStatus_t Send( LoRaMacHeader_t *macHdr, uint8_t fPort, void *fBuffer, uint16_t fBufferSize )
mluis 0:91d1a7783bb9 2369 {
mluis 2:14a5d6ad92d5 2370 LoRaMacFrameCtrl_t fCtrl;
mluis 2:14a5d6ad92d5 2371 LoRaMacStatus_t status = LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 2372
mluis 2:14a5d6ad92d5 2373 fCtrl.Value = 0;
mluis 2:14a5d6ad92d5 2374 fCtrl.Bits.FOptsLen = 0;
mluis 2:14a5d6ad92d5 2375 fCtrl.Bits.FPending = 0;
mluis 2:14a5d6ad92d5 2376 fCtrl.Bits.Ack = false;
mluis 2:14a5d6ad92d5 2377 fCtrl.Bits.AdrAckReq = false;
mluis 2:14a5d6ad92d5 2378 fCtrl.Bits.Adr = AdrCtrlOn;
mluis 2:14a5d6ad92d5 2379
mluis 2:14a5d6ad92d5 2380 // Prepare the frame
mluis 2:14a5d6ad92d5 2381 status = PrepareFrame( macHdr, &fCtrl, fPort, fBuffer, fBufferSize );
mluis 2:14a5d6ad92d5 2382
mluis 2:14a5d6ad92d5 2383 // Validate status
mluis 2:14a5d6ad92d5 2384 if( status != LORAMAC_STATUS_OK )
mluis 0:91d1a7783bb9 2385 {
mluis 2:14a5d6ad92d5 2386 return status;
mluis 0:91d1a7783bb9 2387 }
mluis 2:14a5d6ad92d5 2388
mluis 2:14a5d6ad92d5 2389 // Reset confirm parameters
mluis 2:14a5d6ad92d5 2390 McpsConfirm.NbRetries = 0;
mluis 2:14a5d6ad92d5 2391 McpsConfirm.AckReceived = false;
mluis 2:14a5d6ad92d5 2392 McpsConfirm.UpLinkCounter = UpLinkCounter;
mluis 2:14a5d6ad92d5 2393
mluis 2:14a5d6ad92d5 2394 status = ScheduleTx( );
mluis 2:14a5d6ad92d5 2395
mluis 2:14a5d6ad92d5 2396 return status;
mluis 0:91d1a7783bb9 2397 }
mluis 0:91d1a7783bb9 2398
mluis 2:14a5d6ad92d5 2399 static LoRaMacStatus_t ScheduleTx( )
mluis 0:91d1a7783bb9 2400 {
mluis 2:14a5d6ad92d5 2401 TimerTime_t dutyCycleTimeOff = 0;
mluis 2:14a5d6ad92d5 2402
mluis 2:14a5d6ad92d5 2403 // Check if the device is off
mluis 2:14a5d6ad92d5 2404 if( MaxDCycle == 255 )
mluis 2:14a5d6ad92d5 2405 {
mluis 2:14a5d6ad92d5 2406 return LORAMAC_STATUS_DEVICE_OFF;
mluis 2:14a5d6ad92d5 2407 }
mluis 2:14a5d6ad92d5 2408 if( MaxDCycle == 0 )
mluis 0:91d1a7783bb9 2409 {
mluis 2:14a5d6ad92d5 2410 AggregatedTimeOff = 0;
mluis 2:14a5d6ad92d5 2411 }
mluis 2:14a5d6ad92d5 2412
mluis 2:14a5d6ad92d5 2413 // Select channel
mluis 3:b9d87593a8ae 2414 while( SetNextChannel( &dutyCycleTimeOff ) == false )
mluis 3:b9d87593a8ae 2415 {
mluis 3:b9d87593a8ae 2416 // Set the default datarate
mluis 3:b9d87593a8ae 2417 ChannelsDatarate = ChannelsDefaultDatarate;
mluis 3:b9d87593a8ae 2418
mluis 3:b9d87593a8ae 2419 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
mluis 3:b9d87593a8ae 2420 // Re-enable default channels LC1, LC2, LC3
mluis 3:b9d87593a8ae 2421 ChannelsMask[0] = ChannelsMask[0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) );
mluis 3:b9d87593a8ae 2422 #endif
mluis 3:b9d87593a8ae 2423 }
mluis 2:14a5d6ad92d5 2424
mluis 2:14a5d6ad92d5 2425 // Schedule transmission of frame
mluis 2:14a5d6ad92d5 2426 if( dutyCycleTimeOff == 0 )
mluis 2:14a5d6ad92d5 2427 {
mluis 2:14a5d6ad92d5 2428 // Try to send now
mluis 2:14a5d6ad92d5 2429 return SendFrameOnChannel( Channels[Channel] );
mluis 0:91d1a7783bb9 2430 }
mluis 0:91d1a7783bb9 2431 else
mluis 0:91d1a7783bb9 2432 {
mluis 2:14a5d6ad92d5 2433 // Send later - prepare timer
mluis 2:14a5d6ad92d5 2434 LoRaMacState |= MAC_TX_DELAYED;
mluis 2:14a5d6ad92d5 2435 TimerSetValue( &TxDelayedTimer, dutyCycleTimeOff );
mluis 2:14a5d6ad92d5 2436 TimerStart( &TxDelayedTimer );
mluis 2:14a5d6ad92d5 2437
mluis 2:14a5d6ad92d5 2438 return LORAMAC_STATUS_OK;
mluis 0:91d1a7783bb9 2439 }
mluis 2:14a5d6ad92d5 2440 }
mluis 2:14a5d6ad92d5 2441
mluis 2:14a5d6ad92d5 2442 LoRaMacStatus_t PrepareFrame( LoRaMacHeader_t *macHdr, LoRaMacFrameCtrl_t *fCtrl, uint8_t fPort, void *fBuffer, uint16_t fBufferSize )
mluis 2:14a5d6ad92d5 2443 {
mluis 2:14a5d6ad92d5 2444 uint16_t i;
mluis 2:14a5d6ad92d5 2445 uint8_t pktHeaderLen = 0;
mluis 2:14a5d6ad92d5 2446 uint32_t mic = 0;
mluis 2:14a5d6ad92d5 2447 const void* payload = fBuffer;
mluis 2:14a5d6ad92d5 2448 uint8_t payloadSize = fBufferSize;
mluis 2:14a5d6ad92d5 2449 uint8_t framePort = fPort;
mluis 2:14a5d6ad92d5 2450
mluis 2:14a5d6ad92d5 2451 LoRaMacBufferPktLen = 0;
mluis 2:14a5d6ad92d5 2452
mluis 2:14a5d6ad92d5 2453 NodeAckRequested = false;
mluis 2:14a5d6ad92d5 2454
mluis 2:14a5d6ad92d5 2455 if( fBuffer == NULL )
mluis 0:91d1a7783bb9 2456 {
mluis 2:14a5d6ad92d5 2457 fBufferSize = 0;
mluis 2:14a5d6ad92d5 2458 }
mluis 2:14a5d6ad92d5 2459
mluis 2:14a5d6ad92d5 2460 LoRaMacBuffer[pktHeaderLen++] = macHdr->Value;
mluis 2:14a5d6ad92d5 2461
mluis 2:14a5d6ad92d5 2462 switch( macHdr->Bits.MType )
mluis 2:14a5d6ad92d5 2463 {
mluis 2:14a5d6ad92d5 2464 case FRAME_TYPE_JOIN_REQ:
mluis 2:14a5d6ad92d5 2465 RxWindow1Delay = JoinAcceptDelay1 - RADIO_WAKEUP_TIME;
mluis 2:14a5d6ad92d5 2466 RxWindow2Delay = JoinAcceptDelay2 - RADIO_WAKEUP_TIME;
mluis 2:14a5d6ad92d5 2467
mluis 2:14a5d6ad92d5 2468 LoRaMacBufferPktLen = pktHeaderLen;
mluis 2:14a5d6ad92d5 2469
mluis 2:14a5d6ad92d5 2470 memcpyr( LoRaMacBuffer + LoRaMacBufferPktLen, LoRaMacAppEui, 8 );
mluis 2:14a5d6ad92d5 2471 LoRaMacBufferPktLen += 8;
mluis 2:14a5d6ad92d5 2472 memcpyr( LoRaMacBuffer + LoRaMacBufferPktLen, LoRaMacDevEui, 8 );
mluis 2:14a5d6ad92d5 2473 LoRaMacBufferPktLen += 8;
mluis 2:14a5d6ad92d5 2474
mluis 2:14a5d6ad92d5 2475 LoRaMacDevNonce = Radio.Random( );
mluis 2:14a5d6ad92d5 2476
mluis 2:14a5d6ad92d5 2477 LoRaMacBuffer[LoRaMacBufferPktLen++] = LoRaMacDevNonce & 0xFF;
mluis 2:14a5d6ad92d5 2478 LoRaMacBuffer[LoRaMacBufferPktLen++] = ( LoRaMacDevNonce >> 8 ) & 0xFF;
mluis 2:14a5d6ad92d5 2479
mluis 2:14a5d6ad92d5 2480 LoRaMacJoinComputeMic( LoRaMacBuffer, LoRaMacBufferPktLen & 0xFF, LoRaMacAppKey, &mic );
mluis 2:14a5d6ad92d5 2481
mluis 2:14a5d6ad92d5 2482 LoRaMacBuffer[LoRaMacBufferPktLen++] = mic & 0xFF;
mluis 2:14a5d6ad92d5 2483 LoRaMacBuffer[LoRaMacBufferPktLen++] = ( mic >> 8 ) & 0xFF;
mluis 2:14a5d6ad92d5 2484 LoRaMacBuffer[LoRaMacBufferPktLen++] = ( mic >> 16 ) & 0xFF;
mluis 2:14a5d6ad92d5 2485 LoRaMacBuffer[LoRaMacBufferPktLen++] = ( mic >> 24 ) & 0xFF;
mluis 2:14a5d6ad92d5 2486
mluis 2:14a5d6ad92d5 2487 break;
mluis 2:14a5d6ad92d5 2488 case FRAME_TYPE_DATA_CONFIRMED_UP:
mluis 2:14a5d6ad92d5 2489 NodeAckRequested = true;
mluis 2:14a5d6ad92d5 2490 //Intentional falltrough
mluis 2:14a5d6ad92d5 2491 case FRAME_TYPE_DATA_UNCONFIRMED_UP:
mluis 2:14a5d6ad92d5 2492 if( IsLoRaMacNetworkJoined == false )
mluis 0:91d1a7783bb9 2493 {
mluis 2:14a5d6ad92d5 2494 return LORAMAC_STATUS_NO_NETWORK_JOINED; // No network has been joined yet
mluis 2:14a5d6ad92d5 2495 }
mluis 2:14a5d6ad92d5 2496
mluis 3:b9d87593a8ae 2497 fCtrl->Bits.AdrAckReq = AdrNextDr( fCtrl->Bits.Adr, true, &ChannelsDatarate );
mluis 3:b9d87593a8ae 2498
mluis 2:14a5d6ad92d5 2499 if( ValidatePayloadLength( fBufferSize, ChannelsDatarate, MacCommandsBufferIndex ) == false )
mluis 2:14a5d6ad92d5 2500 {
mluis 2:14a5d6ad92d5 2501 return LORAMAC_STATUS_LENGTH_ERROR;
mluis 2:14a5d6ad92d5 2502 }
mluis 2:14a5d6ad92d5 2503
mluis 2:14a5d6ad92d5 2504 RxWindow1Delay = ReceiveDelay1 - RADIO_WAKEUP_TIME;
mluis 2:14a5d6ad92d5 2505 RxWindow2Delay = ReceiveDelay2 - RADIO_WAKEUP_TIME;
mluis 2:14a5d6ad92d5 2506
mluis 2:14a5d6ad92d5 2507 if( SrvAckRequested == true )
mluis 2:14a5d6ad92d5 2508 {
mluis 2:14a5d6ad92d5 2509 SrvAckRequested = false;
mluis 2:14a5d6ad92d5 2510 fCtrl->Bits.Ack = 1;
mluis 2:14a5d6ad92d5 2511 }
mluis 2:14a5d6ad92d5 2512
mluis 2:14a5d6ad92d5 2513 LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr ) & 0xFF;
mluis 2:14a5d6ad92d5 2514 LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr >> 8 ) & 0xFF;
mluis 2:14a5d6ad92d5 2515 LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr >> 16 ) & 0xFF;
mluis 2:14a5d6ad92d5 2516 LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr >> 24 ) & 0xFF;
mluis 2:14a5d6ad92d5 2517
mluis 2:14a5d6ad92d5 2518 LoRaMacBuffer[pktHeaderLen++] = fCtrl->Value;
mluis 2:14a5d6ad92d5 2519
mluis 2:14a5d6ad92d5 2520 LoRaMacBuffer[pktHeaderLen++] = UpLinkCounter & 0xFF;
mluis 2:14a5d6ad92d5 2521 LoRaMacBuffer[pktHeaderLen++] = ( UpLinkCounter >> 8 ) & 0xFF;
mluis 2:14a5d6ad92d5 2522
mluis 2:14a5d6ad92d5 2523 if( ( payload != NULL ) && ( payloadSize > 0 ) )
mluis 2:14a5d6ad92d5 2524 {
mluis 2:14a5d6ad92d5 2525 if( ( MacCommandsBufferIndex <= LORA_MAC_COMMAND_MAX_LENGTH ) && ( MacCommandsInNextTx == true ) )
mluis 1:91e4e6c60d1e 2526 {
mluis 2:14a5d6ad92d5 2527 fCtrl->Bits.FOptsLen += MacCommandsBufferIndex;
mluis 2:14a5d6ad92d5 2528
mluis 2:14a5d6ad92d5 2529 // Update FCtrl field with new value of OptionsLength
mluis 2:14a5d6ad92d5 2530 LoRaMacBuffer[0x05] = fCtrl->Value;
mluis 2:14a5d6ad92d5 2531 for( i = 0; i < MacCommandsBufferIndex; i++ )
mluis 0:91d1a7783bb9 2532 {
mluis 2:14a5d6ad92d5 2533 LoRaMacBuffer[pktHeaderLen++] = MacCommandsBuffer[i];
mluis 0:91d1a7783bb9 2534 }
mluis 0:91d1a7783bb9 2535 }
mluis 0:91d1a7783bb9 2536 }
mluis 0:91d1a7783bb9 2537 else
mluis 0:91d1a7783bb9 2538 {
mluis 2:14a5d6ad92d5 2539 if( ( MacCommandsBufferIndex > 0 ) && ( MacCommandsInNextTx ) )
mluis 0:91d1a7783bb9 2540 {
mluis 2:14a5d6ad92d5 2541 payloadSize = MacCommandsBufferIndex;
mluis 2:14a5d6ad92d5 2542 payload = MacCommandsBuffer;
mluis 2:14a5d6ad92d5 2543 framePort = 0;
mluis 0:91d1a7783bb9 2544 }
mluis 2:14a5d6ad92d5 2545 }
mluis 2:14a5d6ad92d5 2546 MacCommandsInNextTx = false;
mluis 2:14a5d6ad92d5 2547 MacCommandsBufferIndex = 0;
mluis 2:14a5d6ad92d5 2548
mluis 2:14a5d6ad92d5 2549 if( ( payload != NULL ) && ( payloadSize > 0 ) )
mluis 2:14a5d6ad92d5 2550 {
mluis 2:14a5d6ad92d5 2551 LoRaMacBuffer[pktHeaderLen++] = framePort;
mluis 2:14a5d6ad92d5 2552
mluis 2:14a5d6ad92d5 2553 if( framePort == 0 )
mluis 0:91d1a7783bb9 2554 {
mluis 2:14a5d6ad92d5 2555 LoRaMacPayloadEncrypt( (uint8_t* ) payload, payloadSize, LoRaMacNwkSKey, LoRaMacDevAddr, UP_LINK, UpLinkCounter, LoRaMacPayload );
mluis 0:91d1a7783bb9 2556 }
mluis 0:91d1a7783bb9 2557 else
mluis 0:91d1a7783bb9 2558 {
mluis 2:14a5d6ad92d5 2559 LoRaMacPayloadEncrypt( (uint8_t* ) payload, payloadSize, LoRaMacAppSKey, LoRaMacDevAddr, UP_LINK, UpLinkCounter, LoRaMacPayload );
mluis 0:91d1a7783bb9 2560 }
mluis 2:14a5d6ad92d5 2561 memcpy1( LoRaMacBuffer + pktHeaderLen, LoRaMacPayload, payloadSize );
mluis 2:14a5d6ad92d5 2562 }
mluis 2:14a5d6ad92d5 2563 LoRaMacBufferPktLen = pktHeaderLen + payloadSize;
mluis 2:14a5d6ad92d5 2564
mluis 2:14a5d6ad92d5 2565 LoRaMacComputeMic( LoRaMacBuffer, LoRaMacBufferPktLen, LoRaMacNwkSKey, LoRaMacDevAddr, UP_LINK, UpLinkCounter, &mic );
mluis 2:14a5d6ad92d5 2566
mluis 2:14a5d6ad92d5 2567 LoRaMacBuffer[LoRaMacBufferPktLen + 0] = mic & 0xFF;
mluis 2:14a5d6ad92d5 2568 LoRaMacBuffer[LoRaMacBufferPktLen + 1] = ( mic >> 8 ) & 0xFF;
mluis 2:14a5d6ad92d5 2569 LoRaMacBuffer[LoRaMacBufferPktLen + 2] = ( mic >> 16 ) & 0xFF;
mluis 2:14a5d6ad92d5 2570 LoRaMacBuffer[LoRaMacBufferPktLen + 3] = ( mic >> 24 ) & 0xFF;
mluis 2:14a5d6ad92d5 2571
mluis 2:14a5d6ad92d5 2572 LoRaMacBufferPktLen += LORAMAC_MFR_LEN;
mluis 2:14a5d6ad92d5 2573
mluis 2:14a5d6ad92d5 2574 break;
mluis 2:14a5d6ad92d5 2575 case FRAME_TYPE_PROPRIETARY:
mluis 2:14a5d6ad92d5 2576 if( ( fBuffer != NULL ) && ( fBufferSize > 0 ) )
mluis 2:14a5d6ad92d5 2577 {
mluis 2:14a5d6ad92d5 2578 memcpy1( LoRaMacBuffer + pktHeaderLen, ( uint8_t* ) fBuffer, fBufferSize );
mluis 2:14a5d6ad92d5 2579 LoRaMacBufferPktLen = pktHeaderLen + fBufferSize;
mluis 0:91d1a7783bb9 2580 }
mluis 0:91d1a7783bb9 2581 break;
mluis 0:91d1a7783bb9 2582 default:
mluis 2:14a5d6ad92d5 2583 return LORAMAC_STATUS_SERVICE_UNKNOWN;
mluis 0:91d1a7783bb9 2584 }
mluis 2:14a5d6ad92d5 2585
mluis 2:14a5d6ad92d5 2586 return LORAMAC_STATUS_OK;
mluis 0:91d1a7783bb9 2587 }
mluis 0:91d1a7783bb9 2588
mluis 2:14a5d6ad92d5 2589 LoRaMacStatus_t SendFrameOnChannel( ChannelParams_t channel )
mluis 0:91d1a7783bb9 2590 {
mluis 2:14a5d6ad92d5 2591 int8_t datarate = Datarates[ChannelsDatarate];
mluis 2:14a5d6ad92d5 2592 int8_t txPower = 0;
mluis 2:14a5d6ad92d5 2593
mluis 2:14a5d6ad92d5 2594 ChannelsTxPower = LimitTxPower( ChannelsTxPower );
mluis 2:14a5d6ad92d5 2595 txPower = TxPowers[ChannelsTxPower];
mluis 2:14a5d6ad92d5 2596
mluis 2:14a5d6ad92d5 2597 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR;
mluis 2:14a5d6ad92d5 2598 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR;
mluis 2:14a5d6ad92d5 2599 McpsConfirm.Datarate = ChannelsDatarate;
mluis 2:14a5d6ad92d5 2600 McpsConfirm.TxPower = ChannelsTxPower;
mluis 2:14a5d6ad92d5 2601
mluis 2:14a5d6ad92d5 2602 Radio.SetChannel( channel.Frequency );
mluis 2:14a5d6ad92d5 2603
mluis 2:14a5d6ad92d5 2604 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
mluis 2:14a5d6ad92d5 2605 if( ChannelsDatarate == DR_7 )
mluis 2:14a5d6ad92d5 2606 { // High Speed FSK channel
mluis 2:14a5d6ad92d5 2607 Radio.SetMaxPayloadLength( MODEM_FSK, LoRaMacBufferPktLen );
mluis 2:14a5d6ad92d5 2608 Radio.SetTxConfig( MODEM_FSK, txPower, 25e3, 0, datarate * 1e3, 0, 5, false, true, 0, 0, false, 3e6 );
mluis 2:14a5d6ad92d5 2609 TxTimeOnAir = Radio.TimeOnAir( MODEM_FSK, LoRaMacBufferPktLen );
mluis 2:14a5d6ad92d5 2610
mluis 0:91d1a7783bb9 2611 }
mluis 2:14a5d6ad92d5 2612 else if( ChannelsDatarate == DR_6 )
mluis 2:14a5d6ad92d5 2613 { // High speed LoRa channel
mluis 2:14a5d6ad92d5 2614 Radio.SetMaxPayloadLength( MODEM_LORA, LoRaMacBufferPktLen );
mluis 2:14a5d6ad92d5 2615 Radio.SetTxConfig( MODEM_LORA, txPower, 0, 1, datarate, 1, 8, false, true, 0, 0, false, 3e6 );
mluis 2:14a5d6ad92d5 2616 TxTimeOnAir = Radio.TimeOnAir( MODEM_LORA, LoRaMacBufferPktLen );
mluis 0:91d1a7783bb9 2617 }
mluis 1:91e4e6c60d1e 2618 else
mluis 2:14a5d6ad92d5 2619 { // Normal LoRa channel
mluis 2:14a5d6ad92d5 2620 Radio.SetMaxPayloadLength( MODEM_LORA, LoRaMacBufferPktLen );
mluis 2:14a5d6ad92d5 2621 Radio.SetTxConfig( MODEM_LORA, txPower, 0, 0, datarate, 1, 8, false, true, 0, 0, false, 3e6 );
mluis 2:14a5d6ad92d5 2622 TxTimeOnAir = Radio.TimeOnAir( MODEM_LORA, LoRaMacBufferPktLen );
mluis 0:91d1a7783bb9 2623 }
mluis 2:14a5d6ad92d5 2624 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 2:14a5d6ad92d5 2625 Radio.SetMaxPayloadLength( MODEM_LORA, LoRaMacBufferPktLen );
mluis 2:14a5d6ad92d5 2626 if( ChannelsDatarate >= DR_4 )
mluis 2:14a5d6ad92d5 2627 { // High speed LoRa channel BW500 kHz
mluis 2:14a5d6ad92d5 2628 Radio.SetTxConfig( MODEM_LORA, txPower, 0, 2, datarate, 1, 8, false, true, 0, 0, false, 3e6 );
mluis 2:14a5d6ad92d5 2629 TxTimeOnAir = Radio.TimeOnAir( MODEM_LORA, LoRaMacBufferPktLen );
mluis 0:91d1a7783bb9 2630 }
mluis 1:91e4e6c60d1e 2631 else
mluis 2:14a5d6ad92d5 2632 { // Normal LoRa channel
mluis 2:14a5d6ad92d5 2633 Radio.SetTxConfig( MODEM_LORA, txPower, 0, 0, datarate, 1, 8, false, true, 0, 0, false, 3e6 );
mluis 2:14a5d6ad92d5 2634 TxTimeOnAir = Radio.TimeOnAir( MODEM_LORA, LoRaMacBufferPktLen );
mluis 0:91d1a7783bb9 2635 }
mluis 0:91d1a7783bb9 2636 #else
mluis 0:91d1a7783bb9 2637 #error "Please define a frequency band in the compiler options."
mluis 0:91d1a7783bb9 2638 #endif
mluis 2:14a5d6ad92d5 2639
mluis 2:14a5d6ad92d5 2640 // Store the time on air
mluis 2:14a5d6ad92d5 2641 McpsConfirm.TxTimeOnAir = TxTimeOnAir;
mluis 2:14a5d6ad92d5 2642 MlmeConfirm.TxTimeOnAir = TxTimeOnAir;
mluis 2:14a5d6ad92d5 2643
mluis 2:14a5d6ad92d5 2644 // Starts the MAC layer status check timer
mluis 3:b9d87593a8ae 2645 TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT );
mluis 2:14a5d6ad92d5 2646 TimerStart( &MacStateCheckTimer );
mluis 2:14a5d6ad92d5 2647
mluis 2:14a5d6ad92d5 2648 // Send now
mluis 2:14a5d6ad92d5 2649 Radio.Send( LoRaMacBuffer, LoRaMacBufferPktLen );
mluis 2:14a5d6ad92d5 2650
mluis 2:14a5d6ad92d5 2651 LoRaMacState |= MAC_TX_RUNNING;
mluis 2:14a5d6ad92d5 2652
mluis 2:14a5d6ad92d5 2653 return LORAMAC_STATUS_OK;
mluis 2:14a5d6ad92d5 2654 }
mluis 2:14a5d6ad92d5 2655
mluis 2:14a5d6ad92d5 2656 LoRaMacStatus_t LoRaMacInitialization( LoRaMacPrimitives_t *primitives, LoRaMacCallback_t *callbacks )
mluis 2:14a5d6ad92d5 2657 {
mluis 2:14a5d6ad92d5 2658 if( primitives == NULL )
mluis 2:14a5d6ad92d5 2659 {
mluis 2:14a5d6ad92d5 2660 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 2661 }
mluis 2:14a5d6ad92d5 2662
mluis 2:14a5d6ad92d5 2663 if( ( primitives->MacMcpsConfirm == NULL ) ||
mluis 2:14a5d6ad92d5 2664 ( primitives->MacMcpsIndication == NULL ) ||
mluis 2:14a5d6ad92d5 2665 ( primitives->MacMlmeConfirm == NULL ))
mluis 2:14a5d6ad92d5 2666 {
mluis 2:14a5d6ad92d5 2667 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 2668 }
mluis 2:14a5d6ad92d5 2669
mluis 2:14a5d6ad92d5 2670 LoRaMacPrimitives = primitives;
mluis 2:14a5d6ad92d5 2671 LoRaMacCallbacks = callbacks;
mluis 2:14a5d6ad92d5 2672
mluis 2:14a5d6ad92d5 2673 LoRaMacFlags.Value = 0;
mluis 2:14a5d6ad92d5 2674
mluis 2:14a5d6ad92d5 2675 LoRaMacDeviceClass = CLASS_A;
mluis 2:14a5d6ad92d5 2676
mluis 2:14a5d6ad92d5 2677 UpLinkCounter = 1;
mluis 2:14a5d6ad92d5 2678 DownLinkCounter = 0;
mluis 2:14a5d6ad92d5 2679 AdrAckCounter = 0;
mluis 2:14a5d6ad92d5 2680
mluis 2:14a5d6ad92d5 2681 RepeaterSupport = false;
mluis 2:14a5d6ad92d5 2682 IsRxWindowsEnabled = true;
mluis 2:14a5d6ad92d5 2683 IsLoRaMacNetworkJoined = false;
mluis 2:14a5d6ad92d5 2684 LoRaMacState = MAC_IDLE;
mluis 2:14a5d6ad92d5 2685
mluis 2:14a5d6ad92d5 2686 #if defined( USE_BAND_433 )
mluis 2:14a5d6ad92d5 2687 ChannelsMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 );
mluis 2:14a5d6ad92d5 2688 #elif defined( USE_BAND_780 )
mluis 2:14a5d6ad92d5 2689 ChannelsMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 );
mluis 2:14a5d6ad92d5 2690 #elif defined( USE_BAND_868 )
mluis 2:14a5d6ad92d5 2691 ChannelsMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 );
mluis 2:14a5d6ad92d5 2692 #elif defined( USE_BAND_915 )
mluis 2:14a5d6ad92d5 2693 ChannelsMask[0] = 0xFFFF;
mluis 2:14a5d6ad92d5 2694 ChannelsMask[1] = 0xFFFF;
mluis 2:14a5d6ad92d5 2695 ChannelsMask[2] = 0xFFFF;
mluis 2:14a5d6ad92d5 2696 ChannelsMask[3] = 0xFFFF;
mluis 2:14a5d6ad92d5 2697 ChannelsMask[4] = 0x00FF;
mluis 2:14a5d6ad92d5 2698 ChannelsMask[5] = 0x0000;
mluis 2:14a5d6ad92d5 2699
mluis 2:14a5d6ad92d5 2700 memcpy1( ( uint8_t* ) ChannelsMaskRemaining, ( uint8_t* ) ChannelsMask, sizeof( ChannelsMask ) );
mluis 2:14a5d6ad92d5 2701 #elif defined( USE_BAND_915_HYBRID )
mluis 2:14a5d6ad92d5 2702 ChannelsMask[0] = 0x00FF;
mluis 2:14a5d6ad92d5 2703 ChannelsMask[1] = 0x0000;
mluis 2:14a5d6ad92d5 2704 ChannelsMask[2] = 0x0000;
mluis 2:14a5d6ad92d5 2705 ChannelsMask[3] = 0x0000;
mluis 2:14a5d6ad92d5 2706 ChannelsMask[4] = 0x0001;
mluis 2:14a5d6ad92d5 2707 ChannelsMask[5] = 0x0000;
mluis 2:14a5d6ad92d5 2708
mluis 2:14a5d6ad92d5 2709 memcpy1( ( uint8_t* ) ChannelsMaskRemaining, ( uint8_t* ) ChannelsMask, sizeof( ChannelsMask ) );
mluis 2:14a5d6ad92d5 2710 #else
mluis 2:14a5d6ad92d5 2711 #error "Please define a frequency band in the compiler options."
mluis 2:14a5d6ad92d5 2712 #endif
mluis 2:14a5d6ad92d5 2713
mluis 2:14a5d6ad92d5 2714 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 2:14a5d6ad92d5 2715 // 125 kHz channels
mluis 2:14a5d6ad92d5 2716 for( uint8_t i = 0; i < LORA_MAX_NB_CHANNELS - 8; i++ )
mluis 0:91d1a7783bb9 2717 {
mluis 2:14a5d6ad92d5 2718 Channels[i].Frequency = 902.3e6 + i * 200e3;
mluis 2:14a5d6ad92d5 2719 Channels[i].DrRange.Value = ( DR_3 << 4 ) | DR_0;
mluis 2:14a5d6ad92d5 2720 Channels[i].Band = 0;
mluis 2:14a5d6ad92d5 2721 }
mluis 2:14a5d6ad92d5 2722 // 500 kHz channels
mluis 2:14a5d6ad92d5 2723 for( uint8_t i = LORA_MAX_NB_CHANNELS - 8; i < LORA_MAX_NB_CHANNELS; i++ )
mluis 2:14a5d6ad92d5 2724 {
mluis 2:14a5d6ad92d5 2725 Channels[i].Frequency = 903.0e6 + ( i - ( LORA_MAX_NB_CHANNELS - 8 ) ) * 1.6e6;
mluis 2:14a5d6ad92d5 2726 Channels[i].DrRange.Value = ( DR_4 << 4 ) | DR_4;
mluis 2:14a5d6ad92d5 2727 Channels[i].Band = 0;
mluis 2:14a5d6ad92d5 2728 }
mluis 2:14a5d6ad92d5 2729 #endif
mluis 2:14a5d6ad92d5 2730
mluis 2:14a5d6ad92d5 2731 ChannelsTxPower = LORAMAC_DEFAULT_TX_POWER;
mluis 2:14a5d6ad92d5 2732 ChannelsDefaultDatarate = ChannelsDatarate = LORAMAC_DEFAULT_DATARATE;
mluis 2:14a5d6ad92d5 2733 ChannelsNbRep = 1;
mluis 2:14a5d6ad92d5 2734 ChannelsNbRepCounter = 0;
mluis 2:14a5d6ad92d5 2735
mluis 2:14a5d6ad92d5 2736 MaxDCycle = 0;
mluis 2:14a5d6ad92d5 2737 AggregatedDCycle = 1;
mluis 2:14a5d6ad92d5 2738 AggregatedLastTxDoneTime = 0;
mluis 2:14a5d6ad92d5 2739 AggregatedTimeOff = 0;
mluis 2:14a5d6ad92d5 2740
mluis 2:14a5d6ad92d5 2741 #if defined( USE_BAND_433 )
mluis 2:14a5d6ad92d5 2742 DutyCycleOn = false;
mluis 2:14a5d6ad92d5 2743 #elif defined( USE_BAND_780 )
mluis 2:14a5d6ad92d5 2744 DutyCycleOn = false;
mluis 2:14a5d6ad92d5 2745 #elif defined( USE_BAND_868 )
mluis 2:14a5d6ad92d5 2746 DutyCycleOn = true;
mluis 2:14a5d6ad92d5 2747 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 2:14a5d6ad92d5 2748 DutyCycleOn = false;
mluis 2:14a5d6ad92d5 2749 #else
mluis 2:14a5d6ad92d5 2750 #error "Please define a frequency band in the compiler options."
mluis 2:14a5d6ad92d5 2751 #endif
mluis 2:14a5d6ad92d5 2752
mluis 2:14a5d6ad92d5 2753 MaxRxWindow = MAX_RX_WINDOW;
mluis 2:14a5d6ad92d5 2754 ReceiveDelay1 = RECEIVE_DELAY1;
mluis 2:14a5d6ad92d5 2755 ReceiveDelay2 = RECEIVE_DELAY2;
mluis 2:14a5d6ad92d5 2756 JoinAcceptDelay1 = JOIN_ACCEPT_DELAY1;
mluis 2:14a5d6ad92d5 2757 JoinAcceptDelay2 = JOIN_ACCEPT_DELAY2;
mluis 2:14a5d6ad92d5 2758
mluis 2:14a5d6ad92d5 2759 TimerInit( &MacStateCheckTimer, OnMacStateCheckTimerEvent );
mluis 2:14a5d6ad92d5 2760 TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT );
mluis 2:14a5d6ad92d5 2761
mluis 2:14a5d6ad92d5 2762 TimerInit( &TxDelayedTimer, OnTxDelayedTimerEvent );
mluis 2:14a5d6ad92d5 2763 TimerInit( &RxWindowTimer1, OnRxWindow1TimerEvent );
mluis 2:14a5d6ad92d5 2764 TimerInit( &RxWindowTimer2, OnRxWindow2TimerEvent );
mluis 2:14a5d6ad92d5 2765 TimerInit( &AckTimeoutTimer, OnAckTimeoutTimerEvent );
mluis 2:14a5d6ad92d5 2766
mluis 2:14a5d6ad92d5 2767 // Initialize Radio driver
mluis 2:14a5d6ad92d5 2768 RadioEvents.TxDone = OnRadioTxDone;
mluis 2:14a5d6ad92d5 2769 RadioEvents.RxDone = OnRadioRxDone;
mluis 2:14a5d6ad92d5 2770 RadioEvents.RxError = OnRadioRxError;
mluis 2:14a5d6ad92d5 2771 RadioEvents.TxTimeout = OnRadioTxTimeout;
mluis 2:14a5d6ad92d5 2772 RadioEvents.RxTimeout = OnRadioRxTimeout;
mluis 2:14a5d6ad92d5 2773 Radio.Init( &RadioEvents );
mluis 2:14a5d6ad92d5 2774
mluis 2:14a5d6ad92d5 2775 // Random seed initialization
mluis 2:14a5d6ad92d5 2776 srand1( Radio.Random( ) );
mluis 2:14a5d6ad92d5 2777
mluis 2:14a5d6ad92d5 2778 // Initialize channel index.
mluis 2:14a5d6ad92d5 2779 Channel = LORA_MAX_NB_CHANNELS;
mluis 2:14a5d6ad92d5 2780
mluis 2:14a5d6ad92d5 2781 PublicNetwork = true;
mluis 2:14a5d6ad92d5 2782 SetPublicNetwork( PublicNetwork );
mluis 2:14a5d6ad92d5 2783 Radio.Sleep( );
mluis 2:14a5d6ad92d5 2784
mluis 2:14a5d6ad92d5 2785 return LORAMAC_STATUS_OK;
mluis 2:14a5d6ad92d5 2786 }
mluis 2:14a5d6ad92d5 2787
mluis 2:14a5d6ad92d5 2788 LoRaMacStatus_t LoRaMacQueryTxPossible( uint8_t size, LoRaMacTxInfo_t* txInfo )
mluis 2:14a5d6ad92d5 2789 {
mluis 2:14a5d6ad92d5 2790 int8_t datarate = ChannelsDefaultDatarate;
mluis 2:14a5d6ad92d5 2791
mluis 2:14a5d6ad92d5 2792 if( txInfo == NULL )
mluis 2:14a5d6ad92d5 2793 {
mluis 2:14a5d6ad92d5 2794 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 2795 }
mluis 2:14a5d6ad92d5 2796
mluis 2:14a5d6ad92d5 2797 AdrNextDr( AdrCtrlOn, false, &datarate );
mluis 2:14a5d6ad92d5 2798
mluis 2:14a5d6ad92d5 2799 if( RepeaterSupport == true )
mluis 2:14a5d6ad92d5 2800 {
mluis 2:14a5d6ad92d5 2801 txInfo->CurrentPayloadSize = MaxPayloadOfDatarateRepeater[datarate];
mluis 0:91d1a7783bb9 2802 }
mluis 0:91d1a7783bb9 2803 else
mluis 0:91d1a7783bb9 2804 {
mluis 2:14a5d6ad92d5 2805 txInfo->CurrentPayloadSize = MaxPayloadOfDatarate[datarate];
mluis 0:91d1a7783bb9 2806 }
mluis 2:14a5d6ad92d5 2807
mluis 2:14a5d6ad92d5 2808 if( txInfo->CurrentPayloadSize >= MacCommandsBufferIndex )
mluis 0:91d1a7783bb9 2809 {
mluis 2:14a5d6ad92d5 2810 txInfo->MaxPossiblePayload = txInfo->CurrentPayloadSize - MacCommandsBufferIndex;
mluis 0:91d1a7783bb9 2811 }
mluis 0:91d1a7783bb9 2812 else
mluis 0:91d1a7783bb9 2813 {
mluis 2:14a5d6ad92d5 2814 return LORAMAC_STATUS_MAC_CMD_LENGTH_ERROR;
mluis 2:14a5d6ad92d5 2815 }
mluis 2:14a5d6ad92d5 2816
mluis 2:14a5d6ad92d5 2817 if( ValidatePayloadLength( size, datarate, 0 ) == false )
mluis 2:14a5d6ad92d5 2818 {
mluis 2:14a5d6ad92d5 2819 return LORAMAC_STATUS_LENGTH_ERROR;
mluis 0:91d1a7783bb9 2820 }
mluis 2:14a5d6ad92d5 2821
mluis 2:14a5d6ad92d5 2822 if( ValidatePayloadLength( size, datarate, MacCommandsBufferIndex ) == false )
mluis 0:91d1a7783bb9 2823 {
mluis 2:14a5d6ad92d5 2824 return LORAMAC_STATUS_MAC_CMD_LENGTH_ERROR;
mluis 0:91d1a7783bb9 2825 }
mluis 0:91d1a7783bb9 2826
mluis 2:14a5d6ad92d5 2827 return LORAMAC_STATUS_OK;
mluis 0:91d1a7783bb9 2828 }
mluis 0:91d1a7783bb9 2829
mluis 2:14a5d6ad92d5 2830 LoRaMacStatus_t LoRaMacMibGetRequestConfirm( MibRequestConfirm_t *mibGet )
mluis 0:91d1a7783bb9 2831 {
mluis 2:14a5d6ad92d5 2832 LoRaMacStatus_t status = LORAMAC_STATUS_OK;
mluis 2:14a5d6ad92d5 2833
mluis 2:14a5d6ad92d5 2834 if( mibGet == NULL )
mluis 2:14a5d6ad92d5 2835 {
mluis 2:14a5d6ad92d5 2836 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 2837 }
mluis 2:14a5d6ad92d5 2838
mluis 2:14a5d6ad92d5 2839 switch( mibGet->Type )
mluis 0:91d1a7783bb9 2840 {
mluis 2:14a5d6ad92d5 2841 case MIB_DEVICE_CLASS:
mluis 2:14a5d6ad92d5 2842 {
mluis 2:14a5d6ad92d5 2843 mibGet->Param.Class = LoRaMacDeviceClass;
mluis 2:14a5d6ad92d5 2844 break;
mluis 2:14a5d6ad92d5 2845 }
mluis 2:14a5d6ad92d5 2846 case MIB_NETWORK_JOINED:
mluis 2:14a5d6ad92d5 2847 {
mluis 2:14a5d6ad92d5 2848 mibGet->Param.IsNetworkJoined = IsLoRaMacNetworkJoined;
mluis 2:14a5d6ad92d5 2849 break;
mluis 2:14a5d6ad92d5 2850 }
mluis 2:14a5d6ad92d5 2851 case MIB_ADR:
mluis 2:14a5d6ad92d5 2852 {
mluis 2:14a5d6ad92d5 2853 mibGet->Param.AdrEnable = AdrCtrlOn;
mluis 2:14a5d6ad92d5 2854 break;
mluis 2:14a5d6ad92d5 2855 }
mluis 2:14a5d6ad92d5 2856 case MIB_NET_ID:
mluis 2:14a5d6ad92d5 2857 {
mluis 2:14a5d6ad92d5 2858 mibGet->Param.NetID = LoRaMacNetID;
mluis 2:14a5d6ad92d5 2859 break;
mluis 2:14a5d6ad92d5 2860 }
mluis 2:14a5d6ad92d5 2861 case MIB_DEV_ADDR:
mluis 2:14a5d6ad92d5 2862 {
mluis 2:14a5d6ad92d5 2863 mibGet->Param.DevAddr = LoRaMacDevAddr;
mluis 2:14a5d6ad92d5 2864 break;
mluis 2:14a5d6ad92d5 2865 }
mluis 2:14a5d6ad92d5 2866 case MIB_NWK_SKEY:
mluis 2:14a5d6ad92d5 2867 {
mluis 2:14a5d6ad92d5 2868 mibGet->Param.NwkSKey = LoRaMacNwkSKey;
mluis 2:14a5d6ad92d5 2869 break;
mluis 2:14a5d6ad92d5 2870 }
mluis 2:14a5d6ad92d5 2871 case MIB_APP_SKEY:
mluis 2:14a5d6ad92d5 2872 {
mluis 2:14a5d6ad92d5 2873 mibGet->Param.AppSKey = LoRaMacAppSKey;
mluis 2:14a5d6ad92d5 2874 break;
mluis 2:14a5d6ad92d5 2875 }
mluis 2:14a5d6ad92d5 2876 case MIB_PUBLIC_NETWORK:
mluis 2:14a5d6ad92d5 2877 {
mluis 2:14a5d6ad92d5 2878 mibGet->Param.EnablePublicNetwork = PublicNetwork;
mluis 2:14a5d6ad92d5 2879 break;
mluis 2:14a5d6ad92d5 2880 }
mluis 2:14a5d6ad92d5 2881 case MIB_REPEATER_SUPPORT:
mluis 2:14a5d6ad92d5 2882 {
mluis 2:14a5d6ad92d5 2883 mibGet->Param.EnableRepeaterSupport = RepeaterSupport;
mluis 2:14a5d6ad92d5 2884 break;
mluis 2:14a5d6ad92d5 2885 }
mluis 2:14a5d6ad92d5 2886 case MIB_CHANNELS:
mluis 2:14a5d6ad92d5 2887 {
mluis 2:14a5d6ad92d5 2888 mibGet->Param.ChannelList = Channels;
mluis 2:14a5d6ad92d5 2889 break;
mluis 2:14a5d6ad92d5 2890 }
mluis 2:14a5d6ad92d5 2891 case MIB_RX2_CHANNEL:
mluis 2:14a5d6ad92d5 2892 {
mluis 2:14a5d6ad92d5 2893 mibGet->Param.Rx2Channel = Rx2Channel;
mluis 2:14a5d6ad92d5 2894 break;
mluis 2:14a5d6ad92d5 2895 }
mluis 2:14a5d6ad92d5 2896 case MIB_CHANNELS_MASK:
mluis 2:14a5d6ad92d5 2897 {
mluis 2:14a5d6ad92d5 2898 mibGet->Param.ChannelsMask = ChannelsMask;
mluis 2:14a5d6ad92d5 2899 break;
mluis 0:91d1a7783bb9 2900 }
mluis 2:14a5d6ad92d5 2901 case MIB_CHANNELS_NB_REP:
mluis 2:14a5d6ad92d5 2902 {
mluis 2:14a5d6ad92d5 2903 mibGet->Param.ChannelNbRep = ChannelsNbRep;
mluis 2:14a5d6ad92d5 2904 break;
mluis 2:14a5d6ad92d5 2905 }
mluis 2:14a5d6ad92d5 2906 case MIB_MAX_RX_WINDOW_DURATION:
mluis 2:14a5d6ad92d5 2907 {
mluis 2:14a5d6ad92d5 2908 mibGet->Param.MaxRxWindow = MaxRxWindow;
mluis 2:14a5d6ad92d5 2909 break;
mluis 2:14a5d6ad92d5 2910 }
mluis 2:14a5d6ad92d5 2911 case MIB_RECEIVE_DELAY_1:
mluis 2:14a5d6ad92d5 2912 {
mluis 2:14a5d6ad92d5 2913 mibGet->Param.ReceiveDelay1 = ReceiveDelay1;
mluis 2:14a5d6ad92d5 2914 break;
mluis 2:14a5d6ad92d5 2915 }
mluis 2:14a5d6ad92d5 2916 case MIB_RECEIVE_DELAY_2:
mluis 2:14a5d6ad92d5 2917 {
mluis 2:14a5d6ad92d5 2918 mibGet->Param.ReceiveDelay2 = ReceiveDelay2;
mluis 2:14a5d6ad92d5 2919 break;
mluis 2:14a5d6ad92d5 2920 }
mluis 2:14a5d6ad92d5 2921 case MIB_JOIN_ACCEPT_DELAY_1:
mluis 2:14a5d6ad92d5 2922 {
mluis 2:14a5d6ad92d5 2923 mibGet->Param.JoinAcceptDelay1 = JoinAcceptDelay1;
mluis 2:14a5d6ad92d5 2924 break;
mluis 2:14a5d6ad92d5 2925 }
mluis 2:14a5d6ad92d5 2926 case MIB_JOIN_ACCEPT_DELAY_2:
mluis 2:14a5d6ad92d5 2927 {
mluis 2:14a5d6ad92d5 2928 mibGet->Param.JoinAcceptDelay2 = JoinAcceptDelay2;
mluis 2:14a5d6ad92d5 2929 break;
mluis 2:14a5d6ad92d5 2930 }
mluis 2:14a5d6ad92d5 2931 case MIB_CHANNELS_DATARATE:
mluis 2:14a5d6ad92d5 2932 {
mluis 2:14a5d6ad92d5 2933 mibGet->Param.ChannelsDatarate = ChannelsDatarate;
mluis 2:14a5d6ad92d5 2934 break;
mluis 2:14a5d6ad92d5 2935 }
mluis 2:14a5d6ad92d5 2936 case MIB_CHANNELS_TX_POWER:
mluis 2:14a5d6ad92d5 2937 {
mluis 2:14a5d6ad92d5 2938 mibGet->Param.ChannelsTxPower = ChannelsTxPower;
mluis 2:14a5d6ad92d5 2939 break;
mluis 2:14a5d6ad92d5 2940 }
mluis 2:14a5d6ad92d5 2941 case MIB_UPLINK_COUNTER:
mluis 2:14a5d6ad92d5 2942 {
mluis 2:14a5d6ad92d5 2943 mibGet->Param.UpLinkCounter = UpLinkCounter;
mluis 2:14a5d6ad92d5 2944 break;
mluis 2:14a5d6ad92d5 2945 }
mluis 2:14a5d6ad92d5 2946 case MIB_DOWNLINK_COUNTER:
mluis 2:14a5d6ad92d5 2947 {
mluis 2:14a5d6ad92d5 2948 mibGet->Param.DownLinkCounter = DownLinkCounter;
mluis 2:14a5d6ad92d5 2949 break;
mluis 2:14a5d6ad92d5 2950 }
mluis 2:14a5d6ad92d5 2951 case MIB_MULTICAST_CHANNEL:
mluis 2:14a5d6ad92d5 2952 {
mluis 2:14a5d6ad92d5 2953 mibGet->Param.MulticastList = MulticastChannels;
mluis 2:14a5d6ad92d5 2954 break;
mluis 2:14a5d6ad92d5 2955 }
mluis 2:14a5d6ad92d5 2956 default:
mluis 2:14a5d6ad92d5 2957 status = LORAMAC_STATUS_SERVICE_UNKNOWN;
mluis 2:14a5d6ad92d5 2958 break;
mluis 0:91d1a7783bb9 2959 }
mluis 0:91d1a7783bb9 2960
mluis 2:14a5d6ad92d5 2961 return status;
mluis 0:91d1a7783bb9 2962 }
mluis 2:14a5d6ad92d5 2963
mluis 2:14a5d6ad92d5 2964 LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSet )
mluis 0:91d1a7783bb9 2965 {
mluis 2:14a5d6ad92d5 2966 LoRaMacStatus_t status = LORAMAC_STATUS_OK;
mluis 2:14a5d6ad92d5 2967
mluis 2:14a5d6ad92d5 2968 if( mibSet == NULL )
mluis 2:14a5d6ad92d5 2969 {
mluis 2:14a5d6ad92d5 2970 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 0:91d1a7783bb9 2971 }
mluis 0:91d1a7783bb9 2972 if( ( LoRaMacState & MAC_TX_RUNNING ) == MAC_TX_RUNNING )
mluis 0:91d1a7783bb9 2973 {
mluis 2:14a5d6ad92d5 2974 return LORAMAC_STATUS_BUSY;
mluis 0:91d1a7783bb9 2975 }
mluis 2:14a5d6ad92d5 2976
mluis 2:14a5d6ad92d5 2977 switch( mibSet->Type )
mluis 0:91d1a7783bb9 2978 {
mluis 2:14a5d6ad92d5 2979 case MIB_DEVICE_CLASS:
mluis 2:14a5d6ad92d5 2980 {
mluis 2:14a5d6ad92d5 2981 LoRaMacDeviceClass = mibSet->Param.Class;
mluis 2:14a5d6ad92d5 2982 switch( LoRaMacDeviceClass )
mluis 2:14a5d6ad92d5 2983 {
mluis 2:14a5d6ad92d5 2984 case CLASS_A:
mluis 2:14a5d6ad92d5 2985 {
mluis 2:14a5d6ad92d5 2986 // Set the radio into sleep to setup a defined state
mluis 2:14a5d6ad92d5 2987 Radio.Sleep( );
mluis 2:14a5d6ad92d5 2988 break;
mluis 2:14a5d6ad92d5 2989 }
mluis 2:14a5d6ad92d5 2990 case CLASS_B:
mluis 2:14a5d6ad92d5 2991 {
mluis 2:14a5d6ad92d5 2992 break;
mluis 2:14a5d6ad92d5 2993 }
mluis 2:14a5d6ad92d5 2994 case CLASS_C:
mluis 2:14a5d6ad92d5 2995 {
mluis 2:14a5d6ad92d5 2996 // Set the NodeAckRequested indicator to default
mluis 2:14a5d6ad92d5 2997 NodeAckRequested = false;
mluis 2:14a5d6ad92d5 2998 OnRxWindow2TimerEvent( );
mluis 2:14a5d6ad92d5 2999 break;
mluis 2:14a5d6ad92d5 3000 }
mluis 2:14a5d6ad92d5 3001 }
mluis 2:14a5d6ad92d5 3002 break;
mluis 2:14a5d6ad92d5 3003 }
mluis 2:14a5d6ad92d5 3004 case MIB_NETWORK_JOINED:
mluis 2:14a5d6ad92d5 3005 {
mluis 2:14a5d6ad92d5 3006 IsLoRaMacNetworkJoined = mibSet->Param.IsNetworkJoined;
mluis 2:14a5d6ad92d5 3007 break;
mluis 2:14a5d6ad92d5 3008 }
mluis 2:14a5d6ad92d5 3009 case MIB_ADR:
mluis 2:14a5d6ad92d5 3010 {
mluis 2:14a5d6ad92d5 3011 AdrCtrlOn = mibSet->Param.AdrEnable;
mluis 2:14a5d6ad92d5 3012 break;
mluis 2:14a5d6ad92d5 3013 }
mluis 2:14a5d6ad92d5 3014 case MIB_NET_ID:
mluis 2:14a5d6ad92d5 3015 {
mluis 2:14a5d6ad92d5 3016 LoRaMacNetID = mibSet->Param.NetID;
mluis 2:14a5d6ad92d5 3017 break;
mluis 2:14a5d6ad92d5 3018 }
mluis 2:14a5d6ad92d5 3019 case MIB_DEV_ADDR:
mluis 2:14a5d6ad92d5 3020 {
mluis 2:14a5d6ad92d5 3021 LoRaMacDevAddr = mibSet->Param.DevAddr;
mluis 2:14a5d6ad92d5 3022 break;
mluis 2:14a5d6ad92d5 3023 }
mluis 2:14a5d6ad92d5 3024 case MIB_NWK_SKEY:
mluis 0:91d1a7783bb9 3025 {
mluis 2:14a5d6ad92d5 3026 if( mibSet->Param.NwkSKey != NULL )
mluis 2:14a5d6ad92d5 3027 {
mluis 2:14a5d6ad92d5 3028 memcpy1( LoRaMacNwkSKey, mibSet->Param.NwkSKey,
mluis 2:14a5d6ad92d5 3029 sizeof( LoRaMacNwkSKey ) );
mluis 2:14a5d6ad92d5 3030 }
mluis 2:14a5d6ad92d5 3031 else
mluis 2:14a5d6ad92d5 3032 {
mluis 2:14a5d6ad92d5 3033 status = LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 3034 }
mluis 2:14a5d6ad92d5 3035 break;
mluis 2:14a5d6ad92d5 3036 }
mluis 2:14a5d6ad92d5 3037 case MIB_APP_SKEY:
mluis 2:14a5d6ad92d5 3038 {
mluis 2:14a5d6ad92d5 3039 if( mibSet->Param.AppSKey != NULL )
mluis 2:14a5d6ad92d5 3040 {
mluis 2:14a5d6ad92d5 3041 memcpy1( LoRaMacAppSKey, mibSet->Param.AppSKey,
mluis 2:14a5d6ad92d5 3042 sizeof( LoRaMacAppSKey ) );
mluis 2:14a5d6ad92d5 3043 }
mluis 2:14a5d6ad92d5 3044 else
mluis 2:14a5d6ad92d5 3045 {
mluis 2:14a5d6ad92d5 3046 status = LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 3047 }
mluis 2:14a5d6ad92d5 3048 break;
mluis 2:14a5d6ad92d5 3049 }
mluis 2:14a5d6ad92d5 3050 case MIB_PUBLIC_NETWORK:
mluis 2:14a5d6ad92d5 3051 {
mluis 2:14a5d6ad92d5 3052 SetPublicNetwork( mibSet->Param.EnablePublicNetwork );
mluis 2:14a5d6ad92d5 3053 break;
mluis 0:91d1a7783bb9 3054 }
mluis 2:14a5d6ad92d5 3055 case MIB_REPEATER_SUPPORT:
mluis 2:14a5d6ad92d5 3056 {
mluis 2:14a5d6ad92d5 3057 RepeaterSupport = mibSet->Param.EnableRepeaterSupport;
mluis 2:14a5d6ad92d5 3058 break;
mluis 2:14a5d6ad92d5 3059 }
mluis 2:14a5d6ad92d5 3060 case MIB_RX2_CHANNEL:
mluis 2:14a5d6ad92d5 3061 {
mluis 2:14a5d6ad92d5 3062 Rx2Channel = mibSet->Param.Rx2Channel;
mluis 2:14a5d6ad92d5 3063 break;
mluis 2:14a5d6ad92d5 3064 }
mluis 2:14a5d6ad92d5 3065 case MIB_CHANNELS_MASK:
mluis 2:14a5d6ad92d5 3066 {
mluis 2:14a5d6ad92d5 3067 if( mibSet->Param.ChannelsMask )
mluis 2:14a5d6ad92d5 3068 {
mluis 2:14a5d6ad92d5 3069 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 2:14a5d6ad92d5 3070 if( ( CountNbEnabled125kHzChannels( mibSet->Param.ChannelsMask ) < 6 ) &&
mluis 2:14a5d6ad92d5 3071 ( CountNbEnabled125kHzChannels( mibSet->Param.ChannelsMask ) > 0 ) )
mluis 2:14a5d6ad92d5 3072 {
mluis 2:14a5d6ad92d5 3073 status = LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 3074 }
mluis 2:14a5d6ad92d5 3075 else
mluis 2:14a5d6ad92d5 3076 {
mluis 2:14a5d6ad92d5 3077 memcpy1( ( uint8_t* ) ChannelsMask,
mluis 2:14a5d6ad92d5 3078 ( uint8_t* ) mibSet->Param.ChannelsMask, sizeof( ChannelsMask ) );
mluis 2:14a5d6ad92d5 3079 for ( uint8_t i = 0; i < sizeof( ChannelsMask ) / 2; i++ )
mluis 2:14a5d6ad92d5 3080 {
mluis 2:14a5d6ad92d5 3081 ChannelsMaskRemaining[i] &= ChannelsMask[i];
mluis 2:14a5d6ad92d5 3082 }
mluis 2:14a5d6ad92d5 3083 }
mluis 0:91d1a7783bb9 3084 #else
mluis 2:14a5d6ad92d5 3085 memcpy1( ( uint8_t* ) ChannelsMask,
mluis 2:14a5d6ad92d5 3086 ( uint8_t* ) mibSet->Param.ChannelsMask, 2 );
mluis 0:91d1a7783bb9 3087 #endif
mluis 2:14a5d6ad92d5 3088 }
mluis 2:14a5d6ad92d5 3089 else
mluis 2:14a5d6ad92d5 3090 {
mluis 2:14a5d6ad92d5 3091 status = LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 3092 }
mluis 2:14a5d6ad92d5 3093 break;
mluis 2:14a5d6ad92d5 3094 }
mluis 2:14a5d6ad92d5 3095 case MIB_CHANNELS_NB_REP:
mluis 2:14a5d6ad92d5 3096 {
mluis 2:14a5d6ad92d5 3097 if( ( mibSet->Param.ChannelNbRep >= 1 ) &&
mluis 2:14a5d6ad92d5 3098 ( mibSet->Param.ChannelNbRep <= 15 ) )
mluis 2:14a5d6ad92d5 3099 {
mluis 2:14a5d6ad92d5 3100 ChannelsNbRep = mibSet->Param.ChannelNbRep;
mluis 2:14a5d6ad92d5 3101 }
mluis 2:14a5d6ad92d5 3102 else
mluis 2:14a5d6ad92d5 3103 {
mluis 2:14a5d6ad92d5 3104 status = LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 3105 }
mluis 2:14a5d6ad92d5 3106 break;
mluis 2:14a5d6ad92d5 3107 }
mluis 2:14a5d6ad92d5 3108 case MIB_MAX_RX_WINDOW_DURATION:
mluis 2:14a5d6ad92d5 3109 {
mluis 2:14a5d6ad92d5 3110 MaxRxWindow = mibSet->Param.MaxRxWindow;
mluis 2:14a5d6ad92d5 3111 break;
mluis 2:14a5d6ad92d5 3112 }
mluis 2:14a5d6ad92d5 3113 case MIB_RECEIVE_DELAY_1:
mluis 2:14a5d6ad92d5 3114 {
mluis 2:14a5d6ad92d5 3115 ReceiveDelay1 = mibSet->Param.ReceiveDelay1;
mluis 2:14a5d6ad92d5 3116 break;
mluis 2:14a5d6ad92d5 3117 }
mluis 2:14a5d6ad92d5 3118 case MIB_RECEIVE_DELAY_2:
mluis 2:14a5d6ad92d5 3119 {
mluis 2:14a5d6ad92d5 3120 ReceiveDelay2 = mibSet->Param.ReceiveDelay2;
mluis 2:14a5d6ad92d5 3121 break;
mluis 2:14a5d6ad92d5 3122 }
mluis 2:14a5d6ad92d5 3123 case MIB_JOIN_ACCEPT_DELAY_1:
mluis 2:14a5d6ad92d5 3124 {
mluis 2:14a5d6ad92d5 3125 JoinAcceptDelay1 = mibSet->Param.JoinAcceptDelay1;
mluis 2:14a5d6ad92d5 3126 break;
mluis 2:14a5d6ad92d5 3127 }
mluis 2:14a5d6ad92d5 3128 case MIB_JOIN_ACCEPT_DELAY_2:
mluis 2:14a5d6ad92d5 3129 {
mluis 2:14a5d6ad92d5 3130 JoinAcceptDelay2 = mibSet->Param.JoinAcceptDelay2;
mluis 2:14a5d6ad92d5 3131 break;
mluis 2:14a5d6ad92d5 3132 }
mluis 2:14a5d6ad92d5 3133 case MIB_CHANNELS_DATARATE:
mluis 2:14a5d6ad92d5 3134 {
mluis 2:14a5d6ad92d5 3135 if( ValueInRange( mibSet->Param.ChannelsDatarate,
mluis 2:14a5d6ad92d5 3136 LORAMAC_MIN_DATARATE, LORAMAC_MAX_DATARATE ) )
mluis 2:14a5d6ad92d5 3137 {
mluis 2:14a5d6ad92d5 3138 ChannelsDatarate = mibSet->Param.ChannelsDatarate;
mluis 2:14a5d6ad92d5 3139 }
mluis 2:14a5d6ad92d5 3140 else
mluis 2:14a5d6ad92d5 3141 {
mluis 2:14a5d6ad92d5 3142 status = LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 3143 }
mluis 2:14a5d6ad92d5 3144 break;
mluis 2:14a5d6ad92d5 3145 }
mluis 2:14a5d6ad92d5 3146 case MIB_CHANNELS_TX_POWER:
mluis 2:14a5d6ad92d5 3147 {
mluis 2:14a5d6ad92d5 3148 if( ValueInRange( mibSet->Param.ChannelsTxPower,
mluis 2:14a5d6ad92d5 3149 LORAMAC_MAX_TX_POWER, LORAMAC_MIN_TX_POWER ) )
mluis 2:14a5d6ad92d5 3150 {
mluis 2:14a5d6ad92d5 3151 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 2:14a5d6ad92d5 3152 int8_t txPower = LimitTxPower( mibSet->Param.ChannelsTxPower );
mluis 2:14a5d6ad92d5 3153 if( txPower == mibSet->Param.ChannelsTxPower )
mluis 2:14a5d6ad92d5 3154 {
mluis 2:14a5d6ad92d5 3155 ChannelsTxPower = mibSet->Param.ChannelsTxPower;
mluis 2:14a5d6ad92d5 3156 }
mluis 2:14a5d6ad92d5 3157 else
mluis 2:14a5d6ad92d5 3158 {
mluis 2:14a5d6ad92d5 3159 status = LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 3160 }
mluis 2:14a5d6ad92d5 3161 #else
mluis 2:14a5d6ad92d5 3162 ChannelsTxPower = mibSet->Param.ChannelsTxPower;
mluis 2:14a5d6ad92d5 3163 #endif
mluis 2:14a5d6ad92d5 3164 }
mluis 2:14a5d6ad92d5 3165 else
mluis 2:14a5d6ad92d5 3166 {
mluis 2:14a5d6ad92d5 3167 status = LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 3168 }
mluis 2:14a5d6ad92d5 3169 break;
mluis 2:14a5d6ad92d5 3170 }
mluis 2:14a5d6ad92d5 3171 default:
mluis 2:14a5d6ad92d5 3172 status = LORAMAC_STATUS_SERVICE_UNKNOWN;
mluis 2:14a5d6ad92d5 3173 break;
mluis 0:91d1a7783bb9 3174 }
mluis 0:91d1a7783bb9 3175
mluis 2:14a5d6ad92d5 3176 return status;
mluis 0:91d1a7783bb9 3177 }
mluis 0:91d1a7783bb9 3178
mluis 2:14a5d6ad92d5 3179 LoRaMacStatus_t LoRaMacChannelAdd( uint8_t id, ChannelParams_t params )
mluis 0:91d1a7783bb9 3180 {
mluis 3:b9d87593a8ae 3181 #if ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) )
mluis 3:b9d87593a8ae 3182 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 3:b9d87593a8ae 3183 #else
mluis 3:b9d87593a8ae 3184 bool datarateInvalid = false;
mluis 3:b9d87593a8ae 3185 bool frequencyInvalid = false;
mluis 3:b9d87593a8ae 3186 uint8_t band = 0;
mluis 3:b9d87593a8ae 3187
mluis 3:b9d87593a8ae 3188 // The id must not exceed LORA_MAX_NB_CHANNELS
mluis 2:14a5d6ad92d5 3189 if( id >= LORA_MAX_NB_CHANNELS )
mluis 0:91d1a7783bb9 3190 {
mluis 2:14a5d6ad92d5 3191 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 0:91d1a7783bb9 3192 }
mluis 3:b9d87593a8ae 3193 // Validate if the MAC is in a correct state
mluis 2:14a5d6ad92d5 3194 if( ( LoRaMacState & MAC_TX_RUNNING ) == MAC_TX_RUNNING )
mluis 0:91d1a7783bb9 3195 {
mluis 3:b9d87593a8ae 3196 if( ( LoRaMacState & MAC_TX_CONFIG ) != MAC_TX_CONFIG )
mluis 3:b9d87593a8ae 3197 {
mluis 3:b9d87593a8ae 3198 return LORAMAC_STATUS_BUSY;
mluis 3:b9d87593a8ae 3199 }
mluis 0:91d1a7783bb9 3200 }
mluis 3:b9d87593a8ae 3201 // Validate the datarate
mluis 2:14a5d6ad92d5 3202 if( ( params.DrRange.Fields.Min > params.DrRange.Fields.Max ) ||
mluis 2:14a5d6ad92d5 3203 ( ValueInRange( params.DrRange.Fields.Min, LORAMAC_MIN_DATARATE,
mluis 2:14a5d6ad92d5 3204 LORAMAC_MAX_DATARATE ) == false ) ||
mluis 2:14a5d6ad92d5 3205 ( ValueInRange( params.DrRange.Fields.Max, LORAMAC_MIN_DATARATE,
mluis 2:14a5d6ad92d5 3206 LORAMAC_MAX_DATARATE ) == false ) )
mluis 0:91d1a7783bb9 3207 {
mluis 3:b9d87593a8ae 3208 datarateInvalid = true;
mluis 0:91d1a7783bb9 3209 }
mluis 2:14a5d6ad92d5 3210
mluis 3:b9d87593a8ae 3211 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
mluis 3:b9d87593a8ae 3212 if( id < 3 )
mluis 0:91d1a7783bb9 3213 {
mluis 3:b9d87593a8ae 3214 if( params.Frequency != Channels[id].Frequency )
mluis 0:91d1a7783bb9 3215 {
mluis 3:b9d87593a8ae 3216 frequencyInvalid = true;
mluis 3:b9d87593a8ae 3217 }
mluis 3:b9d87593a8ae 3218
mluis 3:b9d87593a8ae 3219 if( params.DrRange.Fields.Min > LORAMAC_DEFAULT_DATARATE )
mluis 3:b9d87593a8ae 3220 {
mluis 3:b9d87593a8ae 3221 datarateInvalid = true;
mluis 3:b9d87593a8ae 3222 }
mluis 3:b9d87593a8ae 3223 if( ValueInRange( params.DrRange.Fields.Max, DR_5, LORAMAC_MAX_DATARATE ) == false )
mluis 3:b9d87593a8ae 3224 {
mluis 3:b9d87593a8ae 3225 datarateInvalid = true;
mluis 0:91d1a7783bb9 3226 }
mluis 0:91d1a7783bb9 3227 }
mluis 3:b9d87593a8ae 3228 #endif
mluis 3:b9d87593a8ae 3229
mluis 3:b9d87593a8ae 3230 // Validate the frequency
mluis 3:b9d87593a8ae 3231 if( ( Radio.CheckRfFrequency( params.Frequency ) == true ) && ( params.Frequency > 0 ) && ( frequencyInvalid == false ) )
mluis 0:91d1a7783bb9 3232 {
mluis 3:b9d87593a8ae 3233 #if defined( USE_BAND_868 )
mluis 3:b9d87593a8ae 3234 if( ( params.Frequency >= 865000000 ) && ( params.Frequency <= 868000000 ) )
mluis 0:91d1a7783bb9 3235 {
mluis 3:b9d87593a8ae 3236 band = BAND_G1_0;
mluis 0:91d1a7783bb9 3237 }
mluis 3:b9d87593a8ae 3238 else if( ( params.Frequency > 868000000 ) && ( params.Frequency <= 868600000 ) )
mluis 0:91d1a7783bb9 3239 {
mluis 3:b9d87593a8ae 3240 band = BAND_G1_1;
mluis 0:91d1a7783bb9 3241 }
mluis 3:b9d87593a8ae 3242 else if( ( params.Frequency >= 868700000 ) && ( params.Frequency <= 869200000 ) )
mluis 0:91d1a7783bb9 3243 {
mluis 3:b9d87593a8ae 3244 band = BAND_G1_2;
mluis 3:b9d87593a8ae 3245 }
mluis 3:b9d87593a8ae 3246 else if( ( params.Frequency >= 869400000 ) && ( params.Frequency <= 869650000 ) )
mluis 3:b9d87593a8ae 3247 {
mluis 3:b9d87593a8ae 3248 band = BAND_G1_3;
mluis 0:91d1a7783bb9 3249 }
mluis 3:b9d87593a8ae 3250 else if( ( params.Frequency >= 869700000 ) && ( params.Frequency <= 870000000 ) )
mluis 0:91d1a7783bb9 3251 {
mluis 3:b9d87593a8ae 3252 band = BAND_G1_4;
mluis 0:91d1a7783bb9 3253 }
mluis 3:b9d87593a8ae 3254 else
mluis 3:b9d87593a8ae 3255 {
mluis 3:b9d87593a8ae 3256 frequencyInvalid = true;
mluis 3:b9d87593a8ae 3257 }
mluis 3:b9d87593a8ae 3258 #endif
mluis 0:91d1a7783bb9 3259 }
mluis 0:91d1a7783bb9 3260 else
mluis 0:91d1a7783bb9 3261 {
mluis 3:b9d87593a8ae 3262 frequencyInvalid = true;
mluis 3:b9d87593a8ae 3263 }
mluis 3:b9d87593a8ae 3264
mluis 3:b9d87593a8ae 3265 if( ( datarateInvalid == true ) && ( frequencyInvalid == true ) )
mluis 3:b9d87593a8ae 3266 {
mluis 3:b9d87593a8ae 3267 return LORAMAC_STATUS_FREQ_AND_DR_INVALID;
mluis 0:91d1a7783bb9 3268 }
mluis 3:b9d87593a8ae 3269 if( datarateInvalid == true )
mluis 3:b9d87593a8ae 3270 {
mluis 3:b9d87593a8ae 3271 return LORAMAC_STATUS_DATARATE_INVALID;
mluis 3:b9d87593a8ae 3272 }
mluis 3:b9d87593a8ae 3273 if( frequencyInvalid == true )
mluis 0:91d1a7783bb9 3274 {
mluis 3:b9d87593a8ae 3275 return LORAMAC_STATUS_FREQUENCY_INVALID;
mluis 2:14a5d6ad92d5 3276 }
mluis 2:14a5d6ad92d5 3277
mluis 3:b9d87593a8ae 3278 // Every parameter is valid, activate the channel
mluis 3:b9d87593a8ae 3279 Channels[id] = params;
mluis 3:b9d87593a8ae 3280 Channels[id].Band = band;
mluis 3:b9d87593a8ae 3281 ChannelsMask[0] |= ( 1 << id );
mluis 3:b9d87593a8ae 3282
mluis 2:14a5d6ad92d5 3283 return LORAMAC_STATUS_OK;
mluis 0:91d1a7783bb9 3284 #endif
mluis 0:91d1a7783bb9 3285 }
mluis 0:91d1a7783bb9 3286
mluis 2:14a5d6ad92d5 3287 LoRaMacStatus_t LoRaMacChannelRemove( uint8_t id )
mluis 0:91d1a7783bb9 3288 {
mluis 3:b9d87593a8ae 3289 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
mluis 2:14a5d6ad92d5 3290 if( ( LoRaMacState & MAC_TX_RUNNING ) == MAC_TX_RUNNING )
mluis 0:91d1a7783bb9 3291 {
mluis 3:b9d87593a8ae 3292 if( ( LoRaMacState & MAC_TX_CONFIG ) != MAC_TX_CONFIG )
mluis 3:b9d87593a8ae 3293 {
mluis 3:b9d87593a8ae 3294 return LORAMAC_STATUS_BUSY;
mluis 3:b9d87593a8ae 3295 }
mluis 0:91d1a7783bb9 3296 }
mluis 3:b9d87593a8ae 3297
mluis 3:b9d87593a8ae 3298 if( id < 3 )
mluis 0:91d1a7783bb9 3299 {
mluis 3:b9d87593a8ae 3300 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 3:b9d87593a8ae 3301 }
mluis 3:b9d87593a8ae 3302 else
mluis 3:b9d87593a8ae 3303 {
mluis 3:b9d87593a8ae 3304 // Remove the channel from the list of channels
mluis 3:b9d87593a8ae 3305 Channels[id] = ( ChannelParams_t ){ 0, { 0 }, 0 };
mluis 3:b9d87593a8ae 3306
mluis 3:b9d87593a8ae 3307 // Disable the channel as it doesn't exist anymore
mluis 3:b9d87593a8ae 3308 if( DisableChannelInMask( id, ChannelsMask ) == false )
mluis 2:14a5d6ad92d5 3309 {
mluis 2:14a5d6ad92d5 3310 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 3311 }
mluis 0:91d1a7783bb9 3312 }
mluis 3:b9d87593a8ae 3313 return LORAMAC_STATUS_OK;
mluis 3:b9d87593a8ae 3314 #elif ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) )
mluis 3:b9d87593a8ae 3315 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 3316 #endif
mluis 2:14a5d6ad92d5 3317 }
mluis 2:14a5d6ad92d5 3318
mluis 2:14a5d6ad92d5 3319 LoRaMacStatus_t LoRaMacMulticastChannelLink( MulticastParams_t *channelParam )
mluis 2:14a5d6ad92d5 3320 {
mluis 2:14a5d6ad92d5 3321 if( channelParam == NULL )
mluis 2:14a5d6ad92d5 3322 {
mluis 2:14a5d6ad92d5 3323 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 3324 }
mluis 2:14a5d6ad92d5 3325 if( ( LoRaMacState & MAC_TX_RUNNING ) == MAC_TX_RUNNING )
mluis 2:14a5d6ad92d5 3326 {
mluis 2:14a5d6ad92d5 3327 return LORAMAC_STATUS_BUSY;
mluis 2:14a5d6ad92d5 3328 }
mluis 2:14a5d6ad92d5 3329
mluis 2:14a5d6ad92d5 3330 // Reset downlink counter
mluis 2:14a5d6ad92d5 3331 channelParam->DownLinkCounter = 0;
mluis 2:14a5d6ad92d5 3332
mluis 2:14a5d6ad92d5 3333 if( MulticastChannels == NULL )
mluis 2:14a5d6ad92d5 3334 {
mluis 2:14a5d6ad92d5 3335 // New node is the fist element
mluis 2:14a5d6ad92d5 3336 MulticastChannels = channelParam;
mluis 0:91d1a7783bb9 3337 }
mluis 0:91d1a7783bb9 3338 else
mluis 0:91d1a7783bb9 3339 {
mluis 2:14a5d6ad92d5 3340 MulticastParams_t *cur = MulticastChannels;
mluis 2:14a5d6ad92d5 3341
mluis 2:14a5d6ad92d5 3342 // Search the last node in the list
mluis 2:14a5d6ad92d5 3343 while( cur->Next != NULL )
mluis 2:14a5d6ad92d5 3344 {
mluis 2:14a5d6ad92d5 3345 cur = cur->Next;
mluis 2:14a5d6ad92d5 3346 }
mluis 2:14a5d6ad92d5 3347 // This function always finds the last node
mluis 2:14a5d6ad92d5 3348 cur->Next = channelParam;
mluis 0:91d1a7783bb9 3349 }
mluis 2:14a5d6ad92d5 3350
mluis 2:14a5d6ad92d5 3351 return LORAMAC_STATUS_OK;
mluis 0:91d1a7783bb9 3352 }
mluis 0:91d1a7783bb9 3353
mluis 2:14a5d6ad92d5 3354 LoRaMacStatus_t LoRaMacMulticastChannelUnlink( MulticastParams_t *channelParam )
mluis 0:91d1a7783bb9 3355 {
mluis 2:14a5d6ad92d5 3356 if( channelParam == NULL )
mluis 0:91d1a7783bb9 3357 {
mluis 2:14a5d6ad92d5 3358 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 0:91d1a7783bb9 3359 }
mluis 2:14a5d6ad92d5 3360 if( ( LoRaMacState & MAC_TX_RUNNING ) == MAC_TX_RUNNING )
mluis 2:14a5d6ad92d5 3361 {
mluis 2:14a5d6ad92d5 3362 return LORAMAC_STATUS_BUSY;
mluis 2:14a5d6ad92d5 3363 }
mluis 2:14a5d6ad92d5 3364
mluis 2:14a5d6ad92d5 3365 if( MulticastChannels != NULL )
mluis 0:91d1a7783bb9 3366 {
mluis 2:14a5d6ad92d5 3367 if( MulticastChannels == channelParam )
mluis 2:14a5d6ad92d5 3368 {
mluis 2:14a5d6ad92d5 3369 // First element
mluis 2:14a5d6ad92d5 3370 MulticastChannels = channelParam->Next;
mluis 2:14a5d6ad92d5 3371 }
mluis 2:14a5d6ad92d5 3372 else
mluis 2:14a5d6ad92d5 3373 {
mluis 2:14a5d6ad92d5 3374 MulticastParams_t *cur = MulticastChannels;
mluis 2:14a5d6ad92d5 3375
mluis 2:14a5d6ad92d5 3376 // Search the node in the list
mluis 2:14a5d6ad92d5 3377 while( cur->Next && cur->Next != channelParam )
mluis 2:14a5d6ad92d5 3378 {
mluis 2:14a5d6ad92d5 3379 cur = cur->Next;
mluis 2:14a5d6ad92d5 3380 }
mluis 2:14a5d6ad92d5 3381 // If we found the node, remove it
mluis 2:14a5d6ad92d5 3382 if( cur->Next )
mluis 2:14a5d6ad92d5 3383 {
mluis 2:14a5d6ad92d5 3384 cur->Next = channelParam->Next;
mluis 2:14a5d6ad92d5 3385 }
mluis 2:14a5d6ad92d5 3386 }
mluis 2:14a5d6ad92d5 3387 channelParam->Next = NULL;
mluis 0:91d1a7783bb9 3388 }
mluis 2:14a5d6ad92d5 3389
mluis 2:14a5d6ad92d5 3390 return LORAMAC_STATUS_OK;
mluis 0:91d1a7783bb9 3391 }
mluis 0:91d1a7783bb9 3392
mluis 2:14a5d6ad92d5 3393 LoRaMacStatus_t LoRaMacMlmeRequest( MlmeReq_t *mlmeRequest )
mluis 0:91d1a7783bb9 3394 {
mluis 2:14a5d6ad92d5 3395 LoRaMacStatus_t status = LORAMAC_STATUS_SERVICE_UNKNOWN;
mluis 2:14a5d6ad92d5 3396 LoRaMacHeader_t macHdr;
mluis 2:14a5d6ad92d5 3397
mluis 2:14a5d6ad92d5 3398 if( mlmeRequest == NULL )
mluis 2:14a5d6ad92d5 3399 {
mluis 2:14a5d6ad92d5 3400 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 3401 }
mluis 2:14a5d6ad92d5 3402 if( ( LoRaMacState & MAC_TX_RUNNING ) == MAC_TX_RUNNING )
mluis 2:14a5d6ad92d5 3403 {
mluis 2:14a5d6ad92d5 3404 return LORAMAC_STATUS_BUSY;
mluis 2:14a5d6ad92d5 3405 }
mluis 2:14a5d6ad92d5 3406
mluis 2:14a5d6ad92d5 3407 memset1( ( uint8_t* ) &MlmeConfirm, 0, sizeof( MlmeConfirm ) );
mluis 2:14a5d6ad92d5 3408
mluis 2:14a5d6ad92d5 3409 MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR;
mluis 2:14a5d6ad92d5 3410
mluis 2:14a5d6ad92d5 3411 switch( mlmeRequest->Type )
mluis 2:14a5d6ad92d5 3412 {
mluis 2:14a5d6ad92d5 3413 case MLME_JOIN:
mluis 2:14a5d6ad92d5 3414 {
mluis 2:14a5d6ad92d5 3415 if( ( LoRaMacState & MAC_TX_DELAYED ) == MAC_TX_DELAYED )
mluis 2:14a5d6ad92d5 3416 {
mluis 2:14a5d6ad92d5 3417 status = LORAMAC_STATUS_BUSY;
mluis 2:14a5d6ad92d5 3418 }
mluis 2:14a5d6ad92d5 3419
mluis 2:14a5d6ad92d5 3420 MlmeConfirm.MlmeRequest = mlmeRequest->Type;
mluis 2:14a5d6ad92d5 3421
mluis 2:14a5d6ad92d5 3422 if( ( mlmeRequest->Req.Join.DevEui == NULL ) ||
mluis 2:14a5d6ad92d5 3423 ( mlmeRequest->Req.Join.AppEui == NULL ) ||
mluis 2:14a5d6ad92d5 3424 ( mlmeRequest->Req.Join.AppKey == NULL ) )
mluis 2:14a5d6ad92d5 3425 {
mluis 2:14a5d6ad92d5 3426 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 3427 }
mluis 2:14a5d6ad92d5 3428
mluis 2:14a5d6ad92d5 3429 LoRaMacFlags.Bits.MlmeReq = 1;
mluis 2:14a5d6ad92d5 3430
mluis 2:14a5d6ad92d5 3431 LoRaMacDevEui = mlmeRequest->Req.Join.DevEui;
mluis 2:14a5d6ad92d5 3432 LoRaMacAppEui = mlmeRequest->Req.Join.AppEui;
mluis 2:14a5d6ad92d5 3433 LoRaMacAppKey = mlmeRequest->Req.Join.AppKey;
mluis 2:14a5d6ad92d5 3434
mluis 2:14a5d6ad92d5 3435 macHdr.Value = 0;
mluis 2:14a5d6ad92d5 3436 macHdr.Bits.MType = FRAME_TYPE_JOIN_REQ;
mluis 2:14a5d6ad92d5 3437
mluis 2:14a5d6ad92d5 3438 IsLoRaMacNetworkJoined = false;
mluis 2:14a5d6ad92d5 3439
mluis 2:14a5d6ad92d5 3440 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
mluis 3:b9d87593a8ae 3441 #if defined( USE_BAND_915 )
mluis 3:b9d87593a8ae 3442 // Re-enable 500 kHz default channels
mluis 3:b9d87593a8ae 3443 ChannelsMask[4] = 0x00FF;
mluis 3:b9d87593a8ae 3444 #else // defined( USE_BAND_915_HYBRID )
mluis 3:b9d87593a8ae 3445 // Re-enable 500 kHz default channels
mluis 3:b9d87593a8ae 3446 ChannelsMask[4] = 0x0001;
mluis 3:b9d87593a8ae 3447 #endif
mluis 3:b9d87593a8ae 3448
mluis 2:14a5d6ad92d5 3449 static uint8_t drSwitch = 0;
mluis 2:14a5d6ad92d5 3450
mluis 2:14a5d6ad92d5 3451 if( ( ++drSwitch & 0x01 ) == 0x01 )
mluis 2:14a5d6ad92d5 3452 {
mluis 2:14a5d6ad92d5 3453 ChannelsDatarate = DR_0;
mluis 2:14a5d6ad92d5 3454 }
mluis 2:14a5d6ad92d5 3455 else
mluis 2:14a5d6ad92d5 3456 {
mluis 2:14a5d6ad92d5 3457 ChannelsDatarate = DR_4;
mluis 2:14a5d6ad92d5 3458 }
mluis 2:14a5d6ad92d5 3459 #endif
mluis 2:14a5d6ad92d5 3460
mluis 2:14a5d6ad92d5 3461 status = Send( &macHdr, 0, NULL, 0 );
mluis 2:14a5d6ad92d5 3462 break;
mluis 2:14a5d6ad92d5 3463 }
mluis 2:14a5d6ad92d5 3464 case MLME_LINK_CHECK:
mluis 2:14a5d6ad92d5 3465 {
mluis 2:14a5d6ad92d5 3466 LoRaMacFlags.Bits.MlmeReq = 1;
mluis 2:14a5d6ad92d5 3467 // LoRaMac will send this command piggy-pack
mluis 2:14a5d6ad92d5 3468 MlmeConfirm.MlmeRequest = mlmeRequest->Type;
mluis 2:14a5d6ad92d5 3469
mluis 2:14a5d6ad92d5 3470 status = AddMacCommand( MOTE_MAC_LINK_CHECK_REQ, 0, 0 );
mluis 2:14a5d6ad92d5 3471 break;
mluis 2:14a5d6ad92d5 3472 }
mluis 2:14a5d6ad92d5 3473 default:
mluis 2:14a5d6ad92d5 3474 break;
mluis 2:14a5d6ad92d5 3475 }
mluis 2:14a5d6ad92d5 3476
mluis 2:14a5d6ad92d5 3477 if( status != LORAMAC_STATUS_OK )
mluis 2:14a5d6ad92d5 3478 {
mluis 2:14a5d6ad92d5 3479 NodeAckRequested = false;
mluis 2:14a5d6ad92d5 3480 LoRaMacFlags.Bits.MlmeReq = 0;
mluis 2:14a5d6ad92d5 3481 }
mluis 2:14a5d6ad92d5 3482
mluis 2:14a5d6ad92d5 3483 return status;
mluis 0:91d1a7783bb9 3484 }
mluis 0:91d1a7783bb9 3485
mluis 2:14a5d6ad92d5 3486 LoRaMacStatus_t LoRaMacMcpsRequest( McpsReq_t *mcpsRequest )
mluis 0:91d1a7783bb9 3487 {
mluis 2:14a5d6ad92d5 3488 LoRaMacStatus_t status = LORAMAC_STATUS_SERVICE_UNKNOWN;
mluis 2:14a5d6ad92d5 3489 LoRaMacHeader_t macHdr;
mluis 2:14a5d6ad92d5 3490 uint8_t fPort = 0;
mluis 2:14a5d6ad92d5 3491 void *fBuffer;
mluis 2:14a5d6ad92d5 3492 uint16_t fBufferSize;
mluis 2:14a5d6ad92d5 3493 int8_t datarate;
mluis 2:14a5d6ad92d5 3494 bool readyToSend = false;
mluis 2:14a5d6ad92d5 3495
mluis 2:14a5d6ad92d5 3496 if( mcpsRequest == NULL )
mluis 2:14a5d6ad92d5 3497 {
mluis 2:14a5d6ad92d5 3498 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 3499 }
mluis 2:14a5d6ad92d5 3500 if( ( ( LoRaMacState & MAC_TX_RUNNING ) == MAC_TX_RUNNING ) ||
mluis 2:14a5d6ad92d5 3501 ( ( LoRaMacState & MAC_TX_DELAYED ) == MAC_TX_DELAYED ) )
mluis 2:14a5d6ad92d5 3502 {
mluis 2:14a5d6ad92d5 3503 return LORAMAC_STATUS_BUSY;
mluis 2:14a5d6ad92d5 3504 }
mluis 2:14a5d6ad92d5 3505
mluis 2:14a5d6ad92d5 3506 macHdr.Value = 0;
mluis 2:14a5d6ad92d5 3507 memset1 ( ( uint8_t* ) &McpsConfirm, 0, sizeof( McpsConfirm ) );
mluis 2:14a5d6ad92d5 3508 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR;
mluis 2:14a5d6ad92d5 3509
mluis 2:14a5d6ad92d5 3510 switch( mcpsRequest->Type )
mluis 2:14a5d6ad92d5 3511 {
mluis 2:14a5d6ad92d5 3512 case MCPS_UNCONFIRMED:
mluis 2:14a5d6ad92d5 3513 {
mluis 2:14a5d6ad92d5 3514 readyToSend = true;
mluis 2:14a5d6ad92d5 3515 AckTimeoutRetries = 1;
mluis 2:14a5d6ad92d5 3516
mluis 2:14a5d6ad92d5 3517 macHdr.Bits.MType = FRAME_TYPE_DATA_UNCONFIRMED_UP;
mluis 2:14a5d6ad92d5 3518 fPort = mcpsRequest->Req.Unconfirmed.fPort;
mluis 2:14a5d6ad92d5 3519 fBuffer = mcpsRequest->Req.Unconfirmed.fBuffer;
mluis 2:14a5d6ad92d5 3520 fBufferSize = mcpsRequest->Req.Unconfirmed.fBufferSize;
mluis 2:14a5d6ad92d5 3521 datarate = mcpsRequest->Req.Unconfirmed.Datarate;
mluis 2:14a5d6ad92d5 3522 break;
mluis 2:14a5d6ad92d5 3523 }
mluis 2:14a5d6ad92d5 3524 case MCPS_CONFIRMED:
mluis 2:14a5d6ad92d5 3525 {
mluis 2:14a5d6ad92d5 3526 readyToSend = true;
mluis 2:14a5d6ad92d5 3527 AckTimeoutRetriesCounter = 1;
mluis 3:b9d87593a8ae 3528 AckTimeoutRetries = mcpsRequest->Req.Confirmed.NbTrials;
mluis 2:14a5d6ad92d5 3529
mluis 2:14a5d6ad92d5 3530 macHdr.Bits.MType = FRAME_TYPE_DATA_CONFIRMED_UP;
mluis 2:14a5d6ad92d5 3531 fPort = mcpsRequest->Req.Confirmed.fPort;
mluis 2:14a5d6ad92d5 3532 fBuffer = mcpsRequest->Req.Confirmed.fBuffer;
mluis 2:14a5d6ad92d5 3533 fBufferSize = mcpsRequest->Req.Confirmed.fBufferSize;
mluis 2:14a5d6ad92d5 3534 datarate = mcpsRequest->Req.Confirmed.Datarate;
mluis 2:14a5d6ad92d5 3535 break;
mluis 2:14a5d6ad92d5 3536 }
mluis 2:14a5d6ad92d5 3537 case MCPS_PROPRIETARY:
mluis 2:14a5d6ad92d5 3538 {
mluis 2:14a5d6ad92d5 3539 readyToSend = true;
mluis 2:14a5d6ad92d5 3540 AckTimeoutRetries = 1;
mluis 2:14a5d6ad92d5 3541
mluis 2:14a5d6ad92d5 3542 macHdr.Bits.MType = FRAME_TYPE_PROPRIETARY;
mluis 2:14a5d6ad92d5 3543 fBuffer = mcpsRequest->Req.Proprietary.fBuffer;
mluis 2:14a5d6ad92d5 3544 fBufferSize = mcpsRequest->Req.Proprietary.fBufferSize;
mluis 2:14a5d6ad92d5 3545 datarate = mcpsRequest->Req.Proprietary.Datarate;
mluis 2:14a5d6ad92d5 3546 break;
mluis 2:14a5d6ad92d5 3547 }
mluis 2:14a5d6ad92d5 3548 default:
mluis 2:14a5d6ad92d5 3549 break;
mluis 2:14a5d6ad92d5 3550 }
mluis 2:14a5d6ad92d5 3551
mluis 2:14a5d6ad92d5 3552 if( readyToSend == true )
mluis 2:14a5d6ad92d5 3553 {
mluis 2:14a5d6ad92d5 3554 if( AdrCtrlOn == false )
mluis 2:14a5d6ad92d5 3555 {
mluis 2:14a5d6ad92d5 3556 if( ValueInRange( datarate, LORAMAC_MIN_DATARATE, LORAMAC_MAX_DATARATE ) == true )
mluis 2:14a5d6ad92d5 3557 {
mluis 2:14a5d6ad92d5 3558 ChannelsDatarate = datarate;
mluis 2:14a5d6ad92d5 3559 }
mluis 2:14a5d6ad92d5 3560 else
mluis 2:14a5d6ad92d5 3561 {
mluis 2:14a5d6ad92d5 3562 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 3563 }
mluis 2:14a5d6ad92d5 3564 }
mluis 2:14a5d6ad92d5 3565
mluis 2:14a5d6ad92d5 3566 status = Send( &macHdr, fPort, fBuffer, fBufferSize );
mluis 2:14a5d6ad92d5 3567 if( status == LORAMAC_STATUS_OK )
mluis 2:14a5d6ad92d5 3568 {
mluis 2:14a5d6ad92d5 3569 McpsConfirm.McpsRequest = mcpsRequest->Type;
mluis 2:14a5d6ad92d5 3570 LoRaMacFlags.Bits.McpsReq = 1;
mluis 2:14a5d6ad92d5 3571 }
mluis 2:14a5d6ad92d5 3572 else
mluis 2:14a5d6ad92d5 3573 {
mluis 2:14a5d6ad92d5 3574 NodeAckRequested = false;
mluis 2:14a5d6ad92d5 3575 }
mluis 2:14a5d6ad92d5 3576 }
mluis 2:14a5d6ad92d5 3577
mluis 2:14a5d6ad92d5 3578 return status;
mluis 0:91d1a7783bb9 3579 }
mluis 0:91d1a7783bb9 3580
mluis 0:91d1a7783bb9 3581 void LoRaMacTestRxWindowsOn( bool enable )
mluis 0:91d1a7783bb9 3582 {
mluis 0:91d1a7783bb9 3583 IsRxWindowsEnabled = enable;
mluis 0:91d1a7783bb9 3584 }
mluis 0:91d1a7783bb9 3585
mluis 2:14a5d6ad92d5 3586 void LoRaMacTestSetMic( uint16_t txPacketCounter )
mluis 0:91d1a7783bb9 3587 {
mluis 2:14a5d6ad92d5 3588 UpLinkCounter = txPacketCounter;
mluis 0:91d1a7783bb9 3589 IsUpLinkCounterFixed = true;
mluis 0:91d1a7783bb9 3590 }
mluis 2:14a5d6ad92d5 3591
mluis 2:14a5d6ad92d5 3592 void LoRaMacTestSetDutyCycleOn( bool enable )
mluis 2:14a5d6ad92d5 3593 {
mluis 2:14a5d6ad92d5 3594 DutyCycleOn = enable;
mluis 2:14a5d6ad92d5 3595 }