Fork of Semtech LoRaWAN stack

Fork of LoRaWAN-lib by canuck lehead

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