Fork of Semtech LoRaWAN stack

Fork of LoRaWAN-lib by canuck lehead

Committer:
Shaun Nelson
Date:
Tue Aug 15 17:09:12 2017 -0400
Branch:
class_b
Revision:
39:ca51084123b8
Parent:
38:182ba91524e4
Child:
47:e7fd944a7215
Fix to pend beacon acquisition callback until acquisition process finishes

Who changed what in which revision?

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