Fork of Semtech LoRaWAN stack

Fork of LoRaWAN-lib by canuck lehead

Committer:
Shaun Nelson
Date:
Thu Sep 21 17:01:33 2017 -0400
Branch:
class_b
Revision:
47:e7fd944a7215
Parent:
39:ca51084123b8
Remove static declaration from DevAddr

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 */
Shaun Nelson 47:e7fd944a7215 112 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 39:ca51084123b8 1505 if( ( LoRaMacClassBIsAcquisitionPending( ) == true ) || ( LoRaMacClassBIsAcquisitionTimerSet() == true ) )
Shaun Nelson 47:e7fd944a7215 1506 // if( LoRaMacClassBIsAcquisitionPending( ) == true )
Shaun Nelson 38:182ba91524e4 1507 {
Shaun Nelson 38:182ba91524e4 1508 MlmeConfirmQueue[0].MlmeRequest = MLME_BEACON_ACQUISITION;
Shaun Nelson 38:182ba91524e4 1509 MlmeConfirmQueue[0].Status = MlmeConfirmQueue[i].Status;
Shaun Nelson 38:182ba91524e4 1510 continue;
Shaun Nelson 38:182ba91524e4 1511 }
Shaun Nelson 38:182ba91524e4 1512 }
Shaun Nelson 38:182ba91524e4 1513 j--;
Shaun Nelson 39:ca51084123b8 1514
Shaun Nelson 38:182ba91524e4 1515 MlmeConfirm.Status = MlmeConfirmQueue[i].Status;
Shaun Nelson 38:182ba91524e4 1516 MlmeConfirm.MlmeRequest = MlmeConfirmQueue[i].MlmeRequest;
Shaun Nelson 39:ca51084123b8 1517
Shaun Nelson 38:182ba91524e4 1518 LoRaMacPrimitives->MacMlmeConfirm( &MlmeConfirm );
Shaun Nelson 38:182ba91524e4 1519 }
Shaun Nelson 38:182ba91524e4 1520 MlmeConfirmQueueCnt = j;
Shaun Nelson 38:182ba91524e4 1521
Shaun Nelson 38:182ba91524e4 1522 if( MlmeConfirmQueueCnt == 0 )
Shaun Nelson 38:182ba91524e4 1523 {
Shaun Nelson 38:182ba91524e4 1524 LoRaMacFlags.Bits.MlmeReq = 0;
Shaun Nelson 38:182ba91524e4 1525 }
Shaun Nelson 38:182ba91524e4 1526 }
Shaun Nelson 38:182ba91524e4 1527
Shaun Nelson 38:182ba91524e4 1528 if( LoRaMacFlags.Bits.MlmeInd == 1 )
Shaun Nelson 38:182ba91524e4 1529 {
Shaun Nelson 38:182ba91524e4 1530 LoRaMacPrimitives->MacMlmeIndication( &MlmeIndication );
Shaun Nelson 38:182ba91524e4 1531 LoRaMacFlags.Bits.MlmeInd = 0;
mluis 2:14a5d6ad92d5 1532 }
mluis 2:14a5d6ad92d5 1533
mluis 32:26002607de9c 1534 // Procedure done. Reset variables.
mluis 2:14a5d6ad92d5 1535 LoRaMacFlags.Bits.MacDone = 0;
Shaun Nelson 38:182ba91524e4 1536
Shaun Nelson 38:182ba91524e4 1537 if( LoRaMacDeviceClass == CLASS_B )
Shaun Nelson 38:182ba91524e4 1538 {
Shaun Nelson 38:182ba91524e4 1539 LoRaMacClassBResumeBeaconing( );
Shaun Nelson 38:182ba91524e4 1540 }
mluis 2:14a5d6ad92d5 1541 }
mluis 2:14a5d6ad92d5 1542 else
mluis 2:14a5d6ad92d5 1543 {
mluis 2:14a5d6ad92d5 1544 // Operation not finished restart timer
mluis 3:b9d87593a8ae 1545 TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT );
mluis 2:14a5d6ad92d5 1546 TimerStart( &MacStateCheckTimer );
mluis 2:14a5d6ad92d5 1547 }
mluis 2:14a5d6ad92d5 1548
mluis 2:14a5d6ad92d5 1549 if( LoRaMacFlags.Bits.McpsInd == 1 )
mluis 2:14a5d6ad92d5 1550 {
mluis 32:26002607de9c 1551 if( LoRaMacDeviceClass == CLASS_C )
mluis 32:26002607de9c 1552 {// Activate RX2 window for Class C
mluis 32:26002607de9c 1553 OnRxWindow2TimerEvent( );
mluis 32:26002607de9c 1554 }
mluis 32:26002607de9c 1555 if( LoRaMacFlags.Bits.McpsIndSkip == 0 )
mluis 32:26002607de9c 1556 {
mluis 32:26002607de9c 1557 LoRaMacPrimitives->MacMcpsIndication( &McpsIndication );
mluis 32:26002607de9c 1558 }
mluis 32:26002607de9c 1559 LoRaMacFlags.Bits.McpsIndSkip = 0;
mluis 2:14a5d6ad92d5 1560 LoRaMacFlags.Bits.McpsInd = 0;
mluis 2:14a5d6ad92d5 1561 }
mluis 2:14a5d6ad92d5 1562 }
mluis 2:14a5d6ad92d5 1563
mluis 2:14a5d6ad92d5 1564 static void OnTxDelayedTimerEvent( void )
mluis 2:14a5d6ad92d5 1565 {
mluis 7:c16969e0f70f 1566 LoRaMacHeader_t macHdr;
mluis 7:c16969e0f70f 1567 LoRaMacFrameCtrl_t fCtrl;
Shaun Nelson 38:182ba91524e4 1568 AlternateDrParams_t altDr;
Shaun Nelson 38:182ba91524e4 1569 uint8_t index = 0;
mluis 7:c16969e0f70f 1570
mluis 2:14a5d6ad92d5 1571 TimerStop( &TxDelayedTimer );
mluis 32:26002607de9c 1572 LoRaMacState &= ~LORAMAC_TX_DELAYED;
mluis 2:14a5d6ad92d5 1573
Shaun Nelson 38:182ba91524e4 1574 index = GetMlmeConfirmIndex( MlmeConfirmQueue, MLME_JOIN );
Shaun Nelson 38:182ba91524e4 1575
Shaun Nelson 38:182ba91524e4 1576 if( ( LoRaMacFlags.Bits.MlmeReq == 1 ) && ( index < LORA_MAC_MLME_CONFIRM_QUEUE_LEN ) )
mluis 7:c16969e0f70f 1577 {
mluis 32:26002607de9c 1578 ResetMacParameters( );
Shaun Nelson 38:182ba91524e4 1579
Shaun Nelson 38:182ba91524e4 1580 altDr.NbTrials = JoinRequestTrials + 1;
Shaun Nelson 38:182ba91524e4 1581 LoRaMacParams.ChannelsDatarate = RegionAlternateDr( LoRaMacRegion, &altDr );
mluis 32:26002607de9c 1582
mluis 7:c16969e0f70f 1583 macHdr.Value = 0;
mluis 7:c16969e0f70f 1584 macHdr.Bits.MType = FRAME_TYPE_JOIN_REQ;
mluis 7:c16969e0f70f 1585
mluis 7:c16969e0f70f 1586 fCtrl.Value = 0;
mluis 7:c16969e0f70f 1587 fCtrl.Bits.Adr = AdrCtrlOn;
mluis 7:c16969e0f70f 1588
mluis 32:26002607de9c 1589 /* In case of join request retransmissions, the stack must prepare
mluis 7:c16969e0f70f 1590 * the frame again, because the network server keeps track of the random
mluis 7:c16969e0f70f 1591 * LoRaMacDevNonce values to prevent reply attacks. */
mluis 7:c16969e0f70f 1592 PrepareFrame( &macHdr, &fCtrl, 0, NULL, 0 );
mluis 7:c16969e0f70f 1593 }
mluis 7:c16969e0f70f 1594
mluis 2:14a5d6ad92d5 1595 ScheduleTx( );
mluis 2:14a5d6ad92d5 1596 }
mluis 2:14a5d6ad92d5 1597
mluis 2:14a5d6ad92d5 1598 static void OnRxWindow1TimerEvent( void )
mluis 2:14a5d6ad92d5 1599 {
mluis 2:14a5d6ad92d5 1600 TimerStop( &RxWindowTimer1 );
mluis 2:14a5d6ad92d5 1601 RxSlot = 0;
mluis 2:14a5d6ad92d5 1602
Shaun Nelson 38:182ba91524e4 1603 RxWindow1Config.Channel = Channel;
Shaun Nelson 38:182ba91524e4 1604 RxWindow1Config.DrOffset = LoRaMacParams.Rx1DrOffset;
Shaun Nelson 38:182ba91524e4 1605 RxWindow1Config.DownlinkDwellTime = LoRaMacParams.DownlinkDwellTime;
Shaun Nelson 38:182ba91524e4 1606 RxWindow1Config.RepeaterSupport = LoRaMacParams.RepeaterSupport;
Shaun Nelson 38:182ba91524e4 1607 RxWindow1Config.RxContinuous = false;
Shaun Nelson 38:182ba91524e4 1608 RxWindow1Config.Window = RxSlot;
Shaun Nelson 38:182ba91524e4 1609
mluis 2:14a5d6ad92d5 1610 if( LoRaMacDeviceClass == CLASS_C )
mluis 2:14a5d6ad92d5 1611 {
mluis 2:14a5d6ad92d5 1612 Radio.Standby( );
mluis 2:14a5d6ad92d5 1613 }
mluis 2:14a5d6ad92d5 1614
Shaun Nelson 38:182ba91524e4 1615 RegionRxConfig( LoRaMacRegion, &RxWindow1Config, ( int8_t* )&McpsIndication.RxDatarate );
Shaun Nelson 38:182ba91524e4 1616 RxWindowSetup( RxWindow1Config.RxContinuous, LoRaMacParams.MaxRxWindow );
mluis 2:14a5d6ad92d5 1617 }
mluis 2:14a5d6ad92d5 1618
mluis 2:14a5d6ad92d5 1619 static void OnRxWindow2TimerEvent( void )
mluis 2:14a5d6ad92d5 1620 {
mluis 2:14a5d6ad92d5 1621 TimerStop( &RxWindowTimer2 );
mluis 32:26002607de9c 1622
Shaun Nelson 38:182ba91524e4 1623 RxWindow2Config.Channel = Channel;
Shaun Nelson 38:182ba91524e4 1624 RxWindow2Config.Frequency = LoRaMacParams.Rx2Channel.Frequency;
Shaun Nelson 38:182ba91524e4 1625 RxWindow2Config.DownlinkDwellTime = LoRaMacParams.DownlinkDwellTime;
Shaun Nelson 38:182ba91524e4 1626 RxWindow2Config.RepeaterSupport = LoRaMacParams.RepeaterSupport;
Shaun Nelson 38:182ba91524e4 1627 RxWindow2Config.Window = 1;
Shaun Nelson 38:182ba91524e4 1628
Shaun Nelson 38:182ba91524e4 1629 if( LoRaMacDeviceClass != CLASS_C )
mluis 4:37c12dbc8dc7 1630 {
Shaun Nelson 38:182ba91524e4 1631 RxWindow2Config.RxContinuous = false;
Shaun Nelson 38:182ba91524e4 1632 }
Shaun Nelson 38:182ba91524e4 1633 else
Shaun Nelson 38:182ba91524e4 1634 {
Shaun Nelson 38:182ba91524e4 1635 RxWindow2Config.RxContinuous = true;
mluis 2:14a5d6ad92d5 1636 }
Shaun Nelson 38:182ba91524e4 1637
Shaun Nelson 38:182ba91524e4 1638 if( RegionRxConfig( LoRaMacRegion, &RxWindow2Config, ( int8_t* )&McpsIndication.RxDatarate ) == true )
mluis 2:14a5d6ad92d5 1639 {
Shaun Nelson 38:182ba91524e4 1640 RxWindowSetup( RxWindow2Config.RxContinuous, LoRaMacParams.MaxRxWindow );
Shaun Nelson 38:182ba91524e4 1641 RxSlot = RxWindow2Config.Window;
mluis 2:14a5d6ad92d5 1642 }
mluis 2:14a5d6ad92d5 1643 }
mluis 2:14a5d6ad92d5 1644
mluis 2:14a5d6ad92d5 1645 static void OnAckTimeoutTimerEvent( void )
mluis 2:14a5d6ad92d5 1646 {
mluis 2:14a5d6ad92d5 1647 TimerStop( &AckTimeoutTimer );
mluis 2:14a5d6ad92d5 1648
mluis 2:14a5d6ad92d5 1649 if( NodeAckRequested == true )
mluis 2:14a5d6ad92d5 1650 {
mluis 2:14a5d6ad92d5 1651 AckTimeoutRetry = true;
mluis 32:26002607de9c 1652 LoRaMacState &= ~LORAMAC_ACK_REQ;
mluis 2:14a5d6ad92d5 1653 }
mluis 2:14a5d6ad92d5 1654 if( LoRaMacDeviceClass == CLASS_C )
mluis 2:14a5d6ad92d5 1655 {
mluis 2:14a5d6ad92d5 1656 LoRaMacFlags.Bits.MacDone = 1;
mluis 2:14a5d6ad92d5 1657 }
mluis 2:14a5d6ad92d5 1658 }
mluis 2:14a5d6ad92d5 1659
Shaun Nelson 38:182ba91524e4 1660 static void RxWindowSetup( bool rxContinuous, uint32_t maxRxWindow )
mluis 2:14a5d6ad92d5 1661 {
Shaun Nelson 38:182ba91524e4 1662 if( rxContinuous == false )
mluis 0:91d1a7783bb9 1663 {
Shaun Nelson 38:182ba91524e4 1664 Radio.Rx( maxRxWindow );
mluis 2:14a5d6ad92d5 1665 }
mluis 2:14a5d6ad92d5 1666 else
mluis 2:14a5d6ad92d5 1667 {
Shaun Nelson 38:182ba91524e4 1668 Radio.Rx( 0 ); // Continuous mode
mluis 2:14a5d6ad92d5 1669 }
mluis 2:14a5d6ad92d5 1670 }
mluis 2:14a5d6ad92d5 1671
Shaun Nelson 38:182ba91524e4 1672 static LoRaMacStatus_t SwitchClass( DeviceClass_t deviceClass )
mluis 2:14a5d6ad92d5 1673 {
Shaun Nelson 38:182ba91524e4 1674 LoRaMacStatus_t status = LORAMAC_STATUS_PARAMETER_INVALID;
Shaun Nelson 38:182ba91524e4 1675
Shaun Nelson 38:182ba91524e4 1676 switch( LoRaMacDeviceClass )
mluis 2:14a5d6ad92d5 1677 {
Shaun Nelson 38:182ba91524e4 1678 case CLASS_A:
mluis 2:14a5d6ad92d5 1679 {
Shaun Nelson 38:182ba91524e4 1680 if( deviceClass == CLASS_B )
Shaun Nelson 38:182ba91524e4 1681 {
Shaun Nelson 38:182ba91524e4 1682 status = LoRaMacClassBSwitchClass( deviceClass );
Shaun Nelson 38:182ba91524e4 1683 if( status == LORAMAC_STATUS_OK )
Shaun Nelson 38:182ba91524e4 1684 {
Shaun Nelson 38:182ba91524e4 1685 LoRaMacDeviceClass = deviceClass;
Shaun Nelson 38:182ba91524e4 1686 }
Shaun Nelson 38:182ba91524e4 1687 }
Shaun Nelson 38:182ba91524e4 1688
Shaun Nelson 38:182ba91524e4 1689 if( deviceClass == CLASS_C )
Shaun Nelson 38:182ba91524e4 1690 {
Shaun Nelson 38:182ba91524e4 1691 LoRaMacDeviceClass = deviceClass;
Shaun Nelson 38:182ba91524e4 1692
Shaun Nelson 38:182ba91524e4 1693 // Set the NodeAckRequested indicator to default
Shaun Nelson 38:182ba91524e4 1694 NodeAckRequested = false;
Shaun Nelson 38:182ba91524e4 1695 OnRxWindow2TimerEvent( );
Shaun Nelson 38:182ba91524e4 1696
Shaun Nelson 38:182ba91524e4 1697 status = LORAMAC_STATUS_OK;
Shaun Nelson 38:182ba91524e4 1698 }
Shaun Nelson 38:182ba91524e4 1699 break;
mluis 2:14a5d6ad92d5 1700 }
Shaun Nelson 38:182ba91524e4 1701 case CLASS_B:
mluis 2:14a5d6ad92d5 1702 {
Shaun Nelson 38:182ba91524e4 1703 status = LoRaMacClassBSwitchClass( deviceClass );
Shaun Nelson 38:182ba91524e4 1704 if( status == LORAMAC_STATUS_OK )
Shaun Nelson 38:182ba91524e4 1705 {
Shaun Nelson 38:182ba91524e4 1706 LoRaMacDeviceClass = deviceClass;
Shaun Nelson 47:e7fd944a7215 1707
Shaun Nelson 47:e7fd944a7215 1708 // This starts ping slot
Shaun Nelson 47:e7fd944a7215 1709 LoRaMacClassBResumeBeaconing( );
Shaun Nelson 38:182ba91524e4 1710 }
Shaun Nelson 38:182ba91524e4 1711 break;
mluis 2:14a5d6ad92d5 1712 }
Shaun Nelson 38:182ba91524e4 1713 case CLASS_C:
mluis 2:14a5d6ad92d5 1714 {
Shaun Nelson 38:182ba91524e4 1715 if( deviceClass == CLASS_A )
Shaun Nelson 38:182ba91524e4 1716 {
Shaun Nelson 38:182ba91524e4 1717 LoRaMacDeviceClass = deviceClass;
Shaun Nelson 38:182ba91524e4 1718
Shaun Nelson 38:182ba91524e4 1719 // Set the radio into sleep to setup a defined state
Shaun Nelson 38:182ba91524e4 1720 Radio.Sleep( );
Shaun Nelson 38:182ba91524e4 1721
Shaun Nelson 38:182ba91524e4 1722 status = LORAMAC_STATUS_OK;
Shaun Nelson 38:182ba91524e4 1723 }
Shaun Nelson 38:182ba91524e4 1724 break;
mluis 2:14a5d6ad92d5 1725 }
mluis 2:14a5d6ad92d5 1726 }
Shaun Nelson 38:182ba91524e4 1727
Shaun Nelson 38:182ba91524e4 1728 return status;
mluis 7:c16969e0f70f 1729 }
mluis 7:c16969e0f70f 1730
mluis 2:14a5d6ad92d5 1731 static bool ValidatePayloadLength( uint8_t lenN, int8_t datarate, uint8_t fOptsLen )
mluis 2:14a5d6ad92d5 1732 {
Shaun Nelson 38:182ba91524e4 1733 GetPhyParams_t getPhy;
Shaun Nelson 38:182ba91524e4 1734 PhyParam_t phyParam;
mluis 2:14a5d6ad92d5 1735 uint16_t maxN = 0;
mluis 2:14a5d6ad92d5 1736 uint16_t payloadSize = 0;
mluis 2:14a5d6ad92d5 1737
Shaun Nelson 38:182ba91524e4 1738 // Setup PHY request
Shaun Nelson 38:182ba91524e4 1739 getPhy.UplinkDwellTime = LoRaMacParams.UplinkDwellTime;
Shaun Nelson 38:182ba91524e4 1740 getPhy.Datarate = datarate;
Shaun Nelson 38:182ba91524e4 1741 getPhy.Attribute = PHY_MAX_PAYLOAD;
Shaun Nelson 38:182ba91524e4 1742
mluis 2:14a5d6ad92d5 1743 // Get the maximum payload length
Shaun Nelson 38:182ba91524e4 1744 if( LoRaMacParams.RepeaterSupport == true )
mluis 2:14a5d6ad92d5 1745 {
Shaun Nelson 38:182ba91524e4 1746 getPhy.Attribute = PHY_MAX_PAYLOAD_REPEATER;
mluis 2:14a5d6ad92d5 1747 }
Shaun Nelson 38:182ba91524e4 1748 phyParam = RegionGetPhyParam( LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 1749 maxN = phyParam.Value;
mluis 2:14a5d6ad92d5 1750
mluis 2:14a5d6ad92d5 1751 // Calculate the resulting payload size
mluis 2:14a5d6ad92d5 1752 payloadSize = ( lenN + fOptsLen );
mluis 2:14a5d6ad92d5 1753
mluis 2:14a5d6ad92d5 1754 // Validation of the application payload size
mluis 2:14a5d6ad92d5 1755 if( ( payloadSize <= maxN ) && ( payloadSize <= LORAMAC_PHY_MAXPAYLOAD ) )
mluis 2:14a5d6ad92d5 1756 {
mluis 2:14a5d6ad92d5 1757 return true;
mluis 2:14a5d6ad92d5 1758 }
mluis 2:14a5d6ad92d5 1759 return false;
mluis 2:14a5d6ad92d5 1760 }
mluis 2:14a5d6ad92d5 1761
mluis 2:14a5d6ad92d5 1762 static LoRaMacStatus_t AddMacCommand( uint8_t cmd, uint8_t p1, uint8_t p2 )
mluis 0:91d1a7783bb9 1763 {
mluis 2:14a5d6ad92d5 1764 LoRaMacStatus_t status = LORAMAC_STATUS_BUSY;
mluis 7:c16969e0f70f 1765 // The maximum buffer length must take MAC commands to re-send into account.
mluis 7:c16969e0f70f 1766 uint8_t bufLen = LORA_MAC_COMMAND_MAX_LENGTH - MacCommandsBufferToRepeatIndex;
mluis 1:91e4e6c60d1e 1767
mluis 0:91d1a7783bb9 1768 switch( cmd )
mluis 0:91d1a7783bb9 1769 {
mluis 0:91d1a7783bb9 1770 case MOTE_MAC_LINK_CHECK_REQ:
mluis 7:c16969e0f70f 1771 if( MacCommandsBufferIndex < bufLen )
mluis 1:91e4e6c60d1e 1772 {
mluis 1:91e4e6c60d1e 1773 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
mluis 1:91e4e6c60d1e 1774 // No payload for this command
mluis 2:14a5d6ad92d5 1775 status = LORAMAC_STATUS_OK;
mluis 1:91e4e6c60d1e 1776 }
mluis 0:91d1a7783bb9 1777 break;
mluis 0:91d1a7783bb9 1778 case MOTE_MAC_LINK_ADR_ANS:
mluis 7:c16969e0f70f 1779 if( MacCommandsBufferIndex < ( bufLen - 1 ) )
mluis 1:91e4e6c60d1e 1780 {
mluis 1:91e4e6c60d1e 1781 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
mluis 1:91e4e6c60d1e 1782 // Margin
mluis 1:91e4e6c60d1e 1783 MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
mluis 2:14a5d6ad92d5 1784 status = LORAMAC_STATUS_OK;
mluis 1:91e4e6c60d1e 1785 }
mluis 0:91d1a7783bb9 1786 break;
mluis 0:91d1a7783bb9 1787 case MOTE_MAC_DUTY_CYCLE_ANS:
mluis 7:c16969e0f70f 1788 if( MacCommandsBufferIndex < bufLen )
mluis 1:91e4e6c60d1e 1789 {
mluis 1:91e4e6c60d1e 1790 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
mluis 1:91e4e6c60d1e 1791 // No payload for this answer
mluis 2:14a5d6ad92d5 1792 status = LORAMAC_STATUS_OK;
mluis 1:91e4e6c60d1e 1793 }
mluis 0:91d1a7783bb9 1794 break;
mluis 0:91d1a7783bb9 1795 case MOTE_MAC_RX_PARAM_SETUP_ANS:
mluis 7:c16969e0f70f 1796 if( MacCommandsBufferIndex < ( bufLen - 1 ) )
mluis 1:91e4e6c60d1e 1797 {
mluis 1:91e4e6c60d1e 1798 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
mluis 1:91e4e6c60d1e 1799 // Status: Datarate ACK, Channel ACK
mluis 1:91e4e6c60d1e 1800 MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
mluis 2:14a5d6ad92d5 1801 status = LORAMAC_STATUS_OK;
mluis 1:91e4e6c60d1e 1802 }
mluis 0:91d1a7783bb9 1803 break;
mluis 0:91d1a7783bb9 1804 case MOTE_MAC_DEV_STATUS_ANS:
mluis 7:c16969e0f70f 1805 if( MacCommandsBufferIndex < ( bufLen - 2 ) )
mluis 1:91e4e6c60d1e 1806 {
mluis 1:91e4e6c60d1e 1807 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
mluis 1:91e4e6c60d1e 1808 // 1st byte Battery
mluis 1:91e4e6c60d1e 1809 // 2nd byte Margin
mluis 1:91e4e6c60d1e 1810 MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
mluis 1:91e4e6c60d1e 1811 MacCommandsBuffer[MacCommandsBufferIndex++] = p2;
mluis 2:14a5d6ad92d5 1812 status = LORAMAC_STATUS_OK;
mluis 1:91e4e6c60d1e 1813 }
mluis 0:91d1a7783bb9 1814 break;
mluis 0:91d1a7783bb9 1815 case MOTE_MAC_NEW_CHANNEL_ANS:
mluis 7:c16969e0f70f 1816 if( MacCommandsBufferIndex < ( bufLen - 1 ) )
mluis 1:91e4e6c60d1e 1817 {
mluis 1:91e4e6c60d1e 1818 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
mluis 1:91e4e6c60d1e 1819 // Status: Datarate range OK, Channel frequency OK
mluis 1:91e4e6c60d1e 1820 MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
mluis 2:14a5d6ad92d5 1821 status = LORAMAC_STATUS_OK;
mluis 1:91e4e6c60d1e 1822 }
mluis 0:91d1a7783bb9 1823 break;
mluis 0:91d1a7783bb9 1824 case MOTE_MAC_RX_TIMING_SETUP_ANS:
mluis 7:c16969e0f70f 1825 if( MacCommandsBufferIndex < bufLen )
mluis 1:91e4e6c60d1e 1826 {
mluis 1:91e4e6c60d1e 1827 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
mluis 1:91e4e6c60d1e 1828 // No payload for this answer
mluis 2:14a5d6ad92d5 1829 status = LORAMAC_STATUS_OK;
mluis 1:91e4e6c60d1e 1830 }
mluis 0:91d1a7783bb9 1831 break;
Shaun Nelson 38:182ba91524e4 1832 case MOTE_MAC_TX_PARAM_SETUP_ANS:
Shaun Nelson 38:182ba91524e4 1833 if( MacCommandsBufferIndex < bufLen )
Shaun Nelson 38:182ba91524e4 1834 {
Shaun Nelson 38:182ba91524e4 1835 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
Shaun Nelson 38:182ba91524e4 1836 // No payload for this answer
Shaun Nelson 38:182ba91524e4 1837 status = LORAMAC_STATUS_OK;
Shaun Nelson 38:182ba91524e4 1838 }
Shaun Nelson 38:182ba91524e4 1839 break;
Shaun Nelson 38:182ba91524e4 1840 case MOTE_MAC_DL_CHANNEL_ANS:
Shaun Nelson 38:182ba91524e4 1841 if( MacCommandsBufferIndex < bufLen )
Shaun Nelson 38:182ba91524e4 1842 {
Shaun Nelson 38:182ba91524e4 1843 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
Shaun Nelson 38:182ba91524e4 1844 // Status: Uplink frequency exists, Channel frequency OK
Shaun Nelson 38:182ba91524e4 1845 MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
Shaun Nelson 38:182ba91524e4 1846 status = LORAMAC_STATUS_OK;
Shaun Nelson 38:182ba91524e4 1847 }
Shaun Nelson 38:182ba91524e4 1848 break;
Shaun Nelson 38:182ba91524e4 1849 case MOTE_MAC_PING_SLOT_INFO_REQ:
Shaun Nelson 38:182ba91524e4 1850 if( MacCommandsBufferIndex < ( LORA_MAC_COMMAND_MAX_LENGTH - 1 ) )
Shaun Nelson 38:182ba91524e4 1851 {
Shaun Nelson 38:182ba91524e4 1852 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
Shaun Nelson 38:182ba91524e4 1853 // Status: Periodicity and Datarate
Shaun Nelson 38:182ba91524e4 1854 MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
Shaun Nelson 38:182ba91524e4 1855 status = LORAMAC_STATUS_OK;
Shaun Nelson 38:182ba91524e4 1856 }
Shaun Nelson 38:182ba91524e4 1857 break;
Shaun Nelson 38:182ba91524e4 1858 case MOTE_MAC_PING_SLOT_FREQ_ANS:
Shaun Nelson 38:182ba91524e4 1859 if( MacCommandsBufferIndex < LORA_MAC_COMMAND_MAX_LENGTH )
Shaun Nelson 38:182ba91524e4 1860 {
Shaun Nelson 38:182ba91524e4 1861 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
Shaun Nelson 38:182ba91524e4 1862 // Status: Datarate range OK, Channel frequency OK
Shaun Nelson 38:182ba91524e4 1863 MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
Shaun Nelson 38:182ba91524e4 1864 status = LORAMAC_STATUS_OK;
Shaun Nelson 38:182ba91524e4 1865 }
Shaun Nelson 38:182ba91524e4 1866 break;
Shaun Nelson 38:182ba91524e4 1867 case MOTE_MAC_BEACON_TIMING_REQ:
Shaun Nelson 38:182ba91524e4 1868 if( MacCommandsBufferIndex < LORA_MAC_COMMAND_MAX_LENGTH )
Shaun Nelson 38:182ba91524e4 1869 {
Shaun Nelson 38:182ba91524e4 1870 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
Shaun Nelson 38:182ba91524e4 1871 // No payload for this answer
Shaun Nelson 38:182ba91524e4 1872 status = LORAMAC_STATUS_OK;
Shaun Nelson 38:182ba91524e4 1873 }
Shaun Nelson 38:182ba91524e4 1874 break;
Shaun Nelson 38:182ba91524e4 1875 case MOTE_MAC_BEACON_FREQ_ANS:
Shaun Nelson 38:182ba91524e4 1876 if( MacCommandsBufferIndex < LORA_MAC_COMMAND_MAX_LENGTH )
Shaun Nelson 38:182ba91524e4 1877 {
Shaun Nelson 38:182ba91524e4 1878 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
Shaun Nelson 38:182ba91524e4 1879 // No payload for this answer
Shaun Nelson 38:182ba91524e4 1880 status = LORAMAC_STATUS_OK;
Shaun Nelson 38:182ba91524e4 1881 }
Shaun Nelson 38:182ba91524e4 1882 break;
mluis 0:91d1a7783bb9 1883 default:
mluis 2:14a5d6ad92d5 1884 return LORAMAC_STATUS_SERVICE_UNKNOWN;
mluis 0:91d1a7783bb9 1885 }
mluis 2:14a5d6ad92d5 1886 if( status == LORAMAC_STATUS_OK )
mluis 0:91d1a7783bb9 1887 {
mluis 0:91d1a7783bb9 1888 MacCommandsInNextTx = true;
mluis 0:91d1a7783bb9 1889 }
mluis 1:91e4e6c60d1e 1890 return status;
mluis 0:91d1a7783bb9 1891 }
mluis 0:91d1a7783bb9 1892
mluis 7:c16969e0f70f 1893 static uint8_t ParseMacCommandsToRepeat( uint8_t* cmdBufIn, uint8_t length, uint8_t* cmdBufOut )
mluis 7:c16969e0f70f 1894 {
mluis 7:c16969e0f70f 1895 uint8_t i = 0;
mluis 7:c16969e0f70f 1896 uint8_t cmdCount = 0;
mluis 7:c16969e0f70f 1897
mluis 7:c16969e0f70f 1898 if( ( cmdBufIn == NULL ) || ( cmdBufOut == NULL ) )
mluis 7:c16969e0f70f 1899 {
mluis 7:c16969e0f70f 1900 return 0;
mluis 7:c16969e0f70f 1901 }
mluis 7:c16969e0f70f 1902
mluis 7:c16969e0f70f 1903 for( i = 0; i < length; i++ )
mluis 7:c16969e0f70f 1904 {
mluis 7:c16969e0f70f 1905 switch( cmdBufIn[i] )
mluis 7:c16969e0f70f 1906 {
mluis 32:26002607de9c 1907 // STICKY
Shaun Nelson 38:182ba91524e4 1908 case MOTE_MAC_DL_CHANNEL_ANS:
mluis 7:c16969e0f70f 1909 case MOTE_MAC_RX_PARAM_SETUP_ANS:
Shaun Nelson 38:182ba91524e4 1910 { // 1 byte payload
mluis 7:c16969e0f70f 1911 cmdBufOut[cmdCount++] = cmdBufIn[i++];
mluis 7:c16969e0f70f 1912 cmdBufOut[cmdCount++] = cmdBufIn[i];
mluis 7:c16969e0f70f 1913 break;
mluis 7:c16969e0f70f 1914 }
mluis 7:c16969e0f70f 1915 case MOTE_MAC_RX_TIMING_SETUP_ANS:
Shaun Nelson 38:182ba91524e4 1916 { // 0 byte payload
mluis 7:c16969e0f70f 1917 cmdBufOut[cmdCount++] = cmdBufIn[i];
mluis 7:c16969e0f70f 1918 break;
mluis 7:c16969e0f70f 1919 }
mluis 32:26002607de9c 1920 // NON-STICKY
mluis 32:26002607de9c 1921 case MOTE_MAC_DEV_STATUS_ANS:
mluis 32:26002607de9c 1922 { // 2 bytes payload
mluis 32:26002607de9c 1923 i += 2;
mluis 32:26002607de9c 1924 break;
mluis 32:26002607de9c 1925 }
mluis 32:26002607de9c 1926 case MOTE_MAC_LINK_ADR_ANS:
mluis 32:26002607de9c 1927 case MOTE_MAC_NEW_CHANNEL_ANS:
mluis 32:26002607de9c 1928 { // 1 byte payload
mluis 32:26002607de9c 1929 i++;
mluis 32:26002607de9c 1930 break;
mluis 32:26002607de9c 1931 }
Shaun Nelson 38:182ba91524e4 1932 case MOTE_MAC_TX_PARAM_SETUP_ANS:
mluis 32:26002607de9c 1933 case MOTE_MAC_DUTY_CYCLE_ANS:
mluis 32:26002607de9c 1934 case MOTE_MAC_LINK_CHECK_REQ:
mluis 32:26002607de9c 1935 { // 0 byte payload
mluis 32:26002607de9c 1936 break;
mluis 32:26002607de9c 1937 }
mluis 7:c16969e0f70f 1938 default:
mluis 7:c16969e0f70f 1939 break;
mluis 7:c16969e0f70f 1940 }
mluis 7:c16969e0f70f 1941 }
mluis 7:c16969e0f70f 1942
mluis 7:c16969e0f70f 1943 return cmdCount;
mluis 7:c16969e0f70f 1944 }
mluis 7:c16969e0f70f 1945
mluis 2:14a5d6ad92d5 1946 static void ProcessMacCommands( uint8_t *payload, uint8_t macIndex, uint8_t commandsSize, uint8_t snr )
mluis 0:91d1a7783bb9 1947 {
Shaun Nelson 38:182ba91524e4 1948 uint8_t status = 0;
Shaun Nelson 38:182ba91524e4 1949 uint8_t index = 0;
Shaun Nelson 38:182ba91524e4 1950
mluis 0:91d1a7783bb9 1951 while( macIndex < commandsSize )
mluis 0:91d1a7783bb9 1952 {
mluis 0:91d1a7783bb9 1953 // Decode Frame MAC commands
mluis 0:91d1a7783bb9 1954 switch( payload[macIndex++] )
mluis 0:91d1a7783bb9 1955 {
mluis 0:91d1a7783bb9 1956 case SRV_MAC_LINK_CHECK_ANS:
Shaun Nelson 38:182ba91524e4 1957 index = GetMlmeConfirmIndex( MlmeConfirmQueue, MLME_LINK_CHECK );
Shaun Nelson 38:182ba91524e4 1958 if( index < LORA_MAC_MLME_CONFIRM_QUEUE_LEN )
Shaun Nelson 38:182ba91524e4 1959 {
Shaun Nelson 38:182ba91524e4 1960 MlmeConfirmQueue[index].Status = LORAMAC_EVENT_INFO_STATUS_OK;
Shaun Nelson 38:182ba91524e4 1961 MlmeConfirm.DemodMargin = payload[macIndex++];
Shaun Nelson 38:182ba91524e4 1962 MlmeConfirm.NbGateways = payload[macIndex++];
Shaun Nelson 38:182ba91524e4 1963 }
mluis 0:91d1a7783bb9 1964 break;
mluis 0:91d1a7783bb9 1965 case SRV_MAC_LINK_ADR_REQ:
mluis 0:91d1a7783bb9 1966 {
Shaun Nelson 38:182ba91524e4 1967 LinkAdrReqParams_t linkAdrReq;
Shaun Nelson 38:182ba91524e4 1968 int8_t linkAdrDatarate = DR_0;
Shaun Nelson 38:182ba91524e4 1969 int8_t linkAdrTxPower = TX_POWER_0;
Shaun Nelson 38:182ba91524e4 1970 uint8_t linkAdrNbRep = 0;
Shaun Nelson 38:182ba91524e4 1971 uint8_t linkAdrNbBytesParsed = 0;
Shaun Nelson 38:182ba91524e4 1972
Shaun Nelson 38:182ba91524e4 1973 // Fill parameter structure
Shaun Nelson 38:182ba91524e4 1974 linkAdrReq.Payload = &payload[macIndex - 1];
Shaun Nelson 38:182ba91524e4 1975 linkAdrReq.PayloadSize = commandsSize - ( macIndex - 1 );
Shaun Nelson 38:182ba91524e4 1976 linkAdrReq.AdrEnabled = AdrCtrlOn;
Shaun Nelson 38:182ba91524e4 1977 linkAdrReq.UplinkDwellTime = LoRaMacParams.UplinkDwellTime;
Shaun Nelson 38:182ba91524e4 1978 linkAdrReq.CurrentDatarate = LoRaMacParams.ChannelsDatarate;
Shaun Nelson 38:182ba91524e4 1979 linkAdrReq.CurrentTxPower = LoRaMacParams.ChannelsTxPower;
Shaun Nelson 38:182ba91524e4 1980 linkAdrReq.CurrentNbRep = LoRaMacParams.ChannelsNbRep;
Shaun Nelson 38:182ba91524e4 1981
Shaun Nelson 38:182ba91524e4 1982 // Process the ADR requests
Shaun Nelson 38:182ba91524e4 1983 status = RegionLinkAdrReq( LoRaMacRegion, &linkAdrReq, &linkAdrDatarate,
Shaun Nelson 38:182ba91524e4 1984 &linkAdrTxPower, &linkAdrNbRep, &linkAdrNbBytesParsed );
Shaun Nelson 38:182ba91524e4 1985
mluis 0:91d1a7783bb9 1986 if( ( status & 0x07 ) == 0x07 )
mluis 0:91d1a7783bb9 1987 {
Shaun Nelson 38:182ba91524e4 1988 LoRaMacParams.ChannelsDatarate = linkAdrDatarate;
Shaun Nelson 38:182ba91524e4 1989 LoRaMacParams.ChannelsTxPower = linkAdrTxPower;
Shaun Nelson 38:182ba91524e4 1990 LoRaMacParams.ChannelsNbRep = linkAdrNbRep;
mluis 0:91d1a7783bb9 1991 }
Shaun Nelson 38:182ba91524e4 1992
Shaun Nelson 38:182ba91524e4 1993 // Add the answers to the buffer
Shaun Nelson 38:182ba91524e4 1994 for( uint8_t i = 0; i < ( linkAdrNbBytesParsed / 5 ); i++ )
Shaun Nelson 38:182ba91524e4 1995 {
Shaun Nelson 38:182ba91524e4 1996 AddMacCommand( MOTE_MAC_LINK_ADR_ANS, status, 0 );
Shaun Nelson 38:182ba91524e4 1997 }
Shaun Nelson 38:182ba91524e4 1998 // Update MAC index
Shaun Nelson 38:182ba91524e4 1999 macIndex += linkAdrNbBytesParsed - 1;
mluis 0:91d1a7783bb9 2000 }
mluis 0:91d1a7783bb9 2001 break;
mluis 0:91d1a7783bb9 2002 case SRV_MAC_DUTY_CYCLE_REQ:
mluis 0:91d1a7783bb9 2003 MaxDCycle = payload[macIndex++];
mluis 0:91d1a7783bb9 2004 AggregatedDCycle = 1 << MaxDCycle;
mluis 0:91d1a7783bb9 2005 AddMacCommand( MOTE_MAC_DUTY_CYCLE_ANS, 0, 0 );
mluis 0:91d1a7783bb9 2006 break;
mluis 0:91d1a7783bb9 2007 case SRV_MAC_RX_PARAM_SETUP_REQ:
mluis 0:91d1a7783bb9 2008 {
Shaun Nelson 38:182ba91524e4 2009 RxParamSetupReqParams_t rxParamSetupReq;
Shaun Nelson 38:182ba91524e4 2010 status = 0x07;
Shaun Nelson 38:182ba91524e4 2011
Shaun Nelson 38:182ba91524e4 2012 rxParamSetupReq.DrOffset = ( payload[macIndex] >> 4 ) & 0x07;
Shaun Nelson 38:182ba91524e4 2013 rxParamSetupReq.Datarate = payload[macIndex] & 0x0F;
mluis 1:91e4e6c60d1e 2014 macIndex++;
mluis 2:14a5d6ad92d5 2015
Shaun Nelson 38:182ba91524e4 2016 rxParamSetupReq.Frequency = ( uint32_t )payload[macIndex++];
Shaun Nelson 38:182ba91524e4 2017 rxParamSetupReq.Frequency |= ( uint32_t )payload[macIndex++] << 8;
Shaun Nelson 38:182ba91524e4 2018 rxParamSetupReq.Frequency |= ( uint32_t )payload[macIndex++] << 16;
Shaun Nelson 38:182ba91524e4 2019 rxParamSetupReq.Frequency *= 100;
Shaun Nelson 38:182ba91524e4 2020
Shaun Nelson 38:182ba91524e4 2021 // Perform request on region
Shaun Nelson 38:182ba91524e4 2022 status = RegionRxParamSetupReq( LoRaMacRegion, &rxParamSetupReq );
mluis 2:14a5d6ad92d5 2023
mluis 0:91d1a7783bb9 2024 if( ( status & 0x07 ) == 0x07 )
mluis 0:91d1a7783bb9 2025 {
Shaun Nelson 38:182ba91524e4 2026 LoRaMacParams.Rx2Channel.Datarate = rxParamSetupReq.Datarate;
Shaun Nelson 38:182ba91524e4 2027 LoRaMacParams.Rx2Channel.Frequency = rxParamSetupReq.Frequency;
Shaun Nelson 38:182ba91524e4 2028 LoRaMacParams.Rx1DrOffset = rxParamSetupReq.DrOffset;
mluis 0:91d1a7783bb9 2029 }
mluis 0:91d1a7783bb9 2030 AddMacCommand( MOTE_MAC_RX_PARAM_SETUP_ANS, status, 0 );
mluis 0:91d1a7783bb9 2031 }
mluis 0:91d1a7783bb9 2032 break;
mluis 0:91d1a7783bb9 2033 case SRV_MAC_DEV_STATUS_REQ:
mluis 1:91e4e6c60d1e 2034 {
mluis 1:91e4e6c60d1e 2035 uint8_t batteryLevel = BAT_LEVEL_NO_MEASURE;
mluis 1:91e4e6c60d1e 2036 if( ( LoRaMacCallbacks != NULL ) && ( LoRaMacCallbacks->GetBatteryLevel != NULL ) )
mluis 1:91e4e6c60d1e 2037 {
mluis 1:91e4e6c60d1e 2038 batteryLevel = LoRaMacCallbacks->GetBatteryLevel( );
mluis 1:91e4e6c60d1e 2039 }
mluis 2:14a5d6ad92d5 2040 AddMacCommand( MOTE_MAC_DEV_STATUS_ANS, batteryLevel, snr );
mluis 2:14a5d6ad92d5 2041 break;
mluis 1:91e4e6c60d1e 2042 }
mluis 0:91d1a7783bb9 2043 case SRV_MAC_NEW_CHANNEL_REQ:
mluis 0:91d1a7783bb9 2044 {
Shaun Nelson 38:182ba91524e4 2045 NewChannelReqParams_t newChannelReq;
mluis 0:91d1a7783bb9 2046 ChannelParams_t chParam;
Shaun Nelson 38:182ba91524e4 2047 status = 0x03;
Shaun Nelson 38:182ba91524e4 2048
Shaun Nelson 38:182ba91524e4 2049 newChannelReq.ChannelId = payload[macIndex++];
Shaun Nelson 38:182ba91524e4 2050 newChannelReq.NewChannel = &chParam;
Shaun Nelson 38:182ba91524e4 2051
mluis 0:91d1a7783bb9 2052 chParam.Frequency = ( uint32_t )payload[macIndex++];
mluis 0:91d1a7783bb9 2053 chParam.Frequency |= ( uint32_t )payload[macIndex++] << 8;
mluis 0:91d1a7783bb9 2054 chParam.Frequency |= ( uint32_t )payload[macIndex++] << 16;
mluis 0:91d1a7783bb9 2055 chParam.Frequency *= 100;
Shaun Nelson 38:182ba91524e4 2056 chParam.Rx1Frequency = 0;
mluis 0:91d1a7783bb9 2057 chParam.DrRange.Value = payload[macIndex++];
mluis 2:14a5d6ad92d5 2058
Shaun Nelson 38:182ba91524e4 2059 status = RegionNewChannelReq( LoRaMacRegion, &newChannelReq );
Shaun Nelson 38:182ba91524e4 2060
mluis 0:91d1a7783bb9 2061 AddMacCommand( MOTE_MAC_NEW_CHANNEL_ANS, status, 0 );
mluis 0:91d1a7783bb9 2062 }
mluis 0:91d1a7783bb9 2063 break;
mluis 0:91d1a7783bb9 2064 case SRV_MAC_RX_TIMING_SETUP_REQ:
mluis 0:91d1a7783bb9 2065 {
mluis 0:91d1a7783bb9 2066 uint8_t delay = payload[macIndex++] & 0x0F;
mluis 2:14a5d6ad92d5 2067
mluis 0:91d1a7783bb9 2068 if( delay == 0 )
mluis 0:91d1a7783bb9 2069 {
mluis 0:91d1a7783bb9 2070 delay++;
mluis 0:91d1a7783bb9 2071 }
Shaun Nelson 38:182ba91524e4 2072 LoRaMacParams.ReceiveDelay1 = delay * 1000;
Shaun Nelson 38:182ba91524e4 2073 LoRaMacParams.ReceiveDelay2 = LoRaMacParams.ReceiveDelay1 + 1000;
mluis 0:91d1a7783bb9 2074 AddMacCommand( MOTE_MAC_RX_TIMING_SETUP_ANS, 0, 0 );
mluis 0:91d1a7783bb9 2075 }
mluis 0:91d1a7783bb9 2076 break;
Shaun Nelson 38:182ba91524e4 2077 case SRV_MAC_TX_PARAM_SETUP_REQ:
Shaun Nelson 38:182ba91524e4 2078 {
Shaun Nelson 38:182ba91524e4 2079 TxParamSetupReqParams_t txParamSetupReq;
Shaun Nelson 38:182ba91524e4 2080 uint8_t eirpDwellTime = payload[macIndex++];
Shaun Nelson 38:182ba91524e4 2081
Shaun Nelson 38:182ba91524e4 2082 txParamSetupReq.UplinkDwellTime = 0;
Shaun Nelson 38:182ba91524e4 2083 txParamSetupReq.DownlinkDwellTime = 0;
Shaun Nelson 38:182ba91524e4 2084
Shaun Nelson 38:182ba91524e4 2085 if( ( eirpDwellTime & 0x20 ) == 0x20 )
Shaun Nelson 38:182ba91524e4 2086 {
Shaun Nelson 38:182ba91524e4 2087 txParamSetupReq.DownlinkDwellTime = 1;
Shaun Nelson 38:182ba91524e4 2088 }
Shaun Nelson 38:182ba91524e4 2089 if( ( eirpDwellTime & 0x10 ) == 0x10 )
Shaun Nelson 38:182ba91524e4 2090 {
Shaun Nelson 38:182ba91524e4 2091 txParamSetupReq.UplinkDwellTime = 1;
Shaun Nelson 38:182ba91524e4 2092 }
Shaun Nelson 38:182ba91524e4 2093 txParamSetupReq.MaxEirp = eirpDwellTime & 0x0F;
Shaun Nelson 38:182ba91524e4 2094
Shaun Nelson 38:182ba91524e4 2095 // Check the status for correctness
Shaun Nelson 38:182ba91524e4 2096 if( RegionTxParamSetupReq( LoRaMacRegion, &txParamSetupReq ) != -1 )
Shaun Nelson 38:182ba91524e4 2097 {
Shaun Nelson 38:182ba91524e4 2098 // Accept command
Shaun Nelson 38:182ba91524e4 2099 LoRaMacParams.UplinkDwellTime = txParamSetupReq.UplinkDwellTime;
Shaun Nelson 38:182ba91524e4 2100 LoRaMacParams.DownlinkDwellTime = txParamSetupReq.DownlinkDwellTime;
Shaun Nelson 38:182ba91524e4 2101 LoRaMacParams.MaxEirp = LoRaMacMaxEirpTable[txParamSetupReq.MaxEirp];
Shaun Nelson 38:182ba91524e4 2102 // Add command response
Shaun Nelson 38:182ba91524e4 2103 AddMacCommand( MOTE_MAC_TX_PARAM_SETUP_ANS, 0, 0 );
Shaun Nelson 38:182ba91524e4 2104 }
Shaun Nelson 38:182ba91524e4 2105 }
Shaun Nelson 38:182ba91524e4 2106 break;
Shaun Nelson 38:182ba91524e4 2107 case SRV_MAC_DL_CHANNEL_REQ:
Shaun Nelson 38:182ba91524e4 2108 {
Shaun Nelson 38:182ba91524e4 2109 DlChannelReqParams_t dlChannelReq;
Shaun Nelson 38:182ba91524e4 2110 status = 0x03;
Shaun Nelson 38:182ba91524e4 2111
Shaun Nelson 38:182ba91524e4 2112 dlChannelReq.ChannelId = payload[macIndex++];
Shaun Nelson 38:182ba91524e4 2113 dlChannelReq.Rx1Frequency = ( uint32_t )payload[macIndex++];
Shaun Nelson 38:182ba91524e4 2114 dlChannelReq.Rx1Frequency |= ( uint32_t )payload[macIndex++] << 8;
Shaun Nelson 38:182ba91524e4 2115 dlChannelReq.Rx1Frequency |= ( uint32_t )payload[macIndex++] << 16;
Shaun Nelson 38:182ba91524e4 2116 dlChannelReq.Rx1Frequency *= 100;
Shaun Nelson 38:182ba91524e4 2117
Shaun Nelson 38:182ba91524e4 2118 status = RegionDlChannelReq( LoRaMacRegion, &dlChannelReq );
Shaun Nelson 38:182ba91524e4 2119
Shaun Nelson 38:182ba91524e4 2120 AddMacCommand( MOTE_MAC_DL_CHANNEL_ANS, status, 0 );
Shaun Nelson 38:182ba91524e4 2121 }
Shaun Nelson 38:182ba91524e4 2122 break;
Shaun Nelson 38:182ba91524e4 2123 case SRV_MAC_PING_SLOT_INFO_ANS:
Shaun Nelson 38:182ba91524e4 2124 {
Shaun Nelson 38:182ba91524e4 2125 LoRaMacClassBPingSlotInfoAns( );
Shaun Nelson 38:182ba91524e4 2126 }
Shaun Nelson 38:182ba91524e4 2127 break;
Shaun Nelson 38:182ba91524e4 2128 case SRV_MAC_PING_SLOT_CHANNEL_REQ:
Shaun Nelson 38:182ba91524e4 2129 {
Shaun Nelson 38:182ba91524e4 2130 uint8_t status = 0x03;
Shaun Nelson 38:182ba91524e4 2131 uint32_t frequency = 0;
Shaun Nelson 38:182ba91524e4 2132 uint8_t datarate;
Shaun Nelson 38:182ba91524e4 2133
Shaun Nelson 38:182ba91524e4 2134 frequency = ( uint32_t )payload[macIndex++];
Shaun Nelson 38:182ba91524e4 2135 frequency |= ( uint32_t )payload[macIndex++] << 8;
Shaun Nelson 38:182ba91524e4 2136 frequency |= ( uint32_t )payload[macIndex++] << 16;
Shaun Nelson 38:182ba91524e4 2137 frequency *= 100;
Shaun Nelson 38:182ba91524e4 2138 datarate = payload[macIndex++] & 0x0F;
Shaun Nelson 38:182ba91524e4 2139
Shaun Nelson 38:182ba91524e4 2140 status = LoRaMacClassBPingSlotChannelReq( datarate, frequency );
Shaun Nelson 38:182ba91524e4 2141 AddMacCommand( MOTE_MAC_PING_SLOT_FREQ_ANS, status, 0 );
Shaun Nelson 38:182ba91524e4 2142 }
Shaun Nelson 38:182ba91524e4 2143 break;
Shaun Nelson 38:182ba91524e4 2144 case SRV_MAC_BEACON_TIMING_ANS:
Shaun Nelson 38:182ba91524e4 2145 {
Shaun Nelson 38:182ba91524e4 2146 uint16_t beaconTimingDelay = 0;
Shaun Nelson 38:182ba91524e4 2147 uint8_t beaconTimingChannel = 0;
Shaun Nelson 38:182ba91524e4 2148
Shaun Nelson 38:182ba91524e4 2149 beaconTimingDelay = ( uint16_t )payload[macIndex++];
Shaun Nelson 38:182ba91524e4 2150 beaconTimingDelay |= ( uint16_t )payload[macIndex++] << 8;
Shaun Nelson 38:182ba91524e4 2151 beaconTimingChannel = payload[macIndex++];
Shaun Nelson 38:182ba91524e4 2152
Shaun Nelson 38:182ba91524e4 2153 LoRaMacClassBBeaconTimingAns( beaconTimingDelay, beaconTimingChannel );
Shaun Nelson 38:182ba91524e4 2154 }
Shaun Nelson 38:182ba91524e4 2155 break;
Shaun Nelson 38:182ba91524e4 2156 case SRV_MAC_BEACON_FREQ_REQ:
Shaun Nelson 38:182ba91524e4 2157 {
Shaun Nelson 38:182ba91524e4 2158 uint32_t frequency = 0;
Shaun Nelson 38:182ba91524e4 2159
Shaun Nelson 38:182ba91524e4 2160 frequency = ( uint32_t )payload[macIndex++];
Shaun Nelson 38:182ba91524e4 2161 frequency |= ( uint32_t )payload[macIndex++] << 8;
Shaun Nelson 38:182ba91524e4 2162 frequency |= ( uint32_t )payload[macIndex++] << 16;
Shaun Nelson 38:182ba91524e4 2163 frequency *= 100;
Shaun Nelson 38:182ba91524e4 2164
Shaun Nelson 38:182ba91524e4 2165 if( LoRaMacClassBBeaconFreqReq( frequency ) == true )
Shaun Nelson 38:182ba91524e4 2166 {
Shaun Nelson 38:182ba91524e4 2167 AddMacCommand( MOTE_MAC_BEACON_FREQ_ANS, 1, 0 );
Shaun Nelson 38:182ba91524e4 2168 }
Shaun Nelson 38:182ba91524e4 2169 else
Shaun Nelson 38:182ba91524e4 2170 {
Shaun Nelson 38:182ba91524e4 2171 AddMacCommand( MOTE_MAC_BEACON_FREQ_ANS, 0, 0 );
Shaun Nelson 38:182ba91524e4 2172 }
Shaun Nelson 38:182ba91524e4 2173 }
Shaun Nelson 38:182ba91524e4 2174 break;
mluis 0:91d1a7783bb9 2175 default:
mluis 0:91d1a7783bb9 2176 // Unknown command. ABORT MAC commands processing
mluis 0:91d1a7783bb9 2177 return;
mluis 0:91d1a7783bb9 2178 }
mluis 0:91d1a7783bb9 2179 }
mluis 0:91d1a7783bb9 2180 }
mluis 0:91d1a7783bb9 2181
mluis 2:14a5d6ad92d5 2182 LoRaMacStatus_t Send( LoRaMacHeader_t *macHdr, uint8_t fPort, void *fBuffer, uint16_t fBufferSize )
mluis 0:91d1a7783bb9 2183 {
mluis 2:14a5d6ad92d5 2184 LoRaMacFrameCtrl_t fCtrl;
mluis 2:14a5d6ad92d5 2185 LoRaMacStatus_t status = LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 2186
mluis 2:14a5d6ad92d5 2187 fCtrl.Value = 0;
mluis 2:14a5d6ad92d5 2188 fCtrl.Bits.FOptsLen = 0;
Shaun Nelson 38:182ba91524e4 2189 if( LoRaMacDeviceClass == CLASS_B )
Shaun Nelson 38:182ba91524e4 2190 {
Shaun Nelson 38:182ba91524e4 2191 fCtrl.Bits.FPending = 1;
Shaun Nelson 38:182ba91524e4 2192 }
Shaun Nelson 38:182ba91524e4 2193 else
Shaun Nelson 38:182ba91524e4 2194 {
Shaun Nelson 38:182ba91524e4 2195 fCtrl.Bits.FPending = 0;
Shaun Nelson 38:182ba91524e4 2196 }
mluis 2:14a5d6ad92d5 2197 fCtrl.Bits.Ack = false;
mluis 2:14a5d6ad92d5 2198 fCtrl.Bits.AdrAckReq = false;
mluis 2:14a5d6ad92d5 2199 fCtrl.Bits.Adr = AdrCtrlOn;
mluis 2:14a5d6ad92d5 2200
mluis 2:14a5d6ad92d5 2201 // Prepare the frame
mluis 2:14a5d6ad92d5 2202 status = PrepareFrame( macHdr, &fCtrl, fPort, fBuffer, fBufferSize );
mluis 2:14a5d6ad92d5 2203
mluis 2:14a5d6ad92d5 2204 // Validate status
mluis 2:14a5d6ad92d5 2205 if( status != LORAMAC_STATUS_OK )
mluis 0:91d1a7783bb9 2206 {
mluis 2:14a5d6ad92d5 2207 return status;
mluis 0:91d1a7783bb9 2208 }
mluis 2:14a5d6ad92d5 2209
mluis 2:14a5d6ad92d5 2210 // Reset confirm parameters
mluis 2:14a5d6ad92d5 2211 McpsConfirm.NbRetries = 0;
mluis 2:14a5d6ad92d5 2212 McpsConfirm.AckReceived = false;
mluis 2:14a5d6ad92d5 2213 McpsConfirm.UpLinkCounter = UpLinkCounter;
mluis 2:14a5d6ad92d5 2214
mluis 2:14a5d6ad92d5 2215 status = ScheduleTx( );
mluis 2:14a5d6ad92d5 2216
mluis 2:14a5d6ad92d5 2217 return status;
mluis 0:91d1a7783bb9 2218 }
mluis 0:91d1a7783bb9 2219
mluis 32:26002607de9c 2220 static LoRaMacStatus_t ScheduleTx( void )
mluis 0:91d1a7783bb9 2221 {
mluis 2:14a5d6ad92d5 2222 TimerTime_t dutyCycleTimeOff = 0;
Shaun Nelson 38:182ba91524e4 2223 TimerTime_t mutexTimeLock = 0;
Shaun Nelson 38:182ba91524e4 2224 TimerTime_t timeOff = 0;
Shaun Nelson 38:182ba91524e4 2225 NextChanParams_t nextChan;
mluis 2:14a5d6ad92d5 2226
mluis 2:14a5d6ad92d5 2227 // Check if the device is off
mluis 2:14a5d6ad92d5 2228 if( MaxDCycle == 255 )
mluis 2:14a5d6ad92d5 2229 {
mluis 2:14a5d6ad92d5 2230 return LORAMAC_STATUS_DEVICE_OFF;
mluis 2:14a5d6ad92d5 2231 }
mluis 2:14a5d6ad92d5 2232 if( MaxDCycle == 0 )
mluis 0:91d1a7783bb9 2233 {
mluis 2:14a5d6ad92d5 2234 AggregatedTimeOff = 0;
mluis 2:14a5d6ad92d5 2235 }
mluis 2:14a5d6ad92d5 2236
Shaun Nelson 38:182ba91524e4 2237 // Update Backoff
Shaun Nelson 38:182ba91524e4 2238 CalculateBackOff( LastTxChannel );
Shaun Nelson 38:182ba91524e4 2239
Shaun Nelson 38:182ba91524e4 2240 nextChan.AggrTimeOff = AggregatedTimeOff;
Shaun Nelson 38:182ba91524e4 2241 nextChan.Datarate = LoRaMacParams.ChannelsDatarate;
Shaun Nelson 38:182ba91524e4 2242 nextChan.DutyCycleEnabled = DutyCycleOn;
Shaun Nelson 38:182ba91524e4 2243 nextChan.Joined = IsLoRaMacNetworkJoined;
Shaun Nelson 38:182ba91524e4 2244 nextChan.LastAggrTx = AggregatedLastTxDoneTime;
Shaun Nelson 38:182ba91524e4 2245
mluis 2:14a5d6ad92d5 2246 // Select channel
Shaun Nelson 38:182ba91524e4 2247 while( RegionNextChannel( LoRaMacRegion, &nextChan, &Channel, &dutyCycleTimeOff, &AggregatedTimeOff ) == false )
mluis 3:b9d87593a8ae 2248 {
mluis 3:b9d87593a8ae 2249 // Set the default datarate
mluis 7:c16969e0f70f 2250 LoRaMacParams.ChannelsDatarate = LoRaMacParamsDefaults.ChannelsDatarate;
Shaun Nelson 38:182ba91524e4 2251 // Update datarate in the function parameters
Shaun Nelson 38:182ba91524e4 2252 nextChan.Datarate = LoRaMacParams.ChannelsDatarate;
mluis 3:b9d87593a8ae 2253 }
mluis 2:14a5d6ad92d5 2254
mluis 32:26002607de9c 2255 // Compute Rx1 windows parameters
Shaun Nelson 38:182ba91524e4 2256 RegionComputeRxWindowParameters( LoRaMacRegion,
Shaun Nelson 38:182ba91524e4 2257 RegionApplyDrOffset( LoRaMacRegion, LoRaMacParams.DownlinkDwellTime, LoRaMacParams.ChannelsDatarate, LoRaMacParams.Rx1DrOffset ),
Shaun Nelson 38:182ba91524e4 2258 LoRaMacParams.MinRxSymbols,
Shaun Nelson 38:182ba91524e4 2259 LoRaMacParams.SystemMaxRxError,
Shaun Nelson 38:182ba91524e4 2260 &RxWindow1Config );
mluis 32:26002607de9c 2261 // Compute Rx2 windows parameters
Shaun Nelson 38:182ba91524e4 2262 RegionComputeRxWindowParameters( LoRaMacRegion,
Shaun Nelson 38:182ba91524e4 2263 LoRaMacParams.Rx2Channel.Datarate,
Shaun Nelson 38:182ba91524e4 2264 LoRaMacParams.MinRxSymbols,
Shaun Nelson 38:182ba91524e4 2265 LoRaMacParams.SystemMaxRxError,
Shaun Nelson 38:182ba91524e4 2266 &RxWindow2Config );
mluis 32:26002607de9c 2267
mluis 32:26002607de9c 2268 if( IsLoRaMacNetworkJoined == false )
mluis 32:26002607de9c 2269 {
Shaun Nelson 38:182ba91524e4 2270 RxWindow1Delay = LoRaMacParams.JoinAcceptDelay1 + RxWindow1Config.WindowOffset;
Shaun Nelson 38:182ba91524e4 2271 RxWindow2Delay = LoRaMacParams.JoinAcceptDelay2 + RxWindow2Config.WindowOffset;
mluis 32:26002607de9c 2272 }
mluis 32:26002607de9c 2273 else
mluis 32:26002607de9c 2274 {
terence304 34:1ac668ce2b15 2275 if( ValidatePayloadLength( LoRaMacTxPayloadLen, LoRaMacParams.ChannelsDatarate, MacCommandsBufferIndex ) == false )
terence304 34:1ac668ce2b15 2276 {
terence304 34:1ac668ce2b15 2277 return LORAMAC_STATUS_LENGTH_ERROR;
terence304 34:1ac668ce2b15 2278 }
Shaun Nelson 38:182ba91524e4 2279 RxWindow1Delay = LoRaMacParams.ReceiveDelay1 + RxWindow1Config.WindowOffset;
Shaun Nelson 38:182ba91524e4 2280 RxWindow2Delay = LoRaMacParams.ReceiveDelay2 + RxWindow2Config.WindowOffset;
mluis 32:26002607de9c 2281 }
mluis 32:26002607de9c 2282
mluis 2:14a5d6ad92d5 2283 // Schedule transmission of frame
mluis 2:14a5d6ad92d5 2284 if( dutyCycleTimeOff == 0 )
mluis 2:14a5d6ad92d5 2285 {
mluis 2:14a5d6ad92d5 2286 // Try to send now
Shaun Nelson 38:182ba91524e4 2287 mutexTimeLock = SendFrameOnChannel( Channel );
mluis 0:91d1a7783bb9 2288 }
Shaun Nelson 38:182ba91524e4 2289
Shaun Nelson 38:182ba91524e4 2290 timeOff = MAX( dutyCycleTimeOff, mutexTimeLock );
Shaun Nelson 38:182ba91524e4 2291
Shaun Nelson 38:182ba91524e4 2292 if( timeOff > 0 )
mluis 0:91d1a7783bb9 2293 {
mluis 2:14a5d6ad92d5 2294 // Send later - prepare timer
mluis 32:26002607de9c 2295 LoRaMacState |= LORAMAC_TX_DELAYED;
Shaun Nelson 38:182ba91524e4 2296 TimerSetValue( &TxDelayedTimer, timeOff );
mluis 2:14a5d6ad92d5 2297 TimerStart( &TxDelayedTimer );
mluis 0:91d1a7783bb9 2298 }
Shaun Nelson 38:182ba91524e4 2299 return LORAMAC_STATUS_OK;
mluis 7:c16969e0f70f 2300 }
mluis 7:c16969e0f70f 2301
mluis 4:37c12dbc8dc7 2302 static void CalculateBackOff( uint8_t channel )
mluis 4:37c12dbc8dc7 2303 {
Shaun Nelson 38:182ba91524e4 2304 CalcBackOffParams_t calcBackOff;
Shaun Nelson 38:182ba91524e4 2305
Shaun Nelson 38:182ba91524e4 2306 calcBackOff.Joined = IsLoRaMacNetworkJoined;
Shaun Nelson 38:182ba91524e4 2307 calcBackOff.DutyCycleEnabled = DutyCycleOn;
Shaun Nelson 38:182ba91524e4 2308 calcBackOff.Channel = channel;
Shaun Nelson 38:182ba91524e4 2309 calcBackOff.ElapsedTime = TimerGetElapsedTime( LoRaMacInitializationTime );
Shaun Nelson 38:182ba91524e4 2310 calcBackOff.TxTimeOnAir = TxTimeOnAir;
Shaun Nelson 38:182ba91524e4 2311 calcBackOff.LastTxIsJoinRequest = LastTxIsJoinRequest;
Shaun Nelson 38:182ba91524e4 2312
Shaun Nelson 38:182ba91524e4 2313 // Update regional back-off
Shaun Nelson 38:182ba91524e4 2314 RegionCalcBackOff( LoRaMacRegion, &calcBackOff );
Shaun Nelson 38:182ba91524e4 2315
Shaun Nelson 38:182ba91524e4 2316 // Update aggregated time-off
mluis 4:37c12dbc8dc7 2317 AggregatedTimeOff = AggregatedTimeOff + ( TxTimeOnAir * AggregatedDCycle - TxTimeOnAir );
mluis 4:37c12dbc8dc7 2318 }
mluis 4:37c12dbc8dc7 2319
Shaun Nelson 38:182ba91524e4 2320 static uint8_t GetMlmeConfirmIndex( MlmeConfirmQueue_t* queue, Mlme_t req )
mluis 7:c16969e0f70f 2321 {
Shaun Nelson 38:182ba91524e4 2322 for( uint8_t i = 0; i < MlmeConfirmQueueCnt; i++ )
mluis 7:c16969e0f70f 2323 {
Shaun Nelson 38:182ba91524e4 2324 if( queue->MlmeRequest == req )
Shaun Nelson 38:182ba91524e4 2325 {
Shaun Nelson 38:182ba91524e4 2326 return i;
Shaun Nelson 38:182ba91524e4 2327 }
Shaun Nelson 38:182ba91524e4 2328 queue++;
mluis 7:c16969e0f70f 2329 }
Shaun Nelson 38:182ba91524e4 2330
Shaun Nelson 38:182ba91524e4 2331 // Out of band
Shaun Nelson 38:182ba91524e4 2332 return LORA_MAC_MLME_CONFIRM_QUEUE_LEN;
Shaun Nelson 38:182ba91524e4 2333 }
Shaun Nelson 38:182ba91524e4 2334
Shaun Nelson 38:182ba91524e4 2335 static void SetEveryMlmeConfirmStatus( MlmeConfirmQueue_t* queue, LoRaMacEventInfoStatus_t status )
Shaun Nelson 38:182ba91524e4 2336 {
Shaun Nelson 38:182ba91524e4 2337 for( uint8_t i = 0; i < MlmeConfirmQueueCnt; i++ )
mluis 7:c16969e0f70f 2338 {
Shaun Nelson 38:182ba91524e4 2339 queue[i].Status = status;
mluis 7:c16969e0f70f 2340 }
mluis 7:c16969e0f70f 2341 }
mluis 7:c16969e0f70f 2342
mluis 7:c16969e0f70f 2343 static void ResetMacParameters( void )
mluis 7:c16969e0f70f 2344 {
mluis 7:c16969e0f70f 2345 IsLoRaMacNetworkJoined = false;
mluis 7:c16969e0f70f 2346
mluis 7:c16969e0f70f 2347 // Counters
mluis 32:26002607de9c 2348 UpLinkCounter = 0;
mluis 7:c16969e0f70f 2349 DownLinkCounter = 0;
mluis 7:c16969e0f70f 2350 AdrAckCounter = 0;
mluis 7:c16969e0f70f 2351
mluis 7:c16969e0f70f 2352 ChannelsNbRepCounter = 0;
mluis 7:c16969e0f70f 2353
mluis 7:c16969e0f70f 2354 AckTimeoutRetries = 1;
mluis 7:c16969e0f70f 2355 AckTimeoutRetriesCounter = 1;
mluis 7:c16969e0f70f 2356 AckTimeoutRetry = false;
mluis 7:c16969e0f70f 2357
mluis 7:c16969e0f70f 2358 MaxDCycle = 0;
mluis 7:c16969e0f70f 2359 AggregatedDCycle = 1;
mluis 7:c16969e0f70f 2360
mluis 7:c16969e0f70f 2361 MacCommandsBufferIndex = 0;
mluis 7:c16969e0f70f 2362 MacCommandsBufferToRepeatIndex = 0;
mluis 7:c16969e0f70f 2363
mluis 7:c16969e0f70f 2364 IsRxWindowsEnabled = true;
mluis 7:c16969e0f70f 2365
mluis 7:c16969e0f70f 2366 LoRaMacParams.ChannelsTxPower = LoRaMacParamsDefaults.ChannelsTxPower;
mluis 7:c16969e0f70f 2367 LoRaMacParams.ChannelsDatarate = LoRaMacParamsDefaults.ChannelsDatarate;
mluis 7:c16969e0f70f 2368 LoRaMacParams.Rx1DrOffset = LoRaMacParamsDefaults.Rx1DrOffset;
mluis 7:c16969e0f70f 2369 LoRaMacParams.Rx2Channel = LoRaMacParamsDefaults.Rx2Channel;
Shaun Nelson 38:182ba91524e4 2370 LoRaMacParams.UplinkDwellTime = LoRaMacParamsDefaults.UplinkDwellTime;
Shaun Nelson 38:182ba91524e4 2371 LoRaMacParams.DownlinkDwellTime = LoRaMacParamsDefaults.DownlinkDwellTime;
Shaun Nelson 38:182ba91524e4 2372 LoRaMacParams.MaxEirp = LoRaMacParamsDefaults.MaxEirp;
Shaun Nelson 38:182ba91524e4 2373 LoRaMacParams.AntennaGain = LoRaMacParamsDefaults.AntennaGain;
mluis 7:c16969e0f70f 2374
mluis 7:c16969e0f70f 2375 NodeAckRequested = false;
mluis 7:c16969e0f70f 2376 SrvAckRequested = false;
mluis 7:c16969e0f70f 2377 MacCommandsInNextTx = false;
mluis 7:c16969e0f70f 2378
mluis 7:c16969e0f70f 2379 // Reset Multicast downlink counters
mluis 7:c16969e0f70f 2380 MulticastParams_t *cur = MulticastChannels;
mluis 7:c16969e0f70f 2381 while( cur != NULL )
mluis 7:c16969e0f70f 2382 {
mluis 7:c16969e0f70f 2383 cur->DownLinkCounter = 0;
mluis 7:c16969e0f70f 2384 cur = cur->Next;
mluis 7:c16969e0f70f 2385 }
mluis 7:c16969e0f70f 2386
mluis 7:c16969e0f70f 2387 // Initialize channel index.
Shaun Nelson 38:182ba91524e4 2388 Channel = 0;
Shaun Nelson 38:182ba91524e4 2389 LastTxChannel = Channel;
mluis 7:c16969e0f70f 2390 }
mluis 7:c16969e0f70f 2391
mluis 2:14a5d6ad92d5 2392 LoRaMacStatus_t PrepareFrame( LoRaMacHeader_t *macHdr, LoRaMacFrameCtrl_t *fCtrl, uint8_t fPort, void *fBuffer, uint16_t fBufferSize )
mluis 2:14a5d6ad92d5 2393 {
Shaun Nelson 38:182ba91524e4 2394 AdrNextParams_t adrNext;
mluis 2:14a5d6ad92d5 2395 uint16_t i;
mluis 2:14a5d6ad92d5 2396 uint8_t pktHeaderLen = 0;
mluis 2:14a5d6ad92d5 2397 uint32_t mic = 0;
mluis 2:14a5d6ad92d5 2398 const void* payload = fBuffer;
mluis 2:14a5d6ad92d5 2399 uint8_t framePort = fPort;
mluis 2:14a5d6ad92d5 2400
mluis 2:14a5d6ad92d5 2401 LoRaMacBufferPktLen = 0;
mluis 2:14a5d6ad92d5 2402
mluis 2:14a5d6ad92d5 2403 NodeAckRequested = false;
mluis 2:14a5d6ad92d5 2404
mluis 2:14a5d6ad92d5 2405 if( fBuffer == NULL )
mluis 0:91d1a7783bb9 2406 {
mluis 2:14a5d6ad92d5 2407 fBufferSize = 0;
mluis 2:14a5d6ad92d5 2408 }
mluis 2:14a5d6ad92d5 2409
mluis 32:26002607de9c 2410 LoRaMacTxPayloadLen = fBufferSize;
mluis 32:26002607de9c 2411
mluis 2:14a5d6ad92d5 2412 LoRaMacBuffer[pktHeaderLen++] = macHdr->Value;
mluis 2:14a5d6ad92d5 2413
mluis 2:14a5d6ad92d5 2414 switch( macHdr->Bits.MType )
mluis 2:14a5d6ad92d5 2415 {
mluis 2:14a5d6ad92d5 2416 case FRAME_TYPE_JOIN_REQ:
mluis 2:14a5d6ad92d5 2417 LoRaMacBufferPktLen = pktHeaderLen;
mluis 2:14a5d6ad92d5 2418
mluis 2:14a5d6ad92d5 2419 memcpyr( LoRaMacBuffer + LoRaMacBufferPktLen, LoRaMacAppEui, 8 );
mluis 2:14a5d6ad92d5 2420 LoRaMacBufferPktLen += 8;
mluis 2:14a5d6ad92d5 2421 memcpyr( LoRaMacBuffer + LoRaMacBufferPktLen, LoRaMacDevEui, 8 );
mluis 2:14a5d6ad92d5 2422 LoRaMacBufferPktLen += 8;
mluis 2:14a5d6ad92d5 2423
mluis 2:14a5d6ad92d5 2424 LoRaMacDevNonce = Radio.Random( );
mluis 2:14a5d6ad92d5 2425
mluis 2:14a5d6ad92d5 2426 LoRaMacBuffer[LoRaMacBufferPktLen++] = LoRaMacDevNonce & 0xFF;
mluis 2:14a5d6ad92d5 2427 LoRaMacBuffer[LoRaMacBufferPktLen++] = ( LoRaMacDevNonce >> 8 ) & 0xFF;
mluis 2:14a5d6ad92d5 2428
mluis 2:14a5d6ad92d5 2429 LoRaMacJoinComputeMic( LoRaMacBuffer, LoRaMacBufferPktLen & 0xFF, LoRaMacAppKey, &mic );
mluis 2:14a5d6ad92d5 2430
mluis 2:14a5d6ad92d5 2431 LoRaMacBuffer[LoRaMacBufferPktLen++] = mic & 0xFF;
mluis 2:14a5d6ad92d5 2432 LoRaMacBuffer[LoRaMacBufferPktLen++] = ( mic >> 8 ) & 0xFF;
mluis 2:14a5d6ad92d5 2433 LoRaMacBuffer[LoRaMacBufferPktLen++] = ( mic >> 16 ) & 0xFF;
mluis 2:14a5d6ad92d5 2434 LoRaMacBuffer[LoRaMacBufferPktLen++] = ( mic >> 24 ) & 0xFF;
mluis 2:14a5d6ad92d5 2435
mluis 2:14a5d6ad92d5 2436 break;
mluis 2:14a5d6ad92d5 2437 case FRAME_TYPE_DATA_CONFIRMED_UP:
mluis 2:14a5d6ad92d5 2438 NodeAckRequested = true;
mluis 32:26002607de9c 2439 //Intentional fallthrough
mluis 2:14a5d6ad92d5 2440 case FRAME_TYPE_DATA_UNCONFIRMED_UP:
mluis 2:14a5d6ad92d5 2441 if( IsLoRaMacNetworkJoined == false )
mluis 0:91d1a7783bb9 2442 {
mluis 2:14a5d6ad92d5 2443 return LORAMAC_STATUS_NO_NETWORK_JOINED; // No network has been joined yet
mluis 2:14a5d6ad92d5 2444 }
mluis 2:14a5d6ad92d5 2445
Shaun Nelson 38:182ba91524e4 2446 // Adr next request
Shaun Nelson 38:182ba91524e4 2447 adrNext.UpdateChanMask = true;
Shaun Nelson 38:182ba91524e4 2448 adrNext.AdrEnabled = fCtrl->Bits.Adr;
Shaun Nelson 38:182ba91524e4 2449 adrNext.AdrAckCounter = AdrAckCounter;
Shaun Nelson 38:182ba91524e4 2450 adrNext.Datarate = LoRaMacParams.ChannelsDatarate;
Shaun Nelson 38:182ba91524e4 2451 adrNext.TxPower = LoRaMacParams.ChannelsTxPower;
Shaun Nelson 38:182ba91524e4 2452 adrNext.UplinkDwellTime = LoRaMacParams.UplinkDwellTime;
Shaun Nelson 38:182ba91524e4 2453
Shaun Nelson 38:182ba91524e4 2454 fCtrl->Bits.AdrAckReq = RegionAdrNext( LoRaMacRegion, &adrNext,
Shaun Nelson 38:182ba91524e4 2455 &LoRaMacParams.ChannelsDatarate, &LoRaMacParams.ChannelsTxPower, &AdrAckCounter );
Shaun Nelson 38:182ba91524e4 2456
mluis 2:14a5d6ad92d5 2457 if( SrvAckRequested == true )
mluis 2:14a5d6ad92d5 2458 {
mluis 2:14a5d6ad92d5 2459 SrvAckRequested = false;
mluis 2:14a5d6ad92d5 2460 fCtrl->Bits.Ack = 1;
mluis 2:14a5d6ad92d5 2461 }
mluis 2:14a5d6ad92d5 2462
mluis 2:14a5d6ad92d5 2463 LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr ) & 0xFF;
mluis 2:14a5d6ad92d5 2464 LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr >> 8 ) & 0xFF;
mluis 2:14a5d6ad92d5 2465 LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr >> 16 ) & 0xFF;
mluis 2:14a5d6ad92d5 2466 LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr >> 24 ) & 0xFF;
mluis 2:14a5d6ad92d5 2467
mluis 2:14a5d6ad92d5 2468 LoRaMacBuffer[pktHeaderLen++] = fCtrl->Value;
mluis 2:14a5d6ad92d5 2469
mluis 2:14a5d6ad92d5 2470 LoRaMacBuffer[pktHeaderLen++] = UpLinkCounter & 0xFF;
mluis 2:14a5d6ad92d5 2471 LoRaMacBuffer[pktHeaderLen++] = ( UpLinkCounter >> 8 ) & 0xFF;
mluis 2:14a5d6ad92d5 2472
mluis 7:c16969e0f70f 2473 // Copy the MAC commands which must be re-send into the MAC command buffer
mluis 7:c16969e0f70f 2474 memcpy1( &MacCommandsBuffer[MacCommandsBufferIndex], MacCommandsBufferToRepeat, MacCommandsBufferToRepeatIndex );
mluis 7:c16969e0f70f 2475 MacCommandsBufferIndex += MacCommandsBufferToRepeatIndex;
mluis 7:c16969e0f70f 2476
mluis 32:26002607de9c 2477 if( ( payload != NULL ) && ( LoRaMacTxPayloadLen > 0 ) )
mluis 2:14a5d6ad92d5 2478 {
Shaun Nelson 38:182ba91524e4 2479 if( MacCommandsInNextTx == true )
mluis 1:91e4e6c60d1e 2480 {
Shaun Nelson 38:182ba91524e4 2481 if( MacCommandsBufferIndex <= LORA_MAC_COMMAND_MAX_FOPTS_LENGTH )
mluis 0:91d1a7783bb9 2482 {
Shaun Nelson 38:182ba91524e4 2483 fCtrl->Bits.FOptsLen += MacCommandsBufferIndex;
Shaun Nelson 38:182ba91524e4 2484
Shaun Nelson 38:182ba91524e4 2485 // Update FCtrl field with new value of OptionsLength
Shaun Nelson 38:182ba91524e4 2486 LoRaMacBuffer[0x05] = fCtrl->Value;
Shaun Nelson 38:182ba91524e4 2487 for( i = 0; i < MacCommandsBufferIndex; i++ )
Shaun Nelson 38:182ba91524e4 2488 {
Shaun Nelson 38:182ba91524e4 2489 LoRaMacBuffer[pktHeaderLen++] = MacCommandsBuffer[i];
Shaun Nelson 38:182ba91524e4 2490 }
Shaun Nelson 38:182ba91524e4 2491 }
Shaun Nelson 38:182ba91524e4 2492 else
Shaun Nelson 38:182ba91524e4 2493 {
Shaun Nelson 38:182ba91524e4 2494 LoRaMacTxPayloadLen = MacCommandsBufferIndex;
Shaun Nelson 38:182ba91524e4 2495 payload = MacCommandsBuffer;
Shaun Nelson 38:182ba91524e4 2496 framePort = 0;
mluis 0:91d1a7783bb9 2497 }
mluis 0:91d1a7783bb9 2498 }
mluis 0:91d1a7783bb9 2499 }
mluis 0:91d1a7783bb9 2500 else
mluis 0:91d1a7783bb9 2501 {
Shaun Nelson 38:182ba91524e4 2502 if( ( MacCommandsBufferIndex > 0 ) && ( MacCommandsInNextTx == true ) )
mluis 0:91d1a7783bb9 2503 {
mluis 32:26002607de9c 2504 LoRaMacTxPayloadLen = MacCommandsBufferIndex;
mluis 2:14a5d6ad92d5 2505 payload = MacCommandsBuffer;
mluis 2:14a5d6ad92d5 2506 framePort = 0;
mluis 0:91d1a7783bb9 2507 }
mluis 2:14a5d6ad92d5 2508 }
mluis 2:14a5d6ad92d5 2509 MacCommandsInNextTx = false;
mluis 7:c16969e0f70f 2510 // Store MAC commands which must be re-send in case the device does not receive a downlink anymore
mluis 7:c16969e0f70f 2511 MacCommandsBufferToRepeatIndex = ParseMacCommandsToRepeat( MacCommandsBuffer, MacCommandsBufferIndex, MacCommandsBufferToRepeat );
mluis 7:c16969e0f70f 2512 if( MacCommandsBufferToRepeatIndex > 0 )
mluis 7:c16969e0f70f 2513 {
mluis 7:c16969e0f70f 2514 MacCommandsInNextTx = true;
mluis 7:c16969e0f70f 2515 }
mluis 32:26002607de9c 2516
mluis 32:26002607de9c 2517 if( ( payload != NULL ) && ( LoRaMacTxPayloadLen > 0 ) )
mluis 2:14a5d6ad92d5 2518 {
mluis 2:14a5d6ad92d5 2519 LoRaMacBuffer[pktHeaderLen++] = framePort;
mluis 2:14a5d6ad92d5 2520
mluis 2:14a5d6ad92d5 2521 if( framePort == 0 )
mluis 0:91d1a7783bb9 2522 {
Shaun Nelson 38:182ba91524e4 2523 // Reset buffer index as the mac commands are being sent on port 0
Shaun Nelson 38:182ba91524e4 2524 MacCommandsBufferIndex = 0;
mluis 32:26002607de9c 2525 LoRaMacPayloadEncrypt( (uint8_t* ) payload, LoRaMacTxPayloadLen, LoRaMacNwkSKey, LoRaMacDevAddr, UP_LINK, UpLinkCounter, &LoRaMacBuffer[pktHeaderLen] );
mluis 0:91d1a7783bb9 2526 }
mluis 0:91d1a7783bb9 2527 else
mluis 0:91d1a7783bb9 2528 {
mluis 32:26002607de9c 2529 LoRaMacPayloadEncrypt( (uint8_t* ) payload, LoRaMacTxPayloadLen, LoRaMacAppSKey, LoRaMacDevAddr, UP_LINK, UpLinkCounter, &LoRaMacBuffer[pktHeaderLen] );
mluis 0:91d1a7783bb9 2530 }
mluis 2:14a5d6ad92d5 2531 }
mluis 32:26002607de9c 2532 LoRaMacBufferPktLen = pktHeaderLen + LoRaMacTxPayloadLen;
mluis 2:14a5d6ad92d5 2533
mluis 2:14a5d6ad92d5 2534 LoRaMacComputeMic( LoRaMacBuffer, LoRaMacBufferPktLen, LoRaMacNwkSKey, LoRaMacDevAddr, UP_LINK, UpLinkCounter, &mic );
mluis 2:14a5d6ad92d5 2535
mluis 2:14a5d6ad92d5 2536 LoRaMacBuffer[LoRaMacBufferPktLen + 0] = mic & 0xFF;
mluis 2:14a5d6ad92d5 2537 LoRaMacBuffer[LoRaMacBufferPktLen + 1] = ( mic >> 8 ) & 0xFF;
mluis 2:14a5d6ad92d5 2538 LoRaMacBuffer[LoRaMacBufferPktLen + 2] = ( mic >> 16 ) & 0xFF;
mluis 2:14a5d6ad92d5 2539 LoRaMacBuffer[LoRaMacBufferPktLen + 3] = ( mic >> 24 ) & 0xFF;
mluis 2:14a5d6ad92d5 2540
mluis 2:14a5d6ad92d5 2541 LoRaMacBufferPktLen += LORAMAC_MFR_LEN;
mluis 2:14a5d6ad92d5 2542
mluis 2:14a5d6ad92d5 2543 break;
mluis 2:14a5d6ad92d5 2544 case FRAME_TYPE_PROPRIETARY:
mluis 32:26002607de9c 2545 if( ( fBuffer != NULL ) && ( LoRaMacTxPayloadLen > 0 ) )
mluis 2:14a5d6ad92d5 2546 {
mluis 32:26002607de9c 2547 memcpy1( LoRaMacBuffer + pktHeaderLen, ( uint8_t* ) fBuffer, LoRaMacTxPayloadLen );
mluis 32:26002607de9c 2548 LoRaMacBufferPktLen = pktHeaderLen + LoRaMacTxPayloadLen;
mluis 0:91d1a7783bb9 2549 }
mluis 0:91d1a7783bb9 2550 break;
mluis 0:91d1a7783bb9 2551 default:
mluis 2:14a5d6ad92d5 2552 return LORAMAC_STATUS_SERVICE_UNKNOWN;
mluis 0:91d1a7783bb9 2553 }
mluis 2:14a5d6ad92d5 2554
mluis 2:14a5d6ad92d5 2555 return LORAMAC_STATUS_OK;
mluis 0:91d1a7783bb9 2556 }
mluis 0:91d1a7783bb9 2557
Shaun Nelson 38:182ba91524e4 2558 TimerTime_t SendFrameOnChannel( uint8_t channel )
mluis 0:91d1a7783bb9 2559 {
Shaun Nelson 38:182ba91524e4 2560 TxConfigParams_t txConfig;
mluis 2:14a5d6ad92d5 2561 int8_t txPower = 0;
mluis 2:14a5d6ad92d5 2562
Shaun Nelson 38:182ba91524e4 2563 txConfig.Channel = channel;
Shaun Nelson 38:182ba91524e4 2564 txConfig.Datarate = LoRaMacParams.ChannelsDatarate;
Shaun Nelson 38:182ba91524e4 2565 txConfig.TxPower = LoRaMacParams.ChannelsTxPower;
Shaun Nelson 38:182ba91524e4 2566 txConfig.MaxEirp = LoRaMacParams.MaxEirp;
Shaun Nelson 38:182ba91524e4 2567 txConfig.AntennaGain = LoRaMacParams.AntennaGain;
Shaun Nelson 38:182ba91524e4 2568 txConfig.PktLen = LoRaMacBufferPktLen;
Shaun Nelson 38:182ba91524e4 2569
Shaun Nelson 38:182ba91524e4 2570 if( LoRaMacDeviceClass == CLASS_B )
Shaun Nelson 38:182ba91524e4 2571 {
Shaun Nelson 38:182ba91524e4 2572 if( LoRaMacClassBIsBeaconExpected( ) == true )
Shaun Nelson 38:182ba91524e4 2573 {
Shaun Nelson 38:182ba91524e4 2574 return LoRaMacClassBGetBeaconReservedTime( );
Shaun Nelson 38:182ba91524e4 2575 }
Shaun Nelson 38:182ba91524e4 2576 if( LoRaMacClassBIsPingExpected( ) == true )
Shaun Nelson 38:182ba91524e4 2577 {
Shaun Nelson 38:182ba91524e4 2578 return LoRaMacClassBGetPingSlotWinTime( );
Shaun Nelson 38:182ba91524e4 2579 }
Shaun Nelson 38:182ba91524e4 2580 }
Shaun Nelson 38:182ba91524e4 2581 RegionTxConfig( LoRaMacRegion, &txConfig, &txPower, &TxTimeOnAir );
Shaun Nelson 38:182ba91524e4 2582
Shaun Nelson 38:182ba91524e4 2583 SetEveryMlmeConfirmStatus( MlmeConfirmQueue, LORAMAC_EVENT_INFO_STATUS_ERROR );
mluis 2:14a5d6ad92d5 2584 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR;
mluis 7:c16969e0f70f 2585 McpsConfirm.Datarate = LoRaMacParams.ChannelsDatarate;
Shaun Nelson 38:182ba91524e4 2586 McpsConfirm.TxPower = txPower;
mluis 2:14a5d6ad92d5 2587
mluis 2:14a5d6ad92d5 2588 // Store the time on air
mluis 2:14a5d6ad92d5 2589 McpsConfirm.TxTimeOnAir = TxTimeOnAir;
mluis 2:14a5d6ad92d5 2590 MlmeConfirm.TxTimeOnAir = TxTimeOnAir;
mluis 2:14a5d6ad92d5 2591
Shaun Nelson 38:182ba91524e4 2592 if( ( LoRaMacDeviceClass == CLASS_B ) || ( LoRaMacClassBIsBeaconModeActive( ) == true ) )
Shaun Nelson 38:182ba91524e4 2593 {
Shaun Nelson 38:182ba91524e4 2594 TimerTime_t collisionTime = LoRaMacClassBIsUplinkCollision( TxTimeOnAir );
Shaun Nelson 38:182ba91524e4 2595
Shaun Nelson 38:182ba91524e4 2596 if( collisionTime > 0 )
Shaun Nelson 38:182ba91524e4 2597 {
Shaun Nelson 38:182ba91524e4 2598 return collisionTime;
Shaun Nelson 38:182ba91524e4 2599 }
Shaun Nelson 38:182ba91524e4 2600 }
Shaun Nelson 38:182ba91524e4 2601
Shaun Nelson 38:182ba91524e4 2602 if( LoRaMacDeviceClass == CLASS_B )
Shaun Nelson 38:182ba91524e4 2603 {
Shaun Nelson 38:182ba91524e4 2604 LoRaMacClassBHaltBeaconing( );
Shaun Nelson 38:182ba91524e4 2605 }
Shaun Nelson 38:182ba91524e4 2606
mluis 2:14a5d6ad92d5 2607 // Starts the MAC layer status check timer
mluis 3:b9d87593a8ae 2608 TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT );
mluis 2:14a5d6ad92d5 2609 TimerStart( &MacStateCheckTimer );
mluis 2:14a5d6ad92d5 2610
mluis 32:26002607de9c 2611 if( IsLoRaMacNetworkJoined == false )
mluis 32:26002607de9c 2612 {
mluis 32:26002607de9c 2613 JoinRequestTrials++;
mluis 32:26002607de9c 2614 }
mluis 32:26002607de9c 2615
Shaun Nelson 38:182ba91524e4 2616 LoRaMacState |= LORAMAC_TX_RUNNING;
Shaun Nelson 38:182ba91524e4 2617
mluis 2:14a5d6ad92d5 2618 // Send now
mluis 2:14a5d6ad92d5 2619 Radio.Send( LoRaMacBuffer, LoRaMacBufferPktLen );
mluis 2:14a5d6ad92d5 2620
mluis 32:26002607de9c 2621 LoRaMacState |= LORAMAC_TX_RUNNING;
mluis 32:26002607de9c 2622
Shaun Nelson 38:182ba91524e4 2623 return 0;
mluis 32:26002607de9c 2624 }
mluis 32:26002607de9c 2625
mluis 32:26002607de9c 2626 LoRaMacStatus_t SetTxContinuousWave( uint16_t timeout )
mluis 32:26002607de9c 2627 {
Shaun Nelson 38:182ba91524e4 2628 ContinuousWaveParams_t continuousWave;
Shaun Nelson 38:182ba91524e4 2629
Shaun Nelson 38:182ba91524e4 2630 continuousWave.Channel = Channel;
Shaun Nelson 38:182ba91524e4 2631 continuousWave.Datarate = LoRaMacParams.ChannelsDatarate;
Shaun Nelson 38:182ba91524e4 2632 continuousWave.TxPower = LoRaMacParams.ChannelsTxPower;
Shaun Nelson 38:182ba91524e4 2633 continuousWave.MaxEirp = LoRaMacParams.MaxEirp;
Shaun Nelson 38:182ba91524e4 2634 continuousWave.AntennaGain = LoRaMacParams.AntennaGain;
Shaun Nelson 38:182ba91524e4 2635 continuousWave.Timeout = timeout;
Shaun Nelson 38:182ba91524e4 2636
Shaun Nelson 38:182ba91524e4 2637 RegionSetContinuousWave( LoRaMacRegion, &continuousWave );
mluis 32:26002607de9c 2638
mluis 32:26002607de9c 2639 // Starts the MAC layer status check timer
mluis 32:26002607de9c 2640 TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT );
mluis 32:26002607de9c 2641 TimerStart( &MacStateCheckTimer );
mluis 32:26002607de9c 2642
mluis 32:26002607de9c 2643 LoRaMacState |= LORAMAC_TX_RUNNING;
mluis 32:26002607de9c 2644
mluis 32:26002607de9c 2645 return LORAMAC_STATUS_OK;
mluis 32:26002607de9c 2646 }
mluis 32:26002607de9c 2647
mluis 32:26002607de9c 2648 LoRaMacStatus_t SetTxContinuousWave1( uint16_t timeout, uint32_t frequency, uint8_t power )
mluis 32:26002607de9c 2649 {
mluis 32:26002607de9c 2650 Radio.SetTxContinuousWave( frequency, power, timeout );
mluis 32:26002607de9c 2651
mluis 32:26002607de9c 2652 // Starts the MAC layer status check timer
mluis 32:26002607de9c 2653 TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT );
mluis 32:26002607de9c 2654 TimerStart( &MacStateCheckTimer );
mluis 32:26002607de9c 2655
mluis 32:26002607de9c 2656 LoRaMacState |= LORAMAC_TX_RUNNING;
mluis 2:14a5d6ad92d5 2657
mluis 2:14a5d6ad92d5 2658 return LORAMAC_STATUS_OK;
mluis 2:14a5d6ad92d5 2659 }
mluis 2:14a5d6ad92d5 2660
Shaun Nelson 38:182ba91524e4 2661 LoRaMacStatus_t LoRaMacInitialization( LoRaMacPrimitives_t *primitives, LoRaMacCallback_t *callbacks, LoRaMacRegion_t region )
mluis 2:14a5d6ad92d5 2662 {
Shaun Nelson 38:182ba91524e4 2663 GetPhyParams_t getPhy;
Shaun Nelson 38:182ba91524e4 2664 PhyParam_t phyParam;
Shaun Nelson 38:182ba91524e4 2665 LoRaMacClassBCallback_t classBCallbacks;
Shaun Nelson 38:182ba91524e4 2666 LoRaMacClassBParams_t classBParams;
Shaun Nelson 38:182ba91524e4 2667
mluis 2:14a5d6ad92d5 2668 if( primitives == NULL )
mluis 2:14a5d6ad92d5 2669 {
mluis 2:14a5d6ad92d5 2670 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 2671 }
mluis 2:14a5d6ad92d5 2672
mluis 2:14a5d6ad92d5 2673 if( ( primitives->MacMcpsConfirm == NULL ) ||
mluis 2:14a5d6ad92d5 2674 ( primitives->MacMcpsIndication == NULL ) ||
Shaun Nelson 38:182ba91524e4 2675 ( primitives->MacMlmeConfirm == NULL ) ||
Shaun Nelson 38:182ba91524e4 2676 ( primitives->MacMlmeIndication == NULL ) )
mluis 2:14a5d6ad92d5 2677 {
mluis 2:14a5d6ad92d5 2678 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 2679 }
Shaun Nelson 38:182ba91524e4 2680 // Verify if the region is supported
Shaun Nelson 38:182ba91524e4 2681 if( RegionIsActive( region ) == false )
Shaun Nelson 38:182ba91524e4 2682 {
Shaun Nelson 38:182ba91524e4 2683 return LORAMAC_STATUS_REGION_NOT_SUPPORTED;
Shaun Nelson 38:182ba91524e4 2684 }
mluis 2:14a5d6ad92d5 2685
mluis 2:14a5d6ad92d5 2686 LoRaMacPrimitives = primitives;
mluis 2:14a5d6ad92d5 2687 LoRaMacCallbacks = callbacks;
Shaun Nelson 38:182ba91524e4 2688 LoRaMacRegion = region;
mluis 2:14a5d6ad92d5 2689
mluis 2:14a5d6ad92d5 2690 LoRaMacFlags.Value = 0;
mluis 2:14a5d6ad92d5 2691
mluis 2:14a5d6ad92d5 2692 LoRaMacDeviceClass = CLASS_A;
mluis 32:26002607de9c 2693 LoRaMacState = LORAMAC_IDLE;
mluis 7:c16969e0f70f 2694
mluis 7:c16969e0f70f 2695 JoinRequestTrials = 0;
mluis 32:26002607de9c 2696 MaxJoinRequestTrials = 1;
mluis 7:c16969e0f70f 2697
mluis 7:c16969e0f70f 2698 // Reset duty cycle times
mluis 7:c16969e0f70f 2699 AggregatedLastTxDoneTime = 0;
mluis 7:c16969e0f70f 2700 AggregatedTimeOff = 0;
mluis 7:c16969e0f70f 2701
mluis 7:c16969e0f70f 2702 // Reset to defaults
Shaun Nelson 38:182ba91524e4 2703 getPhy.Attribute = PHY_DUTY_CYCLE;
Shaun Nelson 38:182ba91524e4 2704 phyParam = RegionGetPhyParam( LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 2705 DutyCycleOn = ( bool ) phyParam.Value;
Shaun Nelson 38:182ba91524e4 2706
Shaun Nelson 38:182ba91524e4 2707 getPhy.Attribute = PHY_DEF_TX_POWER;
Shaun Nelson 38:182ba91524e4 2708 phyParam = RegionGetPhyParam( LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 2709 LoRaMacParamsDefaults.ChannelsTxPower = phyParam.Value;
Shaun Nelson 38:182ba91524e4 2710
Shaun Nelson 38:182ba91524e4 2711 getPhy.Attribute = PHY_DEF_TX_DR;
Shaun Nelson 38:182ba91524e4 2712 phyParam = RegionGetPhyParam( LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 2713 LoRaMacParamsDefaults.ChannelsDatarate = phyParam.Value;
Shaun Nelson 38:182ba91524e4 2714
Shaun Nelson 38:182ba91524e4 2715 getPhy.Attribute = PHY_MAX_RX_WINDOW;
Shaun Nelson 38:182ba91524e4 2716 phyParam = RegionGetPhyParam( LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 2717 LoRaMacParamsDefaults.MaxRxWindow = phyParam.Value;
Shaun Nelson 38:182ba91524e4 2718
Shaun Nelson 38:182ba91524e4 2719 getPhy.Attribute = PHY_RECEIVE_DELAY1;
Shaun Nelson 38:182ba91524e4 2720 phyParam = RegionGetPhyParam( LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 2721 LoRaMacParamsDefaults.ReceiveDelay1 = phyParam.Value;
Shaun Nelson 38:182ba91524e4 2722
Shaun Nelson 38:182ba91524e4 2723 getPhy.Attribute = PHY_RECEIVE_DELAY2;
Shaun Nelson 38:182ba91524e4 2724 phyParam = RegionGetPhyParam( LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 2725 LoRaMacParamsDefaults.ReceiveDelay2 = phyParam.Value;
Shaun Nelson 38:182ba91524e4 2726
Shaun Nelson 38:182ba91524e4 2727 getPhy.Attribute = PHY_JOIN_ACCEPT_DELAY1;
Shaun Nelson 38:182ba91524e4 2728 phyParam = RegionGetPhyParam( LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 2729 LoRaMacParamsDefaults.JoinAcceptDelay1 = phyParam.Value;
Shaun Nelson 38:182ba91524e4 2730
Shaun Nelson 38:182ba91524e4 2731 getPhy.Attribute = PHY_JOIN_ACCEPT_DELAY2;
Shaun Nelson 38:182ba91524e4 2732 phyParam = RegionGetPhyParam( LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 2733 LoRaMacParamsDefaults.JoinAcceptDelay2 = phyParam.Value;
Shaun Nelson 38:182ba91524e4 2734
Shaun Nelson 38:182ba91524e4 2735 getPhy.Attribute = PHY_DEF_DR1_OFFSET;
Shaun Nelson 38:182ba91524e4 2736 phyParam = RegionGetPhyParam( LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 2737 LoRaMacParamsDefaults.Rx1DrOffset = phyParam.Value;
Shaun Nelson 38:182ba91524e4 2738
Shaun Nelson 38:182ba91524e4 2739 getPhy.Attribute = PHY_DEF_RX2_FREQUENCY;
Shaun Nelson 38:182ba91524e4 2740 phyParam = RegionGetPhyParam( LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 2741 LoRaMacParamsDefaults.Rx2Channel.Frequency = phyParam.Value;
Shaun Nelson 38:182ba91524e4 2742
Shaun Nelson 38:182ba91524e4 2743 getPhy.Attribute = PHY_DEF_RX2_DR;
Shaun Nelson 38:182ba91524e4 2744 phyParam = RegionGetPhyParam( LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 2745 LoRaMacParamsDefaults.Rx2Channel.Datarate = phyParam.Value;
Shaun Nelson 38:182ba91524e4 2746
Shaun Nelson 38:182ba91524e4 2747 getPhy.Attribute = PHY_DEF_UPLINK_DWELL_TIME;
Shaun Nelson 38:182ba91524e4 2748 phyParam = RegionGetPhyParam( LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 2749 LoRaMacParamsDefaults.UplinkDwellTime = phyParam.Value;
Shaun Nelson 38:182ba91524e4 2750
Shaun Nelson 38:182ba91524e4 2751 getPhy.Attribute = PHY_DEF_DOWNLINK_DWELL_TIME;
Shaun Nelson 38:182ba91524e4 2752 phyParam = RegionGetPhyParam( LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 2753 LoRaMacParamsDefaults.DownlinkDwellTime = phyParam.Value;
Shaun Nelson 38:182ba91524e4 2754
Shaun Nelson 38:182ba91524e4 2755 getPhy.Attribute = PHY_DEF_MAX_EIRP;
Shaun Nelson 38:182ba91524e4 2756 phyParam = RegionGetPhyParam( LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 2757 LoRaMacParamsDefaults.MaxEirp = phyParam.fValue;
Shaun Nelson 38:182ba91524e4 2758
Shaun Nelson 38:182ba91524e4 2759 getPhy.Attribute = PHY_DEF_ANTENNA_GAIN;
Shaun Nelson 38:182ba91524e4 2760 phyParam = RegionGetPhyParam( LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 2761 LoRaMacParamsDefaults.AntennaGain = phyParam.fValue;
Shaun Nelson 38:182ba91524e4 2762
Shaun Nelson 38:182ba91524e4 2763 RegionInitDefaults( LoRaMacRegion, INIT_TYPE_INIT );
Shaun Nelson 38:182ba91524e4 2764
Shaun Nelson 38:182ba91524e4 2765 // Init parameters which are not set in function ResetMacParameters
Shaun Nelson 38:182ba91524e4 2766 LoRaMacParams.RepeaterSupport = false;
Shaun Nelson 38:182ba91524e4 2767 LoRaMacParamsDefaults.ChannelsNbRep = 1;
mluis 32:26002607de9c 2768 LoRaMacParamsDefaults.SystemMaxRxError = 10;
mluis 32:26002607de9c 2769 LoRaMacParamsDefaults.MinRxSymbols = 6;
Shaun Nelson 38:182ba91524e4 2770
mluis 32:26002607de9c 2771 LoRaMacParams.SystemMaxRxError = LoRaMacParamsDefaults.SystemMaxRxError;
mluis 32:26002607de9c 2772 LoRaMacParams.MinRxSymbols = LoRaMacParamsDefaults.MinRxSymbols;
mluis 32:26002607de9c 2773 LoRaMacParams.MaxRxWindow = LoRaMacParamsDefaults.MaxRxWindow;
mluis 32:26002607de9c 2774 LoRaMacParams.ReceiveDelay1 = LoRaMacParamsDefaults.ReceiveDelay1;
mluis 32:26002607de9c 2775 LoRaMacParams.ReceiveDelay2 = LoRaMacParamsDefaults.ReceiveDelay2;
mluis 32:26002607de9c 2776 LoRaMacParams.JoinAcceptDelay1 = LoRaMacParamsDefaults.JoinAcceptDelay1;
mluis 32:26002607de9c 2777 LoRaMacParams.JoinAcceptDelay2 = LoRaMacParamsDefaults.JoinAcceptDelay2;
mluis 32:26002607de9c 2778 LoRaMacParams.ChannelsNbRep = LoRaMacParamsDefaults.ChannelsNbRep;
mluis 32:26002607de9c 2779
mluis 7:c16969e0f70f 2780 ResetMacParameters( );
mluis 7:c16969e0f70f 2781
mluis 7:c16969e0f70f 2782 // Initialize timers
mluis 2:14a5d6ad92d5 2783 TimerInit( &MacStateCheckTimer, OnMacStateCheckTimerEvent );
mluis 2:14a5d6ad92d5 2784 TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT );
mluis 2:14a5d6ad92d5 2785
mluis 2:14a5d6ad92d5 2786 TimerInit( &TxDelayedTimer, OnTxDelayedTimerEvent );
mluis 2:14a5d6ad92d5 2787 TimerInit( &RxWindowTimer1, OnRxWindow1TimerEvent );
mluis 2:14a5d6ad92d5 2788 TimerInit( &RxWindowTimer2, OnRxWindow2TimerEvent );
mluis 2:14a5d6ad92d5 2789 TimerInit( &AckTimeoutTimer, OnAckTimeoutTimerEvent );
mluis 2:14a5d6ad92d5 2790
mluis 32:26002607de9c 2791 // Store the current initialization time
mluis 32:26002607de9c 2792 LoRaMacInitializationTime = TimerGetCurrentTime( );
mluis 32:26002607de9c 2793
mluis 2:14a5d6ad92d5 2794 // Initialize Radio driver
mluis 2:14a5d6ad92d5 2795 RadioEvents.TxDone = OnRadioTxDone;
mluis 2:14a5d6ad92d5 2796 RadioEvents.RxDone = OnRadioRxDone;
mluis 2:14a5d6ad92d5 2797 RadioEvents.RxError = OnRadioRxError;
mluis 2:14a5d6ad92d5 2798 RadioEvents.TxTimeout = OnRadioTxTimeout;
mluis 2:14a5d6ad92d5 2799 RadioEvents.RxTimeout = OnRadioRxTimeout;
mluis 2:14a5d6ad92d5 2800 Radio.Init( &RadioEvents );
mluis 2:14a5d6ad92d5 2801
mluis 2:14a5d6ad92d5 2802 // Random seed initialization
mluis 2:14a5d6ad92d5 2803 srand1( Radio.Random( ) );
mluis 2:14a5d6ad92d5 2804
mluis 2:14a5d6ad92d5 2805 PublicNetwork = true;
mluis 32:26002607de9c 2806 Radio.SetPublicNetwork( PublicNetwork );
mluis 2:14a5d6ad92d5 2807 Radio.Sleep( );
mluis 2:14a5d6ad92d5 2808
Shaun Nelson 38:182ba91524e4 2809 // Initialize class b
Shaun Nelson 38:182ba91524e4 2810 // Apply callback
Shaun Nelson 38:182ba91524e4 2811 classBCallbacks.GetTemperatureLevel = NULL;
Shaun Nelson 38:182ba91524e4 2812 if( callbacks != NULL )
Shaun Nelson 38:182ba91524e4 2813 {
Shaun Nelson 38:182ba91524e4 2814 classBCallbacks.GetTemperatureLevel = callbacks->GetTemperatureLevel;
Shaun Nelson 38:182ba91524e4 2815 }
Shaun Nelson 38:182ba91524e4 2816 classBCallbacks.GetMlmeConfrimIndex = GetMlmeConfirmIndex;
Shaun Nelson 38:182ba91524e4 2817
Shaun Nelson 38:182ba91524e4 2818 // Must all be static. Don't use local references.
Shaun Nelson 38:182ba91524e4 2819 classBParams.MlmeIndication = &MlmeIndication;
Shaun Nelson 38:182ba91524e4 2820 classBParams.McpsIndication = &McpsIndication;
Shaun Nelson 38:182ba91524e4 2821 classBParams.MlmeConfirm = &MlmeConfirm;
Shaun Nelson 38:182ba91524e4 2822 classBParams.LoRaMacFlags = &LoRaMacFlags;
Shaun Nelson 38:182ba91524e4 2823 classBParams.LoRaMacDevAddr = &LoRaMacDevAddr;
Shaun Nelson 38:182ba91524e4 2824 classBParams.MlmeConfirmQueue = MlmeConfirmQueue;
Shaun Nelson 38:182ba91524e4 2825 classBParams.LoRaMacRegion = &LoRaMacRegion;
Shaun Nelson 38:182ba91524e4 2826 classBParams.MacStateCheckTimer = &MacStateCheckTimer;
Shaun Nelson 38:182ba91524e4 2827 classBParams.LoRaMacParams = &LoRaMacParams;
Shaun Nelson 38:182ba91524e4 2828 classBParams.MulticastChannels = MulticastChannels;
Shaun Nelson 38:182ba91524e4 2829
Shaun Nelson 38:182ba91524e4 2830 LoRaMacClassBInit( &classBParams, &classBCallbacks );
Shaun Nelson 38:182ba91524e4 2831
mluis 2:14a5d6ad92d5 2832 return LORAMAC_STATUS_OK;
mluis 2:14a5d6ad92d5 2833 }
mluis 2:14a5d6ad92d5 2834
mluis 2:14a5d6ad92d5 2835 LoRaMacStatus_t LoRaMacQueryTxPossible( uint8_t size, LoRaMacTxInfo_t* txInfo )
mluis 2:14a5d6ad92d5 2836 {
Shaun Nelson 38:182ba91524e4 2837 AdrNextParams_t adrNext;
Shaun Nelson 38:182ba91524e4 2838 GetPhyParams_t getPhy;
Shaun Nelson 38:182ba91524e4 2839 PhyParam_t phyParam;
mluis 7:c16969e0f70f 2840 int8_t datarate = LoRaMacParamsDefaults.ChannelsDatarate;
Shaun Nelson 38:182ba91524e4 2841 int8_t txPower = LoRaMacParamsDefaults.ChannelsTxPower;
mluis 7:c16969e0f70f 2842 uint8_t fOptLen = MacCommandsBufferIndex + MacCommandsBufferToRepeatIndex;
mluis 2:14a5d6ad92d5 2843
mluis 2:14a5d6ad92d5 2844 if( txInfo == NULL )
mluis 2:14a5d6ad92d5 2845 {
mluis 2:14a5d6ad92d5 2846 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 2847 }
mluis 2:14a5d6ad92d5 2848
Shaun Nelson 38:182ba91524e4 2849 // Setup ADR request
Shaun Nelson 38:182ba91524e4 2850 adrNext.UpdateChanMask = false;
Shaun Nelson 38:182ba91524e4 2851 adrNext.AdrEnabled = AdrCtrlOn;
Shaun Nelson 38:182ba91524e4 2852 adrNext.AdrAckCounter = AdrAckCounter;
Shaun Nelson 38:182ba91524e4 2853 adrNext.Datarate = LoRaMacParams.ChannelsDatarate;
Shaun Nelson 38:182ba91524e4 2854 adrNext.TxPower = LoRaMacParams.ChannelsTxPower;
Shaun Nelson 38:182ba91524e4 2855 adrNext.UplinkDwellTime = LoRaMacParams.UplinkDwellTime;
Shaun Nelson 38:182ba91524e4 2856
Shaun Nelson 38:182ba91524e4 2857 // We call the function for information purposes only. We don't want to
Shaun Nelson 38:182ba91524e4 2858 // apply the datarate, the tx power and the ADR ack counter.
Shaun Nelson 38:182ba91524e4 2859 RegionAdrNext( LoRaMacRegion, &adrNext, &datarate, &txPower, &AdrAckCounter );
Shaun Nelson 38:182ba91524e4 2860
Shaun Nelson 38:182ba91524e4 2861 // Setup PHY request
Shaun Nelson 38:182ba91524e4 2862 getPhy.UplinkDwellTime = LoRaMacParams.UplinkDwellTime;
Shaun Nelson 38:182ba91524e4 2863 getPhy.Datarate = datarate;
Shaun Nelson 38:182ba91524e4 2864 getPhy.Attribute = PHY_MAX_PAYLOAD;
Shaun Nelson 38:182ba91524e4 2865
Shaun Nelson 38:182ba91524e4 2866 // Change request in case repeater is supported
Shaun Nelson 38:182ba91524e4 2867 if( LoRaMacParams.RepeaterSupport == true )
mluis 2:14a5d6ad92d5 2868 {
Shaun Nelson 38:182ba91524e4 2869 getPhy.Attribute = PHY_MAX_PAYLOAD_REPEATER;
mluis 0:91d1a7783bb9 2870 }
Shaun Nelson 38:182ba91524e4 2871 phyParam = RegionGetPhyParam( LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 2872 txInfo->CurrentPayloadSize = phyParam.Value;
Shaun Nelson 38:182ba91524e4 2873
Shaun Nelson 38:182ba91524e4 2874 // Verify if the fOpts fit into the maximum payload
mluis 7:c16969e0f70f 2875 if( txInfo->CurrentPayloadSize >= fOptLen )
mluis 0:91d1a7783bb9 2876 {
mluis 7:c16969e0f70f 2877 txInfo->MaxPossiblePayload = txInfo->CurrentPayloadSize - fOptLen;
mluis 0:91d1a7783bb9 2878 }
mluis 0:91d1a7783bb9 2879 else
mluis 0:91d1a7783bb9 2880 {
Shaun Nelson 38:182ba91524e4 2881 txInfo->MaxPossiblePayload = txInfo->CurrentPayloadSize;
Shaun Nelson 38:182ba91524e4 2882 // The fOpts don't fit into the maximum payload. Omit the MAC commands to
Shaun Nelson 38:182ba91524e4 2883 // ensure that another uplink is possible.
Shaun Nelson 38:182ba91524e4 2884 fOptLen = 0;
Shaun Nelson 38:182ba91524e4 2885 MacCommandsBufferIndex = 0;
Shaun Nelson 38:182ba91524e4 2886 MacCommandsBufferToRepeatIndex = 0;
mluis 2:14a5d6ad92d5 2887 }
mluis 2:14a5d6ad92d5 2888
Shaun Nelson 38:182ba91524e4 2889 // Verify if the fOpts and the payload fit into the maximum payload
Shaun Nelson 38:182ba91524e4 2890 if( ValidatePayloadLength( size, datarate, fOptLen ) == false )
mluis 2:14a5d6ad92d5 2891 {
mluis 2:14a5d6ad92d5 2892 return LORAMAC_STATUS_LENGTH_ERROR;
mluis 0:91d1a7783bb9 2893 }
mluis 2:14a5d6ad92d5 2894 return LORAMAC_STATUS_OK;
mluis 0:91d1a7783bb9 2895 }
mluis 0:91d1a7783bb9 2896
mluis 2:14a5d6ad92d5 2897 LoRaMacStatus_t LoRaMacMibGetRequestConfirm( MibRequestConfirm_t *mibGet )
mluis 0:91d1a7783bb9 2898 {
mluis 2:14a5d6ad92d5 2899 LoRaMacStatus_t status = LORAMAC_STATUS_OK;
Shaun Nelson 38:182ba91524e4 2900 GetPhyParams_t getPhy;
Shaun Nelson 38:182ba91524e4 2901 PhyParam_t phyParam;
mluis 2:14a5d6ad92d5 2902
mluis 2:14a5d6ad92d5 2903 if( mibGet == NULL )
mluis 2:14a5d6ad92d5 2904 {
mluis 2:14a5d6ad92d5 2905 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 2906 }
mluis 2:14a5d6ad92d5 2907
mluis 2:14a5d6ad92d5 2908 switch( mibGet->Type )
mluis 0:91d1a7783bb9 2909 {
mluis 2:14a5d6ad92d5 2910 case MIB_DEVICE_CLASS:
mluis 2:14a5d6ad92d5 2911 {
mluis 2:14a5d6ad92d5 2912 mibGet->Param.Class = LoRaMacDeviceClass;
mluis 2:14a5d6ad92d5 2913 break;
mluis 2:14a5d6ad92d5 2914 }
mluis 2:14a5d6ad92d5 2915 case MIB_NETWORK_JOINED:
mluis 2:14a5d6ad92d5 2916 {
mluis 2:14a5d6ad92d5 2917 mibGet->Param.IsNetworkJoined = IsLoRaMacNetworkJoined;
mluis 2:14a5d6ad92d5 2918 break;
mluis 2:14a5d6ad92d5 2919 }
mluis 2:14a5d6ad92d5 2920 case MIB_ADR:
mluis 2:14a5d6ad92d5 2921 {
mluis 2:14a5d6ad92d5 2922 mibGet->Param.AdrEnable = AdrCtrlOn;
mluis 2:14a5d6ad92d5 2923 break;
mluis 2:14a5d6ad92d5 2924 }
mluis 2:14a5d6ad92d5 2925 case MIB_NET_ID:
mluis 2:14a5d6ad92d5 2926 {
mluis 2:14a5d6ad92d5 2927 mibGet->Param.NetID = LoRaMacNetID;
mluis 2:14a5d6ad92d5 2928 break;
mluis 2:14a5d6ad92d5 2929 }
mluis 2:14a5d6ad92d5 2930 case MIB_DEV_ADDR:
mluis 2:14a5d6ad92d5 2931 {
mluis 2:14a5d6ad92d5 2932 mibGet->Param.DevAddr = LoRaMacDevAddr;
mluis 2:14a5d6ad92d5 2933 break;
mluis 2:14a5d6ad92d5 2934 }
mluis 2:14a5d6ad92d5 2935 case MIB_NWK_SKEY:
mluis 2:14a5d6ad92d5 2936 {
mluis 2:14a5d6ad92d5 2937 mibGet->Param.NwkSKey = LoRaMacNwkSKey;
mluis 2:14a5d6ad92d5 2938 break;
mluis 2:14a5d6ad92d5 2939 }
mluis 2:14a5d6ad92d5 2940 case MIB_APP_SKEY:
mluis 2:14a5d6ad92d5 2941 {
mluis 2:14a5d6ad92d5 2942 mibGet->Param.AppSKey = LoRaMacAppSKey;
mluis 2:14a5d6ad92d5 2943 break;
mluis 2:14a5d6ad92d5 2944 }
mluis 2:14a5d6ad92d5 2945 case MIB_PUBLIC_NETWORK:
mluis 2:14a5d6ad92d5 2946 {
mluis 2:14a5d6ad92d5 2947 mibGet->Param.EnablePublicNetwork = PublicNetwork;
mluis 2:14a5d6ad92d5 2948 break;
mluis 2:14a5d6ad92d5 2949 }
mluis 2:14a5d6ad92d5 2950 case MIB_REPEATER_SUPPORT:
mluis 2:14a5d6ad92d5 2951 {
Shaun Nelson 38:182ba91524e4 2952 mibGet->Param.EnableRepeaterSupport = LoRaMacParams.RepeaterSupport;
mluis 2:14a5d6ad92d5 2953 break;
mluis 2:14a5d6ad92d5 2954 }
mluis 2:14a5d6ad92d5 2955 case MIB_CHANNELS:
mluis 2:14a5d6ad92d5 2956 {
Shaun Nelson 38:182ba91524e4 2957 getPhy.Attribute = PHY_CHANNELS;
Shaun Nelson 38:182ba91524e4 2958 phyParam = RegionGetPhyParam( LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 2959
Shaun Nelson 38:182ba91524e4 2960 mibGet->Param.ChannelList = phyParam.Channels;
mluis 2:14a5d6ad92d5 2961 break;
mluis 2:14a5d6ad92d5 2962 }
mluis 2:14a5d6ad92d5 2963 case MIB_RX2_CHANNEL:
mluis 2:14a5d6ad92d5 2964 {
mluis 7:c16969e0f70f 2965 mibGet->Param.Rx2Channel = LoRaMacParams.Rx2Channel;
mluis 2:14a5d6ad92d5 2966 break;
mluis 2:14a5d6ad92d5 2967 }
mluis 32:26002607de9c 2968 case MIB_RX2_DEFAULT_CHANNEL:
mluis 32:26002607de9c 2969 {
mluis 32:26002607de9c 2970 mibGet->Param.Rx2Channel = LoRaMacParamsDefaults.Rx2Channel;
mluis 32:26002607de9c 2971 break;
mluis 32:26002607de9c 2972 }
mluis 32:26002607de9c 2973 case MIB_CHANNELS_DEFAULT_MASK:
mluis 32:26002607de9c 2974 {
Shaun Nelson 38:182ba91524e4 2975 getPhy.Attribute = PHY_CHANNELS_DEFAULT_MASK;
Shaun Nelson 38:182ba91524e4 2976 phyParam = RegionGetPhyParam( LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 2977
Shaun Nelson 38:182ba91524e4 2978 mibGet->Param.ChannelsDefaultMask = phyParam.ChannelsMask;
mluis 32:26002607de9c 2979 break;
mluis 32:26002607de9c 2980 }
mluis 2:14a5d6ad92d5 2981 case MIB_CHANNELS_MASK:
mluis 2:14a5d6ad92d5 2982 {
Shaun Nelson 38:182ba91524e4 2983 getPhy.Attribute = PHY_CHANNELS_MASK;
Shaun Nelson 38:182ba91524e4 2984 phyParam = RegionGetPhyParam( LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 2985
Shaun Nelson 38:182ba91524e4 2986 mibGet->Param.ChannelsMask = phyParam.ChannelsMask;
mluis 2:14a5d6ad92d5 2987 break;
mluis 0:91d1a7783bb9 2988 }
mluis 2:14a5d6ad92d5 2989 case MIB_CHANNELS_NB_REP:
mluis 2:14a5d6ad92d5 2990 {
mluis 7:c16969e0f70f 2991 mibGet->Param.ChannelNbRep = LoRaMacParams.ChannelsNbRep;
mluis 2:14a5d6ad92d5 2992 break;
mluis 2:14a5d6ad92d5 2993 }
mluis 2:14a5d6ad92d5 2994 case MIB_MAX_RX_WINDOW_DURATION:
mluis 2:14a5d6ad92d5 2995 {
mluis 7:c16969e0f70f 2996 mibGet->Param.MaxRxWindow = LoRaMacParams.MaxRxWindow;
mluis 2:14a5d6ad92d5 2997 break;
mluis 2:14a5d6ad92d5 2998 }
mluis 2:14a5d6ad92d5 2999 case MIB_RECEIVE_DELAY_1:
mluis 2:14a5d6ad92d5 3000 {
mluis 7:c16969e0f70f 3001 mibGet->Param.ReceiveDelay1 = LoRaMacParams.ReceiveDelay1;
mluis 2:14a5d6ad92d5 3002 break;
mluis 2:14a5d6ad92d5 3003 }
mluis 2:14a5d6ad92d5 3004 case MIB_RECEIVE_DELAY_2:
mluis 2:14a5d6ad92d5 3005 {
mluis 7:c16969e0f70f 3006 mibGet->Param.ReceiveDelay2 = LoRaMacParams.ReceiveDelay2;
mluis 2:14a5d6ad92d5 3007 break;
mluis 2:14a5d6ad92d5 3008 }
mluis 2:14a5d6ad92d5 3009 case MIB_JOIN_ACCEPT_DELAY_1:
mluis 2:14a5d6ad92d5 3010 {
mluis 7:c16969e0f70f 3011 mibGet->Param.JoinAcceptDelay1 = LoRaMacParams.JoinAcceptDelay1;
mluis 2:14a5d6ad92d5 3012 break;
mluis 2:14a5d6ad92d5 3013 }
mluis 2:14a5d6ad92d5 3014 case MIB_JOIN_ACCEPT_DELAY_2:
mluis 2:14a5d6ad92d5 3015 {
mluis 7:c16969e0f70f 3016 mibGet->Param.JoinAcceptDelay2 = LoRaMacParams.JoinAcceptDelay2;
mluis 2:14a5d6ad92d5 3017 break;
mluis 2:14a5d6ad92d5 3018 }
mluis 4:37c12dbc8dc7 3019 case MIB_CHANNELS_DEFAULT_DATARATE:
mluis 4:37c12dbc8dc7 3020 {
mluis 7:c16969e0f70f 3021 mibGet->Param.ChannelsDefaultDatarate = LoRaMacParamsDefaults.ChannelsDatarate;
mluis 4:37c12dbc8dc7 3022 break;
mluis 4:37c12dbc8dc7 3023 }
mluis 2:14a5d6ad92d5 3024 case MIB_CHANNELS_DATARATE:
mluis 2:14a5d6ad92d5 3025 {
mluis 7:c16969e0f70f 3026 mibGet->Param.ChannelsDatarate = LoRaMacParams.ChannelsDatarate;
mluis 2:14a5d6ad92d5 3027 break;
mluis 2:14a5d6ad92d5 3028 }
mluis 32:26002607de9c 3029 case MIB_CHANNELS_DEFAULT_TX_POWER:
mluis 32:26002607de9c 3030 {
mluis 32:26002607de9c 3031 mibGet->Param.ChannelsDefaultTxPower = LoRaMacParamsDefaults.ChannelsTxPower;
mluis 32:26002607de9c 3032 break;
mluis 32:26002607de9c 3033 }
mluis 2:14a5d6ad92d5 3034 case MIB_CHANNELS_TX_POWER:
mluis 2:14a5d6ad92d5 3035 {
mluis 7:c16969e0f70f 3036 mibGet->Param.ChannelsTxPower = LoRaMacParams.ChannelsTxPower;
mluis 2:14a5d6ad92d5 3037 break;
mluis 2:14a5d6ad92d5 3038 }
mluis 2:14a5d6ad92d5 3039 case MIB_UPLINK_COUNTER:
mluis 2:14a5d6ad92d5 3040 {
mluis 2:14a5d6ad92d5 3041 mibGet->Param.UpLinkCounter = UpLinkCounter;
mluis 2:14a5d6ad92d5 3042 break;
mluis 2:14a5d6ad92d5 3043 }
mluis 2:14a5d6ad92d5 3044 case MIB_DOWNLINK_COUNTER:
mluis 2:14a5d6ad92d5 3045 {
mluis 2:14a5d6ad92d5 3046 mibGet->Param.DownLinkCounter = DownLinkCounter;
mluis 2:14a5d6ad92d5 3047 break;
mluis 2:14a5d6ad92d5 3048 }
mluis 2:14a5d6ad92d5 3049 case MIB_MULTICAST_CHANNEL:
mluis 2:14a5d6ad92d5 3050 {
mluis 2:14a5d6ad92d5 3051 mibGet->Param.MulticastList = MulticastChannels;
mluis 2:14a5d6ad92d5 3052 break;
mluis 2:14a5d6ad92d5 3053 }
mluis 32:26002607de9c 3054 case MIB_SYSTEM_MAX_RX_ERROR:
mluis 32:26002607de9c 3055 {
mluis 32:26002607de9c 3056 mibGet->Param.SystemMaxRxError = LoRaMacParams.SystemMaxRxError;
mluis 32:26002607de9c 3057 break;
mluis 32:26002607de9c 3058 }
mluis 32:26002607de9c 3059 case MIB_MIN_RX_SYMBOLS:
mluis 32:26002607de9c 3060 {
mluis 32:26002607de9c 3061 mibGet->Param.MinRxSymbols = LoRaMacParams.MinRxSymbols;
mluis 32:26002607de9c 3062 break;
mluis 32:26002607de9c 3063 }
Shaun Nelson 38:182ba91524e4 3064 case MIB_ANTENNA_GAIN:
Shaun Nelson 38:182ba91524e4 3065 {
Shaun Nelson 38:182ba91524e4 3066 mibGet->Param.AntennaGain = LoRaMacParams.AntennaGain;
mluis 2:14a5d6ad92d5 3067 break;
Shaun Nelson 38:182ba91524e4 3068 }
Shaun Nelson 38:182ba91524e4 3069 default:
Shaun Nelson 38:182ba91524e4 3070 {
Shaun Nelson 38:182ba91524e4 3071 if( LoRaMacDeviceClass == CLASS_B )
Shaun Nelson 38:182ba91524e4 3072 {
Shaun Nelson 38:182ba91524e4 3073 status = LoRaMacClassBMibGetRequestConfirm( mibGet );
Shaun Nelson 38:182ba91524e4 3074 }
Shaun Nelson 38:182ba91524e4 3075 else
Shaun Nelson 38:182ba91524e4 3076 {
Shaun Nelson 38:182ba91524e4 3077 status = LORAMAC_STATUS_SERVICE_UNKNOWN;
Shaun Nelson 38:182ba91524e4 3078 }
Shaun Nelson 38:182ba91524e4 3079 break;
Shaun Nelson 38:182ba91524e4 3080 }
mluis 0:91d1a7783bb9 3081 }
mluis 2:14a5d6ad92d5 3082 return status;
mluis 0:91d1a7783bb9 3083 }
mluis 2:14a5d6ad92d5 3084
mluis 2:14a5d6ad92d5 3085 LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t *mibSet )
mluis 0:91d1a7783bb9 3086 {
mluis 2:14a5d6ad92d5 3087 LoRaMacStatus_t status = LORAMAC_STATUS_OK;
Shaun Nelson 38:182ba91524e4 3088 ChanMaskSetParams_t chanMaskSet;
Shaun Nelson 38:182ba91524e4 3089 VerifyParams_t verify;
mluis 2:14a5d6ad92d5 3090
mluis 2:14a5d6ad92d5 3091 if( mibSet == NULL )
mluis 2:14a5d6ad92d5 3092 {
mluis 2:14a5d6ad92d5 3093 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 0:91d1a7783bb9 3094 }
mluis 32:26002607de9c 3095 if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING )
mluis 0:91d1a7783bb9 3096 {
mluis 2:14a5d6ad92d5 3097 return LORAMAC_STATUS_BUSY;
mluis 0:91d1a7783bb9 3098 }
mluis 2:14a5d6ad92d5 3099
mluis 2:14a5d6ad92d5 3100 switch( mibSet->Type )
mluis 0:91d1a7783bb9 3101 {
mluis 2:14a5d6ad92d5 3102 case MIB_DEVICE_CLASS:
mluis 2:14a5d6ad92d5 3103 {
Shaun Nelson 38:182ba91524e4 3104 status = SwitchClass( mibSet->Param.Class );
mluis 2:14a5d6ad92d5 3105 break;
mluis 2:14a5d6ad92d5 3106 }
mluis 2:14a5d6ad92d5 3107 case MIB_NETWORK_JOINED:
mluis 2:14a5d6ad92d5 3108 {
mluis 2:14a5d6ad92d5 3109 IsLoRaMacNetworkJoined = mibSet->Param.IsNetworkJoined;
mluis 2:14a5d6ad92d5 3110 break;
mluis 2:14a5d6ad92d5 3111 }
mluis 2:14a5d6ad92d5 3112 case MIB_ADR:
mluis 2:14a5d6ad92d5 3113 {
mluis 2:14a5d6ad92d5 3114 AdrCtrlOn = mibSet->Param.AdrEnable;
mluis 2:14a5d6ad92d5 3115 break;
mluis 2:14a5d6ad92d5 3116 }
mluis 2:14a5d6ad92d5 3117 case MIB_NET_ID:
mluis 2:14a5d6ad92d5 3118 {
mluis 2:14a5d6ad92d5 3119 LoRaMacNetID = mibSet->Param.NetID;
mluis 2:14a5d6ad92d5 3120 break;
mluis 2:14a5d6ad92d5 3121 }
mluis 2:14a5d6ad92d5 3122 case MIB_DEV_ADDR:
mluis 2:14a5d6ad92d5 3123 {
mluis 2:14a5d6ad92d5 3124 LoRaMacDevAddr = mibSet->Param.DevAddr;
mluis 2:14a5d6ad92d5 3125 break;
mluis 2:14a5d6ad92d5 3126 }
mluis 2:14a5d6ad92d5 3127 case MIB_NWK_SKEY:
mluis 0:91d1a7783bb9 3128 {
mluis 2:14a5d6ad92d5 3129 if( mibSet->Param.NwkSKey != NULL )
mluis 2:14a5d6ad92d5 3130 {
mluis 2:14a5d6ad92d5 3131 memcpy1( LoRaMacNwkSKey, mibSet->Param.NwkSKey,
mluis 2:14a5d6ad92d5 3132 sizeof( LoRaMacNwkSKey ) );
mluis 2:14a5d6ad92d5 3133 }
mluis 2:14a5d6ad92d5 3134 else
mluis 2:14a5d6ad92d5 3135 {
mluis 2:14a5d6ad92d5 3136 status = LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 3137 }
mluis 2:14a5d6ad92d5 3138 break;
mluis 2:14a5d6ad92d5 3139 }
mluis 2:14a5d6ad92d5 3140 case MIB_APP_SKEY:
mluis 2:14a5d6ad92d5 3141 {
mluis 2:14a5d6ad92d5 3142 if( mibSet->Param.AppSKey != NULL )
mluis 2:14a5d6ad92d5 3143 {
mluis 2:14a5d6ad92d5 3144 memcpy1( LoRaMacAppSKey, mibSet->Param.AppSKey,
mluis 2:14a5d6ad92d5 3145 sizeof( LoRaMacAppSKey ) );
mluis 2:14a5d6ad92d5 3146 }
mluis 2:14a5d6ad92d5 3147 else
mluis 2:14a5d6ad92d5 3148 {
mluis 2:14a5d6ad92d5 3149 status = LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 3150 }
mluis 2:14a5d6ad92d5 3151 break;
mluis 2:14a5d6ad92d5 3152 }
mluis 2:14a5d6ad92d5 3153 case MIB_PUBLIC_NETWORK:
mluis 2:14a5d6ad92d5 3154 {
mluis 32:26002607de9c 3155 PublicNetwork = mibSet->Param.EnablePublicNetwork;
mluis 32:26002607de9c 3156 Radio.SetPublicNetwork( PublicNetwork );
mluis 2:14a5d6ad92d5 3157 break;
mluis 0:91d1a7783bb9 3158 }
mluis 2:14a5d6ad92d5 3159 case MIB_REPEATER_SUPPORT:
mluis 2:14a5d6ad92d5 3160 {
Shaun Nelson 38:182ba91524e4 3161 LoRaMacParams.RepeaterSupport = mibSet->Param.EnableRepeaterSupport;
mluis 2:14a5d6ad92d5 3162 break;
mluis 2:14a5d6ad92d5 3163 }
mluis 2:14a5d6ad92d5 3164 case MIB_RX2_CHANNEL:
mluis 2:14a5d6ad92d5 3165 {
Shaun Nelson 38:182ba91524e4 3166 verify.DatarateParams.Datarate = mibSet->Param.Rx2Channel.Datarate;
Shaun Nelson 38:182ba91524e4 3167 verify.DatarateParams.DownlinkDwellTime = LoRaMacParams.DownlinkDwellTime;
Shaun Nelson 38:182ba91524e4 3168
Shaun Nelson 38:182ba91524e4 3169 if( RegionVerify( LoRaMacRegion, &verify, PHY_RX_DR ) == true )
mluis 32:26002607de9c 3170 {
Shaun Nelson 38:182ba91524e4 3171 LoRaMacParams.Rx2Channel = mibSet->Param.Rx2Channel;
Shaun Nelson 38:182ba91524e4 3172
Shaun Nelson 38:182ba91524e4 3173 if( ( LoRaMacDeviceClass == CLASS_C ) && ( IsLoRaMacNetworkJoined == true ) )
mluis 32:26002607de9c 3174 {
Shaun Nelson 38:182ba91524e4 3175 // Compute Rx2 windows parameters
Shaun Nelson 38:182ba91524e4 3176 RegionComputeRxWindowParameters( LoRaMacRegion,
Shaun Nelson 38:182ba91524e4 3177 LoRaMacParams.Rx2Channel.Datarate,
Shaun Nelson 38:182ba91524e4 3178 LoRaMacParams.MinRxSymbols,
Shaun Nelson 38:182ba91524e4 3179 LoRaMacParams.SystemMaxRxError,
Shaun Nelson 38:182ba91524e4 3180 &RxWindow2Config );
Shaun Nelson 38:182ba91524e4 3181
Shaun Nelson 38:182ba91524e4 3182 RxWindow2Config.Channel = Channel;
Shaun Nelson 38:182ba91524e4 3183 RxWindow2Config.Frequency = LoRaMacParams.Rx2Channel.Frequency;
Shaun Nelson 38:182ba91524e4 3184 RxWindow2Config.DownlinkDwellTime = LoRaMacParams.DownlinkDwellTime;
Shaun Nelson 38:182ba91524e4 3185 RxWindow2Config.RepeaterSupport = LoRaMacParams.RepeaterSupport;
Shaun Nelson 38:182ba91524e4 3186 RxWindow2Config.Window = 1;
Shaun Nelson 38:182ba91524e4 3187 RxWindow2Config.RxContinuous = true;
Shaun Nelson 38:182ba91524e4 3188
Shaun Nelson 38:182ba91524e4 3189 if( RegionRxConfig( LoRaMacRegion, &RxWindow2Config, ( int8_t* )&McpsIndication.RxDatarate ) == true )
Shaun Nelson 38:182ba91524e4 3190 {
Shaun Nelson 38:182ba91524e4 3191 RxWindowSetup( RxWindow2Config.RxContinuous, LoRaMacParams.MaxRxWindow );
Shaun Nelson 38:182ba91524e4 3192 RxSlot = RxWindow2Config.Window;
Shaun Nelson 38:182ba91524e4 3193 }
Shaun Nelson 38:182ba91524e4 3194 else
mluis 32:26002607de9c 3195 {
mluis 32:26002607de9c 3196 status = LORAMAC_STATUS_PARAMETER_INVALID;
mluis 32:26002607de9c 3197 }
mluis 32:26002607de9c 3198 }
mluis 32:26002607de9c 3199 }
mluis 32:26002607de9c 3200 else
mluis 32:26002607de9c 3201 {
mluis 32:26002607de9c 3202 status = LORAMAC_STATUS_PARAMETER_INVALID;
mluis 32:26002607de9c 3203 }
mluis 32:26002607de9c 3204 break;
mluis 32:26002607de9c 3205 }
Shaun Nelson 38:182ba91524e4 3206 case MIB_RX2_DEFAULT_CHANNEL:
Shaun Nelson 38:182ba91524e4 3207 {
Shaun Nelson 38:182ba91524e4 3208 verify.DatarateParams.Datarate = mibSet->Param.Rx2Channel.Datarate;
Shaun Nelson 38:182ba91524e4 3209 verify.DatarateParams.DownlinkDwellTime = LoRaMacParams.DownlinkDwellTime;
Shaun Nelson 38:182ba91524e4 3210
Shaun Nelson 38:182ba91524e4 3211 if( RegionVerify( LoRaMacRegion, &verify, PHY_RX_DR ) == true )
Shaun Nelson 38:182ba91524e4 3212 {
Shaun Nelson 38:182ba91524e4 3213 LoRaMacParamsDefaults.Rx2Channel = mibSet->Param.Rx2DefaultChannel;
Shaun Nelson 38:182ba91524e4 3214 }
Shaun Nelson 38:182ba91524e4 3215 else
Shaun Nelson 38:182ba91524e4 3216 {
Shaun Nelson 38:182ba91524e4 3217 status = LORAMAC_STATUS_PARAMETER_INVALID;
Shaun Nelson 38:182ba91524e4 3218 }
Shaun Nelson 38:182ba91524e4 3219 break;
Shaun Nelson 38:182ba91524e4 3220 }
Shaun Nelson 38:182ba91524e4 3221 case MIB_CHANNELS_DEFAULT_MASK:
Shaun Nelson 38:182ba91524e4 3222 {
Shaun Nelson 38:182ba91524e4 3223 chanMaskSet.ChannelsMaskIn = mibSet->Param.ChannelsMask;
Shaun Nelson 38:182ba91524e4 3224 chanMaskSet.ChannelsMaskType = CHANNELS_DEFAULT_MASK;
Shaun Nelson 38:182ba91524e4 3225
Shaun Nelson 38:182ba91524e4 3226 if( RegionChanMaskSet( LoRaMacRegion, &chanMaskSet ) == false )
Shaun Nelson 38:182ba91524e4 3227 {
Shaun Nelson 38:182ba91524e4 3228 status = LORAMAC_STATUS_PARAMETER_INVALID;
Shaun Nelson 38:182ba91524e4 3229 }
Shaun Nelson 38:182ba91524e4 3230 break;
Shaun Nelson 38:182ba91524e4 3231 }
mluis 2:14a5d6ad92d5 3232 case MIB_CHANNELS_MASK:
mluis 2:14a5d6ad92d5 3233 {
Shaun Nelson 38:182ba91524e4 3234 chanMaskSet.ChannelsMaskIn = mibSet->Param.ChannelsMask;
Shaun Nelson 38:182ba91524e4 3235 chanMaskSet.ChannelsMaskType = CHANNELS_MASK;
Shaun Nelson 38:182ba91524e4 3236
Shaun Nelson 38:182ba91524e4 3237 if( RegionChanMaskSet( LoRaMacRegion, &chanMaskSet ) == false )
mluis 2:14a5d6ad92d5 3238 {
mluis 2:14a5d6ad92d5 3239 status = LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 3240 }
mluis 2:14a5d6ad92d5 3241 break;
mluis 2:14a5d6ad92d5 3242 }
mluis 2:14a5d6ad92d5 3243 case MIB_CHANNELS_NB_REP:
mluis 2:14a5d6ad92d5 3244 {
mluis 2:14a5d6ad92d5 3245 if( ( mibSet->Param.ChannelNbRep >= 1 ) &&
mluis 2:14a5d6ad92d5 3246 ( mibSet->Param.ChannelNbRep <= 15 ) )
mluis 2:14a5d6ad92d5 3247 {
mluis 7:c16969e0f70f 3248 LoRaMacParams.ChannelsNbRep = mibSet->Param.ChannelNbRep;
mluis 2:14a5d6ad92d5 3249 }
mluis 2:14a5d6ad92d5 3250 else
mluis 2:14a5d6ad92d5 3251 {
mluis 2:14a5d6ad92d5 3252 status = LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 3253 }
mluis 2:14a5d6ad92d5 3254 break;
mluis 2:14a5d6ad92d5 3255 }
mluis 2:14a5d6ad92d5 3256 case MIB_MAX_RX_WINDOW_DURATION:
mluis 2:14a5d6ad92d5 3257 {
mluis 7:c16969e0f70f 3258 LoRaMacParams.MaxRxWindow = mibSet->Param.MaxRxWindow;
mluis 2:14a5d6ad92d5 3259 break;
mluis 2:14a5d6ad92d5 3260 }
mluis 2:14a5d6ad92d5 3261 case MIB_RECEIVE_DELAY_1:
mluis 2:14a5d6ad92d5 3262 {
mluis 7:c16969e0f70f 3263 LoRaMacParams.ReceiveDelay1 = mibSet->Param.ReceiveDelay1;
mluis 2:14a5d6ad92d5 3264 break;
mluis 2:14a5d6ad92d5 3265 }
mluis 2:14a5d6ad92d5 3266 case MIB_RECEIVE_DELAY_2:
mluis 2:14a5d6ad92d5 3267 {
mluis 7:c16969e0f70f 3268 LoRaMacParams.ReceiveDelay2 = mibSet->Param.ReceiveDelay2;
mluis 2:14a5d6ad92d5 3269 break;
mluis 2:14a5d6ad92d5 3270 }
mluis 2:14a5d6ad92d5 3271 case MIB_JOIN_ACCEPT_DELAY_1:
mluis 2:14a5d6ad92d5 3272 {
mluis 7:c16969e0f70f 3273 LoRaMacParams.JoinAcceptDelay1 = mibSet->Param.JoinAcceptDelay1;
mluis 2:14a5d6ad92d5 3274 break;
mluis 2:14a5d6ad92d5 3275 }
mluis 2:14a5d6ad92d5 3276 case MIB_JOIN_ACCEPT_DELAY_2:
mluis 2:14a5d6ad92d5 3277 {
mluis 7:c16969e0f70f 3278 LoRaMacParams.JoinAcceptDelay2 = mibSet->Param.JoinAcceptDelay2;
mluis 2:14a5d6ad92d5 3279 break;
mluis 2:14a5d6ad92d5 3280 }
mluis 4:37c12dbc8dc7 3281 case MIB_CHANNELS_DEFAULT_DATARATE:
mluis 4:37c12dbc8dc7 3282 {
Shaun Nelson 38:182ba91524e4 3283 verify.DatarateParams.Datarate = mibSet->Param.ChannelsDefaultDatarate;
Shaun Nelson 38:182ba91524e4 3284
Shaun Nelson 38:182ba91524e4 3285 if( RegionVerify( LoRaMacRegion, &verify, PHY_DEF_TX_DR ) == true )
mluis 32:26002607de9c 3286 {
Shaun Nelson 38:182ba91524e4 3287 LoRaMacParamsDefaults.ChannelsDatarate = verify.DatarateParams.Datarate;
mluis 32:26002607de9c 3288 }
mluis 4:37c12dbc8dc7 3289 else
mluis 4:37c12dbc8dc7 3290 {
mluis 4:37c12dbc8dc7 3291 status = LORAMAC_STATUS_PARAMETER_INVALID;
mluis 4:37c12dbc8dc7 3292 }
mluis 4:37c12dbc8dc7 3293 break;
mluis 4:37c12dbc8dc7 3294 }
mluis 2:14a5d6ad92d5 3295 case MIB_CHANNELS_DATARATE:
mluis 2:14a5d6ad92d5 3296 {
Shaun Nelson 38:182ba91524e4 3297 verify.DatarateParams.Datarate = mibSet->Param.ChannelsDatarate;
Shaun Nelson 38:182ba91524e4 3298
Shaun Nelson 38:182ba91524e4 3299 if( RegionVerify( LoRaMacRegion, &verify, PHY_TX_DR ) == true )
mluis 2:14a5d6ad92d5 3300 {
Shaun Nelson 38:182ba91524e4 3301 LoRaMacParams.ChannelsDatarate = verify.DatarateParams.Datarate;
mluis 2:14a5d6ad92d5 3302 }
mluis 2:14a5d6ad92d5 3303 else
mluis 2:14a5d6ad92d5 3304 {
mluis 2:14a5d6ad92d5 3305 status = LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 3306 }
mluis 2:14a5d6ad92d5 3307 break;
mluis 2:14a5d6ad92d5 3308 }
mluis 32:26002607de9c 3309 case MIB_CHANNELS_DEFAULT_TX_POWER:
mluis 32:26002607de9c 3310 {
Shaun Nelson 38:182ba91524e4 3311 verify.TxPower = mibSet->Param.ChannelsDefaultTxPower;
Shaun Nelson 38:182ba91524e4 3312
Shaun Nelson 38:182ba91524e4 3313 if( RegionVerify( LoRaMacRegion, &verify, PHY_DEF_TX_POWER ) == true )
mluis 32:26002607de9c 3314 {
Shaun Nelson 38:182ba91524e4 3315 LoRaMacParamsDefaults.ChannelsTxPower = verify.TxPower;
mluis 32:26002607de9c 3316 }
mluis 32:26002607de9c 3317 else
mluis 32:26002607de9c 3318 {
mluis 32:26002607de9c 3319 status = LORAMAC_STATUS_PARAMETER_INVALID;
mluis 32:26002607de9c 3320 }
mluis 32:26002607de9c 3321 break;
mluis 32:26002607de9c 3322 }
mluis 2:14a5d6ad92d5 3323 case MIB_CHANNELS_TX_POWER:
mluis 2:14a5d6ad92d5 3324 {
Shaun Nelson 38:182ba91524e4 3325 verify.TxPower = mibSet->Param.ChannelsTxPower;
Shaun Nelson 38:182ba91524e4 3326
Shaun Nelson 38:182ba91524e4 3327 if( RegionVerify( LoRaMacRegion, &verify, PHY_TX_POWER ) == true )
mluis 2:14a5d6ad92d5 3328 {
Shaun Nelson 38:182ba91524e4 3329 LoRaMacParams.ChannelsTxPower = verify.TxPower;
mluis 2:14a5d6ad92d5 3330 }
mluis 2:14a5d6ad92d5 3331 else
mluis 2:14a5d6ad92d5 3332 {
mluis 2:14a5d6ad92d5 3333 status = LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 3334 }
mluis 2:14a5d6ad92d5 3335 break;
mluis 2:14a5d6ad92d5 3336 }
mluis 4:37c12dbc8dc7 3337 case MIB_UPLINK_COUNTER:
mluis 4:37c12dbc8dc7 3338 {
mluis 4:37c12dbc8dc7 3339 UpLinkCounter = mibSet->Param.UpLinkCounter;
mluis 4:37c12dbc8dc7 3340 break;
mluis 4:37c12dbc8dc7 3341 }
mluis 4:37c12dbc8dc7 3342 case MIB_DOWNLINK_COUNTER:
mluis 4:37c12dbc8dc7 3343 {
mluis 4:37c12dbc8dc7 3344 DownLinkCounter = mibSet->Param.DownLinkCounter;
mluis 4:37c12dbc8dc7 3345 break;
mluis 4:37c12dbc8dc7 3346 }
mluis 32:26002607de9c 3347 case MIB_SYSTEM_MAX_RX_ERROR:
mluis 32:26002607de9c 3348 {
mluis 32:26002607de9c 3349 LoRaMacParams.SystemMaxRxError = LoRaMacParamsDefaults.SystemMaxRxError = mibSet->Param.SystemMaxRxError;
mluis 32:26002607de9c 3350 break;
mluis 32:26002607de9c 3351 }
mluis 32:26002607de9c 3352 case MIB_MIN_RX_SYMBOLS:
mluis 32:26002607de9c 3353 {
mluis 32:26002607de9c 3354 LoRaMacParams.MinRxSymbols = LoRaMacParamsDefaults.MinRxSymbols = mibSet->Param.MinRxSymbols;
mluis 32:26002607de9c 3355 break;
mluis 32:26002607de9c 3356 }
Shaun Nelson 38:182ba91524e4 3357 case MIB_ANTENNA_GAIN:
Shaun Nelson 38:182ba91524e4 3358 {
Shaun Nelson 38:182ba91524e4 3359 LoRaMacParams.AntennaGain = mibSet->Param.AntennaGain;
Shaun Nelson 38:182ba91524e4 3360 break;
Shaun Nelson 38:182ba91524e4 3361 }
mluis 2:14a5d6ad92d5 3362 default:
Shaun Nelson 38:182ba91524e4 3363 {
Shaun Nelson 38:182ba91524e4 3364 if( LoRaMacDeviceClass == CLASS_B )
Shaun Nelson 38:182ba91524e4 3365 {
Shaun Nelson 38:182ba91524e4 3366 status = LoRaMacMibClassBSetRequestConfirm( mibSet );
Shaun Nelson 38:182ba91524e4 3367 }
Shaun Nelson 38:182ba91524e4 3368 else
Shaun Nelson 38:182ba91524e4 3369 {
Shaun Nelson 38:182ba91524e4 3370 status = LORAMAC_STATUS_SERVICE_UNKNOWN;
Shaun Nelson 38:182ba91524e4 3371 }
mluis 2:14a5d6ad92d5 3372 break;
Shaun Nelson 38:182ba91524e4 3373 }
mluis 0:91d1a7783bb9 3374 }
mluis 0:91d1a7783bb9 3375
mluis 2:14a5d6ad92d5 3376 return status;
mluis 0:91d1a7783bb9 3377 }
mluis 0:91d1a7783bb9 3378
mluis 2:14a5d6ad92d5 3379 LoRaMacStatus_t LoRaMacChannelAdd( uint8_t id, ChannelParams_t params )
mluis 0:91d1a7783bb9 3380 {
Shaun Nelson 38:182ba91524e4 3381 ChannelAddParams_t channelAdd;
Shaun Nelson 38:182ba91524e4 3382
mluis 3:b9d87593a8ae 3383 // Validate if the MAC is in a correct state
mluis 32:26002607de9c 3384 if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING )
mluis 0:91d1a7783bb9 3385 {
mluis 32:26002607de9c 3386 if( ( LoRaMacState & LORAMAC_TX_CONFIG ) != LORAMAC_TX_CONFIG )
mluis 3:b9d87593a8ae 3387 {
mluis 3:b9d87593a8ae 3388 return LORAMAC_STATUS_BUSY;
mluis 3:b9d87593a8ae 3389 }
mluis 0:91d1a7783bb9 3390 }
Shaun Nelson 38:182ba91524e4 3391
Shaun Nelson 38:182ba91524e4 3392 channelAdd.NewChannel = &params;
Shaun Nelson 38:182ba91524e4 3393 channelAdd.ChannelId = id;
Shaun Nelson 38:182ba91524e4 3394
Shaun Nelson 38:182ba91524e4 3395 return RegionChannelAdd( LoRaMacRegion, &channelAdd );
mluis 0:91d1a7783bb9 3396 }
mluis 0:91d1a7783bb9 3397
mluis 2:14a5d6ad92d5 3398 LoRaMacStatus_t LoRaMacChannelRemove( uint8_t id )
mluis 0:91d1a7783bb9 3399 {
Shaun Nelson 38:182ba91524e4 3400 ChannelRemoveParams_t channelRemove;
Shaun Nelson 38:182ba91524e4 3401
mluis 32:26002607de9c 3402 if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING )
mluis 0:91d1a7783bb9 3403 {
mluis 32:26002607de9c 3404 if( ( LoRaMacState & LORAMAC_TX_CONFIG ) != LORAMAC_TX_CONFIG )
mluis 3:b9d87593a8ae 3405 {
mluis 3:b9d87593a8ae 3406 return LORAMAC_STATUS_BUSY;
mluis 3:b9d87593a8ae 3407 }
mluis 0:91d1a7783bb9 3408 }
mluis 3:b9d87593a8ae 3409
Shaun Nelson 38:182ba91524e4 3410 channelRemove.ChannelId = id;
Shaun Nelson 38:182ba91524e4 3411
Shaun Nelson 38:182ba91524e4 3412 if( RegionChannelsRemove( LoRaMacRegion, &channelRemove ) == false )
mluis 0:91d1a7783bb9 3413 {
mluis 3:b9d87593a8ae 3414 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 3:b9d87593a8ae 3415 }
mluis 3:b9d87593a8ae 3416 return LORAMAC_STATUS_OK;
mluis 2:14a5d6ad92d5 3417 }
mluis 2:14a5d6ad92d5 3418
mluis 2:14a5d6ad92d5 3419 LoRaMacStatus_t LoRaMacMulticastChannelLink( MulticastParams_t *channelParam )
mluis 2:14a5d6ad92d5 3420 {
mluis 2:14a5d6ad92d5 3421 if( channelParam == NULL )
mluis 2:14a5d6ad92d5 3422 {
mluis 2:14a5d6ad92d5 3423 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 3424 }
mluis 32:26002607de9c 3425 if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING )
mluis 2:14a5d6ad92d5 3426 {
mluis 2:14a5d6ad92d5 3427 return LORAMAC_STATUS_BUSY;
mluis 2:14a5d6ad92d5 3428 }
mluis 2:14a5d6ad92d5 3429
mluis 2:14a5d6ad92d5 3430 // Reset downlink counter
mluis 2:14a5d6ad92d5 3431 channelParam->DownLinkCounter = 0;
Shaun Nelson 38:182ba91524e4 3432 channelParam->Next = NULL;
mluis 2:14a5d6ad92d5 3433
mluis 2:14a5d6ad92d5 3434 if( MulticastChannels == NULL )
mluis 2:14a5d6ad92d5 3435 {
mluis 2:14a5d6ad92d5 3436 // New node is the fist element
mluis 2:14a5d6ad92d5 3437 MulticastChannels = channelParam;
mluis 0:91d1a7783bb9 3438 }
mluis 0:91d1a7783bb9 3439 else
mluis 0:91d1a7783bb9 3440 {
mluis 2:14a5d6ad92d5 3441 MulticastParams_t *cur = MulticastChannels;
mluis 2:14a5d6ad92d5 3442
mluis 2:14a5d6ad92d5 3443 // Search the last node in the list
mluis 2:14a5d6ad92d5 3444 while( cur->Next != NULL )
mluis 2:14a5d6ad92d5 3445 {
mluis 2:14a5d6ad92d5 3446 cur = cur->Next;
mluis 2:14a5d6ad92d5 3447 }
mluis 2:14a5d6ad92d5 3448 // This function always finds the last node
mluis 2:14a5d6ad92d5 3449 cur->Next = channelParam;
mluis 0:91d1a7783bb9 3450 }
mluis 2:14a5d6ad92d5 3451
mluis 2:14a5d6ad92d5 3452 return LORAMAC_STATUS_OK;
mluis 0:91d1a7783bb9 3453 }
mluis 0:91d1a7783bb9 3454
mluis 2:14a5d6ad92d5 3455 LoRaMacStatus_t LoRaMacMulticastChannelUnlink( MulticastParams_t *channelParam )
mluis 0:91d1a7783bb9 3456 {
mluis 2:14a5d6ad92d5 3457 if( channelParam == NULL )
mluis 0:91d1a7783bb9 3458 {
mluis 2:14a5d6ad92d5 3459 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 0:91d1a7783bb9 3460 }
mluis 32:26002607de9c 3461 if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING )
mluis 2:14a5d6ad92d5 3462 {
mluis 2:14a5d6ad92d5 3463 return LORAMAC_STATUS_BUSY;
mluis 2:14a5d6ad92d5 3464 }
mluis 2:14a5d6ad92d5 3465
mluis 2:14a5d6ad92d5 3466 if( MulticastChannels != NULL )
mluis 0:91d1a7783bb9 3467 {
mluis 2:14a5d6ad92d5 3468 if( MulticastChannels == channelParam )
mluis 2:14a5d6ad92d5 3469 {
mluis 2:14a5d6ad92d5 3470 // First element
mluis 2:14a5d6ad92d5 3471 MulticastChannels = channelParam->Next;
mluis 2:14a5d6ad92d5 3472 }
mluis 2:14a5d6ad92d5 3473 else
mluis 2:14a5d6ad92d5 3474 {
mluis 2:14a5d6ad92d5 3475 MulticastParams_t *cur = MulticastChannels;
mluis 2:14a5d6ad92d5 3476
mluis 2:14a5d6ad92d5 3477 // Search the node in the list
mluis 2:14a5d6ad92d5 3478 while( cur->Next && cur->Next != channelParam )
mluis 2:14a5d6ad92d5 3479 {
mluis 2:14a5d6ad92d5 3480 cur = cur->Next;
mluis 2:14a5d6ad92d5 3481 }
mluis 2:14a5d6ad92d5 3482 // If we found the node, remove it
mluis 2:14a5d6ad92d5 3483 if( cur->Next )
mluis 2:14a5d6ad92d5 3484 {
mluis 2:14a5d6ad92d5 3485 cur->Next = channelParam->Next;
mluis 2:14a5d6ad92d5 3486 }
mluis 2:14a5d6ad92d5 3487 }
mluis 2:14a5d6ad92d5 3488 channelParam->Next = NULL;
mluis 0:91d1a7783bb9 3489 }
mluis 2:14a5d6ad92d5 3490
mluis 2:14a5d6ad92d5 3491 return LORAMAC_STATUS_OK;
mluis 0:91d1a7783bb9 3492 }
mluis 0:91d1a7783bb9 3493
mluis 2:14a5d6ad92d5 3494 LoRaMacStatus_t LoRaMacMlmeRequest( MlmeReq_t *mlmeRequest )
mluis 0:91d1a7783bb9 3495 {
mluis 2:14a5d6ad92d5 3496 LoRaMacStatus_t status = LORAMAC_STATUS_SERVICE_UNKNOWN;
mluis 2:14a5d6ad92d5 3497 LoRaMacHeader_t macHdr;
Shaun Nelson 38:182ba91524e4 3498 AlternateDrParams_t altDr;
Shaun Nelson 38:182ba91524e4 3499 VerifyParams_t verify;
Shaun Nelson 38:182ba91524e4 3500 GetPhyParams_t getPhy;
Shaun Nelson 38:182ba91524e4 3501 PhyParam_t phyParam;
mluis 2:14a5d6ad92d5 3502
mluis 2:14a5d6ad92d5 3503 if( mlmeRequest == NULL )
mluis 2:14a5d6ad92d5 3504 {
mluis 2:14a5d6ad92d5 3505 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 3506 }
mluis 32:26002607de9c 3507 if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING )
mluis 2:14a5d6ad92d5 3508 {
mluis 2:14a5d6ad92d5 3509 return LORAMAC_STATUS_BUSY;
mluis 2:14a5d6ad92d5 3510 }
Shaun Nelson 38:182ba91524e4 3511 if( LORA_MAC_MLME_CONFIRM_QUEUE_LEN <= MlmeConfirmQueueCnt )
Shaun Nelson 38:182ba91524e4 3512 {
Shaun Nelson 38:182ba91524e4 3513 return LORAMAC_STATUS_BUSY;
Shaun Nelson 38:182ba91524e4 3514 }
Shaun Nelson 38:182ba91524e4 3515
Shaun Nelson 38:182ba91524e4 3516 // Reset the confirm queue if it is empty
Shaun Nelson 38:182ba91524e4 3517 if( MlmeConfirmQueueCnt == 0 )
Shaun Nelson 38:182ba91524e4 3518 {
Shaun Nelson 38:182ba91524e4 3519 memset1( ( uint8_t* ) &MlmeConfirm, 0, sizeof( MlmeConfirm ) );
Shaun Nelson 38:182ba91524e4 3520 }
Shaun Nelson 38:182ba91524e4 3521
Shaun Nelson 38:182ba91524e4 3522 // Switch requests
mluis 2:14a5d6ad92d5 3523 switch( mlmeRequest->Type )
mluis 2:14a5d6ad92d5 3524 {
mluis 2:14a5d6ad92d5 3525 case MLME_JOIN:
mluis 2:14a5d6ad92d5 3526 {
mluis 32:26002607de9c 3527 if( ( LoRaMacState & LORAMAC_TX_DELAYED ) == LORAMAC_TX_DELAYED )
mluis 2:14a5d6ad92d5 3528 {
mluis 6:d7a34ded7c87 3529 return LORAMAC_STATUS_BUSY;
mluis 2:14a5d6ad92d5 3530 }
mluis 2:14a5d6ad92d5 3531
mluis 2:14a5d6ad92d5 3532 if( ( mlmeRequest->Req.Join.DevEui == NULL ) ||
mluis 2:14a5d6ad92d5 3533 ( mlmeRequest->Req.Join.AppEui == NULL ) ||
mluis 32:26002607de9c 3534 ( mlmeRequest->Req.Join.AppKey == NULL ) ||
mluis 32:26002607de9c 3535 ( mlmeRequest->Req.Join.NbTrials == 0 ) )
mluis 2:14a5d6ad92d5 3536 {
mluis 2:14a5d6ad92d5 3537 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 3538 }
mluis 2:14a5d6ad92d5 3539
Shaun Nelson 38:182ba91524e4 3540 // Apply the request
Shaun Nelson 38:182ba91524e4 3541 LoRaMacFlags.Bits.MlmeReq = 1;
Shaun Nelson 38:182ba91524e4 3542 MlmeConfirmQueue[MlmeConfirmQueueCnt].MlmeRequest = mlmeRequest->Type;
Shaun Nelson 38:182ba91524e4 3543 MlmeConfirmQueueCnt++;
Shaun Nelson 38:182ba91524e4 3544
Shaun Nelson 38:182ba91524e4 3545 // Verify the parameter NbTrials for the join procedure
Shaun Nelson 38:182ba91524e4 3546 verify.NbJoinTrials = mlmeRequest->Req.Join.NbTrials;
Shaun Nelson 38:182ba91524e4 3547
Shaun Nelson 38:182ba91524e4 3548 if( RegionVerify( LoRaMacRegion, &verify, PHY_NB_JOIN_TRIALS ) == false )
mluis 32:26002607de9c 3549 {
Shaun Nelson 38:182ba91524e4 3550 // Value not supported, get default
Shaun Nelson 38:182ba91524e4 3551 getPhy.Attribute = PHY_DEF_NB_JOIN_TRIALS;
Shaun Nelson 38:182ba91524e4 3552 phyParam = RegionGetPhyParam( LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 3553 mlmeRequest->Req.Join.NbTrials = ( uint8_t ) phyParam.Value;
mluis 32:26002607de9c 3554 }
mluis 2:14a5d6ad92d5 3555
mluis 2:14a5d6ad92d5 3556 LoRaMacDevEui = mlmeRequest->Req.Join.DevEui;
mluis 2:14a5d6ad92d5 3557 LoRaMacAppEui = mlmeRequest->Req.Join.AppEui;
mluis 2:14a5d6ad92d5 3558 LoRaMacAppKey = mlmeRequest->Req.Join.AppKey;
mluis 32:26002607de9c 3559 MaxJoinRequestTrials = mlmeRequest->Req.Join.NbTrials;
mluis 32:26002607de9c 3560
mluis 32:26002607de9c 3561 // Reset variable JoinRequestTrials
mluis 32:26002607de9c 3562 JoinRequestTrials = 0;
mluis 32:26002607de9c 3563
mluis 32:26002607de9c 3564 // Setup header information
mluis 2:14a5d6ad92d5 3565 macHdr.Value = 0;
mluis 2:14a5d6ad92d5 3566 macHdr.Bits.MType = FRAME_TYPE_JOIN_REQ;
mluis 2:14a5d6ad92d5 3567
mluis 7:c16969e0f70f 3568 ResetMacParameters( );
mluis 7:c16969e0f70f 3569
Shaun Nelson 38:182ba91524e4 3570 altDr.NbTrials = JoinRequestTrials + 1;
Shaun Nelson 38:182ba91524e4 3571
Shaun Nelson 38:182ba91524e4 3572 LoRaMacParams.ChannelsDatarate = RegionAlternateDr( LoRaMacRegion, &altDr );
mluis 2:14a5d6ad92d5 3573
mluis 2:14a5d6ad92d5 3574 status = Send( &macHdr, 0, NULL, 0 );
mluis 2:14a5d6ad92d5 3575 break;
mluis 2:14a5d6ad92d5 3576 }
mluis 2:14a5d6ad92d5 3577 case MLME_LINK_CHECK:
mluis 2:14a5d6ad92d5 3578 {
Shaun Nelson 38:182ba91524e4 3579 // Apply the request
mluis 2:14a5d6ad92d5 3580 LoRaMacFlags.Bits.MlmeReq = 1;
Shaun Nelson 38:182ba91524e4 3581 MlmeConfirmQueue[MlmeConfirmQueueCnt].MlmeRequest = mlmeRequest->Type;
Shaun Nelson 38:182ba91524e4 3582 MlmeConfirmQueueCnt++;
Shaun Nelson 38:182ba91524e4 3583
mluis 2:14a5d6ad92d5 3584 // LoRaMac will send this command piggy-pack
mluis 2:14a5d6ad92d5 3585 status = AddMacCommand( MOTE_MAC_LINK_CHECK_REQ, 0, 0 );
mluis 2:14a5d6ad92d5 3586 break;
mluis 2:14a5d6ad92d5 3587 }
mluis 32:26002607de9c 3588 case MLME_TXCW:
mluis 32:26002607de9c 3589 {
Shaun Nelson 38:182ba91524e4 3590 // Apply the request
mluis 32:26002607de9c 3591 LoRaMacFlags.Bits.MlmeReq = 1;
Shaun Nelson 38:182ba91524e4 3592 MlmeConfirmQueue[MlmeConfirmQueueCnt].MlmeRequest = mlmeRequest->Type;
Shaun Nelson 38:182ba91524e4 3593 MlmeConfirmQueueCnt++;
mluis 32:26002607de9c 3594 status = SetTxContinuousWave( mlmeRequest->Req.TxCw.Timeout );
mluis 32:26002607de9c 3595 break;
mluis 32:26002607de9c 3596 }
mluis 32:26002607de9c 3597 case MLME_TXCW_1:
mluis 32:26002607de9c 3598 {
Shaun Nelson 38:182ba91524e4 3599 // Apply the request
Shaun Nelson 38:182ba91524e4 3600 LoRaMacFlags.Bits.MlmeReq = 1;
Shaun Nelson 38:182ba91524e4 3601 MlmeConfirmQueue[MlmeConfirmQueueCnt].MlmeRequest = mlmeRequest->Type;
Shaun Nelson 38:182ba91524e4 3602 MlmeConfirmQueueCnt++;
Shaun Nelson 38:182ba91524e4 3603 status = SetTxContinuousWave1( mlmeRequest->Req.TxCw.Timeout, mlmeRequest->Req.TxCw.Frequency, mlmeRequest->Req.TxCw.Power );
Shaun Nelson 38:182ba91524e4 3604 break;
Shaun Nelson 38:182ba91524e4 3605 }
Shaun Nelson 38:182ba91524e4 3606 case MLME_PING_SLOT_INFO:
Shaun Nelson 38:182ba91524e4 3607 {
Shaun Nelson 38:182ba91524e4 3608 uint8_t value = mlmeRequest->Req.PingSlotInfo.PingSlot.Value;
Shaun Nelson 38:182ba91524e4 3609
Shaun Nelson 38:182ba91524e4 3610 // Apply the request
Shaun Nelson 38:182ba91524e4 3611 LoRaMacFlags.Bits.MlmeReq = 1;
Shaun Nelson 38:182ba91524e4 3612 MlmeConfirmQueue[MlmeConfirmQueueCnt].MlmeRequest = mlmeRequest->Type;
Shaun Nelson 38:182ba91524e4 3613 MlmeConfirmQueueCnt++;
Shaun Nelson 38:182ba91524e4 3614 // LoRaMac will send this command piggy-pack
Shaun Nelson 38:182ba91524e4 3615 LoRaMacClassBSetPingSlotInfo( mlmeRequest->Req.PingSlotInfo.PingSlot.Fields.Periodicity );
Shaun Nelson 38:182ba91524e4 3616
Shaun Nelson 38:182ba91524e4 3617 status = AddMacCommand( MOTE_MAC_PING_SLOT_INFO_REQ, value, 0 );
Shaun Nelson 38:182ba91524e4 3618 break;
Shaun Nelson 38:182ba91524e4 3619 }
Shaun Nelson 38:182ba91524e4 3620 case MLME_BEACON_TIMING:
Shaun Nelson 38:182ba91524e4 3621 {
Shaun Nelson 38:182ba91524e4 3622 // Apply the request
mluis 32:26002607de9c 3623 LoRaMacFlags.Bits.MlmeReq = 1;
Shaun Nelson 38:182ba91524e4 3624 MlmeConfirmQueue[MlmeConfirmQueueCnt].MlmeRequest = mlmeRequest->Type;
Shaun Nelson 38:182ba91524e4 3625 MlmeConfirmQueueCnt++;
Shaun Nelson 38:182ba91524e4 3626 // LoRaMac will send this command piggy-pack
Shaun Nelson 38:182ba91524e4 3627 status = AddMacCommand( MOTE_MAC_BEACON_TIMING_REQ, 0, 0 );
Shaun Nelson 38:182ba91524e4 3628 break;
Shaun Nelson 38:182ba91524e4 3629 }
Shaun Nelson 38:182ba91524e4 3630 case MLME_BEACON_ACQUISITION:
Shaun Nelson 38:182ba91524e4 3631 {
Shaun Nelson 38:182ba91524e4 3632 // Apply the request
Shaun Nelson 38:182ba91524e4 3633 LoRaMacFlags.Bits.MlmeReq = 1;
Shaun Nelson 38:182ba91524e4 3634 MlmeConfirmQueue[MlmeConfirmQueueCnt].MlmeRequest = mlmeRequest->Type;
Shaun Nelson 38:182ba91524e4 3635 MlmeConfirmQueueCnt++;
Shaun Nelson 38:182ba91524e4 3636
Shaun Nelson 38:182ba91524e4 3637 if( ( LoRaMacClassBIsAcquisitionPending( ) == false ) && ( LoRaMacClassBIsAcquisitionTimerSet( ) == false ) )
Shaun Nelson 38:182ba91524e4 3638 {
Shaun Nelson 38:182ba91524e4 3639 // Start class B algorithm
Shaun Nelson 38:182ba91524e4 3640 LoRaMacClassBSetBeaconState( BEACON_STATE_ACQUISITION );
Shaun Nelson 38:182ba91524e4 3641 LoRaMacClassBBeaconTimerEvent( );
Shaun Nelson 38:182ba91524e4 3642
Shaun Nelson 38:182ba91524e4 3643 status = LORAMAC_STATUS_OK;
Shaun Nelson 38:182ba91524e4 3644 }
Shaun Nelson 38:182ba91524e4 3645 else
Shaun Nelson 38:182ba91524e4 3646 {
Shaun Nelson 38:182ba91524e4 3647 status = LORAMAC_STATUS_BUSY;
Shaun Nelson 38:182ba91524e4 3648 }
mluis 32:26002607de9c 3649 break;
mluis 32:26002607de9c 3650 }
mluis 2:14a5d6ad92d5 3651 default:
mluis 2:14a5d6ad92d5 3652 break;
mluis 2:14a5d6ad92d5 3653 }
mluis 2:14a5d6ad92d5 3654
mluis 2:14a5d6ad92d5 3655 if( status != LORAMAC_STATUS_OK )
mluis 2:14a5d6ad92d5 3656 {
mluis 2:14a5d6ad92d5 3657 NodeAckRequested = false;
Shaun Nelson 38:182ba91524e4 3658 MlmeConfirmQueueCnt--;
Shaun Nelson 38:182ba91524e4 3659 if( MlmeConfirmQueueCnt == 0 )
Shaun Nelson 38:182ba91524e4 3660 {
Shaun Nelson 38:182ba91524e4 3661 LoRaMacFlags.Bits.MlmeReq = 0;
Shaun Nelson 38:182ba91524e4 3662 }
mluis 2:14a5d6ad92d5 3663 }
mluis 2:14a5d6ad92d5 3664
mluis 2:14a5d6ad92d5 3665 return status;
mluis 0:91d1a7783bb9 3666 }
mluis 0:91d1a7783bb9 3667
mluis 2:14a5d6ad92d5 3668 LoRaMacStatus_t LoRaMacMcpsRequest( McpsReq_t *mcpsRequest )
mluis 0:91d1a7783bb9 3669 {
Shaun Nelson 38:182ba91524e4 3670 GetPhyParams_t getPhy;
Shaun Nelson 38:182ba91524e4 3671 PhyParam_t phyParam;
mluis 2:14a5d6ad92d5 3672 LoRaMacStatus_t status = LORAMAC_STATUS_SERVICE_UNKNOWN;
mluis 2:14a5d6ad92d5 3673 LoRaMacHeader_t macHdr;
Shaun Nelson 38:182ba91524e4 3674 VerifyParams_t verify;
mluis 2:14a5d6ad92d5 3675 uint8_t fPort = 0;
mluis 2:14a5d6ad92d5 3676 void *fBuffer;
mluis 2:14a5d6ad92d5 3677 uint16_t fBufferSize;
mluis 2:14a5d6ad92d5 3678 int8_t datarate;
mluis 2:14a5d6ad92d5 3679 bool readyToSend = false;
mluis 2:14a5d6ad92d5 3680
mluis 2:14a5d6ad92d5 3681 if( mcpsRequest == NULL )
mluis 2:14a5d6ad92d5 3682 {
mluis 2:14a5d6ad92d5 3683 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 3684 }
mluis 32:26002607de9c 3685 if( ( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) ||
mluis 32:26002607de9c 3686 ( ( LoRaMacState & LORAMAC_TX_DELAYED ) == LORAMAC_TX_DELAYED ) )
mluis 2:14a5d6ad92d5 3687 {
mluis 2:14a5d6ad92d5 3688 return LORAMAC_STATUS_BUSY;
mluis 2:14a5d6ad92d5 3689 }
mluis 2:14a5d6ad92d5 3690
mluis 2:14a5d6ad92d5 3691 macHdr.Value = 0;
mluis 2:14a5d6ad92d5 3692 memset1 ( ( uint8_t* ) &McpsConfirm, 0, sizeof( McpsConfirm ) );
mluis 2:14a5d6ad92d5 3693 McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR;
mluis 2:14a5d6ad92d5 3694
Shaun Nelson 38:182ba91524e4 3695 // AckTimeoutRetriesCounter must be reset every time a new request (unconfirmed or confirmed) is performed.
Shaun Nelson 38:182ba91524e4 3696 AckTimeoutRetriesCounter = 1;
Shaun Nelson 38:182ba91524e4 3697
mluis 2:14a5d6ad92d5 3698 switch( mcpsRequest->Type )
mluis 2:14a5d6ad92d5 3699 {
mluis 2:14a5d6ad92d5 3700 case MCPS_UNCONFIRMED:
mluis 2:14a5d6ad92d5 3701 {
mluis 2:14a5d6ad92d5 3702 readyToSend = true;
mluis 2:14a5d6ad92d5 3703 AckTimeoutRetries = 1;
mluis 2:14a5d6ad92d5 3704
mluis 2:14a5d6ad92d5 3705 macHdr.Bits.MType = FRAME_TYPE_DATA_UNCONFIRMED_UP;
mluis 2:14a5d6ad92d5 3706 fPort = mcpsRequest->Req.Unconfirmed.fPort;
mluis 2:14a5d6ad92d5 3707 fBuffer = mcpsRequest->Req.Unconfirmed.fBuffer;
mluis 2:14a5d6ad92d5 3708 fBufferSize = mcpsRequest->Req.Unconfirmed.fBufferSize;
mluis 2:14a5d6ad92d5 3709 datarate = mcpsRequest->Req.Unconfirmed.Datarate;
mluis 2:14a5d6ad92d5 3710 break;
mluis 2:14a5d6ad92d5 3711 }
mluis 2:14a5d6ad92d5 3712 case MCPS_CONFIRMED:
mluis 2:14a5d6ad92d5 3713 {
mluis 2:14a5d6ad92d5 3714 readyToSend = true;
mluis 3:b9d87593a8ae 3715 AckTimeoutRetries = mcpsRequest->Req.Confirmed.NbTrials;
mluis 2:14a5d6ad92d5 3716
mluis 2:14a5d6ad92d5 3717 macHdr.Bits.MType = FRAME_TYPE_DATA_CONFIRMED_UP;
mluis 2:14a5d6ad92d5 3718 fPort = mcpsRequest->Req.Confirmed.fPort;
mluis 2:14a5d6ad92d5 3719 fBuffer = mcpsRequest->Req.Confirmed.fBuffer;
mluis 2:14a5d6ad92d5 3720 fBufferSize = mcpsRequest->Req.Confirmed.fBufferSize;
mluis 2:14a5d6ad92d5 3721 datarate = mcpsRequest->Req.Confirmed.Datarate;
mluis 2:14a5d6ad92d5 3722 break;
mluis 2:14a5d6ad92d5 3723 }
mluis 2:14a5d6ad92d5 3724 case MCPS_PROPRIETARY:
mluis 2:14a5d6ad92d5 3725 {
mluis 2:14a5d6ad92d5 3726 readyToSend = true;
mluis 2:14a5d6ad92d5 3727 AckTimeoutRetries = 1;
mluis 2:14a5d6ad92d5 3728
mluis 2:14a5d6ad92d5 3729 macHdr.Bits.MType = FRAME_TYPE_PROPRIETARY;
mluis 2:14a5d6ad92d5 3730 fBuffer = mcpsRequest->Req.Proprietary.fBuffer;
mluis 2:14a5d6ad92d5 3731 fBufferSize = mcpsRequest->Req.Proprietary.fBufferSize;
mluis 2:14a5d6ad92d5 3732 datarate = mcpsRequest->Req.Proprietary.Datarate;
mluis 2:14a5d6ad92d5 3733 break;
mluis 2:14a5d6ad92d5 3734 }
mluis 2:14a5d6ad92d5 3735 default:
mluis 2:14a5d6ad92d5 3736 break;
mluis 2:14a5d6ad92d5 3737 }
mluis 2:14a5d6ad92d5 3738
Shaun Nelson 38:182ba91524e4 3739 // Get the minimum possible datarate
Shaun Nelson 38:182ba91524e4 3740 getPhy.Attribute = PHY_MIN_TX_DR;
Shaun Nelson 38:182ba91524e4 3741 getPhy.UplinkDwellTime = LoRaMacParams.UplinkDwellTime;
Shaun Nelson 38:182ba91524e4 3742 phyParam = RegionGetPhyParam( LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 3743 // Apply the minimum possible datarate.
Shaun Nelson 38:182ba91524e4 3744 // Some regions have limitations for the minimum datarate.
Shaun Nelson 38:182ba91524e4 3745 datarate = MAX( datarate, phyParam.Value );
Shaun Nelson 38:182ba91524e4 3746
mluis 2:14a5d6ad92d5 3747 if( readyToSend == true )
mluis 2:14a5d6ad92d5 3748 {
mluis 2:14a5d6ad92d5 3749 if( AdrCtrlOn == false )
mluis 2:14a5d6ad92d5 3750 {
Shaun Nelson 38:182ba91524e4 3751 verify.DatarateParams.Datarate = datarate;
Shaun Nelson 38:182ba91524e4 3752 verify.DatarateParams.UplinkDwellTime = LoRaMacParams.UplinkDwellTime;
Shaun Nelson 38:182ba91524e4 3753
Shaun Nelson 38:182ba91524e4 3754 if( RegionVerify( LoRaMacRegion, &verify, PHY_TX_DR ) == true )
mluis 2:14a5d6ad92d5 3755 {
Shaun Nelson 38:182ba91524e4 3756 LoRaMacParams.ChannelsDatarate = verify.DatarateParams.Datarate;
mluis 2:14a5d6ad92d5 3757 }
mluis 2:14a5d6ad92d5 3758 else
mluis 2:14a5d6ad92d5 3759 {
mluis 2:14a5d6ad92d5 3760 return LORAMAC_STATUS_PARAMETER_INVALID;
mluis 2:14a5d6ad92d5 3761 }
mluis 2:14a5d6ad92d5 3762 }
mluis 2:14a5d6ad92d5 3763
mluis 2:14a5d6ad92d5 3764 status = Send( &macHdr, fPort, fBuffer, fBufferSize );
mluis 2:14a5d6ad92d5 3765 if( status == LORAMAC_STATUS_OK )
mluis 2:14a5d6ad92d5 3766 {
mluis 2:14a5d6ad92d5 3767 McpsConfirm.McpsRequest = mcpsRequest->Type;
mluis 2:14a5d6ad92d5 3768 LoRaMacFlags.Bits.McpsReq = 1;
mluis 2:14a5d6ad92d5 3769 }
mluis 2:14a5d6ad92d5 3770 else
mluis 2:14a5d6ad92d5 3771 {
mluis 2:14a5d6ad92d5 3772 NodeAckRequested = false;
mluis 2:14a5d6ad92d5 3773 }
mluis 2:14a5d6ad92d5 3774 }
mluis 2:14a5d6ad92d5 3775
mluis 2:14a5d6ad92d5 3776 return status;
mluis 0:91d1a7783bb9 3777 }
mluis 0:91d1a7783bb9 3778
mluis 0:91d1a7783bb9 3779 void LoRaMacTestRxWindowsOn( bool enable )
mluis 0:91d1a7783bb9 3780 {
mluis 0:91d1a7783bb9 3781 IsRxWindowsEnabled = enable;
mluis 0:91d1a7783bb9 3782 }
mluis 0:91d1a7783bb9 3783
mluis 2:14a5d6ad92d5 3784 void LoRaMacTestSetMic( uint16_t txPacketCounter )
mluis 0:91d1a7783bb9 3785 {
mluis 2:14a5d6ad92d5 3786 UpLinkCounter = txPacketCounter;
mluis 0:91d1a7783bb9 3787 IsUpLinkCounterFixed = true;
mluis 0:91d1a7783bb9 3788 }
mluis 2:14a5d6ad92d5 3789
mluis 2:14a5d6ad92d5 3790 void LoRaMacTestSetDutyCycleOn( bool enable )
mluis 2:14a5d6ad92d5 3791 {
Shaun Nelson 38:182ba91524e4 3792 VerifyParams_t verify;
Shaun Nelson 38:182ba91524e4 3793
Shaun Nelson 38:182ba91524e4 3794 verify.DutyCycle = enable;
Shaun Nelson 38:182ba91524e4 3795
Shaun Nelson 38:182ba91524e4 3796 if( RegionVerify( LoRaMacRegion, &verify, PHY_DUTY_CYCLE ) == true )
Shaun Nelson 38:182ba91524e4 3797 {
Shaun Nelson 38:182ba91524e4 3798 DutyCycleOn = enable;
Shaun Nelson 38:182ba91524e4 3799 }
mluis 2:14a5d6ad92d5 3800 }
mluis 32:26002607de9c 3801
mluis 32:26002607de9c 3802 void LoRaMacTestSetChannel( uint8_t channel )
mluis 32:26002607de9c 3803 {
mluis 32:26002607de9c 3804 Channel = channel;
mluis 32:26002607de9c 3805 }