Fork of Semtech LoRaWAN stack

Fork of LoRaWAN-lib by canuck lehead

Committer:
Shaun Nelson
Date:
Wed Aug 09 16:20:21 2017 -0400
Branch:
class_b
Revision:
38:182ba91524e4
Parent:
34:1ac668ce2b15
Child:
39:ca51084123b8
Synchronized with  https://github.com/Senetco/LoRaMac-node/commit/6cb21de99eaa65caad9d911318df8875867a6e60

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