20171208

Fork of LoRaWAN-lib by Semtech

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers LoRaMac.cpp Source File

LoRaMac.cpp

00001 /*
00002  / _____)             _              | |
00003 ( (____  _____ ____ _| |_ _____  ____| |__
00004  \____ \| ___ |    (_   _) ___ |/ ___)  _ \
00005  _____) ) ____| | | || |_| ____( (___| | | |
00006 (______/|_____)_|_|_| \__)_____)\____)_| |_|
00007     (C)2013 Semtech
00008  ___ _____ _   ___ _  _____ ___  ___  ___ ___
00009 / __|_   _/_\ / __| |/ / __/ _ \| _ \/ __| __|
00010 \__ \ | |/ _ \ (__| ' <| _| (_) |   / (__| _|
00011 |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
00012 embedded.connectivity.solutions===============
00013 
00014 Description: LoRa MAC layer implementation
00015 
00016 License: Revised BSD License, see LICENSE.TXT file include in the project
00017 
00018 Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jäckle ( STACKFORCE )
00019 */
00020 #include <math.h>
00021 #include "board.h"
00022 
00023 #include "LoRaMacCrypto.h"
00024 #include "LoRaMac.h"
00025 #include "LoRaMacTest.h"
00026 
00027 /*!
00028  * Maximum PHY layer payload size
00029  */
00030 #define LORAMAC_PHY_MAXPAYLOAD                      255
00031 
00032 /*!
00033  * Maximum MAC commands buffer size
00034  */
00035 #define LORA_MAC_COMMAND_MAX_LENGTH                 15
00036 
00037 /*!
00038  * FRMPayload overhead to be used when setting the Radio.SetMaxPayloadLength
00039  * in RxWindowSetup function.
00040  * Maximum PHYPayload = MaxPayloadOfDatarate/MaxPayloadOfDatarateRepeater + LORA_MAC_FRMPAYLOAD_OVERHEAD
00041  */
00042 #define LORA_MAC_FRMPAYLOAD_OVERHEAD                13 // MHDR(1) + FHDR(7) + Port(1) + MIC(4)
00043 
00044 /*!
00045  * LoRaMac duty cycle for the back-off procedure during the first hour.
00046  */
00047 #define BACKOFF_DC_1_HOUR                           100
00048 
00049 /*!
00050  * LoRaMac duty cycle for the back-off procedure during the next 10 hours.
00051  */
00052 #define BACKOFF_DC_10_HOURS                         1000
00053 
00054 /*!
00055  * LoRaMac duty cycle for the back-off procedure during the next 24 hours.
00056  */
00057 #define BACKOFF_DC_24_HOURS                         10000
00058 
00059 /*!
00060  * Device IEEE EUI
00061  */
00062 static uint8_t *LoRaMacDevEui;
00063 
00064 /*!
00065  * Application IEEE EUI
00066  */
00067 static uint8_t *LoRaMacAppEui;
00068 
00069 /*!
00070  * AES encryption/decryption cipher application key
00071  */
00072 static uint8_t *LoRaMacAppKey;
00073 
00074 /*!
00075  * AES encryption/decryption cipher network session key
00076  */
00077 static uint8_t LoRaMacNwkSKey[] =
00078 {
00079     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00080     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
00081 };
00082 
00083 /*!
00084  * AES encryption/decryption cipher application session key
00085  */
00086 static uint8_t LoRaMacAppSKey[] =
00087 {
00088     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00089     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
00090 };
00091 
00092 /*!
00093  * Device nonce is a random value extracted by issuing a sequence of RSSI
00094  * measurements
00095  */
00096 static uint16_t LoRaMacDevNonce;
00097 
00098 /*!
00099  * Network ID ( 3 bytes )
00100  */
00101 static uint32_t LoRaMacNetID;
00102 
00103 /*!
00104  * Mote Address
00105  */
00106 static uint32_t LoRaMacDevAddr;
00107 
00108 /*!
00109  * Multicast channels linked list
00110  */
00111 static MulticastParams_t  *MulticastChannels = NULL;
00112 
00113 /*!
00114  * Actual device class
00115  */
00116 static DeviceClass_t  LoRaMacDeviceClass;
00117 
00118 /*!
00119  * Indicates if the node is connected to a private or public network
00120  */
00121 static bool PublicNetwork;
00122 
00123 /*!
00124  * Indicates if the node supports repeaters
00125  */
00126 static bool RepeaterSupport;
00127 
00128 /*!
00129  * Buffer containing the data to be sent or received.
00130  */
00131 static uint8_t LoRaMacBuffer[LORAMAC_PHY_MAXPAYLOAD];
00132 
00133 /*!
00134  * Length of packet in LoRaMacBuffer
00135  */
00136 static uint16_t LoRaMacBufferPktLen = 0;
00137 
00138 /*!
00139  * Length of the payload in LoRaMacBuffer
00140  */
00141 static uint8_t LoRaMacTxPayloadLen = 0;
00142 
00143 /*!
00144  * Buffer containing the upper layer data.
00145  */
00146 static uint8_t LoRaMacRxPayload[LORAMAC_PHY_MAXPAYLOAD];
00147 
00148 /*!
00149  * LoRaMAC frame counter. Each time a packet is sent the counter is incremented.
00150  * Only the 16 LSB bits are sent
00151  */
00152 static uint32_t UpLinkCounter = 0;
00153 
00154 /*!
00155  * LoRaMAC frame counter. Each time a packet is received the counter is incremented.
00156  * Only the 16 LSB bits are received
00157  */
00158 static uint32_t DownLinkCounter = 0;
00159 
00160 /*!
00161  * IsPacketCounterFixed enables the MIC field tests by fixing the
00162  * UpLinkCounter value
00163  */
00164 static bool IsUpLinkCounterFixed = false;
00165 
00166 /*!
00167  * Used for test purposes. Disables the opening of the reception windows.
00168  */
00169 static bool IsRxWindowsEnabled = true;
00170 
00171 /*!
00172  * Indicates if the MAC layer has already joined a network.
00173  */
00174 static bool IsLoRaMacNetworkJoined = false;
00175 
00176 /*!
00177  * LoRaMac ADR control status
00178  */
00179 static bool AdrCtrlOn = false;
00180 
00181 /*!
00182  * Counts the number of missed ADR acknowledgements
00183  */
00184 static uint32_t AdrAckCounter = 0;
00185 
00186 /*!
00187  * If the node has sent a FRAME_TYPE_DATA_CONFIRMED_UP this variable indicates
00188  * if the nodes needs to manage the server acknowledgement.
00189  */
00190 static bool NodeAckRequested = false;
00191 
00192 /*!
00193  * If the server has sent a FRAME_TYPE_DATA_CONFIRMED_DOWN this variable indicates
00194  * if the ACK bit must be set for the next transmission
00195  */
00196 static bool SrvAckRequested = false;
00197 
00198 /*!
00199  * Indicates if the MAC layer wants to send MAC commands
00200  */
00201 static bool MacCommandsInNextTx = false;
00202 
00203 /*!
00204  * Contains the current MacCommandsBuffer index
00205  */
00206 static uint8_t MacCommandsBufferIndex = 0;
00207 
00208 /*!
00209  * Contains the current MacCommandsBuffer index for MAC commands to repeat
00210  */
00211 static uint8_t MacCommandsBufferToRepeatIndex = 0;
00212 
00213 /*!
00214  * Buffer containing the MAC layer commands
00215  */
00216 static uint8_t MacCommandsBuffer[LORA_MAC_COMMAND_MAX_LENGTH];
00217 
00218 /*!
00219  * Buffer containing the MAC layer commands which must be repeated
00220  */
00221 static uint8_t MacCommandsBufferToRepeat[LORA_MAC_COMMAND_MAX_LENGTH];
00222 
00223 #if defined( USE_BAND_433 )
00224 /*!
00225  * Data rates table definition
00226  */
00227 const uint8_t Datarates[]  = { 12, 11, 10,  9,  8,  7,  7, 50 };
00228 
00229 /*!
00230  * Bandwidths table definition in Hz
00231  */
00232 const uint32_t Bandwidths[] = { 125e3, 125e3, 125e3, 125e3, 125e3, 125e3, 250e3, 0 };
00233 
00234 /*!
00235  * Maximum payload with respect to the datarate index. Cannot operate with repeater.
00236  */
00237 const uint8_t MaxPayloadOfDatarate[] = { 51, 51, 51, 115, 242, 242, 242, 242 };
00238 
00239 /*!
00240  * Maximum payload with respect to the datarate index. Can operate with repeater.
00241  */
00242 const uint8_t MaxPayloadOfDatarateRepeater[] = { 51, 51, 51, 115, 222, 222, 222, 222 };
00243 
00244 /*!
00245  * Tx output powers table definition
00246  */
00247 const int8_t TxPowers[]    = { 10, 7, 4, 1, -2, -5 };
00248 
00249 /*!
00250  * LoRaMac bands
00251  */
00252 static Band_t  Bands[LORA_MAX_NB_BANDS] =
00253 {
00254     BAND0,
00255 };
00256 
00257 /*!
00258  * LoRaMAC channels
00259  */
00260 static ChannelParams_t  Channels[LORA_MAX_NB_CHANNELS] =
00261 {
00262     LC1,
00263     LC2,
00264     LC3,
00265 };
00266 #elif defined( USE_BAND_470 )
00267 
00268 /*!
00269  * Data rates table definition
00270  */
00271 const uint8_t Datarates[]  = { 12, 11, 10,  9,  8,  7 };
00272 
00273 /*!
00274  * Bandwidths table definition in Hz
00275  */
00276 const uint32_t Bandwidths[] = { 125e3, 125e3, 125e3, 125e3, 125e3, 125e3 };
00277 
00278 /*!
00279  * Maximum payload with respect to the datarate index. Cannot operate with repeater.
00280  */
00281 const uint8_t MaxPayloadOfDatarate[] = { 51, 51, 51, 115, 222, 222 };
00282 
00283 /*!
00284  * Maximum payload with respect to the datarate index. Can operate with repeater.
00285  */
00286 const uint8_t MaxPayloadOfDatarateRepeater[] = { 51, 51, 51, 115, 222, 222 };
00287 
00288 /*!
00289  * Tx output powers table definition
00290  */
00291 const int8_t TxPowers[]    = { 17, 16, 14, 12, 10, 7, 5, 2 };
00292 
00293 /*!
00294  * LoRaMac bands
00295  */
00296 static Band_t  Bands[LORA_MAX_NB_BANDS] =
00297 {
00298     BAND0,
00299 };
00300 
00301 /*!
00302  * LoRaMAC channels
00303  */
00304 static ChannelParams_t  Channels[LORA_MAX_NB_CHANNELS];
00305 
00306 /*!
00307  * Defines the first channel for RX window 1 for CN470 band
00308  */
00309 #define LORAMAC_FIRST_RX1_CHANNEL           ( (uint32_t) 500.3e6 )
00310 
00311 /*!
00312  * Defines the last channel for RX window 1 for CN470 band
00313  */
00314 #define LORAMAC_LAST_RX1_CHANNEL            ( (uint32_t) 509.7e6 )
00315 
00316 /*!
00317  * Defines the step width of the channels for RX window 1
00318  */
00319 #define LORAMAC_STEPWIDTH_RX1_CHANNEL       ( (uint32_t) 200e3 )
00320 
00321 #elif defined( USE_BAND_780 )
00322 /*!
00323  * Data rates table definition
00324  */
00325 const uint8_t Datarates[]  = { 12, 11, 10,  9,  8,  7,  7, 50 };
00326 
00327 /*!
00328  * Bandwidths table definition in Hz
00329  */
00330 const uint32_t Bandwidths[] = { 125e3, 125e3, 125e3, 125e3, 125e3, 125e3, 250e3, 0 };
00331 
00332 /*!
00333  * Maximum payload with respect to the datarate index. Cannot operate with repeater.
00334  */
00335 const uint8_t MaxPayloadOfDatarate[] = { 51, 51, 51, 115, 242, 242, 242, 242 };
00336 
00337 /*!
00338  * Maximum payload with respect to the datarate index. Can operate with repeater.
00339  */
00340 const uint8_t MaxPayloadOfDatarateRepeater[] = { 51, 51, 51, 115, 222, 222, 222, 222 };
00341 
00342 /*!
00343  * Tx output powers table definition
00344  */
00345 const int8_t TxPowers[]    = { 10, 7, 4, 1, -2, -5 };
00346 
00347 /*!
00348  * LoRaMac bands
00349  */
00350 static Band_t  Bands[LORA_MAX_NB_BANDS] =
00351 {
00352     BAND0,
00353 };
00354 
00355 /*!
00356  * LoRaMAC channels
00357  */
00358 static ChannelParams_t  Channels[LORA_MAX_NB_CHANNELS] =
00359 {
00360     LC1,
00361     LC2,
00362     LC3,
00363 };
00364 #elif defined( USE_BAND_868 )
00365 /*!
00366  * Data rates table definition
00367  */
00368 const uint8_t Datarates[]  = { 12, 11, 10,  9,  8,  7,  7, 50 };
00369 
00370 /*!
00371  * Bandwidths table definition in Hz
00372  */
00373 const uint32_t Bandwidths[] = { 125e3, 125e3, 125e3, 125e3, 125e3, 125e3, 250e3, 0 };
00374 
00375 /*!
00376  * Maximum payload with respect to the datarate index. Cannot operate with repeater.
00377  */
00378 const uint8_t MaxPayloadOfDatarate[] = { 51, 51, 51, 115, 242, 242, 242, 242 };
00379 
00380 /*!
00381  * Maximum payload with respect to the datarate index. Can operate with repeater.
00382  */
00383 const uint8_t MaxPayloadOfDatarateRepeater[] = { 51, 51, 51, 115, 222, 222, 222, 222 };
00384 
00385 /*!
00386  * Tx output powers table definition
00387  */
00388 const int8_t TxPowers[]    = { 20, 14, 11,  8,  5,  2 };
00389 
00390 /*!
00391  * LoRaMac bands
00392  */
00393 static Band_t  Bands[LORA_MAX_NB_BANDS] =
00394 {
00395     BAND0,
00396     BAND1,
00397     BAND2,
00398     BAND3,
00399     BAND4,
00400 };
00401 
00402 /*!
00403  * LoRaMAC channels
00404  */
00405 static ChannelParams_t  Channels[LORA_MAX_NB_CHANNELS] =
00406 {
00407     LC1,
00408     //Commented out by Chris
00409     //LC2,
00410     //LC3,
00411 };
00412 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
00413 /*!
00414  * Data rates table definition
00415  */
00416 const uint8_t Datarates[]  = { 10, 9, 8,  7,  8,  0,  0, 0, 12, 11, 10, 9, 8, 7, 0, 0 };
00417 
00418 /*!
00419  * Bandwidths table definition in Hz
00420  */
00421 const uint32_t Bandwidths[] = { 125e3, 125e3, 125e3, 125e3, 500e3, 0, 0, 0, 500e3, 500e3, 500e3, 500e3, 500e3, 500e3, 0, 0 };
00422 
00423 /*!
00424  * Up/Down link data rates offset definition
00425  */
00426 const int8_t DatarateOffsets[5][4] =
00427 {
00428     { DR_10, DR_9 , DR_8 , DR_8  }, // DR_0
00429     { DR_11, DR_10, DR_9 , DR_8  }, // DR_1
00430     { DR_12, DR_11, DR_10, DR_9  }, // DR_2
00431     { DR_13, DR_12, DR_11, DR_10 }, // DR_3
00432     { DR_13, DR_13, DR_12, DR_11 }, // DR_4
00433 };
00434 
00435 /*!
00436  * Maximum payload with respect to the datarate index. Cannot operate with repeater.
00437  */
00438 const uint8_t MaxPayloadOfDatarate[] = { 11, 53, 125, 242, 242, 0, 0, 0, 53, 129, 242, 242, 242, 242, 0, 0 };
00439 
00440 /*!
00441  * Maximum payload with respect to the datarate index. Can operate with repeater.
00442  */
00443 const uint8_t MaxPayloadOfDatarateRepeater[] = { 11, 53, 125, 242, 242, 0, 0, 0, 33, 109, 222, 222, 222, 222, 0, 0 };
00444 
00445 /*!
00446  * Tx output powers table definition
00447  */
00448 const int8_t TxPowers[]    = { 30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10 };
00449 
00450 /*!
00451  * LoRaMac bands
00452  */
00453 static Band_t  Bands[LORA_MAX_NB_BANDS] =
00454 {
00455     BAND0,
00456 };
00457 
00458 /*!
00459  * LoRaMAC channels
00460  */
00461 static ChannelParams_t  Channels[LORA_MAX_NB_CHANNELS];
00462 
00463 /*!
00464  * Contains the channels which remain to be applied.
00465  */
00466 static uint16_t ChannelsMaskRemaining[6];
00467 
00468 /*!
00469  * Defines the first channel for RX window 1 for US band
00470  */
00471 #define LORAMAC_FIRST_RX1_CHANNEL           ( (uint32_t) 923.3e6 )
00472 
00473 /*!
00474  * Defines the last channel for RX window 1 for US band
00475  */
00476 #define LORAMAC_LAST_RX1_CHANNEL            ( (uint32_t) 927.5e6 )
00477 
00478 /*!
00479  * Defines the step width of the channels for RX window 1
00480  */
00481 #define LORAMAC_STEPWIDTH_RX1_CHANNEL       ( (uint32_t) 600e3 )
00482 
00483 #else
00484     #error "Please define a frequency band in the compiler options."
00485 #endif
00486 
00487 /*!
00488  * LoRaMac parameters
00489  */
00490 LoRaMacParams_t  LoRaMacParams;
00491 
00492 /*!
00493  * LoRaMac default parameters
00494  */
00495 LoRaMacParams_t  LoRaMacParamsDefaults;
00496 
00497 /*!
00498  * Uplink messages repetitions counter
00499  */
00500 static uint8_t ChannelsNbRepCounter = 0;
00501 
00502 /*!
00503  * Maximum duty cycle
00504  * \remark Possibility to shutdown the device.
00505  */
00506 static uint8_t MaxDCycle = 0;
00507 
00508 /*!
00509  * Aggregated duty cycle management
00510  */
00511 static uint16_t AggregatedDCycle;
00512 static TimerTime_t AggregatedLastTxDoneTime;
00513 static TimerTime_t AggregatedTimeOff;
00514 
00515 /*!
00516  * Enables/Disables duty cycle management (Test only)
00517  */
00518 static bool DutyCycleOn;
00519 
00520 /*!
00521  * Current channel index
00522  */
00523 static uint8_t Channel;
00524 
00525 /*!
00526  * Stores the time at LoRaMac initialization.
00527  *
00528  * \remark Used for the BACKOFF_DC computation.
00529  */
00530 static TimerTime_t LoRaMacInitializationTime = 0;
00531 
00532 /*!
00533  * LoRaMac internal states
00534  */
00535 enum eLoRaMacState
00536 {
00537     LORAMAC_IDLE          = 0x00000000,
00538     LORAMAC_TX_RUNNING    = 0x00000001,
00539     LORAMAC_RX            = 0x00000002,
00540     LORAMAC_ACK_REQ       = 0x00000004,
00541     LORAMAC_ACK_RETRY     = 0x00000008,
00542     LORAMAC_TX_DELAYED    = 0x00000010,
00543     LORAMAC_TX_CONFIG     = 0x00000020,
00544     LORAMAC_RX_ABORT      = 0x00000040,
00545 };
00546 
00547 /*!
00548  * LoRaMac internal state
00549  */
00550 uint32_t LoRaMacState = LORAMAC_IDLE;
00551 
00552 /*!
00553  * LoRaMac timer used to check the LoRaMacState (runs every second)
00554  */
00555 static TimerEvent_t MacStateCheckTimer;
00556 
00557 /*!
00558  * LoRaMac upper layer event functions
00559  */
00560 static LoRaMacPrimitives_t  *LoRaMacPrimitives;
00561 
00562 /*!
00563  * LoRaMac upper layer callback functions
00564  */
00565 static LoRaMacCallback_t *LoRaMacCallbacks;
00566 
00567 /*!
00568  * Radio events function pointer
00569  */
00570 static RadioEvents_t RadioEvents;
00571 
00572 /*!
00573  * LoRaMac duty cycle delayed Tx timer
00574  */
00575 static TimerEvent_t TxDelayedTimer;
00576 
00577 /*!
00578  * LoRaMac reception windows timers
00579  */
00580 static TimerEvent_t RxWindowTimer1;
00581 static TimerEvent_t RxWindowTimer2;
00582 
00583 /*!
00584  * LoRaMac reception windows delay
00585  * \remark normal frame: RxWindowXDelay = ReceiveDelayX - RADIO_WAKEUP_TIME
00586  *         join frame  : RxWindowXDelay = JoinAcceptDelayX - RADIO_WAKEUP_TIME
00587  */
00588 static uint32_t RxWindow1Delay;
00589 static uint32_t RxWindow2Delay;
00590 
00591 /*!
00592  * Rx window parameters
00593  */
00594 typedef struct
00595 {
00596     int8_t Datarate;
00597     uint8_t Bandwidth;
00598     uint32_t RxWindowTimeout;
00599     int32_t RxOffset;
00600 }RxConfigParams_t;
00601 
00602 /*!
00603  * Rx windows params
00604  */
00605 static RxConfigParams_t RxWindowsParams[2];
00606 
00607 /*!
00608  * Acknowledge timeout timer. Used for packet retransmissions.
00609  */
00610 static TimerEvent_t AckTimeoutTimer;
00611 
00612 /*!
00613  * Number of trials to get a frame acknowledged
00614  */
00615 static uint8_t AckTimeoutRetries = 1;
00616 
00617 /*!
00618  * Number of trials to get a frame acknowledged
00619  */
00620 static uint8_t AckTimeoutRetriesCounter = 1;
00621 
00622 /*!
00623  * Indicates if the AckTimeout timer has expired or not
00624  */
00625 static bool AckTimeoutRetry = false;
00626 
00627 /*!
00628  * Last transmission time on air
00629  */
00630 TimerTime_t TxTimeOnAir = 0;
00631 
00632 /*!
00633  * Number of trials for the Join Request
00634  */
00635 static uint8_t JoinRequestTrials;
00636 
00637 /*!
00638  * Maximum number of trials for the Join Request
00639  */
00640 static uint8_t MaxJoinRequestTrials;
00641 
00642 /*!
00643  * Structure to hold an MCPS indication data.
00644  */
00645 static McpsIndication_t  McpsIndication;
00646 
00647 /*!
00648  * Structure to hold MCPS confirm data.
00649  */
00650 static McpsConfirm_t  McpsConfirm;
00651 
00652 /*!
00653  * Structure to hold MLME confirm data.
00654  */
00655 static MlmeConfirm_t  MlmeConfirm;
00656 
00657 /*!
00658  * Holds the current rx window slot
00659  */
00660 static uint8_t RxSlot = 0;
00661 
00662 /*!
00663  * LoRaMac tx/rx operation state
00664  */
00665 LoRaMacFlags_t  LoRaMacFlags;
00666 
00667 /*!
00668  * \brief Function to be executed on Radio Tx Done event
00669  */
00670 static void OnRadioTxDone( void );
00671 
00672 /*!
00673  * \brief This function prepares the MAC to abort the execution of function
00674  *        OnRadioRxDone in case of a reception error.
00675  */
00676 static void PrepareRxDoneAbort( void );
00677 
00678 /*!
00679  * \brief Function to be executed on Radio Rx Done event
00680  */
00681 static void OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr );
00682 
00683 /*!
00684  * \brief Function executed on Radio Tx Timeout event
00685  */
00686 static void OnRadioTxTimeout( void );
00687 
00688 /*!
00689  * \brief Function executed on Radio Rx error event
00690  */
00691 static void OnRadioRxError( void );
00692 
00693 /*!
00694  * \brief Function executed on Radio Rx Timeout event
00695  */
00696 static void OnRadioRxTimeout( void );
00697 
00698 /*!
00699  * \brief Function executed on Resend Frame timer event.
00700  */
00701 static void OnMacStateCheckTimerEvent( void );
00702 
00703 /*!
00704  * \brief Function executed on duty cycle delayed Tx  timer event
00705  */
00706 static void OnTxDelayedTimerEvent( void );
00707 
00708 /*!
00709  * \brief Function executed on first Rx window timer event
00710  */
00711 static void OnRxWindow1TimerEvent( void );
00712 
00713 /*!
00714  * \brief Function executed on second Rx window timer event
00715  */
00716 static void OnRxWindow2TimerEvent( void );
00717 
00718 /*!
00719  * \brief Function executed on AckTimeout timer event
00720  */
00721 static void OnAckTimeoutTimerEvent( void );
00722 
00723 /*!
00724  * \brief Searches and set the next random available channel
00725  *
00726  * \param [OUT] Time to wait for the next transmission according to the duty
00727  *              cycle.
00728  *
00729  * \retval status  Function status [1: OK, 0: Unable to find a channel on the
00730  *                                  current datarate]
00731  */
00732 static bool SetNextChannel( TimerTime_t* time );
00733 
00734 /*!
00735  * \brief Initializes and opens the reception window
00736  *
00737  * \param [IN] freq window channel frequency
00738  * \param [IN] datarate window channel datarate
00739  * \param [IN] bandwidth window channel bandwidth
00740  * \param [IN] timeout window channel timeout
00741  *
00742  * \retval status Operation status [true: Success, false: Fail]
00743  */
00744 static bool RxWindowSetup( uint32_t freq, int8_t datarate, uint32_t bandwidth, uint16_t timeout, bool rxContinuous );
00745 
00746 /*!
00747  * \brief Verifies if the RX window 2 frequency is in range
00748  *
00749  * \param [IN] freq window channel frequency
00750  *
00751  * \retval status  Function status [1: OK, 0: Frequency not applicable]
00752  */
00753 static bool Rx2FreqInRange( uint32_t freq );
00754 
00755 /*!
00756  * \brief Adds a new MAC command to be sent.
00757  *
00758  * \Remark MAC layer internal function
00759  *
00760  * \param [in] cmd MAC command to be added
00761  *                 [MOTE_MAC_LINK_CHECK_REQ,
00762  *                  MOTE_MAC_LINK_ADR_ANS,
00763  *                  MOTE_MAC_DUTY_CYCLE_ANS,
00764  *                  MOTE_MAC_RX2_PARAM_SET_ANS,
00765  *                  MOTE_MAC_DEV_STATUS_ANS
00766  *                  MOTE_MAC_NEW_CHANNEL_ANS]
00767  * \param [in] p1  1st parameter ( optional depends on the command )
00768  * \param [in] p2  2nd parameter ( optional depends on the command )
00769  *
00770  * \retval status  Function status [0: OK, 1: Unknown command, 2: Buffer full]
00771  */
00772 static LoRaMacStatus_t  AddMacCommand( uint8_t cmd, uint8_t p1, uint8_t p2 );
00773 
00774 /*!
00775  * \brief Parses the MAC commands which must be repeated.
00776  *
00777  * \Remark MAC layer internal function
00778  *
00779  * \param [IN] cmdBufIn  Buffer which stores the MAC commands to send
00780  * \param [IN] length  Length of the input buffer to parse
00781  * \param [OUT] cmdBufOut  Buffer which stores the MAC commands which must be
00782  *                         repeated.
00783  *
00784  * \retval Size of the MAC commands to repeat.
00785  */
00786 static uint8_t ParseMacCommandsToRepeat( uint8_t* cmdBufIn, uint8_t length, uint8_t* cmdBufOut );
00787 
00788 /*!
00789  * \brief Validates if the payload fits into the frame, taking the datarate
00790  *        into account.
00791  *
00792  * \details Refer to chapter 4.3.2 of the LoRaWAN specification, v1.0
00793  *
00794  * \param lenN Length of the application payload. The length depends on the
00795  *             datarate and is region specific
00796  *
00797  * \param datarate Current datarate
00798  *
00799  * \param fOptsLen Length of the fOpts field
00800  *
00801  * \retval [false: payload does not fit into the frame, true: payload fits into
00802  *          the frame]
00803  */
00804 static bool ValidatePayloadLength( uint8_t lenN, int8_t datarate, uint8_t fOptsLen );
00805 
00806 /*!
00807  * \brief Counts the number of bits in a mask.
00808  *
00809  * \param [IN] mask A mask from which the function counts the active bits.
00810  * \param [IN] nbBits The number of bits to check.
00811  *
00812  * \retval Number of enabled bits in the mask.
00813  */
00814 static uint8_t CountBits( uint16_t mask, uint8_t nbBits );
00815 
00816 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
00817 /*!
00818  * \brief Counts the number of enabled 125 kHz channels in the channel mask.
00819  *        This function can only be applied to US915 band.
00820  *
00821  * \param [IN] channelsMask Pointer to the first element of the channel mask
00822  *
00823  * \retval Number of enabled channels in the channel mask
00824  */
00825 static uint8_t CountNbEnabled125kHzChannels( uint16_t *channelsMask );
00826 
00827 #if defined( USE_BAND_915_HYBRID )
00828 /*!
00829  * \brief Validates the correctness of the channel mask for US915, hybrid mode.
00830  *
00831  * \param [IN] mask Block definition to set.
00832  * \param [OUT] channelsMask Pointer to the first element of the channel mask
00833  */
00834 static void ReenableChannels( uint16_t mask, uint16_t* channelsMask );
00835 
00836 /*!
00837  * \brief Validates the correctness of the channel mask for US915, hybrid mode.
00838  *
00839  * \param [IN] channelsMask Pointer to the first element of the channel mask
00840  *
00841  * \retval [true: channel mask correct, false: channel mask not correct]
00842  */
00843 static bool ValidateChannelMask( uint16_t* channelsMask );
00844 #endif
00845 
00846 #endif
00847 
00848 /*!
00849  * \brief Validates the correctness of the datarate against the enable channels.
00850  *
00851  * \param [IN] datarate Datarate to be check
00852  * \param [IN] channelsMask Pointer to the first element of the channel mask
00853  *
00854  * \retval [true: datarate can be used, false: datarate can not be used]
00855  */
00856 static bool ValidateDatarate( int8_t datarate, uint16_t* channelsMask );
00857 
00858 /*!
00859  * \brief Limits the Tx power according to the number of enabled channels
00860  *
00861  * \param [IN] txPower txPower to limit
00862  * \param [IN] maxBandTxPower Maximum band allowed TxPower
00863  *
00864  * \retval Returns the maximum valid tx power
00865  */
00866 static int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower );
00867 
00868 /*!
00869  * \brief Verifies, if a value is in a given range.
00870  *
00871  * \param value Value to verify, if it is in range
00872  *
00873  * \param min Minimum possible value
00874  *
00875  * \param max Maximum possible value
00876  *
00877  * \retval Returns the maximum valid tx power
00878  */
00879 static bool ValueInRange( int8_t value, int8_t min, int8_t max );
00880 
00881 /*!
00882  * \brief Calculates the next datarate to set, when ADR is on or off
00883  *
00884  * \param [IN] adrEnabled Specify whether ADR is on or off
00885  *
00886  * \param [IN] updateChannelMask Set to true, if the channel masks shall be updated
00887  *
00888  * \param [OUT] datarateOut Reports the datarate which will be used next
00889  *
00890  * \retval Returns the state of ADR ack request
00891  */
00892 static bool AdrNextDr( bool adrEnabled, bool updateChannelMask, int8_t* datarateOut );
00893 
00894 /*!
00895  * \brief Disables channel in a specified channel mask
00896  *
00897  * \param [IN] id - Id of the channel
00898  *
00899  * \param [IN] mask - Pointer to the channel mask to edit
00900  *
00901  * \retval [true, if disable was successful, false if not]
00902  */
00903 static bool DisableChannelInMask( uint8_t id, uint16_t* mask );
00904 
00905 /*!
00906  * \brief Decodes MAC commands in the fOpts field and in the payload
00907  */
00908 static void ProcessMacCommands( uint8_t *payload, uint8_t macIndex, uint8_t commandsSize, uint8_t snr );
00909 
00910 /*!
00911  * \brief LoRaMAC layer generic send frame
00912  *
00913  * \param [IN] macHdr      MAC header field
00914  * \param [IN] fPort       MAC payload port
00915  * \param [IN] fBuffer     MAC data buffer to be sent
00916  * \param [IN] fBufferSize MAC data buffer size
00917  * \retval status          Status of the operation.
00918  */
00919 LoRaMacStatus_t  Send( LoRaMacHeader_t  *macHdr, uint8_t fPort, void *fBuffer, uint16_t fBufferSize );
00920 
00921 /*!
00922  * \brief LoRaMAC layer frame buffer initialization
00923  *
00924  * \param [IN] macHdr      MAC header field
00925  * \param [IN] fCtrl       MAC frame control field
00926  * \param [IN] fOpts       MAC commands buffer
00927  * \param [IN] fPort       MAC payload port
00928  * \param [IN] fBuffer     MAC data buffer to be sent
00929  * \param [IN] fBufferSize MAC data buffer size
00930  * \retval status          Status of the operation.
00931  */
00932 LoRaMacStatus_t  PrepareFrame( LoRaMacHeader_t  *macHdr, LoRaMacFrameCtrl_t  *fCtrl, uint8_t fPort, void *fBuffer, uint16_t fBufferSize );
00933 
00934 /*
00935  * \brief Schedules the frame according to the duty cycle
00936  *
00937  * \retval Status of the operation
00938  */
00939 static LoRaMacStatus_t  ScheduleTx( void );
00940 
00941 /*
00942  * \brief Sets the duty cycle for the join procedure.
00943  *
00944  * \retval Duty cycle
00945  */
00946 static uint16_t JoinDutyCycle( void );
00947 
00948 /*
00949  * \brief Calculates the back-off time for the band of a channel.
00950  *
00951  * \param [IN] channel     The last Tx channel index
00952  */
00953 static void CalculateBackOff( uint8_t channel );
00954 
00955 /*
00956  * \brief Alternates the datarate of the channel for the join request.
00957  *
00958  * \param [IN] nbTrials    Number of performed join requests.
00959  * \retval Datarate to apply
00960  */
00961 static int8_t AlternateDatarate( uint16_t nbTrials );
00962 
00963 /*!
00964  * \brief LoRaMAC layer prepared frame buffer transmission with channel specification
00965  *
00966  * \remark PrepareFrame must be called at least once before calling this
00967  *         function.
00968  *
00969  * \param [IN] channel     Channel parameters
00970  * \retval status          Status of the operation.
00971  */
00972 LoRaMacStatus_t  SendFrameOnChannel( ChannelParams_t  channel );
00973 
00974 /*!
00975  * \brief Sets the radio in continuous transmission mode
00976  *
00977  * \remark Uses the radio parameters set on the previous transmission.
00978  *
00979  * \param [IN] timeout     Time in seconds while the radio is kept in continuous wave mode
00980  * \retval status          Status of the operation.
00981  */
00982 LoRaMacStatus_t  SetTxContinuousWave( uint16_t timeout );
00983 
00984 /*!
00985  * \brief Sets the radio in continuous transmission mode
00986  *
00987  * \remark Uses the radio parameters set on the previous transmission.
00988  *
00989  * \param [IN] timeout     Time in seconds while the radio is kept in continuous wave mode
00990  * \param [IN] frequency   RF frequency to be set.
00991  * \param [IN] power       RF ouptput power to be set.
00992  * \retval status          Status of the operation.
00993  */
00994 LoRaMacStatus_t  SetTxContinuousWave1( uint16_t timeout, uint32_t frequency, uint8_t power );
00995 
00996 /*!
00997  * \brief Resets MAC specific parameters to default
00998  */
00999 static void ResetMacParameters( void );
01000 
01001 /*
01002  * Rx window precise timing
01003  *
01004  * For more details please consult the following document, chapter 3.1.2.
01005  * http://www.semtech.com/images/datasheet/SX1272_settings_for_LoRaWAN_v2.0.pdf
01006  * or
01007  * http://www.semtech.com/images/datasheet/SX1276_settings_for_LoRaWAN_v2.0.pdf
01008  *
01009  *                 Downlink start: T = Tx + 1s (+/- 20 us)
01010  *                            |
01011  *             TRxEarly       |        TRxLate
01012  *                |           |           |
01013  *                |           |           +---+---+---+---+---+---+---+---+
01014  *                |           |           |       Latest Rx window        |
01015  *                |           |           +---+---+---+---+---+---+---+---+
01016  *                |           |           |
01017  *                +---+---+---+---+---+---+---+---+
01018  *                |       Earliest Rx window      |
01019  *                +---+---+---+---+---+---+---+---+
01020  *                            |
01021  *                            +---+---+---+---+---+---+---+---+
01022  *Downlink preamble 8 symbols |   |   |   |   |   |   |   |   |
01023  *                            +---+---+---+---+---+---+---+---+
01024  *
01025  *                     Worst case Rx window timings
01026  *
01027  * TRxLate  = DEFAULT_MIN_RX_SYMBOLS * tSymbol - RADIO_WAKEUP_TIME
01028  * TRxEarly = 8 - DEFAULT_MIN_RX_SYMBOLS * tSymbol - RxWindowTimeout - RADIO_WAKEUP_TIME
01029  *
01030  * TRxLate - TRxEarly = 2 * DEFAULT_SYSTEM_MAX_RX_ERROR
01031  *
01032  * RxOffset = ( TRxLate + TRxEarly ) / 2
01033  *
01034  * RxWindowTimeout = ( 2 * DEFAULT_MIN_RX_SYMBOLS - 8 ) * tSymbol + 2 * DEFAULT_SYSTEM_MAX_RX_ERROR
01035  * RxOffset = 4 * tSymbol - RxWindowTimeout / 2 - RADIO_WAKE_UP_TIME
01036  *
01037  * Minimal value of RxWindowTimeout must be 5 symbols which implies that the system always tolerates at least an error of 1.5 * tSymbol
01038  */
01039 /*!
01040  * Computes the Rx window parameters.
01041  *
01042  * \param [IN] datarate     Rx window datarate to be used
01043  * \param [IN] rxError      Maximum timing error of the receiver. in milliseconds
01044  *                          The receiver will turn on in a [-rxError : +rxError] ms
01045  *                          interval around RxOffset
01046  *
01047  * \retval rxConfigParams   Returns a RxConfigParams_t structure.
01048  */
01049 static RxConfigParams_t ComputeRxWindowParameters( int8_t datarate, uint32_t rxError );
01050 
01051 static void OnRadioTxDone( void )
01052 {
01053     TimerTime_t curTime = TimerGetCurrentTime( );
01054 
01055     if( LoRaMacDeviceClass != CLASS_C  )
01056     {
01057         Radio.Sleep( );
01058     }
01059     else
01060     {
01061         OnRxWindow2TimerEvent( );
01062     }
01063 
01064     // Setup timers
01065     if( IsRxWindowsEnabled == true )
01066     {
01067         TimerSetValue( &RxWindowTimer1, RxWindow1Delay );
01068         TimerStart( &RxWindowTimer1 );
01069         if( LoRaMacDeviceClass != CLASS_C  )
01070         {
01071             TimerSetValue( &RxWindowTimer2, RxWindow2Delay );
01072             TimerStart( &RxWindowTimer2 );
01073         }
01074         if( ( LoRaMacDeviceClass == CLASS_C  ) || ( NodeAckRequested == true ) )
01075         {
01076             TimerSetValue( &AckTimeoutTimer, RxWindow2Delay + ACK_TIMEOUT +
01077                                              randr( -ACK_TIMEOUT_RND, ACK_TIMEOUT_RND ) );
01078             TimerStart( &AckTimeoutTimer );
01079         }
01080     }
01081     else
01082     {
01083         McpsConfirm.Status  = LORAMAC_EVENT_INFO_STATUS_OK ;
01084         MlmeConfirm.Status  = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT ;
01085 
01086         if( LoRaMacFlags.Value  == 0 )
01087         {
01088             LoRaMacFlags.Bits.McpsReq  = 1;
01089         }
01090         LoRaMacFlags.Bits.MacDone  = 1;
01091     }
01092 
01093     // Update last tx done time for the current channel
01094     Bands[Channels[Channel].Band ].LastTxDoneTime  = curTime;
01095     // Update Aggregated last tx done time
01096     AggregatedLastTxDoneTime = curTime;
01097     // Update Backoff
01098     CalculateBackOff( Channel );
01099 
01100     if( NodeAckRequested == false )
01101     {
01102         McpsConfirm.Status  = LORAMAC_EVENT_INFO_STATUS_OK ;
01103         ChannelsNbRepCounter++;
01104     }
01105 }
01106 
01107 static void PrepareRxDoneAbort( void )
01108 {
01109     LoRaMacState |= LORAMAC_RX_ABORT;
01110 
01111     if( NodeAckRequested )
01112     {
01113         OnAckTimeoutTimerEvent( );
01114     }
01115 
01116     LoRaMacFlags.Bits.McpsInd  = 1;
01117     LoRaMacFlags.Bits.MacDone  = 1;
01118 
01119     // Trig OnMacCheckTimerEvent call as soon as possible
01120     TimerSetValue( &MacStateCheckTimer, 1 );
01121     TimerStart( &MacStateCheckTimer );
01122 }
01123 
01124 static void OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr )
01125 {
01126     LoRaMacHeader_t  macHdr;
01127     LoRaMacFrameCtrl_t  fCtrl;
01128     bool skipIndication = false;
01129 
01130     uint8_t pktHeaderLen = 0;
01131     uint32_t address = 0;
01132     uint8_t appPayloadStartIndex = 0;
01133     uint8_t port = 0xFF;
01134     uint8_t frameLen = 0;
01135     uint32_t mic = 0;
01136     uint32_t micRx = 0;
01137 
01138     uint16_t sequenceCounter = 0;
01139     uint16_t sequenceCounterPrev = 0;
01140     uint16_t sequenceCounterDiff = 0;
01141     uint32_t downLinkCounter = 0;
01142 
01143     MulticastParams_t  *curMulticastParams = NULL;
01144     uint8_t *nwkSKey = LoRaMacNwkSKey;
01145     uint8_t *appSKey = LoRaMacAppSKey;
01146 
01147     uint8_t multicast = 0;
01148 
01149     bool isMicOk = false;
01150 
01151     McpsConfirm.AckReceived  = false;
01152     McpsIndication.Rssi  = rssi;
01153     McpsIndication.Snr  = snr;
01154     McpsIndication.RxSlot  = RxSlot;
01155     McpsIndication.Port  = 0;
01156     McpsIndication.Multicast  = 0;
01157     McpsIndication.FramePending  = 0;
01158     McpsIndication.Buffer  = NULL;
01159     McpsIndication.BufferSize  = 0;
01160     McpsIndication.RxData  = false;
01161     McpsIndication.AckReceived  = false;
01162     McpsIndication.DownLinkCounter  = 0;
01163     McpsIndication.McpsIndication  = MCPS_UNCONFIRMED ;
01164 
01165     Radio.Sleep( );
01166     TimerStop( &RxWindowTimer2 );
01167 
01168     macHdr.Value  = payload[pktHeaderLen++];
01169 
01170     switch( macHdr.Bits.MType  )
01171     {
01172         case FRAME_TYPE_JOIN_ACCEPT :
01173             if( IsLoRaMacNetworkJoined == true )
01174             {
01175                 McpsIndication.Status  = LORAMAC_EVENT_INFO_STATUS_ERROR ;
01176                 PrepareRxDoneAbort( );
01177                 return;
01178             }
01179             LoRaMacJoinDecrypt ( payload + 1, size - 1, LoRaMacAppKey, LoRaMacRxPayload + 1 );
01180 
01181             LoRaMacRxPayload[0] = macHdr.Value ;
01182 
01183             LoRaMacJoinComputeMic ( LoRaMacRxPayload, size - LORAMAC_MFR_LEN, LoRaMacAppKey, &mic );
01184 
01185             micRx |= ( uint32_t )LoRaMacRxPayload[size - LORAMAC_MFR_LEN];
01186             micRx |= ( ( uint32_t )LoRaMacRxPayload[size - LORAMAC_MFR_LEN + 1] << 8 );
01187             micRx |= ( ( uint32_t )LoRaMacRxPayload[size - LORAMAC_MFR_LEN + 2] << 16 );
01188             micRx |= ( ( uint32_t )LoRaMacRxPayload[size - LORAMAC_MFR_LEN + 3] << 24 );
01189 
01190             if( micRx == mic )
01191             {
01192                 LoRaMacJoinComputeSKeys ( LoRaMacAppKey, LoRaMacRxPayload + 1, LoRaMacDevNonce, LoRaMacNwkSKey, LoRaMacAppSKey );
01193 
01194                 LoRaMacNetID = ( uint32_t )LoRaMacRxPayload[4];
01195                 LoRaMacNetID |= ( ( uint32_t )LoRaMacRxPayload[5] << 8 );
01196                 LoRaMacNetID |= ( ( uint32_t )LoRaMacRxPayload[6] << 16 );
01197 
01198                 LoRaMacDevAddr = ( uint32_t )LoRaMacRxPayload[7];
01199                 LoRaMacDevAddr |= ( ( uint32_t )LoRaMacRxPayload[8] << 8 );
01200                 LoRaMacDevAddr |= ( ( uint32_t )LoRaMacRxPayload[9] << 16 );
01201                 LoRaMacDevAddr |= ( ( uint32_t )LoRaMacRxPayload[10] << 24 );
01202 
01203                 // DLSettings
01204                 LoRaMacParams.Rx1DrOffset  = ( LoRaMacRxPayload[11] >> 4 ) & 0x07;
01205                 LoRaMacParams.Rx2Channel .Datarate  = LoRaMacRxPayload[11] & 0x0F;
01206 
01207                 // RxDelay
01208                 LoRaMacParams.ReceiveDelay1  = ( LoRaMacRxPayload[12] & 0x0F );
01209                 if( LoRaMacParams.ReceiveDelay1  == 0 )
01210                 {
01211                     LoRaMacParams.ReceiveDelay1  = 1;
01212                 }
01213                 LoRaMacParams.ReceiveDelay1  *= 1e3;
01214                 LoRaMacParams.ReceiveDelay2  = LoRaMacParams.ReceiveDelay1  + 1e3;
01215 
01216 #if !( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) )
01217                 //CFList
01218                 if( ( size - 1 ) > 16 )
01219                 {
01220                     ChannelParams_t  param;
01221                     param.DrRange .Value  = ( DR_5 << 4 ) | DR_0;
01222 
01223                     LoRaMacState |= LORAMAC_TX_CONFIG;
01224                     for( uint8_t i = 3, j = 0; i < ( 5 + 3 ); i++, j += 3 )
01225                     {
01226                         param.Frequency  = ( ( uint32_t )LoRaMacRxPayload[13 + j] | ( ( uint32_t )LoRaMacRxPayload[14 + j] << 8 ) | ( ( uint32_t )LoRaMacRxPayload[15 + j] << 16 ) ) * 100;
01227                         if( param.Frequency  != 0 )
01228                         {
01229                             LoRaMacChannelAdd( i, param );
01230                         }
01231                         else
01232                         {
01233                             LoRaMacChannelRemove( i );
01234                         }
01235                     }
01236                     LoRaMacState &= ~LORAMAC_TX_CONFIG;
01237                 }
01238 #endif
01239                 MlmeConfirm.Status  = LORAMAC_EVENT_INFO_STATUS_OK ;
01240                 IsLoRaMacNetworkJoined = true;
01241                 LoRaMacParams.ChannelsDatarate  = LoRaMacParamsDefaults.ChannelsDatarate ;
01242             }
01243             else
01244             {
01245                 MlmeConfirm.Status  = LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL ;
01246             }
01247             break;
01248         case FRAME_TYPE_DATA_CONFIRMED_DOWN :
01249         case FRAME_TYPE_DATA_UNCONFIRMED_DOWN :
01250             {
01251                 address = payload[pktHeaderLen++];
01252                 address |= ( (uint32_t)payload[pktHeaderLen++] << 8 );
01253                 address |= ( (uint32_t)payload[pktHeaderLen++] << 16 );
01254                 address |= ( (uint32_t)payload[pktHeaderLen++] << 24 );
01255 
01256                 if( address != LoRaMacDevAddr )
01257                 {
01258                     curMulticastParams = MulticastChannels;
01259                     while( curMulticastParams != NULL )
01260                     {
01261                         if( address == curMulticastParams->Address  )
01262                         {
01263                             multicast = 1;
01264                             nwkSKey = curMulticastParams->NwkSKey ;
01265                             appSKey = curMulticastParams->AppSKey ;
01266                             downLinkCounter = curMulticastParams->DownLinkCounter ;
01267                             break;
01268                         }
01269                         curMulticastParams = curMulticastParams->Next ;
01270                     }
01271                     if( multicast == 0 )
01272                     {
01273                         // We are not the destination of this frame.
01274                         McpsIndication.Status  = LORAMAC_EVENT_INFO_STATUS_ADDRESS_FAIL ;
01275                         PrepareRxDoneAbort( );
01276                         return;
01277                     }
01278                 }
01279                 else
01280                 {
01281                     multicast = 0;
01282                     nwkSKey = LoRaMacNwkSKey;
01283                     appSKey = LoRaMacAppSKey;
01284                     downLinkCounter = DownLinkCounter;
01285                 }
01286 
01287                 fCtrl.Value  = payload[pktHeaderLen++];
01288 
01289                 sequenceCounter = ( uint16_t )payload[pktHeaderLen++];
01290                 sequenceCounter |= ( uint16_t )payload[pktHeaderLen++] << 8;
01291 
01292                 appPayloadStartIndex = 8 + fCtrl.Bits.FOptsLen ;
01293 
01294                 micRx |= ( uint32_t )payload[size - LORAMAC_MFR_LEN];
01295                 micRx |= ( ( uint32_t )payload[size - LORAMAC_MFR_LEN + 1] << 8 );
01296                 micRx |= ( ( uint32_t )payload[size - LORAMAC_MFR_LEN + 2] << 16 );
01297                 micRx |= ( ( uint32_t )payload[size - LORAMAC_MFR_LEN + 3] << 24 );
01298 
01299                 sequenceCounterPrev = ( uint16_t )downLinkCounter;
01300                 sequenceCounterDiff = ( sequenceCounter - sequenceCounterPrev );
01301 
01302                 if( sequenceCounterDiff < ( 1 << 15 ) )
01303                 {
01304                     downLinkCounter += sequenceCounterDiff;
01305                     LoRaMacComputeMic( payload, size - LORAMAC_MFR_LEN, nwkSKey, address, DOWN_LINK, downLinkCounter, &mic );
01306                     if( micRx == mic )
01307                     {
01308                         isMicOk = true;
01309                     }
01310                 }
01311                 else
01312                 {
01313                     // check for sequence roll-over
01314                     uint32_t  downLinkCounterTmp = downLinkCounter + 0x10000 + ( int16_t )sequenceCounterDiff;
01315                     LoRaMacComputeMic( payload, size - LORAMAC_MFR_LEN, nwkSKey, address, DOWN_LINK, downLinkCounterTmp, &mic );
01316                     if( micRx == mic )
01317                     {
01318                         isMicOk = true;
01319                         downLinkCounter = downLinkCounterTmp;
01320                     }
01321                 }
01322 
01323                 // Check for a the maximum allowed counter difference
01324                 if( sequenceCounterDiff >= MAX_FCNT_GAP )
01325                 {
01326                     McpsIndication.Status  = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_TOO_MANY_FRAMES_LOSS ;
01327                     McpsIndication.DownLinkCounter  = downLinkCounter;
01328                     PrepareRxDoneAbort( );
01329                     return;
01330                 }
01331 
01332                 if( isMicOk == true )
01333                 {
01334                     McpsIndication.Status  = LORAMAC_EVENT_INFO_STATUS_OK ;
01335                     McpsIndication.Multicast  = multicast;
01336                     McpsIndication.FramePending  = fCtrl.Bits.FPending ;
01337                     McpsIndication.Buffer  = NULL;
01338                     McpsIndication.BufferSize  = 0;
01339                     McpsIndication.DownLinkCounter  = downLinkCounter;
01340 
01341                     McpsConfirm.Status  = LORAMAC_EVENT_INFO_STATUS_OK ;
01342 
01343                     AdrAckCounter = 0;
01344                     MacCommandsBufferToRepeatIndex = 0;
01345 
01346                     // Update 32 bits downlink counter
01347                     if( multicast == 1 )
01348                     {
01349                         McpsIndication.McpsIndication  = MCPS_MULTICAST ;
01350 
01351                         if( ( curMulticastParams->DownLinkCounter  == downLinkCounter ) &&
01352                             ( curMulticastParams->DownLinkCounter  != 0 ) )
01353                         {
01354                             McpsIndication.Status  = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED ;
01355                             McpsIndication.DownLinkCounter  = downLinkCounter;
01356                             PrepareRxDoneAbort( );
01357                             return;
01358                         }
01359                         curMulticastParams->DownLinkCounter  = downLinkCounter;
01360                     }
01361                     else
01362                     {
01363                         if( macHdr.Bits.MType  == FRAME_TYPE_DATA_CONFIRMED_DOWN  )
01364                         {
01365                             SrvAckRequested = true;
01366                             McpsIndication.McpsIndication  = MCPS_CONFIRMED ;
01367 
01368                             if( ( DownLinkCounter == downLinkCounter ) &&
01369                                 ( DownLinkCounter != 0 ) )
01370                             {
01371                                 // Duplicated confirmed downlink. Skip indication.
01372                                 // In this case, the MAC layer shall accept the MAC commands
01373                                 // which are included in the downlink retransmission.
01374                                 // It should not provide the same frame to the application
01375                                 // layer again.
01376                                 skipIndication = true;
01377                             }
01378                         }
01379                         else
01380                         {
01381                             SrvAckRequested = false;
01382                             McpsIndication.McpsIndication  = MCPS_UNCONFIRMED ;
01383 
01384                             if( ( DownLinkCounter == downLinkCounter ) &&
01385                                 ( DownLinkCounter != 0 ) )
01386                             {
01387                                 McpsIndication.Status  = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED ;
01388                                 McpsIndication.DownLinkCounter  = downLinkCounter;
01389                                 PrepareRxDoneAbort( );
01390                                 return;
01391                             }
01392                         }
01393                         DownLinkCounter = downLinkCounter;
01394                     }
01395 
01396                     // This must be done before parsing the payload and the MAC commands.
01397                     // We need to reset the MacCommandsBufferIndex here, since we need
01398                     // to take retransmissions and repititions into account. Error cases
01399                     // will be handled in function OnMacStateCheckTimerEvent.
01400                     if( McpsConfirm.McpsRequest  == MCPS_CONFIRMED  )
01401                     {
01402                         if( fCtrl.Bits.Ack  == 1 )
01403                         {// Reset MacCommandsBufferIndex when we have received an ACK.
01404                             MacCommandsBufferIndex = 0;
01405                         }
01406                     }
01407                     else
01408                     {// Reset the variable if we have received any valid frame.
01409                         MacCommandsBufferIndex = 0;
01410                     }
01411 
01412                     // Process payload and MAC commands
01413                     if( ( ( size - 4 ) - appPayloadStartIndex ) > 0 )
01414                     {
01415                         port = payload[appPayloadStartIndex++];
01416                         frameLen = ( size - 4 ) - appPayloadStartIndex;
01417 
01418                         McpsIndication.Port  = port;
01419 
01420                         if( port == 0 )
01421                         {
01422                             // Only allow frames which do not have fOpts
01423                             if( fCtrl.Bits.FOptsLen  == 0 )
01424                             {
01425                                 LoRaMacPayloadDecrypt ( payload + appPayloadStartIndex,
01426                                                        frameLen,
01427                                                        nwkSKey,
01428                                                        address,
01429                                                        DOWN_LINK,
01430                                                        downLinkCounter,
01431                                                        LoRaMacRxPayload );
01432 
01433                                 // Decode frame payload MAC commands
01434                                 ProcessMacCommands( LoRaMacRxPayload, 0, frameLen, snr );
01435                             }
01436                             else
01437                             {
01438                                 skipIndication = true;
01439                             }
01440                         }
01441                         else
01442                         {
01443                             if( fCtrl.Bits.FOptsLen  > 0 )
01444                             {
01445                                 // Decode Options field MAC commands. Omit the fPort.
01446                                 ProcessMacCommands( payload, 8, appPayloadStartIndex - 1, snr );
01447                             }
01448 
01449                             LoRaMacPayloadDecrypt ( payload + appPayloadStartIndex,
01450                                                    frameLen,
01451                                                    appSKey,
01452                                                    address,
01453                                                    DOWN_LINK,
01454                                                    downLinkCounter,
01455                                                    LoRaMacRxPayload );
01456 
01457                             if( skipIndication == false )
01458                             {
01459                                 McpsIndication.Buffer  = LoRaMacRxPayload;
01460                                 McpsIndication.BufferSize  = frameLen;
01461                                 McpsIndication.RxData  = true;
01462                             }
01463                         }
01464                     }
01465                     else
01466                     {
01467                         if( fCtrl.Bits.FOptsLen  > 0 )
01468                         {
01469                             // Decode Options field MAC commands
01470                             ProcessMacCommands( payload, 8, appPayloadStartIndex, snr );
01471                         }
01472                     }
01473 
01474                     if( skipIndication == false )
01475                     {
01476                         // Check if the frame is an acknowledgement
01477                         if( fCtrl.Bits.Ack  == 1 )
01478                         {
01479                             McpsConfirm.AckReceived  = true;
01480                             McpsIndication.AckReceived  = true;
01481 
01482                             // Stop the AckTimeout timer as no more retransmissions
01483                             // are needed.
01484                             TimerStop( &AckTimeoutTimer );
01485                         }
01486                         else
01487                         {
01488                             McpsConfirm.AckReceived  = false;
01489 
01490                             if( AckTimeoutRetriesCounter > AckTimeoutRetries )
01491                             {
01492                                 // Stop the AckTimeout timer as no more retransmissions
01493                                 // are needed.
01494                                 TimerStop( &AckTimeoutTimer );
01495                             }
01496                         }
01497                     }
01498                     // Provide always an indication, skip the callback to the user application,
01499                     // in case of a confirmed downlink retransmission.
01500                     LoRaMacFlags.Bits.McpsInd  = 1;
01501                     LoRaMacFlags.Bits.McpsIndSkip  = skipIndication;
01502                 }
01503                 else
01504                 {
01505                     McpsIndication.Status  = LORAMAC_EVENT_INFO_STATUS_MIC_FAIL ;
01506 
01507                     PrepareRxDoneAbort( );
01508                     return;
01509                 }
01510             }
01511             break;
01512         case FRAME_TYPE_PROPRIETARY :
01513             {
01514                 memcpy1( LoRaMacRxPayload, &payload[pktHeaderLen], size );
01515 
01516                 McpsIndication.McpsIndication  = MCPS_PROPRIETARY ;
01517                 McpsIndication.Status  = LORAMAC_EVENT_INFO_STATUS_OK ;
01518                 McpsIndication.Buffer  = LoRaMacRxPayload;
01519                 McpsIndication.BufferSize  = size - pktHeaderLen;
01520 
01521                 LoRaMacFlags.Bits.McpsInd  = 1;
01522                 break;
01523             }
01524         default:
01525             McpsIndication.Status  = LORAMAC_EVENT_INFO_STATUS_ERROR ;
01526             PrepareRxDoneAbort( );
01527             break;
01528     }
01529     LoRaMacFlags.Bits.MacDone  = 1;
01530 
01531     // Trig OnMacCheckTimerEvent call as soon as possible
01532     TimerSetValue( &MacStateCheckTimer, 1 );
01533     TimerStart( &MacStateCheckTimer );
01534 }
01535 
01536 static void OnRadioTxTimeout( void )
01537 {
01538     if( LoRaMacDeviceClass != CLASS_C  )
01539     {
01540         Radio.Sleep( );
01541     }
01542     else
01543     {
01544         OnRxWindow2TimerEvent( );
01545     }
01546 
01547     McpsConfirm.Status  = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT ;
01548     MlmeConfirm.Status  = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT ;
01549     LoRaMacFlags.Bits.MacDone  = 1;
01550 }
01551 
01552 static void OnRadioRxError( void )
01553 {
01554     if( LoRaMacDeviceClass != CLASS_C  )
01555     {
01556         Radio.Sleep( );
01557     }
01558     else
01559     {
01560         OnRxWindow2TimerEvent( );
01561     }
01562 
01563     if( RxSlot == 0 )
01564     {
01565         if( NodeAckRequested == true )
01566         {
01567             McpsConfirm.Status  = LORAMAC_EVENT_INFO_STATUS_RX1_ERROR ;
01568         }
01569         MlmeConfirm.Status  = LORAMAC_EVENT_INFO_STATUS_RX1_ERROR ;
01570 
01571         if( TimerGetElapsedTime( AggregatedLastTxDoneTime ) >= RxWindow2Delay )
01572         {
01573             LoRaMacFlags.Bits.MacDone  = 1;
01574         }
01575     }
01576     else
01577     {
01578         if( NodeAckRequested == true )
01579         {
01580             McpsConfirm.Status  = LORAMAC_EVENT_INFO_STATUS_RX2_ERROR ;
01581         }
01582         MlmeConfirm.Status  = LORAMAC_EVENT_INFO_STATUS_RX2_ERROR ;
01583         LoRaMacFlags.Bits.MacDone  = 1;
01584     }
01585 }
01586 
01587 static void OnRadioRxTimeout( void )
01588 {
01589     if( LoRaMacDeviceClass != CLASS_C  )
01590     {
01591         Radio.Sleep( );
01592     }
01593     else
01594     {
01595         OnRxWindow2TimerEvent( );
01596     }
01597 
01598     if( RxSlot == 1 )
01599     {
01600         if( NodeAckRequested == true )
01601         {
01602             McpsConfirm.Status  = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT ;
01603         }
01604         MlmeConfirm.Status  = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT ;
01605         LoRaMacFlags.Bits.MacDone  = 1;
01606     }
01607 }
01608 
01609 static void OnMacStateCheckTimerEvent( void )
01610 {
01611     TimerStop( &MacStateCheckTimer );
01612     bool txTimeout = false;
01613 
01614     if( LoRaMacFlags.Bits.MacDone  == 1 )
01615     {
01616         if( ( LoRaMacState & LORAMAC_RX_ABORT ) == LORAMAC_RX_ABORT )
01617         {
01618             LoRaMacState &= ~LORAMAC_RX_ABORT;
01619             LoRaMacState &= ~LORAMAC_TX_RUNNING;
01620         }
01621 
01622         if( ( LoRaMacFlags.Bits.MlmeReq  == 1 ) || ( ( LoRaMacFlags.Bits.McpsReq  == 1 ) ) )
01623         {
01624             if( ( McpsConfirm.Status  == LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT  ) ||
01625                 ( MlmeConfirm.Status  == LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT  ) )
01626             {
01627                 // Stop transmit cycle due to tx timeout.
01628                 LoRaMacState &= ~LORAMAC_TX_RUNNING;
01629                 MacCommandsBufferIndex = 0;
01630                 McpsConfirm.NbRetries  = AckTimeoutRetriesCounter;
01631                 McpsConfirm.AckReceived  = false;
01632                 McpsConfirm.TxTimeOnAir  = 0;
01633                 txTimeout = true;
01634             }
01635         }
01636 
01637         if( ( NodeAckRequested == false ) && ( txTimeout == false ) )
01638         {
01639             if( ( LoRaMacFlags.Bits.MlmeReq  == 1 ) || ( ( LoRaMacFlags.Bits.McpsReq  == 1 ) ) )
01640             {
01641                 if( ( LoRaMacFlags.Bits.MlmeReq  == 1 ) && ( MlmeConfirm.MlmeRequest  == MLME_JOIN  ) )
01642                 {// Procedure for the join request
01643                     MlmeConfirm.NbRetries  = JoinRequestTrials;
01644 
01645                     if( MlmeConfirm.Status  == LORAMAC_EVENT_INFO_STATUS_OK  )
01646                     {// Node joined successfully
01647                         UpLinkCounter = 0;
01648                         ChannelsNbRepCounter = 0;
01649                         LoRaMacState &= ~LORAMAC_TX_RUNNING;
01650                     }
01651                     else
01652                     {
01653                         if( JoinRequestTrials >= MaxJoinRequestTrials )
01654                         {
01655                             LoRaMacState &= ~LORAMAC_TX_RUNNING;
01656                         }
01657                         else
01658                         {
01659                             LoRaMacFlags.Bits.MacDone  = 0;
01660                             // Sends the same frame again
01661                             OnTxDelayedTimerEvent( );
01662                         }
01663                     }
01664                 }
01665                 else
01666                 {// Procedure for all other frames
01667                     if( ( ChannelsNbRepCounter >= LoRaMacParams.ChannelsNbRep  ) || ( LoRaMacFlags.Bits.McpsInd  == 1 ) )
01668                     {
01669                         if( LoRaMacFlags.Bits.McpsInd  == 0 )
01670                         {   // Maximum repititions without downlink. Reset MacCommandsBufferIndex. Increase ADR Ack counter.
01671                             // Only process the case when the MAC did not receive a downlink.
01672                             MacCommandsBufferIndex = 0;
01673                             AdrAckCounter++;
01674                         }
01675 
01676                         ChannelsNbRepCounter = 0;
01677 
01678                         if( IsUpLinkCounterFixed == false )
01679                         {
01680                             UpLinkCounter++;
01681                         }
01682 
01683                         LoRaMacState &= ~LORAMAC_TX_RUNNING;
01684                     }
01685                     else
01686                     {
01687                         LoRaMacFlags.Bits.MacDone  = 0;
01688                         // Sends the same frame again
01689                         OnTxDelayedTimerEvent( );
01690                     }
01691                 }
01692             }
01693         }
01694 
01695         if( LoRaMacFlags.Bits.McpsInd  == 1 )
01696         {// Procedure if we received a frame
01697             if( ( McpsConfirm.AckReceived  == true ) || ( AckTimeoutRetriesCounter > AckTimeoutRetries ) )
01698             {
01699                 AckTimeoutRetry = false;
01700                 NodeAckRequested = false;
01701                 if( IsUpLinkCounterFixed == false )
01702                 {
01703                     UpLinkCounter++;
01704                 }
01705                 McpsConfirm.NbRetries  = AckTimeoutRetriesCounter;
01706 
01707                 LoRaMacState &= ~LORAMAC_TX_RUNNING;
01708             }
01709         }
01710 
01711         if( ( AckTimeoutRetry == true ) && ( ( LoRaMacState & LORAMAC_TX_DELAYED ) == 0 ) )
01712         {// Retransmissions procedure for confirmed uplinks
01713             AckTimeoutRetry = false;
01714             if( ( AckTimeoutRetriesCounter < AckTimeoutRetries ) && ( AckTimeoutRetriesCounter <= MAX_ACK_RETRIES ) )
01715             {
01716                 AckTimeoutRetriesCounter++;
01717 
01718                 if( ( AckTimeoutRetriesCounter % 2 ) == 1 )
01719                 {
01720                     LoRaMacParams.ChannelsDatarate  = MAX( LoRaMacParams.ChannelsDatarate  - 1, LORAMAC_TX_MIN_DATARATE );
01721                 }
01722                 // Try to send the frame again
01723                 if( ScheduleTx( ) == LORAMAC_STATUS_OK  )
01724                 {
01725                     LoRaMacFlags.Bits.MacDone  = 0;
01726                 }
01727                 else
01728                 {
01729                     // The DR is not applicable for the payload size
01730                     McpsConfirm.Status  = LORAMAC_EVENT_INFO_STATUS_TX_DR_PAYLOAD_SIZE_ERROR ;
01731 
01732                     MacCommandsBufferIndex = 0;
01733                     LoRaMacState &= ~LORAMAC_TX_RUNNING;
01734                     NodeAckRequested = false;
01735                     McpsConfirm.AckReceived  = false;
01736                     McpsConfirm.NbRetries  = AckTimeoutRetriesCounter;
01737                     McpsConfirm.Datarate  = LoRaMacParams.ChannelsDatarate ;
01738                     if( IsUpLinkCounterFixed == false )
01739                     {
01740                         UpLinkCounter++;
01741                     }
01742                 }
01743             }
01744             else
01745             {
01746 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
01747                 // Re-enable default channels LC1, LC2, LC3
01748                 LoRaMacParams.ChannelsMask [0] = LoRaMacParams.ChannelsMask [0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) );
01749 #elif defined( USE_BAND_470 )
01750                 // Re-enable default channels
01751                 memcpy1( ( uint8_t* )LoRaMacParams.ChannelsMask , ( uint8_t* )LoRaMacParamsDefaults.ChannelsMask , sizeof( LoRaMacParams.ChannelsMask  ) );
01752 #elif defined( USE_BAND_915 )
01753                 // Re-enable default channels
01754                 memcpy1( ( uint8_t* )LoRaMacParams.ChannelsMask , ( uint8_t* )LoRaMacParamsDefaults.ChannelsMask , sizeof( LoRaMacParams.ChannelsMask  ) );
01755 #elif defined( USE_BAND_915_HYBRID )
01756                 // Re-enable default channels
01757                 ReenableChannels( LoRaMacParamsDefaults.ChannelsMask [4], LoRaMacParams.ChannelsMask  );
01758 #else
01759     #error "Please define a frequency band in the compiler options."
01760 #endif
01761                 LoRaMacState &= ~LORAMAC_TX_RUNNING;
01762 
01763                 MacCommandsBufferIndex = 0;
01764                 NodeAckRequested = false;
01765                 McpsConfirm.AckReceived  = false;
01766                 McpsConfirm.NbRetries  = AckTimeoutRetriesCounter;
01767                 if( IsUpLinkCounterFixed == false )
01768                 {
01769                     UpLinkCounter++;
01770                 }
01771             }
01772         }
01773     }
01774     // Handle reception for Class B and Class C
01775     if( ( LoRaMacState & LORAMAC_RX ) == LORAMAC_RX )
01776     {
01777         LoRaMacState &= ~LORAMAC_RX;
01778     }
01779     if( LoRaMacState == LORAMAC_IDLE )
01780     {
01781         if( LoRaMacFlags.Bits.McpsReq  == 1 )
01782         {
01783             LoRaMacPrimitives->MacMcpsConfirm( &McpsConfirm );
01784             LoRaMacFlags.Bits.McpsReq  = 0;
01785         }
01786 
01787         if( LoRaMacFlags.Bits.MlmeReq  == 1 )
01788         {
01789             LoRaMacPrimitives->MacMlmeConfirm( &MlmeConfirm );
01790             LoRaMacFlags.Bits.MlmeReq  = 0;
01791         }
01792 
01793         // Procedure done. Reset variables.
01794         LoRaMacFlags.Bits.MacDone  = 0;
01795     }
01796     else
01797     {
01798         // Operation not finished restart timer
01799         TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT );
01800         TimerStart( &MacStateCheckTimer );
01801     }
01802 
01803     if( LoRaMacFlags.Bits.McpsInd  == 1 )
01804     {
01805         if( LoRaMacDeviceClass == CLASS_C  )
01806         {// Activate RX2 window for Class C
01807             OnRxWindow2TimerEvent( );
01808         }
01809         if( LoRaMacFlags.Bits.McpsIndSkip  == 0 )
01810         {
01811             LoRaMacPrimitives->MacMcpsIndication( &McpsIndication );
01812         }
01813         LoRaMacFlags.Bits.McpsIndSkip  = 0;
01814         LoRaMacFlags.Bits.McpsInd  = 0;
01815     }
01816 }
01817 
01818 static void OnTxDelayedTimerEvent( void )
01819 {
01820     LoRaMacHeader_t  macHdr;
01821     LoRaMacFrameCtrl_t  fCtrl;
01822 
01823     TimerStop( &TxDelayedTimer );
01824     LoRaMacState &= ~LORAMAC_TX_DELAYED;
01825 
01826     if( ( LoRaMacFlags.Bits.MlmeReq  == 1 ) && ( MlmeConfirm.MlmeRequest  == MLME_JOIN  ) )
01827     {
01828         ResetMacParameters( );
01829         // Add a +1, since we start to count from 0
01830         LoRaMacParams.ChannelsDatarate  = AlternateDatarate( JoinRequestTrials + 1 );
01831 
01832         macHdr.Value  = 0;
01833         macHdr.Bits.MType  = FRAME_TYPE_JOIN_REQ ;
01834 
01835         fCtrl.Value  = 0;
01836         fCtrl.Bits.Adr  = AdrCtrlOn;
01837 
01838         /* In case of join request retransmissions, the stack must prepare
01839          * the frame again, because the network server keeps track of the random
01840          * LoRaMacDevNonce values to prevent reply attacks. */
01841         PrepareFrame( &macHdr, &fCtrl, 0, NULL, 0 );
01842     }
01843 
01844     ScheduleTx( );
01845 }
01846 
01847 static void OnRxWindow1TimerEvent( void )
01848 {
01849     TimerStop( &RxWindowTimer1 );
01850     RxSlot = 0;
01851 
01852     if( LoRaMacDeviceClass == CLASS_C  )
01853     {
01854         Radio.Standby( );
01855     }
01856 
01857 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
01858     RxWindowSetup( Channels[Channel].Frequency, RxWindowsParams[0].Datarate, RxWindowsParams[0].Bandwidth, RxWindowsParams[0].RxWindowTimeout, false );
01859 #elif defined( USE_BAND_470 )
01860     RxWindowSetup( LORAMAC_FIRST_RX1_CHANNEL + ( Channel % 48 ) * LORAMAC_STEPWIDTH_RX1_CHANNEL, RxWindowsParams[0].Datarate, RxWindowsParams[0].Bandwidth, RxWindowsParams[0].RxWindowTimeout, false );
01861 #elif ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) )
01862     RxWindowSetup( LORAMAC_FIRST_RX1_CHANNEL + ( Channel % 8 ) * LORAMAC_STEPWIDTH_RX1_CHANNEL, RxWindowsParams[0].Datarate, RxWindowsParams[0].Bandwidth, RxWindowsParams[0].RxWindowTimeout, false );
01863 #else
01864     #error "Please define a frequency band in the compiler options."
01865 #endif
01866 }
01867 
01868 static void OnRxWindow2TimerEvent( void )
01869 {
01870     bool rxContinuousMode = false;
01871 
01872     TimerStop( &RxWindowTimer2 );
01873 
01874     if( LoRaMacDeviceClass == CLASS_C  )
01875     {
01876         rxContinuousMode = true;
01877     }
01878     if( RxWindowSetup( LoRaMacParams.Rx2Channel .Frequency , RxWindowsParams[1].Datarate, RxWindowsParams[1].Bandwidth, RxWindowsParams[1].RxWindowTimeout, rxContinuousMode ) == true )
01879     {
01880         RxSlot = 1;
01881     }
01882 }
01883 
01884 static void OnAckTimeoutTimerEvent( void )
01885 {
01886     TimerStop( &AckTimeoutTimer );
01887 
01888     if( NodeAckRequested == true )
01889     {
01890         AckTimeoutRetry = true;
01891         LoRaMacState &= ~LORAMAC_ACK_REQ;
01892     }
01893     if( LoRaMacDeviceClass == CLASS_C  )
01894     {
01895         LoRaMacFlags.Bits.MacDone  = 1;
01896     }
01897 }
01898 
01899 static bool SetNextChannel( TimerTime_t* time )
01900 {
01901     uint8_t nbEnabledChannels = 0;
01902     uint8_t delayTx = 0;
01903     uint8_t enabledChannels[LORA_MAX_NB_CHANNELS];
01904     TimerTime_t nextTxDelay = ( TimerTime_t )( -1 );
01905 
01906     memset1( enabledChannels, 0, LORA_MAX_NB_CHANNELS );
01907 
01908 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
01909     if( CountNbEnabled125kHzChannels( ChannelsMaskRemaining ) == 0 )
01910     { // Restore default channels
01911         memcpy1( ( uint8_t* ) ChannelsMaskRemaining, ( uint8_t* ) LoRaMacParams.ChannelsMask , 8 );
01912     }
01913     if( ( LoRaMacParams.ChannelsDatarate  >= DR_4 ) && ( ( ChannelsMaskRemaining[4] & 0x00FF ) == 0 ) )
01914     { // Make sure, that the channels are activated
01915         ChannelsMaskRemaining[4] = LoRaMacParams.ChannelsMask [4];
01916     }
01917 #elif defined( USE_BAND_470 )
01918     if( ( CountBits( LoRaMacParams.ChannelsMask [0], 16 ) == 0 ) &&
01919         ( CountBits( LoRaMacParams.ChannelsMask [1], 16 ) == 0 ) &&
01920         ( CountBits( LoRaMacParams.ChannelsMask [2], 16 ) == 0 ) &&
01921         ( CountBits( LoRaMacParams.ChannelsMask [3], 16 ) == 0 ) &&
01922         ( CountBits( LoRaMacParams.ChannelsMask [4], 16 ) == 0 ) &&
01923         ( CountBits( LoRaMacParams.ChannelsMask [5], 16 ) == 0 ) )
01924     {
01925         memcpy1( ( uint8_t* )LoRaMacParams.ChannelsMask , ( uint8_t* )LoRaMacParamsDefaults.ChannelsMask , sizeof( LoRaMacParams.ChannelsMask  ) );
01926     }
01927 #else
01928     if( CountBits( LoRaMacParams.ChannelsMask [0], 16 ) == 0 )
01929     {
01930         // Re-enable default channels, if no channel is enabled
01931         LoRaMacParams.ChannelsMask [0] = LoRaMacParams.ChannelsMask [0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) );
01932     }
01933 #endif
01934 
01935     // Update Aggregated duty cycle
01936     if( AggregatedTimeOff <= TimerGetElapsedTime( AggregatedLastTxDoneTime ) )
01937     {
01938         AggregatedTimeOff = 0;
01939 
01940         // Update bands Time OFF
01941         for( uint8_t i = 0; i < LORA_MAX_NB_BANDS; i++ )
01942         {
01943             if( ( IsLoRaMacNetworkJoined == false ) || ( DutyCycleOn == true ) )
01944             {
01945                 if( Bands[i].TimeOff <= TimerGetElapsedTime( Bands[i].LastTxDoneTime ) )
01946                 {
01947                     Bands[i].TimeOff  = 0;
01948                 }
01949                 if( Bands[i].TimeOff != 0 )
01950                 {
01951                     nextTxDelay = MIN( Bands[i].TimeOff - TimerGetElapsedTime( Bands[i].LastTxDoneTime ), nextTxDelay );
01952                 }
01953             }
01954             else
01955             {
01956                 if( DutyCycleOn == false )
01957                 {
01958                     Bands[i].TimeOff  = 0;
01959                 }
01960             }
01961         }
01962 
01963         // Search how many channels are enabled
01964         for( uint8_t i = 0, k = 0; i < LORA_MAX_NB_CHANNELS; i += 16, k++ )
01965         {
01966             for( uint8_t j = 0; j < 16; j++ )
01967             {
01968 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
01969                 if( ( ChannelsMaskRemaining[k] & ( 1 << j ) ) != 0 )
01970 #else
01971                 if( ( LoRaMacParams.ChannelsMask [k] & ( 1 << j ) ) != 0 )
01972 #endif
01973                 {
01974                     if( Channels[i + j].Frequency == 0 )
01975                     { // Check if the channel is enabled
01976                         continue;
01977                     }
01978 #if defined( USE_BAND_868 ) || defined( USE_BAND_433 ) || defined( USE_BAND_780 )
01979                     if( IsLoRaMacNetworkJoined == false )
01980                     {
01981                         if( ( JOIN_CHANNELS & ( 1 << j ) ) == 0 )
01982                         {
01983                             continue;
01984                         }
01985                     }
01986 #endif
01987                     if( ( ( Channels[i + j].DrRange.Fields.Min <= LoRaMacParams.ChannelsDatarate  ) &&
01988                           ( LoRaMacParams.ChannelsDatarate  <= Channels[i + j].DrRange .Fields.Max  ) ) == false )
01989                     { // Check if the current channel selection supports the given datarate
01990                         continue;
01991                     }
01992                     if( Bands[Channels[i + j].Band].TimeOff > 0 )
01993                     { // Check if the band is available for transmission
01994                         delayTx++;
01995                         continue;
01996                     }
01997                     enabledChannels[nbEnabledChannels++] = i + j;
01998                 }
01999             }
02000         }
02001     }
02002     else
02003     {
02004         delayTx++;
02005         nextTxDelay = AggregatedTimeOff - TimerGetElapsedTime( AggregatedLastTxDoneTime );
02006     }
02007 
02008     if( nbEnabledChannels > 0 )
02009     {
02010         Channel = enabledChannels[randr( 0, nbEnabledChannels - 1 )];
02011 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
02012         if( Channel < ( LORA_MAX_NB_CHANNELS - 8 ) )
02013         {
02014             DisableChannelInMask( Channel, ChannelsMaskRemaining );
02015         }
02016 #endif
02017         *time = 0;
02018         return true;
02019     }
02020     else
02021     {
02022         if( delayTx > 0 )
02023         {
02024             // Delay transmission due to AggregatedTimeOff or to a band time off
02025             *time = nextTxDelay;
02026             return true;
02027         }
02028         // Datarate not supported by any channel
02029         *time = 0;
02030         return false;
02031     }
02032 }
02033 
02034 static bool RxWindowSetup( uint32_t freq, int8_t datarate, uint32_t bandwidth, uint16_t timeout, bool rxContinuous )
02035 {
02036     uint8_t downlinkDatarate = Datarates[datarate];
02037     RadioModems_t modem;
02038 
02039     if( Radio.GetStatus( ) == RF_IDLE )
02040     {
02041         Radio.SetChannel( freq );
02042 
02043         // Store downlink datarate
02044         McpsIndication.RxDatarate  = ( uint8_t ) datarate;
02045 
02046 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
02047         if( datarate == DR_7 )
02048         {
02049             modem = MODEM_FSK;
02050             Radio.SetRxConfig( modem, 50e3, downlinkDatarate * 1e3, 0, 83.333e3, 5, timeout, false, 0, true, 0, 0, false, rxContinuous );
02051         }
02052         else
02053         {
02054             modem = MODEM_LORA;
02055             Radio.SetRxConfig( modem, bandwidth, downlinkDatarate, 1, 0, 8, timeout, false, 0, false, 0, 0, true, rxContinuous );
02056         }
02057 #elif defined( USE_BAND_470 ) || defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
02058         modem = MODEM_LORA;
02059         Radio.SetRxConfig( modem, bandwidth, downlinkDatarate, 1, 0, 8, timeout, false, 0, false, 0, 0, true, rxContinuous );
02060 #endif
02061 
02062         if( RepeaterSupport == true )
02063         {
02064             Radio.SetMaxPayloadLength( modem, MaxPayloadOfDatarateRepeater[datarate] + LORA_MAC_FRMPAYLOAD_OVERHEAD );
02065         }
02066         else
02067         {
02068             Radio.SetMaxPayloadLength( modem, MaxPayloadOfDatarate[datarate] + LORA_MAC_FRMPAYLOAD_OVERHEAD );
02069         }
02070 
02071         if( rxContinuous == false )
02072         {
02073             Radio.Rx( LoRaMacParams.MaxRxWindow  );
02074         }
02075         else
02076         {
02077             Radio.Rx( 0 ); // Continuous mode
02078         }
02079         return true;
02080     }
02081     return false;
02082 }
02083 
02084 static bool Rx2FreqInRange( uint32_t freq )
02085 {
02086 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
02087     if( Radio.CheckRfFrequency( freq ) == true )
02088 #elif defined( USE_BAND_470 ) || defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
02089     if( ( Radio.CheckRfFrequency( freq ) == true ) &&
02090         ( freq >= LORAMAC_FIRST_RX1_CHANNEL ) &&
02091         ( freq <= LORAMAC_LAST_RX1_CHANNEL ) &&
02092         ( ( ( freq - ( uint32_t ) LORAMAC_FIRST_RX1_CHANNEL ) % ( uint32_t ) LORAMAC_STEPWIDTH_RX1_CHANNEL ) == 0 ) )
02093 #endif
02094     {
02095         return true;
02096     }
02097     return false;
02098 }
02099 
02100 static bool ValidatePayloadLength( uint8_t lenN, int8_t datarate, uint8_t fOptsLen )
02101 {
02102     uint16_t maxN = 0;
02103     uint16_t payloadSize = 0;
02104 
02105     // Get the maximum payload length
02106     if( RepeaterSupport == true )
02107     {
02108         maxN = MaxPayloadOfDatarateRepeater[datarate];
02109     }
02110     else
02111     {
02112         maxN = MaxPayloadOfDatarate[datarate];
02113     }
02114 
02115     // Calculate the resulting payload size
02116     payloadSize = ( lenN + fOptsLen );
02117 
02118     // Validation of the application payload size
02119     if( ( payloadSize <= maxN ) && ( payloadSize <= LORAMAC_PHY_MAXPAYLOAD ) )
02120     {
02121         return true;
02122     }
02123     return false;
02124 }
02125 
02126 static uint8_t CountBits( uint16_t mask, uint8_t nbBits )
02127 {
02128     uint8_t nbActiveBits = 0;
02129 
02130     for( uint8_t j = 0; j < nbBits; j++ )
02131     {
02132         if( ( mask & ( 1 << j ) ) == ( 1 << j ) )
02133         {
02134             nbActiveBits++;
02135         }
02136     }
02137     return nbActiveBits;
02138 }
02139 
02140 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
02141 static uint8_t CountNbEnabled125kHzChannels( uint16_t *channelsMask )
02142 {
02143     uint8_t nb125kHzChannels = 0;
02144 
02145     for( uint8_t i = 0, k = 0; i < LORA_MAX_NB_CHANNELS - 8; i += 16, k++ )
02146     {
02147         nb125kHzChannels += CountBits( channelsMask[k], 16 );
02148     }
02149 
02150     return nb125kHzChannels;
02151 }
02152 
02153 #if defined( USE_BAND_915_HYBRID )
02154 static void ReenableChannels( uint16_t mask, uint16_t* channelsMask )
02155 {
02156     uint16_t blockMask = mask;
02157 
02158     for( uint8_t i = 0, j = 0; i < 4; i++, j += 2 )
02159     {
02160         channelsMask[i] = 0;
02161         if( ( blockMask & ( 1 << j ) ) != 0 )
02162         {
02163             channelsMask[i] |= 0x00FF;
02164         }
02165         if( ( blockMask & ( 1 << ( j + 1 ) ) ) != 0 )
02166         {
02167             channelsMask[i] |= 0xFF00;
02168         }
02169     }
02170     channelsMask[4] = blockMask;
02171     channelsMask[5] = 0x0000;
02172 }
02173 
02174 static bool ValidateChannelMask( uint16_t* channelsMask )
02175 {
02176     bool chanMaskState = false;
02177     uint16_t block1 = 0;
02178     uint16_t block2 = 0;
02179     uint8_t index = 0;
02180 
02181     for( uint8_t i = 0; i < 4; i++ )
02182     {
02183         block1 = channelsMask[i] & 0x00FF;
02184         block2 = channelsMask[i] & 0xFF00;
02185 
02186         if( ( CountBits( block1, 16 ) > 5 ) && ( chanMaskState == false ) )
02187         {
02188             channelsMask[i] &= block1;
02189             channelsMask[4] = 1 << ( i * 2 );
02190             chanMaskState = true;
02191             index = i;
02192         }
02193         else if( ( CountBits( block2, 16 ) > 5 ) && ( chanMaskState == false ) )
02194         {
02195             channelsMask[i] &= block2;
02196             channelsMask[4] = 1 << ( i * 2 + 1 );
02197             chanMaskState = true;
02198             index = i;
02199         }
02200     }
02201 
02202     // Do only change the channel mask, if we have found a valid block.
02203     if( chanMaskState == true )
02204     {
02205         for( uint8_t i = 0; i < 4; i++ )
02206         {
02207             if( i != index )
02208             {
02209                 channelsMask[i] = 0;
02210             }
02211         }
02212     }
02213     return chanMaskState;
02214 }
02215 #endif
02216 #endif
02217 
02218 static bool ValidateDatarate( int8_t datarate, uint16_t* channelsMask )
02219 {
02220     if( ValueInRange( datarate, LORAMAC_TX_MIN_DATARATE, LORAMAC_TX_MAX_DATARATE ) == false )
02221     {
02222         return false;
02223     }
02224     for( uint8_t i = 0, k = 0; i < LORA_MAX_NB_CHANNELS; i += 16, k++ )
02225     {
02226         for( uint8_t j = 0; j < 16; j++ )
02227         {
02228             if( ( ( channelsMask[k] & ( 1 << j ) ) != 0 ) )
02229             {// Check datarate validity for enabled channels
02230                 if( ValueInRange( datarate, Channels[i + j].DrRange.Fields.Min, Channels[i + j].DrRange .Fields.Max  ) == true )
02231                 {
02232                     // At least 1 channel has been found we can return OK.
02233                     return true;
02234                 }
02235             }
02236         }
02237     }
02238     return false;
02239 }
02240 
02241 static int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower )
02242 {
02243     int8_t resultTxPower = txPower;
02244 
02245     // Limit tx power to the band max
02246     resultTxPower =  MAX( txPower, maxBandTxPower );
02247 
02248 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
02249     if( ( LoRaMacParams.ChannelsDatarate  == DR_4 ) ||
02250         ( ( LoRaMacParams.ChannelsDatarate  >= DR_8 ) && ( LoRaMacParams.ChannelsDatarate  <= DR_13 ) ) )
02251     {// Limit tx power to max 26dBm
02252         resultTxPower =  MAX( txPower, TX_POWER_26_DBM );
02253     }
02254     else
02255     {
02256         if( CountNbEnabled125kHzChannels( LoRaMacParams.ChannelsMask  ) < 50 )
02257         {// Limit tx power to max 21dBm
02258             resultTxPower = MAX( txPower, TX_POWER_20_DBM );
02259         }
02260     }
02261 #endif
02262     return resultTxPower;
02263 }
02264 
02265 static bool ValueInRange( int8_t value, int8_t min, int8_t max )
02266 {
02267     if( ( value >= min ) && ( value <= max ) )
02268     {
02269         return true;
02270     }
02271     return false;
02272 }
02273 
02274 static bool DisableChannelInMask( uint8_t id, uint16_t* mask )
02275 {
02276     uint8_t index = 0;
02277     index = id / 16;
02278 
02279     if( ( index > 4 ) || ( id >= LORA_MAX_NB_CHANNELS ) )
02280     {
02281         return false;
02282     }
02283 
02284     // Deactivate channel
02285     mask[index] &= ~( 1 << ( id % 16 ) );
02286 
02287     return true;
02288 }
02289 
02290 static bool AdrNextDr( bool adrEnabled, bool updateChannelMask, int8_t* datarateOut )
02291 {
02292     bool adrAckReq = false;
02293     int8_t datarate = LoRaMacParams.ChannelsDatarate ;
02294 
02295     if( adrEnabled == true )
02296     {
02297         if( datarate == LORAMAC_TX_MIN_DATARATE )
02298         {
02299             AdrAckCounter = 0;
02300             adrAckReq = false;
02301         }
02302         else
02303         {
02304             if( AdrAckCounter >= ADR_ACK_LIMIT )
02305             {
02306                 adrAckReq = true;
02307                 LoRaMacParams.ChannelsTxPower  = LORAMAC_MAX_TX_POWER;
02308             }
02309             else
02310             {
02311                 adrAckReq = false;
02312             }
02313             if( AdrAckCounter >= ( ADR_ACK_LIMIT + ADR_ACK_DELAY ) )
02314             {
02315                 if( ( AdrAckCounter % ADR_ACK_DELAY ) == 1 )
02316                 {
02317 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
02318                     if( datarate > LORAMAC_TX_MIN_DATARATE )
02319                     {
02320                         datarate--;
02321                     }
02322                     if( datarate == LORAMAC_TX_MIN_DATARATE )
02323                     {
02324                         if( updateChannelMask == true )
02325                         {
02326                             // Re-enable default channels LC1, LC2, LC3
02327                             LoRaMacParams.ChannelsMask [0] = LoRaMacParams.ChannelsMask [0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) );
02328                         }
02329                     }
02330 #elif defined( USE_BAND_470 )
02331                     if( datarate > LORAMAC_TX_MIN_DATARATE )
02332                     {
02333                         datarate--;
02334                     }
02335                     if( datarate == LORAMAC_TX_MIN_DATARATE )
02336                     {
02337                         if( updateChannelMask == true )
02338                         {
02339                             // Re-enable default channels
02340                             memcpy1( ( uint8_t* )LoRaMacParams.ChannelsMask , ( uint8_t* )LoRaMacParamsDefaults.ChannelsMask , sizeof( LoRaMacParams.ChannelsMask  ) );
02341                         }
02342                     }
02343 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
02344                     if( ( datarate > LORAMAC_TX_MIN_DATARATE ) && ( datarate == DR_8 ) )
02345                     {
02346                         datarate = DR_4;
02347                     }
02348                     else if( datarate > LORAMAC_TX_MIN_DATARATE )
02349                     {
02350                         datarate--;
02351                     }
02352                     if( datarate == LORAMAC_TX_MIN_DATARATE )
02353                     {
02354                         if( updateChannelMask == true )
02355                         {
02356 #if defined( USE_BAND_915 )
02357                             // Re-enable default channels
02358                             memcpy1( ( uint8_t* )LoRaMacParams.ChannelsMask , ( uint8_t* )LoRaMacParamsDefaults.ChannelsMask , sizeof( LoRaMacParams.ChannelsMask  ) );
02359 #else // defined( USE_BAND_915_HYBRID )
02360                             // Re-enable default channels
02361                             ReenableChannels( LoRaMacParamsDefaults.ChannelsMask [4], LoRaMacParams.ChannelsMask  );
02362 #endif
02363                         }
02364                     }
02365 #else
02366 #error "Please define a frequency band in the compiler options."
02367 #endif
02368                 }
02369             }
02370         }
02371     }
02372 
02373     *datarateOut = datarate;
02374 
02375     return adrAckReq;
02376 }
02377 
02378 static LoRaMacStatus_t  AddMacCommand( uint8_t cmd, uint8_t p1, uint8_t p2 )
02379 {
02380     LoRaMacStatus_t  status = LORAMAC_STATUS_BUSY ;
02381     // The maximum buffer length must take MAC commands to re-send into account.
02382     uint8_t bufLen = LORA_MAC_COMMAND_MAX_LENGTH - MacCommandsBufferToRepeatIndex;
02383 
02384     switch( cmd )
02385     {
02386         case MOTE_MAC_LINK_CHECK_REQ :
02387             if( MacCommandsBufferIndex < bufLen )
02388             {
02389                 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
02390                 // No payload for this command
02391                 status = LORAMAC_STATUS_OK ;
02392             }
02393             break;
02394         case MOTE_MAC_LINK_ADR_ANS :
02395             if( MacCommandsBufferIndex < ( bufLen - 1 ) )
02396             {
02397                 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
02398                 // Margin
02399                 MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
02400                 status = LORAMAC_STATUS_OK ;
02401             }
02402             break;
02403         case MOTE_MAC_DUTY_CYCLE_ANS :
02404             if( MacCommandsBufferIndex < bufLen )
02405             {
02406                 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
02407                 // No payload for this answer
02408                 status = LORAMAC_STATUS_OK ;
02409             }
02410             break;
02411         case MOTE_MAC_RX_PARAM_SETUP_ANS :
02412             if( MacCommandsBufferIndex < ( bufLen - 1 ) )
02413             {
02414                 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
02415                 // Status: Datarate ACK, Channel ACK
02416                 MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
02417                 status = LORAMAC_STATUS_OK ;
02418             }
02419             break;
02420         case MOTE_MAC_DEV_STATUS_ANS :
02421             if( MacCommandsBufferIndex < ( bufLen - 2 ) )
02422             {
02423                 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
02424                 // 1st byte Battery
02425                 // 2nd byte Margin
02426                 MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
02427                 MacCommandsBuffer[MacCommandsBufferIndex++] = p2;
02428                 status = LORAMAC_STATUS_OK ;
02429             }
02430             break;
02431         case MOTE_MAC_NEW_CHANNEL_ANS :
02432             if( MacCommandsBufferIndex < ( bufLen - 1 ) )
02433             {
02434                 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
02435                 // Status: Datarate range OK, Channel frequency OK
02436                 MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
02437                 status = LORAMAC_STATUS_OK ;
02438             }
02439             break;
02440         case MOTE_MAC_RX_TIMING_SETUP_ANS :
02441             if( MacCommandsBufferIndex < bufLen )
02442             {
02443                 MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
02444                 // No payload for this answer
02445                 status = LORAMAC_STATUS_OK ;
02446             }
02447             break;
02448         default:
02449             return LORAMAC_STATUS_SERVICE_UNKNOWN ;
02450     }
02451     if( status == LORAMAC_STATUS_OK  )
02452     {
02453         MacCommandsInNextTx = true;
02454     }
02455     return status;
02456 }
02457 
02458 static uint8_t ParseMacCommandsToRepeat( uint8_t* cmdBufIn, uint8_t length, uint8_t* cmdBufOut )
02459 {
02460     uint8_t i = 0;
02461     uint8_t cmdCount = 0;
02462 
02463     if( ( cmdBufIn == NULL ) || ( cmdBufOut == NULL ) )
02464     {
02465         return 0;
02466     }
02467 
02468     for( i = 0; i < length; i++ )
02469     {
02470         switch( cmdBufIn[i] )
02471         {
02472             // STICKY
02473             case MOTE_MAC_RX_PARAM_SETUP_ANS :
02474             {
02475                 cmdBufOut[cmdCount++] = cmdBufIn[i++];
02476                 cmdBufOut[cmdCount++] = cmdBufIn[i];
02477                 break;
02478             }
02479             case MOTE_MAC_RX_TIMING_SETUP_ANS :
02480             {
02481                 cmdBufOut[cmdCount++] = cmdBufIn[i];
02482                 break;
02483             }
02484             // NON-STICKY
02485             case MOTE_MAC_DEV_STATUS_ANS :
02486             { // 2 bytes payload
02487                 i += 2;
02488                 break;
02489             }
02490             case MOTE_MAC_LINK_ADR_ANS :
02491             case MOTE_MAC_NEW_CHANNEL_ANS :
02492             { // 1 byte payload
02493                 i++;
02494                 break;
02495             }
02496             case MOTE_MAC_DUTY_CYCLE_ANS :
02497             case MOTE_MAC_LINK_CHECK_REQ :
02498             { // 0 byte payload
02499                 break;
02500             }
02501             default:
02502                 break;
02503         }
02504     }
02505 
02506     return cmdCount;
02507 }
02508 
02509 static void ProcessMacCommands( uint8_t *payload, uint8_t macIndex, uint8_t commandsSize, uint8_t snr )
02510 {
02511     while( macIndex < commandsSize )
02512     {
02513         // Decode Frame MAC commands
02514         switch( payload[macIndex++] )
02515         {
02516             case SRV_MAC_LINK_CHECK_ANS :
02517                 MlmeConfirm.Status  = LORAMAC_EVENT_INFO_STATUS_OK ;
02518                 MlmeConfirm.DemodMargin  = payload[macIndex++];
02519                 MlmeConfirm.NbGateways  = payload[macIndex++];
02520                 break;
02521             case SRV_MAC_LINK_ADR_REQ :
02522                 {
02523                     uint8_t i;
02524                     uint8_t status = 0x07;
02525                     uint16_t chMask;
02526                     int8_t txPower = 0;
02527                     int8_t datarate = 0;
02528                     uint8_t nbRep = 0;
02529                     uint8_t chMaskCntl = 0;
02530                     uint16_t channelsMask[6] = { 0, 0, 0, 0, 0, 0 };
02531 
02532                     // Initialize local copy of the channels mask array
02533                     for( i = 0; i < 6; i++ )
02534                     {
02535                         channelsMask[i] = LoRaMacParams.ChannelsMask [i];
02536                     }
02537                     datarate = payload[macIndex++];
02538                     txPower = datarate & 0x0F;
02539                     datarate = ( datarate >> 4 ) & 0x0F;
02540 
02541                     if( ( AdrCtrlOn == false ) &&
02542                         ( ( LoRaMacParams.ChannelsDatarate  != datarate ) || ( LoRaMacParams.ChannelsTxPower  != txPower ) ) )
02543                     { // ADR disabled don't handle ADR requests if server tries to change datarate or txpower
02544                         // Answer the server with fail status
02545                         // Power ACK     = 0
02546                         // Data rate ACK = 0
02547                         // Channel mask  = 0
02548                         AddMacCommand( MOTE_MAC_LINK_ADR_ANS , 0, 0 );
02549                         macIndex += 3;  // Skip over the remaining bytes of the request
02550                         break;
02551                     }
02552                     chMask = ( uint16_t )payload[macIndex++];
02553                     chMask |= ( uint16_t )payload[macIndex++] << 8;
02554 
02555                     nbRep = payload[macIndex++];
02556                     chMaskCntl = ( nbRep >> 4 ) & 0x07;
02557                     nbRep &= 0x0F;
02558                     if( nbRep == 0 )
02559                     {
02560                         nbRep = 1;
02561                     }
02562 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
02563                     if( ( chMaskCntl == 0 ) && ( chMask == 0 ) )
02564                     {
02565                         status &= 0xFE; // Channel mask KO
02566                     }
02567                     else if( ( ( chMaskCntl >= 1 ) && ( chMaskCntl <= 5 )) ||
02568                              ( chMaskCntl >= 7 ) )
02569                     {
02570                         // RFU
02571                         status &= 0xFE; // Channel mask KO
02572                     }
02573                     else
02574                     {
02575                         for( i = 0; i < LORA_MAX_NB_CHANNELS; i++ )
02576                         {
02577                             if( chMaskCntl == 6 )
02578                             {
02579                                 if( Channels[i].Frequency != 0 )
02580                                 {
02581                                     chMask |= 1 << i;
02582                                 }
02583                             }
02584                             else
02585                             {
02586                                 if( ( ( chMask & ( 1 << i ) ) != 0 ) &&
02587                                     ( Channels[i].Frequency  == 0 ) )
02588                                 {// Trying to enable an undefined channel
02589                                     status &= 0xFE; // Channel mask KO
02590                                 }
02591                             }
02592                         }
02593                         channelsMask[0] = chMask;
02594                     }
02595 #elif defined( USE_BAND_470 )
02596                     if( chMaskCntl == 6 )
02597                     {
02598                         // Enable all 125 kHz channels
02599                         for( uint8_t i = 0, k = 0; i < LORA_MAX_NB_CHANNELS; i += 16, k++ )
02600                         {
02601                             for( uint8_t j = 0; j < 16; j++ )
02602                             {
02603                                 if( Channels[i + j].Frequency != 0 )
02604                                 {
02605                                     channelsMask[k] |= 1 << j;
02606                                 }
02607                             }
02608                         }
02609                     }
02610                     else if( chMaskCntl == 7 )
02611                     {
02612                         status &= 0xFE; // Channel mask KO
02613                     }
02614                     else
02615                     {
02616                         for( uint8_t i = 0; i < 16; i++ )
02617                         {
02618                             if( ( ( chMask & ( 1 << i ) ) != 0 ) &&
02619                                 ( Channels[chMaskCntl * 16 + i].Frequency  == 0 ) )
02620                             {// Trying to enable an undefined channel
02621                                 status &= 0xFE; // Channel mask KO
02622                             }
02623                         }
02624                         channelsMask[chMaskCntl] = chMask;
02625                     }
02626 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
02627                     if( chMaskCntl == 6 )
02628                     {
02629                         // Enable all 125 kHz channels
02630                         channelsMask[0] = 0xFFFF;
02631                         channelsMask[1] = 0xFFFF;
02632                         channelsMask[2] = 0xFFFF;
02633                         channelsMask[3] = 0xFFFF;
02634                         // Apply chMask to channels 64 to 71
02635                         channelsMask[4] = chMask;
02636                     }
02637                     else if( chMaskCntl == 7 )
02638                     {
02639                         // Disable all 125 kHz channels
02640                         channelsMask[0] = 0x0000;
02641                         channelsMask[1] = 0x0000;
02642                         channelsMask[2] = 0x0000;
02643                         channelsMask[3] = 0x0000;
02644                         // Apply chMask to channels 64 to 71
02645                         channelsMask[4] = chMask;
02646                     }
02647                     else if( chMaskCntl == 5 )
02648                     {
02649                         // RFU
02650                         status &= 0xFE; // Channel mask KO
02651                     }
02652                     else
02653                     {
02654                         channelsMask[chMaskCntl] = chMask;
02655 
02656                         // FCC 15.247 paragraph F mandates to hop on at least 2 125 kHz channels
02657                         if( ( datarate < DR_4 ) && ( CountNbEnabled125kHzChannels( channelsMask ) < 2 ) )
02658                         {
02659                             status &= 0xFE; // Channel mask KO
02660                         }
02661 
02662 #if defined( USE_BAND_915_HYBRID )
02663                         if( ValidateChannelMask( channelsMask ) == false )
02664                         {
02665                             status &= 0xFE; // Channel mask KO
02666                         }
02667 #endif
02668                     }
02669 #else
02670     #error "Please define a frequency band in the compiler options."
02671 #endif
02672                     if( ValidateDatarate( datarate, channelsMask ) == false )
02673                     {
02674                         status &= 0xFD; // Datarate KO
02675                     }
02676 
02677                     //
02678                     // Remark MaxTxPower = 0 and MinTxPower = 5
02679                     //
02680                     if( ValueInRange( txPower, LORAMAC_MAX_TX_POWER, LORAMAC_MIN_TX_POWER ) == false )
02681                     {
02682                         status &= 0xFB; // TxPower KO
02683                     }
02684                     if( ( status & 0x07 ) == 0x07 )
02685                     {
02686                         LoRaMacParams.ChannelsDatarate  = datarate;
02687                         LoRaMacParams.ChannelsTxPower  = txPower;
02688 
02689                         memcpy1( ( uint8_t* )LoRaMacParams.ChannelsMask , ( uint8_t* )channelsMask, sizeof( LoRaMacParams.ChannelsMask  ) );
02690 
02691                         LoRaMacParams.ChannelsNbRep  = nbRep;
02692 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
02693                         // Reset ChannelsMaskRemaining to the new ChannelsMask
02694                         ChannelsMaskRemaining[0] &= channelsMask[0];
02695                         ChannelsMaskRemaining[1] &= channelsMask[1];
02696                         ChannelsMaskRemaining[2] &= channelsMask[2];
02697                         ChannelsMaskRemaining[3] &= channelsMask[3];
02698                         ChannelsMaskRemaining[4] = channelsMask[4];
02699                         ChannelsMaskRemaining[5] = channelsMask[5];
02700 #endif
02701                     }
02702                     AddMacCommand( MOTE_MAC_LINK_ADR_ANS , status, 0 );
02703                 }
02704                 break;
02705             case SRV_MAC_DUTY_CYCLE_REQ :
02706                 MaxDCycle = payload[macIndex++];
02707                 AggregatedDCycle = 1 << MaxDCycle;
02708                 AddMacCommand( MOTE_MAC_DUTY_CYCLE_ANS , 0, 0 );
02709                 break;
02710             case SRV_MAC_RX_PARAM_SETUP_REQ :
02711                 {
02712                     uint8_t status = 0x07;
02713                     int8_t datarate = 0;
02714                     int8_t drOffset = 0;
02715                     uint32_t freq = 0;
02716 
02717                     drOffset = ( payload[macIndex] >> 4 ) & 0x07;
02718                     datarate = payload[macIndex] & 0x0F;
02719                     macIndex++;
02720 
02721                     freq =  ( uint32_t )payload[macIndex++];
02722                     freq |= ( uint32_t )payload[macIndex++] << 8;
02723                     freq |= ( uint32_t )payload[macIndex++] << 16;
02724                     freq *= 100;
02725 
02726                     if( Rx2FreqInRange( freq ) == false )
02727                     {
02728                         status &= 0xFE; // Channel frequency KO
02729                     }
02730 
02731                     if( ValueInRange( datarate, LORAMAC_RX_MIN_DATARATE, LORAMAC_RX_MAX_DATARATE ) == false )
02732                     {
02733                         status &= 0xFD; // Datarate KO
02734                     }
02735 #if ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) )
02736                     if( ( ValueInRange( datarate, DR_5, DR_7 ) == true ) ||
02737                         ( datarate > DR_13 ) )
02738                     {
02739                         status &= 0xFD; // Datarate KO
02740                     }
02741 #endif
02742                     if( ValueInRange( drOffset, LORAMAC_MIN_RX1_DR_OFFSET, LORAMAC_MAX_RX1_DR_OFFSET ) == false )
02743                     {
02744                         status &= 0xFB; // Rx1DrOffset range KO
02745                     }
02746 
02747                     if( ( status & 0x07 ) == 0x07 )
02748                     {
02749                         LoRaMacParams.Rx2Channel .Datarate  = datarate;
02750                         LoRaMacParams.Rx2Channel .Frequency  = freq;
02751                         LoRaMacParams.Rx1DrOffset  = drOffset;
02752                     }
02753                     AddMacCommand( MOTE_MAC_RX_PARAM_SETUP_ANS , status, 0 );
02754                 }
02755                 break;
02756             case SRV_MAC_DEV_STATUS_REQ :
02757                 {
02758                     uint8_t batteryLevel = BAT_LEVEL_NO_MEASURE ;
02759                     if( ( LoRaMacCallbacks != NULL ) && ( LoRaMacCallbacks->GetBatteryLevel != NULL ) )
02760                     {
02761                         batteryLevel = LoRaMacCallbacks->GetBatteryLevel( );
02762                     }
02763                     AddMacCommand( MOTE_MAC_DEV_STATUS_ANS , batteryLevel, snr );
02764                     break;
02765                 }
02766             case SRV_MAC_NEW_CHANNEL_REQ :
02767                 {
02768                     uint8_t status = 0x03;
02769 
02770 #if defined( USE_BAND_470 ) || defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
02771                     status &= 0xFC; // Channel frequency and datarate KO
02772                     macIndex += 5;
02773 #else
02774                     int8_t channelIndex = 0;
02775                     ChannelParams_t  chParam;
02776 
02777                     channelIndex = payload[macIndex++];
02778                     chParam.Frequency  = ( uint32_t )payload[macIndex++];
02779                     chParam.Frequency  |= ( uint32_t )payload[macIndex++] << 8;
02780                     chParam.Frequency  |= ( uint32_t )payload[macIndex++] << 16;
02781                     chParam.Frequency  *= 100;
02782                     chParam.DrRange .Value  = payload[macIndex++];
02783 
02784                     LoRaMacState |= LORAMAC_TX_CONFIG;
02785                     if( chParam.Frequency  == 0 )
02786                     {
02787                         if( channelIndex < 3 )
02788                         {
02789                             status &= 0xFC;
02790                         }
02791                         else
02792                         {
02793                             if( LoRaMacChannelRemove( channelIndex ) != LORAMAC_STATUS_OK  )
02794                             {
02795                                 status &= 0xFC;
02796                             }
02797                         }
02798                     }
02799                     else
02800                     {
02801                         switch( LoRaMacChannelAdd( channelIndex, chParam ) )
02802                         {
02803                             case LORAMAC_STATUS_OK :
02804                             {
02805                                 break;
02806                             }
02807                             case LORAMAC_STATUS_FREQUENCY_INVALID :
02808                             {
02809                                 status &= 0xFE;
02810                                 break;
02811                             }
02812                             case LORAMAC_STATUS_DATARATE_INVALID :
02813                             {
02814                                 status &= 0xFD;
02815                                 break;
02816                             }
02817                             case LORAMAC_STATUS_FREQ_AND_DR_INVALID :
02818                             {
02819                                 status &= 0xFC;
02820                                 break;
02821                             }
02822                             default:
02823                             {
02824                                 status &= 0xFC;
02825                                 break;
02826                             }
02827                         }
02828                     }
02829                     LoRaMacState &= ~LORAMAC_TX_CONFIG;
02830 #endif
02831                     AddMacCommand( MOTE_MAC_NEW_CHANNEL_ANS , status, 0 );
02832                 }
02833                 break;
02834             case SRV_MAC_RX_TIMING_SETUP_REQ :
02835                 {
02836                     uint8_t delay = payload[macIndex++] & 0x0F;
02837 
02838                     if( delay == 0 )
02839                     {
02840                         delay++;
02841                     }
02842                     LoRaMacParams.ReceiveDelay1  = delay * 1e3;
02843                     LoRaMacParams.ReceiveDelay2  = LoRaMacParams.ReceiveDelay1  + 1e3;
02844                     AddMacCommand( MOTE_MAC_RX_TIMING_SETUP_ANS , 0, 0 );
02845                 }
02846                 break;
02847             default:
02848                 // Unknown command. ABORT MAC commands processing
02849                 return;
02850         }
02851     }
02852 }
02853 
02854 LoRaMacStatus_t  Send( LoRaMacHeader_t  *macHdr, uint8_t fPort, void *fBuffer, uint16_t fBufferSize )
02855 {
02856     LoRaMacFrameCtrl_t  fCtrl;
02857     LoRaMacStatus_t  status = LORAMAC_STATUS_PARAMETER_INVALID ;
02858 
02859     fCtrl.Value  = 0;
02860     fCtrl.Bits.FOptsLen       = 0;
02861     fCtrl.Bits.FPending       = 0;
02862     fCtrl.Bits.Ack            = false;
02863     fCtrl.Bits.AdrAckReq      = false;
02864     fCtrl.Bits.Adr            = AdrCtrlOn;
02865 
02866     // Prepare the frame
02867     status = PrepareFrame( macHdr, &fCtrl, fPort, fBuffer, fBufferSize );
02868 
02869     // Validate status
02870     if( status != LORAMAC_STATUS_OK  )
02871     {
02872         return status;
02873     }
02874 
02875     // Reset confirm parameters
02876     McpsConfirm.NbRetries  = 0;
02877     McpsConfirm.AckReceived  = false;
02878     McpsConfirm.UpLinkCounter  = UpLinkCounter;
02879 
02880     status = ScheduleTx( );
02881 
02882     return status;
02883 }
02884 
02885 static LoRaMacStatus_t  ScheduleTx( void )
02886 {
02887     TimerTime_t dutyCycleTimeOff = 0;
02888 
02889     // Check if the device is off
02890     if( MaxDCycle == 255 )
02891     {
02892         return LORAMAC_STATUS_DEVICE_OFF ;
02893     }
02894     if( MaxDCycle == 0 )
02895     {
02896         AggregatedTimeOff = 0;
02897     }
02898 
02899     // Select channel
02900     while( SetNextChannel( &dutyCycleTimeOff ) == false )
02901     {
02902         // Set the default datarate
02903         LoRaMacParams.ChannelsDatarate  = LoRaMacParamsDefaults.ChannelsDatarate ;
02904 
02905 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
02906         // Re-enable default channels LC1, LC2, LC3
02907         LoRaMacParams.ChannelsMask [0] = LoRaMacParams.ChannelsMask [0] | ( LC( 1 ) + LC( 2 ) + LC( 3 ) );
02908 #endif
02909     }
02910 
02911     // Compute Rx1 windows parameters
02912 #if ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) )
02913     RxWindowsParams[0] = ComputeRxWindowParameters( DatarateOffsets[LoRaMacParams.ChannelsDatarate ][LoRaMacParams.Rx1DrOffset ], LoRaMacParams.SystemMaxRxError  );
02914 #else
02915     RxWindowsParams[0] = ComputeRxWindowParameters( MAX( DR_0, LoRaMacParams.ChannelsDatarate  - LoRaMacParams.Rx1DrOffset  ), LoRaMacParams.SystemMaxRxError  );
02916 #endif
02917     // Compute Rx2 windows parameters
02918     RxWindowsParams[1] = ComputeRxWindowParameters( LoRaMacParams.Rx2Channel .Datarate , LoRaMacParams.SystemMaxRxError  );
02919 
02920     if( IsLoRaMacNetworkJoined == false )
02921     {
02922         RxWindow1Delay = LoRaMacParams.JoinAcceptDelay1  + RxWindowsParams[0].RxOffset;
02923         RxWindow2Delay = LoRaMacParams.JoinAcceptDelay2  + RxWindowsParams[1].RxOffset;
02924     }
02925     else
02926     {
02927         if( ValidatePayloadLength( LoRaMacTxPayloadLen, LoRaMacParams.ChannelsDatarate , MacCommandsBufferIndex ) == false )
02928         {
02929             return LORAMAC_STATUS_LENGTH_ERROR ;
02930         }
02931         RxWindow1Delay = LoRaMacParams.ReceiveDelay1  + RxWindowsParams[0].RxOffset;
02932         RxWindow2Delay = LoRaMacParams.ReceiveDelay2  + RxWindowsParams[1].RxOffset;
02933     }
02934 
02935     // Schedule transmission of frame
02936     if( dutyCycleTimeOff == 0 )
02937     {
02938         // Try to send now
02939         return SendFrameOnChannel( Channels[Channel] );
02940     }
02941     else
02942     {
02943         // Send later - prepare timer
02944         LoRaMacState |= LORAMAC_TX_DELAYED;
02945         TimerSetValue( &TxDelayedTimer, dutyCycleTimeOff );
02946         TimerStart( &TxDelayedTimer );
02947 
02948         return LORAMAC_STATUS_OK ;
02949     }
02950 }
02951 
02952 static uint16_t JoinDutyCycle( void )
02953 {
02954     uint16_t dutyCycle = 0;
02955     TimerTime_t timeElapsed = TimerGetElapsedTime( LoRaMacInitializationTime );
02956 
02957     if( timeElapsed < 3600e3 )
02958     {
02959         dutyCycle = BACKOFF_DC_1_HOUR;
02960     }
02961     else if( timeElapsed < ( 3600e3 + 36000e3 ) )
02962     {
02963         dutyCycle = BACKOFF_DC_10_HOURS;
02964     }
02965     else
02966     {
02967         dutyCycle = BACKOFF_DC_24_HOURS;
02968     }
02969     return dutyCycle;
02970 }
02971 
02972 static void CalculateBackOff( uint8_t channel )
02973 {
02974     uint16_t dutyCycle = Bands[Channels[channel].Band ].DCycle ;
02975     uint16_t joinDutyCycle = 0;
02976 
02977     // Reset time-off to initial value.
02978     Bands[Channels[channel].Band ].TimeOff  = 0;
02979 
02980     if( IsLoRaMacNetworkJoined == false )
02981     {
02982         // The node has not joined yet. Apply join duty cycle to all regions.
02983         joinDutyCycle = JoinDutyCycle( );
02984         dutyCycle = MAX( dutyCycle, joinDutyCycle );
02985 
02986         // Update Band time-off.
02987         Bands[Channels[channel].Band ].TimeOff  = TxTimeOnAir * dutyCycle - TxTimeOnAir;
02988     }
02989     else
02990     {
02991         if( DutyCycleOn == true )
02992         {
02993             Bands[Channels[channel].Band ].TimeOff  = TxTimeOnAir * dutyCycle - TxTimeOnAir;
02994         }
02995     }
02996 
02997     // Update Aggregated Time OFF
02998     AggregatedTimeOff = AggregatedTimeOff + ( TxTimeOnAir * AggregatedDCycle - TxTimeOnAir );
02999 }
03000 
03001 static int8_t AlternateDatarate( uint16_t nbTrials )
03002 {
03003     int8_t datarate = LORAMAC_TX_MIN_DATARATE;
03004 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
03005 #if defined( USE_BAND_915 )
03006     // Re-enable 500 kHz default channels
03007     LoRaMacParams.ChannelsMask [4] = 0x00FF;
03008 #else // defined( USE_BAND_915_HYBRID )
03009     // Re-enable 500 kHz default channels
03010     ReenableChannels( LoRaMacParamsDefaults.ChannelsMask [4], LoRaMacParams.ChannelsMask  );
03011 #endif
03012 
03013     if( ( nbTrials & 0x01 ) == 0x01 )
03014     {
03015         datarate = DR_4;
03016     }
03017     else
03018     {
03019         datarate = DR_0;
03020     }
03021 #else
03022     if( ( nbTrials % 48 ) == 0 )
03023     {
03024         datarate = DR_0;
03025     }
03026     else if( ( nbTrials % 32 ) == 0 )
03027     {
03028         datarate = DR_1;
03029     }
03030     else if( ( nbTrials % 24 ) == 0 )
03031     {
03032         datarate = DR_2;
03033     }
03034     else if( ( nbTrials % 16 ) == 0 )
03035     {
03036         datarate = DR_3;
03037     }
03038     else if( ( nbTrials % 8 ) == 0 )
03039     {
03040         datarate = DR_4;
03041     }
03042     else
03043     {
03044         datarate = DR_5;
03045     }
03046 #endif
03047     return datarate;
03048 }
03049 
03050 static void ResetMacParameters( void )
03051 {
03052     IsLoRaMacNetworkJoined = false;
03053 
03054     // Counters
03055     UpLinkCounter = 0;
03056     DownLinkCounter = 0;
03057     AdrAckCounter = 0;
03058 
03059     ChannelsNbRepCounter = 0;
03060 
03061     AckTimeoutRetries = 1;
03062     AckTimeoutRetriesCounter = 1;
03063     AckTimeoutRetry = false;
03064 
03065     MaxDCycle = 0;
03066     AggregatedDCycle = 1;
03067 
03068     MacCommandsBufferIndex = 0;
03069     MacCommandsBufferToRepeatIndex = 0;
03070 
03071     IsRxWindowsEnabled = true;
03072 
03073     LoRaMacParams.ChannelsTxPower  = LoRaMacParamsDefaults.ChannelsTxPower ;
03074     LoRaMacParams.ChannelsDatarate  = LoRaMacParamsDefaults.ChannelsDatarate ;
03075 
03076     LoRaMacParams.Rx1DrOffset  = LoRaMacParamsDefaults.Rx1DrOffset ;
03077     LoRaMacParams.Rx2Channel  = LoRaMacParamsDefaults.Rx2Channel ;
03078 
03079     memcpy1( ( uint8_t* ) LoRaMacParams.ChannelsMask , ( uint8_t* ) LoRaMacParamsDefaults.ChannelsMask , sizeof( LoRaMacParams.ChannelsMask  ) );
03080 
03081 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
03082     memcpy1( ( uint8_t* ) ChannelsMaskRemaining, ( uint8_t* ) LoRaMacParamsDefaults.ChannelsMask , sizeof( LoRaMacParams.ChannelsMask  ) );
03083 #endif
03084 
03085 
03086     NodeAckRequested = false;
03087     SrvAckRequested = false;
03088     MacCommandsInNextTx = false;
03089 
03090     // Reset Multicast downlink counters
03091     MulticastParams_t  *cur = MulticastChannels;
03092     while( cur != NULL )
03093     {
03094         cur->DownLinkCounter  = 0;
03095         cur = cur->Next ;
03096     }
03097 
03098     // Initialize channel index.
03099     Channel = LORA_MAX_NB_CHANNELS;
03100 }
03101 
03102 LoRaMacStatus_t  PrepareFrame( LoRaMacHeader_t  *macHdr, LoRaMacFrameCtrl_t  *fCtrl, uint8_t fPort, void *fBuffer, uint16_t fBufferSize )
03103 {
03104     uint16_t i;
03105     uint8_t pktHeaderLen = 0;
03106     uint32_t mic = 0;
03107     const void* payload = fBuffer;
03108     uint8_t framePort = fPort;
03109 
03110     LoRaMacBufferPktLen = 0;
03111 
03112     NodeAckRequested = false;
03113 
03114     if( fBuffer == NULL )
03115     {
03116         fBufferSize = 0;
03117     }
03118 
03119     LoRaMacTxPayloadLen = fBufferSize;
03120 
03121     LoRaMacBuffer[pktHeaderLen++] = macHdr->Value ;
03122 
03123     switch( macHdr->Bits.MType  )
03124     {
03125         case FRAME_TYPE_JOIN_REQ :
03126             LoRaMacBufferPktLen = pktHeaderLen;
03127 
03128             memcpyr( LoRaMacBuffer + LoRaMacBufferPktLen, LoRaMacAppEui, 8 );
03129             LoRaMacBufferPktLen += 8;
03130             memcpyr( LoRaMacBuffer + LoRaMacBufferPktLen, LoRaMacDevEui, 8 );
03131             LoRaMacBufferPktLen += 8;
03132 
03133             LoRaMacDevNonce = Radio.Random( );
03134 
03135             LoRaMacBuffer[LoRaMacBufferPktLen++] = LoRaMacDevNonce & 0xFF;
03136             LoRaMacBuffer[LoRaMacBufferPktLen++] = ( LoRaMacDevNonce >> 8 ) & 0xFF;
03137 
03138             LoRaMacJoinComputeMic ( LoRaMacBuffer, LoRaMacBufferPktLen & 0xFF, LoRaMacAppKey, &mic );
03139 
03140             LoRaMacBuffer[LoRaMacBufferPktLen++] = mic & 0xFF;
03141             LoRaMacBuffer[LoRaMacBufferPktLen++] = ( mic >> 8 ) & 0xFF;
03142             LoRaMacBuffer[LoRaMacBufferPktLen++] = ( mic >> 16 ) & 0xFF;
03143             LoRaMacBuffer[LoRaMacBufferPktLen++] = ( mic >> 24 ) & 0xFF;
03144 
03145             break;
03146         case FRAME_TYPE_DATA_CONFIRMED_UP :
03147             NodeAckRequested = true;
03148             //Intentional fallthrough
03149         case FRAME_TYPE_DATA_UNCONFIRMED_UP :
03150             if( IsLoRaMacNetworkJoined == false )
03151             {
03152                 return LORAMAC_STATUS_NO_NETWORK_JOINED ; // No network has been joined yet
03153             }
03154 
03155             fCtrl->Bits.AdrAckReq  = AdrNextDr( fCtrl->Bits.Adr , true, &LoRaMacParams.ChannelsDatarate  );
03156 
03157             if( SrvAckRequested == true )
03158             {
03159                 SrvAckRequested = false;
03160                 fCtrl->Bits.Ack  = 1;
03161             }
03162 
03163             LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr ) & 0xFF;
03164             LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr >> 8 ) & 0xFF;
03165             LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr >> 16 ) & 0xFF;
03166             LoRaMacBuffer[pktHeaderLen++] = ( LoRaMacDevAddr >> 24 ) & 0xFF;
03167 
03168             LoRaMacBuffer[pktHeaderLen++] = fCtrl->Value ;
03169 
03170             LoRaMacBuffer[pktHeaderLen++] = UpLinkCounter & 0xFF;
03171             LoRaMacBuffer[pktHeaderLen++] = ( UpLinkCounter >> 8 ) & 0xFF;
03172 
03173             // Copy the MAC commands which must be re-send into the MAC command buffer
03174             memcpy1( &MacCommandsBuffer[MacCommandsBufferIndex], MacCommandsBufferToRepeat, MacCommandsBufferToRepeatIndex );
03175             MacCommandsBufferIndex += MacCommandsBufferToRepeatIndex;
03176 
03177             if( ( payload != NULL ) && ( LoRaMacTxPayloadLen > 0 ) )
03178             {
03179                 if( ( MacCommandsBufferIndex <= LORA_MAC_COMMAND_MAX_LENGTH ) && ( MacCommandsInNextTx == true ) )
03180                 {
03181                     fCtrl->Bits.FOptsLen  += MacCommandsBufferIndex;
03182 
03183                     // Update FCtrl field with new value of OptionsLength
03184                     LoRaMacBuffer[0x05] = fCtrl->Value ;
03185                     for( i = 0; i < MacCommandsBufferIndex; i++ )
03186                     {
03187                         LoRaMacBuffer[pktHeaderLen++] = MacCommandsBuffer[i];
03188                     }
03189                 }
03190             }
03191             else
03192             {
03193                 if( ( MacCommandsBufferIndex > 0 ) && ( MacCommandsInNextTx ) )
03194                 {
03195                     LoRaMacTxPayloadLen = MacCommandsBufferIndex;
03196                     payload = MacCommandsBuffer;
03197                     framePort = 0;
03198                 }
03199             }
03200             MacCommandsInNextTx = false;
03201             // Store MAC commands which must be re-send in case the device does not receive a downlink anymore
03202             MacCommandsBufferToRepeatIndex = ParseMacCommandsToRepeat( MacCommandsBuffer, MacCommandsBufferIndex, MacCommandsBufferToRepeat );
03203             if( MacCommandsBufferToRepeatIndex > 0 )
03204             {
03205                 MacCommandsInNextTx = true;
03206             }
03207 
03208             if( ( payload != NULL ) && ( LoRaMacTxPayloadLen > 0 ) )
03209             {
03210                 LoRaMacBuffer[pktHeaderLen++] = framePort;
03211 
03212                 if( framePort == 0 )
03213                 {
03214                     LoRaMacPayloadEncrypt ( (uint8_t* ) payload, LoRaMacTxPayloadLen, LoRaMacNwkSKey, LoRaMacDevAddr, UP_LINK, UpLinkCounter, &LoRaMacBuffer[pktHeaderLen] );
03215                 }
03216                 else
03217                 {
03218                     LoRaMacPayloadEncrypt ( (uint8_t* ) payload, LoRaMacTxPayloadLen, LoRaMacAppSKey, LoRaMacDevAddr, UP_LINK, UpLinkCounter, &LoRaMacBuffer[pktHeaderLen] );
03219                 }
03220             }
03221             LoRaMacBufferPktLen = pktHeaderLen + LoRaMacTxPayloadLen;
03222 
03223             LoRaMacComputeMic( LoRaMacBuffer, LoRaMacBufferPktLen, LoRaMacNwkSKey, LoRaMacDevAddr, UP_LINK, UpLinkCounter, &mic );
03224 
03225             LoRaMacBuffer[LoRaMacBufferPktLen + 0] = mic & 0xFF;
03226             LoRaMacBuffer[LoRaMacBufferPktLen + 1] = ( mic >> 8 ) & 0xFF;
03227             LoRaMacBuffer[LoRaMacBufferPktLen + 2] = ( mic >> 16 ) & 0xFF;
03228             LoRaMacBuffer[LoRaMacBufferPktLen + 3] = ( mic >> 24 ) & 0xFF;
03229 
03230             LoRaMacBufferPktLen += LORAMAC_MFR_LEN;
03231 
03232             break;
03233         case FRAME_TYPE_PROPRIETARY :
03234             if( ( fBuffer != NULL ) && ( LoRaMacTxPayloadLen > 0 ) )
03235             {
03236                 memcpy1( LoRaMacBuffer + pktHeaderLen, ( uint8_t* ) fBuffer, LoRaMacTxPayloadLen );
03237                 LoRaMacBufferPktLen = pktHeaderLen + LoRaMacTxPayloadLen;
03238             }
03239             break;
03240         default:
03241             return LORAMAC_STATUS_SERVICE_UNKNOWN ;
03242     }
03243 
03244     return LORAMAC_STATUS_OK ;
03245 }
03246 
03247 LoRaMacStatus_t  SendFrameOnChannel( ChannelParams_t  channel )
03248 {
03249     int8_t datarate = Datarates[LoRaMacParams.ChannelsDatarate ];
03250     int8_t txPowerIndex = 0;
03251     int8_t txPower = 0;
03252 
03253     txPowerIndex = LimitTxPower( LoRaMacParams.ChannelsTxPower , Bands[channel.Band ].TxMaxPower  );
03254     txPower = TxPowers[txPowerIndex];
03255 
03256     MlmeConfirm.Status  = LORAMAC_EVENT_INFO_STATUS_ERROR ;
03257     McpsConfirm.Status  = LORAMAC_EVENT_INFO_STATUS_ERROR ;
03258     McpsConfirm.Datarate  = LoRaMacParams.ChannelsDatarate ;
03259     McpsConfirm.TxPower  = txPowerIndex;
03260     McpsConfirm.UpLinkFrequency  = channel.Frequency ;
03261 
03262     Radio.SetChannel( channel.Frequency  );
03263 
03264 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
03265     if( LoRaMacParams.ChannelsDatarate  == DR_7 )
03266     { // High Speed FSK channel
03267         Radio.SetMaxPayloadLength( MODEM_FSK, LoRaMacBufferPktLen );
03268         Radio.SetTxConfig( MODEM_FSK, txPower, 25e3, 0, datarate * 1e3, 0, 5, false, true, 0, 0, false, 3e3 );
03269         TxTimeOnAir = Radio.TimeOnAir( MODEM_FSK, LoRaMacBufferPktLen );
03270 
03271     }
03272     else if( LoRaMacParams.ChannelsDatarate  == DR_6 )
03273     { // High speed LoRa channel
03274         Radio.SetMaxPayloadLength( MODEM_LORA, LoRaMacBufferPktLen );
03275         Radio.SetTxConfig( MODEM_LORA, txPower, 0, 1, datarate, 1, 8, false, true, 0, 0, false, 3e3 );
03276         TxTimeOnAir = Radio.TimeOnAir( MODEM_LORA, LoRaMacBufferPktLen );
03277     }
03278     else
03279     { // Normal LoRa channel
03280         Radio.SetMaxPayloadLength( MODEM_LORA, LoRaMacBufferPktLen );
03281         Radio.SetTxConfig( MODEM_LORA, txPower, 0, 0, datarate, 1, 8, false, true, 0, 0, false, 3e3 );
03282         TxTimeOnAir = Radio.TimeOnAir( MODEM_LORA, LoRaMacBufferPktLen );
03283     }
03284 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
03285     Radio.SetMaxPayloadLength( MODEM_LORA, LoRaMacBufferPktLen );
03286     if( LoRaMacParams.ChannelsDatarate  >= DR_4 )
03287     { // High speed LoRa channel BW500 kHz
03288         Radio.SetTxConfig( MODEM_LORA, txPower, 0, 2, datarate, 1, 8, false, true, 0, 0, false, 3e3 );
03289         TxTimeOnAir = Radio.TimeOnAir( MODEM_LORA, LoRaMacBufferPktLen );
03290     }
03291     else
03292     { // Normal LoRa channel
03293         Radio.SetTxConfig( MODEM_LORA, txPower, 0, 0, datarate, 1, 8, false, true, 0, 0, false, 3e3 );
03294         TxTimeOnAir = Radio.TimeOnAir( MODEM_LORA, LoRaMacBufferPktLen );
03295     }
03296 #elif defined( USE_BAND_470 )
03297     Radio.SetMaxPayloadLength( MODEM_LORA, LoRaMacBufferPktLen );
03298     Radio.SetTxConfig( MODEM_LORA, txPower, 0, 0, datarate, 1, 8, false, true, 0, 0, false, 3e3 );
03299     TxTimeOnAir = Radio.TimeOnAir( MODEM_LORA, LoRaMacBufferPktLen );
03300 #else
03301     #error "Please define a frequency band in the compiler options."
03302 #endif
03303 
03304     // Store the time on air
03305     McpsConfirm.TxTimeOnAir  = TxTimeOnAir;
03306     MlmeConfirm.TxTimeOnAir  = TxTimeOnAir;
03307 
03308     // Starts the MAC layer status check timer
03309     TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT );
03310     TimerStart( &MacStateCheckTimer );
03311 
03312     if( IsLoRaMacNetworkJoined == false )
03313     {
03314         JoinRequestTrials++;
03315     }
03316 
03317     // Send now
03318     Radio.Send( LoRaMacBuffer, LoRaMacBufferPktLen );
03319 
03320     LoRaMacState |= LORAMAC_TX_RUNNING;
03321 
03322     return LORAMAC_STATUS_OK ;
03323 }
03324 
03325 LoRaMacStatus_t  SetTxContinuousWave( uint16_t timeout )
03326 {
03327     int8_t txPowerIndex = 0;
03328     int8_t txPower = 0;
03329 
03330     txPowerIndex = LimitTxPower( LoRaMacParams.ChannelsTxPower , Bands[Channels[Channel].Band ].TxMaxPower  );
03331     txPower = TxPowers[txPowerIndex];
03332 
03333     // Starts the MAC layer status check timer
03334     TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT );
03335     TimerStart( &MacStateCheckTimer );
03336 
03337     Radio.SetTxContinuousWave( Channels[Channel].Frequency, txPower, timeout );
03338 
03339     LoRaMacState |= LORAMAC_TX_RUNNING;
03340 
03341     return LORAMAC_STATUS_OK ;
03342 }
03343 
03344 LoRaMacStatus_t  SetTxContinuousWave1( uint16_t timeout, uint32_t frequency, uint8_t power )
03345 {
03346     Radio.SetTxContinuousWave( frequency, power, timeout );
03347 
03348     // Starts the MAC layer status check timer
03349     TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT );
03350     TimerStart( &MacStateCheckTimer );
03351 
03352     LoRaMacState |= LORAMAC_TX_RUNNING;
03353 
03354     return LORAMAC_STATUS_OK ;
03355 }
03356 
03357 LoRaMacStatus_t  LoRaMacInitialization( LoRaMacPrimitives_t  *primitives, LoRaMacCallback_t *callbacks )
03358 {
03359     if( primitives == NULL )
03360     {
03361         return LORAMAC_STATUS_PARAMETER_INVALID ;
03362     }
03363 
03364     if( ( primitives->MacMcpsConfirm == NULL ) ||
03365         ( primitives->MacMcpsIndication == NULL ) ||
03366         ( primitives->MacMlmeConfirm == NULL ) )
03367     {
03368         return LORAMAC_STATUS_PARAMETER_INVALID ;
03369     }
03370 
03371     LoRaMacPrimitives = primitives;
03372     LoRaMacCallbacks = callbacks;
03373 
03374     LoRaMacFlags.Value  = 0;
03375 
03376     LoRaMacDeviceClass = CLASS_A ;
03377     LoRaMacState = LORAMAC_IDLE;
03378 
03379     JoinRequestTrials = 0;
03380     MaxJoinRequestTrials = 1;
03381     RepeaterSupport = false;
03382 
03383     // Reset duty cycle times
03384     AggregatedLastTxDoneTime = 0;
03385     AggregatedTimeOff = 0;
03386 
03387     // Duty cycle
03388 #if defined( USE_BAND_433 )
03389     DutyCycleOn = true;
03390 #elif defined( USE_BAND_470 )
03391     DutyCycleOn = false;
03392 #elif defined( USE_BAND_780 )
03393     DutyCycleOn = true;
03394 #elif defined( USE_BAND_868 )
03395     //Edited by Chris
03396     //DutyCycleOn = true;
03397     DutyCycleOn = false;
03398 #elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
03399     DutyCycleOn = false;
03400 #else
03401     #error "Please define a frequency band in the compiler options."
03402 #endif
03403 
03404     // Reset to defaults
03405     LoRaMacParamsDefaults.ChannelsTxPower  = LORAMAC_DEFAULT_TX_POWER;
03406     LoRaMacParamsDefaults.ChannelsDatarate  = LORAMAC_DEFAULT_DATARATE;
03407 
03408     LoRaMacParamsDefaults.SystemMaxRxError  = 10;
03409     LoRaMacParamsDefaults.MinRxSymbols  = 6;
03410     LoRaMacParamsDefaults.MaxRxWindow  = MAX_RX_WINDOW;
03411     LoRaMacParamsDefaults.ReceiveDelay1  = RECEIVE_DELAY1;
03412     LoRaMacParamsDefaults.ReceiveDelay2  = RECEIVE_DELAY2;
03413     LoRaMacParamsDefaults.JoinAcceptDelay1  = JOIN_ACCEPT_DELAY1;
03414     LoRaMacParamsDefaults.JoinAcceptDelay2  = JOIN_ACCEPT_DELAY2;
03415 
03416     LoRaMacParamsDefaults.ChannelsNbRep  = 1;
03417     LoRaMacParamsDefaults.Rx1DrOffset  = 0;
03418 
03419     LoRaMacParamsDefaults.Rx2Channel  = ( Rx2ChannelParams_t  )RX_WND_2_CHANNEL;
03420 
03421     // Channel mask
03422 #if defined( USE_BAND_433 )
03423     LoRaMacParamsDefaults.ChannelsMask [0] = LC( 1 ) + LC( 2 ) + LC( 3 );
03424 #elif defined ( USE_BAND_470 )
03425     LoRaMacParamsDefaults.ChannelsMask [0] = 0xFFFF;
03426     LoRaMacParamsDefaults.ChannelsMask [1] = 0xFFFF;
03427     LoRaMacParamsDefaults.ChannelsMask [2] = 0xFFFF;
03428     LoRaMacParamsDefaults.ChannelsMask [3] = 0xFFFF;
03429     LoRaMacParamsDefaults.ChannelsMask [4] = 0xFFFF;
03430     LoRaMacParamsDefaults.ChannelsMask [5] = 0xFFFF;
03431 #elif defined( USE_BAND_780 )
03432     LoRaMacParamsDefaults.ChannelsMask [0] = LC( 1 ) + LC( 2 ) + LC( 3 );
03433 #elif defined( USE_BAND_868 )
03434     LoRaMacParamsDefaults.ChannelsMask [0] = LC( 1 ) + LC( 2 ) + LC( 3 );
03435 #elif defined( USE_BAND_915 )
03436     LoRaMacParamsDefaults.ChannelsMask [0] = 0xFFFF;
03437     LoRaMacParamsDefaults.ChannelsMask [1] = 0xFFFF;
03438     LoRaMacParamsDefaults.ChannelsMask [2] = 0xFFFF;
03439     LoRaMacParamsDefaults.ChannelsMask [3] = 0xFFFF;
03440     LoRaMacParamsDefaults.ChannelsMask [4] = 0x00FF;
03441     LoRaMacParamsDefaults.ChannelsMask [5] = 0x0000;
03442 #elif defined( USE_BAND_915_HYBRID )
03443     LoRaMacParamsDefaults.ChannelsMask [0] = 0x00FF;
03444     LoRaMacParamsDefaults.ChannelsMask [1] = 0x0000;
03445     LoRaMacParamsDefaults.ChannelsMask [2] = 0x0000;
03446     LoRaMacParamsDefaults.ChannelsMask [3] = 0x0000;
03447     LoRaMacParamsDefaults.ChannelsMask [4] = 0x0001;
03448     LoRaMacParamsDefaults.ChannelsMask [5] = 0x0000;
03449 #else
03450     #error "Please define a frequency band in the compiler options."
03451 #endif
03452 
03453 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
03454     // 125 kHz channels
03455     for( uint8_t i = 0; i < LORA_MAX_NB_CHANNELS - 8; i++ )
03456     {
03457         Channels[i].Frequency  = 902.3e6 + i * 200e3;
03458         Channels[i].DrRange .Value  = ( DR_3 << 4 ) | DR_0;
03459         Channels[i].Band  = 0;
03460     }
03461     // 500 kHz channels
03462     for( uint8_t i = LORA_MAX_NB_CHANNELS - 8; i < LORA_MAX_NB_CHANNELS; i++ )
03463     {
03464         Channels[i].Frequency  = 903.0e6 + ( i - ( LORA_MAX_NB_CHANNELS - 8 ) ) * 1.6e6;
03465         Channels[i].DrRange .Value  = ( DR_4 << 4 ) | DR_4;
03466         Channels[i].Band  = 0;
03467     }
03468 #elif defined( USE_BAND_470 )
03469     // 125 kHz channels
03470     for( uint8_t i = 0; i < LORA_MAX_NB_CHANNELS; i++ )
03471     {
03472         Channels[i].Frequency  = 470.3e6 + i * 200e3;
03473         Channels[i].DrRange .Value  = ( DR_5 << 4 ) | DR_0;
03474         Channels[i].Band  = 0;
03475     }
03476 #endif
03477 
03478     // Init parameters which are not set in function ResetMacParameters
03479     LoRaMacParams.SystemMaxRxError  = LoRaMacParamsDefaults.SystemMaxRxError ;
03480     LoRaMacParams.MinRxSymbols  = LoRaMacParamsDefaults.MinRxSymbols ;
03481     LoRaMacParams.MaxRxWindow  = LoRaMacParamsDefaults.MaxRxWindow ;
03482     LoRaMacParams.ReceiveDelay1  = LoRaMacParamsDefaults.ReceiveDelay1 ;
03483     LoRaMacParams.ReceiveDelay2  = LoRaMacParamsDefaults.ReceiveDelay2 ;
03484     LoRaMacParams.JoinAcceptDelay1  = LoRaMacParamsDefaults.JoinAcceptDelay1 ;
03485     LoRaMacParams.JoinAcceptDelay2  = LoRaMacParamsDefaults.JoinAcceptDelay2 ;
03486     LoRaMacParams.ChannelsNbRep  = LoRaMacParamsDefaults.ChannelsNbRep ;
03487 
03488     ResetMacParameters( );
03489 
03490     // Initialize timers
03491     TimerInit( &MacStateCheckTimer, OnMacStateCheckTimerEvent );
03492     TimerSetValue( &MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT );
03493 
03494     TimerInit( &TxDelayedTimer, OnTxDelayedTimerEvent );
03495     TimerInit( &RxWindowTimer1, OnRxWindow1TimerEvent );
03496     TimerInit( &RxWindowTimer2, OnRxWindow2TimerEvent );
03497     TimerInit( &AckTimeoutTimer, OnAckTimeoutTimerEvent );
03498 
03499     // Store the current initialization time
03500     LoRaMacInitializationTime = TimerGetCurrentTime( );
03501 
03502     // Initialize Radio driver
03503     RadioEvents.TxDone = OnRadioTxDone;
03504     RadioEvents.RxDone = OnRadioRxDone;
03505     RadioEvents.RxError = OnRadioRxError;
03506     RadioEvents.TxTimeout = OnRadioTxTimeout;
03507     RadioEvents.RxTimeout = OnRadioRxTimeout;
03508     Radio.Init( &RadioEvents );
03509 
03510     // Random seed initialization
03511     srand1( Radio.Random( ) );
03512 
03513     PublicNetwork = true;
03514     Radio.SetPublicNetwork( PublicNetwork );
03515     Radio.Sleep( );
03516 
03517     return LORAMAC_STATUS_OK ;
03518 }
03519 
03520 LoRaMacStatus_t  LoRaMacQueryTxPossible( uint8_t size, LoRaMacTxInfo_t * txInfo )
03521 {
03522     int8_t datarate = LoRaMacParamsDefaults.ChannelsDatarate ;
03523     uint8_t fOptLen = MacCommandsBufferIndex + MacCommandsBufferToRepeatIndex;
03524 
03525     if( txInfo == NULL )
03526     {
03527         return LORAMAC_STATUS_PARAMETER_INVALID ;
03528     }
03529 
03530     AdrNextDr( AdrCtrlOn, false, &datarate );
03531 
03532     if( RepeaterSupport == true )
03533     {
03534         txInfo->CurrentPayloadSize  = MaxPayloadOfDatarateRepeater[datarate];
03535     }
03536     else
03537     {
03538         txInfo->CurrentPayloadSize  = MaxPayloadOfDatarate[datarate];
03539     }
03540 
03541     if( txInfo->CurrentPayloadSize  >= fOptLen )
03542     {
03543         txInfo->MaxPossiblePayload  = txInfo->CurrentPayloadSize  - fOptLen;
03544     }
03545     else
03546     {
03547         return LORAMAC_STATUS_MAC_CMD_LENGTH_ERROR ;
03548     }
03549 
03550     if( ValidatePayloadLength( size, datarate, 0 ) == false )
03551     {
03552         return LORAMAC_STATUS_LENGTH_ERROR ;
03553     }
03554 
03555     if( ValidatePayloadLength( size, datarate, fOptLen ) == false )
03556     {
03557         return LORAMAC_STATUS_MAC_CMD_LENGTH_ERROR ;
03558     }
03559 
03560     return LORAMAC_STATUS_OK ;
03561 }
03562 
03563 LoRaMacStatus_t  LoRaMacMibGetRequestConfirm( MibRequestConfirm_t  *mibGet )
03564 {
03565     LoRaMacStatus_t  status = LORAMAC_STATUS_OK ;
03566 
03567     if( mibGet == NULL )
03568     {
03569         return LORAMAC_STATUS_PARAMETER_INVALID ;
03570     }
03571 
03572     switch( mibGet->Type  )
03573     {
03574         case MIB_DEVICE_CLASS :
03575         {
03576             mibGet->Param .Class  = LoRaMacDeviceClass;
03577             break;
03578         }
03579         case MIB_NETWORK_JOINED :
03580         {
03581             mibGet->Param .IsNetworkJoined  = IsLoRaMacNetworkJoined;
03582             break;
03583         }
03584         case MIB_ADR :
03585         {
03586             mibGet->Param .AdrEnable  = AdrCtrlOn;
03587             break;
03588         }
03589         case MIB_NET_ID :
03590         {
03591             mibGet->Param .NetID  = LoRaMacNetID;
03592             break;
03593         }
03594         case MIB_DEV_ADDR :
03595         {
03596             mibGet->Param .DevAddr  = LoRaMacDevAddr;
03597             break;
03598         }
03599         case MIB_NWK_SKEY :
03600         {
03601             mibGet->Param .NwkSKey  = LoRaMacNwkSKey;
03602             break;
03603         }
03604         case MIB_APP_SKEY :
03605         {
03606             mibGet->Param .AppSKey  = LoRaMacAppSKey;
03607             break;
03608         }
03609         case MIB_PUBLIC_NETWORK :
03610         {
03611             mibGet->Param .EnablePublicNetwork  = PublicNetwork;
03612             break;
03613         }
03614         case MIB_REPEATER_SUPPORT :
03615         {
03616             mibGet->Param .EnableRepeaterSupport  = RepeaterSupport;
03617             break;
03618         }
03619         case MIB_CHANNELS :
03620         {
03621             mibGet->Param .ChannelList  = Channels;
03622             break;
03623         }
03624         case MIB_RX2_CHANNEL :
03625         {
03626             mibGet->Param .Rx2Channel  = LoRaMacParams.Rx2Channel ;
03627             break;
03628         }
03629         case MIB_RX2_DEFAULT_CHANNEL :
03630         {
03631             mibGet->Param .Rx2Channel  = LoRaMacParamsDefaults.Rx2Channel ;
03632             break;
03633         }
03634         case MIB_CHANNELS_DEFAULT_MASK :
03635         {
03636             mibGet->Param .ChannelsDefaultMask  = LoRaMacParamsDefaults.ChannelsMask ;
03637             break;
03638         }
03639         case MIB_CHANNELS_MASK :
03640         {
03641             mibGet->Param .ChannelsMask  = LoRaMacParams.ChannelsMask ;
03642             break;
03643         }
03644         case MIB_CHANNELS_NB_REP :
03645         {
03646             mibGet->Param .ChannelNbRep  = LoRaMacParams.ChannelsNbRep ;
03647             break;
03648         }
03649         case MIB_MAX_RX_WINDOW_DURATION :
03650         {
03651             mibGet->Param .MaxRxWindow  = LoRaMacParams.MaxRxWindow ;
03652             break;
03653         }
03654         case MIB_RECEIVE_DELAY_1 :
03655         {
03656             mibGet->Param .ReceiveDelay1  = LoRaMacParams.ReceiveDelay1 ;
03657             break;
03658         }
03659         case MIB_RECEIVE_DELAY_2 :
03660         {
03661             mibGet->Param .ReceiveDelay2  = LoRaMacParams.ReceiveDelay2 ;
03662             break;
03663         }
03664         case MIB_JOIN_ACCEPT_DELAY_1 :
03665         {
03666             mibGet->Param .JoinAcceptDelay1  = LoRaMacParams.JoinAcceptDelay1 ;
03667             break;
03668         }
03669         case MIB_JOIN_ACCEPT_DELAY_2 :
03670         {
03671             mibGet->Param .JoinAcceptDelay2  = LoRaMacParams.JoinAcceptDelay2 ;
03672             break;
03673         }
03674         case MIB_CHANNELS_DEFAULT_DATARATE :
03675         {
03676             mibGet->Param .ChannelsDefaultDatarate  = LoRaMacParamsDefaults.ChannelsDatarate ;
03677             break;
03678         }
03679         case MIB_CHANNELS_DATARATE :
03680         {
03681             mibGet->Param .ChannelsDatarate  = LoRaMacParams.ChannelsDatarate ;
03682             break;
03683         }
03684         case MIB_CHANNELS_DEFAULT_TX_POWER :
03685         {
03686             mibGet->Param .ChannelsDefaultTxPower  = LoRaMacParamsDefaults.ChannelsTxPower ;
03687             break;
03688         }
03689         case MIB_CHANNELS_TX_POWER :
03690         {
03691             mibGet->Param .ChannelsTxPower  = LoRaMacParams.ChannelsTxPower ;
03692             break;
03693         }
03694         case MIB_UPLINK_COUNTER :
03695         {
03696             mibGet->Param .UpLinkCounter  = UpLinkCounter;
03697             break;
03698         }
03699         case MIB_DOWNLINK_COUNTER :
03700         {
03701             mibGet->Param .DownLinkCounter  = DownLinkCounter;
03702             break;
03703         }
03704         case MIB_MULTICAST_CHANNEL :
03705         {
03706             mibGet->Param .MulticastList  = MulticastChannels;
03707             break;
03708         }
03709         case MIB_SYSTEM_MAX_RX_ERROR :
03710         {
03711             mibGet->Param .SystemMaxRxError  = LoRaMacParams.SystemMaxRxError ;
03712             break;
03713         }
03714         case MIB_MIN_RX_SYMBOLS :
03715         {
03716             mibGet->Param .MinRxSymbols  = LoRaMacParams.MinRxSymbols ;
03717             break;
03718         }
03719         default:
03720             status = LORAMAC_STATUS_SERVICE_UNKNOWN ;
03721             break;
03722     }
03723 
03724     return status;
03725 }
03726 
03727 LoRaMacStatus_t  LoRaMacMibSetRequestConfirm( MibRequestConfirm_t  *mibSet )
03728 {
03729     LoRaMacStatus_t  status = LORAMAC_STATUS_OK ;
03730 
03731     if( mibSet == NULL )
03732     {
03733         return LORAMAC_STATUS_PARAMETER_INVALID ;
03734     }
03735     if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING )
03736     {
03737         return LORAMAC_STATUS_BUSY ;
03738     }
03739 
03740     switch( mibSet->Type  )
03741     {
03742         case MIB_DEVICE_CLASS :
03743         {
03744             LoRaMacDeviceClass = mibSet->Param .Class ;
03745             switch( LoRaMacDeviceClass )
03746             {
03747                 case CLASS_A :
03748                 {
03749                     // Set the radio into sleep to setup a defined state
03750                     Radio.Sleep( );
03751                     break;
03752                 }
03753                 case CLASS_B :
03754                 {
03755                     break;
03756                 }
03757                 case CLASS_C :
03758                 {
03759                     // Set the NodeAckRequested indicator to default
03760                     NodeAckRequested = false;
03761                     OnRxWindow2TimerEvent( );
03762                     break;
03763                 }
03764             }
03765             break;
03766         }
03767         case MIB_NETWORK_JOINED :
03768         {
03769             IsLoRaMacNetworkJoined = mibSet->Param .IsNetworkJoined ;
03770             break;
03771         }
03772         case MIB_ADR :
03773         {
03774             AdrCtrlOn = mibSet->Param .AdrEnable ;
03775             break;
03776         }
03777         case MIB_NET_ID :
03778         {
03779             LoRaMacNetID = mibSet->Param .NetID ;
03780             break;
03781         }
03782         case MIB_DEV_ADDR :
03783         {
03784             LoRaMacDevAddr = mibSet->Param .DevAddr ;
03785             break;
03786         }
03787         case MIB_NWK_SKEY :
03788         {
03789             if( mibSet->Param .NwkSKey  != NULL )
03790             {
03791                 memcpy1( LoRaMacNwkSKey, mibSet->Param .NwkSKey ,
03792                                sizeof( LoRaMacNwkSKey ) );
03793             }
03794             else
03795             {
03796                 status = LORAMAC_STATUS_PARAMETER_INVALID ;
03797             }
03798             break;
03799         }
03800         case MIB_APP_SKEY :
03801         {
03802             if( mibSet->Param .AppSKey  != NULL )
03803             {
03804                 memcpy1( LoRaMacAppSKey, mibSet->Param .AppSKey ,
03805                                sizeof( LoRaMacAppSKey ) );
03806             }
03807             else
03808             {
03809                 status = LORAMAC_STATUS_PARAMETER_INVALID ;
03810             }
03811             break;
03812         }
03813         case MIB_PUBLIC_NETWORK :
03814         {
03815             PublicNetwork = mibSet->Param .EnablePublicNetwork ;
03816             Radio.SetPublicNetwork( PublicNetwork );
03817             break;
03818         }
03819         case MIB_REPEATER_SUPPORT :
03820         {
03821              RepeaterSupport = mibSet->Param .EnableRepeaterSupport ;
03822             break;
03823         }
03824         case MIB_RX2_CHANNEL :
03825         {
03826             LoRaMacParams.Rx2Channel  = mibSet->Param .Rx2Channel ;
03827             break;
03828         }
03829         case MIB_RX2_DEFAULT_CHANNEL :
03830         {
03831             LoRaMacParamsDefaults.Rx2Channel  = mibSet->Param .Rx2DefaultChannel ;
03832             break;
03833         }
03834         case MIB_CHANNELS_DEFAULT_MASK :
03835         {
03836             if( mibSet->Param .ChannelsDefaultMask  )
03837             {
03838 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
03839                 bool chanMaskState = true;
03840 
03841 #if defined( USE_BAND_915_HYBRID )
03842                 chanMaskState = ValidateChannelMask( mibSet->Param .ChannelsDefaultMask  );
03843 #endif
03844                 if( chanMaskState == true )
03845                 {
03846                     if( ( CountNbEnabled125kHzChannels( mibSet->Param .ChannelsMask  ) < 2 ) &&
03847                         ( CountNbEnabled125kHzChannels( mibSet->Param .ChannelsMask  ) > 0 ) )
03848                     {
03849                         status = LORAMAC_STATUS_PARAMETER_INVALID ;
03850                     }
03851                     else
03852                     {
03853                         memcpy1( ( uint8_t* ) LoRaMacParamsDefaults.ChannelsMask ,
03854                                  ( uint8_t* ) mibSet->Param .ChannelsDefaultMask , sizeof( LoRaMacParamsDefaults.ChannelsMask  ) );
03855                         for ( uint8_t i = 0; i < sizeof( LoRaMacParamsDefaults.ChannelsMask  ) / 2; i++ )
03856                         {
03857                             // Disable channels which are no longer available
03858                             ChannelsMaskRemaining[i] &= LoRaMacParamsDefaults.ChannelsMask [i];
03859                         }
03860                     }
03861                 }
03862                 else
03863                 {
03864                     status = LORAMAC_STATUS_PARAMETER_INVALID ;
03865                 }
03866 #elif defined( USE_BAND_470 )
03867                 memcpy1( ( uint8_t* ) LoRaMacParamsDefaults.ChannelsMask ,
03868                          ( uint8_t* ) mibSet->Param .ChannelsDefaultMask , sizeof( LoRaMacParamsDefaults.ChannelsMask  ) );
03869 #else
03870                 memcpy1( ( uint8_t* ) LoRaMacParamsDefaults.ChannelsMask ,
03871                          ( uint8_t* ) mibSet->Param .ChannelsDefaultMask , 2 );
03872 #endif
03873             }
03874             else
03875             {
03876                 status = LORAMAC_STATUS_PARAMETER_INVALID ;
03877             }
03878             break;
03879         }
03880         case MIB_CHANNELS_MASK :
03881         {
03882             if( mibSet->Param .ChannelsMask  )
03883             {
03884 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
03885                 bool chanMaskState = true;
03886 
03887 #if defined( USE_BAND_915_HYBRID )
03888                 chanMaskState = ValidateChannelMask( mibSet->Param .ChannelsMask  );
03889 #endif
03890                 if( chanMaskState == true )
03891                 {
03892                     if( ( CountNbEnabled125kHzChannels( mibSet->Param .ChannelsMask  ) < 2 ) &&
03893                         ( CountNbEnabled125kHzChannels( mibSet->Param .ChannelsMask  ) > 0 ) )
03894                     {
03895                         status = LORAMAC_STATUS_PARAMETER_INVALID ;
03896                     }
03897                     else
03898                     {
03899                         memcpy1( ( uint8_t* ) LoRaMacParams.ChannelsMask ,
03900                                  ( uint8_t* ) mibSet->Param .ChannelsMask , sizeof( LoRaMacParams.ChannelsMask  ) );
03901                         for ( uint8_t i = 0; i < sizeof( LoRaMacParams.ChannelsMask  ) / 2; i++ )
03902                         {
03903                             // Disable channels which are no longer available
03904                             ChannelsMaskRemaining[i] &= LoRaMacParams.ChannelsMask [i];
03905                         }
03906                     }
03907                 }
03908                 else
03909                 {
03910                     status = LORAMAC_STATUS_PARAMETER_INVALID ;
03911                 }
03912 #elif defined( USE_BAND_470 )
03913                 memcpy1( ( uint8_t* ) LoRaMacParams.ChannelsMask ,
03914                          ( uint8_t* ) mibSet->Param .ChannelsMask , sizeof( LoRaMacParams.ChannelsMask  ) );
03915 #else
03916                 memcpy1( ( uint8_t* ) LoRaMacParams.ChannelsMask ,
03917                          ( uint8_t* ) mibSet->Param .ChannelsMask , 2 );
03918 #endif
03919             }
03920             else
03921             {
03922                 status = LORAMAC_STATUS_PARAMETER_INVALID ;
03923             }
03924             break;
03925         }
03926         case MIB_CHANNELS_NB_REP :
03927         {
03928             if( ( mibSet->Param .ChannelNbRep  >= 1 ) &&
03929                 ( mibSet->Param .ChannelNbRep  <= 15 ) )
03930             {
03931                 LoRaMacParams.ChannelsNbRep  = mibSet->Param .ChannelNbRep ;
03932             }
03933             else
03934             {
03935                 status = LORAMAC_STATUS_PARAMETER_INVALID ;
03936             }
03937             break;
03938         }
03939         case MIB_MAX_RX_WINDOW_DURATION :
03940         {
03941             LoRaMacParams.MaxRxWindow  = mibSet->Param .MaxRxWindow ;
03942             break;
03943         }
03944         case MIB_RECEIVE_DELAY_1 :
03945         {
03946             LoRaMacParams.ReceiveDelay1  = mibSet->Param .ReceiveDelay1 ;
03947             break;
03948         }
03949         case MIB_RECEIVE_DELAY_2 :
03950         {
03951             LoRaMacParams.ReceiveDelay2  = mibSet->Param .ReceiveDelay2 ;
03952             break;
03953         }
03954         case MIB_JOIN_ACCEPT_DELAY_1 :
03955         {
03956             LoRaMacParams.JoinAcceptDelay1  = mibSet->Param .JoinAcceptDelay1 ;
03957             break;
03958         }
03959         case MIB_JOIN_ACCEPT_DELAY_2 :
03960         {
03961             LoRaMacParams.JoinAcceptDelay2  = mibSet->Param .JoinAcceptDelay2 ;
03962             break;
03963         }
03964         case MIB_CHANNELS_DEFAULT_DATARATE :
03965         {
03966 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
03967             if( ValueInRange( mibSet->Param .ChannelsDefaultDatarate ,
03968                               DR_0, DR_5 ) )
03969             {
03970                 LoRaMacParamsDefaults.ChannelsDatarate  = mibSet->Param .ChannelsDefaultDatarate ;
03971             }
03972 #else
03973             if( ValueInRange( mibSet->Param .ChannelsDefaultDatarate ,
03974                               LORAMAC_TX_MIN_DATARATE, LORAMAC_TX_MAX_DATARATE ) )
03975             {
03976                 LoRaMacParamsDefaults.ChannelsDatarate  = mibSet->Param .ChannelsDefaultDatarate ;
03977             }
03978 #endif
03979             else
03980             {
03981                 status = LORAMAC_STATUS_PARAMETER_INVALID ;
03982             }
03983             break;
03984         }
03985         case MIB_CHANNELS_DATARATE :
03986         {
03987             if( ValueInRange( mibSet->Param .ChannelsDatarate ,
03988                               LORAMAC_TX_MIN_DATARATE, LORAMAC_TX_MAX_DATARATE ) )
03989             {
03990                 LoRaMacParams.ChannelsDatarate  = mibSet->Param .ChannelsDatarate ;
03991             }
03992             else
03993             {
03994                 status = LORAMAC_STATUS_PARAMETER_INVALID ;
03995             }
03996             break;
03997         }
03998         case MIB_CHANNELS_DEFAULT_TX_POWER :
03999         {
04000             if( ValueInRange( mibSet->Param .ChannelsDefaultTxPower ,
04001                               LORAMAC_MAX_TX_POWER, LORAMAC_MIN_TX_POWER ) )
04002             {
04003                 LoRaMacParamsDefaults.ChannelsTxPower  = mibSet->Param .ChannelsDefaultTxPower ;
04004             }
04005             else
04006             {
04007                 status = LORAMAC_STATUS_PARAMETER_INVALID ;
04008             }
04009             break;
04010         }
04011         case MIB_CHANNELS_TX_POWER :
04012         {
04013             if( ValueInRange( mibSet->Param .ChannelsTxPower ,
04014                               LORAMAC_MAX_TX_POWER, LORAMAC_MIN_TX_POWER ) )
04015             {
04016                 LoRaMacParams.ChannelsTxPower  = mibSet->Param .ChannelsTxPower ;
04017             }
04018             else
04019             {
04020                 status = LORAMAC_STATUS_PARAMETER_INVALID ;
04021             }
04022             break;
04023         }
04024         case MIB_UPLINK_COUNTER :
04025         {
04026             UpLinkCounter = mibSet->Param .UpLinkCounter ;
04027             break;
04028         }
04029         case MIB_DOWNLINK_COUNTER :
04030         {
04031             DownLinkCounter = mibSet->Param .DownLinkCounter ;
04032             break;
04033         }
04034         case MIB_SYSTEM_MAX_RX_ERROR :
04035         {
04036             LoRaMacParams.SystemMaxRxError  = LoRaMacParamsDefaults.SystemMaxRxError  = mibSet->Param .SystemMaxRxError ;
04037             break;
04038         }
04039         case MIB_MIN_RX_SYMBOLS :
04040         {
04041             LoRaMacParams.MinRxSymbols  = LoRaMacParamsDefaults.MinRxSymbols  = mibSet->Param .MinRxSymbols ;
04042             break;
04043         }
04044         default:
04045             status = LORAMAC_STATUS_SERVICE_UNKNOWN ;
04046             break;
04047     }
04048 
04049     return status;
04050 }
04051 
04052 LoRaMacStatus_t  LoRaMacChannelAdd( uint8_t id, ChannelParams_t  params )
04053 {
04054 #if defined( USE_BAND_470 ) || defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
04055     return LORAMAC_STATUS_PARAMETER_INVALID ;
04056 #else
04057     bool datarateInvalid = false;
04058     bool frequencyInvalid = false;
04059     uint8_t band = 0;
04060 
04061     // The id must not exceed LORA_MAX_NB_CHANNELS
04062     if( id >= LORA_MAX_NB_CHANNELS )
04063     {
04064         return LORAMAC_STATUS_PARAMETER_INVALID ;
04065     }
04066     // Validate if the MAC is in a correct state
04067     if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING )
04068     {
04069         if( ( LoRaMacState & LORAMAC_TX_CONFIG ) != LORAMAC_TX_CONFIG )
04070         {
04071             return LORAMAC_STATUS_BUSY ;
04072         }
04073     }
04074     // Validate the datarate
04075     if( ( params.DrRange .Fields.Min  > params.DrRange .Fields.Max  ) ||
04076         ( ValueInRange( params.DrRange .Fields.Min , LORAMAC_TX_MIN_DATARATE,
04077                         LORAMAC_TX_MAX_DATARATE ) == false ) ||
04078         ( ValueInRange( params.DrRange .Fields.Max , LORAMAC_TX_MIN_DATARATE,
04079                         LORAMAC_TX_MAX_DATARATE ) == false ) )
04080     {
04081         datarateInvalid = true;
04082     }
04083 
04084 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
04085     if( id < 3 )
04086     {
04087         if( params.Frequency  != Channels[id].Frequency  )
04088         {
04089             frequencyInvalid = true;
04090         }
04091 
04092         if( params.DrRange .Fields.Min  > DR_0 )
04093         {
04094             datarateInvalid = true;
04095         }
04096         if( ValueInRange( params.DrRange .Fields.Max , DR_5, LORAMAC_TX_MAX_DATARATE ) == false )
04097         {
04098             datarateInvalid = true;
04099         }
04100     }
04101 #endif
04102 
04103     // Validate the frequency
04104     if( ( Radio.CheckRfFrequency( params.Frequency  ) == true ) && ( params.Frequency  > 0 ) && ( frequencyInvalid == false ) )
04105     {
04106 #if defined( USE_BAND_868 )
04107         if( ( params.Frequency  >= 863000000 ) && ( params.Frequency  < 865000000 ) )
04108         {
04109             band = BAND_G1_2;
04110         }
04111         else if( ( params.Frequency  >= 865000000 ) && ( params.Frequency  <= 868000000 ) )
04112         {
04113             band = BAND_G1_0;
04114         }
04115         else if( ( params.Frequency  > 868000000 ) && ( params.Frequency  <= 868600000 ) )
04116         {
04117             band = BAND_G1_1;
04118         }
04119         else if( ( params.Frequency  >= 868700000 ) && ( params.Frequency  <= 869200000 ) )
04120         {
04121             band = BAND_G1_2;
04122         }
04123         else if( ( params.Frequency  >= 869400000 ) && ( params.Frequency  <= 869650000 ) )
04124         {
04125             band = BAND_G1_3;
04126         }
04127         else if( ( params.Frequency  >= 869700000 ) && ( params.Frequency  <= 870000000 ) )
04128         {
04129             band = BAND_G1_4;
04130         }
04131         else
04132         {
04133             frequencyInvalid = true;
04134         }
04135 #endif
04136     }
04137     else
04138     {
04139         frequencyInvalid = true;
04140     }
04141 
04142     if( ( datarateInvalid == true ) && ( frequencyInvalid == true ) )
04143     {
04144         return LORAMAC_STATUS_FREQ_AND_DR_INVALID ;
04145     }
04146     if( datarateInvalid == true )
04147     {
04148         return LORAMAC_STATUS_DATARATE_INVALID ;
04149     }
04150     if( frequencyInvalid == true )
04151     {
04152         return LORAMAC_STATUS_FREQUENCY_INVALID ;
04153     }
04154 
04155     // Every parameter is valid, activate the channel
04156     Channels[id] = params;
04157     Channels[id].Band  = band;
04158     LoRaMacParams.ChannelsMask [0] |= ( 1 << id );
04159 
04160     return LORAMAC_STATUS_OK ;
04161 #endif
04162 }
04163 
04164 LoRaMacStatus_t  LoRaMacChannelRemove( uint8_t id )
04165 {
04166 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
04167     if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING )
04168     {
04169         if( ( LoRaMacState & LORAMAC_TX_CONFIG ) != LORAMAC_TX_CONFIG )
04170         {
04171             return LORAMAC_STATUS_BUSY ;
04172         }
04173     }
04174 
04175     if( ( id < 3 ) || ( id >= LORA_MAX_NB_CHANNELS ) )
04176     {
04177         return LORAMAC_STATUS_PARAMETER_INVALID ;
04178     }
04179     else
04180     {
04181         // Remove the channel from the list of channels
04182         Channels[id] = ( ChannelParams_t  ){ 0, { 0 }, 0 };
04183 
04184         // Disable the channel as it doesn't exist anymore
04185         if( DisableChannelInMask( id, LoRaMacParams.ChannelsMask  ) == false )
04186         {
04187             return LORAMAC_STATUS_PARAMETER_INVALID ;
04188         }
04189     }
04190     return LORAMAC_STATUS_OK ;
04191 #elif ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) || defined( USE_BAND_470 ) )
04192     return LORAMAC_STATUS_PARAMETER_INVALID ;
04193 #endif
04194 }
04195 
04196 LoRaMacStatus_t  LoRaMacMulticastChannelLink( MulticastParams_t  *channelParam )
04197 {
04198     if( channelParam == NULL )
04199     {
04200         return LORAMAC_STATUS_PARAMETER_INVALID ;
04201     }
04202     if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING )
04203     {
04204         return LORAMAC_STATUS_BUSY ;
04205     }
04206 
04207     // Reset downlink counter
04208     channelParam->DownLinkCounter  = 0;
04209 
04210     if( MulticastChannels == NULL )
04211     {
04212         // New node is the fist element
04213         MulticastChannels = channelParam;
04214     }
04215     else
04216     {
04217         MulticastParams_t  *cur = MulticastChannels;
04218 
04219         // Search the last node in the list
04220         while( cur->Next  != NULL )
04221         {
04222             cur = cur->Next ;
04223         }
04224         // This function always finds the last node
04225         cur->Next  = channelParam;
04226     }
04227 
04228     return LORAMAC_STATUS_OK ;
04229 }
04230 
04231 LoRaMacStatus_t  LoRaMacMulticastChannelUnlink( MulticastParams_t  *channelParam )
04232 {
04233     if( channelParam == NULL )
04234     {
04235         return LORAMAC_STATUS_PARAMETER_INVALID ;
04236     }
04237     if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING )
04238     {
04239         return LORAMAC_STATUS_BUSY ;
04240     }
04241 
04242     if( MulticastChannels != NULL )
04243     {
04244         if( MulticastChannels == channelParam )
04245         {
04246           // First element
04247           MulticastChannels = channelParam->Next ;
04248         }
04249         else
04250         {
04251             MulticastParams_t  *cur = MulticastChannels;
04252 
04253             // Search the node in the list
04254             while( cur->Next  && cur->Next  != channelParam )
04255             {
04256                 cur = cur->Next ;
04257             }
04258             // If we found the node, remove it
04259             if( cur->Next  )
04260             {
04261                 cur->Next  = channelParam->Next ;
04262             }
04263         }
04264         channelParam->Next  = NULL;
04265     }
04266 
04267     return LORAMAC_STATUS_OK ;
04268 }
04269 
04270 LoRaMacStatus_t  LoRaMacMlmeRequest( MlmeReq_t  *mlmeRequest )
04271 {
04272     LoRaMacStatus_t  status = LORAMAC_STATUS_SERVICE_UNKNOWN ;
04273     LoRaMacHeader_t  macHdr;
04274 
04275     if( mlmeRequest == NULL )
04276     {
04277         return LORAMAC_STATUS_PARAMETER_INVALID ;
04278     }
04279     if( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING )
04280     {
04281         return LORAMAC_STATUS_BUSY ;
04282     }
04283 
04284     memset1( ( uint8_t* ) &MlmeConfirm, 0, sizeof( MlmeConfirm ) );
04285 
04286     MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR ;
04287 
04288     switch( mlmeRequest->Type  )
04289     {
04290         case MLME_JOIN :
04291         {
04292             if( ( LoRaMacState & LORAMAC_TX_DELAYED ) == LORAMAC_TX_DELAYED )
04293             {
04294                 return LORAMAC_STATUS_BUSY ;
04295             }
04296 
04297             if( ( mlmeRequest->Req.Join .DevEui  == NULL ) ||
04298                 ( mlmeRequest->Req.Join .AppEui  == NULL ) ||
04299                 ( mlmeRequest->Req.Join .AppKey  == NULL ) ||
04300                 ( mlmeRequest->Req.Join .NbTrials  == 0 ) )
04301             {
04302                 return LORAMAC_STATUS_PARAMETER_INVALID ;
04303             }
04304 
04305 #if ( defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID ) )
04306             // Enables at least the usage of the 2 datarates.
04307             if( mlmeRequest->Req.Join .NbTrials  < 2 )
04308             {
04309                 mlmeRequest->Req.Join .NbTrials  = 2;
04310             }
04311 #else
04312             // Enables at least the usage of all datarates.
04313             if( mlmeRequest->Req.Join .NbTrials  < 48 )
04314             {
04315                 mlmeRequest->Req.Join .NbTrials  = 48;
04316             }
04317 #endif
04318 
04319             LoRaMacFlags.Bits.MlmeReq  = 1;
04320             MlmeConfirm.MlmeRequest = mlmeRequest->Type ;
04321 
04322             LoRaMacDevEui = mlmeRequest->Req.Join .DevEui ;
04323             LoRaMacAppEui = mlmeRequest->Req.Join .AppEui ;
04324             LoRaMacAppKey = mlmeRequest->Req.Join .AppKey ;
04325             MaxJoinRequestTrials = mlmeRequest->Req.Join .NbTrials ;
04326 
04327             // Reset variable JoinRequestTrials
04328             JoinRequestTrials = 0;
04329 
04330             // Setup header information
04331             macHdr.Value  = 0;
04332             macHdr.Bits.MType   = FRAME_TYPE_JOIN_REQ ;
04333 
04334             ResetMacParameters( );
04335 
04336             // Add a +1, since we start to count from 0
04337             LoRaMacParams.ChannelsDatarate  = AlternateDatarate( JoinRequestTrials + 1 );
04338 
04339             status = Send( &macHdr, 0, NULL, 0 );
04340             break;
04341         }
04342         case MLME_LINK_CHECK :
04343         {
04344             LoRaMacFlags.Bits.MlmeReq  = 1;
04345             // LoRaMac will send this command piggy-pack
04346             MlmeConfirm.MlmeRequest = mlmeRequest->Type ;
04347 
04348             status = AddMacCommand( MOTE_MAC_LINK_CHECK_REQ , 0, 0 );
04349             break;
04350         }
04351         case MLME_TXCW :
04352         {
04353             MlmeConfirm.MlmeRequest = mlmeRequest->Type ;
04354             LoRaMacFlags.Bits.MlmeReq  = 1;
04355             status = SetTxContinuousWave( mlmeRequest->Req.TxCw .Timeout  );
04356             break;
04357         }
04358         case MLME_TXCW_1 :
04359         {
04360             MlmeConfirm.MlmeRequest = mlmeRequest->Type ;
04361             LoRaMacFlags.Bits.MlmeReq  = 1;
04362             status = SetTxContinuousWave1( mlmeRequest->Req.TxCw .Timeout , mlmeRequest->Req.TxCw .Frequency , mlmeRequest->Req.TxCw .Power  );
04363             break;
04364         }
04365         default:
04366             break;
04367     }
04368 
04369     if( status != LORAMAC_STATUS_OK  )
04370     {
04371         NodeAckRequested = false;
04372         LoRaMacFlags.Bits.MlmeReq  = 0;
04373     }
04374 
04375     return status;
04376 }
04377 
04378 LoRaMacStatus_t  LoRaMacMcpsRequest( McpsReq_t  *mcpsRequest )
04379 {
04380     LoRaMacStatus_t  status = LORAMAC_STATUS_SERVICE_UNKNOWN ;
04381     LoRaMacHeader_t  macHdr;
04382     uint8_t fPort = 0;
04383     void *fBuffer;
04384     uint16_t fBufferSize;
04385     int8_t datarate;
04386     bool readyToSend = false;
04387 
04388     if( mcpsRequest == NULL )
04389     {
04390         return LORAMAC_STATUS_PARAMETER_INVALID ;
04391     }
04392     if( ( ( LoRaMacState & LORAMAC_TX_RUNNING ) == LORAMAC_TX_RUNNING ) ||
04393         ( ( LoRaMacState & LORAMAC_TX_DELAYED ) == LORAMAC_TX_DELAYED ) )
04394     {
04395         return LORAMAC_STATUS_BUSY ;
04396     }
04397 
04398     macHdr.Value  = 0;
04399     memset1 ( ( uint8_t* ) &McpsConfirm, 0, sizeof( McpsConfirm ) );
04400     McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR ;
04401 
04402     switch( mcpsRequest->Type  )
04403     {
04404         case MCPS_UNCONFIRMED :
04405         {
04406             readyToSend = true;
04407             AckTimeoutRetries = 1;
04408 
04409             macHdr.Bits.MType  = FRAME_TYPE_DATA_UNCONFIRMED_UP ;
04410             fPort = mcpsRequest->Req.Unconfirmed .fPort ;
04411             fBuffer = mcpsRequest->Req.Unconfirmed .fBuffer ;
04412             fBufferSize = mcpsRequest->Req.Unconfirmed .fBufferSize ;
04413             datarate = mcpsRequest->Req.Unconfirmed .Datarate ;
04414             break;
04415         }
04416         case MCPS_CONFIRMED :
04417         {
04418             readyToSend = true;
04419             AckTimeoutRetriesCounter = 1;
04420             AckTimeoutRetries = mcpsRequest->Req.Confirmed .NbTrials ;
04421 
04422             macHdr.Bits.MType  = FRAME_TYPE_DATA_CONFIRMED_UP ;
04423             fPort = mcpsRequest->Req.Confirmed .fPort ;
04424             fBuffer = mcpsRequest->Req.Confirmed .fBuffer ;
04425             fBufferSize = mcpsRequest->Req.Confirmed .fBufferSize ;
04426             datarate = mcpsRequest->Req.Confirmed .Datarate ;
04427             break;
04428         }
04429         case MCPS_PROPRIETARY :
04430         {
04431             readyToSend = true;
04432             AckTimeoutRetries = 1;
04433 
04434             macHdr.Bits.MType  = FRAME_TYPE_PROPRIETARY ;
04435             fBuffer = mcpsRequest->Req.Proprietary .fBuffer ;
04436             fBufferSize = mcpsRequest->Req.Proprietary .fBufferSize ;
04437             datarate = mcpsRequest->Req.Proprietary .Datarate ;
04438             break;
04439         }
04440         default:
04441             break;
04442     }
04443 
04444     if( readyToSend == true )
04445     {
04446         if( AdrCtrlOn == false )
04447         {
04448             if( ValueInRange( datarate, LORAMAC_TX_MIN_DATARATE, LORAMAC_TX_MAX_DATARATE ) == true )
04449             {
04450                 LoRaMacParams.ChannelsDatarate  = datarate;
04451             }
04452             else
04453             {
04454                 return LORAMAC_STATUS_PARAMETER_INVALID ;
04455             }
04456         }
04457 
04458         status = Send( &macHdr, fPort, fBuffer, fBufferSize );
04459         if( status == LORAMAC_STATUS_OK  )
04460         {
04461             McpsConfirm.McpsRequest = mcpsRequest->Type ;
04462             LoRaMacFlags.Bits.McpsReq  = 1;
04463         }
04464         else
04465         {
04466             NodeAckRequested = false;
04467         }
04468     }
04469 
04470     return status;
04471 }
04472 
04473 void LoRaMacTestRxWindowsOn( bool enable )
04474 {
04475     IsRxWindowsEnabled = enable;
04476 }
04477 
04478 void LoRaMacTestSetMic( uint16_t txPacketCounter )
04479 {
04480     UpLinkCounter = txPacketCounter;
04481     IsUpLinkCounterFixed = true;
04482 }
04483 
04484 void LoRaMacTestSetDutyCycleOn( bool enable )
04485 {
04486 #if ( defined( USE_BAND_868 ) || defined( USE_BAND_433 ) || defined( USE_BAND_780 ) )
04487     DutyCycleOn = enable;
04488 #else
04489     DutyCycleOn = false;
04490 #endif
04491 }
04492 
04493 void LoRaMacTestSetChannel( uint8_t channel )
04494 {
04495     Channel = channel;
04496 }
04497 
04498 static RxConfigParams_t ComputeRxWindowParameters( int8_t datarate, uint32_t rxError )
04499 {
04500     RxConfigParams_t rxConfigParams = { 0, 0, 0, 0 };
04501     double tSymbol = 0.0;
04502 
04503     rxConfigParams.Datarate = datarate;
04504     switch( Bandwidths[datarate] )
04505     {
04506         default:
04507         case 125000:
04508             rxConfigParams.Bandwidth = 0;
04509             break;
04510         case 250000:
04511             rxConfigParams.Bandwidth = 1;
04512             break;
04513         case 500000:
04514             rxConfigParams.Bandwidth = 2;
04515             break;
04516     }
04517 
04518 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
04519     if( datarate == DR_7 )
04520     { // FSK
04521         tSymbol = ( 1.0 / ( double )Datarates[datarate] ) * 8.0; // 1 symbol equals 1 byte
04522     }
04523     else
04524 #endif
04525     { // LoRa
04526         tSymbol = ( ( double )( 1 << Datarates[datarate] ) / ( double )Bandwidths[datarate] ) * 1e3;
04527     }
04528 
04529     rxConfigParams.RxWindowTimeout = MAX( ( uint32_t )ceil( ( ( 2 * LoRaMacParams.MinRxSymbols  - 8 ) * tSymbol + 2 * rxError ) / tSymbol ), LoRaMacParams.MinRxSymbols  ); // Computed number of symbols
04530 
04531     rxConfigParams.RxOffset = ( int32_t )ceil( ( 4.0 * tSymbol ) - ( ( rxConfigParams.RxWindowTimeout * tSymbol ) / 2.0 ) - RADIO_WAKEUP_TIME );
04532 
04533     return rxConfigParams;
04534 }