Semtech / LoRaWAN-lib-dev
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers LoRaMac.cpp Source File

LoRaMac.cpp

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